From c27e9c266c6dde39e9a0a68c48b26e2dc8fb71e4 Mon Sep 17 00:00:00 2001 From: Sam Rose Date: Fri, 14 Jun 2024 09:45:30 +0100 Subject: [PATCH] Replace SortDirection with SortOrder, SortDirection is being removed. --- packages/backend-core/src/sql/sql.ts | 6 +- packages/pro | 2 +- .../server/src/integrations/googlesheets.ts | 2 +- .../src/sdk/app/rows/search/external.ts | 6 +- .../server/src/sdk/app/rows/search/sqs.ts | 5 +- .../shared-core/src/tests/filters.test.ts | 415 ------------------ packages/types/src/sdk/datasources.ts | 5 - packages/types/src/sdk/search.ts | 6 +- yarn.lock | 24 +- 9 files changed, 25 insertions(+), 446 deletions(-) delete mode 100644 packages/shared-core/src/tests/filters.test.ts diff --git a/packages/backend-core/src/sql/sql.ts b/packages/backend-core/src/sql/sql.ts index 61d5849058..7ab3e8ca80 100644 --- a/packages/backend-core/src/sql/sql.ts +++ b/packages/backend-core/src/sql/sql.ts @@ -18,7 +18,6 @@ import { SqlQuery, RelationshipsJson, SearchFilters, - SortDirection, SqlQueryBinding, Table, TableSourceType, @@ -27,6 +26,7 @@ import { QueryOptions, JsonTypes, prefixed, + SortOrder, } from "@budibase/types" import environment from "../environment" import { helpers } from "@budibase/shared-core" @@ -420,11 +420,11 @@ class InternalBuilder { if (sort && Object.keys(sort || {}).length > 0) { for (let [key, value] of Object.entries(sort)) { const direction = - value.direction === SortDirection.ASCENDING ? "asc" : "desc" + value.direction === SortOrder.ASCENDING ? "asc" : "desc" let nulls if (this.client === SqlClient.POSTGRES) { // All other clients already sort this as expected by default, and adding this to the rest of the clients is causing issues - nulls = value.direction === SortDirection.ASCENDING ? "first" : "last" + nulls = value.direction === SortOrder.ASCENDING ? "first" : "last" } query = query.orderBy(`${aliased}.${key}`, direction, nulls) diff --git a/packages/pro b/packages/pro index 85b4fc9ea0..e093f49a9d 160000 --- a/packages/pro +++ b/packages/pro @@ -1 +1 @@ -Subproject commit 85b4fc9ea01472bf69840d046733ad596ef893e2 +Subproject commit e093f49a9d0f548fe8cf7b981d1e88eb0fcc394a diff --git a/packages/server/src/integrations/googlesheets.ts b/packages/server/src/integrations/googlesheets.ts index d02d646fa4..9dee9b2a53 100644 --- a/packages/server/src/integrations/googlesheets.ts +++ b/packages/server/src/integrations/googlesheets.ts @@ -566,7 +566,7 @@ class GoogleSheetsIntegration implements DatasourcePlus { query.filters.equal[`_${GOOGLE_SHEETS_PRIMARY_KEY}`] = id } } - let filtered = dataFilters.runQuery(rows, query.filters) + let filtered = dataFilters.runQuery(rows, query.filters || {}) if (hasFilters && query.paginate) { filtered = filtered.slice(offset, offset + limit) } diff --git a/packages/server/src/sdk/app/rows/search/external.ts b/packages/server/src/sdk/app/rows/search/external.ts index 077f971903..0430965ec7 100644 --- a/packages/server/src/sdk/app/rows/search/external.ts +++ b/packages/server/src/sdk/app/rows/search/external.ts @@ -1,6 +1,5 @@ import { SortJson, - SortDirection, Operation, PaginationJson, IncludeRelationship, @@ -9,6 +8,7 @@ import { RowSearchParams, SearchResponse, Table, + SortOrder, } from "@budibase/types" import * as exporters from "../../../../api/controllers/view/exporters" import { handleRequest } from "../../../../api/controllers/row/external" @@ -52,8 +52,8 @@ export async function search( if (params.sort) { const direction = params.sortOrder === "descending" - ? SortDirection.DESCENDING - : SortDirection.ASCENDING + ? SortOrder.DESCENDING + : SortOrder.ASCENDING sort = { [params.sort]: { direction }, } diff --git a/packages/server/src/sdk/app/rows/search/sqs.ts b/packages/server/src/sdk/app/rows/search/sqs.ts index 87b905a29f..59a0afc0a4 100644 --- a/packages/server/src/sdk/app/rows/search/sqs.ts +++ b/packages/server/src/sdk/app/rows/search/sqs.ts @@ -8,7 +8,6 @@ import { RowSearchParams, SearchFilters, SearchResponse, - SortDirection, SortOrder, SortType, SqlClient, @@ -170,8 +169,8 @@ export async function search( sortField.type === FieldType.NUMBER ? SortType.NUMBER : SortType.STRING const sortDirection = params.sortOrder === SortOrder.ASCENDING - ? SortDirection.ASCENDING - : SortDirection.DESCENDING + ? SortOrder.ASCENDING + : SortOrder.DESCENDING request.sort = { [sortField.name]: { direction: sortDirection, diff --git a/packages/shared-core/src/tests/filters.test.ts b/packages/shared-core/src/tests/filters.test.ts deleted file mode 100644 index f5c2c2f06c..0000000000 --- a/packages/shared-core/src/tests/filters.test.ts +++ /dev/null @@ -1,415 +0,0 @@ -import { - SearchFilters, - SearchFilterOperator, - FieldType, - SearchFilter, -} from "@budibase/types" -import { buildQuery, runQuery } from "../filters" - -describe("runQuery", () => { - const docs = [ - { - order_id: 1, - customer_id: 259, - order_status: 4, - order_date: "2016-01-01T00:00:00.000Z", - required_date: "2016-01-03T00:00:00.000Z", - shipped_date: "2016-01-03T00:00:00.000Z", - store_id: 1, - staff_id: 2, - description: "Large box", - label: undefined, - }, - { - order_id: 2, - customer_id: 1212, - order_status: 4, - order_date: "2016-01-05T00:00:00.000Z", - required_date: "2016-01-04T00:00:00.000Z", - shipped_date: "2016-01-03T00:00:00.000Z", - store_id: 2, - staff_id: 6, - description: "Small box", - label: "FRAGILE", - }, - { - order_id: 3, - customer_id: 523, - order_status: 5, - order_date: "2016-01-12T00:00:00.000Z", - required_date: "2016-01-05T00:00:00.000Z", - shipped_date: "2016-01-03T00:00:00.000Z", - store_id: 2, - staff_id: 7, - description: "Heavy box", - label: "HEAVY", - }, - ] - - function buildQuery(filters: { [filterKey: string]: any }): SearchFilters { - const query: SearchFilters = { - string: {}, - fuzzy: {}, - range: {}, - equal: {}, - notEqual: {}, - empty: {}, - notEmpty: {}, - contains: {}, - notContains: {}, - oneOf: {}, - containsAny: {}, - allOr: false, - } - - for (const filterKey in filters) { - query[filterKey as SearchFilterOperator] = filters[filterKey] - } - - return query - } - - it("should return input docs if no search query is provided", () => { - expect(runQuery(docs)).toBe(docs) - }) - - it("should return matching rows for equal filter", () => { - const query = buildQuery({ - equal: { order_status: 4 }, - }) - expect(runQuery(docs, query).map(row => row.order_id)).toEqual([1, 2]) - }) - - it("should return matching row for notEqual filter", () => { - const query = buildQuery({ - notEqual: { order_status: 4 }, - }) - - expect(runQuery(docs, query).map(row => row.order_id)).toEqual([3]) - }) - - it("should return starts with matching rows for fuzzy and string filters", () => { - expect( - runQuery( - docs, - buildQuery({ - fuzzy: { description: "sm" }, - }) - ).map(row => row.description) - ).toEqual(["Small box"]) - expect( - runQuery( - docs, - buildQuery({ - string: { description: "SM" }, - }) - ).map(row => row.description) - ).toEqual(["Small box"]) - }) - - it("should return rows within a range filter", () => { - const query = buildQuery({ - range: { - customer_id: { - low: 500, - high: 1000, - }, - }, - }) - - expect(runQuery(docs, query).map(row => row.order_id)).toEqual([3]) - }) - - it("should return rows with numeric strings within a range filter", () => { - const query = buildQuery({ - range: { - customer_id: { - low: "500", - high: "1000", - }, - }, - }) - expect(runQuery(docs, query).map(row => row.order_id)).toEqual([3]) - }) - - it("should return rows with ISO date strings within a range filter", () => { - const query = buildQuery({ - range: { - order_date: { - low: "2016-01-04T00:00:00.000Z", - high: "2016-01-11T00:00:00.000Z", - }, - }, - }) - - expect(runQuery(docs, query).map(row => row.order_id)).toEqual([2]) - }) - - it("should return return all docs if an invalid doc value is passed into a range filter", async () => { - const docs = [ - { - order_id: 4, - customer_id: 1758, - order_status: 5, - order_date: "{{ Binding.INVALID }}", - required_date: "2017-03-05T00:00:00.000Z", - shipped_date: "2017-03-03T00:00:00.000Z", - store_id: 2, - staff_id: 7, - description: undefined, - label: "", - }, - ] - - const query = buildQuery({ - range: { - order_date: { - low: "2016-01-04T00:00:00.000Z", - high: "2016-01-11T00:00:00.000Z", - }, - }, - }) - - expect(runQuery(docs, query)).toEqual(docs) - }) - - it("should return rows with matches on empty filter", () => { - const query = buildQuery({ - empty: { - label: null, - }, - }) - - expect(runQuery(docs, query).map(row => row.order_id)).toEqual([1]) - }) - - it("should return rows with matches on notEmpty filter", () => { - const query = buildQuery({ - notEmpty: { - label: null, - }, - }) - - expect(runQuery(docs, query).map(row => row.order_id)).toEqual([2, 3]) - }) - - it.each([[523, 259], "523,259"])( - "should return rows with matches on numeric oneOf filter", - input => { - const query = buildQuery({ - oneOf: { - customer_id: input, - }, - }) - - expect(runQuery(docs, query).map(row => row.customer_id)).toEqual([ - 259, 523, - ]) - } - ) - - it.each([ - [false, []], - [true, [1, 2, 3]], - ])("should return %s if allOr is %s ", (allOr, expectedResult) => { - const query = buildQuery({ - allOr, - oneOf: { staff_id: [10] }, - contains: { description: ["box"] }, - }) - - expect(runQuery(docs, query).map(row => row.order_id)).toEqual( - expectedResult - ) - }) - - it("should return matching results if allOr is true and only one filter matches with different operands", () => { - const query = buildQuery({ - allOr: true, - equal: { order_status: 4 }, - oneOf: { label: ["FRAGILE"] }, - }) - - expect(runQuery(docs, query).map(row => row.order_id)).toEqual([1, 2]) - }) - - it("should handle when a value is null or undefined", () => { - const query = buildQuery({ - allOr: true, - equal: { order_status: null }, - oneOf: { label: ["FRAGILE"] }, - }) - - expect(runQuery(docs, query).map(row => row.order_id)).toEqual([2]) - }) -}) - -describe("buildQuery", () => { - it("should return a basic search query template if the input is not an array", () => { - const filter: any = "NOT_AN_ARRAY" - expect(buildQuery(filter)).toEqual({ - string: {}, - fuzzy: {}, - range: {}, - equal: {}, - notEqual: {}, - empty: {}, - notEmpty: {}, - contains: {}, - notContains: {}, - oneOf: {}, - containsAny: {}, - }) - }) - - it("should parseFloat if the type is a number, but the value is a numeric string", () => { - const filter: SearchFilter[] = [ - { - operator: SearchFilterOperator.EQUAL, - field: "customer_id", - type: FieldType.NUMBER, - value: "1212", - }, - { - operator: SearchFilterOperator.ONE_OF, - field: "customer_id", - type: FieldType.NUMBER, - value: "1000,1212,3400", - }, - ] - expect(buildQuery(filter)).toEqual({ - string: {}, - fuzzy: {}, - range: {}, - equal: { - customer_id: 1212, - }, - notEqual: {}, - empty: {}, - notEmpty: {}, - contains: {}, - notContains: {}, - oneOf: { - customer_id: [1000, 1212, 3400], - }, - containsAny: {}, - }) - }) - - it("should not parseFloat if the type is a number, but the value is a handlebars binding string", () => { - const filter: SearchFilter[] = [ - { - operator: SearchFilterOperator.EQUAL, - field: "customer_id", - type: FieldType.NUMBER, - value: "{{ customer_id }}", - }, - { - operator: SearchFilterOperator.ONE_OF, - field: "customer_id", - type: FieldType.NUMBER, - value: "{{ list_of_customer_ids }}", - }, - ] - expect(buildQuery(filter)).toEqual({ - string: {}, - fuzzy: {}, - range: {}, - equal: { - customer_id: "{{ customer_id }}", - }, - notEqual: {}, - empty: {}, - notEmpty: {}, - contains: {}, - notContains: {}, - oneOf: { - customer_id: "{{ list_of_customer_ids }}", - }, - containsAny: {}, - }) - }) - - it("should cast string to boolean if the type is boolean", () => { - const filter: SearchFilter[] = [ - { - operator: SearchFilterOperator.EQUAL, - field: "a", - type: FieldType.BOOLEAN, - value: "not_true", - }, - { - operator: SearchFilterOperator.NOT_EQUAL, - field: "b", - type: FieldType.BOOLEAN, - value: "not_true", - }, - { - operator: SearchFilterOperator.EQUAL, - field: "c", - type: FieldType.BOOLEAN, - value: "true", - }, - ] - expect(buildQuery(filter)).toEqual({ - string: {}, - fuzzy: {}, - range: {}, - equal: { - b: true, - c: true, - }, - notEqual: { - a: true, - }, - empty: {}, - notEmpty: {}, - contains: {}, - notContains: {}, - oneOf: {}, - containsAny: {}, - }) - }) - - it("should split the string for contains operators", () => { - const filter: SearchFilter[] = [ - { - operator: SearchFilterOperator.CONTAINS, - field: "description", - type: FieldType.ARRAY, - value: "Large box,Heavy box,Small box", - }, - { - operator: SearchFilterOperator.NOT_CONTAINS, - field: "description", - type: FieldType.ARRAY, - value: "Large box,Heavy box,Small box", - }, - { - operator: SearchFilterOperator.CONTAINS_ANY, - field: "description", - type: FieldType.ARRAY, - value: "Large box,Heavy box,Small box", - }, - ] - expect(buildQuery(filter)).toEqual({ - string: {}, - fuzzy: {}, - range: {}, - equal: {}, - notEqual: {}, - empty: {}, - notEmpty: {}, - contains: { - description: ["Large box", "Heavy box", "Small box"], - }, - notContains: { - description: ["Large box", "Heavy box", "Small box"], - }, - oneOf: {}, - containsAny: { - description: ["Large box", "Heavy box", "Small box"], - }, - }) - }) -}) diff --git a/packages/types/src/sdk/datasources.ts b/packages/types/src/sdk/datasources.ts index 77e4877dfa..3a788cbac6 100644 --- a/packages/types/src/sdk/datasources.ts +++ b/packages/types/src/sdk/datasources.ts @@ -22,11 +22,6 @@ export const RowOperations = [ Operation.BULK_CREATE, ] -export enum SortDirection { - ASCENDING = "ASCENDING", - DESCENDING = "DESCENDING", -} - export enum QueryType { SQL = "sql", JSON = "json", diff --git a/packages/types/src/sdk/search.ts b/packages/types/src/sdk/search.ts index dc8ea09bcc..00bb6e267d 100644 --- a/packages/types/src/sdk/search.ts +++ b/packages/types/src/sdk/search.ts @@ -1,6 +1,6 @@ -import { Operation, SortDirection } from "./datasources" +import { Operation } from "./datasources" import { Row, Table, DocumentType } from "../documents" -import { SortType } from "../api" +import { SortOrder, SortType } from "../api" import { Knex } from "knex" export enum SearchFilterOperator { @@ -77,7 +77,7 @@ export type SearchQueryFields = Omit export interface SortJson { [key: string]: { - direction: SortDirection + direction: SortOrder type?: SortType } } diff --git a/yarn.lock b/yarn.lock index 426fa2275d..d71dd4da78 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3495,10 +3495,10 @@ dependencies: lodash "^4.17.21" -"@koa/cors@^3.1.0": - version "3.4.3" - resolved "https://registry.yarnpkg.com/@koa/cors/-/cors-3.4.3.tgz#d669ee6e8d6e4f0ec4a7a7b0a17e7a3ed3752ebb" - integrity sha512-WPXQUaAeAMVaLTEFpoq3T2O1C+FstkjJnDQqy95Ck1UdILajsRhu6mhJ8H2f4NFPRBoCNN+qywTJfq/gGki5mw== +"@koa/cors@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@koa/cors/-/cors-5.0.0.tgz#0029b5f057fa0d0ae0e37dd2c89ece315a0daffd" + integrity sha512-x/iUDjcS90W69PryLDIMgFyV21YLTnG9zOpPXS7Bkt2b8AsY3zZsIpOLBkYr9fBcF3HbkKaER5hOBZLfpLgYNw== dependencies: vary "^1.1.2" @@ -5817,10 +5817,10 @@ "@types/koa-compose" "*" "@types/node" "*" -"@types/koa__cors@^3.1.1": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@types/koa__cors/-/koa__cors-3.3.1.tgz#0ec7543c4c620fd23451bfdd3e21b9a6aadedccd" - integrity sha512-aFGYhTFW7651KhmZZ05VG0QZJre7QxBxDj2LF1lf6GA/wSXEfKVAJxiQQWzRV4ZoMzQIO8vJBXKsUcRuvYK9qw== +"@types/koa__cors@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@types/koa__cors/-/koa__cors-5.0.0.tgz#74567a045b599266e2cd3940cef96cedecc2ef1f" + integrity sha512-LCk/n25Obq5qlernGOK/2LUwa/2YJb2lxHUkkvYFDOpLXlVI6tKcdfCHRBQnOY4LwH6el5WOLs6PD/a8Uzau6g== dependencies: "@types/koa" "*" @@ -16343,10 +16343,10 @@ node-source-walk@^5.0.0: dependencies: "@babel/parser" "^7.0.0" -nodemailer@6.7.2: - version "6.7.2" - resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.7.2.tgz#44b2ad5f7ed71b7067f7a21c4fedabaec62b85e0" - integrity sha512-Dz7zVwlef4k5R71fdmxwR8Q39fiboGbu3xgswkzGwczUfjp873rVxt1O46+Fh0j1ORnAC6L9+heI8uUpO6DT7Q== +nodemailer@6.9.13: + version "6.9.13" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.9.13.tgz#5b292bf1e92645f4852ca872c56a6ba6c4a3d3d6" + integrity sha512-7o38Yogx6krdoBf3jCAqnIN4oSQFx+fMa0I7dK1D+me9kBxx12D+/33wSb+fhOCtIxvYJ+4x4IMEhmhCKfAiOA== nodemailer@6.9.9: version "6.9.9"