diff --git a/packages/www/components/editor.tsx b/packages/www/components/editor.tsx index 9ac170546..2ff8d1fbe 100644 --- a/packages/www/components/editor.tsx +++ b/packages/www/components/editor.tsx @@ -1,4 +1,5 @@ -import { TLDraw } from '@tldraw/tldraw' +import { TLDraw, TLDrawState, Data } from '@tldraw/tldraw' +import * as gtag from '-utils/gtag' import React from 'react' interface EditorProps { @@ -6,15 +7,26 @@ interface EditorProps { } export default function Editor({ id = 'home' }: EditorProps) { - const handleMount = React.useCallback((tlstate) => { + // Put the tlstate into the window, for debugging. + const handleMount = React.useCallback((tlstate: TLDrawState) => { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore window.tlstate = tlstate }, []) + // Send events to gtag as actions. + const handleChange = React.useCallback((_tlstate: TLDrawState, _state: Data, reason: string) => { + gtag.event({ + action: reason, + category: 'editor', + label: `page:${id}`, + value: 0, + }) + }, []) + return (
- +
) } diff --git a/packages/www/next.config.js b/packages/www/next.config.js index af4b6a360..526120117 100644 --- a/packages/www/next.config.js +++ b/packages/www/next.config.js @@ -1,14 +1,75 @@ /* eslint-disable @typescript-eslint/no-var-requires */ +const withPWA = require('next-pwa') +const SentryWebpackPlugin = require('@sentry/webpack-plugin') const withTM = require('next-transpile-modules')(['@tldraw/tldraw']) -const { NODE_ENV } = process.env +const { + GITHUB_ID, + GITHUB_SECRET, + GITHUB_API_SECRET, + NEXT_PUBLIC_SENTRY_DSN: SENTRY_DSN, + SENTRY_ORG, + SENTRY_PROJECT, + SENTRY_AUTH_TOKEN, + NODE_ENV, + VERCEL_GIT_COMMIT_SHA, + GA_MEASUREMENT_ID, +} = process.env + +process.env.SENTRY_DSN = SENTRY_DSN const isProduction = NODE_ENV === 'production' -module.exports = withTM({ - reactStrictMode: true, - pwa: { - disable: !isProduction, - dest: 'public', - }, -}) +const basePath = '' + +module.exports = withTM( + withPWA({ + reactStrictMode: true, + pwa: { + disable: !isProduction, + dest: 'public', + }, + productionBrowserSourceMaps: true, + env: { + NEXT_PUBLIC_COMMIT_SHA: VERCEL_GIT_COMMIT_SHA, + GA_MEASUREMENT_ID, + GITHUB_ID, + GITHUB_SECRET, + GITHUB_API_SECRET, + }, + webpack: (config, options) => { + if (!options.isServer) { + config.resolve.alias['@sentry/node'] = '@sentry/browser' + } + + config.plugins.push( + new options.webpack.DefinePlugin({ + 'process.env.NEXT_IS_SERVER': JSON.stringify(options.isServer.toString()), + }) + ) + + if ( + SENTRY_DSN && + SENTRY_ORG && + SENTRY_PROJECT && + SENTRY_AUTH_TOKEN && + VERCEL_GIT_COMMIT_SHA && + isProduction + ) { + config.plugins.push( + new SentryWebpackPlugin({ + include: '.next', + ignore: ['node_modules'], + stripPrefix: ['webpack://_N_E/'], + urlPrefix: `~${basePath}/_next`, + release: VERCEL_GIT_COMMIT_SHA, + authToken: SENTRY_AUTH_TOKEN, + org: SENTRY_PROJECT, + project: SENTRY_ORG, + }) + ) + } + return config + }, + }) +) diff --git a/packages/www/package.json b/packages/www/package.json index 087d9f4c7..54017aa5f 100644 --- a/packages/www/package.json +++ b/packages/www/package.json @@ -16,6 +16,10 @@ "lint": "next lint" }, "dependencies": { + "@sentry/integrations": "^6.13.2", + "@sentry/node": "^6.13.2", + "@sentry/react": "^6.13.2", + "@sentry/tracing": "^6.13.2", "@stitches/react": "^1.0.0", "@tldraw/tldraw": "^0.0.97", "next": "11.1.2", @@ -27,6 +31,7 @@ "react-dom": "17.0.2" }, "devDependencies": { + "@sentry/webpack-plugin": "^1.17.1", "@types/react": "^17.0.19", "@types/react-dom": "^17.0.9", "eslint": "7.32.0", diff --git a/packages/www/pages/_app.tsx b/packages/www/pages/_app.tsx index 1e1cec924..3ef1a969f 100644 --- a/packages/www/pages/_app.tsx +++ b/packages/www/pages/_app.tsx @@ -1,6 +1,12 @@ import '../styles/globals.css' +import { init } from '-utils/sentry' +import useGtag from '-utils/useGtag' + +init() function MyApp({ Component, pageProps }) { + useGtag() + return } diff --git a/packages/www/pages/_document.tsx b/packages/www/pages/_document.tsx index 34f37c5b7..c08bbdbf8 100644 --- a/packages/www/pages/_document.tsx +++ b/packages/www/pages/_document.tsx @@ -2,6 +2,10 @@ import NextDocument, { Html, Head, Main, NextScript, DocumentContext } from 'nex import { getCssText } from '../styles' import { GA_TRACKING_ID } from '../utils/gtag' +const APP_NAME = 'tldraw' +const APP_DESCRIPTION = 'A tiny little drawing app.' +const APP_URL = 'https://tldraw.com' + class MyDocument extends NextDocument { static async getInitialProps(ctx: DocumentContext): Promise<{ styles: JSX.Element @@ -28,10 +32,6 @@ class MyDocument extends NextDocument { } render(): JSX.Element { - const APP_NAME = 'tldraw' - const APP_DESCRIPTION = 'A tiny little drawing app.' - const APP_URL = 'https://tldraw.com' - return ( diff --git a/packages/www/utils/gtag.ts b/packages/www/utils/gtag.ts index e1a4c92aa..407fb7c02 100644 --- a/packages/www/utils/gtag.ts +++ b/packages/www/utils/gtag.ts @@ -10,7 +10,8 @@ type GTagEvent = { export const pageview = (url: URL): void => { if ('gtag' in window) { - ;(window as any)?.gtag('config', GA_TRACKING_ID, { + const win = window as any + win?.gtag('config', GA_TRACKING_ID, { page_path: url, }) } @@ -18,7 +19,8 @@ export const pageview = (url: URL): void => { export const event = ({ action, category, label, value }: GTagEvent): void => { if ('gtag' in window) { - ;(window as any)?.gtag('event', action, { + const win = window as any + win?.gtag('event', action, { event_category: category, event_label: label, value: value, diff --git a/packages/www/utils/sentry.ts b/packages/www/utils/sentry.ts new file mode 100644 index 000000000..1a4463bb2 --- /dev/null +++ b/packages/www/utils/sentry.ts @@ -0,0 +1,33 @@ +import * as Sentry from '@sentry/node' +import { RewriteFrames } from '@sentry/integrations' + +export function init(): void { + if (!process.env.NEXT_PUBLIC_SENTRY_DSN) return + + const integrations = [] + + if (process.env.NEXT_IS_SERVER === 'true' && process.env.NEXT_PUBLIC_SENTRY_SERVER_ROOT_DIR) { + // For Node.js, rewrite Error.stack to use relative paths, so that source + // maps starting with ~/_next map to files in Error.stack with path + // app:///_next + integrations.push( + new RewriteFrames({ + iteratee: (frame) => { + frame.filename = frame.filename.replace( + process.env.NEXT_PUBLIC_SENTRY_SERVER_ROOT_DIR, + 'app:///' + ) + frame.filename = frame.filename.replace('.next', '_next') + return frame + }, + }) + ) + } + + Sentry.init({ + enabled: process.env.NODE_ENV === 'production', + integrations, + dsn: process.env.NEXT_PUBLIC_SENTRY_DSN, + release: process.env.NEXT_PUBLIC_COMMIT_SHA, + }) +} diff --git a/packages/www/utils/useGtag.ts b/packages/www/utils/useGtag.ts new file mode 100644 index 000000000..a31f220ab --- /dev/null +++ b/packages/www/utils/useGtag.ts @@ -0,0 +1,20 @@ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +import router from 'next/router' +import { useEffect } from 'react' +import * as gtag from 'utils/gtag' + +function handleRouteChange(url: URL) { + gtag.pageview(url) +} + +export default function useGtag() { + useEffect(() => { + if (process.env.NODE_ENV !== 'production') return + + router.events.on('routeChangeComplete', handleRouteChange) + + return () => { + router.events.off('routeChangeComplete', handleRouteChange) + } + }, []) +} diff --git a/yarn.lock b/yarn.lock index 8a61b3b1c..5d6f98aa3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3557,6 +3557,125 @@ resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.0.6.tgz#023d72a5c4531b4ce204528971700a78a85a0c50" integrity sha512-Myxw//kzromB9yWgS8qYGuGVf91oBUUJpNvy5eM50sqvmKLbKjwLxohJnkWGTeeI9v9IBMtPLxz5Gc60FIfvCA== +"@sentry/browser@6.13.2": + version "6.13.2" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-6.13.2.tgz#8b731ecf8c3cdd92a4b6893a26f975fd5844056d" + integrity sha512-bkFXK4vAp2UX/4rQY0pj2Iky55Gnwr79CtveoeeMshoLy5iDgZ8gvnLNAz7om4B9OQk1u7NzLEa4IXAmHTUyag== + dependencies: + "@sentry/core" "6.13.2" + "@sentry/types" "6.13.2" + "@sentry/utils" "6.13.2" + tslib "^1.9.3" + +"@sentry/cli@^1.68.0": + version "1.68.0" + resolved "https://registry.yarnpkg.com/@sentry/cli/-/cli-1.68.0.tgz#2ced8fac67ee01e746a45e8ee45a518d4526937e" + integrity sha512-zc7+cxKDqpHLREGJKRH6KwE8fZW8bnczg3OLibJ0czleXoWPdAuOK1Xm1BTMcOnaXfg3VKAh0rI7S1PTdj+SrQ== + dependencies: + https-proxy-agent "^5.0.0" + mkdirp "^0.5.5" + node-fetch "^2.6.0" + npmlog "^4.1.2" + progress "^2.0.3" + proxy-from-env "^1.1.0" + +"@sentry/core@6.13.2": + version "6.13.2" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-6.13.2.tgz#2ce164f81667aa89cd116f807d772b4718434583" + integrity sha512-snXNNFLwlS7yYxKTX4DBXebvJK+6ikBWN6noQ1CHowvM3ReFBlrdrs0Z0SsSFEzXm2S4q7f6HHbm66GSQZ/8FQ== + dependencies: + "@sentry/hub" "6.13.2" + "@sentry/minimal" "6.13.2" + "@sentry/types" "6.13.2" + "@sentry/utils" "6.13.2" + tslib "^1.9.3" + +"@sentry/hub@6.13.2": + version "6.13.2" + resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-6.13.2.tgz#ebc66fd55c96c7686a53ffd3521b6a63f883bb79" + integrity sha512-sppSuJdNMiMC/vFm/dQowCBh11uTrmvks00fc190YWgxHshodJwXMdpc+pN61VSOmy2QA4MbQ5aMAgHzPzel3A== + dependencies: + "@sentry/types" "6.13.2" + "@sentry/utils" "6.13.2" + tslib "^1.9.3" + +"@sentry/integrations@^6.13.2": + version "6.13.2" + resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-6.13.2.tgz#906f2dd920439e5886f479a6da57f9c5d928f656" + integrity sha512-CzxMtNr4nkZbifD0Rb6tXwqfqm+fWKl4IQTaFrJ92VNdgihBMVWYmflRqkMkGh1iFN8bVPpXrGyplY5tFN+2kA== + dependencies: + "@sentry/types" "6.13.2" + "@sentry/utils" "6.13.2" + localforage "^1.8.1" + tslib "^1.9.3" + +"@sentry/minimal@6.13.2": + version "6.13.2" + resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-6.13.2.tgz#de3ecc62b9463bf56ccdbcf4c75f7ea1aeeebc11" + integrity sha512-6iJfEvHzzpGBHDfLxSHcGObh73XU1OSQKWjuhDOe7UQDyI4BQmTfcXAC+Fr8sm8C/tIsmpVi/XJhs8cubFdSMw== + dependencies: + "@sentry/hub" "6.13.2" + "@sentry/types" "6.13.2" + tslib "^1.9.3" + +"@sentry/node@^6.13.2": + version "6.13.2" + resolved "https://registry.yarnpkg.com/@sentry/node/-/node-6.13.2.tgz#6f5ee51eacad19b59e6ffb70b2d0e14396fd6233" + integrity sha512-0Vw22amG143MTiNaSny66YGU3+uW7HxyGI9TLGE7aJY1nNmC0DE+OgqQYGBRCrrPu+VFXRDxrOg9b15A1gKqjA== + dependencies: + "@sentry/core" "6.13.2" + "@sentry/hub" "6.13.2" + "@sentry/tracing" "6.13.2" + "@sentry/types" "6.13.2" + "@sentry/utils" "6.13.2" + cookie "^0.4.1" + https-proxy-agent "^5.0.0" + lru_map "^0.3.3" + tslib "^1.9.3" + +"@sentry/react@^6.13.2": + version "6.13.2" + resolved "https://registry.yarnpkg.com/@sentry/react/-/react-6.13.2.tgz#481f1549b1509b4d94eb943934ebeba6430a1a8f" + integrity sha512-aLkWyn697LTcmK1PPnUg5UJcyBUPoI68motqgBY53SIYDAwOeYNUQt2aanDuOTY5aE2PdnJwU48klA8vuYkoRQ== + dependencies: + "@sentry/browser" "6.13.2" + "@sentry/minimal" "6.13.2" + "@sentry/types" "6.13.2" + "@sentry/utils" "6.13.2" + hoist-non-react-statics "^3.3.2" + tslib "^1.9.3" + +"@sentry/tracing@6.13.2", "@sentry/tracing@^6.13.2": + version "6.13.2" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-6.13.2.tgz#512389ba459f48ae75e14f1528ab062dc46e4956" + integrity sha512-bHJz+C/nd6biWTNcYAu91JeRilsvVgaye4POkdzWSmD0XoLWHVMrpCQobGpXe7onkp2noU3YQjhqgtBqPHtnpw== + dependencies: + "@sentry/hub" "6.13.2" + "@sentry/minimal" "6.13.2" + "@sentry/types" "6.13.2" + "@sentry/utils" "6.13.2" + tslib "^1.9.3" + +"@sentry/types@6.13.2": + version "6.13.2" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-6.13.2.tgz#8388d5b92ea8608936e7aae842801dc90e0184e6" + integrity sha512-6WjGj/VjjN8LZDtqJH5ikeB1o39rO1gYS6anBxiS3d0sXNBb3Ux0pNNDFoBxQpOhmdDHXYS57MEptX9EV82gmg== + +"@sentry/utils@6.13.2": + version "6.13.2" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-6.13.2.tgz#fb8010e7b67cc8c084d8067d64ef25289269cda5" + integrity sha512-foF4PbxqPMWNbuqdXkdoOmKm3quu3PP7Q7j/0pXkri4DtCuvF/lKY92mbY0V9rHS/phCoj+3/Se5JvM2ymh2/w== + dependencies: + "@sentry/types" "6.13.2" + tslib "^1.9.3" + +"@sentry/webpack-plugin@^1.17.1": + version "1.17.1" + resolved "https://registry.yarnpkg.com/@sentry/webpack-plugin/-/webpack-plugin-1.17.1.tgz#1b3ebbe9991e4d77125ace2b24594059a088268a" + integrity sha512-L47a0hxano4a+9jbvQSBzHCT1Ph8fYAvGGUvFg8qc69yXS9si5lXRNIH/pavN6mqJjhQjAcEsEp+vxgvT4xZDQ== + dependencies: + "@sentry/cli" "^1.68.0" + "@sinonjs/commons@^1.7.0": version "1.8.3" resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d" @@ -5542,6 +5661,11 @@ convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: dependencies: safe-buffer "~5.1.1" +cookie@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== + copy-concurrently@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" @@ -7428,7 +7552,7 @@ hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" -hoist-non-react-statics@^3.1.0: +hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== @@ -7604,6 +7728,11 @@ image-size@1.0.0: dependencies: queue "6.0.2" +immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha1-nbHb0Pr43m++D13V5Wu2BigN5ps= + import-fresh@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-2.0.0.tgz#d81355c15612d386c61f9ddd3922d4304822a546" @@ -8985,6 +9114,13 @@ libnpmpublish@^4.0.0: semver "^7.1.3" ssri "^8.0.1" +lie@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" + integrity sha1-mkNrLMd0bKWd56QfpGmz77dr2H4= + dependencies: + immediate "~3.0.5" + lines-and-columns@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" @@ -9050,6 +9186,13 @@ loader-utils@^1.4.0: emojis-list "^3.0.0" json5 "^1.0.1" +localforage@^1.8.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4" + integrity sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg== + dependencies: + lie "3.1.1" + locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" @@ -9207,6 +9350,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lru_map@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" + integrity sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0= + lunr@^2.3.9: version "2.3.9" resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" @@ -9904,6 +10052,13 @@ node-fetch@^2.5.0, node-fetch@^2.6.1: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.2.tgz#986996818b73785e47b1965cc34eb093a1d464d0" integrity sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA== +node-fetch@^2.6.0: + version "2.6.4" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.4.tgz#7f1d13b8f9ff0c1a994dc6f73c69f7d652c7ace2" + integrity sha512-aD1fO+xtLiSCc9vuD+sYMxpIuQyhHscGSkBEo2o5LTV/3bTEAYvdUii29n8LlO5uLCmWdGP7uVUVXFo5SRdkLA== + dependencies: + whatwg-url "^5.0.0" + node-gyp@^5.0.2: version "5.1.1" resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.1.1.tgz#eb915f7b631c937d282e33aed44cb7a025f62a3e" @@ -10916,7 +11071,7 @@ process@0.11.10, process@^0.11.10: resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI= -progress@^2.0.0: +progress@^2.0.0, progress@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== @@ -10983,6 +11138,11 @@ protoduck@^5.0.1: dependencies: genfun "^5.0.0" +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + psl@^1.1.28, psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" @@ -12839,6 +12999,11 @@ tr46@^2.1.0: dependencies: punycode "^2.1.1" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= + tree-kill@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" @@ -13388,6 +13553,11 @@ wcwidth@^1.0.0: dependencies: defaults "^1.0.3" +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE= + webidl-conversions@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" @@ -13423,6 +13593,14 @@ whatwg-mimetype@^2.3.0: resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0= + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + whatwg-url@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06"