From be43c163dc30b7c2aca7e0415e94f7858a97cefe Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Sat, 18 Sep 2021 09:25:59 -0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=8C=20Socket=20+=20RabbitMQ=20setup=20?= =?UTF-8?q?for=20download-client=20touched=20folders/files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 4 +- src/client/actions/fileops.actions.tsx | 31 ++----- src/client/assets/scss/App.scss | 9 ++ src/client/components/App.tsx | 16 +++- src/client/components/ComicDetail.tsx | 20 ++++- src/client/components/Import.tsx | 53 ++++++++++- src/client/context/socket/socket.context.tsx | 37 ++++++++ src/client/index.tsx | 11 ++- src/client/reducers/fileops.reducer.ts | 5 +- .../shared/utils/tradepaperback.utils.ts | 5 +- src/server/index.ts | 32 ++++++- .../route/routes/importComics.routes.ts | 38 +------- yarn.lock | 90 +++++++++++++++++-- 13 files changed, 265 insertions(+), 86 deletions(-) create mode 100644 src/client/context/socket/socket.context.tsx diff --git a/package.json b/package.json index 81d45c1..c297c15 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,6 @@ "babel-polyfill": "^6.26.0", "better-docs": "^2.3.2", "calibre-opds": "^1.0.7", - "chokidar": "^3.5.2", "comlink-loader": "^2.0.0", "compromise": "^13.11.3", "compromise-dates": "^2.2.1", @@ -56,6 +55,7 @@ "react-dom": "^17.0.1", "react-fast-compare": "^3.2.0", "react-final-form": "^6.5.3", + "react-lazylog": "^4.5.3", "react-loader-spinner": "^4.0.0", "react-notification-system": "^0.4.0", "react-notification-system-redux": "^2.0.1", @@ -65,7 +65,7 @@ "react-window-dynamic-list": "^2.3.5", "sharp": "^0.28.1", "socket.io-client": "^4.1.2", - "threetwo-ui-typings": "^1.0.3", + "threetwo-ui-typings": "^1.0.5", "voca": "^1.4.0", "websocket": "^1.0.34", "ws": "^7.5.3", diff --git a/src/client/actions/fileops.actions.tsx b/src/client/actions/fileops.actions.tsx index b34057b..82e59e5 100644 --- a/src/client/actions/fileops.actions.tsx +++ b/src/client/actions/fileops.actions.tsx @@ -1,4 +1,5 @@ import axios from "axios"; +import { useContext } from "react"; import { IFolderData, IExtractedComicBookCoverFile } from "threetwo-ui-typings"; import { API_BASE_URI, SOCKET_BASE_URI } from "../constants/endpoints"; import { @@ -15,14 +16,8 @@ import { } from "../constants/action-types"; import { refineQuery } from "../shared/utils/filenameparser.utils"; import sortBy from "array-sort-by"; -import { io } from "socket.io-client"; -import { - success, - error, - warning, - info, - removeAll, -} from "react-notification-system-redux"; +import { success } from "react-notification-system-redux"; +import { WebSocketContext } from "../context/socket/socket.context"; export async function walkFolder(path: string): Promise> { return axios @@ -51,24 +46,8 @@ export async function walkFolder(path: string): Promise> { * @return {Promise} HTML of the page */ export const fetchComicBookMetadata = (options) => async (dispatch) => { - const socket = io(SOCKET_BASE_URI, { - reconnectionDelayMax: 10000, - secure: false, - rejectUnauthorized: false, - }); - socket.on("connect", () => { - console.log(`connect ${socket.id}`); - dispatch({ - type: RMQ_SOCKET_CONNECTED, - isSocketConnected: true, - socketId: socket.id, - }); - }); - socket.on("disconnect", () => { - console.log(`disconnect`); - }); + const socket = useContext(WebSocketContext); const extractionOptions = { - sourceFolder: options, extractTarget: "cover", targetExtractionFolder: "./userdata/covers", extractionMode: "bulk", @@ -82,7 +61,7 @@ export const fetchComicBookMetadata = (options) => async (dispatch) => { success({ // uid: 'once-please', // you can specify your own uid if required title: "Import Started", - message: `${socket.id} connected. ${walkedFolders.length} comics scanned.`, + message: ` Socket ${socket.id} connected. ${walkedFolders.length} comics scanned.`, dismissible: "click", position: "tr", autoDismiss: 0, diff --git a/src/client/assets/scss/App.scss b/src/client/assets/scss/App.scss index a9e24de..52486e1 100644 --- a/src/client/assets/scss/App.scss +++ b/src/client/assets/scss/App.scss @@ -28,6 +28,15 @@ $border-color: red; .min { overflow: visible; + margin: auto; + .tag__custom { + height: auto !important; + padding: 0.3rem; + white-space: unset !important; + width: 100%; + background-color: #effaf5; + color: #257953; + } .tags { display: inline; margin-right: 5px; diff --git a/src/client/components/App.tsx b/src/client/components/App.tsx index 6d4ec9c..b4e240f 100644 --- a/src/client/components/App.tsx +++ b/src/client/components/App.tsx @@ -29,6 +29,19 @@ const style = { }, tr: { top: "40px", + right: "10px", + }, + }, + Title: { + DefaultStyle: { + fontSize: "14px", + margin: "0 0 5px 0", + padding: 0, + fontWeight: "bold", + }, + + success: { + color: "hsl(141, 71%, 48%)", }, }, NotificationItem: { @@ -36,7 +49,7 @@ const style = { success: { // Applied to every notification, regardless of the notification level borderTop: "none", - backgroundColor: "none", + backgroundColor: "#FFF", borderRadius: "0.4rem", WebkitBoxShadow: "-7px 11px 25px -9px rgba(0, 0, 0, 0.3)", MozBoxShadow: "-7px 11px 25px -9px rgba(0, 0, 0, 0.3)", @@ -53,6 +66,7 @@ export const App = (): ReactElement => { notifications={notifications} style={style} newOnTop={true} + allowHTML={true} /> diff --git a/src/client/components/ComicDetail.tsx b/src/client/components/ComicDetail.tsx index 46aecf6..d8c1fc0 100644 --- a/src/client/components/ComicDetail.tsx +++ b/src/client/components/ComicDetail.tsx @@ -213,10 +213,26 @@ export const ComicDetail = ({}: ComicDetailProps): ReactElement => {
Raw File Details
{props.data.containedIn}
-
{prettyBytes(props.data.fileSize)}
{props.data.path}
- {props.data.extension} +
+
+
+ Size + + {prettyBytes(props.data.fileSize)} + +
+
+
+
+ Extension + + {props.data.extension} + +
+
+
diff --git a/src/client/components/Import.tsx b/src/client/components/Import.tsx index 952bd72..73742c9 100644 --- a/src/client/components/Import.tsx +++ b/src/client/components/Import.tsx @@ -1,10 +1,12 @@ import React, { ReactElement, useCallback } from "react"; -import { isNil, isUndefined } from "lodash"; +import { isEmpty, isNil, isUndefined } from "lodash"; import { useSelector, useDispatch } from "react-redux"; import { fetchComicBookMetadata } from "../actions/fileops.actions"; import { IFolderData } from "threetwo-ui-typings"; +import { LazyLog, ScrollFollow } from "react-lazylog"; import DynamicList, { createCache } from "react-window-dynamic-list"; -; +import "react-loader-spinner/dist/loader/css/react-spinner-loader.css"; +import Loader from "react-loader-spinner"; interface IProps { matches?: unknown; @@ -32,13 +34,27 @@ export const Import = (props: IProps): ReactElement => { console.log(state); return state.fileOps.isSocketConnected; }); - + const importResults = useSelector( + (state: RootState) => state.fileOps.comicBookMetadata, + ); + const IMSCallInProgress = useSelector( + (state: RootState) => state.fileOps.IMSCallInProgress, + ); const initiateImport = useCallback(() => { if (typeof props.path !== "undefined") { console.log("asdasd"); dispatch(fetchComicBookMetadata(props.path)); } }, [dispatch]); + const cache = createCache(); + const renderRow = ({ index, style }) => ( +
  • + {importResults[index].comicBookCoverMetadata.name} +
    + {importResults[index].comicBookCoverMetadata.path} +
    +
  • + ); return (
    @@ -78,6 +94,37 @@ export const Import = (props: IProps): ReactElement => { Import and Tag

    + + {!isEmpty(importResults) ? ( + <> +

    Import Results

    +
    +
      + + {renderRow} + +
    + + ) : ( +
    +
    + +
    +
    + )}
    ); diff --git a/src/client/context/socket/socket.context.tsx b/src/client/context/socket/socket.context.tsx new file mode 100644 index 0000000..1284d33 --- /dev/null +++ b/src/client/context/socket/socket.context.tsx @@ -0,0 +1,37 @@ +import React, { createContext } from "react"; +import io, { Socket } from "socket.io-client"; +import { SOCKET_BASE_URI } from "../../constants/endpoints"; +import { useDispatch } from "react-redux"; +import { RMQ_SOCKET_CONNECTED } from "../../constants/action-types"; + +const WebSocketContext = createContext(null); +export const WebSocketProvider = ({ children }) => { + let socket: Socket; + let ws; + const dispatch = useDispatch(); + + if (!socket) { + socket = io(SOCKET_BASE_URI); + + socket.on("connect", () => { + dispatch({ + type: RMQ_SOCKET_CONNECTED, + isSocketConnected: true, + socketId: socket.id, + }); + }); + socket.on("disconnect", () => { + console.log(`disconnect`); + }); + + ws = { + socket: socket, + }; + } + + return ( + {children} + ); +}; +export { WebSocketContext }; +export default WebSocketProvider; diff --git a/src/client/index.tsx b/src/client/index.tsx index 7dcb563..9a3fd9c 100644 --- a/src/client/index.tsx +++ b/src/client/index.tsx @@ -2,6 +2,9 @@ import * as React from "react"; import { render } from "react-dom"; import { Provider } from "react-redux"; import { ConnectedRouter } from "connected-react-router"; +import WebSocketProvider, { + WebSocketContext, +} from "./context/socket/socket.context"; import configureStore, { history } from "./store/index"; import App from "./components/App"; @@ -10,9 +13,11 @@ const rootEl = document.getElementById("root"); render( - - - + + + + + , rootEl, ); diff --git a/src/client/reducers/fileops.reducer.ts b/src/client/reducers/fileops.reducer.ts index 85c632d..c35ed4d 100644 --- a/src/client/reducers/fileops.reducer.ts +++ b/src/client/reducers/fileops.reducer.ts @@ -12,7 +12,7 @@ import { IMS_CV_METADATA_IMPORT_CALL_IN_PROGRESS, } from "../constants/action-types"; const initialState = { - dataTransferred: false, + IMSCallInProgress: false, comicBookMetadata: [], isSocketConnected: false, isComicVineMetadataImportInProgress: false, @@ -26,7 +26,7 @@ function fileOpsReducer(state = initialState, action) { return { ...state, comicBookMetadata: [...state.comicBookMetadata, action.data], - dataTransferred: true, + IMSCallInProgress: false, }; case RMQ_SOCKET_CONNECTED: @@ -34,6 +34,7 @@ function fileOpsReducer(state = initialState, action) { ...state, isSocketConnected: action.isSocketConnected, socketId: action.socketId, + IMSCallInProgress: true, }; case IMS_RAW_IMPORT_SUCCESSFUL: return { diff --git a/src/client/shared/utils/tradepaperback.utils.ts b/src/client/shared/utils/tradepaperback.utils.ts index ee7aa54..dcd1a11 100644 --- a/src/client/shared/utils/tradepaperback.utils.ts +++ b/src/client/shared/utils/tradepaperback.utils.ts @@ -4,9 +4,10 @@ export const detectTradePaperbacks = (deck): any => { const paperback = [ /((trade)?\s?(paperback)|(tpb))/gim, // https://regex101.com/r/FhuowT/1 /(hard\s?cover)\s?(collect((ion)|(ed)|(ing)))/gim, //https://regex101.com/r/eFJVRM/1 - /(collected\s?editions)/gim, // https://regex101.com/r/40pAm5/1 - /(?:collects|issues|issue)/gim, ]; + const miniSeries = [ + + ] const matches = paperback .map((regex) => { return deck.match(regex); diff --git a/src/server/index.ts b/src/server/index.ts index 2c4d154..61630f7 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -1,8 +1,9 @@ import express, { Request, Response, Router, Express } from "express"; import bodyParser from "body-parser"; import { createServer } from "http"; -import { Server, Socket } from "socket.io"; +import { Server } from "socket.io"; import router from "./route"; +const amqp = require("amqplib/callback_api"); // call express const app: Express = express(); // define our app using express @@ -42,6 +43,35 @@ io.on("connection", (socket) => { }); }); +amqp.connect("amqp://localhost", (error0, connection) => { + if (error0) { + throw error0; + } + connection.createChannel((error1, channel) => { + if (error1) { + throw error1; + } + const queue = "comicBookCovers"; + channel.assertQueue(queue, { + durable: false, + }); + + console.log(`Connected to ${queue} queue.`); + console.log(`Waiting for comic book cover data in ${queue}`); + + channel.consume( + queue, + (data) => { + //Socket Trigger All Clients + io.sockets.emit("coverExtracted", JSON.parse(data.content.toString())); + }, + { + noAck: true, + }, + ); + }); +}); + // socket server httpServer.listen(8051); console.log(`Socket server is listening on 8051`); diff --git a/src/server/route/routes/importComics.routes.ts b/src/server/route/routes/importComics.routes.ts index ade8f77..d3d0f30 100644 --- a/src/server/route/routes/importComics.routes.ts +++ b/src/server/route/routes/importComics.routes.ts @@ -1,8 +1,6 @@ import router from "../router"; import { Request, Response } from "express"; -const amqp = require("amqplib/callback_api"); import axios from "axios"; -import { io } from "../../index"; router.route("/getComicCovers").post(async (req: Request, res: Response) => { typeof req.body === "object" ? req.body : {}; @@ -14,41 +12,7 @@ router.route("/getComicCovers").post(async (req: Request, res: Response) => { walkedFolders: req.body.walkedFolders, }, }); - const queueConsumer = amqp.connect( - "amqp://localhost", - (error0, connection) => { - if (error0) { - throw error0; - } - connection.createChannel((error1, channel) => { - if (error1) { - throw error1; - } - const queue = "comicBookCovers"; - channel.assertQueue(queue, { - durable: false, - }); - - console.log(`Connected to ${queue} queue.`); - console.log(`Waiting for comic book cover data in ${queue}`); - - channel.consume( - queue, - (data) => { - //Socket Trigger All Clients - io.sockets.emit( - "coverExtracted", - JSON.parse(data.content.toString()), - ); - }, - { - noAck: true, - }, - ); - }); - }, - ); - res.send({ queue: queueConsumer }); + res.send({ po: "jo" }); }); export default router; diff --git a/yarn.lock b/yarn.lock index 7b4317d..b5c210d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -978,7 +978,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.12.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7": +"@babel/runtime@^7.12.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.7": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a" integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw== @@ -1338,6 +1338,13 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@mattiasbuelens/web-streams-polyfill@^0.2.0": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@mattiasbuelens/web-streams-polyfill/-/web-streams-polyfill-0.2.1.tgz#d7c4aa94f98084ec0787be084d47167d62ea5f67" + integrity sha512-oKuFCQFa3W7Hj7zKn0+4ypI8JFm4ZKIoncwAC6wd5WwFW2sL7O1hpPoJdSWpynQ4DJ4lQ6MvFoVDmCLilonDFg== + dependencies: + "@types/whatwg-streams" "^0.0.7" + "@nicolo-ribaudo/chokidar-2@2.1.8-no-fsevents.2": version "2.1.8-no-fsevents.2" resolved "https://registry.npmjs.org/@nicolo-ribaudo/chokidar-2/-/chokidar-2-2.1.8-no-fsevents.2.tgz" @@ -1965,6 +1972,11 @@ dependencies: "@types/node" "*" +"@types/whatwg-streams@^0.0.7": + version "0.0.7" + resolved "https://registry.yarnpkg.com/@types/whatwg-streams/-/whatwg-streams-0.0.7.tgz#28bfe73dc850562296367249c4b32a50db81e9d3" + integrity sha512-6sDiSEP6DWcY2ZolsJ2s39ZmsoGQ7KVwBDI3sESQsEm9P2dHTcqnDIHRZFRNtLCzWp7hCFGqYbw5GyfpQnJ01A== + "@types/yargs-parser@*": version "20.2.1" resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.1.tgz" @@ -3657,7 +3669,7 @@ chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" -chokidar@^3.4.0, chokidar@^3.5.2: +chokidar@^3.4.0: version "3.5.2" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ== @@ -3827,6 +3839,11 @@ clone@^1.0.2: resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= +clsx@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" + integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== + cmd-shim@^4.0.1: version "4.1.0" resolved "https://registry.npmjs.org/cmd-shim/-/cmd-shim-4.1.0.tgz" @@ -4738,7 +4755,7 @@ dom-converter@^0.2.0: dependencies: utila "~0.4" -dom-helpers@^5.0.1: +dom-helpers@^5.0.1, dom-helpers@^5.1.3: version "5.2.1" resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== @@ -5728,6 +5745,11 @@ fd-slicer@~1.1.0: dependencies: pend "~1.2.0" +fetch-readablestream@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/fetch-readablestream/-/fetch-readablestream-0.2.0.tgz#eaa6d1a76b12de2d4731a343393c6ccdcfe2c795" + integrity sha512-qu4mXWf4wus4idBIN/kVH+XSer8IZ9CwHP+Pd7DL7TuKNC1hP7ykon4kkBjwJF3EMX2WsFp4hH7gU7CyL7ucXw== + figures@^1.3.5: version "1.7.0" resolved "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz" @@ -6867,6 +6889,11 @@ imagemin@^7.0.1: resolved "https://registry.npmjs.org/immutable/-/immutable-4.0.0-rc.14.tgz" integrity sha512-pfkvmRKJSoW7JFx0QeYlAmT+kNYvn5j0u7bnpNq4N2RCvHSTlLT208G8jgaquNe+Q8kCPHKOSpxJkyvLDpYq0w== +immutable@^3.8.2: + version "3.8.2" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3" + integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM= + import-fresh@^3.0.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz" @@ -8961,6 +8988,11 @@ minizlib@^2.0.0, minizlib@^2.1.1: minipass "^3.0.0" yallist "^4.0.0" +mitt@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mitt/-/mitt-1.2.0.tgz#cb24e6569c806e31bd4e3995787fe38a04fdf90d" + integrity sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw== + mixin-deep@^1.2.0: version "1.3.2" resolved "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz" @@ -10927,6 +10959,21 @@ react-is@^17.0.1: resolved "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== +react-lazylog@^4.5.3: + version "4.5.3" + resolved "https://registry.yarnpkg.com/react-lazylog/-/react-lazylog-4.5.3.tgz#289e24995b5599e75943556ac63f5e2c04d0001e" + integrity sha512-lyov32A/4BqihgXgtNXTHCajXSXkYHPlIEmV8RbYjHIMxCFSnmtdg4kDCI3vATz7dURtiFTvrw5yonHnrS+NNg== + dependencies: + "@mattiasbuelens/web-streams-polyfill" "^0.2.0" + fetch-readablestream "^0.2.0" + immutable "^3.8.2" + mitt "^1.1.2" + prop-types "^15.6.1" + react-string-replace "^0.4.1" + react-virtualized "^9.21.0" + text-encoding-utf-8 "^1.0.1" + whatwg-fetch "^2.0.4" + react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz" @@ -11036,6 +11083,13 @@ react-sliding-pane@^7.0.0: prop-types "^15.7.2" react-modal "^3.12.1" +react-string-replace@^0.4.1: + version "0.4.4" + resolved "https://registry.yarnpkg.com/react-string-replace/-/react-string-replace-0.4.4.tgz#24006fbe0db573d5be583133df38b1a735cb4225" + integrity sha512-FAMkhxmDpCsGTwTZg7p/2v+/GTmxAp73so3fbSvlAcBBX36ujiGRNEaM/1u+jiYQrArhns+7eE92g2pi5E5FUA== + dependencies: + lodash "^4.17.4" + react-table@^7.7.0: version "7.7.0" resolved "https://registry.npmjs.org/react-table/-/react-table-7.7.0.tgz" @@ -11051,6 +11105,18 @@ react-transition-group@^4.3.0: loose-envify "^1.4.0" prop-types "^15.6.2" +react-virtualized@^9.21.0: + version "9.22.3" + resolved "https://registry.yarnpkg.com/react-virtualized/-/react-virtualized-9.22.3.tgz#f430f16beb0a42db420dbd4d340403c0de334421" + integrity sha512-MKovKMxWTcwPSxE1kK1HcheQTWfuCxAuBoSTf2gwyMM21NdX/PXUhnoP8Uc5dRKd+nKm8v41R36OellhdCpkrw== + dependencies: + "@babel/runtime" "^7.7.2" + clsx "^1.0.4" + dom-helpers "^5.1.3" + loose-envify "^1.4.0" + prop-types "^15.7.2" + react-lifecycles-compat "^3.0.4" + react-window-dynamic-list@^2.3.5: version "2.4.2" resolved "https://registry.npmjs.org/react-window-dynamic-list/-/react-window-dynamic-list-2.4.2.tgz" @@ -12860,15 +12926,20 @@ test-exclude@^6.0.0: glob "^7.1.4" minimatch "^3.0.4" +text-encoding-utf-8@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/text-encoding-utf-8/-/text-encoding-utf-8-1.0.2.tgz#585b62197b0ae437e3c7b5d0af27ac1021e10d13" + integrity sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg== + text-table@^0.2.0, text-table@~0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= -threetwo-ui-typings@^1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/threetwo-ui-typings/-/threetwo-ui-typings-1.0.3.tgz" - integrity sha512-whyTLLMsgDIR6jkrJrz58qiMG8mYXF5V8akBI0okCmsE2djsnVPaihvXcL8bZWH4/HktqC86iJs9F9oYaG/4Ig== +threetwo-ui-typings@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/threetwo-ui-typings/-/threetwo-ui-typings-1.0.5.tgz#3b9b6967178ac603377bc711de4823403f74264b" + integrity sha512-3SxAFXpWWxP3umyO7QkH5s4ySDeXC08qIASrx6M3AkzLJCt2uCqYKumAxM9H78ETasEh0oOXzgusy6BvVMIRYA== dependencies: typescript "^4.3.2" @@ -13855,6 +13926,11 @@ whatwg-encoding@^1.0.5: dependencies: iconv-lite "0.4.24" +whatwg-fetch@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" + integrity sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng== + whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz"