RFC: "V2": strongly‐typed schemas, optional client‐side validation #227
Replies: 4 comments 13 replies
-
@scottrippey regarding export type Posts = InferResultType<typeof postsQuery>
export async function getAllPosts(): Promise<Posts> {
return runQuery(postsQuery)
} The Would it be possible to change export type Post = InferResultType<typeof postsQuery>
export async function getAllPosts(): Promise<Post[]> {
return runQuery(postsQuery)
} And I can use the |
Beta Was this translation helpful? Give feedback.
-
Hi! 👋
I think this may be less of a lift than you're imagining. If you changed |
Beta Was this translation helpful? Give feedback.
-
BTW, if you want a disgusting number of tests for GROQ: https://github.com/saiichihashimoto/sanity-typed/tree/main/packages/groq/src Those should be adaptable for Also, I made a package for the test-utils you copied over a while ago, so you can get any updates I get from it. |
Beta Was this translation helpful? Give feedback.
-
Hey hey, love what you are doing with this library and even more looking forward to tighter integration with schemas. Just curious about the current status of "groq-builder", I couldn't see any specific mention outside of this discussion. Is there a roadmap for a 1.0 release? Either way I'm going to have a play on some non-prod projects :D |
Beta Was this translation helpful? Give feedback.
-
Request For Comments
We are considering implementing a new Version 2 of GroqD, based on the PoC work done in #201, #202.
Goals
Currently, GroqD is unaware of the Sanity Scheam; it only validates the results.
It's up to the developer to know what fields can be queried, what their types are, and how to navigate nested structures.
The goal of this new version is to improve the developer workflow. We want GroqD to be aware of the Sanity Schema, so that it can provide developers with code completion, type-inferrance and type-checking for all queries.
As a side-effect, "client-side validation" becomes redundant, so we'd like to make it optional. This will reduce bundle size and improve performance.
Implementation
Schema Generation
The
@sanity-typed/types
package can be used to infer strong TypeScript types from a Sanity schema.However, for most scenarios, the Sanity schema will be defined in a separate project/repo than the client that is using GroqD. So, it will usually be necessary to compile the sanity schema into a
.d.ts
file, and then copy that into the client project.Unfortunately, the
@sanity-typed/types
package is VERY slow to infer the schema. Even if we used the TypeScript compiler to generate the.d.ts
file, it would still need to infer the types, which causes major compiler issues and IDE issues.In order for this solution to be realistic and achievable, we need to solve this problem first.
One possible solution is to create a CLI tool that can be used to generate the required "flattened" type definition from the Sanity schema. This would be very similar to
graphql-codegen
.Another solution would be to allow developers to manually specify the types, by hand-editing each document type. While this could be prone to errors, it would allow developers to strongly-type their schema, and could be a worthwhile tradeoff.
Query Builder
The majority of GroqD's API will be intact, but now with strong types. Eg.
q.order('_createdAt', 'desc')
orq.filterByType("product")
.A few of the important API changes:
.grab
function will be replaced by.projection
, which mostly shares the same API, but with some important improvements:true
, like.projection({ name: true })
. Result types are inferred from the source schema..grabOne("name")
will become.projection("name")
, since this can be overloaded.true
you can pass a "parser" function, like.projection({ name: (n) => n.toUpperCase() })
..projection({ name: (n) => n.split(' ') })
.projection({ name: zod.string() })
Additional Considerations
projection
instead ofgrab
filter$(string)
vsfilter(TypedExpression)
groq-builder
Beta Was this translation helpful? Give feedback.
All reactions