mercurius
Advanced tools
Comparing version 12.1.0 to 12.2.0
@@ -328,3 +328,4 @@ 'use strict' | ||
keepAlive, | ||
fullWsTransport | ||
fullWsTransport, | ||
errorFormatter | ||
}) | ||
@@ -331,0 +332,0 @@ } else { |
@@ -22,3 +22,4 @@ 'use strict' | ||
keepAlive, | ||
fullWsTransport | ||
fullWsTransport, | ||
errorFormatter | ||
}) { | ||
@@ -38,2 +39,3 @@ this.fastify = fastify | ||
this.fullWsTransport = fullWsTransport | ||
this.errorFormatter = errorFormatter | ||
this.headers = {} | ||
@@ -313,3 +315,6 @@ | ||
} | ||
this.sendMessage(this.protocolMessageTypes.GQL_DATA, id, value) | ||
const hasErrors = Array.isArray(value.errors) && value.errors.length > 0 | ||
const response = hasErrors ? this.errorFormatter(value, this.context).response : value | ||
this.sendMessage(this.protocolMessageTypes.GQL_DATA, id, response) | ||
} | ||
@@ -316,0 +321,0 @@ |
@@ -9,3 +9,3 @@ 'use strict' | ||
function createConnectionHandler ({ subscriber, fastify, onConnect, onDisconnect, entityResolversFactory, subscriptionContextFn, keepAlive, fullWsTransport }) { | ||
function createConnectionHandler ({ subscriber, fastify, onConnect, onDisconnect, entityResolversFactory, subscriptionContextFn, keepAlive, fullWsTransport, errorFormatter }) { | ||
return async (connection, request) => { | ||
@@ -51,3 +51,4 @@ const { socket } = connection | ||
keepAlive, | ||
fullWsTransport | ||
fullWsTransport, | ||
errorFormatter | ||
}) | ||
@@ -66,3 +67,3 @@ | ||
module.exports = async function (fastify, opts) { | ||
const { getOptions, subscriber, verifyClient, onConnect, onDisconnect, entityResolversFactory, subscriptionContextFn, keepAlive, fullWsTransport } = opts | ||
const { getOptions, subscriber, verifyClient, onConnect, onDisconnect, entityResolversFactory, subscriptionContextFn, keepAlive, fullWsTransport, errorFormatter } = opts | ||
@@ -90,5 +91,6 @@ // If `fastify.websocketServer` exists, it means `@fastify/websocket` already registered. | ||
keepAlive, | ||
fullWsTransport | ||
fullWsTransport, | ||
errorFormatter | ||
}) | ||
}) | ||
} |
{ | ||
"name": "mercurius", | ||
"version": "12.1.0", | ||
"version": "12.2.0", | ||
"description": "Fastify GraphQL adapter with subscription support", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
@@ -5,2 +5,4 @@ 'use strict' | ||
const Fastify = require('fastify') | ||
const mq = require('mqemitter') | ||
const WebSocket = require('ws') | ||
const GQL = require('..') | ||
@@ -10,2 +12,3 @@ const { ErrorWithProps } = GQL | ||
const split = require('split2') | ||
const { GraphQLError } = require('graphql-jit/dist/error') | ||
@@ -364,2 +367,196 @@ test('ErrorWithProps - support status code in the constructor', async (t) => { | ||
test('subscription server sends correct error if there\'s a graphql error', t => { | ||
const app = Fastify() | ||
t.teardown(() => app.close()) | ||
const sendTestQuery = () => { | ||
app.inject({ | ||
method: 'POST', | ||
url: '/graphql', | ||
body: { | ||
query: ` | ||
query { | ||
notifications { | ||
id | ||
message | ||
} | ||
} | ||
` | ||
} | ||
}, () => { | ||
sendTestMutation() | ||
}) | ||
} | ||
const sendTestMutation = () => { | ||
app.inject({ | ||
method: 'POST', | ||
url: '/graphql', | ||
body: { | ||
query: ` | ||
mutation { | ||
addNotification(message: "Hello World") { | ||
id | ||
} | ||
} | ||
` | ||
} | ||
}, () => {}) | ||
} | ||
const emitter = mq() | ||
const schema = ` | ||
type Notification { | ||
id: ID! | ||
message: Int | ||
} | ||
type Query { | ||
notifications: [Notification] | ||
} | ||
type Mutation { | ||
addNotification(message: String): Notification | ||
} | ||
type Subscription { | ||
notificationAdded: Notification | ||
} | ||
` | ||
let idCount = 1 | ||
const notifications = [{ | ||
id: idCount, | ||
message: 'Notification message' | ||
}] | ||
const resolvers = { | ||
Query: { | ||
notifications: () => notifications | ||
}, | ||
Mutation: { | ||
addNotification: async (_, { message }) => { | ||
const id = idCount++ | ||
const notification = { | ||
id, | ||
message | ||
} | ||
notifications.push(notification) | ||
await emitter.emit({ | ||
topic: 'NOTIFICATION_ADDED', | ||
payload: { | ||
notificationAdded: notification | ||
} | ||
}) | ||
return notification | ||
} | ||
}, | ||
Subscription: { | ||
notificationAdded: { | ||
subscribe: (root, args, ctx) => { | ||
return ctx.pubsub.subscribe('NOTIFICATION_ADDED') | ||
} | ||
} | ||
} | ||
} | ||
app.register(GQL, { | ||
schema, | ||
resolvers, | ||
errorFormatter: (execution, ctx) => { | ||
const formatted = GQL.defaultErrorFormatter(execution, ctx) | ||
const errors = execution.errors.map(() => { | ||
return new GraphQLError('Whoops! Something went wrong.') | ||
}) | ||
return { | ||
statusCode: formatted.statusCode, | ||
response: { | ||
data: formatted.response.data, | ||
errors | ||
} | ||
} | ||
}, | ||
subscription: { | ||
emitter | ||
} | ||
}) | ||
app.listen({ port: 0 }, err => { | ||
t.error(err) | ||
const ws = new WebSocket('ws://localhost:' + (app.server.address()).port + '/graphql', 'graphql-ws') | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8', objectMode: true }) | ||
t.teardown(client.destroy.bind(client)) | ||
client.setEncoding('utf8') | ||
client.write(JSON.stringify({ | ||
type: 'connection_init' | ||
})) | ||
client.write(JSON.stringify({ | ||
id: 1, | ||
type: 'start', | ||
payload: { | ||
query: ` | ||
subscription { | ||
notificationAdded { | ||
id | ||
message | ||
} | ||
} | ||
` | ||
} | ||
})) | ||
client.write(JSON.stringify({ | ||
id: 2, | ||
type: 'start', | ||
payload: { | ||
query: ` | ||
subscription { | ||
notificationAdded { | ||
id | ||
message | ||
} | ||
} | ||
` | ||
} | ||
})) | ||
client.write(JSON.stringify({ | ||
id: 2, | ||
type: 'stop' | ||
})) | ||
client.on('data', chunk => { | ||
const data = JSON.parse(chunk) | ||
if (data.id === 1 && data.type === 'data') { | ||
t.equal(chunk, JSON.stringify({ | ||
type: 'data', | ||
id: 1, | ||
payload: { | ||
data: { | ||
notificationAdded: { | ||
id: '1', | ||
message: null | ||
} | ||
}, | ||
errors: [{ | ||
message: 'Whoops! Something went wrong.' | ||
}] | ||
} | ||
})) | ||
client.end() | ||
t.end() | ||
} else if (data.id === 2 && data.type === 'complete') { | ||
sendTestQuery() | ||
} | ||
}) | ||
}) | ||
}) | ||
test('POST query with a resolver which which throws and a custom error formatter', async (t) => { | ||
@@ -366,0 +563,0 @@ const app = Fastify() |
@@ -1062,2 +1062,184 @@ 'use strict' | ||
test('subscription server sends correct error if there\'s a graphql error', t => { | ||
const app = Fastify() | ||
t.teardown(() => app.close()) | ||
const sendTestQuery = () => { | ||
app.inject({ | ||
method: 'POST', | ||
url: '/graphql', | ||
body: { | ||
query: ` | ||
query { | ||
notifications { | ||
id | ||
message | ||
} | ||
} | ||
` | ||
} | ||
}, () => { | ||
sendTestMutation() | ||
}) | ||
} | ||
const sendTestMutation = () => { | ||
app.inject({ | ||
method: 'POST', | ||
url: '/graphql', | ||
body: { | ||
query: ` | ||
mutation { | ||
addNotification(message: "Hello World") { | ||
id | ||
} | ||
} | ||
` | ||
} | ||
}, () => {}) | ||
} | ||
const emitter = mq() | ||
const schema = ` | ||
type Notification { | ||
id: ID! | ||
message: Int | ||
} | ||
type Query { | ||
notifications: [Notification] | ||
} | ||
type Mutation { | ||
addNotification(message: String): Notification | ||
} | ||
type Subscription { | ||
notificationAdded: Notification | ||
} | ||
` | ||
let idCount = 1 | ||
const notifications = [{ | ||
id: idCount, | ||
message: 'Notification message' | ||
}] | ||
const resolvers = { | ||
Query: { | ||
notifications: () => notifications | ||
}, | ||
Mutation: { | ||
addNotification: async (_, { message }) => { | ||
const id = idCount++ | ||
const notification = { | ||
id, | ||
message | ||
} | ||
notifications.push(notification) | ||
await emitter.emit({ | ||
topic: 'NOTIFICATION_ADDED', | ||
payload: { | ||
notificationAdded: notification | ||
} | ||
}) | ||
return notification | ||
} | ||
}, | ||
Subscription: { | ||
notificationAdded: { | ||
subscribe: (root, args, ctx) => { | ||
return ctx.pubsub.subscribe('NOTIFICATION_ADDED') | ||
} | ||
} | ||
} | ||
} | ||
app.register(GQL, { | ||
schema, | ||
resolvers, | ||
subscription: { | ||
emitter | ||
} | ||
}) | ||
app.listen({ port: 0 }, err => { | ||
t.error(err) | ||
const ws = new WebSocket('ws://localhost:' + (app.server.address()).port + '/graphql', 'graphql-ws') | ||
const client = WebSocket.createWebSocketStream(ws, { encoding: 'utf8', objectMode: true }) | ||
t.teardown(client.destroy.bind(client)) | ||
client.setEncoding('utf8') | ||
client.write(JSON.stringify({ | ||
type: 'connection_init' | ||
})) | ||
client.write(JSON.stringify({ | ||
id: 1, | ||
type: 'start', | ||
payload: { | ||
query: ` | ||
subscription { | ||
notificationAdded { | ||
id | ||
message | ||
} | ||
} | ||
` | ||
} | ||
})) | ||
client.write(JSON.stringify({ | ||
id: 2, | ||
type: 'start', | ||
payload: { | ||
query: ` | ||
subscription { | ||
notificationAdded { | ||
id | ||
message | ||
} | ||
} | ||
` | ||
} | ||
})) | ||
client.write(JSON.stringify({ | ||
id: 2, | ||
type: 'stop' | ||
})) | ||
client.on('data', chunk => { | ||
const data = JSON.parse(chunk) | ||
if (data.id === 1 && data.type === 'data') { | ||
t.equal(chunk, JSON.stringify({ | ||
type: 'data', | ||
id: 1, | ||
payload: { | ||
data: { | ||
notificationAdded: { | ||
id: '1', | ||
message: null | ||
} | ||
}, | ||
errors: [{ | ||
message: 'Int cannot represent non-integer value: "Hello World"', | ||
locations: [{ line: 5, column: 15 }], | ||
path: ['notificationAdded', 'message'] | ||
}] | ||
} | ||
})) | ||
client.end() | ||
t.end() | ||
} else if (data.id === 2 && data.type === 'complete') { | ||
sendTestQuery() | ||
} | ||
}) | ||
}) | ||
}) | ||
test('subscription server exposes pubsub', t => { | ||
@@ -1064,0 +1246,0 @@ const app = Fastify() |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
582787
18414