From 9e4a821e3f012ff3eecc3e9d28157e3555a95cf3 Mon Sep 17 00:00:00 2001 From: roggervalf Date: Sat, 8 Mar 2025 23:20:41 -0600 Subject: [PATCH 1/3] feat: add support for more operators than contains --- src/utils/convert-filter.ts | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/utils/convert-filter.ts b/src/utils/convert-filter.ts index 61cc24c..be50ff9 100644 --- a/src/utils/convert-filter.ts +++ b/src/utils/convert-filter.ts @@ -29,14 +29,34 @@ export const convertFilter = (filter) => { }, }; } + + let operatorExpression; + if (typeof value === 'object') { + if (value.startsWith) { + operatorExpression = { + [(Op.like as unknown) as string]: `${escape(value.startsWith)}%`, + }; + } else if (value.endsWith) { + operatorExpression = { + [(Op.like as unknown) as string]: `%${escape(value.endsWith)}`, + }; + } else if (value.equals) { + operatorExpression = { + [Op.eq]: `${escape(value.equals)}`, + }; + } + } else { + operatorExpression = { + [(Op.like as unknown) as string]: `%${escape(value)}%`, + }; + } + return { ...memo, [Op.and]: [ ...(memo[Op.and] || []), { - [property.name()]: { - [(Op.like as unknown) as string]: `%${escape(value)}%`, - }, + [property.name()]: operatorExpression, }, ], }; From ee2a551fa2e3bbc7e30a0be6495fedc847d60568 Mon Sep 17 00:00:00 2001 From: roggervalf Date: Mon, 17 Mar 2025 00:48:16 -0600 Subject: [PATCH 2/3] feat: support or operators --- src/utils/convert-filter.ts | 64 +++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/src/utils/convert-filter.ts b/src/utils/convert-filter.ts index be50ff9..3241f76 100644 --- a/src/utils/convert-filter.ts +++ b/src/utils/convert-filter.ts @@ -3,6 +3,21 @@ import { Op } from 'sequelize'; export const uuidRegex = /^[0-9A-F]{8}-[0-9A-F]{4}-[5|4|3|2|1][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i; +const OPERATOR_SEPARATOR = '~' + +const MATCHING_PATTERNS = { + EQ: 'equals', + NE: 'notEquals', + CO: 'contains', + EW: 'endsWith', + SW: 'startsWith', +} + +const OPERATORS = { + AND: 'and', + OR: 'or' +} + export const convertFilter = (filter) => { if (!filter) { return {}; @@ -32,17 +47,54 @@ export const convertFilter = (filter) => { let operatorExpression; if (typeof value === 'object') { - if (value.startsWith) { + if (value[MATCHING_PATTERNS.SW]) { + operatorExpression = { + [(Op.like as unknown) as string]: `${escape(value[MATCHING_PATTERNS.SW])}%`, + }; + } else if (value[MATCHING_PATTERNS.EW]) { operatorExpression = { - [(Op.like as unknown) as string]: `${escape(value.startsWith)}%`, + [(Op.like as unknown) as string]: `%${escape(value[MATCHING_PATTERNS.EW])}`, }; - } else if (value.endsWith) { + } else if (value[MATCHING_PATTERNS.EQ]) { operatorExpression = { - [(Op.like as unknown) as string]: `%${escape(value.endsWith)}`, + [Op.eq]: `${escape(value[MATCHING_PATTERNS.EQ])}`, }; - } else if (value.equals) { + } else if (value[MATCHING_PATTERNS.NE]) { operatorExpression = { - [Op.eq]: `${escape(value.equals)}`, + [Op.ne]: `${escape(value[MATCHING_PATTERNS.NE])}`, + }; + } else { + const orPrefix = `${OPERATORS.OR}${OPERATOR_SEPARATOR}`; + if (value[`${orPrefix}${MATCHING_PATTERNS.SW}`]) { + operatorExpression = { + [(Op.like as unknown) as string]: `${escape(value[`${orPrefix}${MATCHING_PATTERNS.SW}`])}%`, + }; + } else if (value[`${orPrefix}${MATCHING_PATTERNS.EW}`]) { + operatorExpression = { + [(Op.like as unknown) as string]: `%${escape(value[`${orPrefix}${MATCHING_PATTERNS.EW}`])}`, + }; + } else if (value[`${orPrefix}${MATCHING_PATTERNS.EQ}`]) { + operatorExpression = { + [Op.eq]: `${escape(value[`${orPrefix}${MATCHING_PATTERNS.EQ}`])}`, + }; + } else if (value[`${orPrefix}${MATCHING_PATTERNS.NE}`]) { + operatorExpression = { + [Op.ne]: `${escape(value[`${orPrefix}${MATCHING_PATTERNS.NE}`])}`, + }; + } else if (value[OPERATORS.OR]) { + operatorExpression = { + [(Op.like as unknown) as string]: `%${escape(value[OPERATORS.OR])}%`, + }; + } + + return { + ...memo, + [Op.or]: [ + ...(memo[Op.or] || []), + { + [property.name()]: operatorExpression, + }, + ], }; } } else { From 25e4ca794612d1a55021889fd5ac194fe51a010f Mon Sep 17 00:00:00 2001 From: roggervalf Date: Mon, 17 Mar 2025 00:49:22 -0600 Subject: [PATCH 3/3] chore: apply lint --- src/utils/convert-filter.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/utils/convert-filter.ts b/src/utils/convert-filter.ts index 3241f76..bb564ff 100644 --- a/src/utils/convert-filter.ts +++ b/src/utils/convert-filter.ts @@ -3,7 +3,7 @@ import { Op } from 'sequelize'; export const uuidRegex = /^[0-9A-F]{8}-[0-9A-F]{4}-[5|4|3|2|1][0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i; -const OPERATOR_SEPARATOR = '~' +const OPERATOR_SEPARATOR = '~'; const MATCHING_PATTERNS = { EQ: 'equals', @@ -11,12 +11,12 @@ const MATCHING_PATTERNS = { CO: 'contains', EW: 'endsWith', SW: 'startsWith', -} +}; const OPERATORS = { AND: 'and', - OR: 'or' -} + OR: 'or', +}; export const convertFilter = (filter) => { if (!filter) { @@ -85,7 +85,7 @@ export const convertFilter = (filter) => { operatorExpression = { [(Op.like as unknown) as string]: `%${escape(value[OPERATORS.OR])}%`, }; - } + } return { ...memo,