Merge 374f71c859 into 0cb14f3f6c
commit
ef7fbe0e8b
|
|
@ -2,27 +2,14 @@ import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import styles from './Favicon.module.css';
|
import styles from './Favicon.module.css';
|
||||||
|
|
||||||
function getHostName(url) {
|
function Favicon({ url, ...props }) {
|
||||||
const match = url.match(/^(?:https?:\/\/)?(?:[^@\n]+@)?(?:www\.)?([^:/\n?=]+)/im);
|
const faviconUrl = url ? url : '/default-favicon.png';
|
||||||
return match && match.length > 1 ? match[1] : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Favicon({ domain, ...props }) {
|
return <img className={styles.favicon} src={faviconUrl} height="16" alt="" {...props} />;
|
||||||
const hostName = domain ? getHostName(domain) : null;
|
|
||||||
|
|
||||||
return hostName ? (
|
|
||||||
<img
|
|
||||||
className={styles.favicon}
|
|
||||||
src={`https://icons.duckduckgo.com/ip3/${hostName}.ico`}
|
|
||||||
height="16"
|
|
||||||
alt=""
|
|
||||||
{...props}
|
|
||||||
/>
|
|
||||||
) : null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Favicon.propTypes = {
|
Favicon.propTypes = {
|
||||||
domain: PropTypes.string,
|
url: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Favicon;
|
export default Favicon;
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ import styles from './WebsiteChart.module.css';
|
||||||
export default function WebsiteChart({
|
export default function WebsiteChart({
|
||||||
websiteId,
|
websiteId,
|
||||||
title,
|
title,
|
||||||
domain,
|
favicon,
|
||||||
stickyHeader = false,
|
stickyHeader = false,
|
||||||
showLink = false,
|
showLink = false,
|
||||||
showChart = true,
|
showChart = true,
|
||||||
|
|
@ -81,7 +81,7 @@ export default function WebsiteChart({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container}>
|
<div className={styles.container}>
|
||||||
<WebsiteHeader websiteId={websiteId} title={title} domain={domain} showLink={showLink} />
|
<WebsiteHeader websiteId={websiteId} title={title} favicon={favicon} showLink={showLink} />
|
||||||
<div className={classNames(styles.header, 'row')}>
|
<div className={classNames(styles.header, 'row')}>
|
||||||
<StickyHeader
|
<StickyHeader
|
||||||
className={classNames(styles.metrics, 'col row')}
|
className={classNames(styles.metrics, 'col row')}
|
||||||
|
|
|
||||||
|
|
@ -11,10 +11,10 @@ import ActiveUsers from './ActiveUsers';
|
||||||
import Arrow from 'assets/arrow-right.svg';
|
import Arrow from 'assets/arrow-right.svg';
|
||||||
import styles from './WebsiteHeader.module.css';
|
import styles from './WebsiteHeader.module.css';
|
||||||
|
|
||||||
export default function WebsiteHeader({ websiteId, title, domain, showLink = false }) {
|
export default function WebsiteHeader({ websiteId, title, favicon, showLink = false }) {
|
||||||
const header = showLink ? (
|
const header = showLink ? (
|
||||||
<>
|
<>
|
||||||
<Favicon domain={domain} />
|
<Favicon url={favicon} />
|
||||||
<Link
|
<Link
|
||||||
className={styles.titleLink}
|
className={styles.titleLink}
|
||||||
href="/website/[...id]"
|
href="/website/[...id]"
|
||||||
|
|
@ -25,7 +25,7 @@ export default function WebsiteHeader({ websiteId, title, domain, showLink = fal
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<Favicon domain={domain} />
|
<Favicon url={favicon} />
|
||||||
<OverflowText tooltipId={`${websiteId}-title`}>{title}</OverflowText>
|
<OverflowText tooltipId={`${websiteId}-title`}>{title}</OverflowText>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ export default function TestConsole() {
|
||||||
<WebsiteChart
|
<WebsiteChart
|
||||||
websiteId={website.website_id}
|
websiteId={website.website_id}
|
||||||
title={website.name}
|
title={website.name}
|
||||||
domain={website.domain}
|
favicon={website.favicon}
|
||||||
showLink
|
showLink
|
||||||
/>
|
/>
|
||||||
<PageHeader>Events</PageHeader>
|
<PageHeader>Events</PageHeader>
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ export default function WebsiteDetails({ websiteId }) {
|
||||||
<WebsiteChart
|
<WebsiteChart
|
||||||
websiteId={websiteId}
|
websiteId={websiteId}
|
||||||
title={data.name}
|
title={data.name}
|
||||||
domain={data.domain}
|
favicon={data.favicon}
|
||||||
onDataLoad={handleDataLoad}
|
onDataLoad={handleDataLoad}
|
||||||
showLink={false}
|
showLink={false}
|
||||||
stickyHeader
|
stickyHeader
|
||||||
|
|
|
||||||
|
|
@ -46,13 +46,13 @@ export default function WebsiteList({ websites, showCharts, limit }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{ordered.map(({ website_id, name, domain }, index) =>
|
{ordered.map(({ website_id, name, favicon }, index) =>
|
||||||
index < limit ? (
|
index < limit ? (
|
||||||
<div key={website_id} className={styles.website}>
|
<div key={website_id} className={styles.website}>
|
||||||
<WebsiteChart
|
<WebsiteChart
|
||||||
websiteId={website_id}
|
websiteId={website_id}
|
||||||
title={name}
|
title={name}
|
||||||
domain={domain}
|
favicon={favicon}
|
||||||
showChart={showCharts}
|
showChart={showCharts}
|
||||||
showLink
|
showLink
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -83,13 +83,13 @@ export default function WebsiteSettings() {
|
||||||
</ButtonLayout>
|
</ButtonLayout>
|
||||||
);
|
);
|
||||||
|
|
||||||
const DetailsLink = ({ website_id, name, domain }) => (
|
const DetailsLink = ({ website_id, name, favicon }) => (
|
||||||
<Link
|
<Link
|
||||||
className={styles.detailLink}
|
className={styles.detailLink}
|
||||||
href="/website/[...id]"
|
href="/website/[...id]"
|
||||||
as={`/website/${website_id}/${name}`}
|
as={`/website/${website_id}/${name}`}
|
||||||
>
|
>
|
||||||
<Favicon domain={domain} />
|
<Favicon url={favicon} />
|
||||||
<OverflowText tooltipId={`${website_id}-name`}>{name}</OverflowText>
|
<OverflowText tooltipId={`${website_id}-name`}>{name}</OverflowText>
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE `website` ADD COLUMN `favicon` VARCHAR(500) NULL;
|
||||||
|
|
@ -85,6 +85,7 @@ model website {
|
||||||
domain String? @db.VarChar(500)
|
domain String? @db.VarChar(500)
|
||||||
share_id String? @unique() @db.VarChar(64)
|
share_id String? @unique() @db.VarChar(64)
|
||||||
created_at DateTime? @default(now()) @db.Timestamp(0)
|
created_at DateTime? @default(now()) @db.Timestamp(0)
|
||||||
|
favicon String? @db.VarChar(500)
|
||||||
account account @relation(fields: [user_id], references: [user_id])
|
account account @relation(fields: [user_id], references: [user_id])
|
||||||
event event[]
|
event event[]
|
||||||
pageview pageview[]
|
pageview pageview[]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "website" ADD COLUMN "favicon" VARCHAR(500);
|
||||||
|
|
@ -85,6 +85,7 @@ model website {
|
||||||
domain String? @db.VarChar(500)
|
domain String? @db.VarChar(500)
|
||||||
share_id String? @unique @db.VarChar(64)
|
share_id String? @unique @db.VarChar(64)
|
||||||
created_at DateTime? @default(now()) @db.Timestamptz(6)
|
created_at DateTime? @default(now()) @db.Timestamptz(6)
|
||||||
|
favicon String? @db.VarChar(500)
|
||||||
account account @relation(fields: [user_id], references: [user_id])
|
account account @relation(fields: [user_id], references: [user_id])
|
||||||
event event[]
|
event event[]
|
||||||
pageview pageview[]
|
pageview pageview[]
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,64 @@
|
||||||
|
/**
|
||||||
|
* ISC License
|
||||||
|
* Copyright 2022 github.com/sudoaugustin/favecon
|
||||||
|
* Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
import fetch from 'node-fetch';
|
||||||
|
import { parse } from 'node-html-parser';
|
||||||
|
import { TimeoutController } from 'timeout-abort-controller';
|
||||||
|
|
||||||
|
const filterLinks = links => {
|
||||||
|
const attrs = ['rel', 'href', 'sizes'];
|
||||||
|
const filterAttrs = link =>
|
||||||
|
attrs.reduce((total, attr) => ({ ...total, [attr]: link.getAttribute(attr) }), {});
|
||||||
|
return [...links]
|
||||||
|
.filter(link => link.getAttribute('href') && link.getAttribute('rel').includes('icon'))
|
||||||
|
.map(filterAttrs);
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatValues = (url, icons) => {
|
||||||
|
const getOrigin = url => new URL(url).origin;
|
||||||
|
return icons.map(({ sizes, href, rel }) => ({
|
||||||
|
size: parseInt(sizes?.split('x')[0]) || undefined,
|
||||||
|
href: href[0] === '/' ? `${getOrigin(url)}${href}` : href,
|
||||||
|
rel,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchLinks = async url => {
|
||||||
|
// Time out the favicon request if it doesn't respond in a reasonable time.
|
||||||
|
const tc = new TimeoutController(3000);
|
||||||
|
|
||||||
|
let links = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
const html = await (await fetch(url, { signal: tc.signal })).text();
|
||||||
|
links = parse(html).querySelectorAll('head link');
|
||||||
|
} catch (e) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(`Could not fetch favicon for url ${url}`, e);
|
||||||
|
} finally {
|
||||||
|
tc.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
return links;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getIcons = async url => {
|
||||||
|
const links = await fetchLinks(url);
|
||||||
|
const icons = filterLinks(links);
|
||||||
|
return formatValues(url, icons);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default async domain => {
|
||||||
|
const icons = await getIcons(`https://${domain}`);
|
||||||
|
|
||||||
|
if (icons.length && icons.length > 0) {
|
||||||
|
return icons[0]?.href;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
@ -57,6 +57,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/inter": "4.5.7",
|
"@fontsource/inter": "4.5.7",
|
||||||
"@prisma/client": "4.3.1",
|
"@prisma/client": "4.3.1",
|
||||||
|
"abort-controller": "^3.0.0",
|
||||||
"chalk": "^4.1.1",
|
"chalk": "^4.1.1",
|
||||||
"chart.js": "^2.9.4",
|
"chart.js": "^2.9.4",
|
||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
|
|
@ -86,6 +87,7 @@
|
||||||
"next": "^12.2.5",
|
"next": "^12.2.5",
|
||||||
"next-basics": "^0.7.0",
|
"next-basics": "^0.7.0",
|
||||||
"node-fetch": "^3.2.8",
|
"node-fetch": "^3.2.8",
|
||||||
|
"node-html-parser": "^6.1.1",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^17.0.0",
|
"react": "^17.0.0",
|
||||||
|
|
@ -100,6 +102,7 @@
|
||||||
"request-ip": "^3.3.0",
|
"request-ip": "^3.3.0",
|
||||||
"semver": "^7.3.6",
|
"semver": "^7.3.6",
|
||||||
"thenby": "^1.3.4",
|
"thenby": "^1.3.4",
|
||||||
|
"timeout-abort-controller": "^3.0.0",
|
||||||
"timezone-support": "^2.0.2",
|
"timezone-support": "^2.0.2",
|
||||||
"uuid": "^8.3.2",
|
"uuid": "^8.3.2",
|
||||||
"zustand": "^3.7.2"
|
"zustand": "^3.7.2"
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { ok, unauthorized, methodNotAllowed, getRandomChars } from 'next-basics'
|
||||||
import { updateWebsite, createWebsite, getWebsiteById } from 'queries';
|
import { updateWebsite, createWebsite, getWebsiteById } from 'queries';
|
||||||
import { useAuth } from 'lib/middleware';
|
import { useAuth } from 'lib/middleware';
|
||||||
import { uuid } from 'lib/crypto';
|
import { uuid } from 'lib/crypto';
|
||||||
|
import getFavicon from 'lib/favicon';
|
||||||
|
|
||||||
export default async (req, res) => {
|
export default async (req, res) => {
|
||||||
await useAuth(req, res);
|
await useAuth(req, res);
|
||||||
|
|
@ -13,6 +14,8 @@ export default async (req, res) => {
|
||||||
const { name, domain, owner } = req.body;
|
const { name, domain, owner } = req.body;
|
||||||
const website_owner = parseInt(owner);
|
const website_owner = parseInt(owner);
|
||||||
|
|
||||||
|
const favicon = await getFavicon(domain);
|
||||||
|
|
||||||
if (website_id) {
|
if (website_id) {
|
||||||
const website = await getWebsiteById(website_id);
|
const website = await getWebsiteById(website_id);
|
||||||
|
|
||||||
|
|
@ -28,13 +31,19 @@ export default async (req, res) => {
|
||||||
share_id = null;
|
share_id = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
await updateWebsite(website_id, { name, domain, share_id, user_id: website_owner });
|
await updateWebsite(website_id, { name, domain, share_id, user_id: website_owner, favicon });
|
||||||
|
|
||||||
return ok(res);
|
return ok(res);
|
||||||
} else {
|
} else {
|
||||||
const website_uuid = uuid();
|
const website_uuid = uuid();
|
||||||
const share_id = enable_share_url ? getRandomChars(8) : null;
|
const share_id = enable_share_url ? getRandomChars(8) : null;
|
||||||
const website = await createWebsite(website_owner, { website_uuid, name, domain, share_id });
|
const website = await createWebsite(website_owner, {
|
||||||
|
website_uuid,
|
||||||
|
name,
|
||||||
|
domain,
|
||||||
|
share_id,
|
||||||
|
favicon,
|
||||||
|
});
|
||||||
|
|
||||||
return ok(res, website);
|
return ok(res, website);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
82
yarn.lock
82
yarn.lock
|
|
@ -1978,6 +1978,13 @@ JSONStream@1.3.4:
|
||||||
jsonparse "^1.2.0"
|
jsonparse "^1.2.0"
|
||||||
through ">=2.2.7 <3"
|
through ">=2.2.7 <3"
|
||||||
|
|
||||||
|
abort-controller@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
|
||||||
|
integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==
|
||||||
|
dependencies:
|
||||||
|
event-target-shim "^5.0.0"
|
||||||
|
|
||||||
acorn-dynamic-import@^4.0.0:
|
acorn-dynamic-import@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz"
|
resolved "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz"
|
||||||
|
|
@ -2674,6 +2681,17 @@ css-select@^4.1.3:
|
||||||
domutils "^2.8.0"
|
domutils "^2.8.0"
|
||||||
nth-check "^2.0.1"
|
nth-check "^2.0.1"
|
||||||
|
|
||||||
|
css-select@^5.1.0:
|
||||||
|
version "5.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6"
|
||||||
|
integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==
|
||||||
|
dependencies:
|
||||||
|
boolbase "^1.0.0"
|
||||||
|
css-what "^6.1.0"
|
||||||
|
domhandler "^5.0.2"
|
||||||
|
domutils "^3.0.1"
|
||||||
|
nth-check "^2.0.1"
|
||||||
|
|
||||||
css-tree@^1.1.2, css-tree@^1.1.3:
|
css-tree@^1.1.2, css-tree@^1.1.3:
|
||||||
version "1.1.3"
|
version "1.1.3"
|
||||||
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
|
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
|
||||||
|
|
@ -2682,7 +2700,7 @@ css-tree@^1.1.2, css-tree@^1.1.3:
|
||||||
mdn-data "2.0.14"
|
mdn-data "2.0.14"
|
||||||
source-map "^0.6.1"
|
source-map "^0.6.1"
|
||||||
|
|
||||||
css-what@^6.0.1:
|
css-what@^6.0.1, css-what@^6.1.0:
|
||||||
version "6.1.0"
|
version "6.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
|
resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
|
||||||
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
|
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
|
||||||
|
|
@ -2962,7 +2980,16 @@ dom-serializer@^1.0.1:
|
||||||
domhandler "^4.2.0"
|
domhandler "^4.2.0"
|
||||||
entities "^2.0.0"
|
entities "^2.0.0"
|
||||||
|
|
||||||
domelementtype@^2.0.1, domelementtype@^2.2.0:
|
dom-serializer@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53"
|
||||||
|
integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==
|
||||||
|
dependencies:
|
||||||
|
domelementtype "^2.3.0"
|
||||||
|
domhandler "^5.0.2"
|
||||||
|
entities "^4.2.0"
|
||||||
|
|
||||||
|
domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
|
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d"
|
||||||
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
|
integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==
|
||||||
|
|
@ -2974,6 +3001,13 @@ domhandler@^4.2.0, domhandler@^4.3.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
domelementtype "^2.2.0"
|
domelementtype "^2.2.0"
|
||||||
|
|
||||||
|
domhandler@^5.0.1, domhandler@^5.0.2:
|
||||||
|
version "5.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31"
|
||||||
|
integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==
|
||||||
|
dependencies:
|
||||||
|
domelementtype "^2.3.0"
|
||||||
|
|
||||||
domutils@^2.8.0:
|
domutils@^2.8.0:
|
||||||
version "2.8.0"
|
version "2.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
|
resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
|
||||||
|
|
@ -2983,6 +3017,15 @@ domutils@^2.8.0:
|
||||||
domelementtype "^2.2.0"
|
domelementtype "^2.2.0"
|
||||||
domhandler "^4.2.0"
|
domhandler "^4.2.0"
|
||||||
|
|
||||||
|
domutils@^3.0.1:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c"
|
||||||
|
integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==
|
||||||
|
dependencies:
|
||||||
|
dom-serializer "^2.0.0"
|
||||||
|
domelementtype "^2.3.0"
|
||||||
|
domhandler "^5.0.1"
|
||||||
|
|
||||||
dotenv@^10.0.0:
|
dotenv@^10.0.0:
|
||||||
version "10.0.0"
|
version "10.0.0"
|
||||||
resolved "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz"
|
resolved "https://registry.npmjs.org/dotenv/-/dotenv-10.0.0.tgz"
|
||||||
|
|
@ -3035,6 +3078,11 @@ entities@^2.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
|
resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
|
||||||
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
|
integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
|
||||||
|
|
||||||
|
entities@^4.2.0:
|
||||||
|
version "4.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174"
|
||||||
|
integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==
|
||||||
|
|
||||||
entities@^4.3.0:
|
entities@^4.3.0:
|
||||||
version "4.3.1"
|
version "4.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/entities/-/entities-4.3.1.tgz#c34062a94c865c322f9d67b4384e4169bcede6a4"
|
resolved "https://registry.yarnpkg.com/entities/-/entities-4.3.1.tgz#c34062a94c865c322f9d67b4384e4169bcede6a4"
|
||||||
|
|
@ -3357,6 +3405,11 @@ esutils@^2.0.2:
|
||||||
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
|
||||||
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
|
||||||
|
|
||||||
|
event-target-shim@^5.0.0:
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
|
||||||
|
integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==
|
||||||
|
|
||||||
execa@^5.1.1:
|
execa@^5.1.1:
|
||||||
version "5.1.1"
|
version "5.1.1"
|
||||||
resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz"
|
resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz"
|
||||||
|
|
@ -3791,6 +3844,11 @@ has@^1.0.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
function-bind "^1.1.1"
|
function-bind "^1.1.1"
|
||||||
|
|
||||||
|
he@1.2.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
|
||||||
|
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
|
||||||
|
|
||||||
hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
|
hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
|
||||||
version "3.3.2"
|
version "3.3.2"
|
||||||
resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz"
|
resolved "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz"
|
||||||
|
|
@ -4784,6 +4842,14 @@ node-fetch@^3.2.8:
|
||||||
fetch-blob "^3.1.4"
|
fetch-blob "^3.1.4"
|
||||||
formdata-polyfill "^4.0.10"
|
formdata-polyfill "^4.0.10"
|
||||||
|
|
||||||
|
node-html-parser@^6.1.1:
|
||||||
|
version "6.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-html-parser/-/node-html-parser-6.1.1.tgz#7f38f4427fafc242a22135d9db80c1455e837467"
|
||||||
|
integrity sha512-eYYblUeoMg0nR6cYGM4GRb1XncNa9FXEftuKAU1qyMIr6rXVtNyUKduvzZtkqFqSHVByq2lLjC7WO8tz7VDmnA==
|
||||||
|
dependencies:
|
||||||
|
css-select "^5.1.0"
|
||||||
|
he "1.2.0"
|
||||||
|
|
||||||
node-releases@^2.0.3:
|
node-releases@^2.0.3:
|
||||||
version "2.0.5"
|
version "2.0.5"
|
||||||
resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz"
|
resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.5.tgz"
|
||||||
|
|
@ -5838,6 +5904,11 @@ restore-cursor@^3.1.0:
|
||||||
onetime "^5.1.0"
|
onetime "^5.1.0"
|
||||||
signal-exit "^3.0.2"
|
signal-exit "^3.0.2"
|
||||||
|
|
||||||
|
retimer@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/retimer/-/retimer-3.0.0.tgz#98b751b1feaf1af13eb0228f8ea68b8f9da530df"
|
||||||
|
integrity sha512-WKE0j11Pa0ZJI5YIk0nflGI7SQsfl2ljihVy7ogh7DeQSeYAUi0ubZ/yEueGtDfUPk6GH5LRw1hBdLq4IwUBWA==
|
||||||
|
|
||||||
reusify@^1.0.4:
|
reusify@^1.0.4:
|
||||||
version "1.0.4"
|
version "1.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
|
||||||
|
|
@ -6426,6 +6497,13 @@ through@2.3.8, "through@>=2.2.7 <3", through@^2.3.8:
|
||||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||||
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
|
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
|
||||||
|
|
||||||
|
timeout-abort-controller@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/timeout-abort-controller/-/timeout-abort-controller-3.0.0.tgz#dd57ffca041652c03769904f8d95afd93fb95595"
|
||||||
|
integrity sha512-O3e+2B8BKrQxU2YRyEjC/2yFdb33slI22WRdUaDx6rvysfi9anloNZyR2q0l6LnePo5qH7gSM7uZtvvwZbc2yA==
|
||||||
|
dependencies:
|
||||||
|
retimer "^3.0.0"
|
||||||
|
|
||||||
timezone-support@^2.0.2:
|
timezone-support@^2.0.2:
|
||||||
version "2.0.2"
|
version "2.0.2"
|
||||||
resolved "https://registry.npmjs.org/timezone-support/-/timezone-support-2.0.2.tgz"
|
resolved "https://registry.npmjs.org/timezone-support/-/timezone-support-2.0.2.tgz"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue