npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@sanity-typed/groq

v1.8.12

Published

Infer GROQ Result Types from GROQ strings

Downloads

4,312

Readme

@sanity-typed/groq

NPM Downloads GitHub commit activity (branch) GitHub Repo stars GitHub contributors GitHub issues by-label Minified Size License

GitHub Sponsors

Infer GROQ Result Types from GROQ strings

Page Contents

Install

npm install @sanity-typed/groq

Usage

Typically, this isn't used directly, but via @sanity-typed/client's and @sanity-typed/groq-js's methods that use groq strings. But it can be done directly:

import { ExecuteQuery, RootScope } from "@sanity-typed/groq";

type Foo = ExecuteQuery<
  '*[_type=="foo"]',
  RootScope<
    // If you have SanityValues from @sanity-typed/types, use those types:
    // import { DocumentValues } from "@sanity-typed/types";
    // DocumentValues<SanityValues>
    ({ _type: "bar" } | { _type: "foo" })[],
    { _type: "bar" } | { _type: "foo" }
  >
>;
/**
 *  Foo === {
 *    _type: "foo";
 *  }[]
 */

There is also a Parse and Evaluate if you need the AST:

import { Evaluate, Parse, RootScope } from "@sanity-typed/groq";

type Tree = Parse<'*[_type=="foo"]'>;
/**
 *  Tree === {
 *    type: "Filter";
 *    base: { type: "Everything" };
 *    expr: {
 *      type: "OpCall";
 *      op: "==";
 *      left: { type: "AccessAttribute"; name: "_type" };
 *      right: { type: "Value"; value: "foo" };
 *    };
 *  }
 */

type Foo = Evaluate<
  Tree,
  RootScope<
    // If you have SanityValues from @sanity-typed/types, use those types:
    // import { DocumentValues } from "@sanity-typed/types";
    // DocumentValues<SanityValues>
    ({ _type: "bar" } | { _type: "foo" })[],
    { _type: "bar" } | { _type: "foo" }
  >
>;
/**
 *  Foo === {
 *    _type: "foo";
 *  }[]
 */

For either, you can pass in a full scope:

import { ExecuteQuery } from "@sanity-typed/groq";

type Foo = ExecuteQuery<
  '*[_type=="foo"]',
  {
    context: {
      client: ClientConfig;
      dataset: ({ _type: "bar" } | { _type: "foo" })[];
      delta:
        | {
            after: { _type: "bar" } | null;
            before: { _type: "bar" } | null;
          }
        | {
            after: { _type: "foo" } | null;
            before: { _type: "foo" } | null;
          };
      identity: string;
      parameters: { [param: string]: any };
    };
    parent: null;
    this: null;
  }
>;

Chances are, you don't need this package directly.

Considerations

The parsed tree changes in seemingly breaking ways

@sanity-typed/groq attempts to type its parsed types as close as possible to groq-js's parse function output. Any fixes to match it more correctly won't be considered a major change and, if groq-js changes it's output in a version update, we're likely to match it. If you're using the parsed tree's types directly, this might cause your code to break. We don't consider this a breaking change because the intent of these groq libraries is to match the types of a groq query as closely as possible.

Typescript Errors in IDEs

Often you'll run into an issue where you get typescript errors in your IDE but, when building workspace (either you studio or app using types), there are no errors. This only occurs because your IDE is using a different version of typescript than the one in your workspace. A few debugging steps:

VSCode

Type instantiation is excessively deep and possibly infinite

🚨 CHECK Typescript Errors in IDEs FIRST!!! ISSUES WILL GET CLOSED IMMEDIATELY!!! 🚨

You might run into the dreaded Type instantiation is excessively deep and possibly infinite error when writing GROQ queries. This isn't too uncommon with more complex GROQ queries. Unfortunately, this isn't a completely avoidable problem, as typescript has limits on complexity and parsing types from a string is an inherently complex problem. A set of steps for a workaround:

  1. While not ideal, use @ts-expect-error to disable the error. You could use @ts-ignore instead, but ideally you'd like to remove the comment if a fix is released.
  2. You still likely want manual types. Intersect the returned type with whatever is missing as a patch.
  3. Create a PR in groq/src/specific-issues.test.ts with your issue. #642 is a great example for this. Try to reduce your query and config as much as possible. The goal is a minimal reproduction.
  4. If a PR isn't possible, make an issue with the same content. ie, the query and config you're using. Again, reduce them as much as possible. And then, now that you've done all the work, move it into a PR instead!
  5. I'm one person and some of these issues are quite complex. Take a stab at fixing the bug! There's a ridiculous amount of tests so it's relatively safe to try things out.

People will sometimes create a repo with their issue. Please open a PR with a minimal test instead. Without a PR there will be no tests reflecting your issue and it may appear again in a regression. Forking a github repo to make a PR is a more welcome way to contribute to an open source library.

Alternatives