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

gqlr

v2.0.1

Published

WIP: (g)raph(ql)-(r)equest. A simplified fork of graphql-request

Downloads

90

Readme

gqlr

tests

Minimaler Fork of the Minimal GraphQL client graphql-request.

Features

  • Even simpler than graphql-request! Needlessly duplicated code removed.
  • Same Promise-based API (works with async / await).
  • No Typescript.
  • Actually Isomorphic (works with Node / browsers). Ships a real ESM module, instead of the fake one TS generates.

Why?

graphql-request was causing problems downstream due to the fake ESM module it ships, making it incompatible with both browser esm and node.js esm. Additionally, many people are using graphql-request already, so making some simple breaking changes would cause a headache for everyone involved.

Install

npm add gqlr

Quickstart

Send a GraphQL query with a single line of code. ▶️ Try it out.

import { request } from 'gqlr'

const query = `{
  Movie(title: "Inception") {
    releaseDate
    actors {
      name
    }
  }
}`

request('https://api.graph.cool/simple/v1/movies', query).then((data) => console.log(data))

or directly in the browser with native ESM:

import { request } from 'https://unpkg.com/gqlr@^1?module'

const query = `{
  Movie(title: "Inception") {
    releaseDate
    actors {
      name
    }
  }
}`

request('https://api.graph.cool/simple/v1/movies', query).then((data) => console.log(data))

Usage

import { request, GraphQLClient } from 'gqlr' // Works with real Node.js ESM

// Run GraphQL queries/mutations using a static function
request(endpoint, query, variables).then((data) => console.log(data))

// ... or create a GraphQL client instance to send requests
const client = new GraphQLClient(endpoint, { headers: {} })
client.request(query, variables).then((data) => console.log(data))

API

import { GraphQLClient, request, rawRequest } from 'gqlr'

Import the GraphQLClient class, request and rawRequest from gqlr.

client = new GraphQLClient(url, [opts])

Create a new client instance of GraphQLClient for a given url with the following default opts passed the node-fetch internally:

{
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
}

Any opts.headers are mixed in with the default headers, and any other properties on opts are passed as fetch options.

{ headers, status, ...result } = await client.rawRequest(query, [variables])

Make a query request with a client including the optional variables object, returning extra response properties like extensions.

data = await client.request(query, [variables])

Make a query request with a client including the optional variables object, returning just the data field.

data = await client.stringRequest(body)

Make a request with a body string to the configured GQL endpoint. The body should be in the form of:

const body = JSON.stringify({
  query: '{ viewer { id } }',
  variables: {}
})

Useful with tools like SWR, where you usually stringify a query and variables object into a cache key that gets passed to your fetcher function. With stringRequest, you can avoid double JSON.stringify problems, or complex variable scope passing.

client = client.setHeaders(headers)

Pass a headers object to a client to customize the headers.

client = client.setHeader(key, value)

Set a specific header by a key and a value.

{ headers, status, ...result } = rawRequest(url, query, [variables], [opts])

Convenience function to instantiate a client and make a request in a single function call, returning the extended properties of the graphql request.

data = request(url, query, [variables], [opts])

Convenience function to instantiate a client and make a request in a single function call.

data = stringRequest(url, body, [opts])

Convenience function to instantiate a client and make a stringRequest in a single function call.

Examples

Authentication via HTTP header

import { GraphQLClient } from 'gqlr'

async function main() {
  const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'

  const graphQLClient = new GraphQLClient(endpoint, {
    headers: {
      authorization: 'Bearer MY_TOKEN',
    },
  })

  const query = /* GraphQL */ `
    {
      Movie(title: "Inception") {
        releaseDate
        actors {
          name
        }
      }
    }
  `

  const data = await graphQLClient.request(query)
  console.log(JSON.stringify(data, undefined, 2))
}

main().catch((error) => console.error(error))

Example File

Passing more options to fetch

import { GraphQLClient } from 'gqlr'

async function main() {
  const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'

  const graphQLClient = new GraphQLClient(endpoint, {
    credentials: 'include',
    mode: 'cors',
  })

  const query = /* GraphQL */ `
    {
      Movie(title: "Inception") {
        releaseDate
        actors {
          name
        }
      }
    }
  `

  const data = await graphQLClient.request(query)
  console.log(JSON.stringify(data, undefined, 2))
}

main().catch((error) => console.error(error))

Example

Using variables

import { request } from 'gqlr'

async function main() {
  const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'

  const query = /* GraphQL */ `
    query getMovie($title: String!) {
      Movie(title: $title) {
        releaseDate
        actors {
          name
        }
      }
    }
  `

  const variables = {
    title: 'Inception',
  }

  const data = await request(endpoint, query, variables)
  console.log(JSON.stringify(data, undefined, 2))
}

main().catch((error) => console.error(error))

Example

Error handling

import { request } from 'gqlr'

async function main() {
  const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'

  const query = /* GraphQL */ `
    {
      Movie(title: "Inception") {
        releaseDate
        actors {
          fullname # "Cannot query field 'fullname' on type 'Actor'. Did you mean 'name'?"
        }
      }
    }
  `

  try {
    const data = await request(endpoint, query)
    console.log(JSON.stringify(data, undefined, 2))
  } catch (error) {
    console.error(JSON.stringify(error, undefined, 2))
    process.exit(1)
  }
}

main().catch((error) => console.error(error))

Example

Using require instead of import

const { request } = require('gqlr')

async function main() {
  const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'

  const query = /* GraphQL */ `
    {
      Movie(title: "Inception") {
        releaseDate
        actors {
          name
        }
      }
    }
  `

  const data = await request(endpoint, query)
  console.log(JSON.stringify(data, undefined, 2))
}

main().catch((error) => console.error(error))

Cookie support for node

npm install fetch-cookie
// This probably only works in CJS environments.
require('fetch-cookie/node-fetch')(require('node-fetch'))

require { GraphQLClient } = require('gqlr')

async function main() {
  const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'

  const graphQLClient = new GraphQLClient(endpoint, {
    headers: {
      authorization: 'Bearer MY_TOKEN',
    },
  })

  const query = /* GraphQL */ `
    {
      Movie(title: "Inception") {
        releaseDate
        actors {
          name
        }
      }
    }
  `

  const data = await graphQLClient.rawRequest(query)
  console.log(JSON.stringify(data, undefined, 2))
}

main().catch((error) => console.error(error))

Example

Receiving a raw response

The request method will return the data or errors key from the response. If you need to access the extensions key you can use the rawRequest method:

import { rawRequest } from 'gqlr'

async function main() {
  const endpoint = 'https://api.graph.cool/simple/v1/cixos23120m0n0173veiiwrjr'

  const query = /* GraphQL */ `
    {
      Movie(title: "Inception") {
        releaseDate
        actors {
          name
        }
      }
    }
  `

  const { data, errors, extensions, headers, status } = await rawRequest(endpoint, query)
  console.log(JSON.stringify({ data, errors, extensions, headers, status }, undefined, 2))
}

main().catch((error) => console.error(error))

Example

FAQ

What's the difference between gqlr and graphql-request?

gqlr is a minimal, mostly drop-in replacement of graphql-request aimed at:

  • shipping artifacts with working esm exports.
  • work in the browser without a bundler (even more minimal)
  • work with Node.js "type": "module".
  • further reducing library size (remove unnecessarily duplicated code)
  • removing the project overhead of Typescript syntax, Typescript tooling, and Typescript bugs.
  • Clarify undocumented methods and edge-cases.

Breaking changes include:

  • No fake 'default' export. If you use this, switch to importing named exports.
  • Imports node-fetch. This might break react native, not sure.

This is too simple, to use the power of graphql you must use...

  • This module pairs really well with swr and other similar ideas. If you need caching, react hooks and any other party tricks, just use that. Orthogonal concerns ftw.