mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-29 19:13:59 +00:00
load extensions
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import PluginsProvider from './plugins/PluginsProvider.svelte';
|
||||||
import Screen from './Screen.svelte';
|
import Screen from './Screen.svelte';
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<PluginsProvider />
|
||||||
<Screen />
|
<Screen />
|
||||||
|
|||||||
87
packages/web/src/plugins/PluginsList.js
Normal file
87
packages/web/src/plugins/PluginsList.js
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
// import React from 'react';
|
||||||
|
// import styled from 'styled-components';
|
||||||
|
// import useTheme from '../theme/useTheme';
|
||||||
|
// import { useSetOpenedTabs } from '../utility/globalState';
|
||||||
|
// import { extractPluginIcon, extractPluginAuthor } from '../plugins/manifestExtractors';
|
||||||
|
// import useOpenNewTab from '../utility/useOpenNewTab';
|
||||||
|
|
||||||
|
// 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(openNewTab, packageManifest) {
|
||||||
|
// openNewTab({
|
||||||
|
// title: packageManifest.name,
|
||||||
|
// icon: 'icon plugin',
|
||||||
|
// tabComponent: 'PluginTab',
|
||||||
|
// props: {
|
||||||
|
// packageName: packageManifest.name,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// function PluginsListItem({ packageManifest }) {
|
||||||
|
// const openNewTab = useOpenNewTab();
|
||||||
|
// const theme = useTheme();
|
||||||
|
// return (
|
||||||
|
// <Wrapper onClick={() => openPlugin(openNewTab, packageManifest)} theme={theme}>
|
||||||
|
// <Icon src={extractPluginIcon(packageManifest)} />
|
||||||
|
// <Texts>
|
||||||
|
// <Line>
|
||||||
|
// <Name>{packageManifest.name}</Name>
|
||||||
|
// <Version>{packageManifest.version}</Version>
|
||||||
|
// </Line>
|
||||||
|
// <Line>
|
||||||
|
// <Description>{packageManifest.description}</Description>
|
||||||
|
// </Line>
|
||||||
|
// <Line>
|
||||||
|
// <Author>{extractPluginAuthor(packageManifest)}</Author>
|
||||||
|
// </Line>
|
||||||
|
// </Texts>
|
||||||
|
// </Wrapper>
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
|
||||||
|
// export default function PluginsList({ plugins }) {
|
||||||
|
// return (
|
||||||
|
// <>
|
||||||
|
// {plugins.map(packageManifest => (
|
||||||
|
// <PluginsListItem packageManifest={packageManifest} key={packageManifest.name} />
|
||||||
|
// ))}
|
||||||
|
// </>
|
||||||
|
// );
|
||||||
|
// }
|
||||||
74
packages/web/src/plugins/PluginsProvider.svelte
Normal file
74
packages/web/src/plugins/PluginsProvider.svelte
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<script lang="ts" context="module">
|
||||||
|
const dbgateEnv = {
|
||||||
|
axios,
|
||||||
|
};
|
||||||
|
|
||||||
|
async function loadPlugins(pluginsDict, installedPlugins) {
|
||||||
|
const newPlugins = {};
|
||||||
|
for (const installed of installedPlugins || []) {
|
||||||
|
if (!_.keys(pluginsDict).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}; plugin`);
|
||||||
|
console.log('Loaded plugin', module);
|
||||||
|
const moduleContent = module.__esModule ? module.default : module;
|
||||||
|
if (moduleContent.initialize) moduleContent.initialize(dbgateEnv);
|
||||||
|
newPlugins[installed.name] = moduleContent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newPlugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
const extensions = {
|
||||||
|
plugins,
|
||||||
|
fileFormats: buildFileFormats(plugins),
|
||||||
|
drivers: buildDrivers(plugins),
|
||||||
|
};
|
||||||
|
return extensions;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import _ from 'lodash';
|
||||||
|
import { extensions } from '../stores';
|
||||||
|
import axios from '../utility/axios';
|
||||||
|
import { useInstalledPlugins } from '../utility/metadataLoaders';
|
||||||
|
import { buildFileFormats } from './fileformats';
|
||||||
|
|
||||||
|
let pluginsDict = {};
|
||||||
|
const installedPlugins = useInstalledPlugins();
|
||||||
|
|
||||||
|
$: loadPlugins(pluginsDict, $installedPlugins).then(newPlugins => {
|
||||||
|
if (_.isEmpty(newPlugins)) return;
|
||||||
|
pluginsDict = _.pick(
|
||||||
|
{ ...pluginsDict, ...newPlugins },
|
||||||
|
$installedPlugins.map(y => y.name)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
$: plugins = ($installedPlugins || [])
|
||||||
|
.map(manifest => ({
|
||||||
|
packageName: manifest.name,
|
||||||
|
manifest,
|
||||||
|
content: pluginsDict[manifest.name],
|
||||||
|
}))
|
||||||
|
.filter(x => x.content);
|
||||||
|
|
||||||
|
$: $extensions = buildExtensions(plugins);
|
||||||
|
</script>
|
||||||
34
packages/web/src/plugins/fileformats.ts
Normal file
34
packages/web/src/plugins/fileformats.ts
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import { FileFormatDefinition } from 'dbgate-types';
|
||||||
|
|
||||||
|
const jsonlFormat = {
|
||||||
|
storageType: 'jsonl',
|
||||||
|
extension: 'jsonl',
|
||||||
|
name: 'JSON lines',
|
||||||
|
readerFunc: 'jsonLinesReader',
|
||||||
|
writerFunc: 'jsonLinesWriter',
|
||||||
|
};
|
||||||
|
|
||||||
|
export function buildFileFormats(plugins): FileFormatDefinition[] {
|
||||||
|
const res = [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;
|
||||||
|
}
|
||||||
21
packages/web/src/plugins/manifestExtractors.ts
Normal file
21
packages/web/src/plugins/manifestExtractors.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
|
export function extractPluginIcon(packageManifest) {
|
||||||
|
const { links } = packageManifest || {};
|
||||||
|
const { repository } = links || {};
|
||||||
|
const homepage = (links && links.homepage) || packageManifest.homepage;
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { writable } from 'svelte/store';
|
import { writable } from 'svelte/store';
|
||||||
|
import { ExtensionsDirectory } from 'dbgate-types';
|
||||||
|
|
||||||
interface TabDefinition {
|
interface TabDefinition {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -23,5 +24,6 @@ export const selectedWidget = writable('database');
|
|||||||
export const openedConnections = writable([]);
|
export const openedConnections = writable([]);
|
||||||
export const currentDatabase = writable(null);
|
export const currentDatabase = writable(null);
|
||||||
export const openedTabs = writableWithStorage<TabDefinition[]>([], 'openedTabs');
|
export const openedTabs = writableWithStorage<TabDefinition[]>([], 'openedTabs');
|
||||||
|
export const extensions = writable<ExtensionsDirectory>(null);
|
||||||
|
|
||||||
// export const leftPanelWidth = writable(300);
|
// export const leftPanelWidth = writable(300);
|
||||||
|
|||||||
@@ -350,11 +350,11 @@ export function useArchiveFolders(args) {
|
|||||||
return useCore(archiveFoldersLoader, args);
|
return useCore(archiveFoldersLoader, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getInstalledPlugins(args) {
|
export function getInstalledPlugins(args = {}) {
|
||||||
return getCore(installedPluginsLoader, args) || [];
|
return getCore(installedPluginsLoader, args) || [];
|
||||||
}
|
}
|
||||||
export function useInstalledPlugins(args) {
|
export function useInstalledPlugins(args = {}) {
|
||||||
return useCore(installedPluginsLoader, args) || [];
|
return useCore(installedPluginsLoader, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getFiles(args) {
|
export function getFiles(args) {
|
||||||
|
|||||||
Reference in New Issue
Block a user