FormidableLabs / groqd

A schema-unaware, runtime and type-safe query builder for GROQ.
https://commerce.nearform.com/open-source/groqd
MIT License
230 stars 16 forks source link

sanityImage inside a q.object() not working, keyValidator._parse is not a function #224

Closed Joostdeboer closed 1 year ago

Joostdeboer commented 1 year ago

I've been struggling with this issue the moment I started using the application. Every time I try to request an image including its url by using "sanityImage" from the library, I get the following error:

afbeelding

Meanwhile, if I try to use sanityImage outside of the object, for instance in the top level of the query, I do not receive any such errors. When looking through the error log, I receive the error that keyValidator._parse is not a function.

Reproduction code:

const temp = q('*')
    .filter('_type == "testPage"')
    .grab({
        working: sanityImage('image', { withAsset: ['base'] }),
        notWorking: q.object({
            image: sanityImage('image', { withAsset: ['base'] }),
        }),
    })
    .slice(0);

I feel like I'm doing something wrong, but it is unclear from the documentation what exactly the correct format should be in this case. Any ideas?

gksander commented 1 year ago

Hi @Joostdeboer – thanks for writing in. This is a bit confusing, because Zod and Groqd get a bit intertwined here. The sanityImage helper returns a groqd query (which is groq query string plus a Zod schema). Such query can be nested inside of e.g. a .grab calls (since groqd .grab argument can handle a nested query), but Zod itself knows nothing about groqd querys. q.object is a Zod member so it just doesn't understand what to do with a groqd query.

The reason sanityImage returns a groqd query instead of just a Zod object is because it needs to do some dereferencing on the groq side to fetch the image asset.

I'll make a note to add this to the docs, because this isn't the first (and likely won't be the last) time this has come up. The recommendation right now is to refactor to use nested queries (such as q().filter().grab({})) calls for when you need to use sanityImage.

I'm closing this accordingly, but feel free to re-open if you believe there's more to discuss here!