Merge branch 'master' into fix/feature-flag-checks
This commit is contained in:
commit
483bb585c3
|
@ -0,0 +1,51 @@
|
|||
import {
|
||||
AutomationActionStepId,
|
||||
AutomationCustomIOType,
|
||||
AutomationIOType,
|
||||
AutomationStepDefinition,
|
||||
AutomationStepType,
|
||||
} from "@budibase/types"
|
||||
|
||||
export const definition: AutomationStepDefinition = {
|
||||
name: "Branch",
|
||||
icon: "Branch3",
|
||||
tagline: "Branch from this step",
|
||||
description: "Branching",
|
||||
stepId: AutomationActionStepId.BRANCH,
|
||||
internal: true,
|
||||
features: {},
|
||||
inputs: {},
|
||||
schema: {
|
||||
inputs: {
|
||||
properties: {
|
||||
branches: {
|
||||
properties: {
|
||||
name: {
|
||||
type: AutomationIOType.STRING,
|
||||
},
|
||||
condition: {
|
||||
customType: AutomationCustomIOType.FILTERS,
|
||||
},
|
||||
},
|
||||
},
|
||||
children: {
|
||||
type: AutomationIOType.ARRAY,
|
||||
},
|
||||
},
|
||||
required: ["conditions"],
|
||||
},
|
||||
outputs: {
|
||||
properties: {
|
||||
branchName: {
|
||||
type: AutomationIOType.STRING,
|
||||
},
|
||||
result: {
|
||||
type: AutomationIOType.BOOLEAN,
|
||||
description: "Whether the condition was met",
|
||||
},
|
||||
},
|
||||
required: ["output"],
|
||||
},
|
||||
},
|
||||
type: AutomationStepType.LOGIC,
|
||||
}
|
|
@ -7,7 +7,7 @@ import {
|
|||
ServerLogStepOutputs,
|
||||
FieldType,
|
||||
} from "@budibase/types"
|
||||
import { createAutomationBuilder } from "../utilities/AutomationBuilder"
|
||||
import { createAutomationBuilder } from "../utilities/AutomationTestBuilder"
|
||||
import { DatabaseName } from "../../../integrations/tests/utils"
|
||||
|
||||
describe("Automation Scenarios", () => {
|
||||
|
@ -23,6 +23,43 @@ describe("Automation Scenarios", () => {
|
|||
|
||||
afterAll(setup.afterAll)
|
||||
|
||||
// eslint-disable-next-line jest/no-commented-out-tests
|
||||
// describe("Branching automations", () => {
|
||||
// eslint-disable-next-line jest/no-commented-out-tests
|
||||
// it("should run an automation with a trigger, loop, and create row step", async () => {
|
||||
// const builder = createAutomationBuilder({
|
||||
// name: "Test Trigger with Loop and Create Row",
|
||||
// })
|
||||
|
||||
// builder
|
||||
// .serverLog({ text: "Starting automation" })
|
||||
// .branch({
|
||||
// topLevelBranch1: {
|
||||
// steps: stepBuilder =>
|
||||
// stepBuilder.serverLog({ text: "Branch 1" }).branch({
|
||||
// branch1: {
|
||||
// steps: stepBuilder =>
|
||||
// stepBuilder.serverLog({ text: "Branch 1.1" }),
|
||||
// condition: { notEmpty: { column: 10 } },
|
||||
// },
|
||||
// branch2: {
|
||||
// steps: stepBuilder =>
|
||||
// stepBuilder.serverLog({ text: "Branch 1.2" }),
|
||||
// condition: { fuzzy: { column: "sadsd" } },
|
||||
// },
|
||||
// }),
|
||||
// condition: { equal: { column: 10 } },
|
||||
// },
|
||||
// topLevelBranch2: {
|
||||
// steps: stepBuilder => stepBuilder.serverLog({ text: "Branch 2" }),
|
||||
// condition: { equal: { column: 20 } },
|
||||
// },
|
||||
// })
|
||||
// .run()
|
||||
// })
|
||||
|
||||
// })
|
||||
|
||||
describe("Loop automations", () => {
|
||||
it("should run an automation with a trigger, loop, and create row step", async () => {
|
||||
const builder = createAutomationBuilder({
|
||||
|
|
|
@ -30,10 +30,13 @@ import {
|
|||
AutomationStepInputs,
|
||||
AutomationTriggerInputs,
|
||||
ServerLogStepInputs,
|
||||
BranchStepInputs,
|
||||
SearchFilters,
|
||||
Branch,
|
||||
} from "@budibase/types"
|
||||
import {} from "../../steps/loop"
|
||||
import TestConfiguration from "../../../tests/utilities/TestConfiguration"
|
||||
import * as setup from "../utilities"
|
||||
import { definition } from "../../../automations/steps/branch"
|
||||
|
||||
type TriggerOutputs =
|
||||
| RowCreatedTriggerOutputs
|
||||
|
@ -43,69 +46,56 @@ type TriggerOutputs =
|
|||
| CronTriggerOutputs
|
||||
| undefined
|
||||
|
||||
class AutomationBuilder {
|
||||
private automationConfig: Automation = {
|
||||
name: "",
|
||||
definition: {
|
||||
steps: [],
|
||||
trigger: {} as AutomationTrigger,
|
||||
},
|
||||
type: "automation",
|
||||
appId: setup.getConfig().getAppId(),
|
||||
}
|
||||
private config: TestConfiguration = setup.getConfig()
|
||||
private triggerOutputs: TriggerOutputs
|
||||
private triggerSet: boolean = false
|
||||
type StepBuilderFunction = (stepBuilder: StepBuilder) => void
|
||||
|
||||
constructor(options: { name?: string } = {}) {
|
||||
this.automationConfig.name = options.name || `Test Automation ${uuidv4()}`
|
||||
type BranchConfig = {
|
||||
[key: string]: {
|
||||
steps: StepBuilderFunction
|
||||
condition: SearchFilters
|
||||
}
|
||||
}
|
||||
|
||||
// TRIGGERS
|
||||
rowSaved(inputs: RowCreatedTriggerInputs, outputs: RowCreatedTriggerOutputs) {
|
||||
this.triggerOutputs = outputs
|
||||
return this.trigger(
|
||||
TRIGGER_DEFINITIONS.ROW_SAVED,
|
||||
AutomationTriggerStepId.ROW_SAVED,
|
||||
inputs,
|
||||
outputs
|
||||
)
|
||||
class BaseStepBuilder {
|
||||
protected steps: AutomationStep[] = []
|
||||
|
||||
protected step<TStep extends AutomationActionStepId>(
|
||||
stepId: TStep,
|
||||
stepSchema: Omit<AutomationStep, "id" | "stepId" | "inputs">,
|
||||
inputs: AutomationStepInputs<TStep>
|
||||
): this {
|
||||
this.steps.push({
|
||||
...stepSchema,
|
||||
inputs: inputs as any,
|
||||
id: uuidv4(),
|
||||
stepId,
|
||||
})
|
||||
return this
|
||||
}
|
||||
|
||||
rowUpdated(
|
||||
inputs: RowUpdatedTriggerInputs,
|
||||
outputs: RowUpdatedTriggerOutputs
|
||||
) {
|
||||
this.triggerOutputs = outputs
|
||||
return this.trigger(
|
||||
TRIGGER_DEFINITIONS.ROW_UPDATED,
|
||||
AutomationTriggerStepId.ROW_UPDATED,
|
||||
inputs,
|
||||
outputs
|
||||
)
|
||||
protected addBranchStep(branchConfig: BranchConfig): void {
|
||||
const branchStepInputs: BranchStepInputs = {
|
||||
branches: [] as Branch[],
|
||||
children: {},
|
||||
}
|
||||
|
||||
rowDeleted(
|
||||
inputs: RowDeletedTriggerInputs,
|
||||
outputs: RowDeletedTriggerOutputs
|
||||
) {
|
||||
this.triggerOutputs = outputs
|
||||
return this.trigger(
|
||||
TRIGGER_DEFINITIONS.ROW_DELETED,
|
||||
AutomationTriggerStepId.ROW_DELETED,
|
||||
inputs,
|
||||
outputs
|
||||
)
|
||||
}
|
||||
Object.entries(branchConfig).forEach(([key, branch]) => {
|
||||
const stepBuilder = new StepBuilder()
|
||||
branch.steps(stepBuilder)
|
||||
|
||||
appAction(outputs: AppActionTriggerOutputs, inputs?: AppActionTriggerInputs) {
|
||||
this.triggerOutputs = outputs
|
||||
return this.trigger(
|
||||
TRIGGER_DEFINITIONS.APP,
|
||||
AutomationTriggerStepId.APP,
|
||||
inputs,
|
||||
outputs
|
||||
)
|
||||
branchStepInputs.branches.push({
|
||||
name: key,
|
||||
condition: branch.condition,
|
||||
})
|
||||
branchStepInputs.children![key] = stepBuilder.build()
|
||||
})
|
||||
|
||||
const branchStep: AutomationStep = {
|
||||
...definition,
|
||||
id: uuidv4(),
|
||||
stepId: AutomationActionStepId.BRANCH,
|
||||
inputs: branchStepInputs,
|
||||
}
|
||||
this.steps.push(branchStep)
|
||||
}
|
||||
|
||||
// STEPS
|
||||
|
@ -171,6 +161,84 @@ class AutomationBuilder {
|
|||
input
|
||||
)
|
||||
}
|
||||
}
|
||||
class StepBuilder extends BaseStepBuilder {
|
||||
build(): AutomationStep[] {
|
||||
return this.steps
|
||||
}
|
||||
|
||||
branch(branchConfig: BranchConfig): this {
|
||||
this.addBranchStep(branchConfig)
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
class AutomationBuilder extends BaseStepBuilder {
|
||||
private automationConfig: Automation
|
||||
private config: TestConfiguration
|
||||
private triggerOutputs: any
|
||||
private triggerSet: boolean = false
|
||||
|
||||
constructor(options: { name?: string } = {}) {
|
||||
super()
|
||||
this.automationConfig = {
|
||||
name: options.name || `Test Automation ${uuidv4()}`,
|
||||
definition: {
|
||||
steps: [],
|
||||
trigger: {} as AutomationTrigger,
|
||||
},
|
||||
type: "automation",
|
||||
appId: setup.getConfig().getAppId(),
|
||||
}
|
||||
this.config = setup.getConfig()
|
||||
}
|
||||
|
||||
// TRIGGERS
|
||||
rowSaved(inputs: RowCreatedTriggerInputs, outputs: RowCreatedTriggerOutputs) {
|
||||
this.triggerOutputs = outputs
|
||||
return this.trigger(
|
||||
TRIGGER_DEFINITIONS.ROW_SAVED,
|
||||
AutomationTriggerStepId.ROW_SAVED,
|
||||
inputs,
|
||||
outputs
|
||||
)
|
||||
}
|
||||
|
||||
rowUpdated(
|
||||
inputs: RowUpdatedTriggerInputs,
|
||||
outputs: RowUpdatedTriggerOutputs
|
||||
) {
|
||||
this.triggerOutputs = outputs
|
||||
return this.trigger(
|
||||
TRIGGER_DEFINITIONS.ROW_UPDATED,
|
||||
AutomationTriggerStepId.ROW_UPDATED,
|
||||
inputs,
|
||||
outputs
|
||||
)
|
||||
}
|
||||
|
||||
rowDeleted(
|
||||
inputs: RowDeletedTriggerInputs,
|
||||
outputs: RowDeletedTriggerOutputs
|
||||
) {
|
||||
this.triggerOutputs = outputs
|
||||
return this.trigger(
|
||||
TRIGGER_DEFINITIONS.ROW_DELETED,
|
||||
AutomationTriggerStepId.ROW_DELETED,
|
||||
inputs,
|
||||
outputs
|
||||
)
|
||||
}
|
||||
|
||||
appAction(outputs: AppActionTriggerOutputs, inputs?: AppActionTriggerInputs) {
|
||||
this.triggerOutputs = outputs
|
||||
return this.trigger(
|
||||
TRIGGER_DEFINITIONS.APP,
|
||||
AutomationTriggerStepId.APP,
|
||||
inputs,
|
||||
outputs
|
||||
)
|
||||
}
|
||||
|
||||
private trigger<TStep extends AutomationTriggerStepId>(
|
||||
triggerSchema: AutomationTriggerDefinition,
|
||||
|
@ -181,7 +249,6 @@ class AutomationBuilder {
|
|||
if (this.triggerSet) {
|
||||
throw new Error("Only one trigger can be set for an automation.")
|
||||
}
|
||||
|
||||
this.automationConfig.definition.trigger = {
|
||||
...triggerSchema,
|
||||
stepId,
|
||||
|
@ -194,21 +261,20 @@ class AutomationBuilder {
|
|||
return this
|
||||
}
|
||||
|
||||
private step<TStep extends AutomationActionStepId>(
|
||||
stepId: TStep,
|
||||
stepSchema: Omit<AutomationStep, "id" | "stepId" | "inputs">,
|
||||
inputs: AutomationStepInputs<TStep>
|
||||
): this {
|
||||
this.automationConfig.definition.steps.push({
|
||||
...stepSchema,
|
||||
inputs: inputs as any,
|
||||
id: uuidv4(),
|
||||
stepId,
|
||||
})
|
||||
return this
|
||||
branch(branchConfig: BranchConfig): {
|
||||
run: () => Promise<AutomationResults>
|
||||
} {
|
||||
this.addBranchStep(branchConfig)
|
||||
return {
|
||||
run: () => this.run(),
|
||||
}
|
||||
}
|
||||
|
||||
async run() {
|
||||
if (!Object.keys(this.automationConfig.definition.trigger).length) {
|
||||
throw new Error("Please add a trigger to this automation test")
|
||||
}
|
||||
this.automationConfig.definition.steps = this.steps
|
||||
const automation = await this.config.createAutomation(this.automationConfig)
|
||||
const results = await testAutomation(
|
||||
this.config,
|
||||
|
@ -218,7 +284,9 @@ class AutomationBuilder {
|
|||
return this.processResults(results)
|
||||
}
|
||||
|
||||
private processResults(results: { body: AutomationResults }) {
|
||||
private processResults(results: {
|
||||
body: AutomationResults
|
||||
}): AutomationResults {
|
||||
results.body.steps.shift()
|
||||
return {
|
||||
trigger: results.body.trigger,
|
|
@ -111,10 +111,15 @@ export type LoopStepOutputs = {
|
|||
}
|
||||
|
||||
export type BranchStepInputs = {
|
||||
conditions: SearchFilters
|
||||
branches: Branch[]
|
||||
children?: Record<string, AutomationStep[]>
|
||||
}
|
||||
|
||||
export type Branch = {
|
||||
name: string
|
||||
condition: SearchFilters
|
||||
}
|
||||
|
||||
export type MakeIntegrationInputs = {
|
||||
url: string
|
||||
body: any
|
||||
|
|
Loading…
Reference in New Issue