
Security News
CISA Rebuffs Funding Concerns as CVE Foundation Draws Criticism
CISA denies CVE funding issues amid backlash over a new CVE foundation formed by board members, raising concerns about transparency and program governance.
awesome-graphql-client
Advanced tools
GraphQL Client with file upload support for NodeJS and browser
npm install awesome-graphql-client
import { AwesomeGraphQLClient } from 'awesome-graphql-client'
const client = new AwesomeGraphQLClient({ endpoint: '/graphql' })
// Also query can be an output from graphql-tag (see examples below)
const GetUsers = `
query getUsers {
users {
id
}
}
`
const UploadUserAvatar = `
mutation uploadUserAvatar($userId: Int!, $file: Upload!) {
updateUser(id: $userId, input: { avatar: $file }) {
id
}
}
`
client
.request(GetUsers)
.then(data =>
client.request(UploadUserAvatar, {
id: data.users[0].id,
file: document.querySelector('input#avatar').files[0],
}),
)
.then(data => console.log(data.updateUser.id))
.catch(error => console.log(error))
const { openAsBlob } = require('node:fs')
const { AwesomeGraphQLClient } = require('awesome-graphql-client')
const client = new AwesomeGraphQLClient({
endpoint: 'http://localhost:8080/graphql',
})
// Also query can be an output from graphql-tag (see examples below)
const UploadUserAvatar = `
mutation uploadUserAvatar($userId: Int!, $file: Upload!) {
updateUser(id: $userId, input: { avatar: $file }) {
id
}
}
`
const blob = await openAsBlob('./avatar.png')
client
.request(UploadUserAvatar, { file: new File([blob], 'avatar.png'), userId: 10 })
.then(data => console.log(data.updateUser.id))
.catch(error => console.log(error))
const { createReadStream, statSync } = require('node:fs')
const path = require('node:path')
const { Readable } = require('node:stream')
const { AwesomeGraphQLClient } = require('awesome-graphql-client')
class StreamableFile extends Blob {
constructor(filePath) {
const { mtime, size } = statSync(filePath)
super([])
this.name = path.parse(filePath).base
this.lastModified = mtime.getTime()
this.#filePath = filePath
Object.defineProperty(this, 'size', {
value: size,
writable: false,
})
Object.defineProperty(this, Symbol.toStringTag, {
value: 'File',
writable: false,
})
}
stream() {
return Readable.toWeb(createReadStream(this.#filePath))
}
}
const client = new AwesomeGraphQLClient({
endpoint: 'http://localhost:8080/graphql',
})
// Also query can be an output from graphql-tag (see examples below)
const UploadUserAvatar = `
mutation uploadUserAvatar($userId: Int!, $file: Upload!) {
updateUser(id: $userId, input: { avatar: $file }) {
id
}
}
`
client
.request(UploadUserAvatar, { file: new StreamableFile('./avatar.png'), userId: 10 })
.then(data => console.log(data.updateUser.id))
.catch(error => console.log(error))
AwesomeGraphQLClient
Usage:
import { AwesomeGraphQLClient } from 'awesome-graphql-client'
const client = new AwesomeGraphQLClient(config)
config
propertiesendpoint
: string - The URL to your GraphQL endpoint (required)fetch
: Function - Fetch polyfillfetchOptions
: object - Overrides for fetch optionsFormData
: object - FormData polyfillformatQuery
: function(query: any): string - Custom query formatter (see example)onError
: function(error: GraphQLRequestError | Error): void - Provided callback will be called before throwing an error (see example)isFileUpload
: function(value: unknown): boolean - Custom predicate function for checking if value is a file (see example)client
methodsclient.setFetchOptions(fetchOptions: FetchOptions)
: Sets fetch options. See examples belowclient.getFetchOptions()
: Returns current fetch optionsclient.setEndpoint(): string
: Sets a new GraphQL endpointclient.getEndpoint(): string
: Returns current GraphQL endpointclient.request(query, variables?, fetchOptions?): Promise<data>
: Sends GraphQL Request and returns data or throws an errorclient.requestSafe(query, variables?, fetchOptions?): Promise<{ ok: true, data, response } | { ok: false, error, partialData }>
: Sends GraphQL Request and returns object with 'ok: true', 'data' and 'response' or with 'ok: false', 'error' and 'partialData' fields. See examples below. Notice: this function never throws.GraphQLRequestError
instance
fieldsmessage
: string - Error messagequery
: string - GraphQL queryvariables
: string | undefined - GraphQL variablesresponse
: Response - response returned from fetchfieldErrors
: GraphQLFieldError[] - GraphQL field errorsinterface getUser {
user: { id: number; login: string } | null
}
interface getUserVariables {
id: number
}
const query = `
query getUser($id: Int!) {
user {
id
login
}
}
`
const client = new AwesomeGraphQLClient({
endpoint: 'http://localhost:3000/graphql',
})
client
.request<getUser, getUserVariables>(query, { id: 10 })
.then(data => console.log(data))
.catch(error => console.log(error))
client.requestSafe<getUser, getUserVariables>(query, { id: 10 }).then(result => {
if (!result.ok) {
throw result.error
}
console.log(`Status ${result.response.status}`, `Data ${result.data.user}`)
})
You can generate types from queries by using GraphQL Code Generator with TypedDocumentNode plugin
# queries.graphql
query getUser($id: Int!) {
user {
id
login
}
}
// index.ts
import { TypedDocumentNode } from '@graphql-typed-document-node/core'
import { AwesomeGraphQLClient } from 'awesome-graphql-client'
import { print } from 'graphql/language/printer'
import { GetCharactersDocument } from './generated'
const gqlClient = new AwesomeGraphQLClient({
endpoint: 'https://rickandmortyapi.com/graphql',
formatQuery: (query: TypedDocumentNode) => print(query),
})
// AwesomeGraphQLClient will infer all types from the passed query automagically:
gqlClient
.request(GetCharactersDocument, { name: 'Rick' })
.then(data => console.log(data))
.catch(error => console.log(error))
Check out full example at examples/typed-document-node
import { AwesomeGraphQLClient, GraphQLRequestError } from 'awesome-graphql-client'
const client = new AwesomeGraphQLClient({
endpoint: '/graphql',
onError(error) {
if (error instanceof GraphQLRequestError) {
console.error(error.message)
console.groupCollapsed('Operation:')
console.log({ query: error.query, variables: error.variables })
console.groupEnd()
} else {
console.error(error)
}
},
})
Internally it uses URLSearchParams API. Consider polyfilling URL standard for this feature to work in IE
client
.request(query, variables, { method: 'GET' })
.then(data => console.log(data))
.catch(err => console.log(err))
formatQuery
import { AwesomeGraphQLClient } from 'awesome-graphql-client'
import { DocumentNode } from 'graphql/language/ast'
import { print } from 'graphql/language/printer'
import gql from 'graphql-tag'
const client = new AwesomeGraphQLClient({
endpoint: '/graphql',
formatQuery: (query: DocumentNode | string) =>
typeof query === 'string' ? query : print(query),
})
const query = gql`
query me {
me {
login
}
}
`
client
.request(query)
.then(data => console.log(data))
.catch(err => console.log(err))
graphql-tag
Recommended approach if you're using graphql-tag
only for syntax highlighting and static analysis such as linting and types generation. It has less computational cost and makes overall smaller bundles. GraphQL fragments are supported too.
import { AwesomeGraphQLClient, gql } from 'awesome-graphql-client'
const client = new AwesomeGraphQLClient({ endpoint: '/graphql' })
const query = gql`
query me {
me {
login
}
}
`
client
.request(query)
.then(data => console.log(data))
.catch(err => console.log(err))
Perfect for Typescript projects. See example above
const { AwesomeGraphQLClient } = require('awesome-graphql-client')
const fetchCookie = require('fetch-cookie')
const client = new AwesomeGraphQLClient({
endpoint: 'http://localhost:8080/graphql',
fetch: fetchCookie(globalThis.fetch),
})
const { AwesomeGraphQLClient, isFileUpload } = require('awesome-graphql-client')
const client = new AwesomeGraphQLClient({
endpoint: 'http://localhost:8080/graphql',
// By default File, Blob, Buffer, Promise and stream-like instances are considered as files.
// You can expand this behaviour by adding a custom predicate
isFileUpload: value => isFileUpload(value) || value instanceof MyCustomFile,
})
https://github.com/lynxtaa/awesome-graphql-client/tree/master/examples
FAQs
GraphQL Client with file upload support for NodeJS and browser
The npm package awesome-graphql-client receives a total of 6,703 weekly downloads. As such, awesome-graphql-client popularity was classified as popular.
We found that awesome-graphql-client demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISA denies CVE funding issues amid backlash over a new CVE foundation formed by board members, raising concerns about transparency and program governance.
Product
We’re excited to announce a powerful new capability in Socket: historical data and enhanced analytics.
Product
Module Reachability filters out unreachable CVEs so you can focus on vulnerabilities that actually matter to your application.