From 47e16dd84467d3f9b72fad11d6e4563ce8d1e7b0 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 24 Oct 2024 13:07:13 +0200 Subject: [PATCH 1/4] Typing emitter --- .../server/src/api/controllers/row/index.ts | 19 +++++++++-------- .../server/src/events/AutomationEmitter.ts | 4 ++-- packages/types/src/sdk/koa.ts | 21 ++++++++++++++++++- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/packages/server/src/api/controllers/row/index.ts b/packages/server/src/api/controllers/row/index.ts index 4d40476b7c..d3b1d3d5b2 100644 --- a/packages/server/src/api/controllers/row/index.ts +++ b/packages/server/src/api/controllers/row/index.ts @@ -7,6 +7,7 @@ import * as internal from "./internal" import * as external from "./external" import { isExternalTableID } from "../../../integrations/utils" import { + AutomationEventType, Ctx, DeleteRow, DeleteRowRequest, @@ -64,15 +65,15 @@ export async function patch( ctx.throw(404, "Row not found") } ctx.status = 200 - ctx.eventEmitter && - ctx.eventEmitter.emitRow({ - eventName: `row:update`, - appId, - row, - table, - oldRow, - user: sdk.users.getUserContextBindings(ctx.user), - }) + + ctx.eventEmitter?.emitRow({ + eventName: AutomationEventType.ROW_UPDATE, + appId, + row, + table, + oldRow, + user: sdk.users.getUserContextBindings(ctx.user), + }) ctx.message = `${table.name} updated successfully.` ctx.body = row gridSocket?.emitRowUpdate(ctx, row) diff --git a/packages/server/src/events/AutomationEmitter.ts b/packages/server/src/events/AutomationEmitter.ts index a63273bdc0..ec1ea7f28c 100644 --- a/packages/server/src/events/AutomationEmitter.ts +++ b/packages/server/src/events/AutomationEmitter.ts @@ -1,12 +1,12 @@ import { rowEmission, tableEmission } from "./utils" import mainEmitter from "./index" import env from "../environment" -import { Table, Row, DocumentType, App } from "@budibase/types" +import { Table, Row, DocumentType, App, ContextEmitter } from "@budibase/types" import { context } from "@budibase/backend-core" const MAX_AUTOMATIONS_ALLOWED = 5 -class AutomationEmitter { +class AutomationEmitter implements ContextEmitter { chainCount: number metadata: { automationChainCount: number } diff --git a/packages/types/src/sdk/koa.ts b/packages/types/src/sdk/koa.ts index a7df701171..8add047c0b 100644 --- a/packages/types/src/sdk/koa.ts +++ b/packages/types/src/sdk/koa.ts @@ -1,5 +1,14 @@ import { Context, Request } from "koa" -import { User, Role, UserRoles, Account, ConfigType } from "../documents" +import { + User, + Role, + UserRoles, + Account, + ConfigType, + Row, + Table, + AutomationEventType, +} from "../documents" import { FeatureFlag, License } from "../sdk" import { Files } from "formidable" @@ -40,6 +49,7 @@ export interface UserCtx extends Ctx { user: ContextUser roleId?: string + eventEmitter?: ContextEmitter } /** @@ -49,3 +59,12 @@ export interface UserCtx export interface BBContext extends Ctx { user?: ContextUser } + +export interface ContextEmitter { + emitRow: (params: { + eventName: AutomationEventType + appId: string + row: Row + table?: Table + }) => Promise +} From 342d70b3265a559f2d20337471a7ddc2dc4ee9c4 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 24 Oct 2024 13:34:47 +0200 Subject: [PATCH 2/4] Proper typing --- .../server/src/api/controllers/row/index.ts | 46 +++++++++---------- packages/server/src/db/linkedRows/index.ts | 11 +---- packages/server/src/events/BudibaseEmitter.ts | 16 +++++-- packages/server/src/events/utils.ts | 6 +-- packages/types/src/core/events.ts | 8 ++++ packages/types/src/core/index.ts | 1 + packages/types/src/sdk/koa.ts | 26 +++++++++-- 7 files changed, 68 insertions(+), 46 deletions(-) create mode 100644 packages/types/src/core/events.ts diff --git a/packages/server/src/api/controllers/row/index.ts b/packages/server/src/api/controllers/row/index.ts index d3b1d3d5b2..fe29d46700 100644 --- a/packages/server/src/api/controllers/row/index.ts +++ b/packages/server/src/api/controllers/row/index.ts @@ -7,11 +7,11 @@ import * as internal from "./internal" import * as external from "./external" import { isExternalTableID } from "../../../integrations/utils" import { - AutomationEventType, Ctx, DeleteRow, DeleteRowRequest, DeleteRows, + EventType, ExportRowsRequest, ExportRowsResponse, FieldType, @@ -67,7 +67,7 @@ export async function patch( ctx.status = 200 ctx.eventEmitter?.emitRow({ - eventName: AutomationEventType.ROW_UPDATE, + eventName: EventType.ROW_UPDATE, appId, row, table, @@ -104,14 +104,14 @@ export const save = async (ctx: UserCtx) => { sdk.rows.save(sourceId, ctx.request.body, ctx.user?._id) ) ctx.status = 200 - ctx.eventEmitter && - ctx.eventEmitter.emitRow({ - eventName: `row:save`, - appId, - row, - table, - user: sdk.users.getUserContextBindings(ctx.user), - }) + + ctx.eventEmitter?.emitRow({ + eventName: EventType.ROW_SAVE, + appId, + row, + table, + user: sdk.users.getUserContextBindings(ctx.user), + }) ctx.message = `${table.name} saved successfully` // prefer squashed for response ctx.body = row || squashed @@ -183,13 +183,12 @@ async function deleteRows(ctx: UserCtx) { } for (let row of rows) { - ctx.eventEmitter && - ctx.eventEmitter.emitRow({ - eventName: `row:delete`, - appId, - row, - user: sdk.users.getUserContextBindings(ctx.user), - }) + ctx.eventEmitter?.emitRow({ + eventName: EventType.ROW_DELETE, + appId, + row, + user: sdk.users.getUserContextBindings(ctx.user), + }) gridSocket?.emitRowDeletion(ctx, row) } return rows @@ -204,13 +203,12 @@ async function deleteRow(ctx: UserCtx) { await quotas.removeRow() } - ctx.eventEmitter && - ctx.eventEmitter.emitRow({ - eventName: `row:delete`, - appId, - row: resp.row, - user: sdk.users.getUserContextBindings(ctx.user), - }) + ctx.eventEmitter?.emitRow({ + eventName: EventType.ROW_DELETE, + appId, + row: resp.row, + user: sdk.users.getUserContextBindings(ctx.user), + }) gridSocket?.emitRowDeletion(ctx, resp.row) return resp diff --git a/packages/server/src/db/linkedRows/index.ts b/packages/server/src/db/linkedRows/index.ts index fbb83b49a5..73ac695878 100644 --- a/packages/server/src/db/linkedRows/index.ts +++ b/packages/server/src/db/linkedRows/index.ts @@ -17,6 +17,7 @@ import { import { context, features } from "@budibase/backend-core" import { ContextUser, + EventType, FeatureFlag, FieldType, LinkDocumentValue, @@ -44,15 +45,7 @@ const INVALID_DISPLAY_COLUMN_TYPE = [ * This functionality makes sure that when rows with links are created, updated or deleted they are processed * correctly - making sure that no stale links are left around and that all links have been made successfully. */ - -export const EventType = { - ROW_SAVE: "row:save", - ROW_UPDATE: "row:update", - ROW_DELETE: "row:delete", - TABLE_SAVE: "table:save", - TABLE_UPDATED: "table:updated", - TABLE_DELETE: "table:delete", -} +export { EventType } from "@budibase/types" function clearRelationshipFields(schema: TableSchema, rows: Row[]) { for (let [key, field] of Object.entries(schema)) { diff --git a/packages/server/src/events/BudibaseEmitter.ts b/packages/server/src/events/BudibaseEmitter.ts index c8983096d0..9fc5c2f906 100644 --- a/packages/server/src/events/BudibaseEmitter.ts +++ b/packages/server/src/events/BudibaseEmitter.ts @@ -1,6 +1,12 @@ import { EventEmitter } from "events" import { rowEmission, tableEmission } from "./utils" -import { Table, Row, User } from "@budibase/types" +import { + Table, + Row, + UserBindings, + EventType, + ContextEmitter, +} from "@budibase/types" /** * keeping event emitter in one central location as it might be used for things other than @@ -12,7 +18,7 @@ import { Table, Row, User } from "@budibase/types" * Extending the standard emitter to some syntactic sugar and standardisation to the emitted event. * This is specifically quite important for template strings used in automations. */ -class BudibaseEmitter extends EventEmitter { +class BudibaseEmitter extends EventEmitter implements ContextEmitter { emitRow({ eventName, appId, @@ -21,17 +27,17 @@ class BudibaseEmitter extends EventEmitter { oldRow, user, }: { - eventName: string + eventName: EventType.ROW_SAVE | EventType.ROW_DELETE | EventType.ROW_UPDATE appId: string row: Row table?: Table oldRow?: Row - user: User + user: UserBindings }) { rowEmission({ emitter: this, eventName, appId, row, table, oldRow, user }) } - emitTable(eventName: string, appId: string, table?: Table) { + emitTable(eventName: EventType, appId: string, table?: Table) { tableEmission({ emitter: this, eventName, appId, table }) } diff --git a/packages/server/src/events/utils.ts b/packages/server/src/events/utils.ts index 5e4a1bebbf..9cb5eef187 100644 --- a/packages/server/src/events/utils.ts +++ b/packages/server/src/events/utils.ts @@ -1,4 +1,4 @@ -import { Table, Row, User } from "@budibase/types" +import { Table, Row, UserBindings } from "@budibase/types" import BudibaseEmitter from "./BudibaseEmitter" type BBEventOpts = { @@ -9,7 +9,7 @@ type BBEventOpts = { row?: Row oldRow?: Row metadata?: any - user?: User + user?: UserBindings } interface BBEventTable extends Table { @@ -25,7 +25,7 @@ type BBEvent = { id?: string revision?: string metadata?: any - user?: User + user?: UserBindings } export function rowEmission({ diff --git a/packages/types/src/core/events.ts b/packages/types/src/core/events.ts new file mode 100644 index 0000000000..3ce948b3b5 --- /dev/null +++ b/packages/types/src/core/events.ts @@ -0,0 +1,8 @@ +export const enum EventType { + ROW_SAVE = "row:save", + ROW_UPDATE = "row:update", + ROW_DELETE = "row:delete", + TABLE_SAVE = "table:save", + TABLE_UPDATED = "table:updated", + TABLE_DELETE = "table:delete", +} diff --git a/packages/types/src/core/index.ts b/packages/types/src/core/index.ts index b5cbd7affa..73cc7d35e0 100644 --- a/packages/types/src/core/index.ts +++ b/packages/types/src/core/index.ts @@ -1 +1,2 @@ export * from "./installation" +export * from "./events" diff --git a/packages/types/src/sdk/koa.ts b/packages/types/src/sdk/koa.ts index 8add047c0b..f0a81a7886 100644 --- a/packages/types/src/sdk/koa.ts +++ b/packages/types/src/sdk/koa.ts @@ -7,10 +7,11 @@ import { ConfigType, Row, Table, - AutomationEventType, + UserBindings, } from "../documents" import { FeatureFlag, License } from "../sdk" import { Files } from "formidable" +import { EventType } from "../core" export interface ContextUser extends Omit { globalId?: string @@ -61,10 +62,25 @@ export interface BBContext extends Ctx { } export interface ContextEmitter { - emitRow: (params: { - eventName: AutomationEventType + emitRow(values: { + eventName: EventType.ROW_SAVE appId: string row: Row - table?: Table - }) => Promise + table: Table + user: UserBindings + }): void + emitRow(values: { + eventName: EventType.ROW_UPDATE + appId: string + row: Row + table: Table + oldRow: Row + user: UserBindings + }): void + emitRow(values: { + eventName: EventType.ROW_DELETE + appId: string + row: Row + user: UserBindings + }): void } From 637c13c1af339313f99763ff10d1e1c6cb861581 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 24 Oct 2024 13:44:20 +0200 Subject: [PATCH 3/4] Proper typing for emitTable --- packages/server/src/api/controllers/table/index.ts | 8 ++++---- packages/types/src/sdk/koa.ts | 5 +++++ 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/server/src/api/controllers/table/index.ts b/packages/server/src/api/controllers/table/index.ts index 2f2f93bffe..77c1f3923a 100644 --- a/packages/server/src/api/controllers/table/index.ts +++ b/packages/server/src/api/controllers/table/index.ts @@ -16,6 +16,7 @@ import { BulkImportResponse, CsvToJsonRequest, CsvToJsonResponse, + EventType, FetchTablesResponse, FieldType, MigrateRequest, @@ -129,8 +130,7 @@ export async function save(ctx: UserCtx) { } ctx.status = 200 ctx.message = `Table ${table.name} saved successfully.` - ctx.eventEmitter && - ctx.eventEmitter.emitTable(`table:save`, appId, { ...savedTable }) + ctx.eventEmitter?.emitTable(EventType.TABLE_SAVE, appId, { ...savedTable }) ctx.body = savedTable savedTable = await processTable(savedTable) @@ -143,8 +143,8 @@ export async function destroy(ctx: UserCtx) { await sdk.rowActions.deleteAll(tableId) const deletedTable = await pickApi({ tableId }).destroy(ctx) await events.table.deleted(deletedTable) - ctx.eventEmitter && - ctx.eventEmitter.emitTable(`table:delete`, appId, deletedTable) + + ctx.eventEmitter?.emitTable(EventType.TABLE_DELETE, appId, deletedTable) ctx.status = 200 ctx.table = deletedTable ctx.body = { message: `Table ${tableId} deleted.` } diff --git a/packages/types/src/sdk/koa.ts b/packages/types/src/sdk/koa.ts index f0a81a7886..95ea2b652f 100644 --- a/packages/types/src/sdk/koa.ts +++ b/packages/types/src/sdk/koa.ts @@ -83,4 +83,9 @@ export interface ContextEmitter { row: Row user: UserBindings }): void + emitTable( + eventName: EventType.TABLE_SAVE | EventType.TABLE_DELETE, + appId: string, + table?: Table + ): void } From 4dedde5165b9c876480e8077f5bbe63ad55d9ee3 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Thu, 24 Oct 2024 13:51:44 +0200 Subject: [PATCH 4/4] Add missing rowaction --- .../server/src/events/AutomationEmitter.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/packages/server/src/events/AutomationEmitter.ts b/packages/server/src/events/AutomationEmitter.ts index ec1ea7f28c..a95acd0877 100644 --- a/packages/server/src/events/AutomationEmitter.ts +++ b/packages/server/src/events/AutomationEmitter.ts @@ -1,7 +1,15 @@ import { rowEmission, tableEmission } from "./utils" import mainEmitter from "./index" import env from "../environment" -import { Table, Row, DocumentType, App, ContextEmitter } from "@budibase/types" +import { + Table, + Row, + DocumentType, + App, + ContextEmitter, + EventType, + UserBindings, +} from "@budibase/types" import { context } from "@budibase/backend-core" const MAX_AUTOMATIONS_ALLOWED = 5 @@ -36,11 +44,15 @@ class AutomationEmitter implements ContextEmitter { appId, row, table, + oldRow, + user, }: { - eventName: string + eventName: EventType.ROW_SAVE | EventType.ROW_DELETE | EventType.ROW_UPDATE appId: string row: Row table?: Table + oldRow?: Row + user: UserBindings }) { let MAX_AUTOMATION_CHAIN = await this.getMaxAutomationChain() @@ -54,7 +66,9 @@ class AutomationEmitter implements ContextEmitter { appId, row, table, + oldRow, metadata: this.metadata, + user, }) }