graphql-ws
Advanced tools
Comparing version 5.8.1 to 5.8.2
@@ -145,89 +145,94 @@ "use strict"; | ||
}; | ||
let execArgs; | ||
const maybeExecArgsOrErrors = await (onSubscribe === null || onSubscribe === void 0 ? void 0 : onSubscribe(ctx, message)); | ||
if (maybeExecArgsOrErrors) { | ||
if ((0, utils_1.areGraphQLErrors)(maybeExecArgsOrErrors)) | ||
return await emit.error(maybeExecArgsOrErrors); | ||
else if (Array.isArray(maybeExecArgsOrErrors)) | ||
throw new Error('Invalid return value from onSubscribe hook, expected an array of GraphQLError objects'); | ||
// not errors, is exec args | ||
execArgs = maybeExecArgsOrErrors; | ||
} | ||
else { | ||
// you either provide a schema dynamically through | ||
// `onSubscribe` or you set one up during the server setup | ||
if (!schema) | ||
throw new Error('The GraphQL schema is not provided'); | ||
const args = { | ||
operationName: payload.operationName, | ||
document: (0, graphql_1.parse)(payload.query), | ||
variableValues: payload.variables, | ||
}; | ||
execArgs = Object.assign(Object.assign({}, args), { schema: typeof schema === 'function' | ||
? await schema(ctx, message, args) | ||
: schema }); | ||
const validationErrors = (validate !== null && validate !== void 0 ? validate : graphql_1.validate)(execArgs.schema, execArgs.document); | ||
if (validationErrors.length > 0) | ||
return await emit.error(validationErrors); | ||
} | ||
const operationAST = (0, graphql_1.getOperationAST)(execArgs.document, execArgs.operationName); | ||
if (!operationAST) | ||
return await emit.error([ | ||
new graphql_1.GraphQLError('Unable to identify operation'), | ||
]); | ||
// if `onSubscribe` didnt specify a rootValue, inject one | ||
if (!('rootValue' in execArgs)) | ||
execArgs.rootValue = roots === null || roots === void 0 ? void 0 : roots[operationAST.operation]; | ||
// if `onSubscribe` didn't specify a context, inject one | ||
if (!('contextValue' in execArgs)) | ||
execArgs.contextValue = | ||
typeof context === 'function' | ||
? await context(ctx, message, execArgs) | ||
: context; | ||
// the execution arguments have been prepared | ||
// perform the operation and act accordingly | ||
let operationResult; | ||
if (operationAST.operation === 'subscription') | ||
operationResult = await (subscribe !== null && subscribe !== void 0 ? subscribe : graphql_1.subscribe)(execArgs); | ||
// operation === 'query' || 'mutation' | ||
else | ||
operationResult = await (execute !== null && execute !== void 0 ? execute : graphql_1.execute)(execArgs); | ||
const maybeResult = await (onOperation === null || onOperation === void 0 ? void 0 : onOperation(ctx, message, execArgs, operationResult)); | ||
if (maybeResult) | ||
operationResult = maybeResult; | ||
if ((0, utils_1.isAsyncIterable)(operationResult)) { | ||
/** multiple emitted results */ | ||
if (!(id in ctx.subscriptions)) { | ||
// subscription was completed/canceled before the operation settled | ||
if ((0, utils_1.isAsyncGenerator)(operationResult)) | ||
operationResult.return(undefined); | ||
try { | ||
let execArgs; | ||
const maybeExecArgsOrErrors = await (onSubscribe === null || onSubscribe === void 0 ? void 0 : onSubscribe(ctx, message)); | ||
if (maybeExecArgsOrErrors) { | ||
if ((0, utils_1.areGraphQLErrors)(maybeExecArgsOrErrors)) | ||
return await emit.error(maybeExecArgsOrErrors); | ||
else if (Array.isArray(maybeExecArgsOrErrors)) | ||
throw new Error('Invalid return value from onSubscribe hook, expected an array of GraphQLError objects'); | ||
// not errors, is exec args | ||
execArgs = maybeExecArgsOrErrors; | ||
} | ||
else { | ||
ctx.subscriptions[id] = operationResult; | ||
try { | ||
for (var operationResult_1 = __asyncValues(operationResult), operationResult_1_1; operationResult_1_1 = await operationResult_1.next(), !operationResult_1_1.done;) { | ||
const result = operationResult_1_1.value; | ||
await emit.next(result, execArgs); | ||
} | ||
// you either provide a schema dynamically through | ||
// `onSubscribe` or you set one up during the server setup | ||
if (!schema) | ||
throw new Error('The GraphQL schema is not provided'); | ||
const args = { | ||
operationName: payload.operationName, | ||
document: (0, graphql_1.parse)(payload.query), | ||
variableValues: payload.variables, | ||
}; | ||
execArgs = Object.assign(Object.assign({}, args), { schema: typeof schema === 'function' | ||
? await schema(ctx, message, args) | ||
: schema }); | ||
const validationErrors = (validate !== null && validate !== void 0 ? validate : graphql_1.validate)(execArgs.schema, execArgs.document); | ||
if (validationErrors.length > 0) | ||
return await emit.error(validationErrors); | ||
} | ||
const operationAST = (0, graphql_1.getOperationAST)(execArgs.document, execArgs.operationName); | ||
if (!operationAST) | ||
return await emit.error([ | ||
new graphql_1.GraphQLError('Unable to identify operation'), | ||
]); | ||
// if `onSubscribe` didnt specify a rootValue, inject one | ||
if (!('rootValue' in execArgs)) | ||
execArgs.rootValue = roots === null || roots === void 0 ? void 0 : roots[operationAST.operation]; | ||
// if `onSubscribe` didn't specify a context, inject one | ||
if (!('contextValue' in execArgs)) | ||
execArgs.contextValue = | ||
typeof context === 'function' | ||
? await context(ctx, message, execArgs) | ||
: context; | ||
// the execution arguments have been prepared | ||
// perform the operation and act accordingly | ||
let operationResult; | ||
if (operationAST.operation === 'subscription') | ||
operationResult = await (subscribe !== null && subscribe !== void 0 ? subscribe : graphql_1.subscribe)(execArgs); | ||
// operation === 'query' || 'mutation' | ||
else | ||
operationResult = await (execute !== null && execute !== void 0 ? execute : graphql_1.execute)(execArgs); | ||
const maybeResult = await (onOperation === null || onOperation === void 0 ? void 0 : onOperation(ctx, message, execArgs, operationResult)); | ||
if (maybeResult) | ||
operationResult = maybeResult; | ||
if ((0, utils_1.isAsyncIterable)(operationResult)) { | ||
/** multiple emitted results */ | ||
if (!(id in ctx.subscriptions)) { | ||
// subscription was completed/canceled before the operation settled | ||
if ((0, utils_1.isAsyncGenerator)(operationResult)) | ||
operationResult.return(undefined); | ||
} | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
else { | ||
ctx.subscriptions[id] = operationResult; | ||
try { | ||
if (operationResult_1_1 && !operationResult_1_1.done && (_a = operationResult_1.return)) await _a.call(operationResult_1); | ||
for (var operationResult_1 = __asyncValues(operationResult), operationResult_1_1; operationResult_1_1 = await operationResult_1.next(), !operationResult_1_1.done;) { | ||
const result = operationResult_1_1.value; | ||
await emit.next(result, execArgs); | ||
} | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
finally { | ||
try { | ||
if (operationResult_1_1 && !operationResult_1_1.done && (_a = operationResult_1.return)) await _a.call(operationResult_1); | ||
} | ||
finally { if (e_1) throw e_1.error; } | ||
} | ||
} | ||
} | ||
else { | ||
/** single emitted result */ | ||
// if the client completed the subscription before the single result | ||
// became available, he effectively canceled it and no data should be sent | ||
if (id in ctx.subscriptions) | ||
await emit.next(operationResult, execArgs); | ||
} | ||
// lack of subscription at this point indicates that the client | ||
// completed the subscription, he doesnt need to be reminded | ||
await emit.complete(id in ctx.subscriptions); | ||
} | ||
else { | ||
/** single emitted result */ | ||
// if the client completed the subscription before the single result | ||
// became available, he effectively canceled it and no data should be sent | ||
if (id in ctx.subscriptions) | ||
await emit.next(operationResult, execArgs); | ||
finally { | ||
// whatever happens to the subscription, we finally want to get rid of the reservation | ||
delete ctx.subscriptions[id]; | ||
} | ||
// lack of subscription at this point indicates that the client | ||
// completed the subscription, he doesnt need to be reminded | ||
await emit.complete(id in ctx.subscriptions); | ||
delete ctx.subscriptions[id]; | ||
return; | ||
@@ -234,0 +239,0 @@ } |
{ | ||
"name": "graphql-ws", | ||
"version": "5.8.1", | ||
"version": "5.8.2", | ||
"description": "Coherent, zero-dependency, lazy, simple, GraphQL over WebSocket Protocol compliant server and client", | ||
@@ -85,3 +85,3 @@ "keywords": [ | ||
"devDependencies": { | ||
"@babel/core": "^7.17.9", | ||
"@babel/core": "^7.17.10", | ||
"@babel/plugin-proposal-class-properties": "^7.16.7", | ||
@@ -91,3 +91,3 @@ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.16.7", | ||
"@babel/plugin-proposal-optional-chaining": "^7.16.7", | ||
"@babel/preset-env": "^7.16.11", | ||
"@babel/preset-env": "^7.17.10", | ||
"@babel/preset-typescript": "^7.16.7", | ||
@@ -97,18 +97,20 @@ "@rollup/plugin-typescript": "^8.3.2", | ||
"@semantic-release/git": "^10.0.1", | ||
"@types/jest": "^27.4.1", | ||
"@types/jest": "^27.5.1", | ||
"@types/ws": "^8.5.3", | ||
"@typescript-eslint/eslint-plugin": "^5.20.0", | ||
"@typescript-eslint/parser": "^5.20.0", | ||
"babel-jest": "^27.5.1", | ||
"eslint": "^8.14.0", | ||
"@typescript-eslint/eslint-plugin": "^5.23.0", | ||
"@typescript-eslint/parser": "^5.23.0", | ||
"babel-jest": "^28.1.0", | ||
"eslint": "^8.15.0", | ||
"eslint-config-prettier": "^8.5.0", | ||
"eslint-plugin-prettier": "^4.0.0", | ||
"fastify": "^3.28.0", | ||
"fastify-websocket": "^4.2.2", | ||
"fastify": "^3.29.0", | ||
"fastify-websocket": "4.2.2", | ||
"glob": "^8.0.1", | ||
"graphql": "^16.3.0", | ||
"jest": "^27.5.1", | ||
"graphql": "^16.5.0", | ||
"jest": "^28.1.0", | ||
"jest-environment-jsdom": "^28.1.0", | ||
"jest-jasmine2": "^28.1.0", | ||
"prettier": "^2.6.2", | ||
"replacestream": "^4.0.3", | ||
"rollup": "^2.70.2", | ||
"rollup": "^2.72.1", | ||
"rollup-plugin-terser": "^7.0.2", | ||
@@ -120,5 +122,5 @@ "semantic-release": "^19.0.2", | ||
"typedoc-plugin-markdown": "^3.12.1", | ||
"typescript": "^4.6.3", | ||
"typescript": "^4.6.4", | ||
"uWebSockets.js": "uNetworking/uWebSockets.js#v20.8.0", | ||
"ws": "^8.5.0", | ||
"ws": "^8.6.0", | ||
"ws7": "npm:ws@^7.5.7" | ||
@@ -125,0 +127,0 @@ }, |
@@ -1021,3 +1021,3 @@ <div align="center"> | ||
onConnect: async (ctx) => { | ||
// do your auth on every connect | ||
// do your auth on every connect (recommended) | ||
await handleAuth(ctx.extra.request); | ||
@@ -1029,6 +1029,2 @@ }, | ||
}, | ||
onNext: async (ctx) => { | ||
// haha why not on every result emission? | ||
await handleAuth(ctx.extra.request); | ||
}, | ||
}); | ||
@@ -1718,3 +1714,3 @@ | ||
onConnect: async (ctx) => { | ||
// do your auth check on every connect | ||
// do your auth check on every connect (recommended) | ||
if (!(await isTokenValid(ctx.connectionParams?.token))) | ||
@@ -1730,7 +1726,2 @@ // returning false from the onConnect callback will close with `4403: Forbidden`; | ||
}, | ||
onNext: async (ctx) => { | ||
// why not on every result emission? lol | ||
if (!(await isTokenValid(ctx.connectionParams?.token))) | ||
return ctx.extra.socket.close(CloseCode.Forbidden, 'Forbidden'); | ||
}, | ||
}, | ||
@@ -1737,0 +1728,0 @@ wsServer, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
288296
4560
38
1807