From 74c1ecf33c2611a41594234524636a3687e3f2b4 Mon Sep 17 00:00:00 2001 From: Akalanka Perera Date: Mon, 25 Mar 2024 14:31:23 +0000 Subject: [PATCH] Feat!: added support for more complex filters --- packages/mongoose-filter-query/readme.md | 12 ++++++++++ packages/mongoose-filter-query/src/index.js | 24 ++++++++++++------- .../mongoose-filter-query/test/__mocks.js | 14 +++++++++++ .../mongoose-filter-query/test/index.test.js | 6 +++++ 4 files changed, 48 insertions(+), 8 deletions(-) diff --git a/packages/mongoose-filter-query/readme.md b/packages/mongoose-filter-query/readme.md index d50dc4d..ced2182 100644 --- a/packages/mongoose-filter-query/readme.md +++ b/packages/mongoose-filter-query/readme.md @@ -115,12 +115,24 @@ console.log(data); - This will return all users with a first name of John, Eric or matches the given regular expression

+```javascript +"http://localhost:3000/api/users?filter[or]=first_name=eq(John),last_name=eq(Eric)"; +``` + +- This will return all users with a first name of John or a last name of Eric

+ ```javascript "http://localhost:3000/api/users?filter[age]=and(gt(20),lt(30))"; ``` - This will return all users with an age which is between 20 and 30

+```javascript +"http://localhost:3000/api/users?filter[and]=age=gt(20),first_name=eq(John)"; +``` + +- This will return all users with an age greater than 20 and a first name of John

+ ## Multiple Filters

- Multiple filters can be chained together with the use of the & operator

diff --git a/packages/mongoose-filter-query/src/index.js b/packages/mongoose-filter-query/src/index.js index f0f6282..e94afd9 100644 --- a/packages/mongoose-filter-query/src/index.js +++ b/packages/mongoose-filter-query/src/index.js @@ -7,15 +7,23 @@ const mongooseFilterQuery = (req, res, next) => { if (req.query.filter) { Object.keys(req.query.filter).forEach((key) => { const value = req.query.filter[key]; - const complexOp = complexOperators.find((op) => value.startsWith(`${op}(`)); - if (complexOp) { - const values = replaceOperator(value, complexOp)?.split(","); - req.query.filter[`$${complexOp}`] = values.map((subValue) => ({ - [key]: mapValue(subValue) - })); - delete req.query.filter[key]; + if (complexOperators.includes(key)) { + req.query.filter[`$${key}`] = value.split(",").map((kv) => { + const [key, value] = kv.split("=") + return { [key]: mapValue(value) } + }) + delete req.query.filter[key] } else { - req.query.filter[key] = mapValue(value); + const complexOp = complexOperators.find((op) => value.startsWith(`${op}(`)); + if (complexOp) { + const values = replaceOperator(value, complexOp)?.split(","); + req.query.filter[`$${complexOp}`] = values.map((subValue) => ({ + [key]: mapValue(subValue) + })); + delete req.query.filter[key]; + } else { + req.query.filter[key] = mapValue(value); + } } }); } else { diff --git a/packages/mongoose-filter-query/test/__mocks.js b/packages/mongoose-filter-query/test/__mocks.js index 8e2f0c0..d10205b 100644 --- a/packages/mongoose-filter-query/test/__mocks.js +++ b/packages/mongoose-filter-query/test/__mocks.js @@ -46,6 +46,20 @@ export const complexFilterResult = { $or: [{ lastName: { $eq: "Doe" } }, { lastName: { $ne: "John" } }] }; +export const complexRootKeyFilterReq = { + query: { + filter: { + or: "firstName=eq(John),lastName=eq(Doe)", + and: "age=gt(20),firstName=eq(John)" + } + } +}; + +export const complexRootKeyFilterResult = { + $or: [{ firstName: { $eq: "John" } }, { lastName: { $eq: "Doe" } }], + $and: [{ age: { $gt: 20 } }, { firstName: { $eq: "John" } }], +}; + export const sortsReq = { query: { sort: { diff --git a/packages/mongoose-filter-query/test/index.test.js b/packages/mongoose-filter-query/test/index.test.js index d19eb7c..43c57d9 100644 --- a/packages/mongoose-filter-query/test/index.test.js +++ b/packages/mongoose-filter-query/test/index.test.js @@ -5,6 +5,8 @@ import { basicFilterResult, complexFilterReq, complexFilterResult, + complexRootKeyFilterReq, + complexRootKeyFilterResult, sortsReq, sortResult, includeReq, @@ -24,6 +26,10 @@ describe("test mongoose-filter-query", () => { mongooseFilterQuery(complexFilterReq, {}, () => {}); expect(complexFilterReq.query.filter).toEqual(complexFilterResult); }); + test("complex as root key", async () => { + mongooseFilterQuery(complexRootKeyFilterReq, {}, () => {}); + expect(complexRootKeyFilterReq.query.filter).toEqual(complexRootKeyFilterResult); + }); test("undefined", async () => { mongooseFilterQuery(sortsReq, {}, () => {}); expect(sortsReq.query.filter).toEqual({});