Move getQueryableFields to utils
This commit is contained in:
parent
084a481821
commit
eb2d71e980
|
@ -1,6 +1,12 @@
|
||||||
import { db } from "@budibase/backend-core"
|
import { db } from "@budibase/backend-core"
|
||||||
import { isLogicalSearchOperator, SearchFilters } from "@budibase/types"
|
import {
|
||||||
|
FieldType,
|
||||||
|
isLogicalSearchOperator,
|
||||||
|
SearchFilters,
|
||||||
|
Table,
|
||||||
|
} from "@budibase/types"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
|
import sdk from "../../../sdk"
|
||||||
|
|
||||||
export const removeInvalidFilters = (
|
export const removeInvalidFilters = (
|
||||||
filters: SearchFilters,
|
filters: SearchFilters,
|
||||||
|
@ -45,3 +51,48 @@ export const removeInvalidFilters = (
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const getQueryableFields = async (
|
||||||
|
fields: string[],
|
||||||
|
table: Table
|
||||||
|
): Promise<string[]> => {
|
||||||
|
const handledTables = new Set<string>([table._id!])
|
||||||
|
const extractTableFields = async (
|
||||||
|
table: Table,
|
||||||
|
allowedFields: string[]
|
||||||
|
): Promise<string[]> => {
|
||||||
|
const result = []
|
||||||
|
for (const field of Object.keys(table.schema).filter(f =>
|
||||||
|
allowedFields.includes(f)
|
||||||
|
)) {
|
||||||
|
const subSchema = table.schema[field]
|
||||||
|
if (subSchema.type === FieldType.LINK) {
|
||||||
|
if (handledTables.has(`${table._id}_${subSchema.tableId}`)) {
|
||||||
|
// avoid circular loops
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
handledTables.add(`${table._id}_${subSchema.tableId}`)
|
||||||
|
const relatedTable = await sdk.tables.getTable(subSchema.tableId)
|
||||||
|
const relatedFields = await extractTableFields(
|
||||||
|
relatedTable,
|
||||||
|
Object.keys(relatedTable.schema)
|
||||||
|
)
|
||||||
|
|
||||||
|
result.push(...relatedFields.map(f => `${subSchema.name}.${f}`))
|
||||||
|
// should be able to filter by relationship using table name
|
||||||
|
result.push(...relatedFields.map(f => `${relatedTable.name}.${f}`))
|
||||||
|
} else {
|
||||||
|
result.push(field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = [
|
||||||
|
"_id", // Querying by _id is always allowed, even if it's never part of the schema
|
||||||
|
]
|
||||||
|
|
||||||
|
result.push(...(await extractTableFields(table, fields)))
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
import {
|
import {
|
||||||
EmptyFilterOption,
|
EmptyFilterOption,
|
||||||
FieldType,
|
|
||||||
Row,
|
Row,
|
||||||
RowSearchParams,
|
RowSearchParams,
|
||||||
SearchResponse,
|
SearchResponse,
|
||||||
SortOrder,
|
SortOrder,
|
||||||
Table,
|
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import { isExternalTableID } from "../../../integrations/utils"
|
import { isExternalTableID } from "../../../integrations/utils"
|
||||||
import * as internal from "./search/internal"
|
import * as internal from "./search/internal"
|
||||||
|
@ -16,7 +14,7 @@ import sdk from "../../index"
|
||||||
import { searchInputMapping } from "./search/utils"
|
import { searchInputMapping } from "./search/utils"
|
||||||
import { db as dbCore } from "@budibase/backend-core"
|
import { db as dbCore } from "@budibase/backend-core"
|
||||||
import tracer from "dd-trace"
|
import tracer from "dd-trace"
|
||||||
import { removeInvalidFilters } from "./queryUtils"
|
import { getQueryableFields, removeInvalidFilters } from "./queryUtils"
|
||||||
|
|
||||||
export { isValidFilter } from "../../../integrations/utils"
|
export { isValidFilter } from "../../../integrations/utils"
|
||||||
|
|
||||||
|
@ -130,48 +128,3 @@ export async function fetchView(
|
||||||
): Promise<Row[]> {
|
): Promise<Row[]> {
|
||||||
return pickApi(tableId).fetchView(viewName, params)
|
return pickApi(tableId).fetchView(viewName, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getQueryableFields(
|
|
||||||
fields: string[],
|
|
||||||
table: Table
|
|
||||||
): Promise<string[]> {
|
|
||||||
const handledTables = new Set<string>([table._id!])
|
|
||||||
const extractTableFields = async (
|
|
||||||
table: Table,
|
|
||||||
allowedFields: string[]
|
|
||||||
): Promise<string[]> => {
|
|
||||||
const result = []
|
|
||||||
for (const field of Object.keys(table.schema).filter(f =>
|
|
||||||
allowedFields.includes(f)
|
|
||||||
)) {
|
|
||||||
const subSchema = table.schema[field]
|
|
||||||
if (subSchema.type === FieldType.LINK) {
|
|
||||||
if (handledTables.has(`${table._id}_${subSchema.tableId}`)) {
|
|
||||||
// avoid circular loops
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
handledTables.add(`${subSchema.tableId}_${table._id}`)
|
|
||||||
const relatedTable = await sdk.tables.getTable(subSchema.tableId)
|
|
||||||
const relatedFields = await extractTableFields(
|
|
||||||
relatedTable,
|
|
||||||
Object.keys(relatedTable.schema)
|
|
||||||
)
|
|
||||||
|
|
||||||
result.push(...relatedFields.map(f => `${subSchema.name}.${f}`))
|
|
||||||
// should be able to filter by relationship using table name
|
|
||||||
result.push(...relatedFields.map(f => `${relatedTable.name}.${f}`))
|
|
||||||
} else {
|
|
||||||
result.push(field)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = [
|
|
||||||
"_id", // Querying by _id is always allowed, even if it's never part of the schema
|
|
||||||
]
|
|
||||||
|
|
||||||
result.push(...(await extractTableFields(table, fields)))
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue