Skip to content

Commit

Permalink
Merge branch 'master' into v3-ui
Browse files Browse the repository at this point in the history
  • Loading branch information
adrinr authored Oct 22, 2024
2 parents 9d4cbaa + 44fbe70 commit 23cf44b
Show file tree
Hide file tree
Showing 22 changed files with 179 additions and 35 deletions.
2 changes: 1 addition & 1 deletion packages/backend-core/src/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ function getPackageJsonFields(): {
if (isDev() && !isTest()) {
try {
const lerna = getParentFile("lerna.json")
localVersion = lerna.version
localVersion = `${lerna.version}+local`
} catch {
//
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script>
import { goto } from "@roxi/routify"
import { automationStore } from "stores/builder"
import {
notifications,
Expand Down Expand Up @@ -32,11 +33,12 @@
triggerVal.stepId,
triggerVal
)
await automationStore.actions.create(name, trigger)
const automation = await automationStore.actions.create(name, trigger)
if (triggerVal.stepId === TriggerStepID.WEBHOOK) {
webhookModal.show()
}
notifications.success(`Automation ${name} created`)
$goto(`../automation/${automation._id}`)
} catch (error) {
notifications.error("Error creating automation")
}
Expand Down
3 changes: 3 additions & 0 deletions packages/server/src/api/controllers/automation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ export async function trigger(ctx: UserCtx) {
automation,
{
fields: ctx.request.body.fields,
user: sdk.users.getUserContextBindings(ctx.user),
timeout:
ctx.request.body.timeout * 1000 || env.AUTOMATION_THREAD_TIMEOUT,
},
Expand All @@ -183,6 +184,7 @@ export async function trigger(ctx: UserCtx) {
await triggers.externalTrigger(automation, {
...ctx.request.body,
appId: ctx.appId,
user: sdk.users.getUserContextBindings(ctx.user),
})
ctx.body = {
message: `Automation ${automation._id} has been triggered.`,
Expand Down Expand Up @@ -212,6 +214,7 @@ export async function test(ctx: UserCtx) {
{
...testInput,
appId: ctx.appId,
user: sdk.users.getUserContextBindings(ctx.user),
},
{ getResponses: true }
)
Expand Down
35 changes: 30 additions & 5 deletions packages/server/src/api/controllers/row/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ export async function patch(
}
ctx.status = 200
ctx.eventEmitter &&
ctx.eventEmitter.emitRow(`row:update`, appId, row, table, oldRow)
ctx.eventEmitter.emitRow({
eventName: `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)
Expand Down Expand Up @@ -96,7 +103,14 @@ export const save = async (ctx: UserCtx<Row, Row>) => {
sdk.rows.save(sourceId, ctx.request.body, ctx.user?._id)
)
ctx.status = 200
ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:save`, appId, row, table)
ctx.eventEmitter &&
ctx.eventEmitter.emitRow({
eventName: `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
Expand Down Expand Up @@ -168,10 +182,15 @@ async function deleteRows(ctx: UserCtx<DeleteRowRequest>) {
}

for (let row of rows) {
ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:delete`, appId, row)
ctx.eventEmitter &&
ctx.eventEmitter.emitRow({
eventName: `row:delete`,
appId,
row,
user: sdk.users.getUserContextBindings(ctx.user),
})
gridSocket?.emitRowDeletion(ctx, row)
}

return rows
}

Expand All @@ -184,7 +203,13 @@ async function deleteRow(ctx: UserCtx<DeleteRowRequest>) {
await quotas.removeRow()
}

ctx.eventEmitter && ctx.eventEmitter.emitRow(`row:delete`, appId, resp.row)
ctx.eventEmitter &&
ctx.eventEmitter.emitRow({
eventName: `row:delete`,
appId,
row: resp.row,
user: sdk.users.getUserContextBindings(ctx.user),
})
gridSocket?.emitRowDeletion(ctx, resp.row)

return resp
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/api/controllers/rowAction/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ export async function run(ctx: Ctx<RowActionTriggerRequest, void>) {
const { tableId, actionId } = ctx.params
const { rowId } = ctx.request.body

await sdk.rowActions.run(tableId, actionId, rowId)
await sdk.rowActions.run(tableId, actionId, rowId, ctx.user)
ctx.status = 200
}
15 changes: 10 additions & 5 deletions packages/server/src/api/controllers/static/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import { InvalidFileExtensions } from "@budibase/shared-core"
import AppComponent from "./templates/BudibaseApp.svelte"
import { join } from "../../../utilities/centralPath"
import * as uuid from "uuid"
import { devClientVersion, ObjectStoreBuckets } from "../../../constants"
import { ObjectStoreBuckets } from "../../../constants"
import { processString } from "@budibase/string-templates"
import {
loadHandlebarsFile,
NODE_MODULES_PATH,
shouldServeLocally,
TOP_LEVEL_PATH,
} from "../../../utilities/fileSystem"
import env from "../../../environment"
Expand Down Expand Up @@ -257,25 +258,29 @@ export const serveBuilderPreview = async function (ctx: Ctx) {
export const serveClientLibrary = async function (ctx: Ctx) {
const version = ctx.request.query.version

if (Array.isArray(version)) {
ctx.throw(400)
}

const appId = context.getAppId() || (ctx.request.query.appId as string)
let rootPath = join(NODE_MODULES_PATH, "@budibase", "client", "dist")
if (!appId) {
ctx.throw(400, "No app ID provided - cannot fetch client library.")
}
if (env.isProd() || (env.isDev() && version !== devClientVersion)) {

const serveLocally = shouldServeLocally(version || "")
if (!serveLocally) {
ctx.body = await objectStore.getReadStream(
ObjectStoreBuckets.APPS,
objectStore.clientLibraryPath(appId!)
)
ctx.set("Content-Type", "application/javascript")
} else if (env.isDev() && version === devClientVersion) {
} else {
// incase running from TS directly
const tsPath = join(require.resolve("@budibase/client"), "..")
return send(ctx, "budibase-client.js", {
root: !fs.existsSync(rootPath) ? tsPath : rootPath,
})
} else {
ctx.throw(500, "Unable to retrieve client library.")
}
}

Expand Down
5 changes: 4 additions & 1 deletion packages/server/src/api/routes/tests/rowAction.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,6 @@ describe("/rowsActions", () => {
it("can trigger an automation given valid data", async () => {
expect(await getAutomationLogs()).toBeEmpty()
await config.api.rowAction.trigger(viewId, rowAction.id, { rowId })

const automationLogs = await getAutomationLogs()
expect(automationLogs).toEqual([
expect.objectContaining({
Expand All @@ -785,6 +784,10 @@ describe("/rowsActions", () => {
...(await config.api.table.get(tableId)),
views: expect.anything(),
},
user: expect.objectContaining({
_id: "ro_ta_users_" + config.getUser()._id,
}),

automation: expect.objectContaining({
_id: rowAction.automationId,
}),
Expand Down
34 changes: 34 additions & 0 deletions packages/server/src/automations/tests/scenarios/scenarios.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -482,4 +482,38 @@ describe("Automation Scenarios", () => {
}
)
})

it("Check user is passed through from row trigger", async () => {
const table = await config.createTable()

const builder = createAutomationBuilder({
name: "Test a user is successfully passed from the trigger",
})

const results = await builder
.rowUpdated(
{ tableId: table._id! },
{
row: { name: "Test", description: "TEST" },
id: "1234",
}
)
.serverLog({ text: "{{ [user].[email] }}" })
.run()

expect(results.steps[0].outputs.message).toContain("example.com")
})

it("Check user is passed through from app trigger", async () => {
const builder = createAutomationBuilder({
name: "Test a user is successfully passed from the trigger",
})

const results = await builder
.appAction({ fields: {} })
.serverLog({ text: "{{ [user].[email] }}" })
.run()

expect(results.steps[0].outputs.message).toContain("example.com")
})
})
8 changes: 7 additions & 1 deletion packages/server/src/automations/triggers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
AutomationStoppedReason,
AutomationStatus,
AutomationRowEvent,
UserBindings,
} from "@budibase/types"
import { executeInThread } from "../threads/automation"
import { dataFilters, sdk } from "@budibase/shared-core"
Expand Down Expand Up @@ -140,7 +141,12 @@ function rowPassesFilters(row: Row, filters: SearchFilters) {

export async function externalTrigger(
automation: Automation,
params: { fields: Record<string, any>; timeout?: number; appId?: string },
params: {
fields: Record<string, any>
timeout?: number
appId?: string
user?: UserBindings
},
{ getResponses }: { getResponses?: boolean } = {}
): Promise<any> {
if (automation.disabled) {
Expand Down
2 changes: 0 additions & 2 deletions packages/server/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,6 @@ export enum AutomationErrors {
FAILURE_CONDITION = "FAILURE_CONDITION_MET",
}

export const devClientVersion = "0.0.0"

// pass through the list from the auth/core lib
export const ObjectStoreBuckets = objectStore.ObjectStoreBuckets
export const MAX_AUTOMATION_RECURRING_ERRORS = 5
Expand Down
3 changes: 2 additions & 1 deletion packages/server/src/definitions/automations.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AutomationResults, LoopStepType } from "@budibase/types"
import { AutomationResults, LoopStepType, UserBindings } from "@budibase/types"

export interface LoopInput {
option: LoopStepType
Expand All @@ -18,5 +18,6 @@ export interface AutomationContext extends AutomationResults {
stepsById: Record<string, any>
stepsByName: Record<string, any>
env?: Record<string, string>
user?: UserBindings
trigger: any
}
12 changes: 11 additions & 1 deletion packages/server/src/events/AutomationEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,17 @@ class AutomationEmitter {
}
}

async emitRow(eventName: string, appId: string, row: Row, table?: Table) {
async emitRow({
eventName,
appId,
row,
table,
}: {
eventName: string
appId: string
row: Row
table?: Table
}) {
let MAX_AUTOMATION_CHAIN = await this.getMaxAutomationChain()

// don't emit even if we've reached max automation chain
Expand Down
24 changes: 16 additions & 8 deletions packages/server/src/events/BudibaseEmitter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { EventEmitter } from "events"
import { rowEmission, tableEmission } from "./utils"
import { Table, Row } from "@budibase/types"
import { Table, Row, User } from "@budibase/types"

/**
* keeping event emitter in one central location as it might be used for things other than
Expand All @@ -13,14 +13,22 @@ import { Table, Row } from "@budibase/types"
* This is specifically quite important for template strings used in automations.
*/
class BudibaseEmitter extends EventEmitter {
emitRow(
eventName: string,
appId: string,
row: Row,
table?: Table,
emitRow({
eventName,
appId,
row,
table,
oldRow,
user,
}: {
eventName: string
appId: string
row: Row
table?: Table
oldRow?: Row
) {
rowEmission({ emitter: this, eventName, appId, row, table, oldRow })
user: User
}) {
rowEmission({ emitter: this, eventName, appId, row, table, oldRow, user })
}

emitTable(eventName: string, appId: string, table?: Table) {
Expand Down
6 changes: 5 additions & 1 deletion packages/server/src/events/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Table, Row } from "@budibase/types"
import { Table, Row, User } from "@budibase/types"
import BudibaseEmitter from "./BudibaseEmitter"

type BBEventOpts = {
Expand All @@ -9,6 +9,7 @@ type BBEventOpts = {
row?: Row
oldRow?: Row
metadata?: any
user?: User
}

interface BBEventTable extends Table {
Expand All @@ -24,6 +25,7 @@ type BBEvent = {
id?: string
revision?: string
metadata?: any
user?: User
}

export function rowEmission({
Expand All @@ -34,12 +36,14 @@ export function rowEmission({
table,
metadata,
oldRow,
user,
}: BBEventOpts) {
let event: BBEvent = {
row,
oldRow,
appId,
tableId: row?.tableId,
user,
}
if (table) {
event.table = table
Expand Down
9 changes: 8 additions & 1 deletion packages/server/src/sdk/app/rowActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
AutomationTriggerStepId,
SEPARATOR,
TableRowActions,
User,
VirtualDocumentType,
} from "@budibase/types"
import { generateRowActionsID } from "../../db/utils"
Expand Down Expand Up @@ -236,7 +237,12 @@ export async function remove(tableId: string, rowActionId: string) {
})
}

export async function run(tableId: any, rowActionId: any, rowId: string) {
export async function run(
tableId: any,
rowActionId: any,
rowId: string,
user: User
) {
const table = await sdk.tables.getTable(tableId)
if (!table) {
throw new HTTPError("Table not found", 404)
Expand All @@ -260,6 +266,7 @@ export async function run(tableId: any, rowActionId: any, rowId: string) {
row,
table,
},
user,
appId: context.getAppId(),
},
{ getResponses: true }
Expand Down
Loading

0 comments on commit 23cf44b

Please sign in to comment.