Merge pull request #7774 from Budibase/events/plugins

Plugin init, imported and deleted events
This commit is contained in:
Michael Drury 2022-09-15 12:55:40 +02:00 committed by GitHub
commit 5e530c7374
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 138 additions and 18 deletions

View File

@ -5,8 +5,15 @@ import {
DatasourceCreatedEvent,
DatasourceUpdatedEvent,
DatasourceDeletedEvent,
SourceName,
} from "@budibase/types"
function isCustom(datasource: Datasource) {
const sources = Object.values(SourceName)
// if not in the base source list, then it must be custom
return !sources.includes(datasource.source)
}
export async function created(
datasource: Datasource,
timestamp?: string | number
@ -14,6 +21,7 @@ export async function created(
const properties: DatasourceCreatedEvent = {
datasourceId: datasource._id as string,
source: datasource.source,
custom: isCustom(datasource),
}
await publishEvent(Event.DATASOURCE_CREATED, properties, timestamp)
}
@ -22,6 +30,7 @@ export async function updated(datasource: Datasource) {
const properties: DatasourceUpdatedEvent = {
datasourceId: datasource._id as string,
source: datasource.source,
custom: isCustom(datasource),
}
await publishEvent(Event.DATASOURCE_UPDATED, properties)
}
@ -30,6 +39,7 @@ export async function deleted(datasource: Datasource) {
const properties: DatasourceDeletedEvent = {
datasourceId: datasource._id as string,
source: datasource.source,
custom: isCustom(datasource),
}
await publishEvent(Event.DATASOURCE_DELETED, properties)
}

View File

@ -18,3 +18,4 @@ export * as view from "./view"
export * as installation from "./installation"
export * as backfill from "./backfill"
export * as group from "./group"
export * as plugin from "./plugin"

View File

@ -0,0 +1,41 @@
import { publishEvent } from "../events"
import {
Event,
Plugin,
PluginDeletedEvent,
PluginImportedEvent,
PluginInitEvent,
} from "@budibase/types"
export async function init(plugin: Plugin) {
const properties: PluginInitEvent = {
type: plugin.schema.type,
name: plugin.name,
description: plugin.description,
version: plugin.version,
}
await publishEvent(Event.PLUGIN_INIT, properties)
}
export async function imported(plugin: Plugin) {
const properties: PluginImportedEvent = {
pluginId: plugin._id as string,
type: plugin.schema.type,
source: plugin.source,
name: plugin.name,
description: plugin.description,
version: plugin.version,
}
await publishEvent(Event.PLUGIN_IMPORTED, properties)
}
export async function deleted(plugin: Plugin) {
const properties: PluginDeletedEvent = {
pluginId: plugin._id as string,
type: plugin.schema.type,
name: plugin.name,
description: plugin.description,
version: plugin.version,
}
await publishEvent(Event.PLUGIN_DELETED, properties)
}

View File

@ -1,3 +1,5 @@
const { Event } = require("@budibase/types")
exports.CommandWords = {
BACKUPS: "backups",
HOSTING: "hosting",
@ -15,6 +17,7 @@ exports.AnalyticsEvents = {
OptOut: "analytics:opt:out",
OptIn: "analytics:opt:in",
SelfHostInit: "hosting:init",
PluginInit: Event.PLUGIN_INIT,
}
exports.POSTHOG_TOKEN = "phc_yGOn4i7jWKaCTapdGR6lfA4AvmuEQ2ijn5zAVSFYPlS"

View File

@ -0,0 +1,11 @@
const AnalyticsClient = require("./analytics/Client")
const client = new AnalyticsClient()
exports.captureEvent = (event, properties) => {
client.capture({
distinctId: "cli",
event,
properties,
})
}

View File

@ -13,7 +13,7 @@ const fs = require("fs")
const compose = require("docker-compose")
const makeEnv = require("./makeEnv")
const axios = require("axios")
const AnalyticsClient = require("../analytics/Client")
const { captureEvent } = require("../events")
const BUDIBASE_SERVICES = ["app-service", "worker-service", "proxy-service"]
const ERROR_FILE = "docker-error.log"
@ -22,8 +22,6 @@ const FILE_URLS = [
]
const DO_USER_DATA_URL = "http://169.254.169.254/metadata/v1/user-data"
const client = new AnalyticsClient()
async function downloadFiles() {
const promises = []
for (let url of FILE_URLS) {
@ -72,12 +70,8 @@ async function init(type) {
return
}
}
client.capture({
distinctId: "cli",
event: AnalyticsEvents.SelfHostInit,
properties: {
captureEvent(AnalyticsEvents.SelfHostInit, {
type,
},
})
await downloadFiles()
const config = isQuick ? makeEnv.QUICK_CONFIG : {}

View File

@ -1,5 +1,5 @@
const Command = require("../structures/Command")
const { CommandWords } = require("../constants")
const { CommandWords, AnalyticsEvents } = require("../constants")
const { getSkeleton, fleshOutSkeleton } = require("./skeleton")
const questions = require("../questions")
const fs = require("fs")
@ -8,6 +8,7 @@ const { validate } = require("@budibase/backend-core/plugins")
const { runPkgCommand } = require("../exec")
const { join } = require("path")
const { success, error, info, moveDirectory } = require("../utils")
const { captureEvent } = require("../events")
function checkInPlugin() {
if (!fs.existsSync("package.json")) {
@ -58,7 +59,7 @@ async function init(opts) {
)
return
}
const desc = await questions.string(
const description = await questions.string(
"Description",
`An amazing Budibase ${type}!`
)
@ -67,7 +68,7 @@ async function init(opts) {
// get the skeleton
console.log(info("Retrieving project..."))
await getSkeleton(type, name)
await fleshOutSkeleton(type, name, desc, version)
await fleshOutSkeleton(type, name, description, version)
console.log(info("Installing dependencies..."))
await runPkgCommand("install", join(process.cwd(), name))
// if no parent directory desired move to cwd
@ -77,6 +78,12 @@ async function init(opts) {
} else {
console.log(info(`Plugin created in directory "${name}"`))
}
captureEvent(AnalyticsEvents.PluginInit, {
type,
name,
description,
version,
})
}
async function verify() {

View File

@ -8,9 +8,10 @@ import {
uploadDirectory,
deleteFolder,
} from "@budibase/backend-core/objectStore"
import { PluginType, FileType, PluginSource } from "@budibase/types"
import { PluginType, FileType, PluginSource, Plugin } from "@budibase/types"
import env from "../../../environment"
import { ClientAppSocket } from "../../../websocket"
import { events } from "@budibase/backend-core"
export async function getPlugins(type?: PluginType) {
const db = getGlobalDB()
@ -113,11 +114,12 @@ export async function destroy(ctx: any) {
const { pluginId } = ctx.params
try {
const plugin = await db.get(pluginId)
const plugin: Plugin = await db.get(pluginId)
const bucketPath = `${plugin.name}/`
await deleteFolder(ObjectStoreBuckets.PLUGINS, bucketPath)
await db.remove(pluginId, plugin._rev)
await events.plugin.deleted(plugin)
} catch (err: any) {
const errMsg = err?.message ? err?.message : err
@ -131,7 +133,7 @@ export async function destroy(ctx: any) {
export async function storePlugin(
metadata: any,
directory: any,
source?: string
source?: PluginSource
) {
const db = getGlobalDB()
const version = metadata.package.version,
@ -173,7 +175,7 @@ export async function storePlugin(
} catch (err) {
rev = undefined
}
let doc = {
let doc: Plugin = {
_id: pluginId,
_rev: rev,
...metadata,
@ -192,6 +194,7 @@ export async function storePlugin(
}
const response = await db.put(doc)
await events.plugin.imported(doc)
ClientAppSocket.emit("plugin-update", { name, hash })
return {
...doc,
@ -199,7 +202,7 @@ export async function storePlugin(
}
}
export async function processPlugin(plugin: FileType, source?: string) {
export async function processPlugin(plugin: FileType, source?: PluginSource) {
const { metadata, directory } = await fileUpload(plugin)
validate(metadata?.schema)

View File

@ -1,3 +1,4 @@
export * from "./config"
export * from "./user"
export * from "./userGroup"
export * from "./plugin"

View File

@ -1,3 +1,5 @@
import { Document } from "../document"
export enum PluginType {
DATASOURCE = "datasource",
COMPONENT = "component",
@ -14,4 +16,17 @@ export interface FileType {
name: string
}
export interface Plugin extends Document {
description: string
name: string
version: string
jsUrl?: string
source: PluginSource
package: { [key: string]: any }
schema: {
type: PluginType
[key: string]: any
}
}
export const PLUGIN_TYPE_ARR = Object.values(PluginType)

View File

@ -1,7 +1,6 @@
export * from "./account"
export * from "./app"
export * from "./global"
export * from "./plugin"
export * from "./platform"
export * from "./document"
export * from "./pouch"

View File

@ -3,14 +3,17 @@ import { BaseEvent } from "./event"
export interface DatasourceCreatedEvent extends BaseEvent {
datasourceId: string
source: string
custom: boolean
}
export interface DatasourceUpdatedEvent extends BaseEvent {
datasourceId: string
source: string
custom: boolean
}
export interface DatasourceDeletedEvent extends BaseEvent {
datasourceId: string
source: string
custom: boolean
}

View File

@ -158,6 +158,11 @@ export enum Event {
USER_GROUP_USERS_REMOVED = "user_group:users_deleted",
USER_GROUP_PERMISSIONS_EDITED = "user_group:permissions_edited",
USER_GROUP_ONBOARDING = "user_group:onboarding_added",
// PLUGIN
PLUGIN_INIT = "plugin:init",
PLUGIN_IMPORTED = "plugin:imported",
PLUGIN_DELETED = "plugin:deleted",
}
// properties added at the final stage of the event pipeline

View File

@ -19,3 +19,4 @@ export * from "./account"
export * from "./backfill"
export * from "./identification"
export * from "./userGroup"
export * from "./plugin"

View File

@ -0,0 +1,26 @@
import { BaseEvent } from "./event"
import { PluginSource, PluginType } from "../../"
export interface PluginInitEvent extends BaseEvent {
type: PluginType
name: string
version: string
description: string
}
export interface PluginImportedEvent extends BaseEvent {
pluginId: string
type: PluginType
source: PluginSource
name: string
version: string
description: string
}
export interface PluginDeletedEvent extends BaseEvent {
pluginId: string
type: PluginType
name: string
version: string
description: string
}