Merge branch 'develop' into BUDI-6785-update-to-node-18
This commit is contained in:
commit
a6ce7ac2ef
|
@ -25,13 +25,13 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout repo and submodules
|
||||
uses: actions/checkout@v3
|
||||
if: github.repository == 'Budibase/budibase'
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'Budibase/budibase'
|
||||
with:
|
||||
submodules: true
|
||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||
- name: Checkout repo only
|
||||
uses: actions/checkout@v3
|
||||
if: github.repository != 'Budibase/budibase'
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != 'Budibase/budibase'
|
||||
|
||||
- name: Use Node.js 18.x
|
||||
uses: actions/setup-node@v3
|
||||
|
@ -46,13 +46,13 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout repo and submodules
|
||||
uses: actions/checkout@v3
|
||||
if: github.repository == 'Budibase/budibase'
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'Budibase/budibase'
|
||||
with:
|
||||
submodules: true
|
||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||
- name: Checkout repo only
|
||||
uses: actions/checkout@v3
|
||||
if: github.repository != 'Budibase/budibase'
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != 'Budibase/budibase'
|
||||
|
||||
- name: Use Node.js 18.x
|
||||
uses: actions/setup-node@v3
|
||||
|
@ -70,13 +70,13 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout repo and submodules
|
||||
uses: actions/checkout@v3
|
||||
if: github.repository == 'Budibase/budibase'
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'Budibase/budibase'
|
||||
with:
|
||||
submodules: true
|
||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||
- name: Checkout repo only
|
||||
uses: actions/checkout@v3
|
||||
if: github.repository != 'Budibase/budibase'
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != 'Budibase/budibase'
|
||||
|
||||
- name: Use Node.js 18.x
|
||||
uses: actions/setup-node@v3
|
||||
|
@ -96,13 +96,13 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout repo and submodules
|
||||
uses: actions/checkout@v3
|
||||
if: github.repository == 'Budibase/budibase'
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'Budibase/budibase'
|
||||
with:
|
||||
submodules: true
|
||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||
- name: Checkout repo only
|
||||
uses: actions/checkout@v3
|
||||
if: github.repository != 'Budibase/budibase'
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != 'Budibase/budibase'
|
||||
|
||||
- name: Use Node.js 18.x
|
||||
uses: actions/setup-node@v3
|
||||
|
@ -120,7 +120,7 @@ jobs:
|
|||
|
||||
test-pro:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'Budibase/budibase'
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'Budibase/budibase'
|
||||
steps:
|
||||
- name: Checkout repo and submodules
|
||||
uses: actions/checkout@v3
|
||||
|
@ -141,13 +141,13 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout repo and submodules
|
||||
uses: actions/checkout@v3
|
||||
if: github.repository == 'Budibase/budibase'
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'Budibase/budibase'
|
||||
with:
|
||||
submodules: true
|
||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN || github.token }}
|
||||
- name: Checkout repo only
|
||||
uses: actions/checkout@v3
|
||||
if: github.repository != 'Budibase/budibase'
|
||||
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != 'Budibase/budibase'
|
||||
|
||||
- name: Use Node.js 18.x
|
||||
uses: actions/setup-node@v3
|
||||
|
@ -167,7 +167,7 @@ jobs:
|
|||
|
||||
check-pro-submodule:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'Budibase/budibase'
|
||||
if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'Budibase/budibase'
|
||||
steps:
|
||||
- name: Checkout repo and submodules
|
||||
uses: actions/checkout@v3
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"version": "2.8.32-alpha.5",
|
||||
"version": "2.8.32-alpha.7",
|
||||
"npmClient": "yarn",
|
||||
"packages": [
|
||||
"packages/*"
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit cf3bef2aad9c739111b306fd0712397adc363f81
|
||||
Subproject commit ecee8071ebe0f98a5bb19646954e373264be210d
|
|
@ -7,6 +7,7 @@ import {
|
|||
RequiredKeys,
|
||||
SearchParams,
|
||||
} from "@budibase/types"
|
||||
import { dataFilters } from "@budibase/shared-core"
|
||||
import sdk from "../../../sdk"
|
||||
|
||||
export async function searchView(
|
||||
|
@ -34,11 +35,12 @@ export async function searchView(
|
|||
ctx.status = 200
|
||||
|
||||
const { body } = ctx.request
|
||||
const query = dataFilters.buildLuceneQuery(view.query || [])
|
||||
|
||||
const searchOptions: RequiredKeys<SearchViewRowRequest> &
|
||||
RequiredKeys<Pick<SearchParams, "tableId" | "query" | "fields">> = {
|
||||
tableId: view.tableId,
|
||||
query: view.query || {},
|
||||
query,
|
||||
fields: viewFields,
|
||||
...getSortOptions(body, view),
|
||||
limit: body.limit,
|
||||
|
|
|
@ -1072,7 +1072,7 @@ describe("/rows", () => {
|
|||
)
|
||||
|
||||
const createViewResponse = await config.api.viewV2.create({
|
||||
query: { equal: { age: 40 } },
|
||||
query: [{ operator: "equal", field: "age", value: 40 }],
|
||||
})
|
||||
|
||||
const response = await config.api.viewV2.search(createViewResponse.id)
|
||||
|
|
|
@ -62,7 +62,7 @@ describe("/v2/views", () => {
|
|||
name: generator.name(),
|
||||
tableId: config.table!._id!,
|
||||
primaryDisplay: generator.word(),
|
||||
query: { allOr: false, equal: { field: "value" } },
|
||||
query: [{ operator: "equal", field: "field", value: "value" }],
|
||||
sort: {
|
||||
field: "fieldToSort",
|
||||
order: SortOrder.DESCENDING,
|
||||
|
@ -190,7 +190,7 @@ describe("/v2/views", () => {
|
|||
const tableId = config.table!._id!
|
||||
await config.api.viewV2.update({
|
||||
...view,
|
||||
query: { equal: { newField: "thatValue" } },
|
||||
query: [{ operator: "equal", field: "newField", value: "thatValue" }],
|
||||
})
|
||||
|
||||
expect(await config.api.table.get(tableId)).toEqual({
|
||||
|
@ -198,7 +198,9 @@ describe("/v2/views", () => {
|
|||
views: {
|
||||
[view.name]: {
|
||||
...view,
|
||||
query: { equal: { newField: "thatValue" } },
|
||||
query: [
|
||||
{ operator: "equal", field: "newField", value: "thatValue" },
|
||||
],
|
||||
schema: expect.anything(),
|
||||
},
|
||||
},
|
||||
|
@ -216,7 +218,13 @@ describe("/v2/views", () => {
|
|||
tableId,
|
||||
name: view.name,
|
||||
primaryDisplay: generator.word(),
|
||||
query: { equal: { [generator.word()]: generator.word() } },
|
||||
query: [
|
||||
{
|
||||
operator: "equal",
|
||||
field: generator.word(),
|
||||
value: generator.word(),
|
||||
},
|
||||
],
|
||||
sort: {
|
||||
field: generator.word(),
|
||||
order: SortOrder.DESCENDING,
|
||||
|
@ -285,7 +293,7 @@ describe("/v2/views", () => {
|
|||
{
|
||||
...view,
|
||||
tableId: generator.guid(),
|
||||
query: { equal: { newField: "thatValue" } },
|
||||
query: [{ operator: "equal", field: "newField", value: "thatValue" }],
|
||||
},
|
||||
{ expectStatus: 404 }
|
||||
)
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
import { Datasource, FieldType, SortDirection, SortType } from "@budibase/types"
|
||||
import {
|
||||
Datasource,
|
||||
FieldType,
|
||||
SearchFilter,
|
||||
SearchQuery,
|
||||
SearchQueryFields,
|
||||
SortDirection,
|
||||
SortType,
|
||||
} from "@budibase/types"
|
||||
import { OperatorOptions, SqlNumberTypeRangeMap } from "./constants"
|
||||
import { deepGet } from "./helpers"
|
||||
|
||||
|
@ -73,13 +81,13 @@ export const NoEmptyFilterStrings = [
|
|||
OperatorOptions.NotEquals.value,
|
||||
OperatorOptions.Contains.value,
|
||||
OperatorOptions.NotContains.value,
|
||||
] as (keyof QueryFields)[]
|
||||
] as (keyof SearchQueryFields)[]
|
||||
|
||||
/**
|
||||
* Removes any fields that contain empty strings that would cause inconsistent
|
||||
* behaviour with how backend tables are filtered (no value means no filter).
|
||||
*/
|
||||
const cleanupQuery = (query: Query) => {
|
||||
const cleanupQuery = (query: SearchQuery) => {
|
||||
if (!query) {
|
||||
return query
|
||||
}
|
||||
|
@ -110,66 +118,12 @@ const removeKeyNumbering = (key: string) => {
|
|||
}
|
||||
}
|
||||
|
||||
type Filter = {
|
||||
operator: keyof Query
|
||||
field: string
|
||||
type: any
|
||||
value: any
|
||||
externalType: keyof typeof SqlNumberTypeRangeMap
|
||||
}
|
||||
|
||||
type Query = QueryFields & QueryConfig
|
||||
type QueryFields = {
|
||||
string?: {
|
||||
[key: string]: string
|
||||
}
|
||||
fuzzy?: {
|
||||
[key: string]: string
|
||||
}
|
||||
range?: {
|
||||
[key: string]: {
|
||||
high: number | string
|
||||
low: number | string
|
||||
}
|
||||
}
|
||||
equal?: {
|
||||
[key: string]: any
|
||||
}
|
||||
notEqual?: {
|
||||
[key: string]: any
|
||||
}
|
||||
empty?: {
|
||||
[key: string]: any
|
||||
}
|
||||
notEmpty?: {
|
||||
[key: string]: any
|
||||
}
|
||||
oneOf?: {
|
||||
[key: string]: any[]
|
||||
}
|
||||
contains?: {
|
||||
[key: string]: any[]
|
||||
}
|
||||
notContains?: {
|
||||
[key: string]: any[]
|
||||
}
|
||||
containsAny?: {
|
||||
[key: string]: any[]
|
||||
}
|
||||
}
|
||||
|
||||
type QueryConfig = {
|
||||
allOr?: boolean
|
||||
}
|
||||
|
||||
type QueryFieldsType = keyof QueryFields
|
||||
|
||||
/**
|
||||
* Builds a lucene JSON query from the filter structure generated in the builder
|
||||
* @param filter the builder filter structure
|
||||
*/
|
||||
export const buildLuceneQuery = (filter: Filter[]) => {
|
||||
let query: Query = {
|
||||
export const buildLuceneQuery = (filter: SearchFilter[]) => {
|
||||
let query: SearchQuery = {
|
||||
string: {},
|
||||
fuzzy: {},
|
||||
range: {},
|
||||
|
@ -227,9 +181,13 @@ export const buildLuceneQuery = (filter: Filter[]) => {
|
|||
}
|
||||
if (operator.startsWith("range") && query.range) {
|
||||
const minint =
|
||||
SqlNumberTypeRangeMap[externalType]?.min || Number.MIN_SAFE_INTEGER
|
||||
SqlNumberTypeRangeMap[
|
||||
externalType as keyof typeof SqlNumberTypeRangeMap
|
||||
]?.min || Number.MIN_SAFE_INTEGER
|
||||
const maxint =
|
||||
SqlNumberTypeRangeMap[externalType]?.max || Number.MAX_SAFE_INTEGER
|
||||
SqlNumberTypeRangeMap[
|
||||
externalType as keyof typeof SqlNumberTypeRangeMap
|
||||
]?.max || Number.MAX_SAFE_INTEGER
|
||||
if (!query.range[field]) {
|
||||
query.range[field] = {
|
||||
low: type === "number" ? minint : "0000-00-00T00:00:00.000Z",
|
||||
|
@ -275,7 +233,7 @@ export const buildLuceneQuery = (filter: Filter[]) => {
|
|||
* @param docs the data
|
||||
* @param query the JSON lucene query
|
||||
*/
|
||||
export const runLuceneQuery = (docs: any[], query?: Query) => {
|
||||
export const runLuceneQuery = (docs: any[], query?: SearchQuery) => {
|
||||
if (!docs || !Array.isArray(docs)) {
|
||||
return []
|
||||
}
|
||||
|
@ -289,7 +247,7 @@ export const runLuceneQuery = (docs: any[], query?: Query) => {
|
|||
// Iterates over a set of filters and evaluates a fail function against a doc
|
||||
const match =
|
||||
(
|
||||
type: QueryFieldsType,
|
||||
type: keyof SearchQueryFields,
|
||||
failFn: (docValue: any, testValue: any) => boolean
|
||||
) =>
|
||||
(doc: any) => {
|
||||
|
@ -456,7 +414,7 @@ export const luceneLimit = (docs: any[], limit: string) => {
|
|||
return docs.slice(0, numLimit)
|
||||
}
|
||||
|
||||
export const hasFilters = (query?: Query) => {
|
||||
export const hasFilters = (query?: SearchQuery) => {
|
||||
if (!query) {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -8,3 +8,4 @@ export * from "./system"
|
|||
export * from "./app"
|
||||
export * from "./global"
|
||||
export * from "./pagination"
|
||||
export * from "./searchFilter"
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
import { FieldType } from "../../documents"
|
||||
|
||||
export type SearchFilter = {
|
||||
operator: keyof SearchQuery
|
||||
field: string
|
||||
type?: FieldType
|
||||
value: any
|
||||
externalType?: string
|
||||
}
|
||||
|
||||
export type SearchQuery = {
|
||||
allOr?: boolean
|
||||
string?: {
|
||||
[key: string]: string
|
||||
}
|
||||
fuzzy?: {
|
||||
[key: string]: string
|
||||
}
|
||||
range?: {
|
||||
[key: string]: {
|
||||
high: number | string
|
||||
low: number | string
|
||||
}
|
||||
}
|
||||
equal?: {
|
||||
[key: string]: any
|
||||
}
|
||||
notEqual?: {
|
||||
[key: string]: any
|
||||
}
|
||||
empty?: {
|
||||
[key: string]: any
|
||||
}
|
||||
notEmpty?: {
|
||||
[key: string]: any
|
||||
}
|
||||
oneOf?: {
|
||||
[key: string]: any[]
|
||||
}
|
||||
contains?: {
|
||||
[key: string]: any[]
|
||||
}
|
||||
notContains?: {
|
||||
[key: string]: any[]
|
||||
}
|
||||
containsAny?: {
|
||||
[key: string]: any[]
|
||||
}
|
||||
}
|
||||
|
||||
export type SearchQueryFields = Omit<SearchQuery, "allOr">
|
|
@ -1,6 +1,5 @@
|
|||
import { SortOrder, SortType } from "../../api"
|
||||
import { SearchFilters } from "../../sdk"
|
||||
import { TableSchema, UIFieldMetadata } from "./table"
|
||||
import { SearchFilter, SortOrder, SortType } from "../../api"
|
||||
import { UIFieldMetadata } from "./table"
|
||||
|
||||
export interface View {
|
||||
name: string
|
||||
|
@ -20,7 +19,7 @@ export interface ViewV2 {
|
|||
name: string
|
||||
primaryDisplay?: string
|
||||
tableId: string
|
||||
query?: SearchFilters
|
||||
query?: SearchFilter[]
|
||||
sort?: {
|
||||
field: string
|
||||
order?: SortOrder
|
||||
|
|
Loading…
Reference in New Issue