feat: habr navigation

fix: dompurify
fix: middleware processing
This commit is contained in:
Artemy 2024-05-15 17:06:51 +03:00
parent 8be52a0237
commit a98f532cf6
7 changed files with 269 additions and 32 deletions

View File

@ -8,7 +8,7 @@ const Readability = new Engine(
);
Readability.route('*path', async (input, ro: Route<{ path: string }>) => {
const reader = new OReadability(input.document);
const reader = new OReadability(input.document.cloneNode(true) as Document);
const parsed = reader.parse();
if (!parsed) {

View File

@ -8,7 +8,7 @@ export const engineList = [
import * as middlewares from './middlewares';
export { middlewares };
export const middlewareList = [middlewares.Highlight];
export const middlewareList = [middlewares.Highlight, middlewares.HabrNav];
import { compile } from 'html-to-text';
export const html2text = compile({

View File

@ -1,3 +1,4 @@
import Highlight from './highlight';
import { HabrNav } from './navigation';
export { Highlight };
export { Highlight, HabrNav };

View File

@ -0,0 +1,27 @@
import { Middleware, JSX } from '@txtdot/sdk';
const HabrNav = new Middleware('Habr Nav', 'Adds navigation in habr pages', [
'habr.com',
]);
HabrNav.use(async (input, ro, out) => {
let nav = [...input.document.querySelectorAll('.tm-main-menu__item')];
return {
...out,
content: (
<>
<ul>
{nav.map((item) => (
<li>
<a href={item.getAttribute('href')}>{item.textContent}</a>
</li>
))}
</ul>
{out.content}
</>
),
};
});
export { HabrNav };

View File

@ -26,19 +26,18 @@
"@txtdot/plugins": "workspace:*",
"@txtdot/sdk": "workspace:*",
"axios": "^1.6.8",
"dompurify": "^3.1.2",
"dotenv": "^16.3.1",
"ejs": "^3.1.10",
"fastify": "^4.26.2",
"iconv-lite": "^0.6.3",
"ip-range-check": "^0.2.0",
"isomorphic-dompurify": "^2.10.0",
"json-schema-to-ts": "^3.0.1",
"linkedom": "^0.18.0",
"micromatch": "^4.0.5",
"sharp": "^0.33.3"
},
"devDependencies": {
"@types/dompurify": "^3.0.5",
"@types/ejs": "^3.1.5",
"@types/jsdom": "^21.1.6",
"@types/micromatch": "^4.0.7",

View File

@ -1,6 +1,5 @@
import axios, { oaxios } from './types/axios';
import micromatch from 'micromatch';
import DOMPurify from 'dompurify';
import { Readable } from 'stream';
import { NotHtmlMimetypeError } from './errors/main';
import { decodeStream, parseEncodingName } from './utils/http';
@ -11,6 +10,7 @@ import { HandlerInput, HandlerOutput } from '@txtdot/sdk';
import config from './config';
import { parseHTML } from 'linkedom';
import { html2text } from './utils/html2text';
import DOMPurify from 'isomorphic-dompurify';
interface IEngineId {
[key: string]: number;
@ -70,7 +70,15 @@ export class Distributor {
remoteUrl
);
const output = await engine.handle(input);
let output = await engine.handle(input);
// Sanitize output before middlewares, because middlewares can add unsafe tags
output = {
...output,
content: DOMPurify.sanitize(output.content),
};
output = await this.processMiddlewares(urlObj.hostname, input, output);
const dom = parseHTML(output.content);
@ -78,7 +86,6 @@ export class Distributor {
const stdTextContent = dom.document.documentElement.textContent;
// post-process
// TODO: generate dom in handler and not parse here twice
replaceHref(
dom.document,
requestUrl,
@ -87,28 +94,14 @@ export class Distributor {
redirectPath
);
const purify = DOMPurify(dom);
const purified_content = purify.sanitize(dom.document.toString());
const purified = {
...output,
content: purified_content,
};
const processed = await this.processMiddlewares(
urlObj.hostname,
input,
purified
);
const title = processed.title || dom.document.title;
const lang = processed.lang || dom.document.documentElement.lang;
const title = output.title || dom.document.title;
const lang = output.lang || dom.document.documentElement.lang;
const textContent =
html2text(stdTextContent, processed, title) ||
html2text(stdTextContent, output, title) ||
'Text output cannot be generated.';
return {
content: processed.content,
content: output.content,
textContent,
title,
lang,

229
pnpm-lock.yaml generated
View File

@ -97,9 +97,6 @@ importers:
axios:
specifier: ^1.6.8
version: 1.6.8
dompurify:
specifier: ^3.1.2
version: 3.1.3
dotenv:
specifier: ^16.3.1
version: 16.4.5
@ -115,6 +112,9 @@ importers:
ip-range-check:
specifier: ^0.2.0
version: 0.2.0
isomorphic-dompurify:
specifier: ^2.10.0
version: 2.10.0
json-schema-to-ts:
specifier: ^3.0.1
version: 3.1.0
@ -128,9 +128,6 @@ importers:
specifier: ^0.33.3
version: 0.33.3
devDependencies:
'@types/dompurify':
specifier: ^3.0.5
version: 3.0.5
'@types/ejs':
specifier: ^3.1.5
version: 3.1.5
@ -1149,10 +1146,18 @@ packages:
cssom@0.5.0:
resolution: {integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==}
cssstyle@4.0.1:
resolution: {integrity: sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==}
engines: {node: '>=18'}
dargs@7.0.0:
resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==}
engines: {node: '>=8'}
data-urls@5.0.0:
resolution: {integrity: sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==}
engines: {node: '>=18'}
dateformat@3.0.3:
resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==}
@ -1176,6 +1181,9 @@ packages:
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
engines: {node: '>=0.10.0'}
decimal.js@10.4.3:
resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==}
dedent@0.7.0:
resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==}
@ -1650,6 +1658,10 @@ packages:
resolution: {integrity: sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==}
engines: {node: ^16.14.0 || >=18.0.0}
html-encoding-sniffer@4.0.0:
resolution: {integrity: sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==}
engines: {node: '>=18'}
html-escaper@3.0.3:
resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
@ -1826,6 +1838,9 @@ packages:
resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
engines: {node: '>=0.10.0'}
is-potential-custom-element-name@1.0.1:
resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==}
is-ssh@1.4.0:
resolution: {integrity: sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==}
@ -1862,6 +1877,10 @@ packages:
resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==}
engines: {node: '>=0.10.0'}
isomorphic-dompurify@2.10.0:
resolution: {integrity: sha512-rqWVh1tZtHL4NsSn+bifrxhZ0CqNNShGEkV+m2SFLL3d4D4jcIbkSVMva5Eep50uCxiCCNJmCLGbuAWY/QoNcQ==}
engines: {node: '>=18'}
jackspeak@2.3.6:
resolution: {integrity: sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==}
engines: {node: '>=14'}
@ -1897,6 +1916,15 @@ packages:
jsbn@1.1.0:
resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==}
jsdom@24.0.0:
resolution: {integrity: sha512-UDS2NayCvmXSXVP6mpTj+73JnNQadZlr9N68189xib2tx5Mls7swlTNao26IoHv46BZJFvXygyRtyXd1feAk1A==}
engines: {node: '>=18'}
peerDependencies:
canvas: ^2.11.2
peerDependenciesMeta:
canvas:
optional: true
json-buffer@3.0.1:
resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
@ -2317,6 +2345,9 @@ packages:
nth-check@2.1.1:
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
nwsapi@2.2.10:
resolution: {integrity: sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==}
nx@18.3.4:
resolution: {integrity: sha512-7rOHRyxpnZGJ3pHnwmpoAMHt9hNuwibWhOhPBJDhJVcbQJtGfwcWWyV/iSEnVXwKZ2lfHVE3TwE+gXFdT/GFiw==}
hasBin: true
@ -2596,6 +2627,9 @@ packages:
engines: {node: '>= 0.10'}
hasBin: true
psl@1.9.0:
resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==}
pump@3.0.0:
resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==}
@ -2603,6 +2637,9 @@ packages:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
querystringify@2.2.0:
resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==}
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
@ -2693,6 +2730,9 @@ packages:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'}
requires-port@1.0.0:
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
resolve-cwd@3.0.0:
resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==}
engines: {node: '>=8'}
@ -2741,6 +2781,9 @@ packages:
resolution: {integrity: sha512-nsii+MXoNb7NyF05LP9kaktx6AoBVT/7zUgDnzIb5IoYAvYkbZOAuoLJjVdsyEVxWv0swCxWkKDK4cMva+WDBA==}
engines: {node: '>= 0.9'}
rrweb-cssom@0.6.0:
resolution: {integrity: sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==}
run-async@2.4.1:
resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==}
engines: {node: '>=0.12.0'}
@ -2767,6 +2810,10 @@ packages:
safer-buffer@2.1.2:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
saxes@6.0.0:
resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==}
engines: {node: '>=v12.22.7'}
secure-json-parse@2.7.0:
resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==}
@ -2969,6 +3016,9 @@ packages:
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
engines: {node: '>= 0.4'}
symbol-tree@3.2.4:
resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==}
tar-stream@2.2.0:
resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
engines: {node: '>=6'}
@ -3017,9 +3067,17 @@ packages:
resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==}
engines: {node: '>=0.6'}
tough-cookie@4.1.4:
resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==}
engines: {node: '>=6'}
tr46@0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
tr46@5.0.0:
resolution: {integrity: sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==}
engines: {node: '>=18'}
trim-newlines@3.0.1:
resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==}
engines: {node: '>=8'}
@ -3113,6 +3171,10 @@ packages:
universal-user-agent@6.0.1:
resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==}
universalify@0.2.0:
resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==}
engines: {node: '>= 4.0.0'}
universalify@2.0.1:
resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==}
engines: {node: '>= 10.0.0'}
@ -3128,6 +3190,9 @@ packages:
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
url-parse@1.5.10:
resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==}
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
@ -3145,12 +3210,32 @@ packages:
resolution: {integrity: sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
w3c-xmlserializer@5.0.0:
resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==}
engines: {node: '>=18'}
wcwidth@1.0.1:
resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==}
webidl-conversions@3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
webidl-conversions@7.0.0:
resolution: {integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==}
engines: {node: '>=12'}
whatwg-encoding@3.1.1:
resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==}
engines: {node: '>=18'}
whatwg-mimetype@4.0.0:
resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==}
engines: {node: '>=18'}
whatwg-url@14.0.0:
resolution: {integrity: sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==}
engines: {node: '>=18'}
whatwg-url@5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
@ -3204,6 +3289,25 @@ packages:
resolution: {integrity: sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA==}
engines: {node: '>=8'}
ws@8.17.0:
resolution: {integrity: sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==}
engines: {node: '>=10.0.0'}
peerDependencies:
bufferutil: ^4.0.1
utf-8-validate: '>=5.0.2'
peerDependenciesMeta:
bufferutil:
optional: true
utf-8-validate:
optional: true
xml-name-validator@5.0.0:
resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
engines: {node: '>=18'}
xmlchars@2.2.0:
resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==}
xtend@4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
@ -4408,8 +4512,17 @@ snapshots:
cssom@0.5.0: {}
cssstyle@4.0.1:
dependencies:
rrweb-cssom: 0.6.0
dargs@7.0.0: {}
data-urls@5.0.0:
dependencies:
whatwg-mimetype: 4.0.0
whatwg-url: 14.0.0
dateformat@3.0.3: {}
dateformat@4.6.3: {}
@ -4425,6 +4538,8 @@ snapshots:
decamelize@1.2.0: {}
decimal.js@10.4.3: {}
dedent@0.7.0: {}
deep-is@0.1.4: {}
@ -4944,6 +5059,10 @@ snapshots:
dependencies:
lru-cache: 10.2.2
html-encoding-sniffer@4.0.0:
dependencies:
whatwg-encoding: 3.1.1
html-escaper@3.0.3: {}
html-to-text@9.0.5:
@ -5139,6 +5258,8 @@ snapshots:
is-plain-object@5.0.0: {}
is-potential-custom-element-name@1.0.1: {}
is-ssh@1.4.0:
dependencies:
protocols: 2.0.1
@ -5165,6 +5286,17 @@ snapshots:
isobject@3.0.1: {}
isomorphic-dompurify@2.10.0:
dependencies:
'@types/dompurify': 3.0.5
dompurify: 3.1.3
jsdom: 24.0.0
transitivePeerDependencies:
- bufferutil
- canvas
- supports-color
- utf-8-validate
jackspeak@2.3.6:
dependencies:
'@isaacs/cliui': 8.0.2
@ -5202,6 +5334,34 @@ snapshots:
jsbn@1.1.0: {}
jsdom@24.0.0:
dependencies:
cssstyle: 4.0.1
data-urls: 5.0.0
decimal.js: 10.4.3
form-data: 4.0.0
html-encoding-sniffer: 4.0.0
http-proxy-agent: 7.0.2
https-proxy-agent: 7.0.4
is-potential-custom-element-name: 1.0.1
nwsapi: 2.2.10
parse5: 7.1.2
rrweb-cssom: 0.6.0
saxes: 6.0.0
symbol-tree: 3.2.4
tough-cookie: 4.1.4
w3c-xmlserializer: 5.0.0
webidl-conversions: 7.0.0
whatwg-encoding: 3.1.1
whatwg-mimetype: 4.0.0
whatwg-url: 14.0.0
ws: 8.17.0
xml-name-validator: 5.0.0
transitivePeerDependencies:
- bufferutil
- supports-color
- utf-8-validate
json-buffer@3.0.1: {}
json-parse-better-errors@1.0.2: {}
@ -5779,6 +5939,8 @@ snapshots:
dependencies:
boolbase: 1.0.0
nwsapi@2.2.10: {}
nx@18.3.4:
dependencies:
'@nrwl/tao': 18.3.4
@ -6116,6 +6278,8 @@ snapshots:
dependencies:
event-stream: 3.3.4
psl@1.9.0: {}
pump@3.0.0:
dependencies:
end-of-stream: 1.4.4
@ -6123,6 +6287,8 @@ snapshots:
punycode@2.3.1: {}
querystringify@2.2.0: {}
queue-microtask@1.2.3: {}
quick-format-unescaped@4.0.4: {}
@ -6232,6 +6398,8 @@ snapshots:
require-from-string@2.0.2: {}
requires-port@1.0.0: {}
resolve-cwd@3.0.0:
dependencies:
resolve-from: 5.0.0
@ -6269,6 +6437,8 @@ snapshots:
route-parser@0.0.5: {}
rrweb-cssom@0.6.0: {}
run-async@2.4.1: {}
run-parallel@1.2.0:
@ -6291,6 +6461,10 @@ snapshots:
safer-buffer@2.1.2: {}
saxes@6.0.0:
dependencies:
xmlchars: 2.2.0
secure-json-parse@2.7.0: {}
selderee@0.11.0:
@ -6513,6 +6687,8 @@ snapshots:
supports-preserve-symlinks-flag@1.0.0: {}
symbol-tree@3.2.4: {}
tar-stream@2.2.0:
dependencies:
bl: 4.1.0
@ -6561,8 +6737,19 @@ snapshots:
toidentifier@1.0.1: {}
tough-cookie@4.1.4:
dependencies:
psl: 1.9.0
punycode: 2.3.1
universalify: 0.2.0
url-parse: 1.5.10
tr46@0.0.3: {}
tr46@5.0.0:
dependencies:
punycode: 2.3.1
trim-newlines@3.0.1: {}
ts-algebra@2.0.0: {}
@ -6640,6 +6827,8 @@ snapshots:
universal-user-agent@6.0.1: {}
universalify@0.2.0: {}
universalify@2.0.1: {}
untildify@4.0.0: {}
@ -6650,6 +6839,11 @@ snapshots:
dependencies:
punycode: 2.3.1
url-parse@1.5.10:
dependencies:
querystringify: 2.2.0
requires-port: 1.0.0
util-deprecate@1.0.2: {}
uuid@9.0.1: {}
@ -6667,12 +6861,29 @@ snapshots:
dependencies:
builtins: 5.1.0
w3c-xmlserializer@5.0.0:
dependencies:
xml-name-validator: 5.0.0
wcwidth@1.0.1:
dependencies:
defaults: 1.0.4
webidl-conversions@3.0.1: {}
webidl-conversions@7.0.0: {}
whatwg-encoding@3.1.1:
dependencies:
iconv-lite: 0.6.3
whatwg-mimetype@4.0.0: {}
whatwg-url@14.0.0:
dependencies:
tr46: 5.0.0
webidl-conversions: 7.0.0
whatwg-url@5.0.0:
dependencies:
tr46: 0.0.3
@ -6740,6 +6951,12 @@ snapshots:
type-fest: 0.4.1
write-json-file: 3.2.0
ws@8.17.0: {}
xml-name-validator@5.0.0: {}
xmlchars@2.2.0: {}
xtend@4.0.2: {}
y18n@5.0.8: {}