Skip to content

Commit

Permalink
feat: support pre-parsed queries (eg. graphql-tag) (#1108)
Browse files Browse the repository at this point in the history
  • Loading branch information
voxpelli authored Sep 6, 2024
1 parent 98ed90e commit b6ec1a1
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 10 deletions.
4 changes: 2 additions & 2 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ declare namespace mercurius {
TData extends Record<string, any> = Record<string, any>,
TVariables extends Record<string, any> = Record<string, any>
>(
source: string,
source: string | DocumentNode,
context?: Record<string, any>,
variables?: TVariables,
operationName?: string
Expand Down Expand Up @@ -737,7 +737,7 @@ declare module 'fastify' {
TData extends Record<string, any> = Record<string, any>,
TVariables extends Record<string, any> = Record<string, any>
>(
source: string,
source: string | DocumentNode,
context?: Record<string, any>,
variables?: TVariables,
operationName?: string
Expand Down
19 changes: 11 additions & 8 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict'

const fp = require('fastify-plugin')
const LRU = require('tiny-lru').lru
const routes = require('./lib/routes')
const { compileQuery, isCompiledQuery } = require('graphql-jit')
const { Factory } = require('single-user-cache')
Expand Down Expand Up @@ -46,7 +45,7 @@ const {
onExtendSchemaHandler
} = require('./lib/handlers')

function buildCache (opts) {
async function buildCache (opts) {
if (Object.prototype.hasOwnProperty.call(opts, 'cache')) {
const isBoolean = typeof opts.cache === 'boolean'
const isNumber = typeof opts.cache === 'number'
Expand All @@ -55,20 +54,22 @@ function buildCache (opts) {
// no cache
return null
} else if (isNumber) {
const QuickLRU = (await import('quick-lru')).default
// cache size as specified
return LRU(opts.cache)
return new QuickLRU({ maxSize: opts.cache })
} else if (!isBoolean && !isNumber) {
throw new MER_ERR_INVALID_OPTS('Cache type is not supported')
}
}

const QuickLRU = (await import('quick-lru')).default
// default cache, 1024 entries
return LRU(1024)
return new QuickLRU({ maxSize: 1024 })
}

const mercurius = fp(async function (app, opts) {
const lru = buildCache(opts)
const lruErrors = buildCache(opts)
const lru = await buildCache(opts)
const lruErrors = await buildCache(opts)

if (lru && opts.validationRules && typeof opts.validationRules === 'function') {
throw new MER_ERR_INVALID_OPTS('Using a function for the validationRules is incompatible with query caching')
Expand Down Expand Up @@ -413,7 +414,7 @@ const mercurius = fp(async function (app, opts) {
const reply = context.reply

// Trigger preParsing hook
if (context.preParsing !== null) {
if (context.preParsing !== null && typeof source === 'string') {
await preParsingHandler({ schema: fastifyGraphQl.schema, source, context })
}

Expand All @@ -433,7 +434,9 @@ const mercurius = fp(async function (app, opts) {
}

try {
document = parse(source, gqlParseOpts)
document = typeof source === 'string'
? parse(source, gqlParseOpts)
: structuredClone(source)
} catch (syntaxError) {
try {
// Do not try to JSON.parse maxToken exceeded validation errors
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"eslint": "^9.9.1",
"fastify": "^4.17.0",
"graphql": "^16.0.0",
"graphql-tag": "^2.12.6",
"graphql-ws": "^5.11.2",
"neostandard": "^0.11.4",
"pre-commit": "^1.2.2",
Expand All @@ -61,6 +62,7 @@
"graphql-jit": "0.8.4",
"mqemitter": "^5.0.0",
"p-map": "^4.0.0",
"quick-lru": "^7.0.0",
"readable-stream": "^4.0.0",
"safe-stable-stringify": "^2.3.0",
"secure-json-parse": "^2.7.0",
Expand Down
31 changes: 31 additions & 0 deletions test/app-decorator.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const { test } = require('tap')
const Fastify = require('fastify')
const GQL = require('..')
const { GraphQLError } = require('graphql')
const gql = require('graphql-tag')

const {
GraphQLScalarType,
Expand Down Expand Up @@ -1439,3 +1440,33 @@ test('defineResolvers should support __resolveReference', async (t) => {
// needed so that graphql is defined
await app.ready()
})

test('graphql-tag', async (t) => {
const app = Fastify()
const schema = `
type Query {
add(x: Int, y: Int): Int
}
`

const resolvers = {
add: async ({ x, y }) => x + y
}

app.register(GQL, {
schema,
resolvers
})

// needed so that graphql is defined
await app.ready()

const query = gql`{ add(x: 2, y: 2) }`
const res = await app.graphql(query)

t.same(res, {
data: {
add: 4
}
})
})

0 comments on commit b6ec1a1

Please sign in to comment.