Security News
Research
Supply Chain Attack on Rspack npm Packages Injects Cryptojacking Malware
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
graphql-helper
Advanced tools
A simple helper library for making GraphQL queries. For browser usage, ensure that you have a Promise polyfill.
A GraphQL helper library intended for use on both the browser and server, using ES6 tagged template strings. This library is meant for statically determined queries, and encourages the use of variables over string generation.
isomorphic-fetch
, but does not come with a Promise polyfill.npm install --save graphql-helper
import * as GraphQL from 'graphql-helper'
GraphQL.configure(
{ host: "http://localhost:3000/graphql" // path to the GraphQL endpoint
, headers: { Authorization: "my-token" } // optional: additional headers in the request
, clientMutationId: () => `ID:${Math.random()}` // optional: function for generating unique IDS
}
)
GraphQL.query a b :: (name :: String, schema :: Schema a) -> QueryString b -> (a -> Promise b)
const MyQuery = GraphQL.query('MyQuery', { siteKey: "String!" }) `{
site(key: $siteKey) {
id
name
}
}`
// usage
MyQuery({ siteKey: "bustle" })
.then(console.log.bind(console))
// => { site: { id: 100, name: "bustle" } }
Translates to the following query:
query MyQuery($siteKey: String!) {
site(key: $siteKey) {
id
name
}
}
Evaluated with the variables:
{
"siteKey": "bustle"
}
If no schema is provided, a query of no arguments is created (returning a thunk).
GraphQL.mutation a b :: (name :: String, schema :: Schema a) -> QueryString b -> (a -> Promise b)
Using mutations requires that your schema be set up as so:
input MyMutationInput {
clientMutationid: String!
# ... any other fields here
}
type MyMutationOutput {
clientMutationId: String!
# ... any other fields here
}
type RootMutationType {
myMutation(input: MyMutationInput!): MyMutationOutput!
}
Allowing you to define a mutation:
const CreateImageCard = GraphQL.mutation('createImageCard', { key: 'String!', lint: 'Boolean' }) `{
image {
key
width
height
}
}`
// usage
CreateImageCard({ key: '2016/07/02/my-file.jpg', lint: false })
.then(console.log.bind(console))
// => { image: { key: '2016/07/02/my-file.jpg', width: 500, height: 300 } }
Which is translated to:
mutation CreateImageCard($input: CreateImageCardInput!) {
createImageCard(input: $input) {
clientMutationId
... on CreateImageCardPayload {
image {
key
width
height
}
}
}
}
Evaluated with the variables:
{
"input": {
"clientMutationId": "SOME_GENERATED_ID",
"key": "2016/07/02/my-file.jpg",
"lint": false
}
}
GraphQL.fragment a :: ( name :: String, type :: String? ) -> QueryString a -> Fragment a
const SitePath = GraphQL.fragment('PathOfSite', 'Path') `{
id
name
slug
}`
const Site = GraphQL.fragment('Site') `{
id
name
paths {
${SitePath}
}
}`
// usage
const MyComplexQuery = GraphQL.query('MyComplexQuery') `{
site(key: "bustle") {
${Site}
}
path(id: 2271) {
${SitePath}
}
}`
MyComplexQuery()
.then(console.log.bind(console))
// => { site: { id: ... }, path: { id: ... } }
Translates to the query:
query MyComplexQuery {
site(key: "bustle") {
...Site
}
path(id: 2271) {
...SitePath
}
}
fragment Site on Site {
id
name
paths {
...SitePath
}
}
fragment PathOfSite on Path {
id
name
slug
}
If no type
argument is given, it will default to being the same as name
Template strings aren't so great at dealing with arrays, so a utility function is exposed to expand unions of fragments:
const ClipArticle = GraphQL.fragment(`ClipArticle`) `{
id
article {
title
}
}`
const ClipPost = GraphQL.fragment('ClipPost') `{
id
post {
title
}
}`
const Clip = GraphQL.union(ClipArticle, ClipPost)
// usage
const unionQuery = GraphQL.query('MyUnionQuery') `{
clips(ids: [ 630, 656, 659 ]) {
${Clip}
}
}`
This method is variadic, i.e. it is of the form GraphQL.union(fragment1, fragment2, fragment3, ...)
The GraphQL.partial
method is highly discouraged in favour of real fragments, however can be useful
in certain cases such as Relay connections where a common pattern is used but there's no clear type or interface:
const paginationPartial = GraphQL.partial `
edges {
cursor
node {
${Card.fragment}
}
}
pageInfo {
hasNextPage
}
`
const query = GraphQL.query('MyQuery') `{
topicConnection {
${paginationPartial}
}
}`
Note that for all of the above methods,
these template strings offer special support for GraphQL.fragment
and GraphQL.union
instances,
but in the end are still plain old strings. Therefore, any piece of GraphQL syntax is valid in the string.
// e.g. the valid will work exactly as you'd expect:
const myFragment = GraphQL.fragment('SomeComplexType') `{
__typename
... on SomeType {
foo
bar
baz {
id
... on SomeNestedType {
foo
}
}
}
... on SomeOtherOption {
${SomeFragment}
}
}`
FAQs
A simple helper library for constructing GraphQL queries.
The npm package graphql-helper receives a total of 38 weekly downloads. As such, graphql-helper popularity was classified as not popular.
We found that graphql-helper demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers 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
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.
Security News
Sonar’s acquisition of Tidelift highlights a growing industry shift toward sustainable open source funding, addressing maintainer burnout and critical software dependencies.