UNPKG

ketting

Version:

Opinionated HATEOAS / Rest client.

112 lines (83 loc) 2.06 kB
import sax from 'sax'; import { Link } from '../link.js'; import { resolve } from './uri.js'; export type HtmlForm = { action: string; method: string | null; enctype: string | null; rel: string | null; id: string | null; } type ParseHtmlResult = { links: Link[]; forms: HtmlForm[]; } export function parseHtml(contextUri: string, body: string): ParseHtmlResult { const parser = sax.parser(false, {}); const links: Link[] = []; const forms: ParseHtmlResult['forms'] = []; parser.onopentag = node => { switch(node.name) { case 'LINK' : case 'A' : links.push(...parseLink(contextUri, node as sax.Tag)); break; case 'FORM' : forms.push(...parseForm(contextUri, node as sax.Tag)); break; } }; parser.write(body).close(); return { forms, links, }; } function parseLink(contextUri: string, node: sax.Tag): Link[] { if (!node.attributes.REL) { return []; } if (!node.attributes.HREF) { return []; } const rels = node.attributes.REL as string; const links: Link[] = []; for (const rel of rels.split(' ')) { const type = node.attributes.TYPE as string; const link: Link = { rel, context: contextUri, href: node.attributes.HREF as string, }; if (type) link.type = type; links.push(link); } return links; } function parseForm(contextUri: string, node: sax.Tag): HtmlForm[] { const rels = node.attributes.REL || null; const id = node.attributes.ID || null; const action = node.attributes.ACTION || ''; const method = node.attributes.METHOD || 'GET'; const enctype = node.attributes.ENCTYPE || 'application/x-www-form-urlencoded'; if (!rels) { return [{ rel: null, id, action: resolve(contextUri, action), method, enctype, }]; } const result = []; for(const rel of rels.split(' ')) { result.push({ rel, id, action: resolve(contextUri, action), method, enctype, }); } return result; }