Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support pre-parsed queries (eg. graphql-tag) #1108

Merged
merged 1 commit into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
}
})
})
Loading