Skip to content

Commit 81ba8e2

Browse files
authored
Merge pull request #150 from alexovn/fix/logical-operator-not-inside-nested-prop
2 parents e90e526 + 4acb9a9 commit 81ba8e2

3 files changed

Lines changed: 41 additions & 2 deletions

File tree

.changeset/happy-games-greet.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"odata-query": patch
3+
---
4+
5+
- fix: resolve an issue with logical operator "not" inside nested property ([#98](https://github.com/techniq/odata-query/issues/98))

src/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,13 @@ function buildFilter<T>(filters: Filter<T> = {}, aliases: Alias[] = [], propPref
303303
result.push(`${op}(${propName},${handleValue(value[op], aliases)})`);
304304
} else {
305305
// Nested property
306-
const filter = buildFilterCore({ [op]: value[op] }, aliases, propName);
306+
const isPropNameContainsNot = /\/not/g.test(propName)
307+
let internalPropName = isPropNameContainsNot ? propName.replace(/\/not/g, '') : propName
308+
309+
const filter = isPropNameContainsNot
310+
? parseNot([buildFilterCore({ [op]: value[op] }, aliases, internalPropName)])
311+
: buildFilterCore({ [op]: value[op] }, aliases, internalPropName)
312+
307313
if (filter) {
308314
result.push(filter);
309315
}

test/index.test.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,17 @@ describe('filter', () => {
164164
});
165165

166166
describe('logical operators', () => {
167+
it('should handle simple logical operators (not)', () => {
168+
const filter = {
169+
not: { FooProp: { startswith: 'foo' } }
170+
};
171+
const expected =
172+
"?$filter=not (startswith(FooProp,'foo'))";
173+
const actual = buildQuery({ filter });
174+
expect(actual).toEqual(expected);
175+
});
176+
177+
167178
it('should handle simple logical operators (not) as an object', () => {
168179
const filter = {
169180
and: [
@@ -173,7 +184,24 @@ describe('filter', () => {
173184
],
174185
};
175186
const expected =
176-
"?$filter=((not (startswith(FooProp,'foo'))) and (not (startswith(BarProp,'bar'))) and (startswith(FooBarProp,'foobar')))";
187+
"?$filter=((not (startswith(FooProp,'foo'))) and (not (startswith(BarProp,'bar'))) and (startswith(FooBarProp,'foobar')))";
188+
const actual = buildQuery({ filter });
189+
expect(actual).toEqual(expected);
190+
});
191+
192+
it('should handle simple logical operators (not) inside nested prop', () => {
193+
const filter = {
194+
Prop: {
195+
all: {
196+
and: [
197+
{ not: { FooProp: { contains: "foo" } } },
198+
{ BarProp: { contains: "bar" }},
199+
],
200+
},
201+
},
202+
};
203+
const expected =
204+
"?$filter=Prop/all(prop:((not (contains(prop/FooProp,'foo'))) and (contains(prop/BarProp,'bar'))))";
177205
const actual = buildQuery({ filter });
178206
expect(actual).toEqual(expected);
179207
});

0 commit comments

Comments
 (0)