Skip to content

Commit

Permalink
Feat!: added support for more complex filters
Browse files Browse the repository at this point in the history
  • Loading branch information
Akalanka47000 authored Mar 25, 2024
1 parent 9a47c30 commit 607bbac
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 20 deletions.
12 changes: 12 additions & 0 deletions packages/mongoose-filter-query/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<br><br>

```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<br><br>

```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<br><br>

```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<br><br>

## Multiple Filters<br><br>

- Multiple filters can be chained together with the use of the & operator<br><br>
Expand Down
23 changes: 3 additions & 20 deletions packages/mongoose-filter-query/src/index.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,9 @@
import { mapValue, replaceOperator } from "./utils";

const complexOperators = ["and", "or"];
import { mapFilters } from "./utils";

const mongooseFilterQuery = (req, res, next) => {
try {
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];
} else {
req.query.filter[key] = mapValue(value);
}
});
} else {
req.query.filter = {};
}
req.query.filter = mapFilters(req.query.filter) ?? {}
mapFilters(req.query.secondaryFilter)
if (req.query.sort) {
Object.keys(req.query.sort).forEach((key) => {
const dir = req.query.sort[key];
Expand Down
29 changes: 29 additions & 0 deletions packages/mongoose-filter-query/src/utils.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const complexOperators = ["and", "or"];

export const replaceOperator = (value, operator) => {
value = value.replace(`${operator}(`, "").slice(0, -1);
if (isNaN(value)) {
Expand Down Expand Up @@ -38,3 +40,30 @@ export const mapValue = (value) => {
}
return value;
};

export const mapFilters = (filter = {}) => {
if (filter) {
Object.keys(filter).forEach((key) => {
const value = filter[key];
if (complexOperators.includes(key)) {
filter[`$${key}`] = value.split(",").map((kv) => {
const [key, value] = kv.split("=")
return { [key]: mapValue(value) }
})
delete filter[key]
} else {
const complexOp = complexOperators.find((op) => value.startsWith(`${op}(`));
if (complexOp) {
const values = replaceOperator(value, complexOp)?.split(",");
filter[`$${complexOp}`] = values.map((subValue) => ({
[key]: mapValue(subValue)
}));
delete filter[key];
} else {
filter[key] = mapValue(value);
}
}
});
}
return filter;
}
14 changes: 14 additions & 0 deletions packages/mongoose-filter-query/test/__mocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down
6 changes: 6 additions & 0 deletions packages/mongoose-filter-query/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {
basicFilterResult,
complexFilterReq,
complexFilterResult,
complexRootKeyFilterReq,
complexRootKeyFilterResult,
sortsReq,
sortResult,
includeReq,
Expand All @@ -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({});
Expand Down

0 comments on commit 607bbac

Please sign in to comment.