qs.parse returns invalid key with brackets when using nested array query#1751
qs.parse returns invalid key with brackets when using nested array query#1751tintinthong merged 13 commits intomainfrom
Conversation
| filter.every.every((value: any, index: number) => | ||
| assertFilter(value, pointer.concat(`[${index}]`)), | ||
| ); |
There was a problem hiding this comment.
.every is problematic because it expects to return a boolean. So, not all assertions are being run thru
| throw new Error(`${pointer.join('/') || '/'}: eq must be an object`); | ||
| } | ||
| Object.entries(filter.eq).every(([key, value]) => | ||
| assertJSONValue(value, pointer.concat(key)), |
There was a problem hiding this comment.
pointer.concat doesn't even mutate the pointer. I would prefer to handle in another PR
060aaa6 to
2611f1a
Compare
b6e0fe1 to
ee8d70d
Compare
| .containsText('Cardy Stackington Jr. III'); | ||
| }); | ||
|
|
||
| test<TestContextWithSSE>(`can parse objects in nested array`, async function (assert) { |
There was a problem hiding this comment.
I meant to come up with a better name here
|
I noticed in the qs docs, this comment:
Is this actually the problem, do these items reside 5+ levels deep? if they were higher up in the composition hierarchy would they be parsed correctly? If so, there is a |
Yes it is! I recall looking into this and thought 5 was sufficient depth. The depth that works is 6! I think this solves my issue, any ideas what should be the default depth? |
Let’s do a |
|
| } | ||
|
|
||
| export const parseQuery = (queryString: string) => { | ||
| // @ts-ignore |
There was a problem hiding this comment.
let's be a little more precise why we are ignoring. I usually do:
// @ts-expect-error no types available for XXX
this way when types do become available our lint will let us know that the following line doesn't need to be ignored anymore
There was a problem hiding this comment.
Thanks. Just fixed
There was a problem hiding this comment.
This has been merged DefinitelyTyped/DefinitelyTyped#71087 and deployed on @6.9.17 of qs. No need for ts-expect-error anymore
EDIT TLDR:
This PR fixes a limitation of the depth that qs.parse is parsing. There is a default of depthLimit = 5 hence, our nested queries would parse key names with brackets outside. This PR configures, depthLimit = 10 and sets strictDepth = true ( a new feature shipped in qs) which errors out if qs.parse recurses too deep.
=====Below Description here is historical=====
Problem
When making complicated queries where any array nests within every array,
qs.parseincorrectly parses the string st a key has brackets wrapped around it.Fixing this problem unlocks the ability to nest
everyandanyqueries which is useful for complex querying in applications that will be used by ecosystem team.Here is the test you can see a3ea344
The cardsQuery after returned from
qs.parsewill look like thisThe issue errors out because
pathSegmentsdoesn't know how to handle bracketsboxel/packages/runtime-common/index-query-engine.ts
Line 914 in a398617
SOLUTION
I decided to post-parse the
qs.parseobject even before going into the realm-index.query-engine. Placing my fix inrealm.tswas intentional because I thought that the issue was withinqs.parse, although, its possibly easier if using one-linerremoveOuterBracketjust occured nearpathSegmentsinsiderealm.ts(open to opinions here) since the recursion is already made.I have also attempted to use qs.parse configuration but was unsuccesful bcos I don't think it works out-of-the-box
allowDotsconfiguration but it totally breaks the query structure query-engine is expecting since it converts keys to nested objects.qs.parseonly allows decoding of one-level deep and I didn't think it was worthwhile to expose myself to a recursiveqs.parse