Lint and tidying

This commit is contained in:
Dean 2025-01-30 10:46:54 +00:00
parent 9f856d13c6
commit ee5d19456e
9 changed files with 125 additions and 87 deletions

View File

@ -40,8 +40,6 @@
export let autofocusEditor = false
export let placeholder = null
let mode: BindingMode | null
let initialValueJS = value?.startsWith?.("{{ js ")
let getCaretPosition: CaretPositionFn | undefined
let insertAtPos: InsertAtPositionFn | undefined
@ -141,9 +139,6 @@
}
const onChangeJSValue = (e: { detail: string }) => {
// if(typeof onChange === "function"){
// }
if (!e.detail?.trim()) {
// Don't bother saving empty values as JS
updateValue(null)
@ -151,18 +146,6 @@
updateValue(encodeJSBinding(e.detail))
}
}
onMount(() => {
// Set the initial mode appropriately
const initialValueMode = initialValueJS
? BindingMode.JavaScript
: BindingMode.Text
if (editorModeOptions.includes(initialValueMode)) {
mode = initialValueMode
} else {
mode = editorModeOptions[0]
}
})
</script>
<div class="code-panel">

View File

@ -1,9 +1,9 @@
import { derived, get, Readable, Writable } from "svelte/store"
import { derived, get, Readable } from "svelte/store"
import { API } from "@/api"
import { cloneDeep } from "lodash/fp"
import { generate } from "shortid"
import { createHistoryStore } from "@/stores/builder/history"
import { licensing, organisation, environment, auth } from "@/stores/portal"
import { licensing, organisation, environment } from "@/stores/portal"
import { tables, appStore } from "@/stores/builder"
import { notifications } from "@budibase/bbui"
import {
@ -34,6 +34,11 @@ import {
GetAutomationActionDefinitionsResponse,
AppSelfResponse,
TestAutomationResponse,
isAutomationResults,
AutomationTestTrigger,
TriggerTestOutputs,
RowActionTriggerOutputs,
WebhookTriggerOutputs,
} from "@budibase/types"
import { ActionStepID, TriggerStepID } from "@/constants/backend/automations"
import { FIELDS } from "@/constants/backend"
@ -100,7 +105,7 @@ const automationActions = (store: AutomationStore) => ({
const appSelfResponse = await API.fetchSelf()
store.update(state => ({
...state,
appSelf: appSelfResponse,
...(appSelfResponse ? { appSelf: appSelfResponse } : {}),
}))
return appSelfResponse
},
@ -882,12 +887,7 @@ const automationActions = (store: AutomationStore) => ({
const message = err.message || err.status || JSON.stringify(err)
throw `Automation test failed - ${message}`
}
if (!result?.trigger && !result?.steps?.length && !result?.message) {
if (result?.err?.code === "usage_limit_exceeded") {
throw "You have exceeded your automation quota"
}
throw "Something went wrong testing your automation"
}
store.update(state => {
state.testResults = result
return state
@ -1594,18 +1594,9 @@ export class SelectedAutomationStore extends DerivedBudiStore<
}
export const selectedAutomation = new SelectedAutomationStore(automationStore)
type TriggerContext = AutomationTrigger & {
meta?: Record<any, any>
table?: Table
body?: Record<any, any>
row?: Record<any, any>
oldRow?: Record<any, any>
outputs?: Record<any, any>
}
export interface AutomationContext {
user: AppSelfResponse
trigger: TriggerContext
trigger?: TriggerTestOutputs
steps: Record<string, AutomationStep>
env: Record<string, any>
settings: Record<string, any>
@ -1619,7 +1610,8 @@ export const evaluationContext: Readable<AutomationContext> = derived(
const results: TestAutomationResponse | undefined =
$selectedAutomation?.testResults
const testData = $selectedAutomation.data?.testData || {}
const testData: TriggerTestOutputs | undefined =
$selectedAutomation.data?.testData
const triggerDef = $selectedAutomation.data?.definition?.trigger
const isWebhook = triggerDef?.stepId! === TriggerStepID.WEBHOOK
@ -1629,36 +1621,50 @@ export const evaluationContext: Readable<AutomationContext> = derived(
? $tables.list.find(table => table._id === rowActionTableId)
: undefined
// Needs a clone to avoid state mutation.
const triggerData: TriggerContext = cloneDeep(
results?.trigger?.outputs || testData
)
let triggerData: TriggerTestOutputs | undefined
if (isRowAction && rowActionTable) {
// Row action table must always be retrieved as it is never
// returned in the test results
triggerData.table = rowActionTable
} else if (isWebhook) {
// Ensure it displays in the event that the configuration have been skipped
triggerData.body = triggerData.body ?? {}
if (results && isAutomationResults(results)) {
const automationTrigger: AutomationTestTrigger | undefined =
results?.trigger
const outputs: TriggerTestOutputs | undefined = automationTrigger?.outputs
triggerData = outputs ? outputs : undefined
if (triggerData) {
if (isRowAction && rowActionTable) {
const rowTrigger = triggerData as RowActionTriggerOutputs
// Row action table must always be retrieved as it is never
// returned in the test results
rowTrigger.table = rowActionTable
} else if (isWebhook) {
const webhookTrigger = triggerData as WebhookTriggerOutputs
// Ensure it displays in the event that the configuration have been skipped
webhookTrigger.body = webhookTrigger.body ?? {}
}
}
// Clean up unnecessary data from the context
// Meta contains UI/UX config data. Non-bindable
delete triggerData?.meta
} else {
// Substitute test data in place of the trigger data if the test hasn't been run
triggerData = testData
}
// Clean up unnecessary data from the context
// Meta contains UI/UX config data. Non-bindable
delete triggerData?.meta
// AppSelf context required to mirror server user context
const userContext = $selectedAutomation.appSelf || {}
// Extract step results from a valid response
const stepResults =
results && isAutomationResults(results) ? results?.steps : []
return {
user: userContext,
trigger: {
...triggerData,
},
// Merge in the trigger data.
...(triggerData ? { trigger: { ...triggerData } } : {}),
// This will initially be empty for each step but will populate
// upon running the test.
steps: (results?.steps || []).reduce(
steps: stepResults.reduce(
(acc: Record<string, any>, res: Record<string, any>) => {
acc[res.id] = res.outputs
return acc

View File

@ -11,6 +11,7 @@ import {
import { configs, context, events } from "@budibase/backend-core"
import sdk from "../../../sdk"
import {
AutomationResults,
ConfigType,
FieldType,
isDidNotTriggerResponse,
@ -615,7 +616,7 @@ describe("/automations", () => {
})
)
const res = await config.api.automation.test(automation._id!, {
const response = await config.api.automation.test(automation._id!, {
fields: {},
oldRow: {
City: oldCity,
@ -625,12 +626,14 @@ describe("/automations", () => {
},
})
if (isDidNotTriggerResponse(res)) {
if (isDidNotTriggerResponse(response)) {
throw new Error("Automation did not trigger")
}
const results: AutomationResults = response as AutomationResults
const expectedResult = oldCity === newCity
expect(res.steps[1].outputs.result).toEqual(expectedResult)
expect(results.steps[1].outputs.result).toEqual(expectedResult)
}
)
})
@ -717,7 +720,8 @@ describe("/automations", () => {
if (isDidNotTriggerResponse(res)) {
expect(expectToRun).toEqual(false)
} else {
expect(res.steps[1].outputs.success).toEqual(expectToRun)
const results: AutomationResults = res as AutomationResults
expect(results.steps[1].outputs.success).toEqual(expectToRun)
}
}
)

View File

@ -6,6 +6,7 @@ import {
AppActionTriggerOutputs,
Automation,
AutomationActionStepId,
AutomationResults,
AutomationStep,
AutomationStepInputs,
AutomationTrigger,
@ -421,11 +422,11 @@ class AutomationBuilder extends BaseStepBuilder {
if (isDidNotTriggerResponse(response)) {
throw new Error(response.message)
}
response.steps.shift()
const results: AutomationResults = response as AutomationResults
results.steps.shift()
return {
trigger: response.trigger,
steps: response.steps,
trigger: results.trigger,
steps: results.steps,
}
}
}

View File

@ -22,6 +22,7 @@ import {
UserBindings,
AutomationResults,
DidNotTriggerResponse,
Table,
} from "@budibase/types"
import { executeInThread } from "../threads/automation"
import { dataFilters, sdk } from "@budibase/shared-core"
@ -154,6 +155,7 @@ interface AutomationTriggerParams {
timeout?: number
appId?: string
user?: UserBindings
table?: Table
}
export async function externalTrigger(

View File

@ -85,6 +85,17 @@ export function isDidNotTriggerResponse(
return !!("message" in response && response.message)
}
export function isAutomationResults(
response: TestAutomationResponse
): response is AutomationResults {
return !!(
"steps" in response &&
response.steps &&
"trigger" in response &&
response.trigger
)
}
export type TestAutomationResponse =
| AutomationResults
| DidNotTriggerResponse

View File

@ -1,3 +1,4 @@
import { Table } from "@budibase/types"
import { SortOrder } from "../../../api"
import {
SearchFilters,
@ -296,6 +297,7 @@ export type RowUpdatedTriggerOutputs = {
row: Row
id: string
revision?: string
oldRow: Row
}
export type WebhookTriggerInputs = {
@ -303,6 +305,17 @@ export type WebhookTriggerInputs = {
triggerUrl: string
}
export type WebhookTriggerOutputs = {
fields: Record<string, any>
export type WebhookTriggerOutputs = Record<string, any> & {
body: Record<string, any>
}
export type RowActionTriggerInputs = {
tableId: string
}
export type RowActionTriggerOutputs = {
row: Row
id: string
revision?: string
table: Table
}

View File

@ -5,6 +5,16 @@ import { Row } from "../row"
import { Table } from "../table"
import { AutomationStep, AutomationTrigger } from "./schema"
import { ContextEmitter } from "../../../sdk"
import {
AppActionTriggerOutputs,
AppSelfResponse,
CronTriggerOutputs,
RowActionTriggerOutputs,
RowCreatedTriggerInputs,
RowDeletedTriggerInputs,
RowUpdatedTriggerOutputs,
WebhookTriggerOutputs,
} from "@budibase/types"
export enum AutomationIOType {
OBJECT = "object",
@ -136,15 +146,7 @@ export interface Automation extends Document {
internal?: boolean
type?: string
disabled?: boolean
testData?: {
row?: Row
meta: {
[key: string]: unknown
}
id: string
revision: string
oldRow?: Row
}
testData?: TriggerTestOutputs
}
interface BaseIOStructure {
@ -191,10 +193,36 @@ export enum AutomationStoppedReason {
TRIGGER_FILTER_NOT_MET = "Automation did not run. Filter conditions in trigger were not met.",
}
// UI and context fields
export type AutomationResultFields = {
meta?: {
[key: string]: unknown
}
user?: AppSelfResponse
automation?: Automation
}
// Base types for Trigger outputs combined with UI and context fields
export type TriggerTestOutputs =
| (WebhookTriggerOutputs & AutomationResultFields)
| (AppActionTriggerOutputs & AutomationResultFields)
| (CronTriggerOutputs & AutomationResultFields)
| (RowActionTriggerOutputs & AutomationResultFields)
| (RowDeletedTriggerInputs & AutomationResultFields)
| (RowCreatedTriggerInputs & AutomationResultFields)
| (RowUpdatedTriggerOutputs & AutomationResultFields)
export type AutomationTestTrigger = {
id: string
inputs: null
stepId: AutomationTriggerStepId
outputs: TriggerTestOutputs
}
export interface AutomationResults {
automationId?: string
status?: AutomationStatus
trigger?: AutomationTrigger
trigger?: AutomationTestTrigger
steps: {
stepId: AutomationTriggerStepId | AutomationActionStepId
inputs: {

View File

@ -1,8 +1,6 @@
import {
Automation,
AutomationMetadata,
AutomationStatus,
AutomationStoppedReason,
Row,
UserBindings,
} from "../../documents"
@ -31,11 +29,3 @@ export interface AutomationRowEvent {
}
export type AutomationJob = Job<AutomationData>
export type DidNotTriggerResponse = {
outputs: {
success: false
status: AutomationStatus.STOPPED
}
message: AutomationStoppedReason.TRIGGER_FILTER_NOT_MET
}