Merge pull request #14922 from Budibase/chore/search-filter-typing

Search filter typing
This commit is contained in:
Adria Navarro 2024-10-31 16:01:12 +01:00 committed by GitHub
commit 86aabcc629
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 58 additions and 38 deletions

View File

@ -8,7 +8,7 @@ import {
import * as actions from "../automations/actions"
import * as automationUtils from "../automations/automationUtils"
import { replaceFakeBindings } from "../automations/loopUtils"
import { dataFilters, helpers } from "@budibase/shared-core"
import { dataFilters, helpers, utils } from "@budibase/shared-core"
import { default as AutomationEmitter } from "../events/AutomationEmitter"
import { generateAutomationMetadataID, isProdAppID } from "../db/utils"
import { definitions as triggerDefs } from "../automations/triggerInfo"
@ -23,10 +23,12 @@ import {
AutomationStatus,
AutomationStep,
AutomationStepStatus,
BranchSearchFilters,
BranchStep,
isLogicalSearchOperator,
LoopStep,
SearchFilters,
UserBindings,
isBasicSearchOperator,
} from "@budibase/types"
import { AutomationContext, TriggerOutput } from "../definitions/automations"
import { WorkerCallback } from "./definitions"
@ -547,34 +549,51 @@ class Orchestrator {
}
private async evaluateBranchCondition(
conditions: SearchFilters
conditions: BranchSearchFilters
): Promise<boolean> {
const toFilter: Record<string, any> = {}
const processedConditions = dataFilters.recurseSearchFilters(
conditions,
filter => {
Object.entries(filter).forEach(([_, value]) => {
Object.entries(value).forEach(([field, val]) => {
const recurseSearchFilters = (
filters: BranchSearchFilters
): BranchSearchFilters => {
for (const filterKey of Object.keys(
filters
) as (keyof typeof filters)[]) {
if (!filters[filterKey]) {
continue
}
if (isLogicalSearchOperator(filterKey)) {
filters[filterKey].conditions = filters[filterKey].conditions.map(
condition => recurseSearchFilters(condition)
)
} else if (isBasicSearchOperator(filterKey)) {
for (const [field, value] of Object.entries(filters[filterKey])) {
const fromContext = processStringSync(
field,
this.processContext(this.context)
)
toFilter[field] = fromContext
if (typeof val === "string" && findHBSBlocks(val).length > 0) {
if (typeof value === "string" && findHBSBlocks(value).length > 0) {
const processedVal = processStringSync(
val,
value,
this.processContext(this.context)
)
value[field] = processedVal
filters[filterKey][field] = processedVal
}
})
})
return filter
}
)
} else {
// We want to types to complain if we extend BranchSearchFilters, but not to throw if the request comes with some extra data. It will just be ignored
utils.unreachable(filterKey, { doNotThrow: true })
}
}
return filters
}
const processedConditions = recurseSearchFilters(conditions)
const result = dataFilters.runQuery([toFilter], processedConditions)
return result.length > 0

View File

@ -142,25 +142,6 @@ export function recurseLogicalOperators(
return filters
}
export function recurseSearchFilters(
filters: SearchFilters,
processFn: (filter: SearchFilters) => SearchFilters
): SearchFilters {
// Process the current level
filters = processFn(filters)
// Recurse through logical operators
for (const logical of LOGICAL_OPERATORS) {
if (filters[logical]) {
filters[logical]!.conditions = filters[logical]!.conditions.map(
condition => recurseSearchFilters(condition, processFn)
)
}
}
return filters
}
/**
* Removes any fields that contain empty strings that would cause inconsistent
* behaviour with how backend tables are filtered (no value means no filter).

View File

@ -26,10 +26,17 @@ const FILTER_ALLOWED_KEYS: (keyof SearchFilter)[] = [
export function unreachable(
value: never,
message = `No such case in exhaustive switch: ${value}`
opts?: {
message?: string
doNotThrow?: boolean
}
) {
const message = opts?.message || `No such case in exhaustive switch: ${value}`
const doNotThrow = !!opts?.doNotThrow
if (!doNotThrow) {
throw new Error(message)
}
}
export async function parallelForeach<T>(
items: T[],

View File

@ -1,5 +1,10 @@
import { SortOrder } from "../../../api"
import { SearchFilters, EmptyFilterOption } from "../../../sdk"
import {
SearchFilters,
EmptyFilterOption,
BasicOperator,
LogicalOperator,
} from "../../../sdk"
import { HttpMethod } from "../query"
import { Row } from "../row"
import { LoopStepType, EmailAttachment, AutomationResults } from "./automation"
@ -118,9 +123,17 @@ export type BranchStepInputs = {
export type Branch = {
id: any
name: string
condition: SearchFilters
condition: BranchSearchFilters
}
export type BranchSearchFilters = Pick<
SearchFilters,
| BasicOperator.EQUAL
| BasicOperator.NOT_EQUAL
| LogicalOperator.AND
| LogicalOperator.OR
>
export type MakeIntegrationInputs = {
url: string
body: any