Skip to content

Commit f41a3dc

Browse files
committed
feat(utils): new util addToQuery
1 parent 5bb4423 commit f41a3dc

File tree

5 files changed

+90
-0
lines changed

5 files changed

+90
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
title: addToQuery
3+
category: utils
4+
---
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { addToQuery } from './add-to-query.util.js'
2+
3+
describe('addToQuery', () => {
4+
it('basic usage', () => {
5+
const result = addToQuery({}, 'id', 1)
6+
7+
expect(result).toEqual({ id: 1 })
8+
})
9+
10+
it('adds if property not in original query', () => {
11+
const result = addToQuery({ name: 'John' }, 'id', 1)
12+
13+
expect(result).toEqual({ name: 'John', id: 1 })
14+
})
15+
16+
it('does not add if exact same property-value pair exists', () => {
17+
const result = addToQuery({ id: 1 }, 'id', 1)
18+
19+
expect(result).toEqual({ id: 1 })
20+
})
21+
22+
it('adds to $and if property exists with different value', () => {
23+
const result = addToQuery({ id: 1 }, 'id', 2)
24+
25+
expect(result).toEqual({ id: 1, $and: [{ id: 2 }] })
26+
})
27+
28+
it('does not add to $and if exact same property-value pair exists in $and', () => {
29+
const result = addToQuery({ id: 1, $and: [{ id: 2 }] }, 'id', 2)
30+
31+
expect(result).toEqual({ id: 1, $and: [{ id: 2 }] })
32+
})
33+
34+
it('adds to $and if property exists with different value and $and already exists', () => {
35+
const result = addToQuery({ id: 1, $and: [{ id: 2 }] }, 'id', 3)
36+
37+
expect(result).toEqual({ id: 1, $and: [{ id: 2 }, { id: 3 }] })
38+
})
39+
})
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import type { Query } from '@feathersjs/feathers'
2+
import { deepEqual } from 'fast-equals'
3+
4+
/**
5+
* Safely adds a property to a query object. If the property already exists, it adds it to the `$and` array.
6+
* If the exact same property-value pair already exists, it does nothing.
7+
*/
8+
export const addToQuery = <Q extends Query>(
9+
targetQuery: Q,
10+
property: string,
11+
value: any,
12+
) => {
13+
if (!(property in targetQuery)) {
14+
return {
15+
...targetQuery,
16+
[property]: value,
17+
}
18+
}
19+
20+
if (deepEqual(targetQuery[property], value)) {
21+
// if the exact same value already exists, do nothing
22+
return targetQuery
23+
}
24+
25+
if (!targetQuery.$and) {
26+
return {
27+
...targetQuery,
28+
$and: [{ [property]: value }],
29+
}
30+
}
31+
32+
// check if the exact same value already exists in $and
33+
if (
34+
targetQuery.$and.some(
35+
(q: any) => property in q && deepEqual(q[property], value),
36+
)
37+
) {
38+
return targetQuery
39+
}
40+
41+
return {
42+
...targetQuery,
43+
$and: [...targetQuery.$and, { [property]: value }],
44+
}
45+
}

src/utils/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export * from './add-to-query/add-to-query.util.js'
12
export * from './add-skip/add-skip.util.js'
23
export * from './check-context/check-context.util.js'
34
export * from './context-to-json/context-to-json.util.js'

test/index.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const hooks = [
3939

4040
const utils = [
4141
'addSkip',
42+
'addToQuery',
4243
'checkContext',
4344
'contextToJson',
4445
'defineHooks',

0 commit comments

Comments
 (0)