Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use sanityImage('string') in q.object? #216

Open
multiplehats opened this issue Aug 14, 2023 · 4 comments
Open

How to use sanityImage('string') in q.object? #216

multiplehats opened this issue Aug 14, 2023 · 4 comments

Comments

@multiplehats
Copy link

Hey guys! Thanks for the awesome library.

One thing I can't figure out for the life of me is how to use sanityImage inside q.object().

import { type Selection, type TypeFromSelection, q, sanityImage } from 'groqd';

const gqField = q.object({
    s3_fileName: q.string().optional(),
    s3_id: q.string().optional(),
    createdAt: q.date(),
    image: sanityImage('image')
    // ^^ error: Type 'EntityQuery<FromSelection<{ readonly _key: ZodNullable<ZodString>; readonly _type: ZodString; } 
    // & { asset: EntityQuery<FromSelection<{ _ref: ZodString; _type: ZodLiteral<"reference">; }>>; }>>' 
    // is missing the following properties from type 'ZodType<any, any, any>': _type, _output, _input, _def, and 30 more.(2740)
})

const gqFields = {
    desktop: q.array(gqField),
    mobile: q.array(gqField),
} satisfies Selection;

export const gqPageFields = {
    id: ['_id', q.string()],
    name: q.string(),
    _updatedAt: q.date(),
    _createdAt: q.date(),
    images: q.object({
        one: q.object(gqFields),
        two: q.object(gqFields),
    })
} satisfies Selection;

export type PageFields = TypeFromSelection<typeof gqPageFields>;

Am I missing something?

@gksander
Copy link
Contributor

Ahh – the Zod/TS errors are not at all comprehensible. The core issue, I believe, is that the fields inside q.object() are looking for zod-compatible types (like q.string(), q.number(), etc.), but the sanityImage helper actually returns back a Groqd EntityQuery instance (basically, a groq sub-query with associated schema). So, the sanityImage – as it stands – will only work inside of a .grab() statement.

I believe the rationale for returning a groqd query from sanityImage (instead of a more simple zod schema) is that to get image assets, you have to deref a field or two (I believe you have to do something like a asset→ call to get asset details. You can't do that without a groq query somewhere in there.

Not sure if it's feasible, but you could probably achieve this by refactoring to using nested .grab() calls instead of q.object().

@tutods
Copy link

tutods commented Aug 29, 2023

@multiplehats any solution?
I'm facing the same issue.

@lime
Copy link

lime commented Sep 28, 2023

I think I got it working after a little trial and error, using nested .grab() calls per @gksander's suggestion.

So instead of this (which is how I expected groqd to work):

q("*")
  .filter("_type == 'page'")
  .grab$({
    hero: q.object({
      heading: q.string(),
      image: sanityImage("image", { withAsset: ["base", "blurHash"] }),
      content: q.contentBlocks(),
    }),
    sections: q.array(
      q.object({
        heading: q.string(),
        image: sanityImage("image", { withAsset: ["base", "blurHash"] }),
        content: q.contentBlocks(),
      })
    ),
  })

I used this:

q("*")
  .filter("_type == 'page'")
  .grab$({
    hero: q("hero").grab$({
      heading: q.string(),
      image: sanityImage("image", { withAsset: ["base", "blurHash"] }),
      content: q.contentBlocks(),
    }),
    sections: q("sections")
      .filter() // turns it into an array query
      .grab$({
        heading: q.string(),
        image: sanityImage("image", { withAsset: ["base", "blurHash"] }),
        content: q.contentBlocks(),
      }),
  })

It seems to give me both the right data and types. Happy to hear suggestions if there are better approaches.

@plckr
Copy link

plckr commented Jul 17, 2024

I'm having the same issue, I had like to find a better solution for this aswell

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants