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

@mygql/graphql

v1.0.1

Published

Generate GraphQL query from JavaScript object.

Downloads

15

Readme

Warning

This module is no longer maintained. Please use generate-graphql-query instead.

README

npm version coverage

npm i @mygql/graphql

Generate GraphQL query from JavaScript object.

This module supports aliases, arguments, directives, enumerations, fragments and variables.

You can use the @mygql/codegen module to generate TypeScript code from your GraphQL introspection and use this module to generate the GraphQL query that to be sent to the server.

To get started with MyGQL, you can click here to read the documentation. To try MyGQL online, you can click here to visit our online playground.

Table of contents:

Usage

Basic usage

import generateGraphQL from '@mygql/graphql'

const query = generateGraphQL({
  query: {
    /**
     * Optional operation name.
     */
    $name: 'CountriesQuery',

    // Querying `countries`.
    countries: {
      // Specify arguments for `countries`.
      $args: {
        filter: {
          continent: {
            in: ['AF']
          }
        }
      },

      // Selecting the fields we want to fetch.
      code: true,

      // We can also use numbers, for they are shorter than booleans.
      // Zero will be treated as `false`. Any other value will be
      // treated as `true`.
      name: 1,

      // Selecting nested object.
      continent: {
        code: 1,

        // If the value is string, the string will be used as alias.
        name: 'continent_name'
      }
    }
  }
})

console.log(query)

The output is:

query CountriesQuery {
  countries (
    filter: {
      continent: {
        in: ["AF"]
      }
    }
  ) {
    code
    name
    continent {
      code
      continent_name: name
    }
  }
}

Using alias

import generateGraphQL from '@mygql/graphql'

const query = generateGraphQL({
  query: {
    // Example of defining alias for the field.
    country: {
      $alias: 'country_fr',
      $args: { code: 'FR' },

      // We can use string to set alias.
      code: 'country_code',
      // We can also use object to set alias.
      name: { $alias: 'country_name' }
    },

    // Example of defining two aliases for the same field.
    countries: [
      {
        $alias: 'af_countries',
        $args: { filter: { continent: { eq: 'AF' } } },
        code: true,
        name: true
      },
      {
        $alias: 'as_countries',
        $args: { filter: { continent: { eq: 'AS' } } },
        code: true,
        name: true
      }
    ]
  }
})

console.log(query)

The output is:

query {
  country_fr: country (
    code: "FR"
  ) {
    country_code: code
    country_name: name
  }
  af_countries: countries (
    filter: {
      continent: {
        eq: "AF"
      }
    }
  ) {
    code
    name
  }
  as_countries: countries (
    filter: {
      continent: {
        eq: "AS"
      }
    }
  ) {
    code
    name
  }
}

Arguments

import generateGraphQL from '@mygql/graphql'

const query = generateGraphQL({
  query: {
    users: {
      $args: {
        // Values will be encoded to corresponding types in GraphQL.
        nameContains: 'a',
        verified: true,
        deletedAt: null,
        status: 1,

        // Argument can be nested object.
        hasFriendsWith: {
          nameContains: 'b',
          deletedAt: null
        },

        orderBy: {
          field: 'created_at',

          // If the value is an object with a key named `$enum`, the value
          // will be processed as enumeration. In our example, the value
          // `DESC` will not be double-quoted in the result for it is a
          // enumeration value.
          direction: { $enum: 'DESC' }
        },

        // If the value is `undefined` or if the argument is empty,
        // the argument will be skipped.
        role: undefined,
        hasRoleWith: {}
      },

      id: true,
      name: true
    }
  }
})

console.log(query)

The output is:

query {
  users (
    nameContains: "a"
    verified: true
    deletedAt: null
    status: 1
    hasFriendsWith: {
      nameContains: "b"
      deletedAt: null
    }
    orderBy: {
      field: "created_at"
      direction: DESC
    }
  ) {
    id
    name
  }
}

Arguments for sub-fields

import generateGraphQL from '@mygql/graphql'

const query = generateGraphQL({
  query: {
    country: {
      $args: { code: 'CN' },

      // Set arguments for the field.
      name: {
        $args: { lang: 'zh' }
      }
    }
  }
})

console.log(query)

The output is:

query {
  country (
    code: "CN"
  ) {
    name (
      lang: "zh"
    )
  }
}

Passing empty objects in the arguments with $raw or $keep

As you can see in the previous example of arguments, the value with an empty object in the arguments will be skipped. But sometimes we need to pass empty object to the server, for example clearing all fields in a JSON field. To achieve that, we can use $raw or $keep to pass empty objects.

import generateGraphQL from '@mygql/graphql'

const query = generateGraphQL({
  mutation: {
    someAction: {
      $args: {
        // The following two objects will be skipped, for they are empty.
        skippedEmptyObject1: {},
        skippedEmptyObject2: { undefinedField: undefined },

        // To keep empty object, we can use the `$keep` flag.
        emptyObject1: { $keep: true },
        emptyObject2: { $keep: true, undefinedField: undefined },

        // We can also use `$raw` to pass objects.
        emptyObject3: { $raw: '{}' },

        // Actually, we can pass any type of value with `$raw`.
        numberWithRaw: { $raw: 1 },
        boolWithRaw: { $raw: true }
      }
    }
  }
})

console.log(query)

The output is:

mutation {
  someAction (
    emptyObject1: {}
    emptyObject2: {}
    emptyObject3: {}
    numberWithRaw: 1
    boolWithRaw: true
  )
}

Enumerations

import generateGraphQL from '@mygql/graphql'

const query = generateGraphQL({
  query: {
    users: {
      $args: {
        // Enum is an object with a key named `$enum`.
        // The enum value will not be double-quoted.
        statusIn: [{ $enum: 'VERIFIED' }],

        orderBy: {
          field: 'created_at',
          direction: { $enum: 'DESC' }
        }
      },

      id: 1,
      name: 1
    }
  }
})

console.log(query)

The output is:

query {
  users (
    statusIn: [VERIFIED]
    orderBy: {
      field: "created_at"
      direction: DESC
    }
  ) {
    id
    name
  }
}

Variables

import generateGraphQL from '@mygql/graphql'

const query = generateGraphQL({
  query: {
    $variables: {
      // Declare a variable named `$codes`.
      $codes: `[String!]! = []`
    },

    countries: {
      // Use the variable named `$codes`.
      $args: {
        filter: {
          code: {
            // Variable is an object with a key named `$var`.
            in: { $var: '$codes' }
          }
        }
      },

      code: true,
      name: true
    }
  }
})

console.log(query)

The output is:

query (
  $codes: [String!]! = []
) {
  countries (
    filter: {
      code: {
        in: $codes
      }
    }
  ) {
    code
    name
  }
}

Directives

import generateGraphQL from '@mygql/graphql'

const query = generateGraphQL({
  query: {
    directivesExample: {
      // Use string to set directive.
      field1: {
        $directives: '@skip(if: false)'
      },

      // Use object to set directive.
      field2: {
        $directives: {
          name: '@include',
          args: { if: true }
        }
      },

      // Use array to set multiple directives.
      field3: {
        $directives: [
          '@skip(if: false)',
          {
            name: '@my_directive',
            args: { arg: 'value' }
          }
        ]
      }
    }
  }
})

console.log(query)

The output is:

query {
  directivesExample {
    field1 @skip(if: false)
    field2 @include (
      if: true
    )
    field3 @skip(if: false) @my_directive (
      arg: "value"
    )
  }
}

Fragments

import generateGraphQL from '@mygql/graphql'

const query = generateGraphQL({
  fragments: {
    // Declare a fragment named `countryFields` on the type `Country`.
    countryFields: {
      $on: 'Country',
      code: true,
      name: true
    }
  },
  query: {
    countries: {
      // Use the fragment named `countryFields`.
      $fragments: [{ spread: 'countryFields' }]
    }
  }
})

console.log(query)

The output is:

query {
  countries {
    ...countryFields
  }
}

fragment countryFields on Country {
  code
  name
}

Inline fragments

import generateGraphQL from '@mygql/graphql'

const query = generateGraphQL({
  query: {
    countries: {
      $fragments: [
        // Inline fragment on the type `Country`.
        {
          inline: {
            $on: 'Country',
            // Set directives for the fragment.
            $directives: {
              name: '@skip',
              args: { if: false }
            },
            name: true
          }
        },
        // The type can be omitted.
        {
          inline: {
            code: true
          }
        }
      ]
    }
  }
})

console.log(query)

The output is:

query {
  countries {
    ... on Country @skip (
      if: false
    ) {
      name
    }
    ... {
      code
    }
  }
}

Mutations

import generateGraphQL from '@mygql/graphql'

const query = generateGraphQL({
  mutation: {
    updateUser: {
      $args: {
        id: '1000',
        name: 'joe'
      },

      name: true
    }
  }
})

console.log(query)

The output is:

mutation {
  updateUser (
    id: "1000"
    name: "joe"
  ) {
    name
  }
}

Multiple fields in mutations

Because mutation fields run in series, one after the other. So the order of the fields in a mutation is very important to avoid race condition. To make sure the field order is correct, we should use the $fields array to ensure the order. Below is an example:

import generateGraphQL from '@mygql/graphql'

const query = generateGraphQL({
  mutation: {
    // Use `$fields` array to make sure the order of multiple fields
    // is correct. In this example, the mutation `operationB` is
    // guaranteed to finish before the mutation `operationA` begins.
    $fields: [
      {
        operationB: {
          $args: { id: '1000' },
          status: true
        }
      },
      {
        operationA: {
          $args: { id: '1000' },
          status: true
        }
      }
    ]
  }
})

console.log(query)

The output is:

mutation {
  operationB (
    id: "1000"
  ) {
    status
  }
  operationA (
    id: "1000"
  ) {
    status
  }
}