generar report.html (fixes #7)

This commit is contained in:
Cat /dev/Nulo 2023-03-31 20:38:34 -03:00
parent 8684fdc219
commit 4515bc2359
3 changed files with 97 additions and 34 deletions

View file

@ -13,6 +13,7 @@
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@nulo/html.js": "^0.0.9",
"domhandler": "^5.0.3", "domhandler": "^5.0.3",
"htmlparser2": "^8.0.1" "htmlparser2": "^8.0.1"
}, },

View file

@ -1,30 +1,42 @@
lockfileVersion: 5.4 lockfileVersion: '6.0'
specifiers:
'@types/htmlparser2': ^3.10.3
'@types/node': ^18.11.9
domhandler: ^5.0.3
htmlparser2: ^8.0.1
typescript: ^4.9.3
dependencies: dependencies:
domhandler: 5.0.3 '@nulo/html.js':
htmlparser2: 8.0.1 specifier: ^0.0.9
version: 0.0.9
domhandler:
specifier: ^5.0.3
version: 5.0.3
htmlparser2:
specifier: ^8.0.1
version: 8.0.1
devDependencies: devDependencies:
'@types/htmlparser2': 3.10.3 '@types/htmlparser2':
'@types/node': 18.11.9 specifier: ^3.10.3
typescript: 4.9.3 version: 3.10.3
'@types/node':
specifier: ^18.11.9
version: 18.11.9
typescript:
specifier: ^4.9.3
version: 4.9.3
packages: packages:
/@types/domutils/1.7.4: /@nulo/html.js@0.0.9:
resolution: {integrity: sha512-/mdpdH3cjL52X/V0H3LLxydcx0vkjQneuk91L9SkBXIoEUwA1nK6sR23MpvoT7zwqMph/fx3fevz0llXvdzayQ==, tarball: https://gitea.nulo.in/api/packages/Nulo/npm/%40nulo%2Fhtml.js/-/0.0.9/html.js-0.0.9.tgz}
dependencies:
html-escaper: 3.0.3
dev: false
/@types/domutils@1.7.4:
resolution: {integrity: sha512-w542nRQ0vpXQjLYP52LKqrugQtUq580dEDiDIyZ6IBmV8a3LXjGVNxfj/jUQxS0kDsbZAWsSxQOcTfVX3HRdwg==} resolution: {integrity: sha512-w542nRQ0vpXQjLYP52LKqrugQtUq580dEDiDIyZ6IBmV8a3LXjGVNxfj/jUQxS0kDsbZAWsSxQOcTfVX3HRdwg==}
dependencies: dependencies:
domhandler: 2.4.2 domhandler: 2.4.2
dev: true dev: true
/@types/htmlparser2/3.10.3: /@types/htmlparser2@3.10.3:
resolution: {integrity: sha512-XA74aD+acytofnZic9n83Rxy/IZ259299bYPx5SEyx7uymPi79lRyKDkhJlsuCaPHB7rEoTEhRN4Vm2G5WmHHg==} resolution: {integrity: sha512-XA74aD+acytofnZic9n83Rxy/IZ259299bYPx5SEyx7uymPi79lRyKDkhJlsuCaPHB7rEoTEhRN4Vm2G5WmHHg==}
dependencies: dependencies:
'@types/domutils': 1.7.4 '@types/domutils': 1.7.4
@ -32,11 +44,11 @@ packages:
domhandler: 2.4.2 domhandler: 2.4.2
dev: true dev: true
/@types/node/18.11.9: /@types/node@18.11.9:
resolution: {integrity: sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==} resolution: {integrity: sha512-CRpX21/kGdzjOpFsZSkcrXMGIBWMGNIHXXBVFSH+ggkftxg+XYP20TESbh+zFvFj3EQOl5byk0HTRn1IL6hbqg==}
dev: true dev: true
/dom-serializer/2.0.0: /dom-serializer@2.0.0:
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
dependencies: dependencies:
domelementtype: 2.3.0 domelementtype: 2.3.0
@ -44,28 +56,28 @@ packages:
entities: 4.4.0 entities: 4.4.0
dev: false dev: false
/domelementtype/1.3.1: /domelementtype@1.3.1:
resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==} resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==}
dev: true dev: true
/domelementtype/2.3.0: /domelementtype@2.3.0:
resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==}
dev: false dev: false
/domhandler/2.4.2: /domhandler@2.4.2:
resolution: {integrity: sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==} resolution: {integrity: sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==}
dependencies: dependencies:
domelementtype: 1.3.1 domelementtype: 1.3.1
dev: true dev: true
/domhandler/5.0.3: /domhandler@5.0.3:
resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==}
engines: {node: '>= 4'} engines: {node: '>= 4'}
dependencies: dependencies:
domelementtype: 2.3.0 domelementtype: 2.3.0
dev: false dev: false
/domutils/3.0.1: /domutils@3.0.1:
resolution: {integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==} resolution: {integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==}
dependencies: dependencies:
dom-serializer: 2.0.0 dom-serializer: 2.0.0
@ -73,12 +85,16 @@ packages:
domhandler: 5.0.3 domhandler: 5.0.3
dev: false dev: false
/entities/4.4.0: /entities@4.4.0:
resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==}
engines: {node: '>=0.12'} engines: {node: '>=0.12'}
dev: false dev: false
/htmlparser2/8.0.1: /html-escaper@3.0.3:
resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
dev: false
/htmlparser2@8.0.1:
resolution: {integrity: sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==} resolution: {integrity: sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==}
dependencies: dependencies:
domelementtype: 2.3.0 domelementtype: 2.3.0
@ -87,7 +103,7 @@ packages:
entities: 4.4.0 entities: 4.4.0
dev: false dev: false
/typescript/4.9.3: /typescript@4.9.3:
resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==} resolution: {integrity: sha512-CIfGzTelbKNEnLpLdGFgdyKhG23CKdKgQPOBc+OUNrkJ2vr+KSzsSV5kq5iWhEQbok+quxgGzrAtGWCyU7tHnA==}
engines: {node: '>=4.2.0'} engines: {node: '>=4.2.0'}
hasBin: true hasBin: true

View file

@ -1,7 +1,18 @@
import { Parser } from "htmlparser2"; import { Parser } from "htmlparser2";
import { DomHandler, Element } from "domhandler"; import { DomHandler, Element } from "domhandler";
import { readdir, readFile } from "fs/promises"; import { readdir, readFile, writeFile } from "fs/promises";
import { join } from "path"; import { join, relative } from "path";
import {
doctype,
metaUtf8,
render,
title,
ul,
li,
h2,
ol,
basicElement,
} from "@nulo/html.js";
const { argv } = process; const { argv } = process;
const dirPath = argv[2] || "."; const dirPath = argv[2] || ".";
@ -15,14 +26,14 @@ interface Thing {
| "media-no-src"; | "media-no-src";
description: string; description: string;
} }
interface Report { type Report = {
things: Thing[]; things: Thing[];
} };
interface Page { type Page = {
report: Report; report: Report;
rawHtml: string; rawHtml: string;
} };
function recurseElement(page: Page, el: Element) { function recurseElement(page: Page, el: Element) {
const { report, rawHtml } = page; const { report, rawHtml } = page;
@ -140,9 +151,9 @@ async function recurseDirectory(reports: Reports, path: string) {
); );
} }
await recurseDirectory(reports, dirPath); await recurseDirectory(reports, dirPath);
const totalThings = Object.values(reports) const totalThings = [...reports.entries()].flatMap(([name, r]) =>
.map((r) => r.things) r.things.map((t) => ({ ...t, fileName: name }))
.flat(); );
const kinds = new Set(totalThings.map((t) => t.type)); const kinds = new Set(totalThings.map((t) => t.type));
console.log( console.log(
`Finished with ${Object.keys(reports).length} files read, ${ `Finished with ${Object.keys(reports).length} files read, ${
@ -168,3 +179,38 @@ const linkHttp = totalThings.filter((t) => t.type === "link-http").length;
console.log( console.log(
`==> ${linkHttp} links to HTTP sites, which is not a real concern unless it's a key part of the site's navigation.` `==> ${linkHttp} links to HTTP sites, which is not a real concern unless it's a key part of the site's navigation.`
); );
const code = basicElement("code");
const reportOutput = "report.html";
console.info(`Writing report to ${reportOutput}`);
const html = render(
doctype(),
metaUtf8,
title("site-analyzer report"),
ul(
li(
`${pathBasedCount} problems that affect users using legacy IPFS gateways`
),
li(
`${mediaHttp} problems that make the website not self-contained, making it miss content if HTTP is unavailable`
),
li(
`${linkHttp} links to HTTP sites, which is not a real concern unless it's a key part of the site's navigation.`
)
),
...[...kinds]
.sort((a, b) => (b === "link-http" ? -1 : 0))
.flatMap((kind) => [
h2(kind),
ol(
...totalThings
.filter((t) => t.type === kind)
.map((t) =>
li(code(relative(dirPath, t.fileName)), ": ", code(t.description))
)
),
])
);
await writeFile(reportOutput, html);