Skip to content

Commit

Permalink
Merge branch 'master' into form-screen-templates-use-id
Browse files Browse the repository at this point in the history
  • Loading branch information
Ghrehh committed Jul 29, 2024
2 parents 7e5078a + 9a181c9 commit bfa032a
Show file tree
Hide file tree
Showing 25 changed files with 151 additions and 73 deletions.
8 changes: 4 additions & 4 deletions packages/backend-core/tests/core/utilities/jestUtils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {
CONSTANT_EXTERNAL_ROW_COLS,
CONSTANT_INTERNAL_ROW_COLS,
PROTECTED_EXTERNAL_COLUMNS,
PROTECTED_INTERNAL_COLUMNS,
} from "@budibase/shared-core"

export function expectFunctionWasCalledTimesWith(
Expand All @@ -14,7 +14,7 @@ export function expectFunctionWasCalledTimesWith(
}

export const expectAnyInternalColsAttributes: {
[K in (typeof CONSTANT_INTERNAL_ROW_COLS)[number]]: any
[K in (typeof PROTECTED_INTERNAL_COLUMNS)[number]]: any
} = {
tableId: expect.anything(),
type: expect.anything(),
Expand All @@ -25,7 +25,7 @@ export const expectAnyInternalColsAttributes: {
}

export const expectAnyExternalColsAttributes: {
[K in (typeof CONSTANT_EXTERNAL_ROW_COLS)[number]]: any
[K in (typeof PROTECTED_EXTERNAL_COLUMNS)[number]]: any
} = {
tableId: expect.anything(),
_id: expect.anything(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
SWITCHABLE_TYPES,
ValidColumnNameRegex,
helpers,
CONSTANT_INTERNAL_ROW_COLS,
CONSTANT_EXTERNAL_ROW_COLS,
PROTECTED_INTERNAL_COLUMNS,
PROTECTED_EXTERNAL_COLUMNS,
} from "@budibase/shared-core"
import { createEventDispatcher, getContext, onMount } from "svelte"
import { cloneDeep } from "lodash/fp"
Expand Down Expand Up @@ -489,8 +489,8 @@
}
const newError = {}
const prohibited = externalTable
? CONSTANT_EXTERNAL_ROW_COLS
: CONSTANT_INTERNAL_ROW_COLS
? PROTECTED_EXTERNAL_COLUMNS
: PROTECTED_INTERNAL_COLUMNS
if (!externalTable && fieldInfo.name?.startsWith("_")) {
newError.name = `Column name cannot start with an underscore.`
} else if (fieldInfo.name && !fieldInfo.name.match(ValidColumnNameRegex)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,9 @@
<Divider />
<Layout gap="XS" noPadding>
<Heading size="XS">History</Heading>
<Body size="S">Free plan stores up to 1 day of automation history</Body>
{#if licensePlan?.type === Constants.PlanType.FREE}
<Body size="S">Free plan stores up to 1 day of automation history</Body>
{/if}
</Layout>
<div class="controls">
<div class="search">
Expand Down
5 changes: 2 additions & 3 deletions packages/server/src/api/controllers/row/utils/basic.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
// need to handle table name + field or just field, depending on if relationships used
import { FieldType, Row, Table } from "@budibase/types"
import { helpers } from "@budibase/shared-core"
import { helpers, PROTECTED_INTERNAL_COLUMNS } from "@budibase/shared-core"
import { generateRowIdField } from "../../../../integrations/utils"
import { CONSTANT_INTERNAL_ROW_COLS } from "../../../../db/utils"

function extractFieldValue({
row,
Expand Down Expand Up @@ -94,7 +93,7 @@ export function basicProcessing({
thisRow._rev = "rev"
} else {
const columns = Object.keys(table.schema)
for (let internalColumn of [...CONSTANT_INTERNAL_ROW_COLS, ...columns]) {
for (let internalColumn of [...PROTECTED_INTERNAL_COLUMNS, ...columns]) {
thisRow[internalColumn] = extractFieldValue({
row,
tableName: table._id!,
Expand Down
11 changes: 9 additions & 2 deletions packages/server/src/api/controllers/rowAction/run.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
export function run() {
throw new Error("Function not implemented.")
import { RowActionTriggerRequest, Ctx } from "@budibase/types"
import sdk from "../../../sdk"

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)
ctx.status = 200
}
3 changes: 3 additions & 0 deletions packages/server/src/api/controllers/table/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ export async function save(
sourceType: rest.sourceType || TableSourceType.INTERNAL,
}

const isImport = !!rows

if (!tableToSave.views) {
tableToSave.views = {}
}
Expand All @@ -35,6 +37,7 @@ export async function save(
rowsToImport: rows,
tableId: ctx.request.body._id,
renaming,
isImport,
})

return table
Expand Down
19 changes: 14 additions & 5 deletions packages/server/src/api/routes/rowAction.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import Router from "@koa/router"
import Joi from "joi"
import { middleware, permissions } from "@budibase/backend-core"
import * as rowActionController from "../controllers/rowAction"
import { authorizedResource } from "../../middleware/authorized"

import { middleware, permissions } from "@budibase/backend-core"
import Joi from "joi"

const { PermissionLevel, PermissionType } = permissions

export function rowActionValidator() {
function rowActionValidator() {
return middleware.joiValidator.body(
Joi.object({
name: Joi.string().required(),
Expand All @@ -16,6 +15,15 @@ export function rowActionValidator() {
)
}

function rowTriggerValidator() {
return middleware.joiValidator.body(
Joi.object({
rowId: Joi.string().required(),
}),
{ allowUnknown: false }
)
}

const router: Router = new Router()

// CRUD endpoints
Expand Down Expand Up @@ -45,7 +53,8 @@ router

// Other endpoints
.post(
"/api/tables/:tableId/actions/:actionId/run",
"/api/tables/:tableId/actions/:actionId/trigger",
rowTriggerValidator(),
authorizedResource(PermissionType.TABLE, PermissionLevel.READ, "tableId"),
rowActionController.run
)
Expand Down
3 changes: 2 additions & 1 deletion packages/server/src/api/routes/tests/row.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import * as setup from "./utilities"

import {
DatabaseName,
getDatasource,
Expand All @@ -7,7 +9,6 @@ import {
import tk from "timekeeper"
import emitter from "../../../../src/events"
import { outputProcessing } from "../../../utilities/rowProcessor"
import * as setup from "./utilities"
import { context, InternalTable, tenancy } from "@budibase/backend-core"
import { quotas } from "@budibase/pro"
import {
Expand Down
32 changes: 26 additions & 6 deletions packages/server/src/automations/triggerInfo/rowAction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import {

export const definition: AutomationTriggerSchema = {
type: AutomationStepType.TRIGGER,
name: "Row Action",
event: AutomationEventType.ROW_ACTION, // TODO
icon: "Workflow", // TODO
tagline:
"Row action triggered in {{inputs.enriched.table.name}} by {{inputs.enriched.row._id}}",
name: "Row Action",
description: "TODO description",
icon: "Workflow",
description: "TODO description", // TODO
stepId: AutomationTriggerStepId.ROW_ACTION,
inputs: {},
schema: {
Expand All @@ -28,8 +29,27 @@ export const definition: AutomationTriggerSchema = {
},
required: ["tableId"],
},
outputs: { properties: {} },
outputs: {
properties: {
id: {
type: AutomationIOType.STRING,
description: "Row ID - can be used for updating",
},
revision: {
type: AutomationIOType.STRING,
description: "Revision of row",
},
table: {
type: AutomationIOType.OBJECT,
customType: AutomationCustomIOType.TABLE,
title: "The table linked to the row action",
},
row: {
type: AutomationIOType.OBJECT,
customType: AutomationCustomIOType.ROW,
description: "The row linked to the row action",
},
},
},
},

event: AutomationEventType.ROW_SAVE,
}
17 changes: 11 additions & 6 deletions packages/server/src/automations/triggers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import {
AutomationStatus,
} from "@budibase/types"
import { executeInThread } from "../threads/automation"
import { dataFilters } from "@budibase/shared-core"
import { dataFilters, sdk } from "@budibase/shared-core"

export const TRIGGER_DEFINITIONS = definitions
const JOB_OPTS = {
Expand Down Expand Up @@ -121,17 +121,15 @@ function rowPassesFilters(row: Row, filters: SearchFilters) {

export async function externalTrigger(
automation: Automation,
params: { fields: Record<string, any>; timeout?: number },
params: { fields: Record<string, any>; timeout?: number; appId?: string },
{ getResponses }: { getResponses?: boolean } = {}
): Promise<any> {
if (automation.disabled) {
throw new Error("Automation is disabled")
}

if (
automation.definition != null &&
automation.definition.trigger != null &&
automation.definition.trigger.stepId === definitions.APP.stepId &&
automation.definition.trigger.stepId === "APP" &&
sdk.automations.isAppAction(automation) &&
!(await checkTestFlag(automation._id!))
) {
// values are likely to be submitted as strings, so we shall convert to correct type
Expand All @@ -141,6 +139,13 @@ export async function externalTrigger(
coercedFields[key] = coerce(params.fields[key], fields[key])
}
params.fields = coercedFields
} else if (sdk.automations.isRowAction(automation)) {
params = {
...params,
// Until we don't refactor all the types, we want to flatten the nested "fields" object
...params.fields,
fields: {},
}
}
const data: AutomationData = { automation, event: params }

Expand Down
8 changes: 0 additions & 8 deletions packages/server/src/db/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,6 @@ export const getUserMetadataParams = dbCore.getUserMetadataParams
export const generateUserMetadataID = dbCore.generateUserMetadataID
export const getGlobalIDFromUserMetadataID =
dbCore.getGlobalIDFromUserMetadataID
export const CONSTANT_INTERNAL_ROW_COLS = [
"_id",
"_rev",
"type",
"createdAt",
"updatedAt",
"tableId",
]

/**
* Gets parameters for retrieving tables, this is a utility function for the getDocParams function.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { sample } from "lodash/fp"
import { Automation, AutomationTriggerStepId } from "@budibase/types"
import { generator } from "@budibase/backend-core/tests"
import TestConfiguration from "../../../../tests/utilities/TestConfiguration"
import automationSdk from "../"
import { structures } from "../../../../api/routes/tests/utilities"
import TestConfiguration from "../../../../tests/utilities/TestConfiguration"

describe("automation sdk", () => {
const config = new TestConfiguration()
Expand Down
3 changes: 1 addition & 2 deletions packages/server/src/sdk/app/automations/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
TableRowActions,
} from "@budibase/types"
import { sdk as coreSdk } from "@budibase/shared-core"
import sdk from "../../../sdk"

export function checkForCollectStep(automation: Automation) {
return automation.definition.steps.some(
Expand All @@ -15,8 +16,6 @@ export function checkForCollectStep(automation: Automation) {
export async function getBuilderData(
automations: Automation[]
): Promise<Record<string, AutomationBuilderData>> {
const sdk = (await import("../../../sdk")).default

const tableNameCache: Record<string, string> = {}
async function getTableName(tableId: string) {
if (!tableNameCache[tableId]) {
Expand Down
29 changes: 28 additions & 1 deletion packages/server/src/sdk/app/rowActions.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { context, HTTPError, utils } from "@budibase/backend-core"

import { generateRowActionsID } from "../../db/utils"
import {
SEPARATOR,
TableRowActions,
VirtualDocumentType,
} from "@budibase/types"
import { generateRowActionsID } from "../../db/utils"
import automations from "./automations"
import { definitions as TRIGGER_DEFINITIONS } from "../../automations/triggerInfo"
import * as triggers from "../../automations/triggers"
import sdk from ".."

function ensureUniqueAndThrow(
doc: TableRowActions,
Expand Down Expand Up @@ -143,3 +145,28 @@ export async function remove(tableId: string, rowActionId: string) {
const db = context.getAppDB()
await db.put(actionsDoc)
}

export async function run(tableId: any, rowActionId: any, rowId: string) {
const table = await sdk.tables.getTable(tableId)
if (!table) {
throw new HTTPError("Table not found", 404)
}

const { actions } = await get(tableId)

const rowAction = actions[rowActionId]
if (!rowAction) {
throw new HTTPError("Row action not found", 404)
}

const automation = await sdk.automations.get(rowAction.automationId)

const row = await sdk.rows.find(tableId, rowId)
await triggers.externalTrigger(automation, {
fields: {
row,
table,
},
appId: context.getAppId(),
})
}
4 changes: 2 additions & 2 deletions packages/server/src/sdk/app/rows/search/external.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
breakExternalTableId,
breakRowIdField,
} from "../../../../integrations/utils"
import { utils, CONSTANT_EXTERNAL_ROW_COLS } from "@budibase/shared-core"
import { utils, PROTECTED_EXTERNAL_COLUMNS } from "@budibase/shared-core"
import { ExportRowsParams, ExportRowsResult } from "./types"
import { HTTPError } from "@budibase/backend-core"
import pick from "lodash/pick"
Expand Down Expand Up @@ -99,7 +99,7 @@ export async function search(
}

if (options.fields) {
const fields = [...options.fields, ...CONSTANT_EXTERNAL_ROW_COLS]
const fields = [...options.fields, ...PROTECTED_EXTERNAL_COLUMNS]
rows = rows.map((r: any) => pick(r, fields))
}

Expand Down
4 changes: 2 additions & 2 deletions packages/server/src/sdk/app/rows/search/internal.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { context, HTTPError } from "@budibase/backend-core"
import { CONSTANT_INTERNAL_ROW_COLS } from "@budibase/shared-core"
import { PROTECTED_INTERNAL_COLUMNS } from "@budibase/shared-core"
import env from "../../../../environment"
import { fullSearch, paginatedSearch } from "./utils"
import { getRowParams, InternalTables } from "../../../../db/utils"
Expand Down Expand Up @@ -75,7 +75,7 @@ export async function search(
}

if (options.fields) {
const fields = [...options.fields, ...CONSTANT_INTERNAL_ROW_COLS]
const fields = [...options.fields, ...PROTECTED_INTERNAL_COLUMNS]
response.rows = response.rows.map((r: any) => pick(r, fields))
}

Expand Down
Loading

0 comments on commit bfa032a

Please sign in to comment.