From 3771134b1c83f9466327a3603f052bacca2e3383 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 21 Nov 2020 10:01:19 +0100 Subject: [PATCH 01/30] search plugins, plugin tab --- packages/api/package.json | 1 + packages/api/src/controllers/plugins.js | 22 ++++++ packages/api/src/main.js | 2 + packages/api/src/utility/directories.js | 4 + packages/web/src/App.js | 5 +- packages/web/src/icons.js | 1 + packages/web/src/plugins/PluginsList.js | 86 +++++++++++++++++++++ packages/web/src/plugins/PluginsProvider.js | 23 ++++++ packages/web/src/tabs/PluginTab.js | 28 +++++++ packages/web/src/tabs/index.js | 2 + packages/web/src/widgets/ArchiveWidget.js | 13 +--- packages/web/src/widgets/PluginsWidget.js | 73 +++++++++++++++++ packages/web/src/widgets/WidgetContainer.js | 2 + packages/web/src/widgets/WidgetIconPanel.js | 5 ++ yarn.lock | 5 ++ 15 files changed, 260 insertions(+), 12 deletions(-) create mode 100644 packages/api/src/controllers/plugins.js create mode 100644 packages/web/src/plugins/PluginsList.js create mode 100644 packages/web/src/plugins/PluginsProvider.js create mode 100644 packages/web/src/tabs/PluginTab.js create mode 100644 packages/web/src/widgets/PluginsWidget.js diff --git a/packages/api/package.json b/packages/api/package.json index 88e76bc04..bdbe00e78 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -46,6 +46,7 @@ "mssql": "^6.0.1", "mysql": "^2.17.1", "nedb-promises": "^4.0.1", + "node-fetch": "^2.6.1", "pg": "^7.17.0", "pg-query-stream": "^3.1.1", "xlsx": "^0.16.8" diff --git a/packages/api/src/controllers/plugins.js b/packages/api/src/controllers/plugins.js new file mode 100644 index 000000000..c24b453bb --- /dev/null +++ b/packages/api/src/controllers/plugins.js @@ -0,0 +1,22 @@ +const fs = require('fs-extra'); +const fetch = require('node-fetch'); + +module.exports = { + script_meta: 'get', + async script({ plugin }) { + const data = await fs.readFile('/home/jena/jenasoft/dbgate-plugin-csv/lib/frontend.js', { + encoding: 'utf-8', + }); + return data; + }, + + search_meta: 'get', + async search({ filter }) { + console.log(`https://api.npms.io/v2/search?q=keywords:dbgate ${encodeURIComponent(filter)}`); + const response = await fetch(`https://api.npms.io/v2/search?q=keywords:dbgate ${encodeURIComponent(filter)}`); + const json = await response.json(); + console.log(json); + const { results } = json || {}; + return results || []; + }, +}; diff --git a/packages/api/src/main.js b/packages/api/src/main.js index bafaf0c59..fa741841f 100644 --- a/packages/api/src/main.js +++ b/packages/api/src/main.js @@ -23,6 +23,7 @@ const config = require('./controllers/config'); const files = require('./controllers/files'); const archive = require('./controllers/archive'); const uploads = require('./controllers/uploads'); +const plugins = require('./controllers/plugins'); const { rundir } = require('./utility/directories'); @@ -67,6 +68,7 @@ function start(argument = null) { useController(app, '/files', files); useController(app, '/archive', archive); useController(app, '/uploads', uploads); + useController(app, '/plugins', plugins); if (process.env.PAGES_DIRECTORY) { app.use('/pages', express.static(process.env.PAGES_DIRECTORY)); diff --git a/packages/api/src/utility/directories.js b/packages/api/src/utility/directories.js index d001c0920..fbb42d921 100644 --- a/packages/api/src/utility/directories.js +++ b/packages/api/src/utility/directories.js @@ -35,6 +35,8 @@ const dirFunc = (dirname, clean = false) => () => { const jsldir = dirFunc('jsl', true); const rundir = dirFunc('run', true); const uploadsdir = dirFunc('uploads', true); +const pluginstmpdir = dirFunc('plugins-tmp', true); +const pluginsdir = dirFunc('plugins'); const archivedir = dirFunc('archive'); module.exports = { @@ -44,4 +46,6 @@ module.exports = { uploadsdir, archivedir, ensureDirectory, + pluginstmpdir, + pluginsdir, }; diff --git a/packages/web/src/App.js b/packages/web/src/App.js index a02f8210c..b8bd715de 100644 --- a/packages/web/src/App.js +++ b/packages/web/src/App.js @@ -16,6 +16,7 @@ import ConnectionsPinger from './utility/ConnectionsPinger'; import { ModalLayerProvider } from './modals/showModal'; import UploadsProvider from './utility/UploadsProvider'; import ThemeHelmet from './themes/ThemeHelmet'; +import PluginsProvider from './plugins/PluginsProvider'; function App() { return ( @@ -31,7 +32,9 @@ function App() { - + + + diff --git a/packages/web/src/icons.js b/packages/web/src/icons.js index 790950042..038e5ab34 100644 --- a/packages/web/src/icons.js +++ b/packages/web/src/icons.js @@ -42,6 +42,7 @@ const iconNames = { 'icon run': 'mdi mdi-play', 'icon chevron-down': 'mdi mdi-chevron-down', + 'icon plugin': 'mdi mdi-toy-brick', 'img green-ok': 'mdi mdi-check-circle color-green-8', 'img alert': 'mdi mdi-alert-circle color-blue-6', diff --git a/packages/web/src/plugins/PluginsList.js b/packages/web/src/plugins/PluginsList.js new file mode 100644 index 000000000..469d7bbb4 --- /dev/null +++ b/packages/web/src/plugins/PluginsList.js @@ -0,0 +1,86 @@ +import React from 'react'; +import styled from 'styled-components'; +import useTheme from '../theme/useTheme'; +import { openNewTab } from '../utility/common'; +import { useSetOpenedTabs } from '../utility/globalState'; + +const Wrapper = styled.div` + margin: 1px 3px 10px 5px; + display: flex; + align-items: center; + &:hover { + background-color: ${(props) => props.theme.left_background_blue[1]}; + } +`; + +const Texts = styled.div` + margin-left: 10px; +`; + +const Name = styled.div` + font-weight: bold; +`; + +const Line = styled.div` + display: flex; +`; + +const Icon = styled.img` + width: 50px; + height: 50px; +`; + +const Description = styled.div` + font-style: italic; +`; + +const Author = styled.div` + font-weight: bold; +`; + +const Version = styled.div` + margin-left: 5px; +`; + +function openPlugin(setOpenedTabs, plugin) { + openNewTab(setOpenedTabs, { + title: plugin.package.name, + icon: 'icon plugin', + tabComponent: 'PluginTab', + props: { + plugin, + }, + }); +} + +function PluginsListItem({ plugin }) { + const setOpenedTabs = useSetOpenedTabs(); + const theme = useTheme(); + return ( + openPlugin(setOpenedTabs, plugin)} theme={theme}> + + + + {plugin.package.name} + {plugin.package.version} + + + {plugin.package.description} + + + {plugin.package.author && plugin.package.author.name} + + + + ); +} + +export default function PluginsList({ plugins }) { + return ( + <> + {plugins.map((plugin) => ( + + ))} + + ); +} diff --git a/packages/web/src/plugins/PluginsProvider.js b/packages/web/src/plugins/PluginsProvider.js new file mode 100644 index 000000000..cac3487db --- /dev/null +++ b/packages/web/src/plugins/PluginsProvider.js @@ -0,0 +1,23 @@ +import React from 'react'; +import axios from '../utility/axios'; + +const PluginsContext = React.createContext(null); + +export default function PluginsProvider({ children }) { + const [plugins, setPlugins] = React.useState(null); + const handleLoadPlugin = async () => { + const resp = await axios.request({ + method: 'get', + url: 'plugins/script', + params: { + plugin: 'csv', + }, + }); + const module = eval(resp.data); + console.log('MODULE', module); + }; + React.useEffect(() => { + handleLoadPlugin(); + }, []); + return {children}; +} diff --git a/packages/web/src/tabs/PluginTab.js b/packages/web/src/tabs/PluginTab.js new file mode 100644 index 000000000..2fba68b31 --- /dev/null +++ b/packages/web/src/tabs/PluginTab.js @@ -0,0 +1,28 @@ +import React from 'react'; +import styled from 'styled-components'; +import _ from 'lodash'; +import ObjectListControl from '../utility/ObjectListControl'; +import { TableColumn } from '../utility/TableControl'; +import columnAppObject from '../appobj/columnAppObject'; +import constraintAppObject from '../appobj/constraintAppObject'; +import { useTableInfo, useDbCore } from '../utility/metadataLoaders'; +import useTheme from '../theme/useTheme'; + +const WhitePage = styled.div` + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + background-color: ${(props) => props.theme.main_background}; + overflow: auto; +`; + +export default function PluginTab({ plugin }) { + const theme = useTheme(); + return ( + +
{plugin.package.name}
+
+ ); +} diff --git a/packages/web/src/tabs/index.js b/packages/web/src/tabs/index.js index 97d46acd6..e77d0bc3e 100644 --- a/packages/web/src/tabs/index.js +++ b/packages/web/src/tabs/index.js @@ -6,6 +6,7 @@ import ShellTab from './ShellTab'; import InfoPageTab from './InfoPageTab'; import ArchiveFileTab from './ArchiveFileTab'; import FreeTableTab from './FreeTableTab'; +import PluginTab from './PluginTab'; export default { TableDataTab, @@ -16,4 +17,5 @@ export default { ShellTab, ArchiveFileTab, FreeTableTab, + PluginTab, }; diff --git a/packages/web/src/widgets/ArchiveWidget.js b/packages/web/src/widgets/ArchiveWidget.js index c628a37a7..e73f1c0be 100644 --- a/packages/web/src/widgets/ArchiveWidget.js +++ b/packages/web/src/widgets/ArchiveWidget.js @@ -1,19 +1,10 @@ import React from 'react'; -import styled from 'styled-components'; import _ from 'lodash'; import { AppObjectList } from '../appobj/AppObjectList'; -import { useCurrentArchive, useOpenedTabs, useSavedSqlFiles, useSetCurrentArchive } from '../utility/globalState'; -import closedTabAppObject from '../appobj/closedTabAppObject'; -import { - SearchBoxWrapper, - WidgetsInnerContainer, - WidgetsMainContainer, - WidgetsOuterContainer, - WidgetTitle, -} from './WidgetStyles'; +import { useCurrentArchive, useSetCurrentArchive } from '../utility/globalState'; +import { SearchBoxWrapper, WidgetsInnerContainer } from './WidgetStyles'; import WidgetColumnBar, { WidgetColumnBarItem } from './WidgetColumnBar'; -import savedSqlFileAppObject from '../appobj/savedSqlFileAppObject'; import { useArchiveFiles, useArchiveFolders } from '../utility/metadataLoaders'; import archiveFolderAppObject from '../appobj/archiveFolderAppObject'; import archiveFileAppObject from '../appobj/archiveFileAppObject'; diff --git a/packages/web/src/widgets/PluginsWidget.js b/packages/web/src/widgets/PluginsWidget.js new file mode 100644 index 000000000..9796fdf05 --- /dev/null +++ b/packages/web/src/widgets/PluginsWidget.js @@ -0,0 +1,73 @@ +import React from 'react'; +import _ from 'lodash'; + +import { AppObjectList } from '../appobj/AppObjectList'; +import { useCurrentArchive, useSetCurrentArchive } from '../utility/globalState'; +import { SearchBoxWrapper, WidgetsInnerContainer } from './WidgetStyles'; +import WidgetColumnBar, { WidgetColumnBarItem } from './WidgetColumnBar'; +import { useArchiveFiles, useArchiveFolders } from '../utility/metadataLoaders'; +import archiveFolderAppObject from '../appobj/archiveFolderAppObject'; +import archiveFileAppObject from '../appobj/archiveFileAppObject'; +import SearchInput from './SearchInput'; +import InlineButton from './InlineButton'; +import axios from '../utility/axios'; +import useFetch from '../utility/useFetch'; +import PluginsList from '../plugins/PluginsList'; + +function InstalledPluginsList() { + // const folders = useArchiveFolders(); + // const [filter, setFilter] = React.useState(''); + + // const setArchive = useSetCurrentArchive(); + + // const handleRefreshFolders = () => { + // axios.post('archive/refresh-folders', {}); + // }; + + return ( + + {/* setArchive(archive.name)} + filter={filter} + /> */} + + ); +} + +function AvailablePluginsList() { + const [filter, setFilter] = React.useState(''); + + const plugins = useFetch({ + url: 'plugins/search', + params: { + filter, + }, + defaultValue: [], + }); + + return ( + <> + + + + + + + + ); +} + +export default function PluginsWidget() { + return ( + + + + + + + + + ); +} diff --git a/packages/web/src/widgets/WidgetContainer.js b/packages/web/src/widgets/WidgetContainer.js index 4ef38c466..9fa204db5 100644 --- a/packages/web/src/widgets/WidgetContainer.js +++ b/packages/web/src/widgets/WidgetContainer.js @@ -3,11 +3,13 @@ import { useCurrentWidget } from '../utility/globalState'; import ArchiveWidget from './ArchiveWidget'; import DatabaseWidget from './DatabaseWidget'; import FilesWidget from './FilesWidget'; +import PluginsWidget from './PluginsWidget'; export default function WidgetContainer() { const currentWidget = useCurrentWidget(); if (currentWidget === 'database') return ; if (currentWidget === 'file') return ; if (currentWidget === 'archive') return ; + if (currentWidget === 'plugins') return ; return null; } diff --git a/packages/web/src/widgets/WidgetIconPanel.js b/packages/web/src/widgets/WidgetIconPanel.js index ce78fd5c5..e00cbcd37 100644 --- a/packages/web/src/widgets/WidgetIconPanel.js +++ b/packages/web/src/widgets/WidgetIconPanel.js @@ -51,6 +51,11 @@ export default function WidgetIconPanel() { name: 'archive', title: 'Archive (saved tabular data)', }, + { + icon: 'icon plugin', + name: 'plugins', + title: 'Extensions & Plugins', + }, // { // icon: 'fa-cog', // name: 'settings', diff --git a/yarn.lock b/yarn.lock index 505cc1a98..161b25e1b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7960,6 +7960,11 @@ node-fetch@^1.0.1: encoding "^0.1.11" is-stream "^1.0.1" +node-fetch@^2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" + integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== + node-forge@0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" From 1f4a93f1d59f5d72b1fb8d2cd3ec8f4c618c49e3 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 21 Nov 2020 10:32:25 +0100 Subject: [PATCH 02/30] download plugin, show readme --- packages/api/package.json | 1 + packages/api/src/controllers/plugins.js | 17 +- packages/web/package.json | 9 +- packages/web/src/plugins/PluginIcon.js | 7 + packages/web/src/plugins/PluginsList.js | 5 +- packages/web/src/tabs/PluginTab.js | 18 +- yarn.lock | 891 +++++++++++++++++++++++- 7 files changed, 922 insertions(+), 26 deletions(-) create mode 100644 packages/web/src/plugins/PluginIcon.js diff --git a/packages/api/package.json b/packages/api/package.json index bdbe00e78..91a53b46a 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -47,6 +47,7 @@ "mysql": "^2.17.1", "nedb-promises": "^4.0.1", "node-fetch": "^2.6.1", + "pacote": "^11.1.13", "pg": "^7.17.0", "pg-query-stream": "^3.1.1", "xlsx": "^0.16.8" diff --git a/packages/api/src/controllers/plugins.js b/packages/api/src/controllers/plugins.js index c24b453bb..aac64d95b 100644 --- a/packages/api/src/controllers/plugins.js +++ b/packages/api/src/controllers/plugins.js @@ -1,9 +1,12 @@ const fs = require('fs-extra'); const fetch = require('node-fetch'); +const path = require('path'); +const pacote = require('pacote'); +const { pluginstmpdir } = require('../utility/directories'); module.exports = { script_meta: 'get', - async script({ plugin }) { + async script({ packageName }) { const data = await fs.readFile('/home/jena/jenasoft/dbgate-plugin-csv/lib/frontend.js', { encoding: 'utf-8', }); @@ -12,11 +15,21 @@ module.exports = { search_meta: 'get', async search({ filter }) { - console.log(`https://api.npms.io/v2/search?q=keywords:dbgate ${encodeURIComponent(filter)}`); const response = await fetch(`https://api.npms.io/v2/search?q=keywords:dbgate ${encodeURIComponent(filter)}`); const json = await response.json(); console.log(json); const { results } = json || {}; return results || []; }, + + readme_meta: 'get', + async readme({ packageName }) { + const dir = path.join(pluginstmpdir(), packageName); + if (!(await fs.exists(dir))) { + await pacote.extract(packageName, dir); + } + const file = path.join(dir, 'README.md'); + if (await fs.exists(file)) return await fs.readFile(file, { encoding: 'utf-8' }); + return ''; + }, }; diff --git a/packages/web/package.json b/packages/web/package.json index dc196cbb3..6d5210e4c 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -4,9 +4,6 @@ "private": true, "dependencies": { "@ant-design/colors": "^5.0.0", - "dbgate-datalib": "^1.0.0", - "dbgate-engines": "^1.0.0", - "dbgate-sqltree": "^1.0.0", "@mdi/font": "^5.8.55", "@testing-library/jest-dom": "^4.2.4", "@testing-library/react": "^9.3.2", @@ -14,6 +11,9 @@ "ace-builds": "^1.4.8", "axios": "^0.19.0", "cross-env": "^6.0.3", + "dbgate-datalib": "^1.0.0", + "dbgate-engines": "^1.0.0", + "dbgate-sqltree": "^1.0.0", "eslint": "^6.8.0", "eslint-plugin-react": "^7.17.0", "formik": "^2.1.0", @@ -24,6 +24,7 @@ "react-dropzone": "^11.2.3", "react-helmet": "^6.1.0", "react-json-view": "^1.19.1", + "react-markdown": "^5.0.3", "react-modal": "^3.11.1", "react-scripts": "3.3.0", "react-select": "^3.1.0", @@ -54,9 +55,9 @@ ] }, "devDependencies": { - "dbgate-types": "^1.0.0", "@types/react": "^16.9.17", "@types/styled-components": "^4.4.2", + "dbgate-types": "^1.0.0", "typescript": "^3.7.4" } } diff --git a/packages/web/src/plugins/PluginIcon.js b/packages/web/src/plugins/PluginIcon.js new file mode 100644 index 000000000..bfc0f211e --- /dev/null +++ b/packages/web/src/plugins/PluginIcon.js @@ -0,0 +1,7 @@ +import React from 'react'; + +export default function PluginIcon({ plugin, className = undefined }) { + return ( + + ); +} diff --git a/packages/web/src/plugins/PluginsList.js b/packages/web/src/plugins/PluginsList.js index 469d7bbb4..608fa5541 100644 --- a/packages/web/src/plugins/PluginsList.js +++ b/packages/web/src/plugins/PluginsList.js @@ -3,6 +3,7 @@ import styled from 'styled-components'; import useTheme from '../theme/useTheme'; import { openNewTab } from '../utility/common'; import { useSetOpenedTabs } from '../utility/globalState'; +import PluginIcon from './PluginIcon'; const Wrapper = styled.div` margin: 1px 3px 10px 5px; @@ -25,7 +26,7 @@ const Line = styled.div` display: flex; `; -const Icon = styled.img` +const Icon = styled(PluginIcon)` width: 50px; height: 50px; `; @@ -58,7 +59,7 @@ function PluginsListItem({ plugin }) { const theme = useTheme(); return ( openPlugin(setOpenedTabs, plugin)} theme={theme}> - + {plugin.package.name} diff --git a/packages/web/src/tabs/PluginTab.js b/packages/web/src/tabs/PluginTab.js index 2fba68b31..e3576531b 100644 --- a/packages/web/src/tabs/PluginTab.js +++ b/packages/web/src/tabs/PluginTab.js @@ -1,12 +1,15 @@ import React from 'react'; import styled from 'styled-components'; import _ from 'lodash'; +import ReactMarkdown from 'react-markdown'; import ObjectListControl from '../utility/ObjectListControl'; import { TableColumn } from '../utility/TableControl'; import columnAppObject from '../appobj/columnAppObject'; import constraintAppObject from '../appobj/constraintAppObject'; import { useTableInfo, useDbCore } from '../utility/metadataLoaders'; import useTheme from '../theme/useTheme'; +import useFetch from '../utility/useFetch'; +import LoadingInfo from '../widgets/LoadingInfo'; const WhitePage = styled.div` position: absolute; @@ -16,13 +19,26 @@ const WhitePage = styled.div` bottom: 0; background-color: ${(props) => props.theme.main_background}; overflow: auto; + padding: 10px; +`; + +const Title = styled.div` + font-size: 20pt; + border-bottom: 1px solid ${(props) => props.theme.border}; `; export default function PluginTab({ plugin }) { const theme = useTheme(); + const packageName = plugin.package.name; + const readme = useFetch({ + params: { packageName }, + url: 'plugins/readme', + defaultValue: null, + }); return ( -
{plugin.package.name}
+ {packageName} + {readme == null ? : {readme}}
); } diff --git a/yarn.lock b/yarn.lock index 161b25e1b..7879c854f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1266,6 +1266,67 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== +"@npmcli/ci-detect@^1.0.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@npmcli/ci-detect/-/ci-detect-1.3.0.tgz#6c1d2c625fb6ef1b9dea85ad0a5afcbef85ef22a" + integrity sha512-oN3y7FAROHhrAt7Rr7PnTSwrHrZVRTS2ZbyxeQwSSYD0ifwM3YNgQqbaRmjcWoPyq77MjchusjJDspbzMmip1Q== + +"@npmcli/git@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-2.0.4.tgz#725f5e32864f3849420e84baf130e426a707cbb7" + integrity sha512-OJZCmJ9DNn1cz9HPXXsPmUBnqaArot3CGYo63CyajHQk+g87rPXVOJByGsskQJhPsUUEXJcsZ2Q6bWd2jSwnBA== + dependencies: + "@npmcli/promise-spawn" "^1.1.0" + lru-cache "^6.0.0" + mkdirp "^1.0.3" + npm-pick-manifest "^6.0.0" + promise-inflight "^1.0.1" + promise-retry "^1.1.1" + semver "^7.3.2" + unique-filename "^1.1.1" + which "^2.0.2" + +"@npmcli/installed-package-contents@^1.0.5": + version "1.0.5" + resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-1.0.5.tgz#cc78565e55d9f14d46acf46a96f70934e516fa3d" + integrity sha512-aKIwguaaqb6ViwSOFytniGvLPb9SMCUm39TgM3SfUo7n0TxUMbwoXfpwyvQ4blm10lzbAwTsvjr7QZ85LvTi4A== + dependencies: + npm-bundled "^1.1.1" + npm-normalize-package-bin "^1.0.1" + read-package-json-fast "^1.1.1" + readdir-scoped-modules "^1.1.0" + +"@npmcli/move-file@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.0.1.tgz#de103070dac0f48ce49cf6693c23af59c0f70464" + integrity sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw== + dependencies: + mkdirp "^1.0.4" + +"@npmcli/node-gyp@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-1.0.1.tgz#dedc4ea9b3c6ef207081ebcd82c053ef60edc478" + integrity sha512-pBqoKPWmuk9iaEcXlLBVRIA6I1kG9JiICU+sG0NuD6NAR461F+02elHJS4WkQxHW2W5rnsfvP/ClKwmsZ9RaaA== + +"@npmcli/promise-spawn@^1.1.0", "@npmcli/promise-spawn@^1.2.0", "@npmcli/promise-spawn@^1.3.0": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz#42d4e56a8e9274fba180dabc0aea6e38f29274f5" + integrity sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg== + dependencies: + infer-owner "^1.0.4" + +"@npmcli/run-script@^1.3.0": + version "1.8.0" + resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-1.8.0.tgz#5cebd6373a4b051e5bf8473eb70c327fa48ebfe5" + integrity sha512-ljPLRbQM5byhqacWl9kIjt/yPMee0heaTskaMBFaFvYzOXNJ64h27xV96Sr+LnjJpqR0qJejG36QzJkXILvghQ== + dependencies: + "@npmcli/node-gyp" "^1.0.0" + "@npmcli/promise-spawn" "^1.3.0" + infer-owner "^1.0.4" + node-gyp "^7.1.0" + puka "^1.0.1" + read-package-json-fast "^1.1.3" + "@sheerun/mutationobserver-shim@^0.3.2": version "0.3.2" resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.2.tgz#8013f2af54a2b7d735f71560ff360d3a8176a87b" @@ -1415,6 +1476,11 @@ resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-7.2.1.tgz#2ad4e844175a3738cb9e7064be5ea070b8863a1c" integrity sha512-oZ0Ib5I4Z2pUEcoo95cT1cr6slco9WY7yiPpG+RGNkj8YcYgJnM7pXmYmorNOReh8MIGcKSqXyeGjxnr8YiZbA== +"@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + "@types/babel__core@^7.1.0": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.3.tgz#e441ea7df63cd080dfcd02ab199e6d16a735fc30" @@ -1518,6 +1584,13 @@ resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440" integrity sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ== +"@types/mdast@^3.0.0", "@types/mdast@^3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.3.tgz#2d7d671b1cd1ea3deb306ea75036c2a0407d2deb" + integrity sha512-SXPBMnFVQg1s00dlMCc/jCdvPqdE4mXaMMCeRlxLDmTAEoegHT53xKtkDnzDTOcmMHUfcjyf36/YYZ6SxRdnsw== + dependencies: + "@types/unist" "*" + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -1630,6 +1703,11 @@ dependencies: "@types/node" "*" +"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" + integrity sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ== + "@types/yargs-parser@*": version "15.0.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d" @@ -1953,6 +2031,22 @@ after@0.8.2: resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +agentkeepalive@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.1.3.tgz#360a09d743a1f4fde749f9ba07caa6575d08259a" + integrity sha512-wn8fw19xKZwdGPO47jivonaHRTd+nGOMP1z11sgGeQzDy2xd5FG0R67dIMcKHDE2cJ5y+YXV30XVGUBPRSY7Hg== + dependencies: + debug "^4.1.0" + depd "^1.1.2" + humanize-ms "^1.2.1" + aggregate-error@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0" @@ -1981,6 +2075,16 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^6.12.3: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + alphanum-sort@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" @@ -2071,11 +2175,19 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" -aproba@^1.1.1: +aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -2162,7 +2274,7 @@ arrify@^1.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= -asap@~2.0.3, asap@~2.0.6: +asap@^2.0.0, asap@~2.0.3, asap@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= @@ -2486,6 +2598,11 @@ backo2@1.0.2: resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" integrity sha1-MasayLEpNjRj41s+u2n038+6eUc= +bail@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" + integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -2828,6 +2945,11 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= +builtins@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" + integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= + busboy@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.3.1.tgz#170899274c5bf38aae27d5c62b71268cd585fd1b" @@ -2895,6 +3017,29 @@ cacache@^13.0.1: ssri "^7.0.0" unique-filename "^1.1.1" +cacache@^15.0.0, cacache@^15.0.5: + version "15.0.5" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.5.tgz#69162833da29170d6732334643c60e005f5f17d0" + integrity sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A== + dependencies: + "@npmcli/move-file" "^1.0.1" + chownr "^2.0.0" + fs-minipass "^2.0.0" + glob "^7.1.4" + infer-owner "^1.0.4" + lru-cache "^6.0.0" + minipass "^3.1.1" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^1.0.3" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^8.0.0" + tar "^6.0.2" + unique-filename "^1.1.1" + cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -3046,6 +3191,21 @@ chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" +character-entities-legacy@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" + integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== + +character-entities@^1.0.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" + integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== + +character-reference-invalid@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" + integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== + chardet@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" @@ -3090,6 +3250,11 @@ chownr@^1.1.1, chownr@^1.1.2: resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw== +chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + chrome-trace-event@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz#234090ee97c7d4ad1a2c4beae27505deffc608a4" @@ -3413,6 +3578,11 @@ console-browserify@^1.1.0: resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== +console-control-strings@^1.0.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= + constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -3975,6 +4145,13 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: dependencies: ms "2.0.0" +debug@4, debug@^4.0.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + debug@=3.1.0, debug@~3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" @@ -3996,6 +4173,11 @@ debug@^4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0: dependencies: ms "^2.1.1" +debuglog@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" + integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= + decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -4088,16 +4270,21 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@^1.1.2, depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + depd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= - des.js@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" @@ -4134,6 +4321,14 @@ detect-port-alt@1.1.6: address "^1.0.1" debug "^2.6.0" +dezalgo@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" + integrity sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY= + dependencies: + asap "^2.0.0" + wrappy "1" + dicer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.3.0.tgz#eacd98b3bfbf92e8ab5c2fdb71aaac44bb06b872" @@ -4238,6 +4433,15 @@ dom-serializer@0: domelementtype "^2.0.1" entities "^2.0.0" +dom-serializer@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.1.0.tgz#5f7c828f1bfc44887dc2a315ab5c45691d544b58" + integrity sha512-ox7bvGXt2n+uLWtCRLybYx60IrOlWL/aCebWJk1T0d4m3y2tzf4U3ij9wBMUb6YJZpz06HCCYuyCDveE2xXmzQ== + dependencies: + domelementtype "^2.0.1" + domhandler "^3.0.0" + entities "^2.0.0" + domain-browser@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" @@ -4267,6 +4471,13 @@ domhandler@^2.3.0: dependencies: domelementtype "1" +domhandler@^3.0.0, domhandler@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-3.3.0.tgz#6db7ea46e4617eb15cf875df68b2b8524ce0037a" + integrity sha512-J1C5rIANUbuYK+FuFL98650rihynUOEzRLxW+90bKZRWB6A1X1Tf82GxR1qAWLyfNPRvjqfip3Q5tdYlmAa9lA== + dependencies: + domelementtype "^2.0.1" + domutils@1.5.1: version "1.5.1" resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf" @@ -4283,6 +4494,15 @@ domutils@^1.5.1, domutils@^1.7.0: dom-serializer "0" domelementtype "1" +domutils@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.4.2.tgz#7ee5be261944e1ad487d9aa0616720010123922b" + integrity sha512-NKbgaM8ZJOecTZsIzW5gSuplsX2IWW2mIK7xVr8hTQF2v1CJWTmLZ1HOCh5sH+IzVPAGE5IucooOkvwBRAdowA== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.0.1" + domhandler "^3.3.0" + dot-prop@^4.1.0, dot-prop@^4.1.1: version "4.2.0" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-4.2.0.tgz#1f19e0c2e1aa0e32797c49799f2837ac6af69c57" @@ -4378,7 +4598,7 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.11: +encoding@^0.1.11, encoding@^0.1.12: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== @@ -4468,6 +4688,16 @@ env-cmd@^10.1.0: commander "^4.0.0" cross-spawn "^7.0.0" +env-paths@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" + integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== + +err-code@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" + integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA= + errno@^0.1.3, errno@~0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" @@ -4959,7 +5189,7 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: assign-symbols "^1.0.0" is-extendable "^1.0.1" -extend@~3.0.2: +extend@^3.0.0, extend@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== @@ -5398,7 +5628,7 @@ fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-minipass@^2.0.0: +fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== @@ -5443,6 +5673,20 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +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" + gensync@^1.0.0-beta.1: version "1.0.0-beta.1" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" @@ -5620,6 +5864,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== +graceful-fs@^4.2.3: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" @@ -5651,6 +5900,14 @@ har-validator@~5.1.0: ajv "^6.5.5" har-schema "^2.0.0" +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + harmony-reflect@^1.4.6: version "1.6.1" resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.1.tgz#c108d4f2bb451efef7a37861fdbdae72c9bdefa9" @@ -5690,6 +5947,11 @@ has-symbols@^1.0.0, has-symbols@^1.0.1: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" @@ -5782,6 +6044,13 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c" integrity sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg== +hosted-git-info@^3.0.6: + version "3.0.7" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.7.tgz#a30727385ea85acfcee94e0aad9e368c792e036c" + integrity sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ== + dependencies: + lru-cache "^6.0.0" + hpack.js@^2.1.6: version "2.1.6" resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" @@ -5837,6 +6106,16 @@ html-minifier@^3.5.20: relateurl "0.2.x" uglify-js "3.4.x" +html-to-react@^1.3.4: + version "1.4.5" + resolved "https://registry.yarnpkg.com/html-to-react/-/html-to-react-1.4.5.tgz#59091c11021d1ef315ef738460abb6a4a41fe1ce" + integrity sha512-KONZUDFPg5OodWaQu2ymfkDmU0JA7zB1iPfvyHehTmMUZnk0DS7/TyCMTzsLH6b4BvxX15g88qZCXFhJWktsmA== + dependencies: + domhandler "^3.3.0" + htmlparser2 "^5.0" + lodash.camelcase "^4.3.0" + ramda "^0.27.1" + html-webpack-plugin@4.0.0-beta.5: version "4.0.0-beta.5" resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.0.0-beta.5.tgz#2c53083c1151bfec20479b1f8aaf0039e77b5513" @@ -5861,6 +6140,21 @@ htmlparser2@^3.3.0: inherits "^2.0.1" readable-stream "^3.1.1" +htmlparser2@^5.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-5.0.1.tgz#7daa6fc3e35d6107ac95a4fc08781f091664f6e7" + integrity sha512-vKZZra6CSe9qsJzh0BjBGXo8dvzNsq/oGvsjfRdOrrryfeD9UOBEEQdeoqCRmKZchF5h2zOBMQ6YuQ0uRUmdbQ== + dependencies: + domelementtype "^2.0.1" + domhandler "^3.3.0" + domutils "^2.4.2" + entities "^2.0.0" + +http-cache-semantics@^4.0.4: + version "4.1.0" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" + integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== + http-deceiver@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" @@ -5903,6 +6197,15 @@ http-errors@~1.7.2: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q= +http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + http-proxy-middleware@0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" @@ -5941,6 +6244,21 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= + dependencies: + ms "^2.0.0" + iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -5991,6 +6309,13 @@ ignore-by-default@^1.0.1: resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= +ignore-walk@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" + integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== + dependencies: + minimatch "^3.0.4" + ignore@^3.3.5: version "3.3.10" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" @@ -6204,6 +6529,19 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-alphabetical@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" + integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== + +is-alphanumerical@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" + integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== + dependencies: + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + is-arguments@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" @@ -6238,6 +6576,11 @@ is-buffer@^1.0.2, is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-buffer@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== + is-callable@^1.1.4, is-callable@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" @@ -6288,6 +6631,11 @@ is-date-object@^1.0.1: resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.2.tgz#bda736f2cd8fd06d32844e7743bfa7494c3bfd7e" integrity sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g== +is-decimal@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" + integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== + is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -6364,6 +6712,11 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-hexadecimal@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" + integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== + is-installed-globally@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.1.0.tgz#0dfd98f5a9111716dd535dda6492f67bf3d25a80" @@ -6372,6 +6725,11 @@ is-installed-globally@^0.1.0: global-dirs "^0.1.0" is-path-inside "^1.0.0" +is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" + integrity sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU= + is-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" @@ -6425,6 +6783,11 @@ is-plain-obj@^1.0.0: resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" integrity sha1-caUMhCnfync8kqOQpKA7OfzVHT4= +is-plain-obj@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -7101,6 +7464,11 @@ json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== +json-parse-even-better-errors@^2.3.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -7159,6 +7527,11 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= +jsonparse@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= + jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -7398,6 +7771,11 @@ lodash._reinterpolate@^3.0.0: resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" integrity sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0= +lodash.camelcase@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" + integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= + lodash.curry@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.curry/-/lodash.curry-4.1.1.tgz#248e36072ede906501d75966200a86dab8b23170" @@ -7490,6 +7868,13 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" @@ -7517,6 +7902,27 @@ make-error@1.x: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== +make-fetch-happen@^8.0.9: + version "8.0.10" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-8.0.10.tgz#f37c5d93d14290488ca6a2ae917a380bd7d24f16" + integrity sha512-jPLPKQjBmDLK5r1BdyDyNKBytmkv2AsDWm2CxHJh+fqhSmC9Pmb7RQxwOq8xQig9+AWIS49+51k4f6vDQ3VnrQ== + dependencies: + agentkeepalive "^4.1.0" + cacache "^15.0.0" + http-cache-semantics "^4.0.4" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^6.0.0" + minipass "^3.1.3" + minipass-collect "^1.0.2" + minipass-fetch "^1.3.0" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + promise-retry "^1.1.1" + socks-proxy-agent "^5.0.0" + ssri "^8.0.0" + makeerror@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" @@ -7557,6 +7963,28 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" +mdast-add-list-metadata@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdast-add-list-metadata/-/mdast-add-list-metadata-1.0.1.tgz#95e73640ce2fc1fa2dcb7ec443d09e2bfe7db4cf" + integrity sha512-fB/VP4MJ0LaRsog7hGPxgOrSL3gE/2uEdZyDuSEnKCv/8IkYHiDkIQSbChiJoHyxZZXZ9bzckyRk+vNxFzh8rA== + dependencies: + unist-util-visit-parents "1.1.2" + +mdast-util-from-markdown@^0.8.0: + version "0.8.1" + resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.1.tgz#781371d493cac11212947226190270c15dc97116" + integrity sha512-qJXNcFcuCSPqUF0Tb0uYcFDIq67qwB3sxo9RPdf9vG8T90ViKnksFqdB/Coq2a7sTnxL/Ify2y7aIQXDkQFH0w== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-to-string "^1.0.0" + micromark "~2.10.0" + parse-entities "^2.0.0" + +mdast-util-to-string@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527" + integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A== + mdn-data@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" @@ -7638,6 +8066,14 @@ microevent.ts@~0.1.1: resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g== +micromark@~2.10.0: + version "2.10.1" + resolved "https://registry.yarnpkg.com/micromark/-/micromark-2.10.1.tgz#cd73f54e0656f10e633073db26b663a221a442a7" + integrity sha512-fUuVF8sC1X7wsCS29SYQ2ZfIZYbTymp0EYr6sab3idFjigFFjGa5UwoniPlV9tAgntjuapW1t9U+S0yDYeGKHQ== + dependencies: + debug "^4.0.0" + parse-entities "^2.0.0" + micromatch@^3.0.4, micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -7741,6 +8177,17 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" +minipass-fetch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.3.2.tgz#573766fb1ae86e30df916a6b060bc2e801bf8f37" + integrity sha512-/i4fX1ss+Dtwyk++OsAI6SEV+eE1dvI6W+0hORdjfruQ7VD5uYTetJIHcEMjWiEiszWjn2aAtP1CB/Q4KfeoYA== + dependencies: + minipass "^3.1.0" + minipass-sized "^1.0.3" + minizlib "^2.0.0" + optionalDependencies: + encoding "^0.1.12" + minipass-flush@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" @@ -7748,6 +8195,14 @@ minipass-flush@^1.0.5: dependencies: minipass "^3.0.0" +minipass-json-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz#7edbb92588fbfc2ff1db2fc10397acb7b6b44aa7" + integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg== + dependencies: + jsonparse "^1.3.1" + minipass "^3.0.0" + minipass-pipeline@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz#3dcb6bb4a546e32969c7ad710f2c79a86abba93a" @@ -7755,6 +8210,13 @@ minipass-pipeline@^1.2.2: dependencies: minipass "^3.0.0" +minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + minipass@^3.0.0, minipass@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5" @@ -7762,6 +8224,21 @@ minipass@^3.0.0, minipass@^3.1.1: dependencies: yallist "^4.0.0" +minipass@^3.1.0, minipass@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" + integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== + dependencies: + yallist "^4.0.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" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + mississippi@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" @@ -7806,6 +8283,11 @@ mkdirp@0.5.1, mkdirp@0.x, mkdirp@^0.5.1, mkdirp@~0.5.1: dependencies: minimist "0.0.8" +mkdirp@^1.0.3, mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + moment@^2.24.0: version "2.24.0" resolved "https://registry.yarnpkg.com/moment/-/moment-2.24.0.tgz#0d055d53f5052aa653c9f6eb68bb5d12bf5c2b5b" @@ -7833,7 +8315,7 @@ ms@2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -ms@^2.1.1: +ms@2.1.2, ms@^2.0.0, ms@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== @@ -7975,6 +8457,22 @@ node-gyp-build@~3.7.0: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-3.7.0.tgz#daa77a4f547b9aed3e2aac779eaf151afd60ec8d" integrity sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w== +node-gyp@^7.1.0: + version "7.1.2" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-7.1.2.tgz#21a810aebb187120251c3bcec979af1587b188ae" + integrity sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ== + dependencies: + env-paths "^2.2.0" + glob "^7.1.4" + graceful-fs "^4.2.3" + nopt "^5.0.0" + npmlog "^4.1.2" + request "^2.88.2" + rimraf "^3.0.2" + semver "^7.3.2" + tar "^6.0.2" + which "^2.0.2" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -8056,6 +8554,13 @@ noms@0.0.0: inherits "^2.0.1" readable-stream "~1.0.31" +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + nopt@~1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" @@ -8105,6 +8610,67 @@ normalize-url@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== +npm-bundled@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" + integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== + dependencies: + npm-normalize-package-bin "^1.0.1" + +npm-install-checks@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-4.0.0.tgz#a37facc763a2fde0497ef2c6d0ac7c3fbe00d7b4" + integrity sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w== + dependencies: + semver "^7.1.1" + +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-package-arg@^8.0.0, npm-package-arg@^8.0.1: + version "8.1.0" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.0.tgz#b5f6319418c3246a1c38e1a8fbaa06231bc5308f" + integrity sha512-/ep6QDxBkm9HvOhOg0heitSd7JHA1U7y1qhhlRlteYYAi9Pdb/ZV7FW5aHpkrpM8+P+4p/jjR8zCyKPBMBjSig== + dependencies: + hosted-git-info "^3.0.6" + semver "^7.0.0" + validate-npm-package-name "^3.0.0" + +npm-packlist@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-2.1.4.tgz#40e96b2b43787d0546a574542d01e066640d09da" + integrity sha512-Qzg2pvXC9U4I4fLnUrBmcIT4x0woLtUgxUi9eC+Zrcv1Xx5eamytGAfbDWQ67j7xOcQ2VW1I3su9smVTIdu7Hw== + dependencies: + glob "^7.1.6" + ignore-walk "^3.0.3" + npm-bundled "^1.1.1" + npm-normalize-package-bin "^1.0.1" + +npm-pick-manifest@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-6.1.0.tgz#2befed87b0fce956790f62d32afb56d7539c022a" + integrity sha512-ygs4k6f54ZxJXrzT0x34NybRlLeZ4+6nECAIbr2i0foTnijtS1TJiyzpqtuUAJOps/hO0tNDr8fRV5g+BtRlTw== + dependencies: + npm-install-checks "^4.0.0" + npm-package-arg "^8.0.0" + semver "^7.0.0" + +npm-registry-fetch@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-9.0.0.tgz#86f3feb4ce00313bc0b8f1f8f69daae6face1661" + integrity sha512-PuFYYtnQ8IyVl6ib9d3PepeehcUeHN9IO5N/iCRhyg9tStQcqGQBRVHmfmMWPDERU3KwZoHFvbJ4FPXPspvzbA== + dependencies: + "@npmcli/ci-detect" "^1.0.0" + lru-cache "^6.0.0" + make-fetch-happen "^8.0.9" + minipass "^3.1.3" + minipass-fetch "^1.3.0" + minipass-json-stream "^1.0.1" + minizlib "^2.0.0" + npm-package-arg "^8.0.0" + 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" @@ -8112,6 +8678,16 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" +npmlog@^4.1.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" + nth-check@^1.0.2, nth-check@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" @@ -8405,6 +8981,13 @@ p-map@^3.0.0: dependencies: aggregate-error "^3.0.0" +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + p-reduce@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" @@ -8442,6 +9025,31 @@ packet-reader@1.0.0: resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74" integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== +pacote@^11.1.13: + version "11.1.13" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-11.1.13.tgz#7e85213693b0b4b1119c4026dc1b68c087641dc2" + integrity sha512-oJ7Bg7p3izrIMhZPHCCHmMHQl+xb+pKBXL5ZYeM2oCZrw6sBRSx7f8l7F+95V2qA0BP3c1cNaaBmUNkbo6Hn9w== + dependencies: + "@npmcli/git" "^2.0.1" + "@npmcli/installed-package-contents" "^1.0.5" + "@npmcli/promise-spawn" "^1.2.0" + "@npmcli/run-script" "^1.3.0" + cacache "^15.0.5" + chownr "^2.0.0" + fs-minipass "^2.1.0" + infer-owner "^1.0.4" + minipass "^3.1.3" + mkdirp "^1.0.3" + npm-package-arg "^8.0.1" + npm-packlist "^2.1.4" + npm-pick-manifest "^6.0.0" + npm-registry-fetch "^9.0.0" + promise-retry "^1.1.1" + read-package-json-fast "^1.1.3" + rimraf "^3.0.2" + ssri "^8.0.0" + tar "^6.0.1" + pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" @@ -8482,6 +9090,18 @@ parse-asn1@^5.0.0: pbkdf2 "^3.0.3" safe-buffer "^5.1.1" +parse-entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" + integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== + dependencies: + character-entities "^1.0.0" + character-entities-legacy "^1.0.0" + character-reference-invalid "^1.0.0" + is-alphanumerical "^1.0.0" + is-decimal "^1.0.0" + is-hexadecimal "^1.0.0" + parse-json@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" @@ -9582,6 +10202,14 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= +promise-retry@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d" + integrity sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0= + dependencies: + err-code "^1.0.0" + retry "^0.10.0" + promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" @@ -9653,6 +10281,11 @@ public-encrypt@^4.0.0: randombytes "^2.0.1" safe-buffer "^5.1.2" +puka@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/puka/-/puka-1.0.1.tgz#a2df782b7eb4cf9564e4c93a5da422de0dfacc02" + integrity sha512-ssjRZxBd7BT3dte1RR3VoeT2cT/ODH8x+h0rUF1rMqB0srHYf48stSDWfiYakTp5UBZMxroZhB2+ExLDHm7W3g== + pump@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" @@ -9743,6 +10376,11 @@ raf@^3.4.1: dependencies: performance-now "^2.1.0" +ramda@^0.27.1: + version "0.27.1" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.1.tgz#66fc2df3ef873874ffc2da6aa8984658abacf5c9" + integrity sha512-PgIdVpn5y5Yns8vqb8FzBUEYn98V3xcPgawAkkgj0YJ0qDsnHCiNmZYfOGMgOvoB0eWFLpYbhxUR3mxfDIMvpw== + randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -9907,6 +10545,11 @@ react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4: resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c" integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q== +react-is@^16.8.6: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + react-json-view@^1.19.1: version "1.19.1" resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.19.1.tgz#95d8e59e024f08a25e5dc8f076ae304eed97cf5c" @@ -9922,6 +10565,22 @@ react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.4: resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== +react-markdown@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-5.0.3.tgz#41040ea7a9324b564b328fb81dd6c04f2a5373ac" + integrity sha512-jDWOc1AvWn0WahpjW6NK64mtx6cwjM4iSsLHJPNBqoAgGOVoIdJMqaKX4++plhOtdd4JksdqzlDibgPx6B/M2w== + dependencies: + "@types/mdast" "^3.0.3" + "@types/unist" "^2.0.3" + html-to-react "^1.3.4" + mdast-add-list-metadata "1.0.1" + prop-types "^15.7.2" + react-is "^16.8.6" + remark-parse "^9.0.0" + unified "^9.0.0" + unist-util-visit "^2.0.0" + xtend "^4.0.1" + react-modal@^3.11.1: version "3.11.1" resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.11.1.tgz#2a0d6877c9e98f123939ea92d2bb4ad7fa5a17f9" @@ -10037,6 +10696,14 @@ react@^16.12.0: object-assign "^4.1.1" prop-types "^15.6.2" +read-package-json-fast@^1.1.1, read-package-json-fast@^1.1.3: + version "1.2.1" + resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-1.2.1.tgz#e8518d6f37c99eb3afc26704c5cbb50d7ead82dd" + integrity sha512-OFbpwnHcv74Oa5YN5WvbOBfLw6yPmPcwvyJJw/tj9cWFBF7juQUDLDSZiOjEcgzfweWeeROOmbPpNN1qm4hcRg== + dependencies: + json-parse-even-better-errors "^2.3.0" + npm-normalize-package-bin "^1.0.1" + read-pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" @@ -10080,7 +10747,7 @@ read-pkg@^4.0.1: parse-json "^4.0.0" pify "^3.0.0" -"readable-stream@1 || 2", readable-stream@2.3.7, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@2.3.7, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -10112,6 +10779,16 @@ readable-stream@~1.0.31: isarray "0.0.1" string_decoder "~0.10.x" +readdir-scoped-modules@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" + integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== + dependencies: + debuglog "^1.0.1" + dezalgo "^1.0.0" + graceful-fs "^4.1.2" + once "^1.3.0" + readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -10259,6 +10936,13 @@ relateurl@0.2.x: resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= +remark-parse@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-9.0.0.tgz#4d20a299665880e4f4af5d90b7c7b8a935853640" + integrity sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw== + dependencies: + mdast-util-from-markdown "^0.8.0" + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" @@ -10285,6 +10969,11 @@ repeat-string@^1.6.1: resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= +replace-ext@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + integrity sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs= + request-promise-core@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.3.tgz#e9a3c081b51380dfea677336061fea879a829ee9" @@ -10327,6 +11016,32 @@ request-promise-native@^1.0.5: tunnel-agent "^0.6.0" uuid "^3.3.2" +request@^2.88.2: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -10437,6 +11152,11 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== +retry@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" + integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= + retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" @@ -10479,6 +11199,13 @@ rimraf@^2.5.4, rimraf@^2.6.3, rimraf@^2.7.1: dependencies: glob "^7.1.3" +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -10642,6 +11369,11 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== +semver@^7.0.0, semver@^7.1.1, semver@^7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -10689,7 +11421,7 @@ serve-static@1.14.1: parseurl "~1.3.3" send "0.17.1" -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= @@ -10827,6 +11559,11 @@ slice-ansi@^2.1.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" +smart-buffer@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" + integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw== + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -10932,6 +11669,23 @@ sockjs@0.3.19: faye-websocket "^0.10.0" uuid "^3.0.1" +socks-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60" + integrity sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA== + dependencies: + agent-base "6" + debug "4" + socks "^2.3.3" + +socks@^2.3.3: + version "2.5.0" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.5.0.tgz#3a7c286db114f67864a4bd8b4207a91d1db3d6db" + integrity sha512-00OqQHp5SCbwm9ecOMJj9aQtMSjwi1uVuGQoxnpKCS50VKZcOZ8z11CTKypmR8sEy7nZimy/qXY7rYJYbRlXmA== + dependencies: + ip "^1.1.5" + smart-buffer "^4.1.0" + sort-keys@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" @@ -11105,6 +11859,13 @@ ssri@^7.0.0: figgy-pudding "^3.5.1" minipass "^3.1.1" +ssri@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.0.tgz#79ca74e21f8ceaeddfcb4b90143c458b8d988808" + integrity sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA== + dependencies: + minipass "^3.1.1" + stable@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" @@ -11207,7 +11968,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^2.0.0, string-width@^2.1.1: +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -11468,6 +12229,18 @@ tapable@^1.0.0, tapable@^1.1.0, tapable@^1.1.3: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== +tar@^6.0.1, tar@^6.0.2: + version "6.0.5" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.5.tgz#bde815086e10b39f1dcd298e89d596e1535e200f" + integrity sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + tarn@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/tarn/-/tarn-1.1.5.tgz#7be88622e951738b9fa3fb77477309242cdddc2d" @@ -11666,7 +12439,7 @@ touch@^3.1.0: dependencies: nopt "~1.0.10" -tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.4.3, tough-cookie@^2.5.0: +tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.4.3, tough-cookie@^2.5.0, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== @@ -11694,6 +12467,11 @@ tree-kill@^1.2.2: resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== +trough@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" + integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== + ts-jest@^25.2.1: version "25.2.1" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-25.2.1.tgz#49bf05da26a8b7fbfbc36b4ae2fcdc2fef35c85d" @@ -11847,6 +12625,18 @@ unicode-property-aliases-ecmascript@^1.0.4: resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz#a9cc6cc7ce63a0a3023fc99e341b94431d405a57" integrity sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw== +unified@^9.0.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.0.tgz#67a62c627c40589edebbf60f53edfd4d822027f8" + integrity sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg== + dependencies: + bail "^1.0.0" + extend "^3.0.0" + is-buffer "^2.0.0" + is-plain-obj "^2.0.0" + trough "^1.0.0" + vfile "^4.0.0" + union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" @@ -11888,6 +12678,40 @@ unique-string@^1.0.0: dependencies: crypto-random-string "^1.0.0" +unist-util-is@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.0.3.tgz#e8b44db55fc20c43752b3346c116344d45d7c91d" + integrity sha512-bTofCFVx0iQM8Jqb1TBDVRIQW03YkD3p66JOd/aCWuqzlLyUtx1ZAGw/u+Zw+SttKvSVcvTiKYbfrtLoLefykw== + +unist-util-stringify-position@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" + integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== + dependencies: + "@types/unist" "^2.0.2" + +unist-util-visit-parents@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-1.1.2.tgz#f6e3afee8bdbf961c0e6f028ea3c0480028c3d06" + integrity sha512-yvo+MMLjEwdc3RhhPYSximset7rwjMrdt9E41Smmvg25UQIenzrN83cRnF1JMzoMi9zZOQeYXHSDf7p+IQkW3Q== + +unist-util-visit-parents@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6" + integrity sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^4.0.0" + +unist-util-visit@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" + integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^4.0.0" + unist-util-visit-parents "^3.0.0" + universalify@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" @@ -12061,6 +12885,13 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +validate-npm-package-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" + integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= + dependencies: + builtins "^1.0.3" + vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -12080,6 +12911,25 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" +vfile-message@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" + integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== + dependencies: + "@types/unist" "^2.0.0" + unist-util-stringify-position "^2.0.0" + +vfile@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.0.tgz#26c78ac92eb70816b01d4565e003b7e65a2a0e01" + integrity sha512-a/alcwCvtuc8OX92rqqo7PflxiCgXRFjdyoGVuYV+qbgCb0GgZJRvIgCD4+U/Kl1yhaRsaTwksF88xbPyGsgpw== + dependencies: + "@types/unist" "^2.0.0" + is-buffer "^2.0.0" + replace-ext "1.0.0" + unist-util-stringify-position "^2.0.0" + vfile-message "^2.0.0" + vm-browserify@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" @@ -12358,13 +13208,20 @@ which@^1.2.14, which@^1.2.9, which@^1.3.0, which@^1.3.1: dependencies: isexe "^2.0.0" -which@^2.0.1: +which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + widest-line@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" @@ -12667,7 +13524,7 @@ xpath.js@~1.1.0: resolved "https://registry.yarnpkg.com/xpath.js/-/xpath.js-1.1.0.tgz#3816a44ed4bb352091083d002a383dd5104a5ff1" integrity sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ== -xtend@^4.0.0, xtend@~4.0.1: +xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== From e14165c403a4809164c5ade220365188c006ef20 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 21 Nov 2020 17:33:59 +0100 Subject: [PATCH 03/30] install/uninstall plugin --- packages/api/src/controllers/plugins.js | 75 +++++++++++++--- packages/web/public/unknown.svg | 15 ++++ packages/web/src/plugins/PluginIcon.js | 7 -- packages/web/src/plugins/PluginsList.js | 28 +++--- packages/web/src/plugins/PluginsProvider.js | 45 +++++++--- .../web/src/plugins/manifestExtractors.js | 20 +++++ packages/web/src/tabs/PluginTab.js | 88 ++++++++++++++++--- packages/web/src/utility/metadataLoaders.js | 13 +++ packages/web/src/widgets/PluginsWidget.js | 26 +----- 9 files changed, 234 insertions(+), 83 deletions(-) create mode 100644 packages/web/public/unknown.svg delete mode 100644 packages/web/src/plugins/PluginIcon.js create mode 100644 packages/web/src/plugins/manifestExtractors.js diff --git a/packages/api/src/controllers/plugins.js b/packages/api/src/controllers/plugins.js index aac64d95b..3abcbc968 100644 --- a/packages/api/src/controllers/plugins.js +++ b/packages/api/src/controllers/plugins.js @@ -2,12 +2,32 @@ const fs = require('fs-extra'); const fetch = require('node-fetch'); const path = require('path'); const pacote = require('pacote'); -const { pluginstmpdir } = require('../utility/directories'); +const { pluginstmpdir, pluginsdir } = require('../utility/directories'); +const socket = require('../utility/socket'); + +async function loadPackageInfo(dir) { + const readmeFile = path.join(dir, 'README.md'); + const packageFile = path.join(dir, 'package.json'); + + if (!(await fs.exists(packageFile))) { + return null; + } + + let readme = null; + let manifest = null; + if (await fs.exists(readmeFile)) readme = await fs.readFile(readmeFile, { encoding: 'utf-8' }); + if (await fs.exists(packageFile)) manifest = JSON.parse(await fs.readFile(packageFile, { encoding: 'utf-8' })); + return { + readme, + manifest, + }; +} module.exports = { script_meta: 'get', async script({ packageName }) { - const data = await fs.readFile('/home/jena/jenasoft/dbgate-plugin-csv/lib/frontend.js', { + const file = path.join(pluginsdir(), packageName, 'lib', 'frontend.js'); + const data = await fs.readFile(file, { encoding: 'utf-8', }); return data; @@ -15,21 +35,54 @@ module.exports = { search_meta: 'get', async search({ filter }) { - const response = await fetch(`https://api.npms.io/v2/search?q=keywords:dbgate ${encodeURIComponent(filter)}`); + // const response = await fetch(`https://api.npms.io/v2/search?q=keywords:dbgate ${encodeURIComponent(filter)}`); + // const json = await response.json(); + // const { results } = json || {}; + // return (results || []).map((x) => x.package); + + const response = await fetch( + `https://www.npmjs.com/search/suggestions?q=dbgate-plugin ${encodeURIComponent(filter)}` + ); const json = await response.json(); - console.log(json); - const { results } = json || {}; - return results || []; + return json || []; }, - readme_meta: 'get', - async readme({ packageName }) { + info_meta: 'get', + async info({ packageName }) { const dir = path.join(pluginstmpdir(), packageName); if (!(await fs.exists(dir))) { await pacote.extract(packageName, dir); } - const file = path.join(dir, 'README.md'); - if (await fs.exists(file)) return await fs.readFile(file, { encoding: 'utf-8' }); - return ''; + return await loadPackageInfo(dir); + // return await { + // ...loadPackageInfo(dir), + // installed: loadPackageInfo(path.join(pluginsdir(), packageName)), + // }; + }, + + installed_meta: 'get', + async installed() { + const files = await fs.readdir(pluginsdir()); + return await Promise.all( + files.map((packageName) => + fs.readFile(path.join(pluginsdir(), packageName, 'package.json')).then((x) => JSON.parse(x)) + ) + ); + }, + + install_meta: 'post', + async install({ packageName }) { + const dir = path.join(pluginsdir(), packageName); + if (!(await fs.exists(dir))) { + await pacote.extract(packageName, dir); + } + socket.emitChanged(`installed-plugins-changed`); + }, + + uninstall_meta: 'post', + async uninstall({ packageName }) { + const dir = path.join(pluginsdir(), packageName); + await fs.rmdir(dir, { recursive: true }); + socket.emitChanged(`installed-plugins-changed`); }, }; diff --git a/packages/web/public/unknown.svg b/packages/web/public/unknown.svg new file mode 100644 index 000000000..ff30dd8cf --- /dev/null +++ b/packages/web/public/unknown.svg @@ -0,0 +1,15 @@ + + + + + + + + image/svg+xml + + + + + + ? + \ No newline at end of file diff --git a/packages/web/src/plugins/PluginIcon.js b/packages/web/src/plugins/PluginIcon.js deleted file mode 100644 index bfc0f211e..000000000 --- a/packages/web/src/plugins/PluginIcon.js +++ /dev/null @@ -1,7 +0,0 @@ -import React from 'react'; - -export default function PluginIcon({ plugin, className = undefined }) { - return ( - - ); -} diff --git a/packages/web/src/plugins/PluginsList.js b/packages/web/src/plugins/PluginsList.js index 608fa5541..41b6de3a6 100644 --- a/packages/web/src/plugins/PluginsList.js +++ b/packages/web/src/plugins/PluginsList.js @@ -3,7 +3,7 @@ import styled from 'styled-components'; import useTheme from '../theme/useTheme'; import { openNewTab } from '../utility/common'; import { useSetOpenedTabs } from '../utility/globalState'; -import PluginIcon from './PluginIcon'; +import { extractPluginIcon, extractPluginAuthor } from '../plugins/manifestExtractors'; const Wrapper = styled.div` margin: 1px 3px 10px 5px; @@ -26,7 +26,7 @@ const Line = styled.div` display: flex; `; -const Icon = styled(PluginIcon)` +const Icon = styled.img` width: 50px; height: 50px; `; @@ -43,33 +43,33 @@ const Version = styled.div` margin-left: 5px; `; -function openPlugin(setOpenedTabs, plugin) { +function openPlugin(setOpenedTabs, packageManifest) { openNewTab(setOpenedTabs, { - title: plugin.package.name, + title: packageManifest.name, icon: 'icon plugin', tabComponent: 'PluginTab', props: { - plugin, + packageName: packageManifest.name, }, }); } -function PluginsListItem({ plugin }) { +function PluginsListItem({ packageManifest }) { const setOpenedTabs = useSetOpenedTabs(); const theme = useTheme(); return ( - openPlugin(setOpenedTabs, plugin)} theme={theme}> - + openPlugin(setOpenedTabs, packageManifest)} theme={theme}> + - {plugin.package.name} - {plugin.package.version} + {packageManifest.name} + {packageManifest.version} - {plugin.package.description} + {packageManifest.description} - {plugin.package.author && plugin.package.author.name} + {extractPluginAuthor(packageManifest)} @@ -79,8 +79,8 @@ function PluginsListItem({ plugin }) { export default function PluginsList({ plugins }) { return ( <> - {plugins.map((plugin) => ( - + {plugins.map((packageManifest) => ( + ))} ); diff --git a/packages/web/src/plugins/PluginsProvider.js b/packages/web/src/plugins/PluginsProvider.js index cac3487db..762e0b546 100644 --- a/packages/web/src/plugins/PluginsProvider.js +++ b/packages/web/src/plugins/PluginsProvider.js @@ -1,23 +1,40 @@ import React from 'react'; +import _ from 'lodash'; import axios from '../utility/axios'; +import { useInstalledPlugins } from '../utility/metadataLoaders'; const PluginsContext = React.createContext(null); export default function PluginsProvider({ children }) { - const [plugins, setPlugins] = React.useState(null); - const handleLoadPlugin = async () => { - const resp = await axios.request({ - method: 'get', - url: 'plugins/script', - params: { - plugin: 'csv', - }, - }); - const module = eval(resp.data); - console.log('MODULE', module); + const installedPlugins = useInstalledPlugins(); + const [plugins, setPlugins] = React.useState({}); + const handleLoadPlugins = async () => { + setPlugins((x) => + _.pick( + x, + installedPlugins.map((y) => y.name) + ) + ); + for (const installed of installedPlugins) { + if (!_.keys(plugins).includes(installed.name)) { + console.log('Loading module', installed.name); + const resp = await axios.request({ + method: 'get', + url: 'plugins/script', + params: { + packageName: installed.name, + }, + }); + const module = eval(resp.data); + setPlugins((v) => ({ + ...v, + [installed.name]: module, + })); + } + } }; React.useEffect(() => { - handleLoadPlugin(); - }, []); - return {children}; + handleLoadPlugins(); + }, [installedPlugins]); + return {children}; } diff --git a/packages/web/src/plugins/manifestExtractors.js b/packages/web/src/plugins/manifestExtractors.js new file mode 100644 index 000000000..715f2db65 --- /dev/null +++ b/packages/web/src/plugins/manifestExtractors.js @@ -0,0 +1,20 @@ +import _ from 'lodash'; + +export function extractPluginIcon(packageManifest) { + const { links } = packageManifest || {}; + const { repository, homepage } = links || {}; + const tested = repository || homepage || packageManifest.homepage; + + if (tested) { + const match = tested.match(/https:\/\/github.com\/([^/]*)\/([^/]*)/); + if (match) { + return `https://raw.githubusercontent.com/${match[1]}/${match[2]}/master/icon.svg`; + } + } + // eslint-disable-next-line no-undef + return `${process.env.PUBLIC_URL}/unknown.svg`; +} + +export function extractPluginAuthor(packageManifest) { + return _.isPlainObject(packageManifest.author) ? packageManifest.author.name : packageManifest.author; +} diff --git a/packages/web/src/tabs/PluginTab.js b/packages/web/src/tabs/PluginTab.js index e3576531b..27698f72f 100644 --- a/packages/web/src/tabs/PluginTab.js +++ b/packages/web/src/tabs/PluginTab.js @@ -2,14 +2,13 @@ import React from 'react'; import styled from 'styled-components'; import _ from 'lodash'; import ReactMarkdown from 'react-markdown'; -import ObjectListControl from '../utility/ObjectListControl'; -import { TableColumn } from '../utility/TableControl'; -import columnAppObject from '../appobj/columnAppObject'; -import constraintAppObject from '../appobj/constraintAppObject'; -import { useTableInfo, useDbCore } from '../utility/metadataLoaders'; import useTheme from '../theme/useTheme'; import useFetch from '../utility/useFetch'; import LoadingInfo from '../widgets/LoadingInfo'; +import { extractPluginIcon, extractPluginAuthor } from '../plugins/manifestExtractors'; +import FormStyledButton from '../widgets/FormStyledButton'; +import axios from '../utility/axios'; +import { useInstalledPlugins } from '../utility/metadataLoaders'; const WhitePage = styled.div` position: absolute; @@ -22,23 +21,84 @@ const WhitePage = styled.div` padding: 10px; `; -const Title = styled.div` - font-size: 20pt; - border-bottom: 1px solid ${(props) => props.theme.border}; +const Icon = styled.img` + width: 80px; + height: 80px; `; -export default function PluginTab({ plugin }) { +const Header = styled.div` + display: flex; + border-bottom: 1px solid ${(props) => props.theme.border}; + margin-bottom: 20px; + padding-bottom: 20px; +`; + +const HeaderBody = styled.div` + margin-left: 10px; +`; + +const Title = styled.div` + font-size: 20pt; +`; + +const HeaderLine = styled.div` + margin-top: 5px; +`; + +const Author = styled.span` + font-weight: bold; +`; + +const Version = styled.span``; + +function Delimiter() { + return | ; +} + +export default function PluginTab({ packageName }) { const theme = useTheme(); - const packageName = plugin.package.name; - const readme = useFetch({ + const installed = useInstalledPlugins(); + const info = useFetch({ params: { packageName }, - url: 'plugins/readme', + url: 'plugins/info', defaultValue: null, }); + const { readme, manifest } = info || {}; + const handleInstall = async () => { + axios.post('plugins/install', { packageName }); + }; + const handleUninstall = async () => { + axios.post('plugins/uninstall', { packageName }); + }; + return ( - {packageName} - {readme == null ? : {readme}} + {info == null || manifest == null ? ( + + ) : ( + <> +
+ + + {packageName} + + {extractPluginAuthor(manifest)} + + {manifest.version && manifest.version} + + + {!installed.find((x) => x.name == packageName) && ( + + )} + {!!installed.find((x) => x.name == packageName) && ( + + )} + + +
+ {readme} + + )}
); } diff --git a/packages/web/src/utility/metadataLoaders.js b/packages/web/src/utility/metadataLoaders.js index 583075919..5ac8b597e 100644 --- a/packages/web/src/utility/metadataLoaders.js +++ b/packages/web/src/utility/metadataLoaders.js @@ -88,6 +88,12 @@ const connectionListLoader = () => ({ reloadTrigger: `connection-list-changed`, }); +const insttalledPluginsLoader = () => ({ + url: 'plugins/installed', + params: {}, + reloadTrigger: `installed-plugins-changed`, +}); + async function getCore(loader, args) { const { url, params, reloadTrigger, transform } = loader(args); const key = stableStringify({ url, ...params }); @@ -243,3 +249,10 @@ export function getArchiveFolders(args) { export function useArchiveFolders(args) { return useCore(archiveFoldersLoader, args); } + +export function getInstalledPlugins(args) { + return getCore(insttalledPluginsLoader, args) || []; +} +export function useInstalledPlugins(args) { + return useCore(insttalledPluginsLoader, args) || []; +} diff --git a/packages/web/src/widgets/PluginsWidget.js b/packages/web/src/widgets/PluginsWidget.js index 9796fdf05..6479cfa51 100644 --- a/packages/web/src/widgets/PluginsWidget.js +++ b/packages/web/src/widgets/PluginsWidget.js @@ -1,37 +1,17 @@ import React from 'react'; -import _ from 'lodash'; - -import { AppObjectList } from '../appobj/AppObjectList'; -import { useCurrentArchive, useSetCurrentArchive } from '../utility/globalState'; import { SearchBoxWrapper, WidgetsInnerContainer } from './WidgetStyles'; import WidgetColumnBar, { WidgetColumnBarItem } from './WidgetColumnBar'; -import { useArchiveFiles, useArchiveFolders } from '../utility/metadataLoaders'; -import archiveFolderAppObject from '../appobj/archiveFolderAppObject'; -import archiveFileAppObject from '../appobj/archiveFileAppObject'; +import { useInstalledPlugins } from '../utility/metadataLoaders'; import SearchInput from './SearchInput'; -import InlineButton from './InlineButton'; -import axios from '../utility/axios'; import useFetch from '../utility/useFetch'; import PluginsList from '../plugins/PluginsList'; function InstalledPluginsList() { - // const folders = useArchiveFolders(); - // const [filter, setFilter] = React.useState(''); - - // const setArchive = useSetCurrentArchive(); - - // const handleRefreshFolders = () => { - // axios.post('archive/refresh-folders', {}); - // }; + const plugins = useInstalledPlugins(); return ( - {/* setArchive(archive.name)} - filter={filter} - /> */} + ); } From 8ab80340605d7651c5f6ae01cdb888f957d686e0 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 21 Nov 2020 17:40:16 +0100 Subject: [PATCH 04/30] usePlugins --- packages/web/src/plugins/PluginsProvider.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/packages/web/src/plugins/PluginsProvider.js b/packages/web/src/plugins/PluginsProvider.js index 762e0b546..7ae3fa25d 100644 --- a/packages/web/src/plugins/PluginsProvider.js +++ b/packages/web/src/plugins/PluginsProvider.js @@ -38,3 +38,15 @@ export default function PluginsProvider({ children }) { }, [installedPlugins]); return {children}; } + +export function usePlugins() { + const installed = useInstalledPlugins(); + const loaded = React.useContext(PluginsContext); + return installed + .map((manifest) => ({ + packageName: manifest.name, + manifest, + content: loaded[manifest.name], + })) + .filter((x) => x.content); +} From 3009724a821cac84e1f44209c1145f98a7eb6e68 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 21 Nov 2020 18:03:35 +0100 Subject: [PATCH 05/30] removed fileformatbase --- packages/types/fileformat.d.ts | 20 +++++++++++++++++++ packages/types/index.d.ts | 1 + packages/web/src/fileformats/csv.ts | 2 -- packages/web/src/fileformats/excel.ts | 2 -- .../web/src/fileformats/fileFormatBase.ts | 11 ---------- packages/web/src/fileformats/jsonl.ts | 2 -- packages/web/src/fileformats/types.ts | 2 +- .../src/impexp/ImportExportConfigurator.js | 12 +++++++++-- packages/web/src/utility/fileformats.js | 6 ++++++ 9 files changed, 38 insertions(+), 20 deletions(-) create mode 100644 packages/types/fileformat.d.ts delete mode 100644 packages/web/src/fileformats/fileFormatBase.ts create mode 100644 packages/web/src/utility/fileformats.js diff --git a/packages/types/fileformat.d.ts b/packages/types/fileformat.d.ts new file mode 100644 index 000000000..ccc569085 --- /dev/null +++ b/packages/types/fileformat.d.ts @@ -0,0 +1,20 @@ +export interface FileFormatDefinition { + storageType: string; + extension: string; + name: string; + readerFunc?: string; + writerFunc?: string; + args?: any[]; + addFilesToSourceList: ( + file: { + full: string; + }, + newSources: string[], + newValues: { + [key: string]: any; + } + ) => void; + getDefaultOutputName?: (sourceName, values) => string; + getOutputParams?: (sourceName, values) => any; + } + \ No newline at end of file diff --git a/packages/types/index.d.ts b/packages/types/index.d.ts index c8c9c73d8..12530325e 100644 --- a/packages/types/index.d.ts +++ b/packages/types/index.d.ts @@ -39,3 +39,4 @@ export * from './query'; export * from './dialect'; export * from './dumper'; export * from './dbtypes'; +export * from './fileformat'; diff --git a/packages/web/src/fileformats/csv.ts b/packages/web/src/fileformats/csv.ts index 1e7cd655d..595aa203b 100644 --- a/packages/web/src/fileformats/csv.ts +++ b/packages/web/src/fileformats/csv.ts @@ -1,8 +1,6 @@ -import fileFormatBase from './fileFormatBase'; import { FileFormatDefinition } from './types'; const csvFormat: FileFormatDefinition = { - ...fileFormatBase, storageType: 'csv', extension: 'csv', name: 'CSV', diff --git a/packages/web/src/fileformats/excel.ts b/packages/web/src/fileformats/excel.ts index 3b1920e80..847f201ad 100644 --- a/packages/web/src/fileformats/excel.ts +++ b/packages/web/src/fileformats/excel.ts @@ -1,9 +1,7 @@ import axios from '../utility/axios'; -import fileFormatBase from './fileFormatBase'; import { FileFormatDefinition } from './types'; const excelFormat: FileFormatDefinition = { - ...fileFormatBase, storageType: 'excel', extension: 'xlsx', name: 'MS Excel', diff --git a/packages/web/src/fileformats/fileFormatBase.ts b/packages/web/src/fileformats/fileFormatBase.ts deleted file mode 100644 index cb7bc1265..000000000 --- a/packages/web/src/fileformats/fileFormatBase.ts +++ /dev/null @@ -1,11 +0,0 @@ -const fileFormatBase = { - addFilesToSourceList: async (file, newSources, newValues) => { - const sourceName = file.name; - newSources.push(sourceName); - newValues[`sourceFile_${sourceName}`] = { - fileName: file.full, - }; - }, -}; - -export default fileFormatBase; diff --git a/packages/web/src/fileformats/jsonl.ts b/packages/web/src/fileformats/jsonl.ts index 02882140c..944f5fef7 100644 --- a/packages/web/src/fileformats/jsonl.ts +++ b/packages/web/src/fileformats/jsonl.ts @@ -1,8 +1,6 @@ -import fileFormatBase from './fileFormatBase'; import { FileFormatDefinition } from './types'; const jsonlFormat: FileFormatDefinition = { - ...fileFormatBase, storageType: 'jsonl', extension: 'jsonl', name: 'JSON lines', diff --git a/packages/web/src/fileformats/types.ts b/packages/web/src/fileformats/types.ts index de9929955..c669c63fd 100644 --- a/packages/web/src/fileformats/types.ts +++ b/packages/web/src/fileformats/types.ts @@ -5,7 +5,7 @@ export interface FileFormatDefinition { readerFunc?: string; writerFunc?: string; args?: any[]; - addFilesToSourceList: ( + addFilesToSourceList?: ( file: { full: string; }, diff --git a/packages/web/src/impexp/ImportExportConfigurator.js b/packages/web/src/impexp/ImportExportConfigurator.js index b416f3ca5..ac137b503 100644 --- a/packages/web/src/impexp/ImportExportConfigurator.js +++ b/packages/web/src/impexp/ImportExportConfigurator.js @@ -97,14 +97,22 @@ function getFileFilters(storageType) { return res; } +async function addFilesToSourceListDefault(file, newSources, newValues) { + const sourceName = file.name; + newSources.push(sourceName); + newValues[`sourceFile_${sourceName}`] = { + fileName: file.full, + }; +} + async function addFilesToSourceList(files, values, setValues, preferedStorageType, setPreviewSource) { const newSources = []; const newValues = {}; const storage = preferedStorageType || values.sourceStorageType; for (const file of getAsArray(files)) { const format = findFileFormat(storage); - if (format && format.addFilesToSourceList) { - await format.addFilesToSourceList(file, newSources, newValues); + if (format) { + await (format.addFilesToSourceList || addFilesToSourceListDefault)(file, newSources, newValues); } } newValues['sourceList'] = [...(values.sourceList || []).filter((x) => !newSources.includes(x)), ...newSources]; diff --git a/packages/web/src/utility/fileformats.js b/packages/web/src/utility/fileformats.js new file mode 100644 index 000000000..2cf6b4578 --- /dev/null +++ b/packages/web/src/utility/fileformats.js @@ -0,0 +1,6 @@ +import { usePlugins } from '../plugins/PluginsProvider'; + +export function useFileFormats() { + const plugins = usePlugins(); + return []; +} From 5ec39054a30d35ab59d3aece560ab19bf8b3005f Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 21 Nov 2020 20:12:33 +0100 Subject: [PATCH 06/30] extensions refactor --- packages/web/src/App.js | 22 ++--- packages/web/src/DragAndDropFileTarget.js | 5 +- packages/web/src/appobj/databaseAppObject.js | 8 +- packages/web/src/fileformats/csv.ts | 39 --------- packages/web/src/fileformats/excel.ts | 50 ----------- packages/web/src/fileformats/index.ts | 20 ----- packages/web/src/fileformats/jsonl.ts | 11 --- packages/web/src/fileformats/types.ts | 19 ----- .../src/impexp/ImportExportConfigurator.js | 43 ++++++---- packages/web/src/impexp/createImpExpScript.js | 40 ++++----- packages/web/src/modals/ImportExportModal.js | 13 +-- packages/web/src/plugins/PluginsProvider.js | 38 +++++---- packages/web/src/utility/UploadsProvider.js | 8 +- packages/web/src/utility/fileformats.js | 82 ++++++++++++++++++- packages/web/src/utility/globalState.js | 2 + packages/web/src/utility/metadataLoaders.js | 6 +- packages/web/src/utility/useExtensions.js | 15 ++++ packages/web/src/widgets/Toolbar.js | 6 +- 18 files changed, 200 insertions(+), 227 deletions(-) delete mode 100644 packages/web/src/fileformats/csv.ts delete mode 100644 packages/web/src/fileformats/excel.ts delete mode 100644 packages/web/src/fileformats/index.ts delete mode 100644 packages/web/src/fileformats/jsonl.ts delete mode 100644 packages/web/src/fileformats/types.ts create mode 100644 packages/web/src/utility/useExtensions.js diff --git a/packages/web/src/App.js b/packages/web/src/App.js index b8bd715de..0497767a6 100644 --- a/packages/web/src/App.js +++ b/packages/web/src/App.js @@ -28,18 +28,18 @@ function App() { - - - - - + + + + + - - - - - - + + + +
+ + diff --git a/packages/web/src/DragAndDropFileTarget.js b/packages/web/src/DragAndDropFileTarget.js index 41e0211f0..85ece2ec1 100644 --- a/packages/web/src/DragAndDropFileTarget.js +++ b/packages/web/src/DragAndDropFileTarget.js @@ -1,8 +1,8 @@ import React from 'react'; import styled from 'styled-components'; -import { fileformats } from './fileformats'; import { FontIcon } from './icons'; import useTheme from './theme/useTheme'; +import useExtensions from './utility/useExtensions'; const TargetStyled = styled.div` position: fixed; @@ -40,6 +40,7 @@ const TitleWrapper = styled.div` export default function DragAndDropFileTarget({ isDragActive, inputProps }) { const theme = useTheme(); + const { fileFormats } = useExtensions(); return ( !!isDragActive && ( @@ -50,7 +51,7 @@ export default function DragAndDropFileTarget({ isDragActive, inputProps }) { Drop the files to upload to DbGate Supported file types:{' '} - {fileformats + {fileFormats .filter((x) => x.readerFunc) .map((x) => x.name) .join(', ')} diff --git a/packages/web/src/appobj/databaseAppObject.js b/packages/web/src/appobj/databaseAppObject.js index ae4598f49..7e3db8f17 100644 --- a/packages/web/src/appobj/databaseAppObject.js +++ b/packages/web/src/appobj/databaseAppObject.js @@ -3,9 +3,9 @@ import _ from 'lodash'; import { DropDownMenuItem } from '../modals/DropDownMenu'; import { openNewTab } from '../utility/common'; import ImportExportModal from '../modals/ImportExportModal'; -import { defaultFileFormat } from '../fileformats'; +import { getDefaultFileFormat } from '../utility/fileformats'; -function Menu({ data, setOpenedTabs, showModal }) { +function Menu({ data, setOpenedTabs, showModal, extensions }) { const { connection, name } = data; const tooltip = `${connection.displayName || connection.server}\n${name}`; @@ -27,7 +27,7 @@ function Menu({ data, setOpenedTabs, showModal }) { { - const resp = await axios.get(`files/analyse-excel?filePath=${encodeURIComponent(file.full)}`); - const sheetNames = resp.data; - for (const sheetName of sheetNames) { - newSources.push(sheetName); - newValues[`sourceFile_${sheetName}`] = { - fileName: file.full, - sheetName, - }; - } - }, - - args: [ - { - type: 'checkbox', - name: 'singleFile', - label: 'Create single file', - direction: 'target', - }, - ], - - getDefaultOutputName: (sourceName, values) => { - if (values.target_excel_singleFile) { - return sourceName; - } - return null; - }, - - getOutputParams: (sourceName, values) => { - if (values.target_excel_singleFile) { - return { - sheetName: values[`targetName_${sourceName}`] || sourceName, - fileName:'data.xlsx' - }; - } - return null; - }, -}; - -export default excelFormat; diff --git a/packages/web/src/fileformats/index.ts b/packages/web/src/fileformats/index.ts deleted file mode 100644 index 2824490fe..000000000 --- a/packages/web/src/fileformats/index.ts +++ /dev/null @@ -1,20 +0,0 @@ -import csv from './csv'; -import jsonl from './jsonl'; -import excel from './excel'; -import { FileFormatDefinition } from './types'; - -export const fileformats = [csv, jsonl, excel]; - -export function findFileFormat(storageType): FileFormatDefinition { - return fileformats.find((x) => x.storageType == storageType); -} - -export function getFileFormatDirections(format: FileFormatDefinition) { - if (!format) return []; - const res = []; - if (format.readerFunc) res.push('source'); - if (format.writerFunc) res.push('target'); - return res; -} - -export const defaultFileFormat = csv; \ No newline at end of file diff --git a/packages/web/src/fileformats/jsonl.ts b/packages/web/src/fileformats/jsonl.ts deleted file mode 100644 index 944f5fef7..000000000 --- a/packages/web/src/fileformats/jsonl.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { FileFormatDefinition } from './types'; - -const jsonlFormat: FileFormatDefinition = { - storageType: 'jsonl', - extension: 'jsonl', - name: 'JSON lines', - readerFunc: 'jsonLinesReader', - writerFunc: 'jsonLinesWriter', -}; - -export default jsonlFormat; diff --git a/packages/web/src/fileformats/types.ts b/packages/web/src/fileformats/types.ts deleted file mode 100644 index c669c63fd..000000000 --- a/packages/web/src/fileformats/types.ts +++ /dev/null @@ -1,19 +0,0 @@ -export interface FileFormatDefinition { - storageType: string; - extension: string; - name: string; - readerFunc?: string; - writerFunc?: string; - args?: any[]; - addFilesToSourceList?: ( - file: { - full: string; - }, - newSources: string[], - newValues: { - [key: string]: any; - } - ) => void; - getDefaultOutputName?: (sourceName, values) => string; - getOutputParams?: (sourceName, values) => any; -} diff --git a/packages/web/src/impexp/ImportExportConfigurator.js b/packages/web/src/impexp/ImportExportConfigurator.js index ac137b503..6913ef286 100644 --- a/packages/web/src/impexp/ImportExportConfigurator.js +++ b/packages/web/src/impexp/ImportExportConfigurator.js @@ -12,10 +12,10 @@ import { FormArchiveFolderSelect, FormArchiveFilesSelect, } from '../utility/forms'; -import { useArchiveFiles, useConnectionInfo, useDatabaseInfo } from '../utility/metadataLoaders'; +import { useArchiveFiles, useConnectionInfo, useDatabaseInfo, useInstalledPlugins } from '../utility/metadataLoaders'; import TableControl, { TableColumn } from '../utility/TableControl'; import { TextField, SelectField, CheckboxField } from '../utility/inputs'; -import { createPreviewReader, getActionOptions, getTargetName, isFileStorage } from './createImpExpScript'; +import { createPreviewReader, getActionOptions, getTargetName } from './createImpExpScript'; import getElectron from '../utility/getElectron'; import ErrorInfo from '../widgets/ErrorInfo'; import getAsArray from '../utility/getAsArray'; @@ -25,8 +25,9 @@ import SqlEditor from '../sqleditor/SqlEditor'; import { useUploadsProvider } from '../utility/UploadsProvider'; import { FontIcon } from '../icons'; import useTheme from '../theme/useTheme'; -import { fileformats, findFileFormat, getFileFormatDirections } from '../fileformats'; +import { findFileFormat, getFileFormatDirections } from '../utility/fileformats'; import FormArgumentList from '../utility/FormArgumentList'; +import useExtensions from '../utility/useExtensions'; const Container = styled.div` // max-height: 50vh; @@ -89,9 +90,9 @@ const Title = styled.div` margin: 10px 0px; `; -function getFileFilters(storageType) { +function getFileFilters(extensions, storageType) { const res = []; - const format = findFileFormat(storageType); + const format = findFileFormat(extensions, storageType); if (format) res.push({ name: format.name, extensions: [format.extension] }); res.push({ name: 'All Files', extensions: ['*'] }); return res; @@ -105,12 +106,12 @@ async function addFilesToSourceListDefault(file, newSources, newValues) { }; } -async function addFilesToSourceList(files, values, setValues, preferedStorageType, setPreviewSource) { +async function addFilesToSourceList(extensions, files, values, setValues, preferedStorageType, setPreviewSource) { const newSources = []; const newValues = {}; const storage = preferedStorageType || values.sourceStorageType; for (const file of getAsArray(files)) { - const format = findFileFormat(storage); + const format = findFileFormat(extensions, storage); if (format) { await (format.addFilesToSourceList || addFilesToSourceListDefault)(file, newSources, newValues); } @@ -132,17 +133,19 @@ function ElectronFilesInput() { const { values, setValues } = useFormikContext(); const electron = getElectron(); const [isLoading, setIsLoading] = React.useState(false); + const extensions = useExtensions(); const handleClick = async () => { const files = electron.remote.dialog.showOpenDialogSync(electron.remote.getCurrentWindow(), { properties: ['openFile', 'multiSelections'], - filters: getFileFilters(values.sourceStorageType), + filters: getFileFilters(extensions, values.sourceStorageType), }); if (files) { const path = window.require('path'); try { setIsLoading(true); await addFilesToSourceList( + extensions, files.map((full) => ({ full, ...path.parse(full), @@ -183,6 +186,7 @@ function SourceTargetConfig({ tablesField = undefined, engine = undefined, }) { + const extensions = useExtensions(); const theme = useTheme(); const { values, setFieldValue } = useFormikContext(); const types = @@ -190,7 +194,7 @@ function SourceTargetConfig({ ? [{ value: 'jsldata', label: 'Query result data', directions: ['source'] }] : [ { value: 'database', label: 'Database', directions: ['source', 'target'] }, - ...fileformats.map((format) => ({ + ...extensions.fileFormats.map((format) => ({ value: format.storageType, label: `${format.name} files(s)`, directions: getFileFormatDirections(format), @@ -201,7 +205,7 @@ function SourceTargetConfig({ const storageType = values[storageTypeField]; const dbinfo = useDatabaseInfo({ conid: values[connectionIdField], database: values[databaseNameField] }); const archiveFiles = useArchiveFiles({ folder: values[archiveFolderField] }); - const format = findFileFormat(storageType); + const format = findFileFormat(extensions, storageType); return ( {direction == 'source' && ( @@ -348,10 +352,17 @@ export default function ImportExportConfigurator({ uploadedFile = undefined, onC const { setUploadListener } = useUploadsProvider(); const theme = useTheme(); const [previewSource, setPreviewSource] = React.useState(null); + const extensions = useExtensions(); + + console.log('ImportExportConfigurator', extensions); + const installed = useInstalledPlugins(); + console.log('installed', installed); const handleUpload = React.useCallback( (file) => { + console.log('UPLOAD', extensions); addFilesToSourceList( + extensions, [ { full: file.filePath, @@ -365,7 +376,7 @@ export default function ImportExportConfigurator({ uploadedFile = undefined, onC ); // setFieldValue('sourceList', [...(sourceList || []), file.originalName]); }, - [setFieldValue, sourceList, values] + [extensions, setFieldValue, sourceList, values] ); React.useEffect(() => { @@ -381,11 +392,11 @@ export default function ImportExportConfigurator({ uploadedFile = undefined, onC } }, []); - const supportsPreview = !!findFileFormat(values.sourceStorageType); + const supportsPreview = !!findFileFormat(extensions, values.sourceStorageType); const handleChangePreviewSource = async () => { if (previewSource && supportsPreview) { - const reader = await createPreviewReader(values, previewSource); + const reader = await createPreviewReader(extensions, values, previewSource); if (onChangePreview) onChangePreview(reader); } else { onChangePreview(null); @@ -444,8 +455,8 @@ export default function ImportExportConfigurator({ uploadedFile = undefined, onC header="Action" formatter={(row) => ( setFieldValue(`actionType_${row}`, e.target.value)} /> )} @@ -455,7 +466,7 @@ export default function ImportExportConfigurator({ uploadedFile = undefined, onC header="Target" formatter={(row) => ( setFieldValue(`targetName_${row}`, e.target.value)} /> )} diff --git a/packages/web/src/impexp/createImpExpScript.js b/packages/web/src/impexp/createImpExpScript.js index feb068550..d5826d4c3 100644 --- a/packages/web/src/impexp/createImpExpScript.js +++ b/packages/web/src/impexp/createImpExpScript.js @@ -4,12 +4,12 @@ import getAsArray from '../utility/getAsArray'; import { getConnectionInfo } from '../utility/metadataLoaders'; import engines from 'dbgate-engines'; import { findObjectLike } from 'dbgate-tools'; -import { findFileFormat } from '../fileformats'; +import { findFileFormat } from '../utility/fileformats'; -export function getTargetName(source, values) { +export function getTargetName(extensions, source, values) { const key = `targetName_${source}`; if (values[key]) return values[key]; - const format = findFileFormat(values.targetStorageType); + const format = findFileFormat(extensions, values.targetStorageType); if (format) { const res = format.getDefaultOutputName ? format.getDefaultOutputName(source, values) : null; if (res) return res; @@ -18,10 +18,6 @@ export function getTargetName(source, values) { return source; } -export function isFileStorage(storageType) { - return !!findFileFormat(storageType); -} - function extractApiParameters(values, direction, format) { const pairs = (format.args || []) .filter((arg) => arg.apiName) @@ -45,7 +41,7 @@ async function getConnection(storageType, conid, database) { return [null, null]; } -function getSourceExpr(sourceName, values, sourceConnection, sourceDriver) { +function getSourceExpr(extensions, sourceName, values, sourceConnection, sourceDriver) { const { sourceStorageType } = values; if (sourceStorageType == 'database') { const fullName = { schemaName: values.sourceSchemaName, pureName: sourceName }; @@ -66,9 +62,9 @@ function getSourceExpr(sourceName, values, sourceConnection, sourceDriver) { }, ]; } - if (isFileStorage(sourceStorageType)) { + if (findFileFormat(extensions, sourceStorageType)) { const sourceFile = values[`sourceFile_${sourceName}`]; - const format = findFileFormat(sourceStorageType); + const format = findFileFormat(extensions, sourceStorageType); if (format && format.readerFunc) { return [ format.readerFunc, @@ -113,9 +109,9 @@ function getFlagsFroAction(action) { }; } -function getTargetExpr(sourceName, values, targetConnection, targetDriver) { +function getTargetExpr(extensions, sourceName, values, targetConnection, targetDriver) { const { targetStorageType } = values; - const format = findFileFormat(targetStorageType); + const format = findFileFormat(extensions, targetStorageType); if (format && format.writerFunc) { const outputParams = format.getOutputParams && format.getOutputParams(sourceName, values); return [ @@ -124,7 +120,7 @@ function getTargetExpr(sourceName, values, targetConnection, targetDriver) { ...(outputParams ? outputParams : { - fileName: getTargetName(sourceName, values), + fileName: getTargetName(extensions, sourceName, values), }), ...extractApiParameters(values, 'target', format), }, @@ -136,7 +132,7 @@ function getTargetExpr(sourceName, values, targetConnection, targetDriver) { { connection: targetConnection, schemaName: values.targetSchemaName, - pureName: getTargetName(sourceName, values), + pureName: getTargetName(extensions, sourceName, values), ...getFlagsFroAction(values[`actionType_${sourceName}`]), }, ]; @@ -146,7 +142,7 @@ function getTargetExpr(sourceName, values, targetConnection, targetDriver) { 'archiveWriter', { folderName: values.targetArchiveFolder, - fileName: getTargetName(sourceName, values), + fileName: getTargetName(extensions, sourceName, values), }, ]; } @@ -154,7 +150,7 @@ function getTargetExpr(sourceName, values, targetConnection, targetDriver) { throw new Error(`Unknown target storage type: ${targetStorageType}`); } -export default async function createImpExpScript(values, addEditorInfo = true) { +export default async function createImpExpScript(extensions, values, addEditorInfo = true) { const script = new ScriptWriter(); const [sourceConnection, sourceDriver] = await getConnection( @@ -172,11 +168,11 @@ export default async function createImpExpScript(values, addEditorInfo = true) { for (const sourceName of sourceList) { const sourceVar = script.allocVariable(); // @ts-ignore - script.assign(sourceVar, ...getSourceExpr(sourceName, values, sourceConnection, sourceDriver)); + script.assign(sourceVar, ...getSourceExpr(extensions, sourceName, values, sourceConnection, sourceDriver)); const targetVar = script.allocVariable(); // @ts-ignore - script.assign(targetVar, ...getTargetExpr(sourceName, values, targetConnection, targetDriver)); + script.assign(targetVar, ...getTargetExpr(extensions, sourceName, values, targetConnection, targetDriver)); script.copyStream(sourceVar, targetVar); script.put(); @@ -188,9 +184,9 @@ export default async function createImpExpScript(values, addEditorInfo = true) { return script.s; } -export function getActionOptions(source, values, targetDbinfo) { +export function getActionOptions(extensions, source, values, targetDbinfo) { const res = []; - const targetName = getTargetName(source, values); + const targetName = getTargetName(extensions, source, values); if (values.targetStorageType == 'database') { let existing = findObjectLike( { schemaName: values.targetSchemaName, pureName: targetName }, @@ -225,13 +221,13 @@ export function getActionOptions(source, values, targetDbinfo) { return res; } -export async function createPreviewReader(values, sourceName) { +export async function createPreviewReader(extensions, values, sourceName) { const [sourceConnection, sourceDriver] = await getConnection( values.sourceStorageType, values.sourceConnectionId, values.sourceDatabaseName ); - const [functionName, props] = getSourceExpr(sourceName, values, sourceConnection, sourceDriver); + const [functionName, props] = getSourceExpr(extensions, sourceName, values, sourceConnection, sourceDriver); return { functionName, props: { diff --git a/packages/web/src/modals/ImportExportModal.js b/packages/web/src/modals/ImportExportModal.js index bd62384d8..4408724aa 100644 --- a/packages/web/src/modals/ImportExportModal.js +++ b/packages/web/src/modals/ImportExportModal.js @@ -22,7 +22,8 @@ import useSocket from '../utility/SocketProvider'; import LoadingInfo from '../widgets/LoadingInfo'; import { FontIcon } from '../icons'; import LargeButton from '../widgets/LargeButton'; -import { defaultFileFormat } from '../fileformats'; +import { getDefaultFileFormat } from '../utility/fileformats'; +import useExtensions from '../utility/useExtensions'; const headerHeight = '60px'; const footerHeight = '100px'; @@ -92,9 +93,10 @@ const FooterButtons = styled.div` function GenerateSctriptButton({ modalState }) { const setOpenedTabs = useSetOpenedTabs(); const { values } = useFormikContext(); + const extensions = useExtensions(); const handleGenerateScript = async () => { - const code = await createImpExpScript(values); + const code = await createImpExpScript(extensions, values); openNewTab(setOpenedTabs, { title: 'Shell', icon: 'img shell', @@ -141,6 +143,7 @@ export default function ImportExportModal({ const refreshArchiveFolderRef = React.useRef(null); const setArchive = useSetCurrentArchive(); const setCurrentWidget = useSetCurrentWidget(); + const extensions = useExtensions(); const [busy, setBusy] = React.useState(false); @@ -165,9 +168,9 @@ export default function ImportExportModal({ const handleExecute = async (values) => { if (busy) return; - + setBusy(true); - const script = await createImpExpScript(values); + const script = await createImpExpScript(extensions, values); setExecuteNumber((num) => num + 1); @@ -194,7 +197,7 @@ export default function ImportExportModal({ onSubmit={handleExecute} initialValues={{ sourceStorageType: 'database', - targetStorageType: importToArchive ? 'archive' : defaultFileFormat.storageType, + targetStorageType: importToArchive ? 'archive' : getDefaultFileFormat(extensions).storageType, sourceArchiveFolder: archive, targetArchiveFolder, ...initialValues, diff --git a/packages/web/src/plugins/PluginsProvider.js b/packages/web/src/plugins/PluginsProvider.js index 7ae3fa25d..6e9f5767d 100644 --- a/packages/web/src/plugins/PluginsProvider.js +++ b/packages/web/src/plugins/PluginsProvider.js @@ -9,12 +9,7 @@ export default function PluginsProvider({ children }) { const installedPlugins = useInstalledPlugins(); const [plugins, setPlugins] = React.useState({}); const handleLoadPlugins = async () => { - setPlugins((x) => - _.pick( - x, - installedPlugins.map((y) => y.name) - ) - ); + const newPlugins = {}; for (const installed of installedPlugins) { if (!_.keys(plugins).includes(installed.name)) { console.log('Loading module', installed.name); @@ -26,12 +21,16 @@ export default function PluginsProvider({ children }) { }, }); const module = eval(resp.data); - setPlugins((v) => ({ - ...v, - [installed.name]: module, - })); + console.log('Loaded plugin', module); + newPlugins[installed.name] = module.__esModule ? module.default : module; } } + setPlugins((x) => + _.pick( + { ...x, ...newPlugins }, + installedPlugins.map((y) => y.name) + ) + ); }; React.useEffect(() => { handleLoadPlugins(); @@ -42,11 +41,16 @@ export default function PluginsProvider({ children }) { export function usePlugins() { const installed = useInstalledPlugins(); const loaded = React.useContext(PluginsContext); - return installed - .map((manifest) => ({ - packageName: manifest.name, - manifest, - content: loaded[manifest.name], - })) - .filter((x) => x.content); + + return React.useMemo( + () => + installed + .map((manifest) => ({ + packageName: manifest.name, + manifest, + content: loaded[manifest.name], + })) + .filter((x) => x.content), + [installed, loaded] + ); } diff --git a/packages/web/src/utility/UploadsProvider.js b/packages/web/src/utility/UploadsProvider.js index 81a5de7d2..f75ab1b8f 100644 --- a/packages/web/src/utility/UploadsProvider.js +++ b/packages/web/src/utility/UploadsProvider.js @@ -1,9 +1,10 @@ import React from 'react'; import { useDropzone } from 'react-dropzone'; -import { findFileFormat } from '../fileformats'; import ImportExportModal from '../modals/ImportExportModal'; import useShowModal from '../modals/showModal'; +import { findFileFormat } from './fileformats'; import resolveApi from './resolveApi'; +import useExtensions from './useExtensions'; const UploadsContext = React.createContext(null); @@ -19,6 +20,7 @@ export function useUploadsProvider() { export function useUploadsZone() { const { uploadListener } = useUploadsProvider(); const showModal = useShowModal(); + const extensions = useExtensions(); const onDrop = React.useCallback( (files) => { @@ -43,7 +45,7 @@ export function useUploadsZone() { if (uploadListener) { uploadListener(fileData); } else { - if (findFileFormat(fileData.storageType)) { + if (findFileFormat(extensions, fileData.storageType)) { showModal((modalState) => ( { + const resp = await axios.get(`files/analyse-excel?filePath=${encodeURIComponent(file.full)}`); + const sheetNames = resp.data; + for (const sheetName of sheetNames) { + newSources.push(sheetName); + newValues[`sourceFile_${sheetName}`] = { + fileName: file.full, + sheetName, + }; + } + }, + + args: [ + { + type: 'checkbox', + name: 'singleFile', + label: 'Create single file', + direction: 'target', + }, + ], + + getDefaultOutputName: (sourceName, values) => { + if (values.target_excel_singleFile) { + return sourceName; + } + return null; + }, + + getOutputParams: (sourceName, values) => { + if (values.target_excel_singleFile) { + return { + sheetName: values[`targetName_${sourceName}`] || sourceName, + fileName: 'data.xlsx', + }; + } + return null; + }, +}; + +const jsonlFormat = { + storageType: 'jsonl', + extension: 'jsonl', + name: 'JSON lines', + readerFunc: 'jsonLinesReader', + writerFunc: 'jsonLinesWriter', +}; + +export function buildFileFormats(plugins) { + const res = [excelFormat, jsonlFormat]; + for (const { content } of plugins) { + const { fileFormats } = content; + if (fileFormats) res.push(...fileFormats); + } + return res; +} + +export function findFileFormat(extensions, storageType) { + return extensions.fileFormats.find((x) => x.storageType == storageType); +} + +export function getFileFormatDirections(format) { + if (!format) return []; + const res = []; + if (format.readerFunc) res.push('source'); + if (format.writerFunc) res.push('target'); + return res; +} + +export function getDefaultFileFormat(extensions) { + return extensions.fileFormats.find((x) => x.storageType == 'csv') || jsonlFormat; } diff --git a/packages/web/src/utility/globalState.js b/packages/web/src/utility/globalState.js index 9a5f576f8..51ede5906 100644 --- a/packages/web/src/utility/globalState.js +++ b/packages/web/src/utility/globalState.js @@ -5,6 +5,7 @@ import { useConnectionInfo, useConfig } from './metadataLoaders'; import usePrevious from './usePrevious'; import useNewQuery from '../query/useNewQuery'; import useShowModal from '../modals/showModal'; +import useExtensions from './useExtensions'; function createGlobalState(defaultValue) { const Context = React.createContext(null); @@ -90,6 +91,7 @@ export function useAppObjectParams() { const currentArchive = useCurrentArchive(); const showModal = useShowModal(); const config = useConfig(); + const extensions = useExtensions(); return { setOpenedTabs, diff --git a/packages/web/src/utility/metadataLoaders.js b/packages/web/src/utility/metadataLoaders.js index 5ac8b597e..ffe8fc6c9 100644 --- a/packages/web/src/utility/metadataLoaders.js +++ b/packages/web/src/utility/metadataLoaders.js @@ -88,7 +88,7 @@ const connectionListLoader = () => ({ reloadTrigger: `connection-list-changed`, }); -const insttalledPluginsLoader = () => ({ +const installedPluginsLoader = () => ({ url: 'plugins/installed', params: {}, reloadTrigger: `installed-plugins-changed`, @@ -251,8 +251,8 @@ export function useArchiveFolders(args) { } export function getInstalledPlugins(args) { - return getCore(insttalledPluginsLoader, args) || []; + return getCore(installedPluginsLoader, args) || []; } export function useInstalledPlugins(args) { - return useCore(insttalledPluginsLoader, args) || []; + return useCore(installedPluginsLoader, args) || []; } diff --git a/packages/web/src/utility/useExtensions.js b/packages/web/src/utility/useExtensions.js new file mode 100644 index 000000000..6b53996c7 --- /dev/null +++ b/packages/web/src/utility/useExtensions.js @@ -0,0 +1,15 @@ +import React from 'react'; +import { usePlugins } from '../plugins/PluginsProvider'; +import { buildFileFormats } from './fileformats'; + +export default function useExtensions() { + const plugins = usePlugins(); + const extensions = React.useMemo( + () => ({ + plugins, + fileFormats: buildFileFormats(plugins), + }), + [plugins] + ); + return extensions; +} diff --git a/packages/web/src/widgets/Toolbar.js b/packages/web/src/widgets/Toolbar.js index d0c91089d..0c3aade65 100644 --- a/packages/web/src/widgets/Toolbar.js +++ b/packages/web/src/widgets/Toolbar.js @@ -10,7 +10,8 @@ import { openNewTab } from '../utility/common'; import useNewFreeTable from '../freetable/useNewFreeTable'; import ImportExportModal from '../modals/ImportExportModal'; import useShowModal from '../modals/showModal'; -import { defaultFileFormat } from '../fileformats'; +import useExtensions from '../utility/useExtensions'; +import { getDefaultFileFormat } from '../utility/fileformats'; const ToolbarContainer = styled.div` display: flex; @@ -28,6 +29,7 @@ export default function ToolBar({ toolbarPortalRef }) { const showModal = useShowModal(); const currentTheme = useCurrentTheme(); const setCurrentTheme = useSetCurrentTheme(); + const extensions = useExtensions(); React.useEffect(() => { window['dbgate_createNewConnection'] = modalState.open; @@ -41,7 +43,7 @@ export default function ToolBar({ toolbarPortalRef }) { modalState={modalState} importToArchive initialValues={{ - sourceStorageType: defaultFileFormat.storageType, + sourceStorageType: getDefaultFileFormat(extensions).storageType, // sourceConnectionId: data.conid, // sourceDatabaseName: data.database, // sourceSchemaName: data.schemaName, From 6ed3eaa896c5d8d8b54812a2aa9f3d423d91fe84 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 21 Nov 2020 20:20:47 +0100 Subject: [PATCH 07/30] useExtensions fixed (extensions in context) --- packages/web/src/App.js | 23 ++++++++++-------- .../src/impexp/ImportExportConfigurator.js | 4 ---- packages/web/src/utility/useExtensions.js | 24 ++++++++++++------- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/packages/web/src/App.js b/packages/web/src/App.js index 0497767a6..28426f75f 100644 --- a/packages/web/src/App.js +++ b/packages/web/src/App.js @@ -17,6 +17,7 @@ import { ModalLayerProvider } from './modals/showModal'; import UploadsProvider from './utility/UploadsProvider'; import ThemeHelmet from './themes/ThemeHelmet'; import PluginsProvider from './plugins/PluginsProvider'; +import { ExtensionsProvider } from './utility/useExtensions'; function App() { return ( @@ -29,16 +30,18 @@ function App() { - - - - - - - - - - + + + + + + + + + + + + diff --git a/packages/web/src/impexp/ImportExportConfigurator.js b/packages/web/src/impexp/ImportExportConfigurator.js index 6913ef286..82c5d21e1 100644 --- a/packages/web/src/impexp/ImportExportConfigurator.js +++ b/packages/web/src/impexp/ImportExportConfigurator.js @@ -354,10 +354,6 @@ export default function ImportExportConfigurator({ uploadedFile = undefined, onC const [previewSource, setPreviewSource] = React.useState(null); const extensions = useExtensions(); - console.log('ImportExportConfigurator', extensions); - const installed = useInstalledPlugins(); - console.log('installed', installed); - const handleUpload = React.useCallback( (file) => { console.log('UPLOAD', extensions); diff --git a/packages/web/src/utility/useExtensions.js b/packages/web/src/utility/useExtensions.js index 6b53996c7..712209138 100644 --- a/packages/web/src/utility/useExtensions.js +++ b/packages/web/src/utility/useExtensions.js @@ -2,14 +2,22 @@ import React from 'react'; import { usePlugins } from '../plugins/PluginsProvider'; import { buildFileFormats } from './fileformats'; -export default function useExtensions() { +const ExtensionsContext = React.createContext(buildExtensions([])); + +export function ExtensionsProvider({ children }) { const plugins = usePlugins(); - const extensions = React.useMemo( - () => ({ - plugins, - fileFormats: buildFileFormats(plugins), - }), - [plugins] - ); + const extensions = React.useMemo(() => buildExtensions(plugins), [plugins]); + return {children}; +} + +export function buildExtensions(plugins) { + const extensions = { + plugins, + fileFormats: buildFileFormats(plugins), + }; return extensions; } + +export default function useExtensions() { + return React.useContext(ExtensionsContext); +} From 286cac066ca2182b083a8ed7b040cdece2e137e0 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 21 Nov 2020 21:16:22 +0100 Subject: [PATCH 08/30] backend exporters/importers from plugins --- packages/api/src/controllers/runners.js | 18 +++++++--- packages/web/src/impexp/ScriptWriter.js | 33 ++++++++++++++++++- packages/web/src/impexp/createImpExpScript.js | 2 +- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/packages/api/src/controllers/runners.js b/packages/api/src/controllers/runners.js index 98dbf7185..a43e4d616 100644 --- a/packages/api/src/controllers/runners.js +++ b/packages/api/src/controllers/runners.js @@ -5,10 +5,19 @@ const uuidv1 = require('uuid/v1'); const byline = require('byline'); const socket = require('../utility/socket'); const { fork } = require('child_process'); -const { rundir, uploadsdir } = require('../utility/directories'); +const { rundir, uploadsdir, pluginsdir } = require('../utility/directories'); + +function extractPlugins(script) { + const requireRegex = /\s*\/\/\s*@require\s+([^\s]+)\s*\n/g; + const matches = [...script.matchAll(requireRegex)]; + return matches.map((x) => x[1]); +} const scriptTemplate = (script) => ` -const dbgateApi = require(process.env.DBGATE_API || "dbgate-api"); +const dbgateApi = require(process.env.DBGATE_API); +${extractPlugins(script) + .map((packageName) => `const ${_.camelCase(packageName)} = require(process.env.PLUGIN_${_.camelCase(packageName)});\n`) + .join('')} require=null; async function run() { ${script} @@ -19,7 +28,7 @@ dbgateApi.runScript(run); `; const loaderScriptTemplate = (functionName, props, runid) => ` -const dbgateApi = require(process.env.DBGATE_API || "dbgate-api"); +const dbgateApi = require(process.env.DBGATE_API); require=null; async function run() { const reader=await dbgateApi.${functionName}(${JSON.stringify(props)}); @@ -73,12 +82,14 @@ module.exports = { const scriptFile = path.join(uploadsdir(), runid + '.js'); fs.writeFileSync(`${scriptFile}`, scriptText); fs.mkdirSync(directory); + const pluginNames = fs.readdirSync(pluginsdir()); console.log(`RUNNING SCRIPT ${scriptFile}`); const subprocess = fork(scriptFile, ['--checkParent'], { cwd: directory, stdio: ['ignore', 'pipe', 'pipe', 'ipc'], env: { DBGATE_API: process.argv[1], + ..._.fromPairs(pluginNames.map((name) => [`PLUGIN_${_.camelCase(name)}`, path.join(pluginsdir(), name)])), }, }); const pipeDispatcher = (severity) => (data) => @@ -153,4 +164,3 @@ module.exports = { return promise; }, }; - diff --git a/packages/web/src/impexp/ScriptWriter.js b/packages/web/src/impexp/ScriptWriter.js index cf459d2e6..84311e38a 100644 --- a/packages/web/src/impexp/ScriptWriter.js +++ b/packages/web/src/impexp/ScriptWriter.js @@ -1,6 +1,10 @@ +import _ from 'lodash'; + export default class ScriptWriter { constructor() { this.s = ''; + this.packageNames = []; + this.engines = []; this.varCount = 0; } @@ -15,7 +19,21 @@ export default class ScriptWriter { } assign(variableName, functionName, props) { - this.put(`const ${variableName} = await dbgateApi.${functionName}(${JSON.stringify(props)});`); + const nsMatch = functionName.match(/^([^@]+)@([^@]+)/); + if (nsMatch) { + const packageName = nsMatch[2]; + if (!this.packageNames.includes(packageName)) { + this.packageNames.push(packageName); + } + this.put( + `const ${variableName} = await ${_.camelCase(packageName)}.shellApi.${nsMatch[1]}(${JSON.stringify(props)});` + ); + } else { + this.put(`const ${variableName} = await dbgateApi.${functionName}(${JSON.stringify(props)});`); + } + if (props && props.connection && props.connection.engine && !this.engines.includes(props.connection.engine)) { + this.engines.push(props.connection.engine); + } } copyStream(sourceVar, targetVar) { @@ -25,4 +43,17 @@ export default class ScriptWriter { comment(s) { this.put(`// ${s}`); } + + getScript(extensions) { + // if (this.packageNames.length > 0) { + // this.comment('@packages'); + // this.comment(JSON.stringify(this.packageNames)); + // } + // if (this.engines.length > 0) { + // this.comment('@engines'); + // this.comment(JSON.stringify(this.engines)); + // } + const packageNames = this.packageNames; + return packageNames.map((packageName) => `// @require ${packageName}\n`).join('') + '\n' + this.s; + } } diff --git a/packages/web/src/impexp/createImpExpScript.js b/packages/web/src/impexp/createImpExpScript.js index d5826d4c3..e9752c221 100644 --- a/packages/web/src/impexp/createImpExpScript.js +++ b/packages/web/src/impexp/createImpExpScript.js @@ -181,7 +181,7 @@ export default async function createImpExpScript(extensions, values, addEditorIn script.comment('@ImportExportConfigurator'); script.comment(JSON.stringify(values)); } - return script.s; + return script.getScript(extensions); } export function getActionOptions(extensions, source, values, targetDbinfo) { From 7d1c0c5c181ee03c64aac10a5113d500492d57ab Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sun, 22 Nov 2020 09:03:16 +0100 Subject: [PATCH 09/30] runner openreader - support for plugins --- packages/api/src/controllers/runners.js | 15 +++++++++++---- packages/tools/src/index.ts | 1 + packages/tools/src/packageTools.ts | 24 ++++++++++++++++++++++++ packages/web/package.json | 1 + packages/web/src/impexp/ScriptWriter.js | 22 +++++----------------- 5 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 packages/tools/src/packageTools.ts diff --git a/packages/api/src/controllers/runners.js b/packages/api/src/controllers/runners.js index a43e4d616..aaac34d64 100644 --- a/packages/api/src/controllers/runners.js +++ b/packages/api/src/controllers/runners.js @@ -6,6 +6,7 @@ const byline = require('byline'); const socket = require('../utility/socket'); const { fork } = require('child_process'); const { rundir, uploadsdir, pluginsdir } = require('../utility/directories'); +const { extractShellApiPlugins, extractShellApiFunctionName } = require('dbgate-tools'); function extractPlugins(script) { const requireRegex = /\s*\/\/\s*@require\s+([^\s]+)\s*\n/g; @@ -13,11 +14,16 @@ function extractPlugins(script) { return matches.map((x) => x[1]); } +const requirePluginsTemplate = (plugins) => + plugins + .map( + (packageName) => `const ${_.camelCase(packageName)} = require(process.env.PLUGIN_${_.camelCase(packageName)});\n` + ) + .join(''); + const scriptTemplate = (script) => ` const dbgateApi = require(process.env.DBGATE_API); -${extractPlugins(script) - .map((packageName) => `const ${_.camelCase(packageName)} = require(process.env.PLUGIN_${_.camelCase(packageName)});\n`) - .join('')} +${requirePluginsTemplate(extractPlugins(script))} require=null; async function run() { ${script} @@ -29,9 +35,10 @@ dbgateApi.runScript(run); const loaderScriptTemplate = (functionName, props, runid) => ` const dbgateApi = require(process.env.DBGATE_API); +${requirePluginsTemplate(extractShellApiPlugins(functionName, props))} require=null; async function run() { -const reader=await dbgateApi.${functionName}(${JSON.stringify(props)}); +const reader=await ${extractShellApiFunctionName(functionName)}(${JSON.stringify(props)}); const writer=await dbgateApi.collectorWriter({runid: '${runid}'}); await dbgateApi.copyStream(reader, writer); } diff --git a/packages/tools/src/index.ts b/packages/tools/src/index.ts index 3e77feffa..9518e5b90 100644 --- a/packages/tools/src/index.ts +++ b/packages/tools/src/index.ts @@ -1,3 +1,4 @@ export * from './commonTypeParser'; export * from './nameTools'; export * from './tableTransforms'; +export * from './packageTools'; diff --git a/packages/tools/src/packageTools.ts b/packages/tools/src/packageTools.ts new file mode 100644 index 000000000..1ce04f702 --- /dev/null +++ b/packages/tools/src/packageTools.ts @@ -0,0 +1,24 @@ +import _ from 'lodash'; + +export function extractShellApiPlugins(functionName, props): string[] { + const res = []; + const nsMatch = functionName.match(/^([^@]+)@([^@]+)/); + if (nsMatch) { + res.push(nsMatch[2]); + } + if (props && props.connection && props.connection.engine) { + const nsMatchEngine = props.connection.engine.match(/^([^@]+)@([^@]+)/); + if (nsMatchEngine) { + res.push(nsMatchEngine[2]); + } + } + return res; +} + +export function extractShellApiFunctionName(functionName) { + const nsMatch = functionName.match(/^([^@]+)@([^@]+)/); + if (nsMatch) { + return `${_.camelCase(nsMatch[2])}.shellApi.${nsMatch[1]}`; + } + return `dbgateApi.${functionName}`; +} diff --git a/packages/web/package.json b/packages/web/package.json index 6d5210e4c..013441840 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -14,6 +14,7 @@ "dbgate-datalib": "^1.0.0", "dbgate-engines": "^1.0.0", "dbgate-sqltree": "^1.0.0", + "dbgate-tools": "^1.0.0", "eslint": "^6.8.0", "eslint-plugin-react": "^7.17.0", "formik": "^2.1.0", diff --git a/packages/web/src/impexp/ScriptWriter.js b/packages/web/src/impexp/ScriptWriter.js index 84311e38a..acd751ff3 100644 --- a/packages/web/src/impexp/ScriptWriter.js +++ b/packages/web/src/impexp/ScriptWriter.js @@ -1,10 +1,11 @@ import _ from 'lodash'; +import { extractShellApiFunctionName, extractShellApiPlugins } from 'dbgate-tools'; export default class ScriptWriter { constructor() { this.s = ''; this.packageNames = []; - this.engines = []; + // this.engines = []; this.varCount = 0; } @@ -19,21 +20,8 @@ export default class ScriptWriter { } assign(variableName, functionName, props) { - const nsMatch = functionName.match(/^([^@]+)@([^@]+)/); - if (nsMatch) { - const packageName = nsMatch[2]; - if (!this.packageNames.includes(packageName)) { - this.packageNames.push(packageName); - } - this.put( - `const ${variableName} = await ${_.camelCase(packageName)}.shellApi.${nsMatch[1]}(${JSON.stringify(props)});` - ); - } else { - this.put(`const ${variableName} = await dbgateApi.${functionName}(${JSON.stringify(props)});`); - } - if (props && props.connection && props.connection.engine && !this.engines.includes(props.connection.engine)) { - this.engines.push(props.connection.engine); - } + this.put(`const ${variableName} = await ${extractShellApiFunctionName(functionName)}(${JSON.stringify(props)});`); + this.packageNames.push(...extractShellApiPlugins(functionName, props)); } copyStream(sourceVar, targetVar) { @@ -54,6 +42,6 @@ export default class ScriptWriter { // this.comment(JSON.stringify(this.engines)); // } const packageNames = this.packageNames; - return packageNames.map((packageName) => `// @require ${packageName}\n`).join('') + '\n' + this.s; + return _.uniq(packageNames).map((packageName) => `// @require ${packageName}\n`).join('') + '\n' + this.s; } } From 3cdba4339fb911b16885faf1ad2d9ae4b68a2954 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sun, 22 Nov 2020 09:14:19 +0100 Subject: [PATCH 10/30] uploads - moved logic to FE because of plugins --- packages/api/src/controllers/uploads.js | 48 ++++++++++----------- packages/types/extensions.d.ts | 30 +++++++++++++ packages/types/fileformat.d.ts | 20 --------- packages/types/index.d.ts | 2 +- packages/web/src/utility/UploadsProvider.js | 10 +++++ packages/web/src/utility/fileformats.js | 1 + packages/web/src/utility/useExtensions.js | 2 + 7 files changed, 68 insertions(+), 45 deletions(-) create mode 100644 packages/types/extensions.d.ts delete mode 100644 packages/types/fileformat.d.ts diff --git a/packages/api/src/controllers/uploads.js b/packages/api/src/controllers/uploads.js index 54407d4da..fc48f9b8d 100644 --- a/packages/api/src/controllers/uploads.js +++ b/packages/api/src/controllers/uploads.js @@ -2,20 +2,20 @@ const path = require('path'); const { uploadsdir } = require('../utility/directories'); const uuidv1 = require('uuid/v1'); -const extensions = [ - { - ext: '.xlsx', - type: 'excel', - }, - { - ext: '.jsonl', - type: 'jsonl', - }, - { - ext: '.csv', - type: 'csv', - }, -]; +// const extensions = [ +// { +// ext: '.xlsx', +// type: 'excel', +// }, +// { +// ext: '.jsonl', +// type: 'jsonl', +// }, +// { +// ext: '.csv', +// type: 'csv', +// }, +// ]; module.exports = { upload_meta: { @@ -31,19 +31,19 @@ module.exports = { const uploadName = uuidv1(); const filePath = path.join(uploadsdir(), uploadName); console.log(`Uploading file ${data.name}, size=${data.size}`); - let storageType = null; - let shortName = data.name; - for (const { ext, type } of extensions) { - if (data.name.endsWith(ext)) { - storageType = type; - shortName = data.name.slice(0, -ext.length); - } - } + // let storageType = null; + // let shortName = data.name; + // for (const { ext, type } of extensions) { + // if (data.name.endsWith(ext)) { + // storageType = type; + // shortName = data.name.slice(0, -ext.length); + // } + // } data.mv(filePath, () => { res.json({ originalName: data.name, - shortName, - storageType, + // shortName, + // storageType, uploadName, filePath, }); diff --git a/packages/types/extensions.d.ts b/packages/types/extensions.d.ts new file mode 100644 index 000000000..5bd430ddb --- /dev/null +++ b/packages/types/extensions.d.ts @@ -0,0 +1,30 @@ +export interface FileFormatDefinition { + storageType: string; + extension: string; + name: string; + readerFunc?: string; + writerFunc?: string; + args?: any[]; + addFilesToSourceList?: ( + file: { + full: string; + }, + newSources: string[], + newValues: { + [key: string]: any; + } + ) => void; + getDefaultOutputName?: (sourceName, values) => string; + getOutputParams?: (sourceName, values) => any; +} + +export interface PluginDefinition { + packageName: string; + manifest: any; + content: any; +} + +export interface ExtensionsDirectory { + plugins: PluginDefinition[]; + fileFormats: FileFormatDefinition[]; +} diff --git a/packages/types/fileformat.d.ts b/packages/types/fileformat.d.ts deleted file mode 100644 index ccc569085..000000000 --- a/packages/types/fileformat.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -export interface FileFormatDefinition { - storageType: string; - extension: string; - name: string; - readerFunc?: string; - writerFunc?: string; - args?: any[]; - addFilesToSourceList: ( - file: { - full: string; - }, - newSources: string[], - newValues: { - [key: string]: any; - } - ) => void; - getDefaultOutputName?: (sourceName, values) => string; - getOutputParams?: (sourceName, values) => any; - } - \ No newline at end of file diff --git a/packages/types/index.d.ts b/packages/types/index.d.ts index 12530325e..6134439fb 100644 --- a/packages/types/index.d.ts +++ b/packages/types/index.d.ts @@ -39,4 +39,4 @@ export * from './query'; export * from './dialect'; export * from './dumper'; export * from './dbtypes'; -export * from './fileformat'; +export * from './extensions'; diff --git a/packages/web/src/utility/UploadsProvider.js b/packages/web/src/utility/UploadsProvider.js index f75ab1b8f..09c0c38b0 100644 --- a/packages/web/src/utility/UploadsProvider.js +++ b/packages/web/src/utility/UploadsProvider.js @@ -30,6 +30,7 @@ export function useUploadsZone() { return; } + console.log('FILE', file); const formData = new FormData(); formData.append('data', file); @@ -42,6 +43,15 @@ export function useUploadsZone() { const resp = await fetch(`${apiBase}/uploads/upload`, fetchOptions); const fileData = await resp.json(); + fileData.shortName = file.name; + + for (const format of extensions.fileFormats) { + if (file.name.endsWith('.' + format.extension)) { + fileData.shortName = file.name.slice(-format.extension.length - 1); + fileData.storageType = format.storageType; + } + } + if (uploadListener) { uploadListener(fileData); } else { diff --git a/packages/web/src/utility/fileformats.js b/packages/web/src/utility/fileformats.js index 49be420ef..9fee0859a 100644 --- a/packages/web/src/utility/fileformats.js +++ b/packages/web/src/utility/fileformats.js @@ -56,6 +56,7 @@ const jsonlFormat = { writerFunc: 'jsonLinesWriter', }; +/** @returns {import('dbgate-types').FileFormatDefinition[]} */ export function buildFileFormats(plugins) { const res = [excelFormat, jsonlFormat]; for (const { content } of plugins) { diff --git a/packages/web/src/utility/useExtensions.js b/packages/web/src/utility/useExtensions.js index 712209138..71a92b6ce 100644 --- a/packages/web/src/utility/useExtensions.js +++ b/packages/web/src/utility/useExtensions.js @@ -11,6 +11,7 @@ export function ExtensionsProvider({ children }) { } export function buildExtensions(plugins) { + /** @type {import('dbgate-types').ExtensionsDirectory} */ const extensions = { plugins, fileFormats: buildFileFormats(plugins), @@ -18,6 +19,7 @@ export function buildExtensions(plugins) { return extensions; } +/** @returns {import('dbgate-types').ExtensionsDirectory} */ export default function useExtensions() { return React.useContext(ExtensionsContext); } From e23e749cc534f81fc9c45582c7512ae574d650aa Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sun, 22 Nov 2020 09:17:51 +0100 Subject: [PATCH 11/30] CSV - completely remove, logic moved to plugin --- packages/api/package.json | 2 - packages/api/src/controllers/uploads.js | 26 +----------- packages/api/src/shell/csvReader.js | 55 ------------------------- packages/api/src/shell/csvWriter.js | 36 ---------------- packages/api/src/shell/index.js | 4 -- yarn.lock | 37 ----------------- 6 files changed, 1 insertion(+), 159 deletions(-) delete mode 100644 packages/api/src/shell/csvReader.js delete mode 100644 packages/api/src/shell/csvWriter.js diff --git a/packages/api/package.json b/packages/api/package.json index 91a53b46a..e4482f94f 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -15,7 +15,6 @@ "mssql", "mssql", "postgresql", - "csv", "excel", "json", "import", @@ -30,7 +29,6 @@ "byline": "^5.0.0", "cors": "^2.8.5", "cross-env": "^6.0.3", - "csv": "^5.3.2", "dbgate-engines": "^1.0.0", "dbgate-sqltree": "^1.0.0", "dbgate-tools": "^1.0.0", diff --git a/packages/api/src/controllers/uploads.js b/packages/api/src/controllers/uploads.js index fc48f9b8d..342a7be8c 100644 --- a/packages/api/src/controllers/uploads.js +++ b/packages/api/src/controllers/uploads.js @@ -2,21 +2,6 @@ const path = require('path'); const { uploadsdir } = require('../utility/directories'); const uuidv1 = require('uuid/v1'); -// const extensions = [ -// { -// ext: '.xlsx', -// type: 'excel', -// }, -// { -// ext: '.jsonl', -// type: 'jsonl', -// }, -// { -// ext: '.csv', -// type: 'csv', -// }, -// ]; - module.exports = { upload_meta: { method: 'post', @@ -31,19 +16,10 @@ module.exports = { const uploadName = uuidv1(); const filePath = path.join(uploadsdir(), uploadName); console.log(`Uploading file ${data.name}, size=${data.size}`); - // let storageType = null; - // let shortName = data.name; - // for (const { ext, type } of extensions) { - // if (data.name.endsWith(ext)) { - // storageType = type; - // shortName = data.name.slice(0, -ext.length); - // } - // } + data.mv(filePath, () => { res.json({ originalName: data.name, - // shortName, - // storageType, uploadName, filePath, }); diff --git a/packages/api/src/shell/csvReader.js b/packages/api/src/shell/csvReader.js deleted file mode 100644 index 25261c8d0..000000000 --- a/packages/api/src/shell/csvReader.js +++ /dev/null @@ -1,55 +0,0 @@ -const _ = require('lodash'); -const csv = require('csv'); -const fs = require('fs'); -const stream = require('stream'); - -class CsvPrepareStream extends stream.Transform { - constructor({ header }) { - super({ objectMode: true }); - this.structure = null; - this.header = header; - } - _transform(chunk, encoding, done) { - if (this.structure) { - this.push( - _.zipObject( - this.structure.columns.map((x) => x.columnName), - chunk - ) - ); - done(); - } else { - if (this.header) { - this.structure = { columns: chunk.map((columnName) => ({ columnName })) }; - this.push(this.structure); - } else { - this.structure = { columns: chunk.map((value, index) => ({ columnName: `col${index + 1}` })) }; - this.push(this.structure); - this.push( - _.zipObject( - this.structure.columns.map((x) => x.columnName), - chunk - ) - ); - } - done(); - } - } -} - -async function csvReader({ fileName, encoding = 'utf-8', header = true, delimiter, limitRows = undefined }) { - console.log(`Reading file ${fileName}`); - const csvStream = csv.parse({ - // @ts-ignore - delimiter, - skip_lines_with_error: true, - to_line: limitRows ? limitRows + 1 : -1, - }); - const fileStream = fs.createReadStream(fileName, encoding); - const csvPrepare = new CsvPrepareStream({ header }); - fileStream.pipe(csvStream); - csvStream.pipe(csvPrepare); - return csvPrepare; -} - -module.exports = csvReader; diff --git a/packages/api/src/shell/csvWriter.js b/packages/api/src/shell/csvWriter.js deleted file mode 100644 index a5297c651..000000000 --- a/packages/api/src/shell/csvWriter.js +++ /dev/null @@ -1,36 +0,0 @@ -const csv = require('csv'); -const fs = require('fs'); -const stream = require('stream'); - -class CsvPrepareStream extends stream.Transform { - constructor({ header }) { - super({ objectMode: true }); - this.structure = null; - this.header = header; - } - _transform(chunk, encoding, done) { - if (this.structure) { - this.push(this.structure.columns.map((col) => chunk[col.columnName])); - done(); - } else { - this.structure = chunk; - if (this.header) { - this.push(chunk.columns.map((x) => x.columnName)); - } - done(); - } - } -} - -async function csvWriter({ fileName, encoding = 'utf-8', header = true, delimiter, quoted }) { - console.log(`Writing file ${fileName}`); - const csvPrepare = new CsvPrepareStream({ header }); - const csvStream = csv.stringify({ delimiter, quoted }); - const fileStream = fs.createWriteStream(fileName, encoding); - csvPrepare.pipe(csvStream); - csvStream.pipe(fileStream); - csvPrepare['finisher'] = fileStream; - return csvPrepare; -} - -module.exports = csvWriter; diff --git a/packages/api/src/shell/index.js b/packages/api/src/shell/index.js index a7143d375..644608716 100644 --- a/packages/api/src/shell/index.js +++ b/packages/api/src/shell/index.js @@ -1,6 +1,4 @@ const queryReader = require('./queryReader'); -const csvWriter = require('./csvWriter'); -const csvReader = require('./csvReader'); const runScript = require('./runScript'); const tableWriter = require('./tableWriter'); const tableReader = require('./tableReader'); @@ -19,8 +17,6 @@ const finalizer = require('./finalizer'); module.exports = { queryReader, - csvWriter, - csvReader, runScript, tableWriter, tableReader, diff --git a/yarn.lock b/yarn.lock index 7879c854f..08c18f2d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4069,31 +4069,6 @@ csstype@^2.5.7, csstype@^2.6.7: resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.10.tgz#e63af50e66d7c266edb6b32909cfd0aabe03928b" integrity sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w== -csv-generate@^3.2.4: - version "3.2.4" - resolved "https://registry.yarnpkg.com/csv-generate/-/csv-generate-3.2.4.tgz#440dab9177339ee0676c9e5c16f50e2b3463c019" - integrity sha512-qNM9eqlxd53TWJeGtY1IQPj90b563Zx49eZs8e0uMyEvPgvNVmX1uZDtdzAcflB3PniuH9creAzcFOdyJ9YGvA== - -csv-parse@^4.8.8: - version "4.10.1" - resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-4.10.1.tgz#1e26ba63d29c75e94d0eba6e9de9a8aaf89d72a6" - integrity sha512-gdDJVchi0oSLIcYXz1H/VSgLE6htHDqJyFsRU/vTkQgmVOZ3S0IR2LXnNbWUYG7VD76dYVwdfBLyx8AX9+An8A== - -csv-stringify@^5.3.6: - version "5.5.0" - resolved "https://registry.yarnpkg.com/csv-stringify/-/csv-stringify-5.5.0.tgz#0bdeaaf60d6e15b89c752a0eceb4b4c2c8af5a8a" - integrity sha512-G05575DSO/9vFzQxZN+Srh30cNyHk0SM0ePyiTChMD5WVt7GMTVPBQf4rtgMF6mqhNCJUPw4pN8LDe8MF9EYOA== - -csv@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/csv/-/csv-5.3.2.tgz#50b344e25dfbb8c62684a1bcec18c22468b2161e" - integrity sha512-odDyucr9OgJTdGM2wrMbJXbOkJx3nnUX3Pt8SFOwlAMOpsUQlz1dywvLMXJWX/4Ib0rjfOsaawuuwfI5ucqBGQ== - dependencies: - csv-generate "^3.2.4" - csv-parse "^4.8.8" - csv-stringify "^5.3.6" - stream-transform "^2.0.1" - cyclist@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" @@ -8271,11 +8246,6 @@ mixin-object@^2.0.1: for-in "^0.1.3" is-extendable "^0.1.1" -mixme@^0.3.1: - version "0.3.5" - resolved "https://registry.yarnpkg.com/mixme/-/mixme-0.3.5.tgz#304652cdaf24a3df0487205e61ac6162c6906ddd" - integrity sha512-SyV9uPETRig5ZmYev0ANfiGeB+g6N2EnqqEfBbCGmmJ6MgZ3E4qv5aPbnHVdZ60KAHHXV+T3sXopdrnIXQdmjQ== - mkdirp@0.5.1, mkdirp@0.x, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" @@ -11926,13 +11896,6 @@ stream-shift@^1.0.0: resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== -stream-transform@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/stream-transform/-/stream-transform-2.0.2.tgz#3cb7a14c802eb39bc40caaab0535e584f3a65caf" - integrity sha512-J+D5jWPF/1oX+r9ZaZvEXFbu7znjxSkbNAHJ9L44bt/tCVuOEWZlDqU9qJk7N2xBU1S+K2DPpSKeR/MucmCA1Q== - dependencies: - mixme "^0.3.1" - streamsearch@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-0.1.2.tgz#808b9d0e56fc273d809ba57338e929919a1a9f1a" From a22320e141011bd81a6baf13fa0d445985748746 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sun, 22 Nov 2020 17:25:41 +0100 Subject: [PATCH 12/30] removed MS excel support, moved to plugin --- packages/api/package.json | 3 +- packages/api/src/controllers/files.js | 12 --- packages/api/src/controllers/plugins.js | 7 ++ packages/api/src/controllers/runners.js | 2 +- packages/api/src/main.js | 2 - packages/api/src/shell/excelSheetReader.js | 41 ---------- packages/api/src/shell/excelSheetWriter.js | 56 ------------- packages/api/src/shell/index.js | 13 +-- packages/api/src/shell/registerPlugins.js | 9 +++ packages/api/src/shell/requirePlugin.js | 29 +++++++ packages/web/src/plugins/PluginsProvider.js | 8 +- packages/web/src/utility/fileformats.js | 52 +----------- yarn.lock | 87 +-------------------- 13 files changed, 64 insertions(+), 257 deletions(-) delete mode 100644 packages/api/src/controllers/files.js delete mode 100644 packages/api/src/shell/excelSheetReader.js delete mode 100644 packages/api/src/shell/excelSheetWriter.js create mode 100644 packages/api/src/shell/registerPlugins.js create mode 100644 packages/api/src/shell/requirePlugin.js diff --git a/packages/api/package.json b/packages/api/package.json index e4482f94f..0a94f7002 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -47,8 +47,7 @@ "node-fetch": "^2.6.1", "pacote": "^11.1.13", "pg": "^7.17.0", - "pg-query-stream": "^3.1.1", - "xlsx": "^0.16.8" + "pg-query-stream": "^3.1.1" }, "scripts": { "start": "nodemon src/index.js", diff --git a/packages/api/src/controllers/files.js b/packages/api/src/controllers/files.js deleted file mode 100644 index 6be3173df..000000000 --- a/packages/api/src/controllers/files.js +++ /dev/null @@ -1,12 +0,0 @@ -const xlsx = require('xlsx'); -const _ = require('lodash'); - -module.exports = { - openedReaders: {}, - - analyseExcel_meta: 'get', - async analyseExcel({ filePath }) { - const workbook = xlsx.readFile(filePath, { bookSheets: true }); - return workbook.SheetNames; - }, -}; diff --git a/packages/api/src/controllers/plugins.js b/packages/api/src/controllers/plugins.js index 3abcbc968..1129d9857 100644 --- a/packages/api/src/controllers/plugins.js +++ b/packages/api/src/controllers/plugins.js @@ -4,6 +4,7 @@ const path = require('path'); const pacote = require('pacote'); const { pluginstmpdir, pluginsdir } = require('../utility/directories'); const socket = require('../utility/socket'); +const requirePlugin = require('../shell/requirePlugin'); async function loadPackageInfo(dir) { const readmeFile = path.join(dir, 'README.md'); @@ -85,4 +86,10 @@ module.exports = { await fs.rmdir(dir, { recursive: true }); socket.emitChanged(`installed-plugins-changed`); }, + + command_meta: 'post', + async command({ packageName, command, args }) { + const content = requirePlugin(packageName); + return content.commands[command](args); + }, }; diff --git a/packages/api/src/controllers/runners.js b/packages/api/src/controllers/runners.js index aaac34d64..b87ae7776 100644 --- a/packages/api/src/controllers/runners.js +++ b/packages/api/src/controllers/runners.js @@ -19,7 +19,7 @@ const requirePluginsTemplate = (plugins) => .map( (packageName) => `const ${_.camelCase(packageName)} = require(process.env.PLUGIN_${_.camelCase(packageName)});\n` ) - .join(''); + .join('') + `dbgateApi.registerPlugins(${plugins.map((x) => _.camelCase(x)).join(',')});\n`; const scriptTemplate = (script) => ` const dbgateApi = require(process.env.DBGATE_API); diff --git a/packages/api/src/main.js b/packages/api/src/main.js index fa741841f..37841c0cf 100644 --- a/packages/api/src/main.js +++ b/packages/api/src/main.js @@ -20,7 +20,6 @@ const sessions = require('./controllers/sessions'); const runners = require('./controllers/runners'); const jsldata = require('./controllers/jsldata'); const config = require('./controllers/config'); -const files = require('./controllers/files'); const archive = require('./controllers/archive'); const uploads = require('./controllers/uploads'); const plugins = require('./controllers/plugins'); @@ -65,7 +64,6 @@ function start(argument = null) { useController(app, '/runners', runners); useController(app, '/jsldata', jsldata); useController(app, '/config', config); - useController(app, '/files', files); useController(app, '/archive', archive); useController(app, '/uploads', uploads); useController(app, '/plugins', plugins); diff --git a/packages/api/src/shell/excelSheetReader.js b/packages/api/src/shell/excelSheetReader.js deleted file mode 100644 index 2ad325d1d..000000000 --- a/packages/api/src/shell/excelSheetReader.js +++ /dev/null @@ -1,41 +0,0 @@ -const xlsx = require('xlsx'); -const stream = require('stream'); -const _ = require('lodash'); - -const loadedWorkbooks = {}; - -async function loadWorkbook(fileName) { - let workbook = loadedWorkbooks[fileName]; - if (workbook) return workbook; - console.log(`Loading excel ${fileName}`); - workbook = xlsx.readFile(fileName); - loadedWorkbooks[fileName] = workbook; - return workbook; -} - -async function excelSheetReader({ fileName, sheetName, limitRows = undefined }) { - const workbook = await loadWorkbook(fileName); - const sheet = workbook.Sheets[sheetName]; - - const pass = new stream.PassThrough({ - objectMode: true, - }); - const rows = xlsx.utils.sheet_to_json(sheet, { header: 1 }); - const header = rows[0]; - const structure = { - columns: _.range(header.length).map((index) => ({ columnName: header[index] })), - }; - pass.write(structure); - for (let rowIndex = 1; rowIndex < rows.length; rowIndex++) { - if (limitRows && rowIndex > limitRows) break; - const row = rows[rowIndex]; - const rowData = _.fromPairs(structure.columns.map((col, index) => [col.columnName, row[index]])); - if (_.isEmpty(_.omitBy(rowData, (v) => v == null || v.toString().trim().length == 0))) continue; - pass.write(rowData); - } - pass.end(); - - return pass; -} - -module.exports = excelSheetReader; diff --git a/packages/api/src/shell/excelSheetWriter.js b/packages/api/src/shell/excelSheetWriter.js deleted file mode 100644 index 30ce9f983..000000000 --- a/packages/api/src/shell/excelSheetWriter.js +++ /dev/null @@ -1,56 +0,0 @@ -const xlsx = require('xlsx'); -const stream = require('stream'); -const finalizer = require('./finalizer'); - -const writingWorkbooks = {}; - -async function saveExcelFiles() { - for (const file in writingWorkbooks) { - xlsx.writeFile(writingWorkbooks[file], file); - } -} - -finalizer.register(saveExcelFiles); - -function createWorkbook(fileName) { - let workbook = writingWorkbooks[fileName]; - if (workbook) return workbook; - workbook = xlsx.utils.book_new(); - writingWorkbooks[fileName] = workbook; - return workbook; -} - -class ExcelSheetWriterStream extends stream.Writable { - constructor({ fileName, sheetName }) { - super({ objectMode: true }); - this.rows = []; - this.structure = null; - this.fileName = fileName; - this.sheetName = sheetName; - } - _write(chunk, enc, next) { - if (this.structure) { - this.rows.push(this.structure.columns.map((col) => chunk[col.columnName])); - } else { - this.structure = chunk; - this.rows.push(chunk.columns.map((x) => x.columnName)); - } - - next(); - } - - _final(callback) { - const workbook = createWorkbook(this.fileName); - xlsx.utils.book_append_sheet(workbook, xlsx.utils.aoa_to_sheet(this.rows), this.sheetName || 'Sheet 1'); - callback(); - } -} - -async function excelSheetWriter({ fileName, sheetName }) { - return new ExcelSheetWriterStream({ - fileName, - sheetName, - }); -} - -module.exports = excelSheetWriter; diff --git a/packages/api/src/shell/index.js b/packages/api/src/shell/index.js index 644608716..521ca41c2 100644 --- a/packages/api/src/shell/index.js +++ b/packages/api/src/shell/index.js @@ -5,8 +5,6 @@ const tableReader = require('./tableReader'); const copyStream = require('./copyStream'); const fakeObjectReader = require('./fakeObjectReader'); const consoleObjectWriter = require('./consoleObjectWriter'); -const excelSheetReader = require('./excelSheetReader'); -const excelSheetWriter = require('./excelSheetWriter'); const jsonLinesWriter = require('./jsonLinesWriter'); const jsonLinesReader = require('./jsonLinesReader'); const jslDataReader = require('./jslDataReader'); @@ -14,14 +12,15 @@ const archiveWriter = require('./archiveWriter'); const archiveReader = require('./archiveReader'); const collectorWriter = require('./collectorWriter'); const finalizer = require('./finalizer'); +const registerPlugins = require('./registerPlugins'); +const requirePlugin = require('./requirePlugin'); -module.exports = { +const dbgateApi = { queryReader, runScript, tableWriter, tableReader, copyStream, - excelSheetReader, jsonLinesWriter, jsonLinesReader, fakeObjectReader, @@ -30,6 +29,10 @@ module.exports = { archiveWriter, archiveReader, collectorWriter, - excelSheetWriter, finalizer, + registerPlugins, }; + +requirePlugin.initialize(dbgateApi); + +module.exports = dbgateApi; diff --git a/packages/api/src/shell/registerPlugins.js b/packages/api/src/shell/registerPlugins.js new file mode 100644 index 000000000..634463a8a --- /dev/null +++ b/packages/api/src/shell/registerPlugins.js @@ -0,0 +1,9 @@ +const requirePlugin = require('./requirePlugin'); + +function registerPlugins(...plugins) { + for (const plugin of plugins) { + requirePlugin(plugin.packageName, plugin); + } +} + +module.exports = registerPlugins; diff --git a/packages/api/src/shell/requirePlugin.js b/packages/api/src/shell/requirePlugin.js new file mode 100644 index 000000000..386d3a3ee --- /dev/null +++ b/packages/api/src/shell/requirePlugin.js @@ -0,0 +1,29 @@ +const path = require('path'); +const { pluginsdir } = require('../utility/directories'); + +const loadedPlugins = {}; + +const dbgateEnv = { + dbgateApi: null, +}; + +function requirePlugin(packageName, requiredPlugin = null) { + if (!packageName) throw new Error('Missing packageName in plugin'); + if (loadedPlugins[packageName]) return loadedPlugins[packageName]; + + if (requiredPlugin == null) { + console.log('Loading module', packageName); + const module = require(path.join(pluginsdir(), packageName, 'lib', 'backend.js')); + requiredPlugin = module.__esModule ? module.default : module; + } + loadedPlugins[packageName] = requiredPlugin; + if (requiredPlugin.initialize) requiredPlugin.initialize(dbgateEnv); + + return requiredPlugin; +} + +requirePlugin.initialize = (value) => { + dbgateEnv.dbgateApi = value; +}; + +module.exports = requirePlugin; diff --git a/packages/web/src/plugins/PluginsProvider.js b/packages/web/src/plugins/PluginsProvider.js index 6e9f5767d..de66b9e79 100644 --- a/packages/web/src/plugins/PluginsProvider.js +++ b/packages/web/src/plugins/PluginsProvider.js @@ -5,6 +5,10 @@ import { useInstalledPlugins } from '../utility/metadataLoaders'; const PluginsContext = React.createContext(null); +const dbgateEnv = { + axios, +}; + export default function PluginsProvider({ children }) { const installedPlugins = useInstalledPlugins(); const [plugins, setPlugins] = React.useState({}); @@ -22,7 +26,9 @@ export default function PluginsProvider({ children }) { }); const module = eval(resp.data); console.log('Loaded plugin', module); - newPlugins[installed.name] = module.__esModule ? module.default : module; + const moduleContent = module.__esModule ? module.default : module; + if (moduleContent.initialize) moduleContent.initialize(dbgateEnv); + newPlugins[installed.name] = moduleContent; } } setPlugins((x) => diff --git a/packages/web/src/utility/fileformats.js b/packages/web/src/utility/fileformats.js index 9fee0859a..52ec9738c 100644 --- a/packages/web/src/utility/fileformats.js +++ b/packages/web/src/utility/fileformats.js @@ -1,53 +1,3 @@ -import { usePlugins } from '../plugins/PluginsProvider'; -import axios from './axios'; -import { FormSchemaSelect } from './forms'; - -const excelFormat = { - storageType: 'excel', - extension: 'xlsx', - name: 'MS Excel', - readerFunc: 'excelSheetReader', - writerFunc: 'excelSheetWriter', - - addFilesToSourceList: async (file, newSources, newValues) => { - const resp = await axios.get(`files/analyse-excel?filePath=${encodeURIComponent(file.full)}`); - const sheetNames = resp.data; - for (const sheetName of sheetNames) { - newSources.push(sheetName); - newValues[`sourceFile_${sheetName}`] = { - fileName: file.full, - sheetName, - }; - } - }, - - args: [ - { - type: 'checkbox', - name: 'singleFile', - label: 'Create single file', - direction: 'target', - }, - ], - - getDefaultOutputName: (sourceName, values) => { - if (values.target_excel_singleFile) { - return sourceName; - } - return null; - }, - - getOutputParams: (sourceName, values) => { - if (values.target_excel_singleFile) { - return { - sheetName: values[`targetName_${sourceName}`] || sourceName, - fileName: 'data.xlsx', - }; - } - return null; - }, -}; - const jsonlFormat = { storageType: 'jsonl', extension: 'jsonl', @@ -58,7 +8,7 @@ const jsonlFormat = { /** @returns {import('dbgate-types').FileFormatDefinition[]} */ export function buildFileFormats(plugins) { - const res = [excelFormat, jsonlFormat]; + const res = [ jsonlFormat]; for (const { content } of plugins) { const { fileFormats } = content; if (fileFormats) res.push(...fileFormats); diff --git a/yarn.lock b/yarn.lock index 08c18f2d4..6ccb69bd8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2018,14 +2018,6 @@ adjust-sourcemap-loader@2.0.0: object-path "0.11.4" regex-parser "2.2.10" -adler-32@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/adler-32/-/adler-32-1.2.0.tgz#6a3e6bf0a63900ba15652808cb15c6813d1a5f25" - integrity sha1-aj5r8KY5ALoVZSgIyxXGgT0aXyU= - dependencies: - exit-on-epipe "~1.0.1" - printj "~1.1.0" - after@0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" @@ -3154,15 +3146,6 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -cfb@^1.1.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/cfb/-/cfb-1.2.0.tgz#6a4d0872b525ed60349e1ef51fb4b0bf73eca9a8" - integrity sha512-sXMvHsKCICVR3Naq+J556K+ExBo9n50iKl6LGarlnvuA2035uMlGA/qVrc0wQtow5P1vJEw9UyrKLCbtIKz+TQ== - dependencies: - adler-32 "~1.2.0" - crc-32 "~1.2.0" - printj "~1.1.2" - chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -3376,14 +3359,6 @@ code-point-at@^1.0.0: resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= -codepage@~1.14.0: - version "1.14.0" - resolved "https://registry.yarnpkg.com/codepage/-/codepage-1.14.0.tgz#8cbe25481323559d7d307571b0fff91e7a1d2f99" - integrity sha1-jL4lSBMjVZ19MHVxsP/5HnodL5k= - dependencies: - commander "~2.14.1" - exit-on-epipe "~1.0.1" - collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" @@ -3439,7 +3414,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@2.17.x, commander@~2.17.1: +commander@2.17.x: version "2.17.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" integrity sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg== @@ -3454,11 +3429,6 @@ commander@^4.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== -commander@~2.14.1: - version "2.14.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.14.1.tgz#2235123e37af8ca3c65df45b026dbd357b01b9aa" - integrity sha512-+YR16o3rK53SmWHU3rEM3tPAh2rwb1yPcQX5irVn7mb0gXbwuCCrnkbV5+PBfETdfg1vui07nM6PCG1zndcjQw== - commander@~2.19.0: version "2.19.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a" @@ -3723,14 +3693,6 @@ cosmiconfig@^6.0.0: path-type "^4.0.0" yaml "^1.7.2" -crc-32@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.0.tgz#cb2db6e29b88508e32d9dd0ec1693e7b41a18208" - integrity sha512-1uBwHxF+Y/4yF5G48fwnKq6QsIXheor3ZLPT80yGBV1oEUwpPojlEhQbWKVw1VwcTQyMGHK1/XMmTjmlsmTTGA== - dependencies: - exit-on-epipe "~1.0.1" - printj "~1.1.0" - create-ecdh@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" @@ -5050,11 +5012,6 @@ exenv@^1.2.0: resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d" integrity sha1-KueOhdmJQVhnCwPUe+wfA72Ru50= -exit-on-epipe@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz#0bdd92e87d5285d267daa8171d0eb06159689692" - integrity sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw== - exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -5551,11 +5508,6 @@ forwarded@~0.1.2: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= -frac@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/frac/-/frac-1.1.2.tgz#3d74f7f6478c88a1b5020306d747dc6313c74d0b" - integrity sha512-w/XBfkibaTl3YDqASwfDUqkna4Z2p9cFSr1aHDt0WoMTECnRfBOv2WArlZILlqgWlmdIlALXGpM2AOhEk5W3IA== - fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" @@ -10142,11 +10094,6 @@ pretty-format@^25.1.0: ansi-styles "^4.0.0" react-is "^16.12.0" -printj@~1.1.0, printj@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/printj/-/printj-1.1.2.tgz#d90deb2975a8b9f600fb3a1c94e3f4c53c78a222" - integrity sha512-zA2SmoLaxZyArQTOPj5LXecR+RagfPSU5Kw1qP+jkWeNlrq+eJZyY2oS68SU1Z/7/myXM4lo9716laOFAVStCQ== - private@^0.1.6: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -11792,13 +11739,6 @@ sqlstring@2.3.1: resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.3.1.tgz#475393ff9e91479aea62dcaf0ca3d14983a7fb40" integrity sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A= -ssf@~0.11.2: - version "0.11.2" - resolved "https://registry.yarnpkg.com/ssf/-/ssf-0.11.2.tgz#0b99698b237548d088fc43cdf2b70c1a7512c06c" - integrity sha512-+idbmIXoYET47hH+d7dfm2epdOMUDjqcB4648sTZ+t2JwoyBFL/insLfB/racrDmsKB3diwsDA696pZMieAC5g== - dependencies: - frac "~1.1.2" - sshpk@^1.7.0: version "1.16.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" @@ -13192,21 +13132,11 @@ widest-line@^2.0.0: dependencies: string-width "^2.1.1" -wmf@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wmf/-/wmf-1.0.2.tgz#7d19d621071a08c2bdc6b7e688a9c435298cc2da" - integrity sha512-/p9K7bEh0Dj6WbXg4JG0xvLQmIadrner1bi45VMJTfnbVHsc7yIajZyoSoK60/dtVBs12Fm6WkUI5/3WAVsNMw== - word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -word@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/word/-/word-0.3.0.tgz#8542157e4f8e849f4a363a288992d47612db9961" - integrity sha512-OELeY0Q61OXpdUfTp+oweA/vtLVg5VDOXh+3he3PNzLGG/y0oylSOC1xRVj0+l4vQ3tj/bB1HVHv1ocXkQceFA== - workbox-background-sync@^4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-4.3.1.tgz#26821b9bf16e9e37fd1d640289edddc08afd1950" @@ -13434,21 +13364,6 @@ xdg-basedir@^3.0.0: resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" integrity sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ= -xlsx@^0.16.8: - version "0.16.8" - resolved "https://registry.yarnpkg.com/xlsx/-/xlsx-0.16.8.tgz#5546de9b0ba15169b36770d4e43b24790d3ff1b8" - integrity sha512-qWub4YCn0xLEGHI7WWhk6IJ73MDu7sPSJQImxN6/LiI8wsHi0hUhICEDbyqBT+jgFgORZxrii0HvhNSwBNAPoQ== - dependencies: - adler-32 "~1.2.0" - cfb "^1.1.4" - codepage "~1.14.0" - commander "~2.17.1" - crc-32 "~1.2.0" - exit-on-epipe "~1.0.1" - ssf "~0.11.2" - wmf "~1.0.1" - word "~0.3.0" - xml-name-validator@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" From 994195667dd91b778a656ce1e750bd7d9227314c Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sun, 22 Nov 2020 17:29:33 +0100 Subject: [PATCH 13/30] fix --- packages/web/src/utility/UploadsProvider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/src/utility/UploadsProvider.js b/packages/web/src/utility/UploadsProvider.js index 09c0c38b0..065b442d0 100644 --- a/packages/web/src/utility/UploadsProvider.js +++ b/packages/web/src/utility/UploadsProvider.js @@ -47,7 +47,7 @@ export function useUploadsZone() { for (const format of extensions.fileFormats) { if (file.name.endsWith('.' + format.extension)) { - fileData.shortName = file.name.slice(-format.extension.length - 1); + fileData.shortName = file.name.slice(0, -format.extension.length - 1); fileData.storageType = format.storageType; } } From d3cfc44fd984061d9881f7adf68aec50c1ce2a75 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sun, 22 Nov 2020 18:00:01 +0100 Subject: [PATCH 14/30] disable axios cache --- packages/web/src/utility/axios.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/web/src/utility/axios.js b/packages/web/src/utility/axios.js index fb26c04df..9a587ccb9 100644 --- a/packages/web/src/utility/axios.js +++ b/packages/web/src/utility/axios.js @@ -1,6 +1,14 @@ import axios from 'axios'; import resolveApi from './resolveApi'; -export default axios.create({ +const axiosInstance = axios.create({ baseURL: resolveApi(), }); + +axiosInstance.defaults.headers = { + 'Cache-Control': 'no-cache', + Pragma: 'no-cache', + Expires: '0', +}; + +export default axiosInstance; From 88cf6d35ed437147c17f28e39fcca81a9bf3f6d4 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Mon, 23 Nov 2020 20:49:25 +0100 Subject: [PATCH 15/30] refactor - default dbaget engine mvoed to dbgate-tools --- .../src/controllers/databaseConnections.js | 2 +- packages/engines/mssql/MsSqlAnalyser.js | 2 +- packages/engines/mssql/MsSqlDumper.js | 2 +- .../engines/mssql/createBulkInsertStream.js | 2 +- packages/engines/mssql/index.js | 2 +- packages/engines/mysql/MySqlAnalyser.js | 8 +- packages/engines/mysql/MySqlDumper.js | 2 +- packages/engines/mysql/index.js | 8 +- packages/engines/postgres/PostgreAnalyser.js | 8 +- packages/engines/postgres/PostgreDumper.js | 2 +- packages/engines/postgres/index.js | 7 +- .../src/DatabaseAnalyser.ts} | 110 ++++++++---------- .../SqlDumper.js => tools/src/SqlDumper.ts} | 63 +++++----- .../src/createBulkInsertStreamBase.ts} | 13 +-- .../driverBase.js => tools/src/driverBase.ts} | 11 +- packages/tools/src/index.ts | 4 + 16 files changed, 115 insertions(+), 131 deletions(-) rename packages/{engines/default/DatabaseAnalyser.js => tools/src/DatabaseAnalyser.ts} (51%) rename packages/{engines/default/SqlDumper.js => tools/src/SqlDumper.ts} (83%) rename packages/{engines/default/createBulkInsertStreamBase.js => tools/src/createBulkInsertStreamBase.ts} (90%) rename packages/{engines/default/driverBase.js => tools/src/driverBase.ts} (70%) diff --git a/packages/api/src/controllers/databaseConnections.js b/packages/api/src/controllers/databaseConnections.js index be16f7e95..37a5a0a9b 100644 --- a/packages/api/src/controllers/databaseConnections.js +++ b/packages/api/src/controllers/databaseConnections.js @@ -2,7 +2,7 @@ const uuidv1 = require('uuid/v1'); const connections = require('./connections'); const socket = require('../utility/socket'); const { fork } = require('child_process'); -const DatabaseAnalyser = require('dbgate-engines/default/DatabaseAnalyser'); +const { DatabaseAnalyser } = require('dbgate-tools'); module.exports = { /** @type {import('dbgate-types').OpenedDatabaseConnection[]} */ diff --git a/packages/engines/mssql/MsSqlAnalyser.js b/packages/engines/mssql/MsSqlAnalyser.js index 8a272a3c8..7804a4c69 100644 --- a/packages/engines/mssql/MsSqlAnalyser.js +++ b/packages/engines/mssql/MsSqlAnalyser.js @@ -2,7 +2,7 @@ const fp = require('lodash/fp'); const _ = require('lodash'); const sql = require('./sql'); -const DatabaseAnalyser = require('../default/DatabaseAnalyser'); +const { DatabaseAnalyser } = require('dbgate-tools'); const { filter } = require('lodash'); const { isTypeString, isTypeNumeric } = require('dbgate-tools'); diff --git a/packages/engines/mssql/MsSqlDumper.js b/packages/engines/mssql/MsSqlDumper.js index ba5bf0b8a..652fc5016 100644 --- a/packages/engines/mssql/MsSqlDumper.js +++ b/packages/engines/mssql/MsSqlDumper.js @@ -1,4 +1,4 @@ -const SqlDumper = require('../default/SqlDumper'); +const { SqlDumper } = require('dbgate-tools'); class MsSqlDumper extends SqlDumper { autoIncrement() { diff --git a/packages/engines/mssql/createBulkInsertStream.js b/packages/engines/mssql/createBulkInsertStream.js index b3f345102..991783b84 100644 --- a/packages/engines/mssql/createBulkInsertStream.js +++ b/packages/engines/mssql/createBulkInsertStream.js @@ -1,4 +1,4 @@ -const createBulkInsertStreamBase = require('../default/createBulkInsertStreamBase'); +const { createBulkInsertStreamBase } = require('dbgate-tools'); /** * diff --git a/packages/engines/mssql/index.js b/packages/engines/mssql/index.js index 2eda2cde9..f09eec170 100644 --- a/packages/engines/mssql/index.js +++ b/packages/engines/mssql/index.js @@ -1,8 +1,8 @@ const _ = require('lodash'); +const { driverBase } = require('dbgate-tools'); const MsSqlAnalyser = require('./MsSqlAnalyser'); const MsSqlDumper = require('./MsSqlDumper'); const createBulkInsertStream = require('./createBulkInsertStream'); -const driverBase = require('../default/driverBase'); /** @type {import('dbgate-types').SqlDialect} */ const dialect = { diff --git a/packages/engines/mysql/MySqlAnalyser.js b/packages/engines/mysql/MySqlAnalyser.js index 64de86467..4ce5aa1a8 100644 --- a/packages/engines/mysql/MySqlAnalyser.js +++ b/packages/engines/mysql/MySqlAnalyser.js @@ -2,7 +2,7 @@ const fp = require('lodash/fp'); const _ = require('lodash'); const sql = require('./sql'); -const DatabaseAnalayser = require('../default/DatabaseAnalyser'); +const { DatabaseAnalyser } = require('dbgate-tools'); const { isTypeString, isTypeNumeric } = require('dbgate-tools'); const { rangeStep } = require('lodash/fp'); @@ -35,7 +35,7 @@ function objectTypeToField(type) { return null; } -class MySqlAnalyser extends DatabaseAnalayser { +class MySqlAnalyser extends DatabaseAnalyser { constructor(pool, driver) { super(pool, driver); } @@ -103,8 +103,8 @@ class MySqlAnalyser extends DatabaseAnalayser { tables: tables.rows.map((table) => ({ ...table, columns: columns.rows.filter((col) => col.pureName == table.pureName).map(getColumnInfo), - primaryKey: DatabaseAnalayser.extractPrimaryKeys(table, pkColumns.rows), - foreignKeys: DatabaseAnalayser.extractForeignKeys(table, fkColumns.rows), + primaryKey: DatabaseAnalyser.extractPrimaryKeys(table, pkColumns.rows), + foreignKeys: DatabaseAnalyser.extractForeignKeys(table, fkColumns.rows), })), views: views.rows.map((view) => ({ ...view, diff --git a/packages/engines/mysql/MySqlDumper.js b/packages/engines/mysql/MySqlDumper.js index 3b778de0c..0a5e6922d 100644 --- a/packages/engines/mysql/MySqlDumper.js +++ b/packages/engines/mysql/MySqlDumper.js @@ -1,4 +1,4 @@ -const SqlDumper = require('../default/SqlDumper'); +const { SqlDumper } = require('dbgate-tools'); class MySqlDumper extends SqlDumper { /** @param type {import('dbgate-types').TransformType} */ diff --git a/packages/engines/mysql/index.js b/packages/engines/mysql/index.js index 5aee7c46d..010e7a461 100644 --- a/packages/engines/mysql/index.js +++ b/packages/engines/mysql/index.js @@ -1,4 +1,4 @@ -const driverBase = require('../default/driverBase'); +const { driverBase } = require('dbgate-tools'); const MySqlAnalyser = require('./MySqlAnalyser'); const MySqlDumper = require('./MySqlDumper'); @@ -143,6 +143,12 @@ const driver = { const { rows } = await this.query(connection, 'show databases'); return rows.map((x) => ({ name: x.Database })); }, + async writeTable(pool, name, options) { + const { stream } = pool._nativeModules; + // @ts-ignore + return createBulkInsertStreamBase(this, stream, pool, name, options); + }, + // createDumper() { // return new MySqlDumper(this); // }, diff --git a/packages/engines/postgres/PostgreAnalyser.js b/packages/engines/postgres/PostgreAnalyser.js index 16ed42b5d..79a4a32a1 100644 --- a/packages/engines/postgres/PostgreAnalyser.js +++ b/packages/engines/postgres/PostgreAnalyser.js @@ -2,7 +2,7 @@ const fp = require('lodash/fp'); const _ = require('lodash'); const sql = require('./sql'); -const DatabaseAnalayser = require('../default/DatabaseAnalyser'); +const { DatabaseAnalyser } = require('dbgate-tools'); const { isTypeString, isTypeNumeric } = require('dbgate-tools'); function normalizeTypeName(dataType) { @@ -35,7 +35,7 @@ function getColumnInfo({ }; } -class PostgreAnalyser extends DatabaseAnalayser { +class PostgreAnalyser extends DatabaseAnalyser { constructor(pool, driver) { super(pool, driver); } @@ -84,8 +84,8 @@ class PostgreAnalyser extends DatabaseAnalayser { columns: columns.rows .filter((col) => col.pureName == table.pureName && col.schemaName == table.schemaName) .map(getColumnInfo), - primaryKey: DatabaseAnalayser.extractPrimaryKeys(table, pkColumns.rows), - foreignKeys: DatabaseAnalayser.extractForeignKeys(table, fkColumns.rows), + primaryKey: DatabaseAnalyser.extractPrimaryKeys(table, pkColumns.rows), + foreignKeys: DatabaseAnalyser.extractForeignKeys(table, fkColumns.rows), })), views: views.rows.map((view) => ({ ...view, diff --git a/packages/engines/postgres/PostgreDumper.js b/packages/engines/postgres/PostgreDumper.js index 12582b547..2fe0bf076 100644 --- a/packages/engines/postgres/PostgreDumper.js +++ b/packages/engines/postgres/PostgreDumper.js @@ -1,4 +1,4 @@ -const SqlDumper = require('../default/SqlDumper'); +const { SqlDumper } = require('dbgate-tools'); class PostgreDumper extends SqlDumper { /** @param type {import('dbgate-types').TransformType} */ diff --git a/packages/engines/postgres/index.js b/packages/engines/postgres/index.js index bc09995b4..9aad592cf 100644 --- a/packages/engines/postgres/index.js +++ b/packages/engines/postgres/index.js @@ -1,5 +1,5 @@ const _ = require('lodash'); -const driverBase = require('../default/driverBase'); +const { driverBase } = require('dbgate-tools'); const PostgreAnalyser = require('./PostgreAnalyser'); const PostgreDumper = require('./PostgreDumper'); @@ -174,6 +174,11 @@ const driver = { // createDumper() { // return new PostgreDumper(this); // }, + async writeTable(pool, name, options) { + const { stream } = pool._nativeModules; + // @ts-ignore + return createBulkInsertStreamBase(this, stream, pool, name, options); + }, async listDatabases(client) { const { rows } = await this.query(client, 'SELECT datname AS name FROM pg_database WHERE datistemplate = false'); return rows; diff --git a/packages/engines/default/DatabaseAnalyser.js b/packages/tools/src/DatabaseAnalyser.ts similarity index 51% rename from packages/engines/default/DatabaseAnalyser.js rename to packages/tools/src/DatabaseAnalyser.ts index 8874a725e..47360ecca 100644 --- a/packages/engines/default/DatabaseAnalyser.js +++ b/packages/tools/src/DatabaseAnalyser.ts @@ -1,21 +1,13 @@ -const _ = require('lodash'); -const fp = require('lodash/fp'); +import { DatabaseInfo, DatabaseModification, EngineDriver } from 'dbgate-types'; +import _ from 'lodash'; +import fp from 'lodash/fp'; -class DatabaseAnalyser { - /** - * - * @param {import('dbgate-types').EngineDriver} driver - */ - constructor(pool, driver) { - this.pool = pool; - this.driver = driver; - // this.result = DatabaseAnalyser.createEmptyStructure(); - /** @type {import('dbgate-types').DatabaseInfo} */ - this.structure = null; - /** import('dbgate-types').DatabaseModification[]) */ - this.modifications = null; - this.singleObjectFilter = null; - } +export class DatabaseAnalyser { + structure: DatabaseInfo; + modifications: DatabaseModification[]; + singleObjectFilter: any; + + constructor(public pool, public driver: EngineDriver) {} async _runAnalysis() { return DatabaseAnalyser.createEmptyStructure(); @@ -80,46 +72,46 @@ class DatabaseAnalyser { // findObjectById(id) { // return this.structure.tables.find((x) => x.objectId == id); // } + + static createEmptyStructure(): DatabaseInfo { + return { + tables: [], + views: [], + functions: [], + procedures: [], + triggers: [], + schemas: [], + }; + } + + static byTableFilter(table) { + return (x) => x.pureName == table.pureName && x.schemaName == x.schemaName; + } + + static extractPrimaryKeys(table, pkColumns) { + const filtered = pkColumns.filter(DatabaseAnalyser.byTableFilter(table)); + if (filtered.length == 0) return undefined; + return { + ..._.pick(filtered[0], ['constraintName', 'schemaName', 'pureName']), + constraintType: 'primaryKey', + columns: filtered.map(fp.pick('columnName')), + }; + } + static extractForeignKeys(table, fkColumns) { + const grouped = _.groupBy(fkColumns.filter(DatabaseAnalyser.byTableFilter(table)), 'constraintName'); + return _.keys(grouped).map((constraintName) => ({ + constraintName, + constraintType: 'foreignKey', + ..._.pick(grouped[constraintName][0], [ + 'constraintName', + 'schemaName', + 'pureName', + 'refSchemaName', + 'refTableName', + 'updateAction', + 'deleteAction', + ]), + columns: grouped[constraintName].map(fp.pick(['columnName', 'refColumnName'])), + })); + } } - -/** @returns {import('dbgate-types').DatabaseInfo} */ -DatabaseAnalyser.createEmptyStructure = () => ({ - tables: [], - views: [], - functions: [], - procedures: [], - triggers: [], - schemas: [], -}); - -DatabaseAnalyser.byTableFilter = (table) => (x) => x.pureName == table.pureName && x.schemaName == x.schemaName; - -DatabaseAnalyser.extractPrimaryKeys = (table, pkColumns) => { - const filtered = pkColumns.filter(DatabaseAnalyser.byTableFilter(table)); - if (filtered.length == 0) return undefined; - return { - ..._.pick(filtered[0], ['constraintName', 'schemaName', 'pureName']), - constraintType: 'primaryKey', - columns: filtered.map(fp.pick('columnName')), - }; -}; - -DatabaseAnalyser.extractForeignKeys = (table, fkColumns) => { - const grouped = _.groupBy(fkColumns.filter(DatabaseAnalyser.byTableFilter(table)), 'constraintName'); - return _.keys(grouped).map((constraintName) => ({ - constraintName, - constraintType: 'foreignKey', - ..._.pick(grouped[constraintName][0], [ - 'constraintName', - 'schemaName', - 'pureName', - 'refSchemaName', - 'refTableName', - 'updateAction', - 'deleteAction', - ]), - columns: grouped[constraintName].map(fp.pick(['columnName', 'refColumnName'])), - })); -}; - -module.exports = DatabaseAnalyser; diff --git a/packages/engines/default/SqlDumper.js b/packages/tools/src/SqlDumper.ts similarity index 83% rename from packages/engines/default/SqlDumper.js rename to packages/tools/src/SqlDumper.ts index e00b96ca1..2e9c51ba5 100644 --- a/packages/engines/default/SqlDumper.js +++ b/packages/tools/src/SqlDumper.ts @@ -1,13 +1,24 @@ -const _ = require('lodash'); -const moment = require('moment'); +import { + ColumnInfo, + EngineDriver, + ForeignKeyInfo, + NamedObjectInfo, + SqlDialect, + TableInfo, + TransformType, +} from 'dbgate-types'; +import _ from 'lodash'; +import moment from 'moment'; -class SqlDumper { - /** @param driver {import('dbgate-types').EngineDriver} */ - constructor(driver) { - this.s = ''; +export class SqlDumper { + s = ''; + driver: EngineDriver; + dialect: SqlDialect; + indentLevel = 0; + + constructor(driver: EngineDriver) { this.driver = driver; this.dialect = driver.dialect; - this.indentLevel = 0; } endCommand() { this.putRaw(';\n'); @@ -85,8 +96,7 @@ class SqlDumper { if (!collection) return; this.putCollection(', ', collection, (item) => this.putFormattedValue(c, item)); } - /** @param format {string} */ - put(format, ...args) { + put(format: string, ...args) { let i = 0; let argIndex = 0; const length = format.length; @@ -149,10 +159,7 @@ class SqlDumper { this.put(' ^auto_increment'); } - /** - * @param column {import('dbgate-types').ColumnInfo} - */ - columnDefinition(column, { includeDefault = true, includeNullable = true, includeCollate = true } = {}) { + columnDefinition(column: ColumnInfo, { includeDefault = true, includeNullable = true, includeCollate = true } = {}) { if (column.computedExpression) { this.put('^as %s', column.computedExpression); if (column.isPersisted) this.put(' ^persisted'); @@ -175,10 +182,7 @@ class SqlDumper { } } - /** - * @param column {import('dbgate-types').ColumnInfo} - */ - columnDefault(column) { + columnDefault(column: ColumnInfo) { if (column.defaultConstraint != null) { this.put(' ^constraint %i ^default %s ', column.defaultConstraint, column.defaultValue); } else { @@ -186,13 +190,7 @@ class SqlDumper { } } - /** - * @template T - * @param {string} delimiter - * @param {T[]} collection - * @param {(col: T) => void} lambda - */ - putCollection(delimiter, collection, lambda) { + putCollection(delimiter: string, collection: T[], lambda: (col: T) => void) { if (!collection) return; let first = true; for (const item of collection) { @@ -202,8 +200,7 @@ class SqlDumper { } } - /** @param table {import('dbgate-types').TableInfo} */ - createTable(table) { + createTable(table: TableInfo) { this.put('^create ^table %f ( &>&n', table); this.putCollection(',&n', table.columns, (col) => { this.put('%i ', col.columnName); @@ -245,8 +242,7 @@ class SqlDumper { // } } - /** @param fk {import('dbgate-types').ForeignKeyInfo} */ - createForeignKeyFore(fk) { + createForeignKeyFore(fk: ForeignKeyInfo) { if (fk.constraintName != null) this.put('^constraint %i ', fk.constraintName); this.put( '^foreign ^key (%,i) ^references %f (%,i)', @@ -258,16 +254,9 @@ class SqlDumper { if (fk.updateAction) this.put(' ^on ^update %k', fk.updateAction); } - /** @param type {import('dbgate-types').TransformType} */ - transform(type, dumpExpr) { + transform(type: TransformType, dumpExpr) { dumpExpr(); } - /** - * @param table {import('dbgate-types').NamedObjectInfo} - * @param allow {boolean} - */ - allowIdentityInsert(table, allow) {} + allowIdentityInsert(table: NamedObjectInfo, allow: boolean) {} } - -module.exports = SqlDumper; diff --git a/packages/engines/default/createBulkInsertStreamBase.js b/packages/tools/src/createBulkInsertStreamBase.ts similarity index 90% rename from packages/engines/default/createBulkInsertStreamBase.js rename to packages/tools/src/createBulkInsertStreamBase.ts index 12550104b..1d02c9eb6 100644 --- a/packages/engines/default/createBulkInsertStreamBase.js +++ b/packages/tools/src/createBulkInsertStreamBase.ts @@ -1,11 +1,8 @@ -const { prepareTableForImport } = require('dbgate-tools'); -const _ = require('lodash'); +import { EngineDriver } from 'dbgate-types'; +import _ from 'lodash'; +import { prepareTableForImport } from './tableTransforms'; -/** - * - * @param {import('dbgate-types').EngineDriver} driver - */ -function createBulkInsertStreamBase(driver, stream, pool, name, options) { +export function createBulkInsertStreamBase(driver, stream, pool, name, options): any { const fullNameQuoted = name.schemaName ? `${driver.dialect.quoteIdentifier(name.schemaName)}.${driver.dialect.quoteIdentifier(name.pureName)}` : driver.dialect.quoteIdentifier(name.pureName); @@ -94,5 +91,3 @@ function createBulkInsertStreamBase(driver, stream, pool, name, options) { return writable; } - -module.exports = createBulkInsertStreamBase; diff --git a/packages/engines/default/driverBase.js b/packages/tools/src/driverBase.ts similarity index 70% rename from packages/engines/default/driverBase.js rename to packages/tools/src/driverBase.ts index 38c6a9599..6adf8bdec 100644 --- a/packages/engines/default/driverBase.js +++ b/packages/tools/src/driverBase.ts @@ -1,6 +1,6 @@ -const createBulkInsertStreamBase = require('./createBulkInsertStreamBase'); +import { createBulkInsertStreamBase } from './createBulkInsertStreamBase'; -const driverBase = { +export const driverBase = { analyserClass: null, dumperClass: null, @@ -24,11 +24,4 @@ const driverBase = { createDumper() { return new this.dumperClass(this); }, - async writeTable(pool, name, options) { - const { stream, mssql } = pool._nativeModules; - // @ts-ignore - return createBulkInsertStreamBase(this, stream, pool, name, options); - }, }; - -module.exports = driverBase; diff --git a/packages/tools/src/index.ts b/packages/tools/src/index.ts index 9518e5b90..857fa0aec 100644 --- a/packages/tools/src/index.ts +++ b/packages/tools/src/index.ts @@ -2,3 +2,7 @@ export * from './commonTypeParser'; export * from './nameTools'; export * from './tableTransforms'; export * from './packageTools'; +export * from './createBulkInsertStreamBase'; +export * from './DatabaseAnalyser'; +export * from './driverBase'; +export * from './SqlDumper'; From ea2996c9b31002406367f093ff9702b722df05f5 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Mon, 23 Nov 2020 20:51:28 +0100 Subject: [PATCH 16/30] fix --- packages/web/src/datagrid/TableDataGrid.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/web/src/datagrid/TableDataGrid.js b/packages/web/src/datagrid/TableDataGrid.js index c7a7dd42c..039ee89f2 100644 --- a/packages/web/src/datagrid/TableDataGrid.js +++ b/packages/web/src/datagrid/TableDataGrid.js @@ -94,6 +94,7 @@ export default function TableDataGrid({ React.useEffect(() => { const newDisplay = createDisplay(); + if (!newDisplay) return; if (display && display.isLoadedCorrectly && !newDisplay.isLoadedCorrectly) return; setDisplay(newDisplay); }, [connection, config, cache || myCache, conid, database, schemaName, pureName, dbinfo]); From eef3195ee18283f442b626fd4048e2d2792554ee Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Mon, 23 Nov 2020 21:01:53 +0100 Subject: [PATCH 17/30] support webpack minimalize for frontend plugins --- packages/web/src/plugins/PluginsProvider.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/web/src/plugins/PluginsProvider.js b/packages/web/src/plugins/PluginsProvider.js index de66b9e79..0561afa85 100644 --- a/packages/web/src/plugins/PluginsProvider.js +++ b/packages/web/src/plugins/PluginsProvider.js @@ -24,7 +24,7 @@ export default function PluginsProvider({ children }) { packageName: installed.name, }, }); - const module = eval(resp.data); + const module = eval(`${resp.data}; plugin`); console.log('Loaded plugin', module); const moduleContent = module.__esModule ? module.default : module; if (moduleContent.initialize) moduleContent.initialize(dbgateEnv); From 5862a2cdc4ad701cee8c591df82c854949b5ba04 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Tue, 24 Nov 2020 18:42:03 +0100 Subject: [PATCH 18/30] plugin list --- packages/api/src/controllers/plugins.js | 6 ++++-- packages/web/src/widgets/PluginsWidget.js | 14 +++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/api/src/controllers/plugins.js b/packages/api/src/controllers/plugins.js index 1129d9857..e382c0f1d 100644 --- a/packages/api/src/controllers/plugins.js +++ b/packages/api/src/controllers/plugins.js @@ -41,11 +41,13 @@ module.exports = { // const { results } = json || {}; // return (results || []).map((x) => x.package); + // DOCS: https://github.com/npm/registry/blob/master/docs/REGISTRY-API.md#get-v1search const response = await fetch( - `https://www.npmjs.com/search/suggestions?q=dbgate-plugin ${encodeURIComponent(filter)}` + `http://registry.npmjs.com/-/v1/search?text=${encodeURIComponent(filter)}+keywords:dbgateplugin&size=25&from=0` ); const json = await response.json(); - return json || []; + const { objects } = json || {}; + return (objects || []).map((x) => x.package); }, info_meta: 'get', diff --git a/packages/web/src/widgets/PluginsWidget.js b/packages/web/src/widgets/PluginsWidget.js index 6479cfa51..2419257a9 100644 --- a/packages/web/src/widgets/PluginsWidget.js +++ b/packages/web/src/widgets/PluginsWidget.js @@ -1,4 +1,5 @@ import React from 'react'; +import _ from 'lodash'; import { SearchBoxWrapper, WidgetsInnerContainer } from './WidgetStyles'; import WidgetColumnBar, { WidgetColumnBarItem } from './WidgetColumnBar'; import { useInstalledPlugins } from '../utility/metadataLoaders'; @@ -18,15 +19,26 @@ function InstalledPluginsList() { function AvailablePluginsList() { const [filter, setFilter] = React.useState(''); + const [search, setSearch] = React.useState(''); const plugins = useFetch({ url: 'plugins/search', params: { - filter, + filter: search, }, defaultValue: [], }); + const setDebouncedFilter = React.useRef( + // @ts-ignore + _.debounce((value) => setSearch(value), 500) + ); + + React.useEffect(() => { + // @ts-ignore + setDebouncedFilter.current(filter); + }, [filter]); + return ( <> From 556a35f4bacd49ab338ad2d23b1f82196c20d3a6 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Tue, 24 Nov 2020 19:06:05 +0100 Subject: [PATCH 19/30] reduce dbgate-tools package size --- packages/tools/package.json | 12 ++++------- packages/tools/src/DatabaseAnalyser.ts | 20 ++++++++++--------- packages/tools/src/SqlDumper.ts | 11 +++++----- .../tools/src/createBulkInsertStreamBase.ts | 4 ++-- packages/tools/src/driverBase.ts | 2 -- packages/tools/src/packageTools.ts | 4 ++-- packages/tools/src/tableTransforms.ts | 4 ++-- 7 files changed, 27 insertions(+), 30 deletions(-) diff --git a/packages/tools/package.json b/packages/tools/package.json index 9baa270e9..352058ccc 100644 --- a/packages/tools/package.json +++ b/packages/tools/package.json @@ -1,23 +1,20 @@ { - "version": "1.0.1", + "version": "1.0.3", "name": "dbgate-tools", "main": "lib/index.js", "typings": "lib/index.d.ts", - "homepage": "https://dbgate.org/", "repository": { "type": "git", "url": "https://github.com/dbshell/dbgate.git" - }, + }, "funding": "https://www.paypal.com/paypalme/JanProchazkaCz/30eur", "author": "Jan Prochazka", "license": "GPL", - "keywords": [ "sql", "dbgate" ], - "scripts": { "prepare": "yarn build", "build": "tsc", @@ -28,14 +25,13 @@ "lib" ], "devDependencies": { - "dbgate-types": "^1.0.0", "@types/node": "^13.7.0", + "dbgate-types": "^1.0.0", "jest": "^24.9.0", "ts-jest": "^25.2.1", "typescript": "^3.7.5" }, "dependencies": { - "lodash": "^4.17.15", - "moment": "^2.24.0" + "lodash": "^4.17.15" } } diff --git a/packages/tools/src/DatabaseAnalyser.ts b/packages/tools/src/DatabaseAnalyser.ts index 47360ecca..d39460a0e 100644 --- a/packages/tools/src/DatabaseAnalyser.ts +++ b/packages/tools/src/DatabaseAnalyser.ts @@ -1,6 +1,8 @@ import { DatabaseInfo, DatabaseModification, EngineDriver } from 'dbgate-types'; -import _ from 'lodash'; -import fp from 'lodash/fp'; +import _sortBy from 'lodash/sortBy'; +import _groupBy from 'lodash/groupBy'; +import _pick from 'lodash/pick'; +import fp_pick from 'lodash/fp/pick'; export class DatabaseAnalyser { structure: DatabaseInfo; @@ -54,7 +56,7 @@ export class DatabaseAnalyser { const newArray = newlyAnalysed[field] || []; const addedChangedIds = newArray.map((x) => extractObjectId(x)); const removeAllIds = [...removedIds, ...addedChangedIds]; - res[field] = _.sortBy( + res[field] = _sortBy( [...this.structure[field].filter((x) => !removeAllIds.includes(extractObjectId(x))), ...newArray], (x) => x.pureName ); @@ -92,17 +94,17 @@ export class DatabaseAnalyser { const filtered = pkColumns.filter(DatabaseAnalyser.byTableFilter(table)); if (filtered.length == 0) return undefined; return { - ..._.pick(filtered[0], ['constraintName', 'schemaName', 'pureName']), + ..._pick(filtered[0], ['constraintName', 'schemaName', 'pureName']), constraintType: 'primaryKey', - columns: filtered.map(fp.pick('columnName')), + columns: filtered.map(fp_pick('columnName')), }; } static extractForeignKeys(table, fkColumns) { - const grouped = _.groupBy(fkColumns.filter(DatabaseAnalyser.byTableFilter(table)), 'constraintName'); - return _.keys(grouped).map((constraintName) => ({ + const grouped = _groupBy(fkColumns.filter(DatabaseAnalyser.byTableFilter(table)), 'constraintName'); + return Object.keys(grouped).map((constraintName) => ({ constraintName, constraintType: 'foreignKey', - ..._.pick(grouped[constraintName][0], [ + ..._pick(grouped[constraintName][0], [ 'constraintName', 'schemaName', 'pureName', @@ -111,7 +113,7 @@ export class DatabaseAnalyser { 'updateAction', 'deleteAction', ]), - columns: grouped[constraintName].map(fp.pick(['columnName', 'refColumnName'])), + columns: grouped[constraintName].map(fp_pick(['columnName', 'refColumnName'])), })); } } diff --git a/packages/tools/src/SqlDumper.ts b/packages/tools/src/SqlDumper.ts index 2e9c51ba5..310460ab5 100644 --- a/packages/tools/src/SqlDumper.ts +++ b/packages/tools/src/SqlDumper.ts @@ -7,8 +7,9 @@ import { TableInfo, TransformType, } from 'dbgate-types'; -import _ from 'lodash'; -import moment from 'moment'; +import _isString from 'lodash/isString' +import _isNumber from 'lodash/isNumber' +import _isDate from 'lodash/isDate' export class SqlDumper { s = ''; @@ -47,9 +48,9 @@ export class SqlDumper { if (value === null) this.putRaw('NULL'); if (value === true) this.putRaw('1'); if (value === false) this.putRaw('0'); - else if (_.isString(value)) this.putStringValue(value); - else if (_.isNumber(value)) this.putRaw(value.toString()); - else if (_.isDate(value)) this.putStringValue(moment(value).toISOString()); + else if (_isString(value)) this.putStringValue(value); + else if (_isNumber(value)) this.putRaw(value.toString()); + else if (_isDate(value)) this.putStringValue(new Date(value).toISOString()); } putCmd(format, ...args) { this.put(format, ...args); diff --git a/packages/tools/src/createBulkInsertStreamBase.ts b/packages/tools/src/createBulkInsertStreamBase.ts index 1d02c9eb6..f8bb53a9d 100644 --- a/packages/tools/src/createBulkInsertStreamBase.ts +++ b/packages/tools/src/createBulkInsertStreamBase.ts @@ -1,5 +1,5 @@ import { EngineDriver } from 'dbgate-types'; -import _ from 'lodash'; +import _intersection from 'lodash/intersection'; import { prepareTableForImport } from './tableTransforms'; export function createBulkInsertStreamBase(driver, stream, pool, name, options): any { @@ -43,7 +43,7 @@ export function createBulkInsertStreamBase(driver, stream, pool, name, options): await driver.query(pool, `TRUNCATE TABLE ${fullNameQuoted}`); } - this.columnNames = _.intersection( + this.columnNames = _intersection( structure.columns.map((x) => x.columnName), writable.structure.columns.map((x) => x.columnName) ); diff --git a/packages/tools/src/driverBase.ts b/packages/tools/src/driverBase.ts index 6adf8bdec..531b37d7b 100644 --- a/packages/tools/src/driverBase.ts +++ b/packages/tools/src/driverBase.ts @@ -1,5 +1,3 @@ -import { createBulkInsertStreamBase } from './createBulkInsertStreamBase'; - export const driverBase = { analyserClass: null, dumperClass: null, diff --git a/packages/tools/src/packageTools.ts b/packages/tools/src/packageTools.ts index 1ce04f702..0aa87b4c1 100644 --- a/packages/tools/src/packageTools.ts +++ b/packages/tools/src/packageTools.ts @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import _camelCase from 'lodash/camelCase'; export function extractShellApiPlugins(functionName, props): string[] { const res = []; @@ -18,7 +18,7 @@ export function extractShellApiPlugins(functionName, props): string[] { export function extractShellApiFunctionName(functionName) { const nsMatch = functionName.match(/^([^@]+)@([^@]+)/); if (nsMatch) { - return `${_.camelCase(nsMatch[2])}.shellApi.${nsMatch[1]}`; + return `${_camelCase(nsMatch[2])}.shellApi.${nsMatch[1]}`; } return `dbgateApi.${functionName}`; } diff --git a/packages/tools/src/tableTransforms.ts b/packages/tools/src/tableTransforms.ts index 5e3ea9ef2..994161b7a 100644 --- a/packages/tools/src/tableTransforms.ts +++ b/packages/tools/src/tableTransforms.ts @@ -1,8 +1,8 @@ import { TableInfo } from 'dbgate-types'; -import _ from 'lodash'; +import _cloneDeep from 'lodash/cloneDeep'; export function prepareTableForImport(table: TableInfo): TableInfo { - const res = _.cloneDeep(table); + const res = _cloneDeep(table); res.foreignKeys = []; if (res.primaryKey) res.primaryKey.constraintName = null; return res; From fb3af22302db080b57630d520be47737ad441da9 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Tue, 24 Nov 2020 19:17:27 +0100 Subject: [PATCH 20/30] reduced package size --- packages/tools/package.json | 2 +- packages/tools/src/DatabaseAnalyser.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/tools/package.json b/packages/tools/package.json index 352058ccc..e8b487c04 100644 --- a/packages/tools/package.json +++ b/packages/tools/package.json @@ -1,5 +1,5 @@ { - "version": "1.0.3", + "version": "1.0.4", "name": "dbgate-tools", "main": "lib/index.js", "typings": "lib/index.d.ts", diff --git a/packages/tools/src/DatabaseAnalyser.ts b/packages/tools/src/DatabaseAnalyser.ts index d39460a0e..d876f8485 100644 --- a/packages/tools/src/DatabaseAnalyser.ts +++ b/packages/tools/src/DatabaseAnalyser.ts @@ -2,8 +2,8 @@ import { DatabaseInfo, DatabaseModification, EngineDriver } from 'dbgate-types'; import _sortBy from 'lodash/sortBy'; import _groupBy from 'lodash/groupBy'; import _pick from 'lodash/pick'; -import fp_pick from 'lodash/fp/pick'; +const fp_pick = (arg) => (array) => _pick(array, arg); export class DatabaseAnalyser { structure: DatabaseInfo; modifications: DatabaseModification[]; From 644a35d8c382ef3424f16a60abb6cb66fe0479b1 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Tue, 24 Nov 2020 19:43:28 +0100 Subject: [PATCH 21/30] remove refs --- packages/web/src/tabs/QueryTab.js | 1 - packages/web/src/tabs/ShellTab.js | 15 ++------------- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/packages/web/src/tabs/QueryTab.js b/packages/web/src/tabs/QueryTab.js index cd8ddb212..2f507071d 100644 --- a/packages/web/src/tabs/QueryTab.js +++ b/packages/web/src/tabs/QueryTab.js @@ -6,7 +6,6 @@ import engines from 'dbgate-engines'; import { useConnectionInfo, - getTableInfo, getDbCore, getConnectionInfo, getSqlObjectInfo, diff --git a/packages/web/src/tabs/ShellTab.js b/packages/web/src/tabs/ShellTab.js index 2197a8ef5..2a6c5150a 100644 --- a/packages/web/src/tabs/ShellTab.js +++ b/packages/web/src/tabs/ShellTab.js @@ -2,22 +2,11 @@ import React from 'react'; import ReactDOM from 'react-dom'; import _ from 'lodash'; import axios from '../utility/axios'; -import engines from 'dbgate-engines'; - -import { useConnectionInfo, getTableInfo, getConnectionInfo, getSqlObjectInfo } from '../utility/metadataLoaders'; -import SqlEditor from '../sqleditor/SqlEditor'; -import { useUpdateDatabaseForTab, useSetOpenedTabs, useOpenedTabs } from '../utility/globalState'; -import QueryToolbar from '../query/QueryToolbar'; -import SocketMessagesView from '../query/SocketMessagesView'; -import { TabPage } from '../widgets/TabControl'; -import ResultTabs from '../sqleditor/ResultTabs'; -import { VerticalSplitter, HorizontalSplitter } from '../widgets/Splitter'; +import { useSetOpenedTabs } from '../utility/globalState'; +import { VerticalSplitter } from '../widgets/Splitter'; import keycodes from '../utility/keycodes'; import { changeTab } from '../utility/common'; import useSocket from '../utility/SocketProvider'; -import SaveSqlFileModal from '../modals/SaveSqlFileModal'; -import useModalState from '../modals/useModalState'; -import sqlFormatter from 'sql-formatter'; import JavaScriptEditor from '../sqleditor/JavaScriptEditor'; import ShellToolbar from '../query/ShellToolbar'; import RunnerOutputPane from '../query/RunnerOutputPane'; From 424aff5d93feb760c326f9817ca4aa8f0627428b Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Tue, 24 Nov 2020 20:15:07 +0100 Subject: [PATCH 22/30] frontend - removed references to dbgate-engines --- packages/tools/src/driverBase.ts | 16 +++++++++++++++- packages/tools/src/packageTools.ts | 16 ++++++++++++++++ packages/types/engines.d.ts | 1 + packages/types/extensions.d.ts | 3 +++ packages/web/src/datagrid/TableDataGrid.js | 6 ++++-- packages/web/src/impexp/createImpExpScript.js | 10 ++++++---- packages/web/src/modals/ConnectionModal.js | 12 ++++++++++-- packages/web/src/tabs/QueryTab.js | 15 ++++++--------- packages/web/src/tabs/ViewDataTab.js | 6 ++++-- packages/web/src/utility/useExtensions.js | 10 ++++++++++ 10 files changed, 75 insertions(+), 20 deletions(-) diff --git a/packages/tools/src/driverBase.ts b/packages/tools/src/driverBase.ts index 531b37d7b..9705b381b 100644 --- a/packages/tools/src/driverBase.ts +++ b/packages/tools/src/driverBase.ts @@ -1,6 +1,20 @@ +import { SqlDumper } from "./SqlDumper"; + +const dialect = { + limitSelect: true, + rangeSelect: true, + offsetFetchRangeSyntax: true, + stringEscapeChar: "'", + fallbackDataType: 'nvarchar(max)', + quoteIdentifier(s) { + return s; + }, +}; + export const driverBase = { analyserClass: null, - dumperClass: null, + dumperClass: SqlDumper, + dialect, async analyseFull(pool) { const analyser = new this.analyserClass(pool, this); diff --git a/packages/tools/src/packageTools.ts b/packages/tools/src/packageTools.ts index 0aa87b4c1..6fd1d5639 100644 --- a/packages/tools/src/packageTools.ts +++ b/packages/tools/src/packageTools.ts @@ -1,4 +1,7 @@ +import { EngineDriver, ExtensionsDirectory } from 'dbgate-types'; import _camelCase from 'lodash/camelCase'; +import _isString from 'lodash/isString'; +import _isPlainObject from 'lodash/isPlainObject'; export function extractShellApiPlugins(functionName, props): string[] { const res = []; @@ -22,3 +25,16 @@ export function extractShellApiFunctionName(functionName) { } return `dbgateApi.${functionName}`; } + +export function findEngineDriver(connection, extensions: ExtensionsDirectory): EngineDriver { + if (_isString(connection)) { + return extensions.drivers.find((x) => x.engine == connection); + } + if (_isPlainObject(connection)) { + const { engine } = connection; + if (engine) { + return extensions.drivers.find((x) => x.engine == engine); + } + } + return null; +} diff --git a/packages/types/engines.d.ts b/packages/types/engines.d.ts index 9dc88dec3..07bdfd4b4 100644 --- a/packages/types/engines.d.ts +++ b/packages/types/engines.d.ts @@ -20,6 +20,7 @@ export interface WriteTableOptions { export interface EngineDriver { engine: string; + title: string; connect(nativeModules, { server, port, user, password, database }): any; query(pool: any, sql: string): Promise; stream(pool: any, sql: string, options: StreamOptions); diff --git a/packages/types/extensions.d.ts b/packages/types/extensions.d.ts index 5bd430ddb..94476a4c4 100644 --- a/packages/types/extensions.d.ts +++ b/packages/types/extensions.d.ts @@ -1,3 +1,5 @@ +import { EngineDriver } from "./engines"; + export interface FileFormatDefinition { storageType: string; extension: string; @@ -27,4 +29,5 @@ export interface PluginDefinition { export interface ExtensionsDirectory { plugins: PluginDefinition[]; fileFormats: FileFormatDefinition[]; + drivers: EngineDriver[]; } diff --git a/packages/web/src/datagrid/TableDataGrid.js b/packages/web/src/datagrid/TableDataGrid.js index 039ee89f2..4239e7da1 100644 --- a/packages/web/src/datagrid/TableDataGrid.js +++ b/packages/web/src/datagrid/TableDataGrid.js @@ -4,13 +4,14 @@ import DataGrid from './DataGrid'; import styled from 'styled-components'; import { TableGridDisplay, createGridConfig, createGridCache } from 'dbgate-datalib'; import { getFilterValueExpression } from 'dbgate-filterparser'; +import { findEngineDriver } from 'dbgate-tools'; import { useConnectionInfo, getTableInfo, useDatabaseInfo } from '../utility/metadataLoaders'; -import engines from 'dbgate-engines'; import useSocket from '../utility/SocketProvider'; import { VerticalSplitter } from '../widgets/Splitter'; import stableStringify from 'json-stable-stringify'; import ReferenceHeader from './ReferenceHeader'; import SqlDataGridCore from './SqlDataGridCore'; +import useExtensions from '../utility/useExtensions'; const ReferenceContainer = styled.div` position: absolute; @@ -49,6 +50,7 @@ export default function TableDataGrid({ const [childCache, setChildCache] = React.useState(createGridCache()); const [refReloadToken, setRefReloadToken] = React.useState(0); const [myLoadedTime, setMyLoadedTime] = React.useState(0); + const extension = useExtensions(); const { childConfig } = config; const setChildConfig = (value, reference = undefined) => { @@ -75,7 +77,7 @@ export default function TableDataGrid({ return connection ? new TableGridDisplay( { schemaName, pureName }, - engines(connection), + findEngineDriver(connection, extension), config, setConfig, cache || myCache, diff --git a/packages/web/src/impexp/createImpExpScript.js b/packages/web/src/impexp/createImpExpScript.js index e9752c221..1df26395e 100644 --- a/packages/web/src/impexp/createImpExpScript.js +++ b/packages/web/src/impexp/createImpExpScript.js @@ -2,8 +2,7 @@ import _ from 'lodash'; import ScriptWriter from './ScriptWriter'; import getAsArray from '../utility/getAsArray'; import { getConnectionInfo } from '../utility/metadataLoaders'; -import engines from 'dbgate-engines'; -import { findObjectLike } from 'dbgate-tools'; +import { findEngineDriver, findObjectLike } from 'dbgate-tools'; import { findFileFormat } from '../utility/fileformats'; export function getTargetName(extensions, source, values) { @@ -26,10 +25,10 @@ function extractApiParameters(values, direction, format) { return _.fromPairs(pairs); } -async function getConnection(storageType, conid, database) { +async function getConnection(extensions, storageType, conid, database) { if (storageType == 'database' || storageType == 'query') { const conn = await getConnectionInfo({ conid }); - const driver = engines(conn); + const driver = findEngineDriver(conn, extensions); return [ { ..._.pick(conn, ['server', 'engine', 'user', 'password', 'port']), @@ -154,11 +153,13 @@ export default async function createImpExpScript(extensions, values, addEditorIn const script = new ScriptWriter(); const [sourceConnection, sourceDriver] = await getConnection( + extensions, values.sourceStorageType, values.sourceConnectionId, values.sourceDatabaseName ); const [targetConnection, targetDriver] = await getConnection( + extensions, values.targetStorageType, values.targetConnectionId, values.targetDatabaseName @@ -223,6 +224,7 @@ export function getActionOptions(extensions, source, values, targetDbinfo) { export async function createPreviewReader(extensions, values, sourceName) { const [sourceConnection, sourceDriver] = await getConnection( + extensions, values.sourceStorageType, values.sourceConnectionId, values.sourceDatabaseName diff --git a/packages/web/src/modals/ConnectionModal.js b/packages/web/src/modals/ConnectionModal.js index 4a2558258..f965637d1 100644 --- a/packages/web/src/modals/ConnectionModal.js +++ b/packages/web/src/modals/ConnectionModal.js @@ -7,10 +7,12 @@ import { Formik, Form } from 'formik'; import ModalHeader from './ModalHeader'; import ModalFooter from './ModalFooter'; import ModalContent from './ModalContent'; +import useExtensions from '../utility/useExtensions'; // import FormikForm from '../utility/FormikForm'; export default function ConnectionModal({ modalState, connection = undefined }) { const [sqlConnectResult, setSqlConnectResult] = React.useState('Not connected'); + const extensions = useExtensions(); const handleTest = async (values) => { const resp = await axios.post('connections/test', values); @@ -31,9 +33,15 @@ export default function ConnectionModal({ modalState, connection = undefined })
- + + {extensions.drivers.map((driver) => ( + + ))} + {/* - + */} diff --git a/packages/web/src/tabs/QueryTab.js b/packages/web/src/tabs/QueryTab.js index 2f507071d..c51eca95b 100644 --- a/packages/web/src/tabs/QueryTab.js +++ b/packages/web/src/tabs/QueryTab.js @@ -2,14 +2,8 @@ import React from 'react'; import ReactDOM from 'react-dom'; import _ from 'lodash'; import axios from '../utility/axios'; -import engines from 'dbgate-engines'; -import { - useConnectionInfo, - getDbCore, - getConnectionInfo, - getSqlObjectInfo, -} from '../utility/metadataLoaders'; +import { useConnectionInfo, getDbCore, getConnectionInfo, getSqlObjectInfo } from '../utility/metadataLoaders'; import SqlEditor from '../sqleditor/SqlEditor'; import { useUpdateDatabaseForTab, useSetOpenedTabs, useOpenedTabs } from '../utility/globalState'; import QueryToolbar from '../query/QueryToolbar'; @@ -23,15 +17,18 @@ import useSocket from '../utility/SocketProvider'; import SaveSqlFileModal from '../modals/SaveSqlFileModal'; import useModalState from '../modals/useModalState'; import sqlFormatter from 'sql-formatter'; +import useExtensions from '../utility/useExtensions'; +import { driverBase, findEngineDriver } from 'dbgate-tools'; function useSqlTemplate(sqlTemplate, props) { const [sql, setSql] = React.useState(''); + const extensions = useExtensions(); async function loadTemplate() { if (sqlTemplate == 'CREATE TABLE') { const tableInfo = await getDbCore(props, props.objectTypeField || 'tables'); const connection = await getConnectionInfo(props); - const driver = engines(connection.engine); + const driver = findEngineDriver(connection, extensions) || driverBase; const dmp = driver.createDumper(); if (tableInfo) dmp.createTable(tableInfo); setSql(dmp.s); @@ -47,7 +44,7 @@ function useSqlTemplate(sqlTemplate, props) { const procedureInfo = await getSqlObjectInfo(props); const connection = await getConnectionInfo(props); - const driver = engines(connection.engine); + const driver = findEngineDriver(connection, extensions) || driverBase; const dmp = driver.createDumper(); if (procedureInfo) dmp.put('^execute %f', procedureInfo); setSql(dmp.s); diff --git a/packages/web/src/tabs/ViewDataTab.js b/packages/web/src/tabs/ViewDataTab.js index 65f751c4e..c3787fed3 100644 --- a/packages/web/src/tabs/ViewDataTab.js +++ b/packages/web/src/tabs/ViewDataTab.js @@ -2,18 +2,20 @@ import React from 'react'; import DataGrid from '../datagrid/DataGrid'; import { ViewGridDisplay, createGridCache, createChangeSet } from 'dbgate-datalib'; import { useConnectionInfo, useViewInfo } from '../utility/metadataLoaders'; -import engines from 'dbgate-engines'; import useUndoReducer from '../utility/useUndoReducer'; import usePropsCompare from '../utility/usePropsCompare'; import { useUpdateDatabaseForTab } from '../utility/globalState'; import useGridConfig from '../utility/useGridConfig'; import SqlDataGridCore from '../datagrid/SqlDataGridCore'; +import useExtensions from '../utility/useExtensions'; +import { findEngineDriver } from 'dbgate-tools'; export default function ViewDataTab({ conid, database, schemaName, pureName, tabVisible, toolbarPortalRef, tabid }) { const viewInfo = useViewInfo({ conid, database, schemaName, pureName }); const [config, setConfig] = useGridConfig(tabid); const [cache, setCache] = React.useState(createGridCache()); const [changeSetState, dispatchChangeSet] = useUndoReducer(createChangeSet()); + const extensions = useExtensions() useUpdateDatabaseForTab(tabVisible, conid, database); const connection = useConnectionInfo({ conid }); @@ -25,7 +27,7 @@ export default function ViewDataTab({ conid, database, schemaName, pureName, tab viewInfo && connection ? new ViewGridDisplay( viewInfo, - engines(connection), + findEngineDriver(connection, extensions), //@ts-ignore config, setConfig, diff --git a/packages/web/src/utility/useExtensions.js b/packages/web/src/utility/useExtensions.js index 71a92b6ce..b428f8241 100644 --- a/packages/web/src/utility/useExtensions.js +++ b/packages/web/src/utility/useExtensions.js @@ -10,11 +10,21 @@ export function ExtensionsProvider({ children }) { return {children}; } +function buildDrivers(plugins) { + const res = []; + for (const { content } of plugins) { + if (content.driver) res.push(content.driver); + if (content.drivers) res.push(...content.drivers); + } + return res; +} + export function buildExtensions(plugins) { /** @type {import('dbgate-types').ExtensionsDirectory} */ const extensions = { plugins, fileFormats: buildFileFormats(plugins), + drivers: buildDrivers(plugins), }; return extensions; } From c96cb08cfddf584449c6c0e45451bc523ecfe71e Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Tue, 24 Nov 2020 20:42:02 +0100 Subject: [PATCH 23/30] backend - using engine driver from plugin --- packages/api/src/proc/connectProcess.js | 7 +++--- .../api/src/proc/databaseConnectionProcess.js | 13 +++++----- .../api/src/proc/serverConnectionProcess.js | 13 +++++----- packages/api/src/proc/sessionProcess.js | 9 ++++--- packages/api/src/shell/queryReader.js | 8 +++---- packages/api/src/shell/tableReader.js | 10 ++++---- packages/api/src/shell/tableWriter.js | 8 +++---- .../api/src/utility/requireEngineDriver.js | 24 +++++++++++++++++++ packages/types/engines.d.ts | 8 +++---- 9 files changed, 58 insertions(+), 42 deletions(-) create mode 100644 packages/api/src/utility/requireEngineDriver.js diff --git a/packages/api/src/proc/connectProcess.js b/packages/api/src/proc/connectProcess.js index 9ba051492..a4c916b2a 100644 --- a/packages/api/src/proc/connectProcess.js +++ b/packages/api/src/proc/connectProcess.js @@ -1,13 +1,12 @@ -const engines = require('dbgate-engines'); -const driverConnect = require('../utility/driverConnect'); const childProcessChecker = require('../utility/childProcessChecker'); +const requireEngineDriver = require('../utility/requireEngineDriver'); function start() { childProcessChecker(); process.on('message', async (connection) => { try { - const driver = engines(connection); - const conn = await driverConnect(driver, connection); + const driver = requireEngineDriver(connection); + const conn = await driver.connect(connection); const res = await driver.getVersion(conn); process.send({ msgtype: 'connected', ...res }); } catch (e) { diff --git a/packages/api/src/proc/databaseConnectionProcess.js b/packages/api/src/proc/databaseConnectionProcess.js index 08665fcf9..6611fcdcf 100644 --- a/packages/api/src/proc/databaseConnectionProcess.js +++ b/packages/api/src/proc/databaseConnectionProcess.js @@ -1,7 +1,6 @@ -const engines = require('dbgate-engines'); const stableStringify = require('json-stable-stringify'); -const driverConnect = require('../utility/driverConnect'); const childProcessChecker = require('../utility/childProcessChecker'); +const requireEngineDriver = require('../utility/requireEngineDriver'); let systemConnection; let storedConnection; @@ -26,14 +25,14 @@ async function checkedAsyncCall(promise) { } async function handleFullRefresh() { - const driver = engines(storedConnection); + const driver = requireEngineDriver(storedConnection); analysedStructure = await checkedAsyncCall(driver.analyseFull(systemConnection)); process.send({ msgtype: 'structure', structure: analysedStructure }); setStatusName('ok'); } async function handleIncrementalRefresh() { - const driver = engines(storedConnection); + const driver = requireEngineDriver(storedConnection); const newStructure = await checkedAsyncCall(driver.analyseIncremental(systemConnection, analysedStructure)); if (newStructure != null) { analysedStructure = newStructure; @@ -58,8 +57,8 @@ async function handleConnect({ connection, structure }) { lastPing = new Date().getTime(); if (!structure) setStatusName('pending'); - const driver = engines(storedConnection); - systemConnection = await checkedAsyncCall(driverConnect(driver, storedConnection)); + const driver = requireEngineDriver(storedConnection); + systemConnection = await checkedAsyncCall(driver.connect(storedConnection)); if (structure) { analysedStructure = structure; handleIncrementalRefresh(); @@ -82,7 +81,7 @@ function waitConnected() { async function handleQueryData({ msgid, sql }) { await waitConnected(); - const driver = engines(storedConnection); + const driver = requireEngineDriver(storedConnection); try { const res = await driver.query(systemConnection, sql); process.send({ msgtype: 'response', msgid, ...res }); diff --git a/packages/api/src/proc/serverConnectionProcess.js b/packages/api/src/proc/serverConnectionProcess.js index 0d08b95ca..225f8cdd1 100644 --- a/packages/api/src/proc/serverConnectionProcess.js +++ b/packages/api/src/proc/serverConnectionProcess.js @@ -1,7 +1,6 @@ -const engines = require('dbgate-engines'); const stableStringify = require('json-stable-stringify'); -const driverConnect = require('../utility/driverConnect'); const childProcessChecker = require('../utility/childProcessChecker'); +const requireEngineDriver = require('../utility/requireEngineDriver'); let systemConnection; let storedConnection; @@ -10,7 +9,7 @@ let lastStatus = null; let lastPing = null; async function handleRefresh() { - const driver = engines(storedConnection); + const driver = requireEngineDriver(storedConnection); try { const databases = await driver.listDatabases(systemConnection); setStatusName('ok'); @@ -46,9 +45,9 @@ async function handleConnect(connection) { setStatusName('pending'); lastPing = new Date().getTime(); - const driver = engines(storedConnection); + const driver = requireEngineDriver(storedConnection); try { - systemConnection = await driverConnect(driver, storedConnection); + systemConnection = await driver.connect(storedConnection); handleRefresh(); setInterval(handleRefresh, 30 * 1000); } catch (err) { @@ -66,8 +65,8 @@ function handlePing() { } async function handleCreateDatabase({ name }) { - const driver = engines(storedConnection); - systemConnection = await driverConnect(driver, storedConnection); + const driver = requireEngineDriver(storedConnection); + systemConnection = await driver.connect(storedConnection); console.log(`RUNNING SCRIPT: CREATE DATABASE ${driver.dialect.quoteIdentifier(name)}`); await driver.query(systemConnection, `CREATE DATABASE ${driver.dialect.quoteIdentifier(name)}`); await handleRefresh(); diff --git a/packages/api/src/proc/sessionProcess.js b/packages/api/src/proc/sessionProcess.js index a24bf42c7..eae01137e 100644 --- a/packages/api/src/proc/sessionProcess.js +++ b/packages/api/src/proc/sessionProcess.js @@ -1,4 +1,3 @@ -const engines = require('dbgate-engines'); const uuidv1 = require('uuid/v1'); const path = require('path'); const fs = require('fs'); @@ -6,8 +5,8 @@ const _ = require('lodash'); const childProcessChecker = require('../utility/childProcessChecker'); const goSplit = require('../utility/goSplit'); -const driverConnect = require('../utility/driverConnect'); const { jsldir } = require('../utility/directories'); +const requireEngineDriver = require('../utility/requireEngineDriver'); let systemConnection; let storedConnection; @@ -119,8 +118,8 @@ class StreamHandler { async function handleConnect(connection) { storedConnection = connection; - const driver = engines(storedConnection); - systemConnection = await driverConnect(driver, storedConnection); + const driver = requireEngineDriver(storedConnection); + systemConnection = await driver.connect(storedConnection); for (const [resolve] of afterConnectCallbacks) { resolve(); } @@ -142,7 +141,7 @@ function waitConnected() { async function handleExecuteQuery({ sql }) { await waitConnected(); - const driver = engines(storedConnection); + const driver = requireEngineDriver(storedConnection); let resultIndex = 0; for (const sqlItem of goSplit(sql)) { diff --git a/packages/api/src/shell/queryReader.js b/packages/api/src/shell/queryReader.js index 12ae13bec..13b2e4159 100644 --- a/packages/api/src/shell/queryReader.js +++ b/packages/api/src/shell/queryReader.js @@ -1,12 +1,10 @@ -const driverConnect = require('../utility/driverConnect'); - -const engines = require('dbgate-engines'); +const requireEngineDriver = require("../utility/requireEngineDriver"); async function queryReader({ connection, sql }) { console.log(`Reading query ${sql}`); - const driver = engines(connection); - const pool = await driverConnect(driver, connection); + const driver = requireEngineDriver(connection); + const pool = await driver.connect(connection); console.log(`Connected.`); return await driver.readQuery(pool, sql); } diff --git a/packages/api/src/shell/tableReader.js b/packages/api/src/shell/tableReader.js index 172fabb0f..54a09b512 100644 --- a/packages/api/src/shell/tableReader.js +++ b/packages/api/src/shell/tableReader.js @@ -1,11 +1,9 @@ const { quoteFullName } = require('dbgate-tools'); -const driverConnect = require('../utility/driverConnect'); - -const engines = require('dbgate-engines'); +const requireEngineDriver = require('../utility/requireEngineDriver'); async function tableReader({ connection, pureName, schemaName }) { - const driver = engines(connection); - const pool = await driverConnect(driver, connection); + const driver = requireEngineDriver(connection); + const pool = await driver.connect(connection); console.log(`Connected.`); const fullName = { pureName, schemaName }; @@ -14,11 +12,13 @@ async function tableReader({ connection, pureName, schemaName }) { const query = `select * from ${quoteFullName(driver.dialect, fullName)}`; if (table) { console.log(`Reading table ${table.pureName}`); + // @ts-ignore return await driver.readQuery(pool, query, table); } const view = await driver.analyseSingleObject(pool, fullName, 'views'); if (view) { console.log(`Reading view ${view.pureName}`); + // @ts-ignore return await driver.readQuery(pool, query, view); } diff --git a/packages/api/src/shell/tableWriter.js b/packages/api/src/shell/tableWriter.js index 0d7b16533..f59e3e4c7 100644 --- a/packages/api/src/shell/tableWriter.js +++ b/packages/api/src/shell/tableWriter.js @@ -1,12 +1,10 @@ -const driverConnect = require('../utility/driverConnect'); - -const engines = require('dbgate-engines'); +const requireEngineDriver = require("../utility/requireEngineDriver"); async function tableWriter({ connection, schemaName, pureName, ...options }) { console.log(`Write table ${schemaName}.${pureName}`); - const driver = engines(connection); - const pool = await driverConnect(driver, connection); + const driver = requireEngineDriver(connection); + const pool = await driver.connect(connection); console.log(`Connected.`); return await driver.writeTable(pool, { schemaName, pureName }, options); } diff --git a/packages/api/src/utility/requireEngineDriver.js b/packages/api/src/utility/requireEngineDriver.js new file mode 100644 index 000000000..d263111a9 --- /dev/null +++ b/packages/api/src/utility/requireEngineDriver.js @@ -0,0 +1,24 @@ +const _ = require('lodash'); +const requirePlugin = require('../shell/requirePlugin'); + + +/** @returns {import('dbgate-types').EngineDriver} */ +function requireEngineDriver(connection) { + let engine = null; + if (_.isString(connection)) { + engine = connection; + } else if (_.isPlainObject(connection)) { + engine = connection.engine; + } + if (!engine) { + throw new Error('Could not get driver from connection'); + } + if (engine.includes('@')) { + const [shortName, packageName] = engine.split('@'); + const plugin = requirePlugin(packageName); + return plugin.driver; + } + throw new Error(`Could not found engine driver ${engine}`); +} + +module.exports = requireEngineDriver; diff --git a/packages/types/engines.d.ts b/packages/types/engines.d.ts index 07bdfd4b4..59b2328dc 100644 --- a/packages/types/engines.d.ts +++ b/packages/types/engines.d.ts @@ -7,9 +7,9 @@ import { DatabaseInfo, NamedObjectInfo, TableInfo, ViewInfo, ProcedureInfo, Func export interface StreamOptions { recordset: (columns) => void; row: (row) => void; - error: (error) => void; - done: (result) => void; - info: (info) => void; + error?: (error) => void; + done?: (result) => void; + info?: (info) => void; } export interface WriteTableOptions { @@ -21,7 +21,7 @@ export interface WriteTableOptions { export interface EngineDriver { engine: string; title: string; - connect(nativeModules, { server, port, user, password, database }): any; + connect({ server, port, user, password, database }): any; query(pool: any, sql: string): Promise; stream(pool: any, sql: string, options: StreamOptions); readQuery(pool: any, sql: string, structure?: TableInfo): Promise; From 06e98cff9f71a13fcbcac674b87e2326ae2b6081 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 26 Nov 2020 14:23:31 +0100 Subject: [PATCH 24/30] fixes --- packages/api/package.json | 4 ---- packages/api/src/controllers/plugins.js | 2 +- packages/api/src/shell/jsonLinesReader.js | 1 + packages/api/src/shell/requirePlugin.js | 2 +- packages/datalib/src/GridDisplay.ts | 1 + packages/web/src/datagrid/TableDataGrid.js | 6 +++--- 6 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/api/package.json b/packages/api/package.json index 0a94f7002..2f326cc53 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -12,10 +12,6 @@ "license": "GPL", "keywords": [ "sql", - "mssql", - "mssql", - "postgresql", - "excel", "json", "import", "export", diff --git a/packages/api/src/controllers/plugins.js b/packages/api/src/controllers/plugins.js index e382c0f1d..5b4d95bb0 100644 --- a/packages/api/src/controllers/plugins.js +++ b/packages/api/src/controllers/plugins.js @@ -27,7 +27,7 @@ async function loadPackageInfo(dir) { module.exports = { script_meta: 'get', async script({ packageName }) { - const file = path.join(pluginsdir(), packageName, 'lib', 'frontend.js'); + const file = path.join(pluginsdir(), packageName, 'dist', 'frontend.js'); const data = await fs.readFile(file, { encoding: 'utf-8', }); diff --git a/packages/api/src/shell/jsonLinesReader.js b/packages/api/src/shell/jsonLinesReader.js index e36db95fc..0a7018bd1 100644 --- a/packages/api/src/shell/jsonLinesReader.js +++ b/packages/api/src/shell/jsonLinesReader.js @@ -18,6 +18,7 @@ class ParseStream extends stream.Transform { } if (!this.limitRows || this.rowsWritten < this.limitRows) { this.push(obj); + this.rowsWritten += 1; } done(); } diff --git a/packages/api/src/shell/requirePlugin.js b/packages/api/src/shell/requirePlugin.js index 386d3a3ee..910c42ca1 100644 --- a/packages/api/src/shell/requirePlugin.js +++ b/packages/api/src/shell/requirePlugin.js @@ -13,7 +13,7 @@ function requirePlugin(packageName, requiredPlugin = null) { if (requiredPlugin == null) { console.log('Loading module', packageName); - const module = require(path.join(pluginsdir(), packageName, 'lib', 'backend.js')); + const module = require(path.join(pluginsdir(), packageName, 'dist', 'backend.js')); requiredPlugin = module.__esModule ? module.default : module; } loadedPlugins[packageName] = requiredPlugin; diff --git a/packages/datalib/src/GridDisplay.ts b/packages/datalib/src/GridDisplay.ts index d3ffc940d..177a0b715 100644 --- a/packages/datalib/src/GridDisplay.ts +++ b/packages/datalib/src/GridDisplay.ts @@ -424,6 +424,7 @@ export abstract class GridDisplay { } getPageQuery(offset: number, count: number) { + if (!this.driver) return null; const select = this.createSelect(); if (!select) return null; if (this.driver.dialect.rangeSelect) select.range = { offset: offset, limit: count }; diff --git a/packages/web/src/datagrid/TableDataGrid.js b/packages/web/src/datagrid/TableDataGrid.js index 4239e7da1..d5bafb689 100644 --- a/packages/web/src/datagrid/TableDataGrid.js +++ b/packages/web/src/datagrid/TableDataGrid.js @@ -50,7 +50,7 @@ export default function TableDataGrid({ const [childCache, setChildCache] = React.useState(createGridCache()); const [refReloadToken, setRefReloadToken] = React.useState(0); const [myLoadedTime, setMyLoadedTime] = React.useState(0); - const extension = useExtensions(); + const extensions = useExtensions(); const { childConfig } = config; const setChildConfig = (value, reference = undefined) => { @@ -77,7 +77,7 @@ export default function TableDataGrid({ return connection ? new TableGridDisplay( { schemaName, pureName }, - findEngineDriver(connection, extension), + findEngineDriver(connection, extensions), config, setConfig, cache || myCache, @@ -99,7 +99,7 @@ export default function TableDataGrid({ if (!newDisplay) return; if (display && display.isLoadedCorrectly && !newDisplay.isLoadedCorrectly) return; setDisplay(newDisplay); - }, [connection, config, cache || myCache, conid, database, schemaName, pureName, dbinfo]); + }, [connection, config, cache || myCache, conid, database, schemaName, pureName, dbinfo, extensions]); const handleDatabaseStructureChanged = React.useCallback(() => { (setCache || setMyCache)(createGridCache()); From d7ceb297e9fd7d42412ab76a9bc2cd35c1d94931 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 26 Nov 2020 14:25:51 +0100 Subject: [PATCH 25/30] removed bindings to engines --- packages/api/package.json | 7 +- packages/api/src/utility/driverConnect.js | 21 -- packages/engines/README.md | 52 ----- packages/engines/index.d.ts | 7 - packages/engines/index.js | 24 -- packages/engines/mssql/MsSqlAnalyser.js | 212 ----------------- packages/engines/mssql/MsSqlDumper.js | 54 ----- .../engines/mssql/createBulkInsertStream.js | 48 ---- packages/engines/mssql/index.js | 210 ----------------- packages/engines/mssql/sql/columns.js | 20 -- packages/engines/mssql/sql/foreignKeys.js | 40 ---- packages/engines/mssql/sql/getSchemas.js | 1 - packages/engines/mssql/sql/index.js | 23 -- packages/engines/mssql/sql/loadSqlCode.js | 8 - packages/engines/mssql/sql/modifications.js | 6 - packages/engines/mssql/sql/primaryKeys.js | 14 -- packages/engines/mssql/sql/programmables.js | 6 - packages/engines/mssql/sql/tables.js | 8 - packages/engines/mssql/sql/viewColumns.js | 18 -- packages/engines/mssql/sql/views.js | 10 - packages/engines/mysql/MySqlAnalyser.js | 214 ------------------ packages/engines/mysql/MySqlDumper.js | 30 --- packages/engines/mysql/index.js | 159 ------------- packages/engines/mysql/sql/columns.js | 15 -- packages/engines/mysql/sql/foreignKeys.js | 17 -- .../mysql/sql/functionModifications.js | 3 - packages/engines/mysql/sql/index.js | 21 -- packages/engines/mysql/sql/primaryKeys.js | 12 - .../mysql/sql/procedureModifications.js | 3 - packages/engines/mysql/sql/programmables.js | 9 - .../engines/mysql/sql/tableModifications.js | 8 - packages/engines/mysql/sql/tables.js | 7 - packages/engines/mysql/sql/views.js | 7 - packages/engines/package.json | 32 --- packages/engines/postgres/PostgreAnalyser.js | 173 -------------- packages/engines/postgres/PostgreDumper.js | 30 --- packages/engines/postgres/index.js | 190 ---------------- packages/engines/postgres/sql/columns.js | 19 -- packages/engines/postgres/sql/foreignKeys.js | 24 -- packages/engines/postgres/sql/index.js | 19 -- packages/engines/postgres/sql/primaryKeys.js | 17 -- .../postgres/sql/routineModifications.js | 10 - packages/engines/postgres/sql/routines.js | 15 -- .../postgres/sql/tableModifications.js | 52 ----- .../engines/postgres/sql/viewModifications.js | 8 - packages/engines/postgres/sql/views.js | 11 - packages/engines/tsconfig.json | 19 -- packages/web/package.json | 1 - 48 files changed, 1 insertion(+), 1913 deletions(-) delete mode 100644 packages/api/src/utility/driverConnect.js delete mode 100644 packages/engines/README.md delete mode 100644 packages/engines/index.d.ts delete mode 100644 packages/engines/index.js delete mode 100644 packages/engines/mssql/MsSqlAnalyser.js delete mode 100644 packages/engines/mssql/MsSqlDumper.js delete mode 100644 packages/engines/mssql/createBulkInsertStream.js delete mode 100644 packages/engines/mssql/index.js delete mode 100644 packages/engines/mssql/sql/columns.js delete mode 100644 packages/engines/mssql/sql/foreignKeys.js delete mode 100644 packages/engines/mssql/sql/getSchemas.js delete mode 100644 packages/engines/mssql/sql/index.js delete mode 100644 packages/engines/mssql/sql/loadSqlCode.js delete mode 100644 packages/engines/mssql/sql/modifications.js delete mode 100644 packages/engines/mssql/sql/primaryKeys.js delete mode 100644 packages/engines/mssql/sql/programmables.js delete mode 100644 packages/engines/mssql/sql/tables.js delete mode 100644 packages/engines/mssql/sql/viewColumns.js delete mode 100644 packages/engines/mssql/sql/views.js delete mode 100644 packages/engines/mysql/MySqlAnalyser.js delete mode 100644 packages/engines/mysql/MySqlDumper.js delete mode 100644 packages/engines/mysql/index.js delete mode 100644 packages/engines/mysql/sql/columns.js delete mode 100644 packages/engines/mysql/sql/foreignKeys.js delete mode 100644 packages/engines/mysql/sql/functionModifications.js delete mode 100644 packages/engines/mysql/sql/index.js delete mode 100644 packages/engines/mysql/sql/primaryKeys.js delete mode 100644 packages/engines/mysql/sql/procedureModifications.js delete mode 100644 packages/engines/mysql/sql/programmables.js delete mode 100644 packages/engines/mysql/sql/tableModifications.js delete mode 100644 packages/engines/mysql/sql/tables.js delete mode 100644 packages/engines/mysql/sql/views.js delete mode 100644 packages/engines/package.json delete mode 100644 packages/engines/postgres/PostgreAnalyser.js delete mode 100644 packages/engines/postgres/PostgreDumper.js delete mode 100644 packages/engines/postgres/index.js delete mode 100644 packages/engines/postgres/sql/columns.js delete mode 100644 packages/engines/postgres/sql/foreignKeys.js delete mode 100644 packages/engines/postgres/sql/index.js delete mode 100644 packages/engines/postgres/sql/primaryKeys.js delete mode 100644 packages/engines/postgres/sql/routineModifications.js delete mode 100644 packages/engines/postgres/sql/routines.js delete mode 100644 packages/engines/postgres/sql/tableModifications.js delete mode 100644 packages/engines/postgres/sql/viewModifications.js delete mode 100644 packages/engines/postgres/sql/views.js delete mode 100644 packages/engines/tsconfig.json diff --git a/packages/api/package.json b/packages/api/package.json index 2f326cc53..a4cfe1712 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -25,7 +25,6 @@ "byline": "^5.0.0", "cors": "^2.8.5", "cross-env": "^6.0.3", - "dbgate-engines": "^1.0.0", "dbgate-sqltree": "^1.0.0", "dbgate-tools": "^1.0.0", "eslint": "^6.8.0", @@ -37,13 +36,9 @@ "http": "^0.0.0", "line-reader": "^0.4.0", "lodash": "^4.17.15", - "mssql": "^6.0.1", - "mysql": "^2.17.1", "nedb-promises": "^4.0.1", "node-fetch": "^2.6.1", - "pacote": "^11.1.13", - "pg": "^7.17.0", - "pg-query-stream": "^3.1.1" + "pacote": "^11.1.13" }, "scripts": { "start": "nodemon src/index.js", diff --git a/packages/api/src/utility/driverConnect.js b/packages/api/src/utility/driverConnect.js deleted file mode 100644 index 2f4f4c9e9..000000000 --- a/packages/api/src/utility/driverConnect.js +++ /dev/null @@ -1,21 +0,0 @@ -const mssql = require('mssql'); -const mysql = require('mysql'); -const pg = require('pg'); -const pgQueryStream = require('pg-query-stream'); -const fs = require('fs'); -const stream = require('stream'); - -const nativeModules = { - mssql, - mysql, - pg, - pgQueryStream, - fs, - stream, -}; - -function driverConnect(driver, connection) { - return driver.connect(nativeModules, connection); -} - -module.exports = driverConnect; diff --git a/packages/engines/README.md b/packages/engines/README.md deleted file mode 100644 index 00fc33089..000000000 --- a/packages/engines/README.md +++ /dev/null @@ -1,52 +0,0 @@ -# dbgate-engines - -JavaScript library implementing MySQL, MS SQL and PostgreSQL operations. Server as abstraction layer for other DbGate packages, which could be database-engine independend. It can be used both on frontent (in browser) and on backend (in nodejs), but connection to real database is allowed only on backend. - -## Installation - - yarn add dbgate-engines - -## Usage -```javascript -const engines = require('dbgate-engines'); -// driver supports operations of EngineDriver listed belowe -const driver = engine('mysql'); -``` - -In most cases, you don't use driver methods directly, but you pass driver instance into other dbgate packages. - -## Driver definition - - -```typescript -export interface EngineDriver { - // works on both frontend and backend - engine: string; - dialect: SqlDialect; - createDumper(): SqlDumper; - - // works only on backend - connect(nativeModules, { server, port, user, password, database }): any; - query(pool: any, sql: string): Promise; - stream(pool: any, sql: string, options: StreamOptions); - readQuery(pool: any, sql: string, structure?: TableInfo): Promise; - writeTable(pool: any, name: NamedObjectInfo, options: WriteTableOptions): Promise; - analyseSingleObject( - pool: any, - name: NamedObjectInfo, - objectTypeField: keyof DatabaseInfo - ): Promise; - analyseSingleTable(pool: any, name: NamedObjectInfo): Promise; - getVersion(pool: any): Promise<{ version: string }>; - listDatabases( - pool: any - ): Promise< - { - name: string; - }[] - >; - analyseFull(pool: any): Promise; - analyseIncremental(pool: any, structure: DatabaseInfo): Promise; -} - -``` \ No newline at end of file diff --git a/packages/engines/index.d.ts b/packages/engines/index.d.ts deleted file mode 100644 index 1ce5b0395..000000000 --- a/packages/engines/index.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -import types from "dbgate-types"; - -declare function getDriver( - connection: string | { engine: string } -): types.EngineDriver; - -export = getDriver; diff --git a/packages/engines/index.js b/packages/engines/index.js deleted file mode 100644 index eb2dd4adc..000000000 --- a/packages/engines/index.js +++ /dev/null @@ -1,24 +0,0 @@ -const _ = require("lodash"); -const mssql = require("./mssql"); -const mysql = require("./mysql"); -const postgres = require("./postgres"); - -const drivers = { - mssql, - mysql, - postgres -}; - -function getDriver(connection) { - if (_.isString(connection)) { - return drivers[connection]; - } - if (_.isPlainObject(connection)) { - const { engine } = connection; - if (engine) { - return drivers[engine]; - } - } - throw new Error(`Cannot extract engine from ${connection}`); -} -module.exports = getDriver; diff --git a/packages/engines/mssql/MsSqlAnalyser.js b/packages/engines/mssql/MsSqlAnalyser.js deleted file mode 100644 index 7804a4c69..000000000 --- a/packages/engines/mssql/MsSqlAnalyser.js +++ /dev/null @@ -1,212 +0,0 @@ -const fp = require('lodash/fp'); -const _ = require('lodash'); -const sql = require('./sql'); - -const { DatabaseAnalyser } = require('dbgate-tools'); -const { filter } = require('lodash'); -const { isTypeString, isTypeNumeric } = require('dbgate-tools'); - -function objectTypeToField(type) { - switch (type.trim()) { - case 'U': - return 'tables'; - case 'V': - return 'views'; - case 'P': - return 'procedures'; - case 'IF': - case 'FN': - case 'TF': - return 'functions'; - case 'TR': - return 'triggers'; - default: - return null; - } -} - -function getColumnInfo({ - isNullable, - isIdentity, - columnName, - dataType, - charMaxLength, - numericPrecision, - numericScale, -}) { - let fullDataType = dataType; - if (charMaxLength && isTypeString(dataType)) fullDataType = `${dataType}(${charMaxLength})`; - if (numericPrecision && numericScale && isTypeNumeric(dataType)) - fullDataType = `${dataType}(${numericPrecision},${numericScale})`; - return { - columnName, - dataType: fullDataType, - notNull: !isNullable, - autoIncrement: !!isIdentity, - }; -} - -class MsSqlAnalyser extends DatabaseAnalyser { - constructor(pool, driver) { - super(pool, driver); - this.singleObjectId = null; - } - - createQuery(resFileName, typeFields) { - let res = sql[resFileName]; - if (this.singleObjectFilter) { - const { typeField } = this.singleObjectFilter; - if (!this.singleObjectId) return null; - if (!typeFields || !typeFields.includes(typeField)) return null; - return res.replace('=[OBJECT_ID_CONDITION]', ` = ${this.singleObjectId}`); - } - if (!this.modifications || !typeFields || this.modifications.length == 0) { - res = res.replace('=[OBJECT_ID_CONDITION]', ' is not null'); - } else { - const filterIds = this.modifications - .filter((x) => typeFields.includes(x.objectTypeField) && (x.action == 'add' || x.action == 'change')) - .map((x) => x.objectId); - if (filterIds.length == 0) { - res = res.replace('=[OBJECT_ID_CONDITION]', ' = 0'); - } else { - res = res.replace('=[OBJECT_ID_CONDITION]', ` in (${filterIds.join(',')})`); - } - } - return res; - } - - async getSingleObjectId() { - if (this.singleObjectFilter) { - const { schemaName, pureName, typeField } = this.singleObjectFilter; - const fullName = schemaName ? `[${schemaName}].[${pureName}]` : pureName; - const resId = await this.driver.query(this.pool, `SELECT OBJECT_ID('${fullName}') AS id`); - this.singleObjectId = resId.rows[0].id; - } - } - - async _runAnalysis() { - await this.getSingleObjectId(); - const tablesRows = await this.driver.query(this.pool, this.createQuery('tables', ['tables'])); - const columnsRows = await this.driver.query(this.pool, this.createQuery('columns', ['tables'])); - const pkColumnsRows = await this.driver.query(this.pool, this.createQuery('primaryKeys', ['tables'])); - const fkColumnsRows = await this.driver.query(this.pool, this.createQuery('foreignKeys', ['tables'])); - const schemaRows = await this.driver.query(this.pool, this.createQuery('getSchemas')); - - const schemas = schemaRows.rows; - - const sqlCodeRows = await this.driver.query( - this.pool, - this.createQuery('loadSqlCode', ['views', 'procedures', 'functions', 'triggers']) - ); - const getCreateSql = (row) => - sqlCodeRows.rows - .filter((x) => x.pureName == row.pureName && x.schemaName == row.schemaName) - .map((x) => x.codeText) - .join(''); - const viewsRows = await this.driver.query(this.pool, this.createQuery('views', ['views'])); - const programmableRows = await this.driver.query( - this.pool, - this.createQuery('programmables', ['procedures', 'functions']) - ); - const viewColumnRows = await this.driver.query(this.pool, this.createQuery('viewColumns', ['views'])); - - const tables = tablesRows.rows.map((row) => ({ - ...row, - columns: columnsRows.rows.filter((col) => col.objectId == row.objectId).map(getColumnInfo), - primaryKey: DatabaseAnalyser.extractPrimaryKeys(row, pkColumnsRows.rows), - foreignKeys: DatabaseAnalyser.extractForeignKeys(row, fkColumnsRows.rows), - })); - - const views = viewsRows.rows.map((row) => ({ - ...row, - createSql: getCreateSql(row), - columns: viewColumnRows.rows.filter((col) => col.objectId == row.objectId).map(getColumnInfo), - })); - - const procedures = programmableRows.rows - .filter((x) => x.sqlObjectType.trim() == 'P') - .map((row) => ({ - ...row, - createSql: getCreateSql(row), - })); - - const functions = programmableRows.rows - .filter((x) => ['FN', 'IF', 'TF'].includes(x.sqlObjectType.trim())) - .map((row) => ({ - ...row, - createSql: getCreateSql(row), - })); - - return this.mergeAnalyseResult( - { - tables, - views, - procedures, - functions, - schemas, - }, - (x) => x.objectId - ); - } - - getDeletedObjectsForField(idArray, objectTypeField) { - return this.structure[objectTypeField] - .filter((x) => !idArray.includes(x.objectId)) - .map((x) => ({ - oldName: _.pick(x, ['schemaName', 'pureName']), - objectId: x.objectId, - action: 'remove', - objectTypeField, - })); - } - - getDeletedObjects(idArray) { - return [ - ...this.getDeletedObjectsForField(idArray, 'tables'), - ...this.getDeletedObjectsForField(idArray, 'views'), - ...this.getDeletedObjectsForField(idArray, 'procedures'), - ...this.getDeletedObjectsForField(idArray, 'functions'), - ...this.getDeletedObjectsForField(idArray, 'triggers'), - ]; - } - - async getModifications() { - const modificationsQueryData = await this.driver.query(this.pool, this.createQuery('modifications')); - // console.log('MOD - SRC', modifications); - // console.log( - // 'MODs', - // this.structure.tables.map((x) => x.modifyDate) - // ); - const modifications = modificationsQueryData.rows.map((x) => { - const { type, objectId, modifyDate, schemaName, pureName } = x; - const field = objectTypeToField(type); - if (!this.structure[field]) return null; - // @ts-ignore - const obj = this.structure[field].find((x) => x.objectId == objectId); - - // object not modified - if (obj && Math.abs(new Date(modifyDate).getTime() - new Date(obj.modifyDate).getTime()) < 1000) return null; - - /** @type {import('dbgate-types').DatabaseModification} */ - const action = obj - ? { - newName: { schemaName, pureName }, - oldName: _.pick(obj, ['schemaName', 'pureName']), - action: 'change', - objectTypeField: field, - objectId, - } - : { - newName: { schemaName, pureName }, - action: 'add', - objectTypeField: field, - objectId, - }; - return action; - }); - - return [..._.compact(modifications), ...this.getDeletedObjects(modificationsQueryData.rows.map((x) => x.objectId))]; - } -} - -module.exports = MsSqlAnalyser; diff --git a/packages/engines/mssql/MsSqlDumper.js b/packages/engines/mssql/MsSqlDumper.js deleted file mode 100644 index 652fc5016..000000000 --- a/packages/engines/mssql/MsSqlDumper.js +++ /dev/null @@ -1,54 +0,0 @@ -const { SqlDumper } = require('dbgate-tools'); - -class MsSqlDumper extends SqlDumper { - autoIncrement() { - this.put(' ^identity'); - } - - putStringValue(value) { - if (/[^\u0000-\u00ff]/.test(value)) { - this.putRaw('N'); - } - super.putStringValue(value); - } - - allowIdentityInsert(table, allow) { - this.putCmd('^set ^identity_insert %f %k;&n', table, allow ? 'on' : 'off'); - } - - /** @param type {import('dbgate-types').TransformType} */ - transform(type, dumpExpr) { - switch (type) { - case 'GROUP:YEAR': - case 'YEAR': - this.put('^datepart(^year, %c)', dumpExpr); - break; - case 'MONTH': - this.put('^datepart(^month, %c)', dumpExpr); - break; - case 'DAY': - this.put('^datepart(^day, %c)', dumpExpr); - break; - case 'GROUP:MONTH': - this.put( - "^convert(^varchar(100), ^datepart(^year, %c)) + '-' + ^convert(^varchar(100), ^datepart(^month, %c))", - dumpExpr, - dumpExpr - ); - break; - case 'GROUP:DAY': - this.put( - "^convert(^varchar(100), ^datepart(^year, %c)) + '-' + ^convert(^varchar(100), ^datepart(^month, %c))+'-' + ^convert(^varchar(100), ^datepart(^day, %c))", - dumpExpr, - dumpExpr, - dumpExpr - ); - break; - default: - dumpExpr(); - break; - } - } -} - -module.exports = MsSqlDumper; diff --git a/packages/engines/mssql/createBulkInsertStream.js b/packages/engines/mssql/createBulkInsertStream.js deleted file mode 100644 index 991783b84..000000000 --- a/packages/engines/mssql/createBulkInsertStream.js +++ /dev/null @@ -1,48 +0,0 @@ -const { createBulkInsertStreamBase } = require('dbgate-tools'); - -/** - * - * @param {import('dbgate-types').EngineDriver} driver - */ -function createBulkInsertStream(driver, mssql, stream, pool, name, options) { - const writable = createBulkInsertStreamBase(driver, stream, pool, name, options); - - const fullName = name.schemaName ? `[${name.schemaName}].[${name.pureName}]` : name.pureName; - - writable.send = async () => { - if (!writable.templateColumns) { - const fullNameQuoted = name.schemaName - ? `${driver.dialect.quoteIdentifier(name.schemaName)}.${driver.dialect.quoteIdentifier(name.pureName)}` - : driver.dialect.quoteIdentifier(name.pureName); - - const respTemplate = await pool.request().query(`SELECT * FROM ${fullNameQuoted} WHERE 1=0`); - writable.templateColumns = respTemplate.recordset.toTable().columns; - } - - const rows = writable.buffer; - writable.buffer = []; - const table = new mssql.Table(fullName); - // table.create = options.createIfNotExists; - for (const column of this.columnNames) { - const tcol = writable.templateColumns.find((x) => x.name == column); - // console.log('TCOL', tcol); - // console.log('TYPE', tcol.type, mssql.Int); - // table.columns.add(column, tcol ? tcol.type : mssql.NVarChar(mssql.MAX)); - table.columns.add(column, tcol ? tcol.type : mssql.NVarChar(mssql.MAX), { - nullable: tcol.nullable, - length: tcol.length, - precision: tcol.precision, - scale: tcol.scale, - }); - } - for (const row of rows) { - table.rows.add(...this.columnNames.map((col) => row[col])); - } - const request = pool.request(); - await request.bulk(table); - }; - - return writable; -} - -module.exports = createBulkInsertStream; diff --git a/packages/engines/mssql/index.js b/packages/engines/mssql/index.js deleted file mode 100644 index f09eec170..000000000 --- a/packages/engines/mssql/index.js +++ /dev/null @@ -1,210 +0,0 @@ -const _ = require('lodash'); -const { driverBase } = require('dbgate-tools'); -const MsSqlAnalyser = require('./MsSqlAnalyser'); -const MsSqlDumper = require('./MsSqlDumper'); -const createBulkInsertStream = require('./createBulkInsertStream'); - -/** @type {import('dbgate-types').SqlDialect} */ -const dialect = { - limitSelect: true, - rangeSelect: true, - offsetFetchRangeSyntax: true, - stringEscapeChar: "'", - fallbackDataType: 'nvarchar(max)', - quoteIdentifier(s) { - return `[${s}]`; - }, -}; - -function extractColumns(columns) { - const mapper = {}; - const res = _.sortBy(_.values(columns), 'index').map((col) => ({ - ...col, - columnName: col.name, - notNull: !col.nullable, - })); - - const generateName = () => { - let index = 1; - while (res.find((x) => x.columnName == `col${index}`)) index += 1; - return `col${index}`; - }; - - // const groups = _.groupBy(res, 'columnName'); - // for (const colname of _.keys(groups)) { - // if (groups[colname].length == 1) continue; - // mapper[colname] = []; - // for (const col of groups[colname]) { - // col.columnName = generateName(); - // mapper[colname].push(colname); - // } - // } - - for (const col of res) { - if (!col.columnName) { - const newName = generateName(); - mapper[col.columnName] = newName; - col.columnName = newName; - } - } - - return [res, mapper]; -} - -/** @type {import('dbgate-types').EngineDriver} */ -const driver = { - ...driverBase, - analyserClass: MsSqlAnalyser, - dumperClass: MsSqlDumper, - async connect(nativeModules, { server, port, user, password, database }) { - const pool = new nativeModules.mssql.ConnectionPool({ - server, - port, - user, - password, - database, - requestTimeout: 1000 * 3600, - options: { - enableArithAbort: true, - }, - }); - await pool.connect(); - pool._nativeModules = nativeModules; - return pool; - }, - // @ts-ignore - async query(pool, sql) { - if (sql == null) { - return { - rows: [], - columns: [], - }; - } - const resp = await pool.request().query(sql); - // console.log(Object.keys(resp.recordset)); - // console.log(resp); - const res = {}; - - if (resp.recordset) { - const [columns] = extractColumns(resp.recordset.columns); - res.columns = columns; - res.rows = resp.recordset; - } - if (resp.rowsAffected) { - res.rowsAffected = _.sum(resp.rowsAffected); - } - return res; - }, - async stream(pool, sql, options) { - const request = await pool.request(); - let currentMapper = null; - - const handleInfo = (info) => { - const { message, lineNumber, procName } = info; - options.info({ - message, - line: lineNumber, - procedure: procName, - time: new Date(), - severity: 'info', - }); - }; - - const handleDone = (result) => { - // console.log('RESULT', result); - options.done(result); - }; - - const handleRow = (row) => { - // if (currentMapper) { - // for (const colname of _.keys(currentMapper)) { - // let index = 0; - // for (const newcolname of currentMapper[colname]) { - // row[newcolname] = row[colname][index]; - // index += 1; - // } - // delete row[colname]; - // } - // } - if (currentMapper) { - row = { ...row }; - for (const colname of _.keys(currentMapper)) { - const newcolname = currentMapper[colname]; - row[newcolname] = row[colname]; - if (_.isArray(row[newcolname])) row[newcolname] = row[newcolname].join(','); - delete row[colname]; - } - } - - options.row(row); - }; - - const handleRecordset = (columns) => { - const [extractedColumns, mapper] = extractColumns(columns); - currentMapper = mapper; - options.recordset(extractedColumns); - }; - - const handleError = (error) => { - const { message, lineNumber, procName } = error; - options.info({ - message, - line: lineNumber, - procedure: procName, - time: new Date(), - severity: 'error', - }); - }; - - request.stream = true; - request.on('recordset', handleRecordset); - request.on('row', handleRow); - request.on('error', handleError); - request.on('done', handleDone); - request.on('info', handleInfo); - request.query(sql); - - return request; - }, - async readQuery(pool, sql, structure) { - const request = await pool.request(); - const { stream } = pool._nativeModules; - - const pass = new stream.PassThrough({ - objectMode: true, - highWaterMark: 100, - }); - - request.stream = true; - request.on('recordset', (driverColumns) => { - const [columns, mapper] = extractColumns(driverColumns); - pass.write(structure || { columns }); - }); - request.on('row', (row) => pass.write(row)); - request.on('error', (err) => { - console.error(err); - pass.end(); - }); - request.on('done', () => pass.end()); - - request.query(sql); - - return pass; - }, - async writeTable(pool, name, options) { - const { stream, mssql } = pool._nativeModules; - return createBulkInsertStream(this, mssql, stream, pool, name, options); - }, - async getVersion(pool) { - const { version } = (await this.query(pool, 'SELECT @@VERSION AS version')).rows[0]; - return { version }; - }, - async listDatabases(pool) { - const { rows } = await this.query(pool, 'SELECT name FROM sys.databases order by name'); - return rows; - }, - dialect, - engine: 'mssql', -}; - -module.exports = driver; diff --git a/packages/engines/mssql/sql/columns.js b/packages/engines/mssql/sql/columns.js deleted file mode 100644 index 3de7ceffa..000000000 --- a/packages/engines/mssql/sql/columns.js +++ /dev/null @@ -1,20 +0,0 @@ -module.exports = ` -select c.name as columnName, t.name as dataType, c.object_id as objectId, c.is_identity as isIdentity, - c.max_length as maxLength, c.precision, c.scale, c.is_nullable as isNullable, - col.CHARACTER_MAXIMUM_LENGTH as charMaxLength, - d.definition as defaultValue, d.name as defaultConstraint, - m.definition as computedExpression, m.is_persisted as isPersisted, c.column_id as columnId, - col.NUMERIC_PRECISION as numericPrecision, - col.NUMERIC_SCALE as numericScale, - -- TODO only if version >= 2008 - c.is_sparse as isSparse -from sys.columns c -inner join sys.types t on c.system_type_id = t.system_type_id and c.user_type_id = t.user_type_id -inner join sys.objects o on c.object_id = o.object_id -INNER JOIN sys.schemas u ON u.schema_id=o.schema_id -INNER JOIN INFORMATION_SCHEMA.COLUMNS col ON col.TABLE_NAME = o.name AND col.TABLE_SCHEMA = u.name and col.COLUMN_NAME = c.name -left join sys.default_constraints d on c.default_object_id = d.object_id -left join sys.computed_columns m on m.object_id = c.object_id and m.column_id = c.column_id -where o.type = 'U' and o.object_id =[OBJECT_ID_CONDITION] -order by c.column_id -`; diff --git a/packages/engines/mssql/sql/foreignKeys.js b/packages/engines/mssql/sql/foreignKeys.js deleted file mode 100644 index 568117b77..000000000 --- a/packages/engines/mssql/sql/foreignKeys.js +++ /dev/null @@ -1,40 +0,0 @@ -module.exports = ` -SELECT - schemaName = FK.TABLE_SCHEMA, - pureName = FK.TABLE_NAME, - columnName = CU.COLUMN_NAME, - - refSchemaName = ISNULL(IXS.name, PK.TABLE_SCHEMA), - refTableName = ISNULL(IXT.name, PK.TABLE_NAME), - refColumnName = IXCC.name, - - constraintName = C.CONSTRAINT_NAME, - updateAction = rc.UPDATE_RULE, - deleteAction = rc.DELETE_RULE, - - objectId = o.object_id - -FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C -INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME - -LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME -LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME ---LEFT JOIN ( ---SELECT i1.TABLE_NAME, i2.COLUMN_NAME ---FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1 ---INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME ---WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY' ---) PT ON PT.TABLE_NAME = PK.TABLE_NAME -INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc ON FK.CONSTRAINT_NAME = rc.CONSTRAINT_NAME - -LEFT JOIN sys.indexes IX ON IX.name = C.UNIQUE_CONSTRAINT_NAME -LEFT JOIN sys.objects IXT ON IXT.object_id = IX.object_id -LEFT JOIN sys.index_columns IXC ON IX.index_id = IXC.index_id and IX.object_id = IXC.object_id -LEFT JOIN sys.columns IXCC ON IXCC.column_id = IXC.column_id AND IXCC.object_id = IXC.object_id -LEFT JOIN sys.schemas IXS ON IXT.schema_id = IXS.schema_id - -inner join sys.objects o on FK.TABLE_NAME = o.name -inner join sys.schemas s on o.schema_id = s.schema_id and FK.TABLE_SCHEMA = s.name - -where o.object_id =[OBJECT_ID_CONDITION] -`; diff --git a/packages/engines/mssql/sql/getSchemas.js b/packages/engines/mssql/sql/getSchemas.js deleted file mode 100644 index a7cb0a4de..000000000 --- a/packages/engines/mssql/sql/getSchemas.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = `select schema_id as objectId, name as schemaName from sys.schemas`; diff --git a/packages/engines/mssql/sql/index.js b/packages/engines/mssql/sql/index.js deleted file mode 100644 index cb40e88a5..000000000 --- a/packages/engines/mssql/sql/index.js +++ /dev/null @@ -1,23 +0,0 @@ -const columns = require('./columns'); -const foreignKeys = require('./foreignKeys'); -const primaryKeys = require('./primaryKeys'); -const tables = require('./tables'); -const modifications = require('./modifications'); -const loadSqlCode = require('./loadSqlCode'); -const views = require('./views'); -const programmables = require('./programmables'); -const viewColumns = require('./viewColumns'); -const getSchemas = require('./getSchemas'); - -module.exports = { - columns, - tables, - foreignKeys, - primaryKeys, - modifications, - loadSqlCode, - views, - programmables, - viewColumns, - getSchemas, -}; diff --git a/packages/engines/mssql/sql/loadSqlCode.js b/packages/engines/mssql/sql/loadSqlCode.js deleted file mode 100644 index c5f8ee87d..000000000 --- a/packages/engines/mssql/sql/loadSqlCode.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = ` -select s.name as pureName, u.name as schemaName, c.text AS codeText - from sys.objects s - inner join sys.syscomments c on s.object_id = c.id - inner join sys.schemas u on u.schema_id = s.schema_id -where (s.object_id =[OBJECT_ID_CONDITION]) -order by u.name, s.name, c.colid -`; diff --git a/packages/engines/mssql/sql/modifications.js b/packages/engines/mssql/sql/modifications.js deleted file mode 100644 index 4389fd6ca..000000000 --- a/packages/engines/mssql/sql/modifications.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = ` -select o.object_id as objectId, o.modify_date as modifyDate, o.type, o.name as pureName, s.name as schemaName -from sys.objects o -inner join sys.schemas s on o.schema_id = s.schema_id -where o.type in ('U', 'V', 'P', 'IF', 'FN', 'TF') -- , 'TR' - triggers disabled -`; diff --git a/packages/engines/mssql/sql/primaryKeys.js b/packages/engines/mssql/sql/primaryKeys.js deleted file mode 100644 index f67beb7f2..000000000 --- a/packages/engines/mssql/sql/primaryKeys.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = ` -select o.object_id, pureName = t.Table_Name, schemaName = t.Table_Schema, columnName = c.Column_Name, constraintName=t.constraint_name from - INFORMATION_SCHEMA.TABLE_CONSTRAINTS t, - sys.objects o, - sys.schemas s, - INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE c -where - c.Constraint_Name = t.Constraint_Name - and t.table_name = o.name - and o.schema_id = s.schema_id and t.Table_Schema = s.name - and c.Table_Name = t.Table_Name - and Constraint_Type = 'PRIMARY KEY' - and o.object_id =[OBJECT_ID_CONDITION] -`; diff --git a/packages/engines/mssql/sql/programmables.js b/packages/engines/mssql/sql/programmables.js deleted file mode 100644 index 8e651d3ec..000000000 --- a/packages/engines/mssql/sql/programmables.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = ` -select o.name as pureName, s.name as schemaName, o.object_id as objectId, o.create_date as createDate, o.modify_date as modifyDate, o.type as sqlObjectType -from sys.objects o -inner join sys.schemas s on o.schema_id = s.schema_id -where o.type in ('P', 'IF', 'FN', 'TF') and o.object_id =[OBJECT_ID_CONDITION] -`; diff --git a/packages/engines/mssql/sql/tables.js b/packages/engines/mssql/sql/tables.js deleted file mode 100644 index 46ab78440..000000000 --- a/packages/engines/mssql/sql/tables.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = ` -select - o.name as pureName, s.name as schemaName, o.object_id as objectId, - o.create_date as createDate, o.modify_date as modifyDate -from sys.tables o -inner join sys.schemas s on o.schema_id = s.schema_id -where o.object_id =[OBJECT_ID_CONDITION] -`; diff --git a/packages/engines/mssql/sql/viewColumns.js b/packages/engines/mssql/sql/viewColumns.js deleted file mode 100644 index 0868c43ae..000000000 --- a/packages/engines/mssql/sql/viewColumns.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = ` -select - o.object_id AS objectId, - col.TABLE_SCHEMA as schemaName, - col.TABLE_NAME as pureName, - col.COLUMN_NAME as columnName, - col.IS_NULLABLE as isNullable, - col.DATA_TYPE as dataType, - col.CHARACTER_MAXIMUM_LENGTH as charMaxLength, - col.NUMERIC_PRECISION as precision, - col.NUMERIC_SCALE as scale, - col.COLUMN_DEFAULT -FROM sys.objects o -INNER JOIN sys.schemas u ON u.schema_id=o.schema_id -INNER JOIN INFORMATION_SCHEMA.COLUMNS col ON col.TABLE_NAME = o.name AND col.TABLE_SCHEMA = u.name -WHERE o.type in ('V') and o.object_id =[OBJECT_ID_CONDITION] -order by col.ORDINAL_POSITION -`; diff --git a/packages/engines/mssql/sql/views.js b/packages/engines/mssql/sql/views.js deleted file mode 100644 index f0edb498f..000000000 --- a/packages/engines/mssql/sql/views.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = ` -SELECT - o.name as pureName, - u.name as schemaName, - o.object_id as objectId, - o.create_date as createDate, - o.modify_date as modifyDate -FROM sys.objects o INNER JOIN sys.schemas u ON u.schema_id=o.schema_id -WHERE type in ('V') and o.object_id =[OBJECT_ID_CONDITION] -`; diff --git a/packages/engines/mysql/MySqlAnalyser.js b/packages/engines/mysql/MySqlAnalyser.js deleted file mode 100644 index 4ce5aa1a8..000000000 --- a/packages/engines/mysql/MySqlAnalyser.js +++ /dev/null @@ -1,214 +0,0 @@ -const fp = require('lodash/fp'); -const _ = require('lodash'); -const sql = require('./sql'); - -const { DatabaseAnalyser } = require('dbgate-tools'); -const { isTypeString, isTypeNumeric } = require('dbgate-tools'); -const { rangeStep } = require('lodash/fp'); - -function getColumnInfo({ - isNullable, - extra, - columnName, - dataType, - charMaxLength, - numericPrecision, - numericScale, - defaultValue, -}) { - let fullDataType = dataType; - if (charMaxLength && isTypeString(dataType)) fullDataType = `${dataType}(${charMaxLength})`; - if (numericPrecision && numericScale && isTypeNumeric(dataType)) - fullDataType = `${dataType}(${numericPrecision},${numericScale})`; - return { - notNull: !isNullable || isNullable == 'NO' || isNullable == 'no', - autoIncrement: extra && extra.toLowerCase().includes('auto_increment'), - columnName, - dataType: fullDataType, - defaultValue, - }; -} - -function objectTypeToField(type) { - if (type == 'VIEW') return 'views'; - if (type == 'BASE TABLE') return 'tables'; - return null; -} - -class MySqlAnalyser extends DatabaseAnalyser { - constructor(pool, driver) { - super(pool, driver); - } - - createQuery(resFileName, typeFields) { - let res = sql[resFileName]; - if (this.singleObjectFilter) { - const { typeField, pureName } = this.singleObjectFilter; - if (!typeFields || !typeFields.includes(typeField)) return null; - res = res.replace('=[OBJECT_NAME_CONDITION]', ` = '${pureName}'`).replace('#DATABASE#', this.pool._database_name); - return res; - } - if (!this.modifications || !typeFields || this.modifications.length == 0) { - res = res.replace('=[OBJECT_NAME_CONDITION]', ' is not null'); - } else { - const filterNames = this.modifications - .filter((x) => typeFields.includes(x.objectTypeField) && (x.action == 'add' || x.action == 'change')) - .map((x) => x.newName && x.newName.pureName) - .filter(Boolean); - if (filterNames.length == 0) { - res = res.replace('=[OBJECT_NAME_CONDITION]', ' IS NULL'); - } else { - res = res.replace('=[OBJECT_NAME_CONDITION]', ` in (${filterNames.map((x) => `'${x}'`).join(',')})`); - } - } - res = res.replace('#DATABASE#', this.pool._database_name); - return res; - } - - getRequestedViewNames(allViewNames) { - if (this.singleObjectFilter) { - const { typeField, pureName } = this.singleObjectFilter; - if (typeField == 'views') return [pureName]; - } - if (this.modifications) { - return this.modifications.filter((x) => x.objectTypeField == 'views').map((x) => x.newName.pureName); - } - return allViewNames; - } - - async getViewTexts(allViewNames) { - const res = {}; - for (const viewName of this.getRequestedViewNames(allViewNames)) { - const resp = await this.driver.query(this.pool, `SHOW CREATE VIEW \`${viewName}\``); - res[viewName] = resp.rows[0]['Create View']; - } - return res; - } - - async _runAnalysis() { - const tables = await this.driver.query(this.pool, this.createQuery('tables', ['tables'])); - const columns = await this.driver.query(this.pool, this.createQuery('columns', ['tables', 'views'])); - const pkColumns = await this.driver.query(this.pool, this.createQuery('primaryKeys', ['tables'])); - const fkColumns = await this.driver.query(this.pool, this.createQuery('foreignKeys', ['tables'])); - const views = await this.driver.query(this.pool, this.createQuery('views', ['views'])); - const programmables = await this.driver.query( - this.pool, - this.createQuery('programmables', ['procedures', 'functions']) - ); - - const viewTexts = await this.getViewTexts(views.rows.map((x) => x.pureName)); - - return this.mergeAnalyseResult( - { - tables: tables.rows.map((table) => ({ - ...table, - columns: columns.rows.filter((col) => col.pureName == table.pureName).map(getColumnInfo), - primaryKey: DatabaseAnalyser.extractPrimaryKeys(table, pkColumns.rows), - foreignKeys: DatabaseAnalyser.extractForeignKeys(table, fkColumns.rows), - })), - views: views.rows.map((view) => ({ - ...view, - columns: columns.rows.filter((col) => col.pureName == view.pureName).map(getColumnInfo), - createSql: viewTexts[view.pureName], - requiresFormat: true, - })), - procedures: programmables.rows.filter((x) => x.objectType == 'PROCEDURE').map(fp.omit(['objectType'])), - functions: programmables.rows.filter((x) => x.objectType == 'FUNCTION').map(fp.omit(['objectType'])), - }, - (x) => x.pureName - ); - } - - getDeletedObjectsForField(nameArray, objectTypeField) { - return this.structure[objectTypeField] - .filter((x) => !nameArray.includes(x.pureName)) - .map((x) => ({ - oldName: _.pick(x, ['pureName']), - action: 'remove', - objectTypeField, - })); - } - - getDeletedObjects(nameArray) { - return [ - ...this.getDeletedObjectsForField(nameArray, 'tables'), - ...this.getDeletedObjectsForField(nameArray, 'views'), - ...this.getDeletedObjectsForField(nameArray, 'procedures'), - ...this.getDeletedObjectsForField(nameArray, 'functions'), - ...this.getDeletedObjectsForField(nameArray, 'triggers'), - ]; - } - - async getModifications() { - const tableModificationsQueryData = await this.driver.query(this.pool, this.createQuery('tableModifications')); - const procedureModificationsQueryData = await this.driver.query( - this.pool, - this.createQuery('procedureModifications') - ); - const functionModificationsQueryData = await this.driver.query( - this.pool, - this.createQuery('functionModifications') - ); - - const allModifications = _.compact([ - ...tableModificationsQueryData.rows.map((x) => { - if (x.objectType == 'BASE TABLE') return { ...x, objectTypeField: 'tables' }; - if (x.objectType == 'VIEW') return { ...x, objectTypeField: 'views' }; - return null; - }), - ...procedureModificationsQueryData.rows.map((x) => ({ - objectTypeField: 'procedures', - modifyDate: x.Modified, - pureName: x.Name, - })), - ...functionModificationsQueryData.rows.map((x) => ({ - objectTypeField: 'functions', - modifyDate: x.Modified, - pureName: x.Name, - })), - ]); - - // console.log('allModifications', allModifications); - // console.log( - // 'DATES', - // this.structure.procedures.map((x) => x.modifyDate) - // ); - // console.log('MOD - SRC', modifications); - // console.log( - // 'MODs', - // this.structure.tables.map((x) => x.modifyDate) - // ); - const modifications = allModifications.map((x) => { - const { objectType, modifyDate, pureName } = x; - const field = objectTypeToField(objectType); - - if (!field || !this.structure[field]) return null; - // @ts-ignore - const obj = this.structure[field].find((x) => x.pureName == pureName); - - // object not modified - if (obj && Math.abs(new Date(modifyDate).getTime() - new Date(obj.modifyDate).getTime()) < 1000) return null; - - // console.log('MODIFICATION OF ', field, pureName, modifyDate, obj.modifyDate); - - /** @type {import('dbgate-types').DatabaseModification} */ - const action = obj - ? { - newName: { pureName }, - oldName: _.pick(obj, ['pureName']), - action: 'change', - objectTypeField: field, - } - : { - newName: { pureName }, - action: 'add', - objectTypeField: field, - }; - return action; - }); - - return [..._.compact(modifications), ...this.getDeletedObjects([...allModifications.map((x) => x.pureName)])]; - } -} - -module.exports = MySqlAnalyser; diff --git a/packages/engines/mysql/MySqlDumper.js b/packages/engines/mysql/MySqlDumper.js deleted file mode 100644 index 0a5e6922d..000000000 --- a/packages/engines/mysql/MySqlDumper.js +++ /dev/null @@ -1,30 +0,0 @@ -const { SqlDumper } = require('dbgate-tools'); - -class MySqlDumper extends SqlDumper { - /** @param type {import('dbgate-types').TransformType} */ - transform(type, dumpExpr) { - switch (type) { - case 'GROUP:YEAR': - case 'YEAR': - this.put('^year(%c)', dumpExpr); - break; - case 'MONTH': - this.put('^month(%c)', dumpExpr); - break; - case 'DAY': - this.put('^day(%c)', dumpExpr); - break; - case 'GROUP:MONTH': - this.put("^date_format(%c, '%s')", dumpExpr, '%Y-%m'); - break; - case 'GROUP:DAY': - this.put("^date_format(%c, '%s')", dumpExpr, '%Y-%m-%d'); - break; - default: - dumpExpr(); - break; - } - } -} - -module.exports = MySqlDumper; diff --git a/packages/engines/mysql/index.js b/packages/engines/mysql/index.js deleted file mode 100644 index 010e7a461..000000000 --- a/packages/engines/mysql/index.js +++ /dev/null @@ -1,159 +0,0 @@ -const { driverBase } = require('dbgate-tools'); -const MySqlAnalyser = require('./MySqlAnalyser'); -const MySqlDumper = require('./MySqlDumper'); - -/** @type {import('dbgate-types').SqlDialect} */ -const dialect = { - rangeSelect: true, - stringEscapeChar: '\\', - fallbackDataType: 'longtext', - quoteIdentifier(s) { - return '`' + s + '`'; - }, -}; - -function extractColumns(fields) { - if (fields) - return fields.map((col) => ({ - columnName: col.name, - })); - return null; -} - -/** @type {import('dbgate-types').EngineDriver} */ -const driver = { - ...driverBase, - analyserClass: MySqlAnalyser, - dumperClass: MySqlDumper, - - async connect(nativeModules, { server, port, user, password, database }) { - const connection = nativeModules.mysql.createConnection({ - host: server, - port, - user, - password, - database, - }); - connection._database_name = database; - connection._nativeModules = nativeModules; - return connection; - }, - async query(connection, sql) { - if (sql == null) { - return { - rows: [], - columns: [], - }; - } - return new Promise((resolve, reject) => { - connection.query(sql, function (error, results, fields) { - if (error) reject(error); - resolve({ rows: results, columns: extractColumns(fields) }); - }); - }); - }, - async stream(connection, sql, options) { - const query = connection.query(sql); - - // const handleInfo = (info) => { - // const { message, lineNumber, procName } = info; - // options.info({ - // message, - // line: lineNumber, - // procedure: procName, - // time: new Date(), - // severity: 'info', - // }); - // }; - - const handleEnd = (result) => { - // console.log('RESULT', result); - options.done(result); - }; - - const handleRow = (row) => { - options.row(row); - }; - - const handleFields = (columns) => { - console.log('FIELDS', columns[0].name); - options.recordset(extractColumns(columns)); - }; - - const handleError = (error) => { - console.log('ERROR', error); - const { message, lineNumber, procName } = error; - options.info({ - message, - line: lineNumber, - procedure: procName, - time: new Date(), - severity: 'error', - }); - }; - - query.on('error', handleError).on('fields', handleFields).on('result', handleRow).on('end', handleEnd); - - return query; - }, - async readQuery(connection, sql, structure) { - const query = connection.query(sql); - const { stream } = connection._nativeModules; - - const pass = new stream.PassThrough({ - objectMode: true, - highWaterMark: 100, - }); - - query - .on('error', (err) => { - console.error(err); - pass.end(); - }) - .on('fields', (fields) => pass.write(structure || { columns: extractColumns(fields) })) - .on('result', (row) => pass.write(row)) - .on('end', () => pass.end()); - - return pass; - }, - async getVersion(connection) { - const { rows } = await this.query(connection, "show variables like 'version'"); - const version = rows[0].Value; - return { version }; - }, - // async analyseFull(pool) { - // const analyser = new MySqlAnalyser(pool, this); - // return analyser.fullAnalysis(); - // }, - // async analyseIncremental(pool, structure) { - // const analyser = new MySqlAnalyser(pool, this); - // return analyser.incrementalAnalysis(structure); - // }, - // async analyseSingleObject(pool, name, typeField = 'tables') { - // const analyser = new MySqlAnalyser(pool, this); - // analyser.singleObjectFilter = { ...name, typeField }; - // const res = await analyser.fullAnalysis(); - // return res.tables[0]; - // }, - // // @ts-ignore - // analyseSingleTable(pool, name) { - // return this.analyseSingleObject(pool, name, 'tables'); - // }, - async listDatabases(connection) { - const { rows } = await this.query(connection, 'show databases'); - return rows.map((x) => ({ name: x.Database })); - }, - async writeTable(pool, name, options) { - const { stream } = pool._nativeModules; - // @ts-ignore - return createBulkInsertStreamBase(this, stream, pool, name, options); - }, - - // createDumper() { - // return new MySqlDumper(this); - // }, - dialect, - engine: 'mysql', -}; - -module.exports = driver; diff --git a/packages/engines/mysql/sql/columns.js b/packages/engines/mysql/sql/columns.js deleted file mode 100644 index 0adb27e2b..000000000 --- a/packages/engines/mysql/sql/columns.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = ` -select - TABLE_NAME as pureName, - COLUMN_NAME as columnName, - IS_NULLABLE as isNullable, - DATA_TYPE as dataType, - CHARACTER_MAXIMUM_LENGTH as charMaxLength, - NUMERIC_PRECISION as numericPrecision, - NUMERIC_SCALE as numericScale, - COLUMN_DEFAULT as defaultValue, - EXTRA as extra -from INFORMATION_SCHEMA.COLUMNS -where TABLE_SCHEMA = '#DATABASE#' and TABLE_NAME =[OBJECT_NAME_CONDITION] -order by ORDINAL_POSITION -`; diff --git a/packages/engines/mysql/sql/foreignKeys.js b/packages/engines/mysql/sql/foreignKeys.js deleted file mode 100644 index 5b43b4031..000000000 --- a/packages/engines/mysql/sql/foreignKeys.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = ` -select - REFERENTIAL_CONSTRAINTS.CONSTRAINT_NAME as constraintName, - REFERENTIAL_CONSTRAINTS.TABLE_NAME as pureName, - REFERENTIAL_CONSTRAINTS.UPDATE_RULE as updateAction, - REFERENTIAL_CONSTRAINTS.DELETE_RULE as deleteAction, - REFERENTIAL_CONSTRAINTS.REFERENCED_TABLE_NAME as refTableName, - KEY_COLUMN_USAGE.COLUMN_NAME as columnName, - KEY_COLUMN_USAGE.REFERENCED_COLUMN_NAME as refColumnName -from INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS -inner join INFORMATION_SCHEMA.KEY_COLUMN_USAGE - on REFERENTIAL_CONSTRAINTS.TABLE_NAME = KEY_COLUMN_USAGE.TABLE_NAME - and REFERENTIAL_CONSTRAINTS.CONSTRAINT_NAME = KEY_COLUMN_USAGE.CONSTRAINT_NAME - and REFERENTIAL_CONSTRAINTS.CONSTRAINT_SCHEMA = KEY_COLUMN_USAGE.CONSTRAINT_SCHEMA -where REFERENTIAL_CONSTRAINTS.CONSTRAINT_SCHEMA = '#DATABASE#' and REFERENTIAL_CONSTRAINTS.TABLE_NAME =[OBJECT_NAME_CONDITION] -order by KEY_COLUMN_USAGE.ORDINAL_POSITION -`; diff --git a/packages/engines/mysql/sql/functionModifications.js b/packages/engines/mysql/sql/functionModifications.js deleted file mode 100644 index f422a219a..000000000 --- a/packages/engines/mysql/sql/functionModifications.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = ` -SHOW FUNCTION STATUS WHERE Db = '#DATABASE#' -`; diff --git a/packages/engines/mysql/sql/index.js b/packages/engines/mysql/sql/index.js deleted file mode 100644 index f5a4992ec..000000000 --- a/packages/engines/mysql/sql/index.js +++ /dev/null @@ -1,21 +0,0 @@ -const columns = require('./columns'); -const tables = require('./tables'); -const primaryKeys = require('./primaryKeys'); -const foreignKeys = require('./foreignKeys'); -const tableModifications = require('./tableModifications'); -const views = require('./views'); -const programmables = require('./programmables'); -const procedureModifications = require('./procedureModifications'); -const functionModifications = require('./functionModifications'); - -module.exports = { - columns, - tables, - primaryKeys, - foreignKeys, - tableModifications, - views, - programmables, - procedureModifications, - functionModifications, -}; diff --git a/packages/engines/mysql/sql/primaryKeys.js b/packages/engines/mysql/sql/primaryKeys.js deleted file mode 100644 index 2b1b346e8..000000000 --- a/packages/engines/mysql/sql/primaryKeys.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = `select - TABLE_CONSTRAINTS.CONSTRAINT_NAME as constraintName, - TABLE_CONSTRAINTS.TABLE_NAME as pureName, - KEY_COLUMN_USAGE.COLUMN_NAME as columnName -from INFORMATION_SCHEMA.TABLE_CONSTRAINTS -inner join INFORMATION_SCHEMA.KEY_COLUMN_USAGE - on TABLE_CONSTRAINTS.TABLE_NAME = KEY_COLUMN_USAGE.TABLE_NAME - and TABLE_CONSTRAINTS.CONSTRAINT_NAME = KEY_COLUMN_USAGE.CONSTRAINT_NAME - and TABLE_CONSTRAINTS.CONSTRAINT_SCHEMA = KEY_COLUMN_USAGE.CONSTRAINT_SCHEMA -where TABLE_CONSTRAINTS.CONSTRAINT_SCHEMA = '#DATABASE#' and TABLE_CONSTRAINTS.TABLE_NAME =[OBJECT_NAME_CONDITION] AND TABLE_CONSTRAINTS.CONSTRAINT_TYPE = 'PRIMARY KEY' -order by KEY_COLUMN_USAGE.ORDINAL_POSITION -`; diff --git a/packages/engines/mysql/sql/procedureModifications.js b/packages/engines/mysql/sql/procedureModifications.js deleted file mode 100644 index 0ccbd49f8..000000000 --- a/packages/engines/mysql/sql/procedureModifications.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = ` -SHOW PROCEDURE STATUS WHERE Db = '#DATABASE#' -`; diff --git a/packages/engines/mysql/sql/programmables.js b/packages/engines/mysql/sql/programmables.js deleted file mode 100644 index dd1b36021..000000000 --- a/packages/engines/mysql/sql/programmables.js +++ /dev/null @@ -1,9 +0,0 @@ -module.exports = ` -select - ROUTINE_NAME as pureName, - ROUTINE_TYPE as objectType, - COALESCE(LAST_ALTERED, CREATED) as modifyDate, - ROUTINE_DEFINITION as createSql -from information_schema.routines -where ROUTINE_SCHEMA = '#DATABASE#' and ROUTINE_NAME =[OBJECT_NAME_CONDITION] -`; diff --git a/packages/engines/mysql/sql/tableModifications.js b/packages/engines/mysql/sql/tableModifications.js deleted file mode 100644 index 6382ea5ae..000000000 --- a/packages/engines/mysql/sql/tableModifications.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = ` -select - TABLE_NAME as pureName, - TABLE_TYPE as objectType, - case when ENGINE='InnoDB' then CREATE_TIME else coalesce(UPDATE_TIME, CREATE_TIME) end as modifyDate -from information_schema.tables -where TABLE_SCHEMA = '#DATABASE#' -`; diff --git a/packages/engines/mysql/sql/tables.js b/packages/engines/mysql/sql/tables.js deleted file mode 100644 index eed928431..000000000 --- a/packages/engines/mysql/sql/tables.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = ` -select - TABLE_NAME as pureName, - case when ENGINE='InnoDB' then CREATE_TIME else coalesce(UPDATE_TIME, CREATE_TIME) end as modifyDate -from information_schema.tables -where TABLE_SCHEMA = '#DATABASE#' and TABLE_TYPE='BASE TABLE' and TABLE_NAME =[OBJECT_NAME_CONDITION]; -`; diff --git a/packages/engines/mysql/sql/views.js b/packages/engines/mysql/sql/views.js deleted file mode 100644 index ea4d8ef35..000000000 --- a/packages/engines/mysql/sql/views.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = ` -select - TABLE_NAME as pureName, - coalesce(UPDATE_TIME, CREATE_TIME) as modifyDate -from information_schema.tables -where TABLE_SCHEMA = '#DATABASE#' and TABLE_NAME =[OBJECT_NAME_CONDITION] and TABLE_TYPE = 'VIEW'; -`; diff --git a/packages/engines/package.json b/packages/engines/package.json deleted file mode 100644 index a0b011d0f..000000000 --- a/packages/engines/package.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "name": "dbgate-engines", - "version": "1.0.3", - "main": "index.js", - "typings": "./index.d.ts", - "homepage": "https://dbgate.org/", - "repository": { - "type": "git", - "url": "https://github.com/dbshell/dbgate.git" - }, - "funding": "https://www.paypal.com/paypalme/JanProchazkaCz/30eur", - "author": "Jan Prochazka", - "license": "GPL", - "keywords": [ - "sql", - "mssql", - "mssql", - "postgresql", - "dbgate" - ], - "devDependencies": { - "@types/lodash": "^4.14.149", - "dbgate-types": "^1.0.0", - "nodemon": "^2.0.2", - "typescript": "^3.7.5" - }, - "dependencies": { - "dbgate-tools": "^1.0.0", - "lodash": "^4.17.15", - "moment": "^2.24.0" - } -} diff --git a/packages/engines/postgres/PostgreAnalyser.js b/packages/engines/postgres/PostgreAnalyser.js deleted file mode 100644 index 79a4a32a1..000000000 --- a/packages/engines/postgres/PostgreAnalyser.js +++ /dev/null @@ -1,173 +0,0 @@ -const fp = require('lodash/fp'); -const _ = require('lodash'); -const sql = require('./sql'); - -const { DatabaseAnalyser } = require('dbgate-tools'); -const { isTypeString, isTypeNumeric } = require('dbgate-tools'); - -function normalizeTypeName(dataType) { - if (dataType == 'character varying') return 'varchar'; - if (dataType == 'timestamp without time zone') return 'timestamp'; - return dataType; -} - -function getColumnInfo({ - isNullable, - isIdentity, - columnName, - dataType, - charMaxLength, - numericPrecision, - numericScale, - defaultValue, -}) { - const normDataType = normalizeTypeName(dataType); - let fullDataType = normDataType; - if (charMaxLength && isTypeString(normDataType)) fullDataType = `${normDataType}(${charMaxLength})`; - if (numericPrecision && numericScale && isTypeNumeric(normDataType)) - fullDataType = `${normDataType}(${numericPrecision},${numericScale})`; - return { - columnName, - dataType: fullDataType, - notNull: !isNullable || isNullable == 'NO' || isNullable == 'no', - autoIncrement: !!isIdentity, - defaultValue, - }; -} - -class PostgreAnalyser extends DatabaseAnalyser { - constructor(pool, driver) { - super(pool, driver); - } - - createQuery(resFileName, typeFields) { - let res = sql[resFileName]; - - if (this.singleObjectFilter) { - const { typeField, schemaName, pureName } = this.singleObjectFilter; - if (!typeFields || !typeFields.includes(typeField)) return null; - res = res.replace(/=OBJECT_ID_CONDITION/g, ` = '${typeField}:${schemaName || 'public'}.${pureName}'`); - return res; - } - if (!this.modifications || !typeFields || this.modifications.length == 0) { - res = res.replace(/=OBJECT_ID_CONDITION/g, ' is not null'); - } else { - const filterNames = this.modifications - .filter((x) => typeFields.includes(x.objectTypeField) && (x.action == 'add' || x.action == 'change')) - .filter((x) => x.newName) - .map((x) => `${x.objectTypeField}:${x.newName.schemaName}.${x.newName.pureName}`); - if (filterNames.length == 0) { - res = res.replace(/=OBJECT_ID_CONDITION/g, ' IS NULL'); - } else { - res = res.replace(/=OBJECT_ID_CONDITION/g, ` in (${filterNames.map((x) => `'${x}'`).join(',')})`); - } - } - return res; - - // let res = sql[resFileName]; - // res = res.replace('=[OBJECT_ID_CONDITION]', ' is not null'); - // return res; - } - async _runAnalysis() { - const tables = await this.driver.query(this.pool, this.createQuery('tableModifications', ['tables'])); - const columns = await this.driver.query(this.pool, this.createQuery('columns', ['tables'])); - const pkColumns = await this.driver.query(this.pool, this.createQuery('primaryKeys', ['tables'])); - const fkColumns = await this.driver.query(this.pool, this.createQuery('foreignKeys', ['tables'])); - const views = await this.driver.query(this.pool, this.createQuery('views', ['views'])); - const routines = await this.driver.query(this.pool, this.createQuery('routines', ['procedures', 'functions'])); - // console.log('PG fkColumns', fkColumns.rows); - - return this.mergeAnalyseResult( - { - tables: tables.rows.map((table) => ({ - ...table, - columns: columns.rows - .filter((col) => col.pureName == table.pureName && col.schemaName == table.schemaName) - .map(getColumnInfo), - primaryKey: DatabaseAnalyser.extractPrimaryKeys(table, pkColumns.rows), - foreignKeys: DatabaseAnalyser.extractForeignKeys(table, fkColumns.rows), - })), - views: views.rows.map((view) => ({ - ...view, - columns: columns.rows - .filter((col) => col.pureName == view.pureName && col.schemaName == view.schemaName) - .map(getColumnInfo), - })), - procedures: routines.rows.filter((x) => x.objectType == 'PROCEDURE'), - functions: routines.rows.filter((x) => x.objectType == 'FUNCTION'), - }, - (x) => `${x.objectTypeField}:${x.schemaName}.${x.pureName}` - ); - } - - async getModifications() { - const tableModificationsQueryData = await this.driver.query(this.pool, this.createQuery('tableModifications')); - const viewModificationsQueryData = await this.driver.query(this.pool, this.createQuery('viewModifications')); - const routineModificationsQueryData = await this.driver.query(this.pool, this.createQuery('routineModifications')); - - const allModifications = _.compact([ - ...tableModificationsQueryData.rows.map((x) => ({ ...x, objectTypeField: 'tables' })), - ...viewModificationsQueryData.rows.map((x) => ({ ...x, objectTypeField: 'views' })), - ...routineModificationsQueryData.rows - .filter((x) => x.objectType == 'PROCEDURE') - .map((x) => ({ ...x, objectTypeField: 'procedures' })), - ...routineModificationsQueryData.rows - .filter((x) => x.objectType == 'FUNCTION') - .map((x) => ({ ...x, objectTypeField: 'functions' })), - ]); - - const modifications = allModifications.map((x) => { - const { objectTypeField, hashCode, pureName, schemaName } = x; - - if (!objectTypeField || !this.structure[objectTypeField]) return null; - const obj = this.structure[objectTypeField].find((x) => x.pureName == pureName && x.schemaName == schemaName); - - // object not modified - if (obj && obj.hashCode == hashCode) return null; - - // console.log('MODIFICATION OF ', objectTypeField, schemaName, pureName); - - /** @type {import('dbgate-types').DatabaseModification} */ - const action = obj - ? { - newName: { schemaName, pureName }, - oldName: _.pick(obj, ['schemaName', 'pureName']), - action: 'change', - objectTypeField, - } - : { - newName: { schemaName, pureName }, - action: 'add', - objectTypeField, - }; - return action; - }); - - return [ - ..._.compact(modifications), - ...this.getDeletedObjects([...allModifications.map((x) => `${x.schemaName}.${x.pureName}`)]), - ]; - } - - getDeletedObjectsForField(nameArray, objectTypeField) { - return this.structure[objectTypeField] - .filter((x) => !nameArray.includes(`${x.schemaName}.${x.pureName}`)) - .map((x) => ({ - oldName: _.pick(x, ['schemaName', 'pureName']), - action: 'remove', - objectTypeField, - })); - } - - getDeletedObjects(nameArray) { - return [ - ...this.getDeletedObjectsForField(nameArray, 'tables'), - ...this.getDeletedObjectsForField(nameArray, 'views'), - ...this.getDeletedObjectsForField(nameArray, 'procedures'), - ...this.getDeletedObjectsForField(nameArray, 'functions'), - ...this.getDeletedObjectsForField(nameArray, 'triggers'), - ]; - } -} - -module.exports = PostgreAnalyser; diff --git a/packages/engines/postgres/PostgreDumper.js b/packages/engines/postgres/PostgreDumper.js deleted file mode 100644 index 2fe0bf076..000000000 --- a/packages/engines/postgres/PostgreDumper.js +++ /dev/null @@ -1,30 +0,0 @@ -const { SqlDumper } = require('dbgate-tools'); - -class PostgreDumper extends SqlDumper { - /** @param type {import('dbgate-types').TransformType} */ - transform(type, dumpExpr) { - switch (type) { - case 'GROUP:YEAR': - case 'YEAR': - this.put('^extract(^year ^from %c)', dumpExpr); - break; - case 'MONTH': - this.put('^extract(^month ^from %c)', dumpExpr); - break; - case 'DAY': - this.put('^extract(^day ^from %c)', dumpExpr); - break; - case 'GROUP:MONTH': - this.put("^to_char(%c, '%s')", dumpExpr, 'YYYY-MM'); - break; - case 'GROUP:DAY': - this.put("^to_char(%c, '%s')", dumpExpr, 'YYYY-MM-DD'); - break; - default: - dumpExpr(); - break; - } - } -} - -module.exports = PostgreDumper; diff --git a/packages/engines/postgres/index.js b/packages/engines/postgres/index.js deleted file mode 100644 index 9aad592cf..000000000 --- a/packages/engines/postgres/index.js +++ /dev/null @@ -1,190 +0,0 @@ -const _ = require('lodash'); -const { driverBase } = require('dbgate-tools'); -const PostgreAnalyser = require('./PostgreAnalyser'); -const PostgreDumper = require('./PostgreDumper'); - -/** @type {import('dbgate-types').SqlDialect} */ -const dialect = { - rangeSelect: true, - // stringEscapeChar: '\\', - stringEscapeChar: "'", - fallbackDataType: 'varchar', - quoteIdentifier(s) { - return '"' + s + '"'; - }, -}; - -/** @type {import('dbgate-types').EngineDriver} */ -const driver = { - ...driverBase, - analyserClass: PostgreAnalyser, - dumperClass: PostgreDumper, - - async connect(nativeModules, { server, port, user, password, database }) { - const client = new nativeModules.pg.Client({ - host: server, - port, - user, - password, - database: database || 'postgres', - }); - await client.connect(); - client._nativeModules = nativeModules; - return client; - }, - async query(client, sql) { - if (sql == null) { - return { - rows: [], - columns: [], - }; - } - const res = await client.query(sql); - return { rows: res.rows, columns: res.fields }; - }, - async stream(client, sql, options) { - const query = new client._nativeModules.pgQueryStream(sql); - const stream = client.query(query); - - // const handleInfo = (info) => { - // const { message, lineNumber, procName } = info; - // options.info({ - // message, - // line: lineNumber, - // procedure: procName, - // time: new Date(), - // severity: 'info', - // }); - // }; - - let wasHeader = false; - - const handleEnd = (result) => { - // console.log('RESULT', result); - options.done(result); - }; - - const handleReadable = () => { - let row = stream.read(); - if (!wasHeader && row) { - options.recordset(_.keys(row).map((columnName) => ({ columnName }))); - wasHeader = true; - } - - while (row) { - options.row(row); - row = stream.read(); - } - }; - - // const handleFields = (columns) => { - // // console.log('FIELDS', columns[0].name); - // options.recordset(columns); - // // options.recordset(extractColumns(columns)); - // }; - - const handleError = (error) => { - console.log('ERROR', error); - const { message, lineNumber, procName } = error; - options.info({ - message, - line: lineNumber, - procedure: procName, - time: new Date(), - severity: 'error', - }); - }; - - stream.on('error', handleError); - stream.on('readable', handleReadable); - // stream.on('result', handleRow) - // stream.on('data', handleRow) - stream.on('end', handleEnd); - - return stream; - }, - // async analyseSingleObject(pool, name, typeField = 'tables') { - // const analyser = new PostgreAnalyser(pool, this); - // analyser.singleObjectFilter = { ...name, typeField }; - // const res = await analyser.fullAnalysis(); - // return res.tables[0]; - // }, - // // @ts-ignore - // analyseSingleTable(pool, name) { - // return this.analyseSingleObject(pool, name, 'tables'); - // }, - async getVersion(client) { - const { rows } = await this.query(client, 'SELECT version()'); - const { version } = rows[0]; - return { version }; - }, - // async analyseFull(pool) { - // const analyser = new PostgreAnalyser(pool, this); - // return analyser.fullAnalysis(); - // }, - // async analyseIncremental(pool, structure) { - // const analyser = new PostgreAnalyser(pool, this); - // return analyser.incrementalAnalysis(structure); - // }, - async readQuery(client, sql, structure) { - const query = new client._nativeModules.pgQueryStream(sql); - const { stream } = client._nativeModules; - - const queryStream = client.query(query); - - let wasHeader = false; - - const pass = new stream.PassThrough({ - objectMode: true, - highWaterMark: 100, - }); - - const handleEnd = (result) => { - pass.end(); - }; - - const handleReadable = () => { - let row = queryStream.read(); - if (!wasHeader && row) { - pass.write( - structure || { - columns: _.keys(row).map((columnName) => ({ columnName })), - } - ); - wasHeader = true; - } - - while (row) { - pass.write(row); - row = queryStream.read(); - } - }; - - const handleError = (error) => { - console.error(error); - pass.end(); - }; - - queryStream.on('error', handleError); - queryStream.on('readable', handleReadable); - queryStream.on('end', handleEnd); - - return pass; - }, - // createDumper() { - // return new PostgreDumper(this); - // }, - async writeTable(pool, name, options) { - const { stream } = pool._nativeModules; - // @ts-ignore - return createBulkInsertStreamBase(this, stream, pool, name, options); - }, - async listDatabases(client) { - const { rows } = await this.query(client, 'SELECT datname AS name FROM pg_database WHERE datistemplate = false'); - return rows; - }, - dialect, - engine: 'postgres', -}; - -module.exports = driver; diff --git a/packages/engines/postgres/sql/columns.js b/packages/engines/postgres/sql/columns.js deleted file mode 100644 index 841eda6b9..000000000 --- a/packages/engines/postgres/sql/columns.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = ` -select - table_schema as "schemaName", - table_name as "pureName", - column_name as "columnName", - is_nullable as "isNullable", - data_type as "dataType", - character_maximum_length as "charMaxLength", - numeric_precision as "numericPrecision", - numeric_scale as "numericScale", - column_default as "defaultValue" -from information_schema.columns -where - table_schema <> 'information_schema' - and table_schema <> 'pg_catalog' - and table_schema !~ '^pg_toast' - and 'tables:' || table_schema || '.' || table_name =OBJECT_ID_CONDITION -order by ordinal_position -`; \ No newline at end of file diff --git a/packages/engines/postgres/sql/foreignKeys.js b/packages/engines/postgres/sql/foreignKeys.js deleted file mode 100644 index fadcf5e78..000000000 --- a/packages/engines/postgres/sql/foreignKeys.js +++ /dev/null @@ -1,24 +0,0 @@ -module.exports = ` -select - fk.constraint_name as "constraintName", - fk.constraint_schema as "constraintSchema", - base.table_name as "pureName", - base.table_schema as "schemaName", - fk.update_rule as "updateAction", - fk.delete_rule as "deleteAction", - ref.table_name as "refTableName", - ref.table_schema as "refSchemaName", - basecol.column_name as "columnName", - refcol.column_name as "refColumnName" -from information_schema.referential_constraints fk -inner join information_schema.table_constraints base on fk.constraint_name = base.constraint_name and fk.constraint_schema = base.constraint_schema -inner join information_schema.table_constraints ref on fk.unique_constraint_name = ref.constraint_name and fk.unique_constraint_schema = ref.constraint_schema -inner join information_schema.key_column_usage basecol on base.table_name = basecol.table_name and base.constraint_name = basecol.constraint_name -inner join information_schema.key_column_usage refcol on ref.table_name = refcol.table_name and ref.constraint_name = refcol.constraint_name and basecol.ordinal_position = refcol.ordinal_position -where - base.table_schema <> 'information_schema' - and base.table_schema <> 'pg_catalog' - and base.table_schema !~ '^pg_toast' - and 'tables:' || base.table_schema || '.' || base.table_name =OBJECT_ID_CONDITION -order by basecol.ordinal_position -`; diff --git a/packages/engines/postgres/sql/index.js b/packages/engines/postgres/sql/index.js deleted file mode 100644 index 7cc2141e9..000000000 --- a/packages/engines/postgres/sql/index.js +++ /dev/null @@ -1,19 +0,0 @@ -const columns = require('./columns'); -const tableModifications = require('./tableModifications'); -const viewModifications = require('./viewModifications'); -const primaryKeys = require('./primaryKeys'); -const foreignKeys = require('./foreignKeys'); -const views = require('./views'); -const routines = require('./routines'); -const routineModifications = require('./routineModifications'); - -module.exports = { - columns, - tableModifications, - viewModifications, - primaryKeys, - foreignKeys, - views, - routines, - routineModifications, -}; diff --git a/packages/engines/postgres/sql/primaryKeys.js b/packages/engines/postgres/sql/primaryKeys.js deleted file mode 100644 index 204ff8478..000000000 --- a/packages/engines/postgres/sql/primaryKeys.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = ` -select - table_constraints.constraint_schema as "constraintSchema", - table_constraints.constraint_name as "constraintName", - table_constraints.table_schema as "schemaName", - table_constraints.table_name as "pureName", - key_column_usage.column_name as "columnName" -from information_schema.table_constraints -inner join information_schema.key_column_usage on table_constraints.table_name = key_column_usage.table_name and table_constraints.constraint_name = key_column_usage.constraint_name -where - table_constraints.table_schema <> 'information_schema' - and table_constraints.table_schema <> 'pg_catalog' - and table_constraints.table_schema !~ '^pg_toast' - and table_constraints.constraint_type = 'PRIMARY KEY' - and 'tables:' || table_constraints.table_schema || '.' || table_constraints.table_name =OBJECT_ID_CONDITION -order by key_column_usage.ordinal_position -`; diff --git a/packages/engines/postgres/sql/routineModifications.js b/packages/engines/postgres/sql/routineModifications.js deleted file mode 100644 index 879a1195c..000000000 --- a/packages/engines/postgres/sql/routineModifications.js +++ /dev/null @@ -1,10 +0,0 @@ -module.exports = ` -select - routine_name as "pureName", - routine_schema as "schemaName", - md5(routine_definition) as "hashCode", - routine_type as "objectType" -from - information_schema.routines where routine_schema != 'information_schema' and routine_schema != 'pg_catalog' - and routine_type in ('PROCEDURE', 'FUNCTION') -`; diff --git a/packages/engines/postgres/sql/routines.js b/packages/engines/postgres/sql/routines.js deleted file mode 100644 index 80c189604..000000000 --- a/packages/engines/postgres/sql/routines.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = ` -select - routine_name as "pureName", - routine_schema as "schemaName", - routine_definition as "createSql", - md5(routine_definition) as "hashCode", - routine_type as "objectType" -from - information_schema.routines where routine_schema != 'information_schema' and routine_schema != 'pg_catalog' - and ( - (routine_type = 'PROCEDURE' and ('procedures:' || routine_schema || '.' || routine_schema) =OBJECT_ID_CONDITION) - or - (routine_type = 'FUNCTION' and ('functions:' || routine_schema || '.' || routine_schema) =OBJECT_ID_CONDITION) - ) -`; diff --git a/packages/engines/postgres/sql/tableModifications.js b/packages/engines/postgres/sql/tableModifications.js deleted file mode 100644 index b34bf292b..000000000 --- a/packages/engines/postgres/sql/tableModifications.js +++ /dev/null @@ -1,52 +0,0 @@ -module.exports = ` -with pkey as -( - select cc.conrelid, format(E'create constraint %I primary key(%s);\\n', cc.conname, - string_agg(a.attname, ', ' - order by array_position(cc.conkey, a.attnum))) pkey - from pg_catalog.pg_constraint cc - join pg_catalog.pg_class c on c.oid = cc.conrelid - join pg_catalog.pg_attribute a on a.attrelid = cc.conrelid - and a.attnum = any(cc.conkey) - where cc.contype = 'p' - group by cc.conrelid, cc.conname -) - - -SELECT oid as "objectId", nspname as "schemaName", relname as "pureName", - md5('CREATE TABLE ' || nspname || '.' || relname || E'\\n(\\n' || - array_to_string( - array_agg( - ' ' || column_name || ' ' || type || ' '|| not_null - ) - , E',\\n' - ) || E'\\n);\\n' || coalesce((select pkey from pkey where pkey.conrelid = oid),'NO_PK')) as "hashCode" -from -( - SELECT - c.relname, a.attname AS column_name, c.oid, - n.nspname, - pg_catalog.format_type(a.atttypid, a.atttypmod) as type, - case - when a.attnotnull - then 'NOT NULL' - else 'NULL' - END as not_null - FROM pg_class c, - pg_namespace n, - pg_attribute a, - pg_type t - - WHERE c.relkind = 'r' - AND a.attnum > 0 - AND a.attrelid = c.oid - AND a.atttypid = t.oid - AND n.oid = c.relnamespace - AND n.nspname <> 'pg_catalog' - AND n.nspname <> 'information_schema' - AND n.nspname !~ '^pg_toast' - ORDER BY a.attnum -) as tabledefinition -where ('tables:' || nspname || '.' || relname) =OBJECT_ID_CONDITION -group by relname, nspname, oid -`; diff --git a/packages/engines/postgres/sql/viewModifications.js b/packages/engines/postgres/sql/viewModifications.js deleted file mode 100644 index a74c01a3f..000000000 --- a/packages/engines/postgres/sql/viewModifications.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = ` -select - table_name as "pureName", - table_schema as "schemaName", - md5(view_definition) as "hashCode" -from - information_schema.views where table_schema != 'information_schema' and table_schema != 'pg_catalog' -`; diff --git a/packages/engines/postgres/sql/views.js b/packages/engines/postgres/sql/views.js deleted file mode 100644 index 8d18ee557..000000000 --- a/packages/engines/postgres/sql/views.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = ` -select - table_name as "pureName", - table_schema as "schemaName", - view_definition as "createSql", - md5(view_definition) as "hashCode" -from - information_schema.views -where table_schema != 'information_schema' and table_schema != 'pg_catalog' - and ('views:' || table_schema || '.' || table_name) =OBJECT_ID_CONDITION -`; diff --git a/packages/engines/tsconfig.json b/packages/engines/tsconfig.json deleted file mode 100644 index bdf53cd0f..000000000 --- a/packages/engines/tsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "allowJs": true, - "checkJs": true, - "noEmit": true, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true, - "moduleResolution": "node", - "lib": [ - "dom", - "dom.iterable", - "esnext" - ], - }, - "include": [ - "." - ] -} diff --git a/packages/web/package.json b/packages/web/package.json index 013441840..2d53268ce 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -12,7 +12,6 @@ "axios": "^0.19.0", "cross-env": "^6.0.3", "dbgate-datalib": "^1.0.0", - "dbgate-engines": "^1.0.0", "dbgate-sqltree": "^1.0.0", "dbgate-tools": "^1.0.0", "eslint": "^6.8.0", From 3533683a324c3692bd31ab905a35d9c642accb79 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 26 Nov 2020 15:42:50 +0100 Subject: [PATCH 26/30] fied require problem in webpacked app --- packages/api/.eslintrc.js | 21 -- packages/api/src/shell/requirePlugin.js | 12 +- packages/api/webpack.config.js | 8 +- packages/filterparser/src/cli.ts | 17 -- yarn.lock | 370 +----------------------- 5 files changed, 28 insertions(+), 400 deletions(-) delete mode 100644 packages/api/.eslintrc.js delete mode 100644 packages/filterparser/src/cli.ts diff --git a/packages/api/.eslintrc.js b/packages/api/.eslintrc.js deleted file mode 100644 index a0427ca1b..000000000 --- a/packages/api/.eslintrc.js +++ /dev/null @@ -1,21 +0,0 @@ -module.exports = { - env: { - node: true, - commonjs: true, - es6: true, - jquery: false, - jest: true, - jasmine: true, - }, - extends: 'eslint:recommended', - globals: { - Atomics: 'readonly', - SharedArrayBuffer: 'readonly', - }, - parserOptions: { - ecmaVersion: 2018, - }, - rules: { - 'no-unused-vars': 'warn', - }, -}; diff --git a/packages/api/src/shell/requirePlugin.js b/packages/api/src/shell/requirePlugin.js index 910c42ca1..eb8b3f537 100644 --- a/packages/api/src/shell/requirePlugin.js +++ b/packages/api/src/shell/requirePlugin.js @@ -12,8 +12,16 @@ function requirePlugin(packageName, requiredPlugin = null) { if (loadedPlugins[packageName]) return loadedPlugins[packageName]; if (requiredPlugin == null) { - console.log('Loading module', packageName); - const module = require(path.join(pluginsdir(), packageName, 'dist', 'backend.js')); + let module; + const modulePath = path.join(pluginsdir(), packageName, 'dist', 'backend.js'); + console.log(`Loading module ${packageName} from ${modulePath}`); + try { + // @ts-ignore + module = __non_webpack_require__(modulePath); + } catch (err) { + console.error('Failed load webpacked module', err); + module = require(modulePath); + } requiredPlugin = module.__esModule ? module.default : module; } loadedPlugins[packageName] = requiredPlugin; diff --git a/packages/api/webpack.config.js b/packages/api/webpack.config.js index ccb4ff33e..d2f383753 100644 --- a/packages/api/webpack.config.js +++ b/packages/api/webpack.config.js @@ -14,9 +14,9 @@ var config = { libraryTarget: 'commonjs2', }, - optimization: { - minimize: false, - }, + // optimization: { + // minimize: false, + // }, // module: { // rules: [ @@ -29,7 +29,7 @@ var config = { plugins: [ new webpack.IgnorePlugin({ checkResource(resource) { - const lazyImports = ['pg-native', 'uws']; + const lazyImports = ['uws']; if (!lazyImports.includes(resource)) { return false; } diff --git a/packages/filterparser/src/cli.ts b/packages/filterparser/src/cli.ts deleted file mode 100644 index 5cee1d064..000000000 --- a/packages/filterparser/src/cli.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { parseFilter } from './parseFilter'; -import { FilterType } from './types'; -import engines from 'dbgate-engines'; -import { dumpSqlCondition, treeToSql } from 'dbgate-sqltree'; - -const ast = parseFilter(process.argv[2], process.argv[3] as FilterType); - -console.log(JSON.stringify(ast, null, ' ')); - -console.log('***************** MS SQL ******************'); -console.log(treeToSql(engines('mssql'), ast, dumpSqlCondition)); - -console.log('***************** MySql *******************'); -console.log(treeToSql(engines('mysql'), ast, dumpSqlCondition)); - -console.log('***************** Postgre *****************'); -console.log(treeToSql(engines('postgres'), ast, dumpSqlCondition)); diff --git a/yarn.lock b/yarn.lock index 6ccb69bd8..877824266 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,34 +9,6 @@ dependencies: "@ctrl/tinycolor" "^3.1.6" -"@azure/ms-rest-azure-env@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@azure/ms-rest-azure-env/-/ms-rest-azure-env-1.1.2.tgz#8505873afd4a1227ec040894a64fdd736b4a101f" - integrity sha512-l7z0DPCi2Hp88w12JhDTtx5d0Y3+vhfE7JKJb9O7sEz71Cwp053N8piTtTnnk/tUor9oZHgEKi/p3tQQmLPjvA== - -"@azure/ms-rest-js@^1.8.7": - version "1.8.14" - resolved "https://registry.yarnpkg.com/@azure/ms-rest-js/-/ms-rest-js-1.8.14.tgz#657fc145db20b6eb3d58d1a2055473aa72eb609d" - integrity sha512-IrCPN22c8RbKWA06ZXuFwwEb15cSnr0zZ6J8Fspp9ns1SSNTERf7hv+gWvTIis1FlwHy42Mfk8hVu0/r3a0AWA== - dependencies: - "@types/tunnel" "0.0.0" - axios "^0.19.0" - form-data "^2.3.2" - tough-cookie "^2.4.3" - tslib "^1.9.2" - tunnel "0.0.6" - uuid "^3.2.1" - xml2js "^0.4.19" - -"@azure/ms-rest-nodeauth@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@azure/ms-rest-nodeauth/-/ms-rest-nodeauth-2.0.2.tgz#037e29540c5625eaec718b8fcc178dd7ad5dfb96" - integrity sha512-KmNNICOxt3EwViAJI3iu2VH8t8BQg5J2rSAyO4IUYLF9ZwlyYsP419pdvl4NBUhluAP2cgN7dfD2V6E6NOMZlQ== - dependencies: - "@azure/ms-rest-azure-env" "^1.1.2" - "@azure/ms-rest-js" "^1.8.7" - adal-node "^0.1.28" - "@babel/code-frame@7.8.3", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" @@ -1601,21 +1573,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.0.tgz#b417deda18cf8400f278733499ad5547ed1abec4" integrity sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ== -"@types/node@^12.12.17": - version "12.12.26" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.26.tgz#213e153babac0ed169d44a6d919501e68f59dea9" - integrity sha512-UmUm94/QZvU5xLcUlNR8hA7Ac+fGpO1EG/a8bcWVz0P0LqtxFmun9Y2bbtuckwGboWJIT70DoWq1r3hb56n3DA== - "@types/node@^13.7.0": version "13.7.7" resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.7.tgz#1628e6461ba8cc9b53196dfeaeec7b07fa6eea99" integrity sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg== -"@types/node@^8.0.47": - version "8.10.59" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.59.tgz#9e34261f30183f9777017a13d185dfac6b899e04" - integrity sha512-8RkBivJrDCyPpBXhVZcjh7cQxVBSmRk9QM7hOketZzp6Tg79c0N8kkpAIito9bnJ3HCVCHVYz+KHTEbfQNfeVQ== - "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" @@ -1658,14 +1620,6 @@ "@types/prop-types" "*" csstype "^2.2.0" -"@types/readable-stream@^2.3.5": - version "2.3.5" - resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.5.tgz#99c215f9c78563ebdfeff400246a724fb36bae4a" - integrity sha512-Mq2eLkGYamlcolW603FY2ROBvcl90jPF+3jLkjpBV6qS+2aVeJqlgRG0TVAa1oWbmPdb5yOWlOPVvQle76nUNw== - dependencies: - "@types/node" "*" - safe-buffer "*" - "@types/stack-utils@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" @@ -1696,13 +1650,6 @@ "@types/react-dom" "*" "@types/testing-library__dom" "*" -"@types/tunnel@0.0.0": - version "0.0.0" - resolved "https://registry.yarnpkg.com/@types/tunnel/-/tunnel-0.0.0.tgz#c2a42943ee63c90652a5557b8c4e56cda77f944e" - integrity sha512-FGDp0iBRiBdPjOgjJmn1NH0KDLN+Z8fRmo+9J7XGBhubq1DPrGrbmG4UTlGzrpbCpesMqD0sWkzi27EYkOMHyg== - dependencies: - "@types/node" "*" - "@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": version "2.0.3" resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.3.tgz#9c088679876f374eb5983f150d4787aa6fb32d7e" @@ -1987,21 +1934,6 @@ acorn@^7.1.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.0.tgz#949d36f2c292535da602283586c2477c57eb2d6c" integrity sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ== -adal-node@^0.1.28: - version "0.1.28" - resolved "https://registry.yarnpkg.com/adal-node/-/adal-node-0.1.28.tgz#468c4bb3ebbd96b1270669f4b9cba4e0065ea485" - integrity sha1-RoxLs+u9lrEnBmn0ucuk4AZepIU= - dependencies: - "@types/node" "^8.0.47" - async ">=0.6.0" - date-utils "*" - jws "3.x.x" - request ">= 2.52.0" - underscore ">= 1.3.1" - uuid "^3.1.0" - xmldom ">= 0.1.x" - xpath.js "~1.1.0" - address@1.1.2, address@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" @@ -2342,11 +2274,6 @@ async@0.2.10: resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E= -async@>=0.6.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/async/-/async-3.1.1.tgz#dd3542db03de837979c9ebbca64ca01b06dc98df" - integrity sha512-X5Dj8hK1pJNC2Wzo2Rcp9FBVdJMGRR/S7V+lH46s8GVFhtbo5O4Le5GECCF/8PISVdkUA6mMPvgz7qTTD1rf1g== - async@^2.6.2: version "2.6.3" resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" @@ -2664,11 +2591,6 @@ big.js@^5.2.2: resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== -bignumber.js@9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" - integrity sha512-t/OYhhJ2SD+YGBQcjY8GzzDHEk9f3nerxjtfa6tlMXfe7frs/WozhvCNoGvpM0P3bNf3Gq5ZRMlGr5f3r4/N8A== - binary-extensions@^1.0.0: version "1.13.1" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" @@ -2693,13 +2615,6 @@ bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" -bl@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-3.0.0.tgz#3611ec00579fd18561754360b21e9f784500ff88" - integrity sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A== - dependencies: - readable-stream "^3.0.1" - blob@0.0.5: version "0.0.5" resolved "https://registry.yarnpkg.com/blob/-/blob-0.0.5.tgz#d680eeef25f8cd91ad533f5b01eed48e64caf683" @@ -2891,11 +2806,6 @@ bser@2.1.1: dependencies: node-int64 "^0.4.0" -buffer-equal-constant-time@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" - integrity sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk= - buffer-from@1.x, buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -2906,11 +2816,6 @@ buffer-indexof@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== -buffer-writer@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" - integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw== - buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -4070,11 +3975,6 @@ date-fns@^2.0.1: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.9.0.tgz#d0b175a5c37ed5f17b97e2272bbc1fa5aec677d2" integrity sha512-khbFLu/MlzLjEzy9Gh8oY1hNt/Dvxw3J6Rbc28cVoYWQaC1S3YI4xwkF9ZWcjDLscbZlY9hISMr66RFzZagLsA== -date-utils@*: - version "1.2.21" - resolved "https://registry.yarnpkg.com/date-utils/-/date-utils-1.2.21.tgz#61fb16cdc1274b3c9acaaffe9fc69df8720a2b64" - integrity sha1-YfsWzcEnSzyayq/+n8ad+HIKK2Q= - debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" @@ -4103,7 +4003,7 @@ debug@^3.0.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6: dependencies: ms "^2.1.1" -debug@^4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0: +debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== @@ -4217,11 +4117,6 @@ depd@^1.1.2, depd@~1.1.2: resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= -depd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - des.js@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" @@ -4485,13 +4380,6 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" -ecdsa-sig-formatter@1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" - integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== - dependencies: - safe-buffer "^5.0.1" - ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -5471,15 +5359,6 @@ fork-ts-checker-webpack-plugin@3.1.1: tapable "^1.0.0" worker-rpc "^0.1.0" -form-data@^2.3.2: - version "2.5.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" - integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - 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" @@ -6193,13 +6072,6 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.5.1.tgz#b2425d3c7b18f7219f2ca663d103bddb91718d64" - integrity sha512-ONHr16SQvKZNSqjQT9gy5z24Jw+uqfO02/ngBSBoqChZ+W8qXX7GPRa1RoUnzGADw8K63R1BXUMzarCVQBpY8Q== - dependencies: - safer-buffer ">= 2.1.2 < 3" - iconv-lite@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01" @@ -7302,11 +7174,6 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -jsbi@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/jsbi/-/jsbi-3.1.1.tgz#8ea18b3e08d102c6cc09acaa9a099921d775f4fa" - integrity sha512-+HQESPaV0mRiH614z4JPVPAftcRC2p53x92lySPzUzFwJbJTMpzHz8OYUkcXPN3fOcHUe0NdVcHnCtX/1+eCrA== - jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -7477,23 +7344,6 @@ jsx-ast-utils@^2.2.1, jsx-ast-utils@^2.2.3: array-includes "^3.0.3" object.assign "^4.1.0" -jwa@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" - integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== - dependencies: - buffer-equal-constant-time "1.0.1" - ecdsa-sig-formatter "1.0.11" - safe-buffer "^5.0.1" - -jws@3.x.x: - version "3.2.2" - resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" - integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== - dependencies: - jwa "^1.4.1" - safe-buffer "^5.0.1" - killable@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" @@ -8242,15 +8092,6 @@ ms@2.1.2, ms@^2.0.0, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -mssql@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/mssql/-/mssql-6.0.1.tgz#3aab69b7c19dd1b304495f27b748535d0110b477" - integrity sha512-7oPhbQjotFJBgMPlzLmPwWlnrryxrDltjCNCD9BK7Df7TA9wc6Mb/0Bcx04NJyHCMAhw8C/iWjbJoeDyUfRNUA== - dependencies: - debug "^4" - tarn "^1.1.5" - tedious "^6.6.2" - multicast-dns-service-types@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" @@ -8269,16 +8110,6 @@ mute-stream@0.0.8: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== -mysql@^2.17.1: - version "2.18.1" - resolved "https://registry.yarnpkg.com/mysql/-/mysql-2.18.1.tgz#2254143855c5a8c73825e4522baf2ea021766717" - integrity sha512-Bca+gk2YWmqp2Uf6k5NFEurwY/0td0cpebAucFpY/3jhrwrVGuxU2uQFCHjU19SJfje0yQvi+rVWdq78hR5lig== - dependencies: - bignumber.js "9.0.0" - readable-stream "2.3.7" - safe-buffer "5.1.2" - sqlstring "2.3.1" - nan@^2.12.1: version "2.14.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" @@ -8301,11 +8132,6 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" -native-duplexpair@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/native-duplexpair/-/native-duplexpair-1.0.0.tgz#7899078e64bf3c8a3d732601b3d40ff05db58fa0" - integrity sha1-eJkHjmS/PIo9cyYBs9QP8F21j6A= - natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -8942,11 +8768,6 @@ package-json@^4.0.0: registry-url "^3.0.3" semver "^5.1.0" -packet-reader@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74" - integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== - pacote@^11.1.13: version "11.1.13" resolved "https://registry.yarnpkg.com/pacote/-/pacote-11.1.13.tgz#7e85213693b0b4b1119c4026dc1b68c087641dc2" @@ -9203,70 +9024,6 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -pg-connection-string@0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-0.1.3.tgz#da1847b20940e42ee1492beaf65d49d91b245df7" - integrity sha1-2hhHsglA5C7hSSvq9l1J2RskXfc= - -pg-cursor@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/pg-cursor/-/pg-cursor-2.2.1.tgz#f0f35f9e729889d795c8191141a6b15c5f8b18a7" - integrity sha512-C0DKcb8do7Mv9tTQvrB+hxPYgJ6FCKnu1CjPMb0txYHW+zULpOH0B01MNtjQA4nrhHJ4Qs1Nf58BGEc158wXIA== - -pg-int8@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" - integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== - -pg-packet-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pg-packet-stream/-/pg-packet-stream-1.1.0.tgz#e45c3ae678b901a2873af1e17b92d787962ef914" - integrity sha512-kRBH0tDIW/8lfnnOyTwKD23ygJ/kexQVXZs7gEyBljw4FYqimZFxnMMx50ndZ8In77QgfGuItS5LLclC2TtjYg== - -pg-pool@^2.0.10: - version "2.0.10" - resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-2.0.10.tgz#842ee23b04e86824ce9d786430f8365082d81c4a" - integrity sha512-qdwzY92bHf3nwzIUcj+zJ0Qo5lpG/YxchahxIN8+ZVmXqkahKXsnl2aiJPHLYN9o5mB/leG+Xh6XKxtP7e0sjg== - -pg-query-stream@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/pg-query-stream/-/pg-query-stream-3.1.1.tgz#f73c5d5252dd0728bbf7f67e53c1ac09713ea245" - integrity sha512-jkIgIzBPWEHqePfA5dKbjsN9dCFIlGnLQ3pEIhU10OhgyOmi0CuP8cGLNgCbCnbbtZEaSuyCAYpe/rtwYMoL9w== - dependencies: - pg-cursor "^2.2.1" - -pg-types@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" - integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== - dependencies: - pg-int8 "1.0.1" - postgres-array "~2.0.0" - postgres-bytea "~1.0.0" - postgres-date "~1.0.4" - postgres-interval "^1.1.0" - -pg@^7.17.0: - version "7.18.1" - resolved "https://registry.yarnpkg.com/pg/-/pg-7.18.1.tgz#67f59c47a99456fcb34f9fe53662b79d4a992f6d" - integrity sha512-1KtKBKg/zWrjEEv//klBbVOPGucuc7HHeJf6OEMueVcUeyF3yueHf+DvhVwBjIAe9/97RAydO/lWjkcMwssuEw== - dependencies: - buffer-writer "2.0.0" - packet-reader "1.0.0" - pg-connection-string "0.1.3" - pg-packet-stream "^1.1.0" - pg-pool "^2.0.10" - pg-types "^2.1.0" - pgpass "1.x" - semver "4.3.2" - -pgpass@1.x: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.2.tgz#2a7bb41b6065b67907e91da1b07c1847c877b306" - integrity sha1-Knu0G2BltnkH6R2hsHwYR8h3swY= - dependencies: - split "^1.0.0" - picomatch@^2.0.4, picomatch@^2.0.7: version "2.2.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.1.tgz#21bac888b6ed8601f831ce7816e335bc779f0a4a" @@ -10029,28 +9786,6 @@ postcss@^7, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.16, po source-map "^0.6.1" supports-color "^6.1.0" -postgres-array@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" - integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== - -postgres-bytea@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" - integrity sha1-AntTPAqokOJtFy1Hz5zOzFIazTU= - -postgres-date@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.4.tgz#1c2728d62ef1bff49abdd35c1f86d4bdf118a728" - integrity sha512-bESRvKVuTrjoBluEcpv2346+6kgB7UlnqWZsnbnCccTNq/pqfj1j6oBaN5+b/NrDXepYUT/HKadqv3iS9lJuVA== - -postgres-interval@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" - integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== - dependencies: - xtend "^4.0.0" - prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -10664,7 +10399,7 @@ read-pkg@^4.0.1: parse-json "^4.0.0" pify "^3.0.0" -"readable-stream@1 || 2", readable-stream@2.3.7, readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -10677,7 +10412,7 @@ read-pkg@^4.0.1: string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.1, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0: +readable-stream@^3.0.6, readable-stream@^3.1.1: version "3.5.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.5.0.tgz#465d70e6d1087f6162d079cd0b5db7fbebfd1606" integrity sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA== @@ -10907,7 +10642,7 @@ request-promise-native@^1.0.5: stealthy-require "^1.1.1" tough-cookie "^2.3.3" -"request@>= 2.52.0", request@^2.87.0, request@^2.88.0: +request@^2.87.0, request@^2.88.0: version "2.88.0" resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg== @@ -11157,16 +10892,16 @@ rxjs@^6.5.2, rxjs@^6.5.3: dependencies: tslib "^1.9.0" -safe-buffer@*, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" - integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== - safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" + integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== + safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -11210,7 +10945,7 @@ sass-loader@8.0.0: schema-utils "^2.1.0" semver "^6.3.0" -sax@>=0.6.0, sax@^1.2.4, sax@~1.2.4: +sax@^1.2.4, 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== @@ -11271,11 +11006,6 @@ semver-diff@^2.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.2.tgz#c7a07158a80bedd052355b770d82d6640f803be7" - integrity sha1-x6BxWKgL7dBSNVt3DYLWZA+AO+c= - semver@6.3.0, semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -11710,18 +11440,6 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" -split@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" - integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== - dependencies: - through "2" - -sprintf-js@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" - integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== - sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -11734,11 +11452,6 @@ sql-formatter@^2.3.3: dependencies: lodash "^4.16.0" -sqlstring@2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/sqlstring/-/sqlstring-2.3.1.tgz#475393ff9e91479aea62dcaf0ca3d14983a7fb40" - integrity sha1-R1OT/56RR5rqYtyvDKPRSYOn+0A= - sshpk@^1.7.0: version "1.16.1" resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" @@ -12144,28 +11857,6 @@ tar@^6.0.1, tar@^6.0.2: mkdirp "^1.0.3" yallist "^4.0.0" -tarn@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/tarn/-/tarn-1.1.5.tgz#7be88622e951738b9fa3fb77477309242cdddc2d" - integrity sha512-PMtJ3HCLAZeedWjJPgGnCvcphbCOMbtZpjKgLq3qM5Qq9aQud+XHrL0WlrlgnTyS8U+jrjGbEXprFcQrxPy52g== - -tedious@^6.6.2: - version "6.7.0" - resolved "https://registry.yarnpkg.com/tedious/-/tedious-6.7.0.tgz#ad02365f16f9e0416b216e13d3f83c53addd42ca" - integrity sha512-8qr7+sB0h4SZVQBRWUgHmYuOEflAOl2eihvxk0fVNvpvGJV4V5UC/YmSvebyfgyfwWcPO22/AnSbYVZZqf9wuQ== - dependencies: - "@azure/ms-rest-nodeauth" "2.0.2" - "@types/node" "^12.12.17" - "@types/readable-stream" "^2.3.5" - bl "^3.0.0" - depd "^2.0.0" - iconv-lite "^0.5.0" - jsbi "^3.1.1" - native-duplexpair "^1.0.0" - punycode "^2.1.0" - readable-stream "^3.4.0" - sprintf-js "^1.1.2" - term-size@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" @@ -12239,7 +11930,7 @@ through2@^2.0.0, through2@^2.0.1: readable-stream "~2.3.6" xtend "~4.0.1" -through@2, through@^2.3.6: +through@^2.3.6: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -12342,7 +12033,7 @@ touch@^3.1.0: dependencies: nopt "~1.0.10" -tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.4.3, tough-cookie@^2.5.0, tough-cookie@~2.5.0: +tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.5.0, tough-cookie@~2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== @@ -12396,7 +12087,7 @@ ts-pnp@1.1.5, ts-pnp@^1.1.2: resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.1.5.tgz#840e0739c89fce5f3abd9037bb091dbff16d9dec" integrity sha512-ti7OGMOUOzo66wLF3liskw6YQIaSsBgc4GOAlWRnIEj8htCxJUxskanMUoJOD6MDCRAXo36goXJZch+nOS0VMA== -tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.2: +tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0: version "1.10.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== @@ -12425,11 +12116,6 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -tunnel@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" - integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== - tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" @@ -12495,11 +12181,6 @@ undefsafe@^2.0.2: dependencies: debug "^2.2.0" -"underscore@>= 1.3.1": - version "1.9.2" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.9.2.tgz#0c8d6f536d6f378a5af264a72f7bec50feb7cf2f" - integrity sha512-D39qtimx0c1fI3ya1Lnhk3E9nONswSKhnffBI0gME9C99fYOkNi04xs8K6pePLhvl1frbDemkaBQ5ikWllR2HQ== - underscore@~1.4.4: version "1.4.4" resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604" @@ -12765,7 +12446,7 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@^3.0.1, uuid@^3.1.0, uuid@^3.2.1, uuid@^3.3.2, uuid@^3.4.0: +uuid@^3.0.1, uuid@^3.3.2, uuid@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== @@ -13369,39 +13050,16 @@ xml-name-validator@^3.0.0: resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== -xml2js@^0.4.19: - version "0.4.23" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" - integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== - dependencies: - sax ">=0.6.0" - xmlbuilder "~11.0.0" - -xmlbuilder@~11.0.0: - version "11.0.1" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" - integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== - xmlchars@^2.1.1: version "2.2.0" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== -"xmldom@>= 0.1.x": - version "0.2.1" - resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.2.1.tgz#cac9465066f161e1c3302793ea4dbe59c518274f" - integrity sha512-kXXiYvmblIgEemGeB75y97FyaZavx6SQhGppLw5TKWAD2Wd0KAly0g23eVLh17YcpxZpnFym1Qk/eaRjy1APPg== - xmlhttprequest-ssl@~1.5.4: version "1.5.5" resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" integrity sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4= -xpath.js@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/xpath.js/-/xpath.js-1.1.0.tgz#3816a44ed4bb352091083d002a383dd5104a5ff1" - integrity sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ== - xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" From 6729317fcb5c19992212f59d3e765828d79c7498 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Thu, 26 Nov 2020 17:24:30 +0100 Subject: [PATCH 27/30] remove pacote - blocks webpack build --- packages/api/package.json | 4 +- packages/api/src/controllers/plugins.js | 18 +- packages/api/src/utility/downloadPackage.js | 64 +++ yarn.lock | 607 +------------------- 4 files changed, 98 insertions(+), 595 deletions(-) create mode 100644 packages/api/src/utility/downloadPackage.js diff --git a/packages/api/package.json b/packages/api/package.json index a4cfe1712..352a0bd80 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -36,9 +36,9 @@ "http": "^0.0.0", "line-reader": "^0.4.0", "lodash": "^4.17.15", + "ncp": "^2.0.0", "nedb-promises": "^4.0.1", - "node-fetch": "^2.6.1", - "pacote": "^11.1.13" + "tar": "^6.0.5" }, "scripts": { "start": "nodemon src/index.js", diff --git a/packages/api/src/controllers/plugins.js b/packages/api/src/controllers/plugins.js index 5b4d95bb0..6d579c69f 100644 --- a/packages/api/src/controllers/plugins.js +++ b/packages/api/src/controllers/plugins.js @@ -1,10 +1,10 @@ const fs = require('fs-extra'); -const fetch = require('node-fetch'); +const axios = require('axios'); const path = require('path'); -const pacote = require('pacote'); const { pluginstmpdir, pluginsdir } = require('../utility/directories'); const socket = require('../utility/socket'); const requirePlugin = require('../shell/requirePlugin'); +const downloadPackage = require('../utility/downloadPackage'); async function loadPackageInfo(dir) { const readmeFile = path.join(dir, 'README.md'); @@ -36,17 +36,11 @@ module.exports = { search_meta: 'get', async search({ filter }) { - // const response = await fetch(`https://api.npms.io/v2/search?q=keywords:dbgate ${encodeURIComponent(filter)}`); - // const json = await response.json(); - // const { results } = json || {}; - // return (results || []).map((x) => x.package); - // DOCS: https://github.com/npm/registry/blob/master/docs/REGISTRY-API.md#get-v1search - const response = await fetch( + const resp = await axios.default.get( `http://registry.npmjs.com/-/v1/search?text=${encodeURIComponent(filter)}+keywords:dbgateplugin&size=25&from=0` ); - const json = await response.json(); - const { objects } = json || {}; + const { objects } = resp.data || {}; return (objects || []).map((x) => x.package); }, @@ -54,7 +48,7 @@ module.exports = { async info({ packageName }) { const dir = path.join(pluginstmpdir(), packageName); if (!(await fs.exists(dir))) { - await pacote.extract(packageName, dir); + await downloadPackage(packageName, dir); } return await loadPackageInfo(dir); // return await { @@ -77,7 +71,7 @@ module.exports = { async install({ packageName }) { const dir = path.join(pluginsdir(), packageName); if (!(await fs.exists(dir))) { - await pacote.extract(packageName, dir); + await downloadPackage(packageName, dir); } socket.emitChanged(`installed-plugins-changed`); }, diff --git a/packages/api/src/utility/downloadPackage.js b/packages/api/src/utility/downloadPackage.js new file mode 100644 index 000000000..37a5ea661 --- /dev/null +++ b/packages/api/src/utility/downloadPackage.js @@ -0,0 +1,64 @@ +// const pacote = require('pacote'); +const axios = require('axios'); +// const tarballExtract = require('tarball-extract'); +const uuidv1 = require('uuid/v1'); +const path = require('path'); +const fs = require('fs'); +const zlib = require('zlib'); +const tar = require('tar'); +const ncp = require('ncp').ncp; +const { uploadsdir } = require('./directories'); + +function extractTarball(tmpFile, destination) { + return new Promise((resolve, reject) => { + fs.createReadStream(tmpFile) + .pipe(zlib.createGunzip()) + .pipe(tar.extract({ cwd: destination })) + .on('error', (err) => reject(err)) + .on('end', () => resolve()); + }); +} + +function saveStreamToFile(pipedStream, fileName) { + return new Promise((resolve, reject) => { + const fileStream = fs.createWriteStream(fileName); + fileStream.on('close', () => resolve()); + pipedStream.pipe(fileStream); + }); +} + +function copyDirectory(source, target) { + return new Promise((resolve, reject) => { + ncp(source, target, (err) => { + if (err) reject(err); + resolve(); + }); + }); +} + +async function downloadPackage(packageName, directory) { + // await pacote.extract(packageName, directory); + const infoResp = await axios.default.get(`https://registry.npmjs.org/${packageName}`); + + const { latest } = infoResp.data['dist-tags'] || {}; + if (!latest) return false; + + const tarball = infoResp.data.versions[latest].dist.tarball; + + const tmpFile = path.join(uploadsdir(), uuidv1() + '.tgz'); + console.log(`Downloading tarball ${tarball} into ${tmpFile}`); + const tarballResp = await axios.default({ + method: 'get', + url: tarball, + responseType: 'stream', + }); + await saveStreamToFile(tarballResp.data, tmpFile); + const tmpDir = path.join(uploadsdir(), uuidv1()); + fs.mkdirSync(tmpDir); + await extractTarball(tmpFile, tmpDir); + await copyDirectory(path.join(tmpDir, 'package'), directory); + + return true; +} + +module.exports = downloadPackage; diff --git a/yarn.lock b/yarn.lock index 877824266..7fffe40e6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1238,67 +1238,6 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== -"@npmcli/ci-detect@^1.0.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@npmcli/ci-detect/-/ci-detect-1.3.0.tgz#6c1d2c625fb6ef1b9dea85ad0a5afcbef85ef22a" - integrity sha512-oN3y7FAROHhrAt7Rr7PnTSwrHrZVRTS2ZbyxeQwSSYD0ifwM3YNgQqbaRmjcWoPyq77MjchusjJDspbzMmip1Q== - -"@npmcli/git@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-2.0.4.tgz#725f5e32864f3849420e84baf130e426a707cbb7" - integrity sha512-OJZCmJ9DNn1cz9HPXXsPmUBnqaArot3CGYo63CyajHQk+g87rPXVOJByGsskQJhPsUUEXJcsZ2Q6bWd2jSwnBA== - dependencies: - "@npmcli/promise-spawn" "^1.1.0" - lru-cache "^6.0.0" - mkdirp "^1.0.3" - npm-pick-manifest "^6.0.0" - promise-inflight "^1.0.1" - promise-retry "^1.1.1" - semver "^7.3.2" - unique-filename "^1.1.1" - which "^2.0.2" - -"@npmcli/installed-package-contents@^1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-1.0.5.tgz#cc78565e55d9f14d46acf46a96f70934e516fa3d" - integrity sha512-aKIwguaaqb6ViwSOFytniGvLPb9SMCUm39TgM3SfUo7n0TxUMbwoXfpwyvQ4blm10lzbAwTsvjr7QZ85LvTi4A== - dependencies: - npm-bundled "^1.1.1" - npm-normalize-package-bin "^1.0.1" - read-package-json-fast "^1.1.1" - readdir-scoped-modules "^1.1.0" - -"@npmcli/move-file@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.0.1.tgz#de103070dac0f48ce49cf6693c23af59c0f70464" - integrity sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw== - dependencies: - mkdirp "^1.0.4" - -"@npmcli/node-gyp@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-1.0.1.tgz#dedc4ea9b3c6ef207081ebcd82c053ef60edc478" - integrity sha512-pBqoKPWmuk9iaEcXlLBVRIA6I1kG9JiICU+sG0NuD6NAR461F+02elHJS4WkQxHW2W5rnsfvP/ClKwmsZ9RaaA== - -"@npmcli/promise-spawn@^1.1.0", "@npmcli/promise-spawn@^1.2.0", "@npmcli/promise-spawn@^1.3.0": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz#42d4e56a8e9274fba180dabc0aea6e38f29274f5" - integrity sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg== - dependencies: - infer-owner "^1.0.4" - -"@npmcli/run-script@^1.3.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-1.8.0.tgz#5cebd6373a4b051e5bf8473eb70c327fa48ebfe5" - integrity sha512-ljPLRbQM5byhqacWl9kIjt/yPMee0heaTskaMBFaFvYzOXNJ64h27xV96Sr+LnjJpqR0qJejG36QzJkXILvghQ== - dependencies: - "@npmcli/node-gyp" "^1.0.0" - "@npmcli/promise-spawn" "^1.3.0" - infer-owner "^1.0.4" - node-gyp "^7.1.0" - puka "^1.0.1" - read-package-json-fast "^1.1.3" - "@sheerun/mutationobserver-shim@^0.3.2": version "0.3.2" resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.2.tgz#8013f2af54a2b7d735f71560ff360d3a8176a87b" @@ -1448,11 +1387,6 @@ resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-7.2.1.tgz#2ad4e844175a3738cb9e7064be5ea070b8863a1c" integrity sha512-oZ0Ib5I4Z2pUEcoo95cT1cr6slco9WY7yiPpG+RGNkj8YcYgJnM7pXmYmorNOReh8MIGcKSqXyeGjxnr8YiZbA== -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - "@types/babel__core@^7.1.0": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.3.tgz#e441ea7df63cd080dfcd02ab199e6d16a735fc30" @@ -1955,22 +1889,6 @@ after@0.8.2: resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" integrity sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8= -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -agentkeepalive@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.1.3.tgz#360a09d743a1f4fde749f9ba07caa6575d08259a" - integrity sha512-wn8fw19xKZwdGPO47jivonaHRTd+nGOMP1z11sgGeQzDy2xd5FG0R67dIMcKHDE2cJ5y+YXV30XVGUBPRSY7Hg== - dependencies: - debug "^4.1.0" - depd "^1.1.2" - humanize-ms "^1.2.1" - aggregate-error@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.0.1.tgz#db2fe7246e536f40d9b5442a39e117d7dd6a24e0" @@ -1999,16 +1917,6 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" -ajv@^6.12.3: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - alphanum-sort@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" @@ -2099,19 +2007,11 @@ anymatch@~3.1.1: normalize-path "^3.0.0" picomatch "^2.0.4" -aproba@^1.0.3, aproba@^1.1.1: +aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== -are-we-there-yet@~1.1.2: - version "1.1.5" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" - integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== - dependencies: - delegates "^1.0.0" - readable-stream "^2.0.6" - argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -2198,7 +2098,7 @@ arrify@^1.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= -asap@^2.0.0, asap@~2.0.3, asap@~2.0.6: +asap@~2.0.3, asap@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY= @@ -2842,11 +2742,6 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug= -builtins@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" - integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= - busboy@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.3.1.tgz#170899274c5bf38aae27d5c62b71268cd585fd1b" @@ -2914,29 +2809,6 @@ cacache@^13.0.1: ssri "^7.0.0" unique-filename "^1.1.1" -cacache@^15.0.0, cacache@^15.0.5: - version "15.0.5" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.0.5.tgz#69162833da29170d6732334643c60e005f5f17d0" - integrity sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A== - dependencies: - "@npmcli/move-file" "^1.0.1" - chownr "^2.0.0" - fs-minipass "^2.0.0" - glob "^7.1.4" - infer-owner "^1.0.4" - lru-cache "^6.0.0" - minipass "^3.1.1" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^1.0.3" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^8.0.0" - tar "^6.0.2" - unique-filename "^1.1.1" - cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -3453,11 +3325,6 @@ console-browserify@^1.1.0: resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== -console-control-strings@^1.0.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= - constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -3982,13 +3849,6 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: dependencies: ms "2.0.0" -debug@4, debug@^4.0.0: - version "4.3.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" - integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== - dependencies: - ms "2.1.2" - debug@=3.1.0, debug@~3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" @@ -4003,6 +3863,13 @@ debug@^3.0.0, debug@^3.1.1, debug@^3.2.5, debug@^3.2.6: dependencies: ms "^2.1.1" +debug@^4.0.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" + integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== + dependencies: + ms "2.1.2" + debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" @@ -4010,11 +3877,6 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@~4.1.0: dependencies: ms "^2.1.1" -debuglog@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" - integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= - decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" @@ -4107,12 +3969,7 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk= -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= - -depd@^1.1.2, depd@~1.1.2: +depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= @@ -4153,14 +4010,6 @@ detect-port-alt@1.1.6: address "^1.0.1" debug "^2.6.0" -dezalgo@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/dezalgo/-/dezalgo-1.0.3.tgz#7f742de066fc748bc8db820569dddce49bf0d456" - integrity sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY= - dependencies: - asap "^2.0.0" - wrappy "1" - dicer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.3.0.tgz#eacd98b3bfbf92e8ab5c2fdb71aaac44bb06b872" @@ -4423,7 +4272,7 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.11, encoding@^0.1.12: +encoding@^0.1.11: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== @@ -4513,16 +4362,6 @@ env-cmd@^10.1.0: commander "^4.0.0" cross-spawn "^7.0.0" -env-paths@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.0.tgz#cdca557dc009152917d6166e2febe1f039685e43" - integrity sha512-6u0VYSCo/OW6IoD5WCLLy9JUGARbamfSavcNXry/eu8aHVFei6CD3Sw+VGX5alea1i9pgPHW0mbu6Xj0uBh7gA== - -err-code@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-1.1.2.tgz#06e0116d3028f6aef4806849eb0ea6a748ae6960" - integrity sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA= - errno@^0.1.3, errno@~0.1.7: version "0.1.7" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" @@ -5434,7 +5273,7 @@ fs-extra@^8.1.0: jsonfile "^4.0.0" universalify "^0.1.0" -fs-minipass@^2.0.0, fs-minipass@^2.1.0: +fs-minipass@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== @@ -5479,20 +5318,6 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= -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" - gensync@^1.0.0-beta.1: version "1.0.0-beta.1" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" @@ -5670,11 +5495,6 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== -graceful-fs@^4.2.3: - version "4.2.4" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" - integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== - growly@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" @@ -5706,14 +5526,6 @@ har-validator@~5.1.0: ajv "^6.5.5" har-schema "^2.0.0" -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - harmony-reflect@^1.4.6: version "1.6.1" resolved "https://registry.yarnpkg.com/harmony-reflect/-/harmony-reflect-1.6.1.tgz#c108d4f2bb451efef7a37861fdbdae72c9bdefa9" @@ -5753,11 +5565,6 @@ has-symbols@^1.0.0, has-symbols@^1.0.1: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== -has-unicode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= - has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" @@ -5850,13 +5657,6 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c" integrity sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg== -hosted-git-info@^3.0.6: - version "3.0.7" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.7.tgz#a30727385ea85acfcee94e0aad9e368c792e036c" - integrity sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ== - dependencies: - lru-cache "^6.0.0" - hpack.js@^2.1.6: version "2.1.6" resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" @@ -5956,11 +5756,6 @@ htmlparser2@^5.0: domutils "^2.4.2" entities "^2.0.0" -http-cache-semantics@^4.0.4: - version "4.1.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" - integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== - http-deceiver@^1.2.7: version "1.2.7" resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" @@ -6003,15 +5798,6 @@ http-errors@~1.7.2: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.4.10.tgz#92c9c1374c35085f75db359ec56cc257cbb93fa4" integrity sha1-ksnBN0w1CF912zWexWzCV8u5P6Q= -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - http-proxy-middleware@0.19.1: version "0.19.1" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" @@ -6050,21 +5836,6 @@ https-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" integrity sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM= -https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== - dependencies: - agent-base "6" - debug "4" - -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0= - dependencies: - ms "^2.0.0" - iconv-lite@0.4.24, iconv-lite@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -6108,13 +5879,6 @@ ignore-by-default@^1.0.1: resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= -ignore-walk@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" - integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== - dependencies: - minimatch "^3.0.4" - ignore@^3.3.5: version "3.3.10" resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" @@ -6524,11 +6288,6 @@ is-installed-globally@^0.1.0: global-dirs "^0.1.0" is-path-inside "^1.0.0" -is-lambda@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" - integrity sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU= - is-npm@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4" @@ -7258,11 +7017,6 @@ json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -7321,11 +7075,6 @@ jsonify@~0.0.0: resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" integrity sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM= -jsonparse@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA= - jsprim@^1.2.2: version "1.4.1" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" @@ -7645,13 +7394,6 @@ lru-cache@^5.1.1: dependencies: yallist "^3.0.2" -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - make-dir@^1.0.0: version "1.3.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" @@ -7679,27 +7421,6 @@ make-error@1.x: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -make-fetch-happen@^8.0.9: - version "8.0.10" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-8.0.10.tgz#f37c5d93d14290488ca6a2ae917a380bd7d24f16" - integrity sha512-jPLPKQjBmDLK5r1BdyDyNKBytmkv2AsDWm2CxHJh+fqhSmC9Pmb7RQxwOq8xQig9+AWIS49+51k4f6vDQ3VnrQ== - dependencies: - agentkeepalive "^4.1.0" - cacache "^15.0.0" - http-cache-semantics "^4.0.4" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^6.0.0" - minipass "^3.1.3" - minipass-collect "^1.0.2" - minipass-fetch "^1.3.0" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - promise-retry "^1.1.1" - socks-proxy-agent "^5.0.0" - ssri "^8.0.0" - makeerror@1.0.x: version "1.0.11" resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" @@ -7954,17 +7675,6 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" -minipass-fetch@^1.3.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.3.2.tgz#573766fb1ae86e30df916a6b060bc2e801bf8f37" - integrity sha512-/i4fX1ss+Dtwyk++OsAI6SEV+eE1dvI6W+0hORdjfruQ7VD5uYTetJIHcEMjWiEiszWjn2aAtP1CB/Q4KfeoYA== - dependencies: - minipass "^3.1.0" - minipass-sized "^1.0.3" - minizlib "^2.0.0" - optionalDependencies: - encoding "^0.1.12" - minipass-flush@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" @@ -7972,14 +7682,6 @@ minipass-flush@^1.0.5: dependencies: minipass "^3.0.0" -minipass-json-stream@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz#7edbb92588fbfc2ff1db2fc10397acb7b6b44aa7" - integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg== - dependencies: - jsonparse "^1.3.1" - minipass "^3.0.0" - minipass-pipeline@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz#3dcb6bb4a546e32969c7ad710f2c79a86abba93a" @@ -7987,13 +7689,6 @@ minipass-pipeline@^1.2.2: dependencies: minipass "^3.0.0" -minipass-sized@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" - integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== - dependencies: - minipass "^3.0.0" - minipass@^3.0.0, minipass@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5" @@ -8001,14 +7696,7 @@ minipass@^3.0.0, minipass@^3.1.1: dependencies: yallist "^4.0.0" -minipass@^3.1.0, minipass@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd" - integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg== - dependencies: - yallist "^4.0.0" - -minizlib@^2.0.0, minizlib@^2.1.1: +minizlib@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== @@ -8055,7 +7743,7 @@ mkdirp@0.5.1, mkdirp@0.x, mkdirp@^0.5.1, mkdirp@~0.5.1: dependencies: minimist "0.0.8" -mkdirp@^1.0.3, mkdirp@^1.0.4: +mkdirp@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -8087,7 +7775,7 @@ ms@2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== -ms@2.1.2, ms@^2.0.0, ms@^2.1.1: +ms@2.1.2, ms@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== @@ -8137,6 +7825,11 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +ncp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" + integrity sha1-GVoh1sRuNh0vsSgbo4uR6d9727M= + nedb-promises@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nedb-promises/-/nedb-promises-4.0.1.tgz#4d0bd1553d045acca5d6713ad76eb97aa830b390" @@ -8190,11 +7883,6 @@ node-fetch@^1.0.1: encoding "^0.1.11" is-stream "^1.0.1" -node-fetch@^2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" - integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== - node-forge@0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" @@ -8205,22 +7893,6 @@ node-gyp-build@~3.7.0: resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-3.7.0.tgz#daa77a4f547b9aed3e2aac779eaf151afd60ec8d" integrity sha512-L/Eg02Epx6Si2NXmedx+Okg+4UHqmaf3TNcxd50SF9NQGcJaON3AtU++kax69XV7YWz4tUspqZSAsVofhFKG2w== -node-gyp@^7.1.0: - version "7.1.2" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-7.1.2.tgz#21a810aebb187120251c3bcec979af1587b188ae" - integrity sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ== - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.3" - nopt "^5.0.0" - npmlog "^4.1.2" - request "^2.88.2" - rimraf "^3.0.2" - semver "^7.3.2" - tar "^6.0.2" - which "^2.0.2" - node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -8302,13 +7974,6 @@ noms@0.0.0: inherits "^2.0.1" readable-stream "~1.0.31" -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - nopt@~1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" @@ -8358,67 +8023,6 @@ normalize-url@^3.0.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== -npm-bundled@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" - integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== - dependencies: - npm-normalize-package-bin "^1.0.1" - -npm-install-checks@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-4.0.0.tgz#a37facc763a2fde0497ef2c6d0ac7c3fbe00d7b4" - integrity sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w== - dependencies: - semver "^7.1.1" - -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-package-arg@^8.0.0, npm-package-arg@^8.0.1: - version "8.1.0" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.0.tgz#b5f6319418c3246a1c38e1a8fbaa06231bc5308f" - integrity sha512-/ep6QDxBkm9HvOhOg0heitSd7JHA1U7y1qhhlRlteYYAi9Pdb/ZV7FW5aHpkrpM8+P+4p/jjR8zCyKPBMBjSig== - dependencies: - hosted-git-info "^3.0.6" - semver "^7.0.0" - validate-npm-package-name "^3.0.0" - -npm-packlist@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-2.1.4.tgz#40e96b2b43787d0546a574542d01e066640d09da" - integrity sha512-Qzg2pvXC9U4I4fLnUrBmcIT4x0woLtUgxUi9eC+Zrcv1Xx5eamytGAfbDWQ67j7xOcQ2VW1I3su9smVTIdu7Hw== - dependencies: - glob "^7.1.6" - ignore-walk "^3.0.3" - npm-bundled "^1.1.1" - npm-normalize-package-bin "^1.0.1" - -npm-pick-manifest@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-6.1.0.tgz#2befed87b0fce956790f62d32afb56d7539c022a" - integrity sha512-ygs4k6f54ZxJXrzT0x34NybRlLeZ4+6nECAIbr2i0foTnijtS1TJiyzpqtuUAJOps/hO0tNDr8fRV5g+BtRlTw== - dependencies: - npm-install-checks "^4.0.0" - npm-package-arg "^8.0.0" - semver "^7.0.0" - -npm-registry-fetch@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-9.0.0.tgz#86f3feb4ce00313bc0b8f1f8f69daae6face1661" - integrity sha512-PuFYYtnQ8IyVl6ib9d3PepeehcUeHN9IO5N/iCRhyg9tStQcqGQBRVHmfmMWPDERU3KwZoHFvbJ4FPXPspvzbA== - dependencies: - "@npmcli/ci-detect" "^1.0.0" - lru-cache "^6.0.0" - make-fetch-happen "^8.0.9" - minipass "^3.1.3" - minipass-fetch "^1.3.0" - minipass-json-stream "^1.0.1" - minizlib "^2.0.0" - npm-package-arg "^8.0.0" - 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" @@ -8426,16 +8030,6 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npmlog@^4.1.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" - nth-check@^1.0.2, nth-check@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c" @@ -8729,13 +8323,6 @@ p-map@^3.0.0: dependencies: aggregate-error "^3.0.0" -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - p-reduce@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" @@ -8768,31 +8355,6 @@ package-json@^4.0.0: registry-url "^3.0.3" semver "^5.1.0" -pacote@^11.1.13: - version "11.1.13" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-11.1.13.tgz#7e85213693b0b4b1119c4026dc1b68c087641dc2" - integrity sha512-oJ7Bg7p3izrIMhZPHCCHmMHQl+xb+pKBXL5ZYeM2oCZrw6sBRSx7f8l7F+95V2qA0BP3c1cNaaBmUNkbo6Hn9w== - dependencies: - "@npmcli/git" "^2.0.1" - "@npmcli/installed-package-contents" "^1.0.5" - "@npmcli/promise-spawn" "^1.2.0" - "@npmcli/run-script" "^1.3.0" - cacache "^15.0.5" - chownr "^2.0.0" - fs-minipass "^2.1.0" - infer-owner "^1.0.4" - minipass "^3.1.3" - mkdirp "^1.0.3" - npm-package-arg "^8.0.1" - npm-packlist "^2.1.4" - npm-pick-manifest "^6.0.0" - npm-registry-fetch "^9.0.0" - promise-retry "^1.1.1" - read-package-json-fast "^1.1.3" - rimraf "^3.0.2" - ssri "^8.0.0" - tar "^6.0.1" - pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" @@ -9854,14 +9416,6 @@ promise-inflight@^1.0.1: resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= -promise-retry@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-1.1.1.tgz#6739e968e3051da20ce6497fb2b50f6911df3d6d" - integrity sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0= - dependencies: - err-code "^1.0.0" - retry "^0.10.0" - promise@^7.1.1: version "7.3.1" resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf" @@ -9933,11 +9487,6 @@ public-encrypt@^4.0.0: randombytes "^2.0.1" safe-buffer "^5.1.2" -puka@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/puka/-/puka-1.0.1.tgz#a2df782b7eb4cf9564e4c93a5da422de0dfacc02" - integrity sha512-ssjRZxBd7BT3dte1RR3VoeT2cT/ODH8x+h0rUF1rMqB0srHYf48stSDWfiYakTp5UBZMxroZhB2+ExLDHm7W3g== - pump@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" @@ -10348,14 +9897,6 @@ react@^16.12.0: object-assign "^4.1.1" prop-types "^15.6.2" -read-package-json-fast@^1.1.1, read-package-json-fast@^1.1.3: - version "1.2.1" - resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-1.2.1.tgz#e8518d6f37c99eb3afc26704c5cbb50d7ead82dd" - integrity sha512-OFbpwnHcv74Oa5YN5WvbOBfLw6yPmPcwvyJJw/tj9cWFBF7juQUDLDSZiOjEcgzfweWeeROOmbPpNN1qm4hcRg== - dependencies: - json-parse-even-better-errors "^2.3.0" - npm-normalize-package-bin "^1.0.1" - read-pkg-up@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" @@ -10399,7 +9940,7 @@ read-pkg@^4.0.1: parse-json "^4.0.0" pify "^3.0.0" -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -10431,16 +9972,6 @@ readable-stream@~1.0.31: isarray "0.0.1" string_decoder "~0.10.x" -readdir-scoped-modules@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.1.0.tgz#8d45407b4f870a0dcaebc0e28670d18e74514309" - integrity sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw== - dependencies: - debuglog "^1.0.1" - dezalgo "^1.0.0" - graceful-fs "^4.1.2" - once "^1.3.0" - readdirp@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" @@ -10668,32 +10199,6 @@ request@^2.87.0, request@^2.88.0: tunnel-agent "^0.6.0" uuid "^3.3.2" -request@^2.88.2: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -10804,11 +10309,6 @@ ret@~0.1.10: resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== -retry@^0.10.0: - version "0.10.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" - integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= - retry@^0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" @@ -10851,13 +10351,6 @@ rimraf@^2.5.4, rimraf@^2.6.3, rimraf@^2.7.1: dependencies: glob "^7.1.3" -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -11016,11 +10509,6 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@^7.0.0, semver@^7.1.1, semver@^7.3.2: - version "7.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== - send@0.17.1: version "0.17.1" resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" @@ -11068,7 +10556,7 @@ serve-static@1.14.1: parseurl "~1.3.3" send "0.17.1" -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= @@ -11206,11 +10694,6 @@ slice-ansi@^2.1.0: astral-regex "^1.0.0" is-fullwidth-code-point "^2.0.0" -smart-buffer@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.1.0.tgz#91605c25d91652f4661ea69ccf45f1b331ca21ba" - integrity sha512-iVICrxOzCynf/SNaBQCw34eM9jROU/s5rzIhpOvzhzuYHfJR/DhZfDkXiZSgKXfgv26HT3Yni3AV/DGw0cGnnw== - snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -11316,23 +10799,6 @@ sockjs@0.3.19: faye-websocket "^0.10.0" uuid "^3.0.1" -socks-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-5.0.0.tgz#7c0f364e7b1cf4a7a437e71253bed72e9004be60" - integrity sha512-lEpa1zsWCChxiynk+lCycKuC502RxDWLKJZoIhnxrWNjLSDGYRFflHA1/228VkRcnv9TIb8w98derGbpKxJRgA== - dependencies: - agent-base "6" - debug "4" - socks "^2.3.3" - -socks@^2.3.3: - version "2.5.0" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.5.0.tgz#3a7c286db114f67864a4bd8b4207a91d1db3d6db" - integrity sha512-00OqQHp5SCbwm9ecOMJj9aQtMSjwi1uVuGQoxnpKCS50VKZcOZ8z11CTKypmR8sEy7nZimy/qXY7rYJYbRlXmA== - dependencies: - ip "^1.1.5" - smart-buffer "^4.1.0" - sort-keys@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" @@ -11482,13 +10948,6 @@ ssri@^7.0.0: figgy-pudding "^3.5.1" minipass "^3.1.1" -ssri@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.0.tgz#79ca74e21f8ceaeddfcb4b90143c458b8d988808" - integrity sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA== - dependencies: - minipass "^3.1.1" - stable@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" @@ -11584,7 +11043,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: +string-width@^2.0.0, string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -11845,7 +11304,7 @@ tapable@^1.0.0, tapable@^1.1.0, tapable@^1.1.3: resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== -tar@^6.0.1, tar@^6.0.2: +tar@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.5.tgz#bde815086e10b39f1dcd298e89d596e1535e200f" integrity sha512-0b4HOimQHj9nXNEAA7zWwMM91Zhhba3pspja6sQbgTpynOJf+bkjBnfybNYzbpLbnwXnbyB4LOREvlyXLkCHSg== @@ -12033,7 +11492,7 @@ touch@^3.1.0: dependencies: nopt "~1.0.10" -tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.5.0, tough-cookie@~2.5.0: +tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== @@ -12469,13 +11928,6 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" -validate-npm-package-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" - integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= - dependencies: - builtins "^1.0.3" - vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" @@ -12792,20 +12244,13 @@ which@^1.2.14, which@^1.2.9, which@^1.3.0, which@^1.3.1: dependencies: isexe "^2.0.0" -which@^2.0.1, which@^2.0.2: +which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - widest-line@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-2.0.1.tgz#7438764730ec7ef4381ce4df82fb98a53142a3fc" From c4ab06a14b075bffdcb9d79a0551597749fc8a8d Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Fri, 27 Nov 2020 18:41:23 +0100 Subject: [PATCH 28/30] plugin fixes --- packages/api/src/controllers/plugins.js | 77 +++++++++++++------ .../web/src/plugins/manifestExtractors.js | 3 +- packages/web/src/tabs/PluginTab.js | 74 +++++++++++------- 3 files changed, 101 insertions(+), 53 deletions(-) diff --git a/packages/api/src/controllers/plugins.js b/packages/api/src/controllers/plugins.js index 6d579c69f..1961a6c09 100644 --- a/packages/api/src/controllers/plugins.js +++ b/packages/api/src/controllers/plugins.js @@ -6,23 +6,23 @@ const socket = require('../utility/socket'); const requirePlugin = require('../shell/requirePlugin'); const downloadPackage = require('../utility/downloadPackage'); -async function loadPackageInfo(dir) { - const readmeFile = path.join(dir, 'README.md'); - const packageFile = path.join(dir, 'package.json'); +// async function loadPackageInfo(dir) { +// const readmeFile = path.join(dir, 'README.md'); +// const packageFile = path.join(dir, 'package.json'); - if (!(await fs.exists(packageFile))) { - return null; - } +// if (!(await fs.exists(packageFile))) { +// return null; +// } - let readme = null; - let manifest = null; - if (await fs.exists(readmeFile)) readme = await fs.readFile(readmeFile, { encoding: 'utf-8' }); - if (await fs.exists(packageFile)) manifest = JSON.parse(await fs.readFile(packageFile, { encoding: 'utf-8' })); - return { - readme, - manifest, - }; -} +// let readme = null; +// let manifest = null; +// if (await fs.exists(readmeFile)) readme = await fs.readFile(readmeFile, { encoding: 'utf-8' }); +// if (await fs.exists(packageFile)) manifest = JSON.parse(await fs.readFile(packageFile, { encoding: 'utf-8' })); +// return { +// readme, +// manifest, +// }; +// } module.exports = { script_meta: 'get', @@ -46,11 +46,28 @@ module.exports = { info_meta: 'get', async info({ packageName }) { - const dir = path.join(pluginstmpdir(), packageName); - if (!(await fs.exists(dir))) { - await downloadPackage(packageName, dir); + try { + const infoResp = await axios.default.get(`https://registry.npmjs.org/${packageName}`); + const { latest } = infoResp.data['dist-tags']; + const manifest = infoResp.data.versions[latest]; + const { readme } = infoResp.data; + + return { + readme, + manifest, + }; + } catch (err) { + return { + state: 'error', + error: err.message, + }; } - return await loadPackageInfo(dir); + + // const dir = path.join(pluginstmpdir(), packageName); + // if (!(await fs.exists(dir))) { + // await downloadPackage(packageName, dir); + // } + // return await loadPackageInfo(dir); // return await { // ...loadPackageInfo(dir), // installed: loadPackageInfo(path.join(pluginsdir(), packageName)), @@ -60,11 +77,23 @@ module.exports = { installed_meta: 'get', async installed() { const files = await fs.readdir(pluginsdir()); - return await Promise.all( - files.map((packageName) => - fs.readFile(path.join(pluginsdir(), packageName, 'package.json')).then((x) => JSON.parse(x)) - ) - ); + const res = []; + for (const packageName of files) { + const manifest = await fs + .readFile(path.join(pluginsdir(), packageName, 'package.json')) + .then((x) => JSON.parse(x)); + const readmeFile = path.join(pluginsdir(), packageName, 'README.md'); + if (await fs.exists(readmeFile)) { + manifest.readme = await fs.readFile(readmeFile, { encoding: 'utf-8' }); + } + res.push(manifest); + } + return res; + // const res = await Promise.all( + // files.map((packageName) => + // fs.readFile(path.join(pluginsdir(), packageName, 'package.json')).then((x) => JSON.parse(x)) + // ) + // ); }, install_meta: 'post', diff --git a/packages/web/src/plugins/manifestExtractors.js b/packages/web/src/plugins/manifestExtractors.js index 715f2db65..32f62ef65 100644 --- a/packages/web/src/plugins/manifestExtractors.js +++ b/packages/web/src/plugins/manifestExtractors.js @@ -2,7 +2,8 @@ import _ from 'lodash'; export function extractPluginIcon(packageManifest) { const { links } = packageManifest || {}; - const { repository, homepage } = links || {}; + const { repository } = links || {}; + const homepage = (links && links.homepage) || packageManifest.homepage; const tested = repository || homepage || packageManifest.homepage; if (tested) { diff --git a/packages/web/src/tabs/PluginTab.js b/packages/web/src/tabs/PluginTab.js index 27698f72f..24d2cbbf5 100644 --- a/packages/web/src/tabs/PluginTab.js +++ b/packages/web/src/tabs/PluginTab.js @@ -55,7 +55,7 @@ function Delimiter() { return | ; } -export default function PluginTab({ packageName }) { +function PluginTabCore({ packageName }) { const theme = useTheme(); const installed = useInstalledPlugins(); const info = useFetch({ @@ -63,7 +63,7 @@ export default function PluginTab({ packageName }) { url: 'plugins/info', defaultValue: null, }); - const { readme, manifest } = info || {}; + let { readme, manifest } = info || {}; const handleInstall = async () => { axios.post('plugins/install', { packageName }); }; @@ -71,34 +71,52 @@ export default function PluginTab({ packageName }) { axios.post('plugins/uninstall', { packageName }); }; + if (info == null) { + return ; + } + + if (manifest == null) { + const installedFound = installed.find((x) => x.name == packageName); + if (installedFound) { + manifest = installedFound; + readme = installedFound.readme; + } + if (manifest == null) { + return null; + } + } + + return ( + <> +
+ + + {packageName} + + {extractPluginAuthor(manifest)} + + {manifest.version && manifest.version} + + + {!installed.find((x) => x.name == packageName) && ( + + )} + {!!installed.find((x) => x.name == packageName) && ( + + )} + + +
+ {readme} + + ); +} + +export default function PluginTab({ packageName }) { + const theme = useTheme(); return ( - {info == null || manifest == null ? ( - - ) : ( - <> -
- - - {packageName} - - {extractPluginAuthor(manifest)} - - {manifest.version && manifest.version} - - - {!installed.find((x) => x.name == packageName) && ( - - )} - {!!installed.find((x) => x.name == packageName) && ( - - )} - - -
- {readme} - - )} +
); } From f2d15e2f84b360f0ecf7123c2fa6094fb00b5d61 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Fri, 27 Nov 2020 21:26:52 +0100 Subject: [PATCH 29/30] preinstall plugins --- packages/api/src/controllers/plugins.js | 32 ++++++++++++++++++++++++- packages/api/src/utility/directories.js | 2 -- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/packages/api/src/controllers/plugins.js b/packages/api/src/controllers/plugins.js index 1961a6c09..2d671ebaa 100644 --- a/packages/api/src/controllers/plugins.js +++ b/packages/api/src/controllers/plugins.js @@ -1,7 +1,7 @@ const fs = require('fs-extra'); const axios = require('axios'); const path = require('path'); -const { pluginstmpdir, pluginsdir } = require('../utility/directories'); +const { pluginsdir, datadir } = require('../utility/directories'); const socket = require('../utility/socket'); const requirePlugin = require('../shell/requirePlugin'); const downloadPackage = require('../utility/downloadPackage'); @@ -24,6 +24,14 @@ const downloadPackage = require('../utility/downloadPackage'); // }; // } +const preinstallPlugins = [ + 'dbgate-plugin-mssql', + 'dbgate-plugin-mysql', + 'dbgate-plugin-postgres', + 'dbgate-plugin-csv', + 'dbgate-plugin-excel', +]; + module.exports = { script_meta: 'get', async script({ packageName }) { @@ -110,6 +118,8 @@ module.exports = { const dir = path.join(pluginsdir(), packageName); await fs.rmdir(dir, { recursive: true }); socket.emitChanged(`installed-plugins-changed`); + this.removedPlugins.push(packageName); + await fs.writeFile(path.join(datadir(), 'removed-plugins'), this.removedPlugins.join('\n')); }, command_meta: 'post', @@ -117,4 +127,24 @@ module.exports = { const content = requirePlugin(packageName); return content.commands[command](args); }, + + async _init() { + const installed = await this.installed(); + try { + this.removedPlugins = (await fs.readFile(path.join(datadir(), 'removed-plugins'), { encoding: 'utf-8' })).split( + '\n' + ); + } catch (err) { + this.removedPlugins = []; + } + for (const packageName of preinstallPlugins) { + if (this.removedPlugins.includes(packageName)) continue; + try { + console.log('Preinstalling plugin', packageName); + await this.install({ packageName }); + } catch (err) { + console.error('Error preinstalling plugin', packageName, err); + } + } + }, }; diff --git a/packages/api/src/utility/directories.js b/packages/api/src/utility/directories.js index fbb42d921..4f0ace4b9 100644 --- a/packages/api/src/utility/directories.js +++ b/packages/api/src/utility/directories.js @@ -35,7 +35,6 @@ const dirFunc = (dirname, clean = false) => () => { const jsldir = dirFunc('jsl', true); const rundir = dirFunc('run', true); const uploadsdir = dirFunc('uploads', true); -const pluginstmpdir = dirFunc('plugins-tmp', true); const pluginsdir = dirFunc('plugins'); const archivedir = dirFunc('archive'); @@ -46,6 +45,5 @@ module.exports = { uploadsdir, archivedir, ensureDirectory, - pluginstmpdir, pluginsdir, }; From fedf2db84720fa6a11440d9e299b5ff9eee15cd4 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Fri, 27 Nov 2020 21:34:19 +0100 Subject: [PATCH 30/30] v3.8.0 --- app/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/package.json b/app/package.json index e806eab49..2631e84a6 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "dbgate", - "version": "3.7.33", + "version": "3.8.0", "private": true, "author": "Jan Prochazka ", "dependencies": {