Skip to content

Commit dd2b750

Browse files
committed
Add ability to specify custom conditionMapper
1 parent 20a5b47 commit dd2b750

2 files changed

Lines changed: 47 additions & 6 deletions

File tree

src/index.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export const splitColumnAndCondition = (filterQS) => {
9090
return { column, condition };
9191
};
9292

93-
const processFilter = (filterQS, castFn, preprocessor) => {
93+
const processFilter = (filterQS, castFn, preprocessor, conditionMapper) => {
9494
const { column, condition } = splitColumnAndCondition(filterQS);
9595

9696
const preprocessed = preprocessor(column);
@@ -105,7 +105,13 @@ const processFilter = (filterQS, castFn, preprocessor) => {
105105
if (cast) query = `(${preprocessed})::${cast}`;
106106
}
107107

108-
const currCondition = conditionMap[condition];
108+
let currCondition = conditionMap[condition];
109+
if (conditionMapper) {
110+
const mappedCondition = conditionMapper(column, condition, currCondition);
111+
if (mappedCondition) {
112+
currCondition = mappedCondition;
113+
}
114+
}
109115
if (currCondition.includes('??')) {
110116
return currCondition.replace('??', query);
111117
}
@@ -116,13 +122,13 @@ const processFilter = (filterQS, castFn, preprocessor) => {
116122

117123
export const knexFlexFilter = (originalQuery, where = {}, opts = {}) => {
118124
const {
119-
castFn, preprocessor = defaultPreprocessor(), isAggregateFn, caseInsensitiveSearch = false,
125+
castFn, preprocessor = defaultPreprocessor(), isAggregateFn, caseInsensitiveSearch = false, conditionMapper,
120126
} = opts;
121127

122128
let result = originalQuery;
123129

124130
Object.keys(where).forEach((key) => {
125-
let query = processFilter(key, castFn, preprocessor);
131+
let query = processFilter(key, castFn, preprocessor, conditionMapper);
126132
const { column, condition } = splitColumnAndCondition(key);
127133
let queryFn = 'whereRaw';
128134
if (isAggregateFn) {

tests/knex-flex-filter.test.js

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11

22
import seedsFn from './helpers/seeds';
33
import knex from './knex';
4-
import knexFlexFilter, { jsonbPreprocessor } from '../src';
4+
import knexFlexFilter, { jsonbPreprocessor, defaultPreprocessor, EQ } from '../src';
55

66
require('./helpers/database');
77

88

99
describe('knex-flex-filter', () => {
10-
let castFn;
10+
let castFn;
1111

1212
beforeEach(async (done) => {
1313
await seedsFn(knex);
@@ -630,4 +630,39 @@ describe('knex-flex-filter', () => {
630630
done();
631631
});
632632
});
633+
634+
describe('when filtering using the condition mapper', () => {
635+
const BLOCK_NUMBER = 5000;
636+
it('should correctly use new condition operator @>', async () => {
637+
const query = knexFlexFilter(
638+
knex.table('entities'),
639+
{
640+
lastBuyBlockNumber_eq: { lastBuyBlockNumber: BLOCK_NUMBER },
641+
},
642+
{
643+
preprocessor: (column) => {
644+
switch (column) {
645+
case 'lastBuyBlockNumber':
646+
return 'data'; // match against data
647+
default:
648+
return defaultPreprocessor()(column);
649+
}
650+
},
651+
conditionMapper: (column, condition, defaultValue) => {
652+
if (column === 'lastBuyBlockNumber' && condition === EQ) {
653+
return '@> ?';
654+
}
655+
return defaultValue;
656+
},
657+
},
658+
);
659+
660+
expect(query._statements[0].value.sql).toEqual('data @> ?');
661+
expect(query._statements[0].value.bindings).toEqual([{ lastBuyBlockNumber: BLOCK_NUMBER }]);
662+
663+
const result = await query;
664+
665+
expect(parseInt(result[0].data.lastBuyBlockNumber, 10)).toEqual(BLOCK_NUMBER);
666+
});
667+
});
633668
});

0 commit comments

Comments
 (0)