Merge pull request #7774 from Budibase/events/plugins
Plugin init, imported and deleted events
This commit is contained in:
commit
b8462eea0c
15 changed files with 138 additions and 18 deletions
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
41
packages/backend-core/src/events/publishers/plugin.ts
Normal file
41
packages/backend-core/src/events/publishers/plugin.ts
Normal 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)
|
||||
}
|
|
@ -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"
|
||||
|
|
11
packages/cli/src/events.js
Normal file
11
packages/cli/src/events.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
const AnalyticsClient = require("./analytics/Client")
|
||||
|
||||
const client = new AnalyticsClient()
|
||||
|
||||
exports.captureEvent = (event, properties) => {
|
||||
client.capture({
|
||||
distinctId: "cli",
|
||||
event,
|
||||
properties,
|
||||
})
|
||||
}
|
|
@ -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: {
|
||||
type,
|
||||
},
|
||||
captureEvent(AnalyticsEvents.SelfHostInit, {
|
||||
type,
|
||||
})
|
||||
await downloadFiles()
|
||||
const config = isQuick ? makeEnv.QUICK_CONFIG : {}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export * from "./config"
|
||||
export * from "./user"
|
||||
export * from "./userGroup"
|
||||
export * from "./plugin"
|
||||
|
|
|
@ -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)
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -19,3 +19,4 @@ export * from "./account"
|
|||
export * from "./backfill"
|
||||
export * from "./identification"
|
||||
export * from "./userGroup"
|
||||
export * from "./plugin"
|
||||
|
|
26
packages/types/src/sdk/events/plugin.ts
Normal file
26
packages/types/src/sdk/events/plugin.ts
Normal 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
|
||||
}
|
Loading…
Reference in a new issue