Merge branch 'feature/plugin-management-ui' of github.com:Budibase/budibase into feature/plugin-management-ui

This commit is contained in:
Peter Clement 2022-09-05 09:37:44 +01:00
commit 70408d8008
6 changed files with 115 additions and 8 deletions

View File

@ -0,0 +1,31 @@
<script>
import { goto } from "@roxi/routify"
import { Body, ModalContent, notifications } from "@budibase/bbui"
import { plugins } from "stores/portal"
export let removePlugin
async function deletePlugin() {
try {
await plugins.deletePlugin(removePlugin._id, removePlugin._rev)
notifications.success(`Plugin ${removePlugin?.name} deleted.`)
$goto("./")
} catch (error) {
notifications.error("Error deleting plugin")
}
}
</script>
<ModalContent
warning
onConfirm={deletePlugin}
title="Delete Plugin"
confirmText="Delete plugin"
cancelText="Cancel"
showCloseIcon={false}
>
<Body>
Are you sure you want to delete <strong>{removePlugin?.name}</strong>
</Body>
</ModalContent>

View File

@ -117,9 +117,6 @@
align-items: center;
}
.opacity {
opacity: 50%;
}
@media (max-width: 640px) {
.desktop {
display: none !important;

View File

@ -13,9 +13,12 @@
import { plugins } from "stores/portal"
import PluginRow from "./_components/PluginRow.svelte"
import AddPluginModal from "./_components/AddPluginModal.svelte"
import DeletePluginModal from "./_components/DeletePluginModal.svelte"
let modal
let deleteModal
let searchTerm = ""
let removePlugin
let filterOptions = [
{ label: "All Plugins", value: "all" },
@ -31,6 +34,12 @@
.filter(plugin =>
plugin?.name?.toLowerCase().includes(searchTerm.toLowerCase())
)
const deletePlugin = plugin => {
deleteModal.show()
removePlugin = plugin
}
onMount(async () => {
await plugins.load()
})
@ -66,7 +75,7 @@
{#if $plugins}
{#each filteredPlugins as plugin}
<PluginRow {plugin} />
<PluginRow {plugin} {deletePlugin} />
{/each}
{/if}
</Layout>
@ -75,6 +84,9 @@
<Modal bind:this={modal}>
<AddPluginModal />
</Modal>
<Modal bind:this={deleteModal}>
<DeletePluginModal {removePlugin} />
</Modal>
<style>
.filters {

View File

@ -32,10 +32,12 @@ export function createPluginsStore() {
case "npm":
pluginData.npmToken = auth
break
case "github":
pluginData.githubToken = auth
break
}
let res = await API.createPlugin(pluginData)
console.log("RESP", res)
let newPlugin = res.plugins[0]
update(state => {

View File

@ -3,6 +3,7 @@ import {
extractPluginTarball,
createNpmPlugin,
createUrlPlugin,
createGithubPlugin,
} from "../../utilities/fileSystem"
import { getGlobalDB } from "@budibase/backend-core/tenancy"
import { generatePluginID, getPluginParams } from "../../db/utils"
@ -61,7 +62,10 @@ export async function create(ctx: any) {
directory = directoryNpm
break
case "github":
console.log("github")
const { metadata: metadataGithub, directory: directoryGithub } =
await createGithubPlugin(ctx, url, name, githubToken)
metadata = metadataGithub
directory = directoryGithub
break
case "url":
const { metadata: metadataUrl, directory: directoryUrl } =

View File

@ -31,6 +31,7 @@ const MemoryStream = require("memorystream")
const { getAppId } = require("@budibase/backend-core/context")
const tar = require("tar")
const fetch = require("node-fetch")
const { NodeVM } = require("vm2")
const TOP_LEVEL_PATH = join(__dirname, "..", "..", "..")
const NODE_MODULES_PATH = join(TOP_LEVEL_PATH, "node_modules")
@ -378,8 +379,69 @@ exports.createUrlPlugin = async (url, name = "", headers = {}) => {
return await downloadUnzipPlugin(name, url, headers)
}
exports.createGithubPlugin = async (ctx, url, name = "", token = "") => {
let githubRepositoryUrl
let githubUrl
if (url.includes(".git")) {
githubRepositoryUrl = token
? url.replace("https://", `https://${token}@`)
: url
githubUrl = url.replace(".git", "")
} else {
githubRepositoryUrl = token
? `${url}.git`.replace("https://", `https://${token}@`)
: `${url}.git`
githubUrl = url
}
const githubApiUrl = githubUrl.replace(
"https://github.com/",
"https://api.github.com/repos/"
)
const headers = token ? { Authorization: `Bearer ${token}` } : {}
try {
const pluginRaw = await fetch(githubApiUrl, { headers })
if (pluginRaw.status !== 200) {
throw `Repository not found`
}
let pluginDetails = await pluginRaw.json()
const pluginName = pluginDetails.name || name
const path = join(budibaseTempDir(), pluginName)
// Remove first if exists
if (fs.existsSync(path)) {
fs.rmSync(path, { recursive: true, force: true })
}
fs.mkdirSync(path)
const script = `
module.exports = async () => {
const child_process = require('child_process')
child_process.execSync(\`git clone ${githubRepositoryUrl} ${join(
budibaseTempDir(),
pluginName
)}\`);
}
`
const scriptRunner = new NodeVM({
require: {
external: true,
builtin: ["child_process"],
root: "./",
},
}).run(script)
await scriptRunner()
return await getPluginMetadata(path)
} catch (e) {
throw e.message
}
}
const downloadUnzipPlugin = async (name, url, headers = {}) => {
console.log(name, url, headers)
const path = join(budibaseTempDir(), name)
try {
// Remove first if exists
@ -407,7 +469,6 @@ const downloadUnzipPlugin = async (name, url, headers = {}) => {
exports.downloadUnzipPlugin = downloadUnzipPlugin
const getPluginMetadata = async path => {
console.log(path)
let metadata = {}
try {
const pkg = fs.readFileSync(join(path, "package.json"), "utf8")