From 44ee03c9e5eda52c1a7e93c0bdf22f35e24740b8 Mon Sep 17 00:00:00 2001 From: talksik Date: Thu, 28 Apr 2022 08:51:34 -0500 Subject: [PATCH] good progress with server and client back and forth - getting there slowly with console logs and understanding the steps along the way --- packages/api/index.ts | 7 +- packages/api/package.json | 3 +- packages/api/routes/rtc.ts | 78 +++++++++++ packages/web/package.json | 1 + packages/web/pages/rtc/index.tsx | 137 ++++++++++++++++++ yarn.lock | 230 ++++++++++++++++++++++++++++--- 6 files changed, 436 insertions(+), 20 deletions(-) create mode 100644 packages/api/routes/rtc.ts create mode 100644 packages/web/pages/rtc/index.tsx diff --git a/packages/api/index.ts b/packages/api/index.ts index 62881f6..be56347 100644 --- a/packages/api/index.ts +++ b/packages/api/index.ts @@ -6,6 +6,7 @@ import { UserService } from "./services/user.service"; import { UserStatus } from "@nirvana/core/models"; import cors from "cors"; import getConversationRoutes from "./routes/conversation"; +import getRtcRoutes from "./routes/rtc"; import getSearchRoutes from "./routes/search"; import getUserRoutes from "./routes/user"; @@ -23,12 +24,16 @@ app.get("/", (req: Request, res: Response) => { res.send("hello world."); }); +app.use("/api/rtc", getRtcRoutes()); + app.use("/api/user", getUserRoutes()); app.use("/api/search", getSearchRoutes()); app.use("/api/conversations", getConversationRoutes()); const PORT = 5000; -var server = app.listen(PORT, () => console.log("express running")); +var server = app.listen(PORT, () => + console.log(`express running on port ${PORT}`) +); // socket IO stuff diff --git a/packages/api/package.json b/packages/api/package.json index 8599526..1f00831 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -12,7 +12,8 @@ "google-auth-library": "^7.14.0", "jsonwebtoken": "^8.5.1", "mongodb": "^4.4.1", - "socket.io": "^4.4.1" + "socket.io": "^4.4.1", + "wrtc": "^0.4.7" }, "scripts": { "dev": "NODE_ENV=development nodemon", diff --git a/packages/api/routes/rtc.ts b/packages/api/routes/rtc.ts new file mode 100644 index 0000000..25dba32 --- /dev/null +++ b/packages/api/routes/rtc.ts @@ -0,0 +1,78 @@ +import express, { Application, Request, Response } from "express"; + +const webrtc = require("wrtc"); + +export default function getRtcRoutes() { + const router = express.Router(); + + router.use(express.json()); + + // get user details based on id token + router.post("/join/:lineId", handleJoin); + + return router; +} + +// a mapping between a certain line and the streams for it +const linesStreams: { + [lineId: string]: any[]; +} = {}; + +async function handleJoin(req: Request, res: Response) { + try { + const { lineId } = req.params; + const { sdp } = req.body; + + const peer = new webrtc.RTCPeerConnection({ + iceServers: [ + { + urls: "stun:stun.stunprotocol.org", + }, + ], + }); + + // allow this peer connection to receive other peoples' streams + peer.ontrack = (e: any) => handleStreams(e, peer, lineId); + + // allow this peer connection for this specific line to get tracks for this line already + linesStreams[lineId]?.forEach((stream: any) => { + stream.getTracks().forEach((track: any) => { + console.log(`have tracks in this line`, track, stream); + peer.addTrack(track, stream); + }); + }); + + // create connection between server and client who hit this endpoint + const desc = new webrtc.RTCSessionDescription(sdp); + await peer.setRemoteDescription(desc); + const answer = await peer.createAnswer(); + await peer.setLocalDescription(answer); + + const payload = { + sdp: peer.localDescription, + }; + + res + .status(200) + .json({ message: `You can now broadcast to ${lineId}!`, data: payload }); + } catch (error) { + console.log(error); + + res.status(500).json({ + message: "Problem in setting up peer connection with media server", + error, + }); + } +} + +function handleStreams(e: any, peer: any, lineId: string) { + // if the room/line exists already, then add to the list of streams + if (lineId in linesStreams) { + const newStreamsForLine = [...(linesStreams[lineId] ?? []), ...e.streams]; + + linesStreams[lineId] = newStreamsForLine; + } else { + // create a new list of streams + linesStreams[lineId] = [...e.streams]; + } +} diff --git a/packages/web/package.json b/packages/web/package.json index b6e76fb..3422dda 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@nirvana/components": "*", + "axios": "^0.27.2", "next": "12.1.4", "react": "^17.0.2", "react-dom": "^17.0.2", diff --git a/packages/web/pages/rtc/index.tsx b/packages/web/pages/rtc/index.tsx new file mode 100644 index 0000000..1f3df77 --- /dev/null +++ b/packages/web/pages/rtc/index.tsx @@ -0,0 +1,137 @@ +import { useEffect, useRef, useState } from "react"; + +import axios from "axios"; +import { toast } from "react-toastify"; + +const lines = ["line1", "line2", "line3", "line4", "line5"]; + +// todo: join different combinations of lines based on page params +// for now, every browser tab/client joins all 5 lines and streams to one specific one + +export default function VideoChat() { + const [selectedLine, setSelectedLine] = useState(lines[0]); + const videoRef = useRef(); + + // connect to media server for line connections as a broadcaster and consumer + useEffect(() => { + navigator.mediaDevices + .getUserMedia({ video: true, audio: true }) + .then((mediaStream: any) => { + console.log("mediaStream", mediaStream); + + if (videoRef.current) { + toast("got local user video stream"); + videoRef.current.srcObject = mediaStream; + videoRef.current.play(); + + // create a unique peer connection to server for each line + lines.forEach((lineId) => { + // create the peer and add the tranceiver + const peer = createPeer(lineId); + + console.log(`peer connection for ${lineId}`, peer); + + peer.addTransceiver("video"); + + mediaStream.getTracks().forEach((track: any) => { + console.log(`adding track to peer connection`); + peer.addTrack(track, mediaStream); + }); + }); + } + }); + }, [lines]); + + const createPeer = (lineId: string) => { + const peer = new RTCPeerConnection({ + iceServers: [ + { + urls: "stun:stun.stunprotocol.org", + }, + ], + }); + peer.ontrack = handleTrackEvent; + peer.onnegotiationneeded = () => handleNegotiationNeededEvent(peer, lineId); + + return peer; + }; + + const handleNegotiationNeededEvent = async ( + peer: RTCPeerConnection, + lineId: string + ) => { + // create offer + const offer = await peer.createOffer(); + await peer.setLocalDescription(offer); + const payload = { + sdp: peer.localDescription, + }; + + // send offer to server to accept + const { data } = await axios.post( + `http://localhost:5000/api/rtc/join/${lineId}`, + payload + ); + + // receive server acceptance and set remote configs + const desc = new RTCSessionDescription(data.data.sdp); + peer.setRemoteDescription(desc).catch((e) => console.log(e)); + + console.log(`done handling negotiation with media server`); + }; + + // render tracks on the server peer sending something + function handleTrackEvent(e: any) { + const incomingStream = e.streams[0]; + + console.log("incoming stream", e); + } + + return ( +
+

This is a baller video app

+ +
    +
  1. + - user joins 5 lines hardcoded lines (stream to and accept any streams + in those lines) +
  2. +
  3. - user can see which line certain content is coming from
  4. +
  5. - user can set medium: share screen or video (along with audio)
  6. +
  7. - user can select medium they want to send to
  8. +
  9. - user hold tilde to stream selected medium in a specific line
  10. +
  11. + - user can receive transmitted stream content from any line, and see + which line it's streamed to +
  12. +
+ +

Your Video

+ toggle medium (todo) +
+ ); +} diff --git a/yarn.lock b/yarn.lock index 18f877b..b0ac5c3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1649,6 +1649,11 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + "aproba@^1.0.3 || ^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" @@ -1662,6 +1667,14 @@ are-we-there-yet@^3.0.0: delegates "^1.0.0" readable-stream "^3.6.0" +are-we-there-yet@~1.1.2: + version "1.1.7" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" + integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + arg@^4.1.0: version "4.1.3" resolved "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz" @@ -1849,6 +1862,14 @@ axios@^0.26.1: dependencies: follow-redirects "^1.14.8" +axios@^0.27.2: + version "0.27.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972" + integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ== + dependencies: + follow-redirects "^1.14.9" + form-data "^4.0.0" + axobject-query@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" @@ -2243,6 +2264,11 @@ chokidar@^3.4.2, chokidar@^3.5.2, chokidar@^3.5.3: optionalDependencies: fsevents "~2.3.2" +chownr@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + chownr@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" @@ -2385,7 +2411,7 @@ colorette@^2.0.10: resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz" integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== -combined-stream@^1.0.6, combined-stream@~1.0.6: +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -2503,7 +2529,7 @@ connect-history-api-fallback@^1.6.0: resolved "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz" integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== -console-control-strings@^1.1.0: +console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control-strings@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= @@ -2721,7 +2747,7 @@ debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: dependencies: ms "2.1.2" -debug@^3.1.0, debug@^3.1.1, debug@^3.2.7: +debug@^3.1.0, debug@^3.1.1, debug@^3.2.6, debug@^3.2.7: version "3.2.7" resolved "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== @@ -2861,7 +2887,7 @@ destroy@~1.0.4: resolved "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz" integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= -detect-libc@^1.0.3: +detect-libc@^1.0.2, detect-libc@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= @@ -2975,6 +3001,13 @@ domelementtype@^2.0.1, domelementtype@^2.2.0: resolved "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz" integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== + dependencies: + webidl-conversions "^4.0.2" + domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.0: version "4.3.0" resolved "https://registry.npmjs.org/domhandler/-/domhandler-4.3.0.tgz" @@ -3951,7 +3984,7 @@ flora-colossus@^1.0.0: debug "^4.1.1" fs-extra "^7.0.0" -follow-redirects@^1.0.0, follow-redirects@^1.14.8: +follow-redirects@^1.0.0, follow-redirects@^1.14.8, follow-redirects@^1.14.9: version "1.14.9" resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz" integrity sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w== @@ -3980,6 +4013,15 @@ fork-ts-checker-webpack-plugin@^6.0.1: semver "^7.3.2" tapable "^1.0.0" +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -4050,6 +4092,13 @@ fs-extra@^9.0.0, fs-extra@^9.0.1: jsonfile "^6.0.1" universalify "^2.0.0" +fs-minipass@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -4110,6 +4159,20 @@ gauge@^4.0.0: strip-ansi "^6.0.1" wide-align "^1.1.5" +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + gaxios@^2.1.0: version "2.3.4" resolved "https://registry.npmjs.org/gaxios/-/gaxios-2.3.4.tgz" @@ -4509,7 +4572,7 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" -has-unicode@^2.0.1: +has-unicode@^2.0.0, has-unicode@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= @@ -4701,7 +4764,7 @@ humanize-ms@^1.2.1: dependencies: ms "^2.0.0" -iconv-lite@0.4.24, iconv-lite@^0.4.24: +iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== @@ -4730,6 +4793,13 @@ ignore-by-default@^1.0.1: resolved "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz" integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= +ignore-walk@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.4.tgz#c9a09f69b7c7b479a5d74ac1a3c0d4236d2a6335" + integrity sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ== + dependencies: + minimatch "^3.0.4" + ignore@^5.1.8, ignore@^5.2.0: version "5.2.0" resolved "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz" @@ -5777,6 +5847,14 @@ minipass-sized@^1.0.3: dependencies: minipass "^3.0.0" +minipass@^2.6.0, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: version "3.1.6" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee" @@ -5784,6 +5862,13 @@ minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: dependencies: yallist "^4.0.0" +minizlib@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + minizlib@^2.0.0, minizlib@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" @@ -5884,6 +5969,15 @@ natural-compare@^1.4.0: resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +needle@^2.2.1: + version "2.9.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.9.1.tgz#22d1dffbe3490c2b83e301f7709b6736cd8f2684" + integrity sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + negotiator@0.6.3, negotiator@^0.6.2: version "0.6.3" resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" @@ -5994,6 +6088,22 @@ node-loader@^2.0.0: dependencies: loader-utils "^2.0.0" +node-pre-gyp@^0.13.0: + version "0.13.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz#df9ab7b68dd6498137717838e4f92a33fc9daa42" + integrity sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + node-releases@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz" @@ -6015,6 +6125,14 @@ nodemon@^2.0.15: undefsafe "^2.0.5" update-notifier "^5.1.0" +nopt@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" + integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== + dependencies: + abbrev "1" + osenv "^0.1.4" + nopt@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" @@ -6059,6 +6177,13 @@ normalize-url@^6.0.1: resolved "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz" integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== +npm-bundled@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" + integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== + dependencies: + npm-normalize-package-bin "^1.0.1" + npm-conf@^1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz" @@ -6067,6 +6192,20 @@ npm-conf@^1.1.3: config-chain "^1.1.11" pify "^3.0.0" +npm-normalize-package-bin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" + integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== + +npm-packlist@^1.1.6: + version "1.4.8" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" + integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + npm-normalize-package-bin "^1.0.1" + npm-run-path@^2.0.0: version "2.0.2" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" @@ -6081,6 +6220,16 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + npmlog@^6.0.0: version "6.0.1" resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.1.tgz#06f1344a174c06e8de9c6c70834cfba2964bba17" @@ -6121,7 +6270,7 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4, object-assign@^4.1.1: +object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -6271,11 +6420,24 @@ ora@^5.0.0, ora@^5.1.0, ora@^5.4.1: strip-ansi "^6.0.0" wcwidth "^1.0.1" -os-tmpdir@~1.0.2: +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + p-cancelable@^1.0.0: version "1.1.0" resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz" @@ -7194,7 +7356,7 @@ rc-virtual-list@^3.2.0, rc-virtual-list@^3.4.2: rc-resize-observer "^1.0.0" rc-util "^5.0.7" -rc@^1.2.8: +rc@^1.2.7, rc@^1.2.8: version "1.2.8" resolved "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz" integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== @@ -7300,7 +7462,7 @@ read-pkg@^2.0.0: normalize-package-data "^2.3.2" path-type "^2.0.0" -readable-stream@^2.0.1, readable-stream@^2.2.2: +readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.2.2: version "2.3.7" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -7536,7 +7698,7 @@ rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" -rimraf@^2.6.3: +rimraf@^2.6.1, rimraf@^2.6.3: version "2.7.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== @@ -7586,7 +7748,7 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@^5.2.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -7603,6 +7765,11 @@ saslprep@^1.0.3: dependencies: sparse-bitfield "^3.0.3" +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + scheduler@^0.20.2: version "0.20.2" resolved "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz" @@ -7670,7 +7837,7 @@ semver-diff@^3.1.1: dependencies: semver "^6.3.0" -"semver@2 || 3 || 4 || 5", semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: version "5.7.1" resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -7743,7 +7910,7 @@ serve-static@1.14.2: parseurl "~1.3.3" send "0.17.2" -set-blocking@^2.0.0: +set-blocking@^2.0.0, set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= @@ -8090,7 +8257,7 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^3.0.0: +strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= @@ -8233,6 +8400,19 @@ tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: resolved "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== +tar@^4: + version "4.4.19" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" + integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== + dependencies: + chownr "^1.1.4" + fs-minipass "^1.2.7" + minipass "^2.9.0" + minizlib "^1.3.3" + mkdirp "^0.5.5" + safe-buffer "^5.2.1" + yallist "^3.1.1" + tar@^6.0.2, tar@^6.0.5, tar@^6.1.2: version "6.1.11" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" @@ -8734,6 +8914,11 @@ webidl-conversions@^3.0.0: resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" 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" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + webidl-conversions@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" @@ -8889,7 +9074,7 @@ which@^2.0.1, which@^2.0.2: dependencies: isexe "^2.0.0" -wide-align@^1.1.5: +wide-align@^1.1.0, wide-align@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== @@ -8946,6 +9131,15 @@ write-file-atomic@^3.0.0: signal-exit "^3.0.2" typedarray-to-buffer "^3.1.5" +wrtc@^0.4.7: + version "0.4.7" + resolved "https://registry.yarnpkg.com/wrtc/-/wrtc-0.4.7.tgz#c61530cd662713e50bffe64b7a78673ce070426c" + integrity sha512-P6Hn7VT4lfSH49HxLHcHhDq+aFf/jd9dPY7lDHeFhZ22N3858EKuwm2jmnlPzpsRGEPaoF6XwkcxY5SYnt4f/g== + dependencies: + node-pre-gyp "^0.13.0" + optionalDependencies: + domexception "^1.0.1" + ws@^7.4.6: version "7.5.7" resolved "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz" @@ -9013,7 +9207,7 @@ y18n@^5.0.5: resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^3.0.2: +yallist@^3.0.0, yallist@^3.0.2, yallist@^3.1.1: version "3.1.1" resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==