-
-
Save trentm/ee7d2d5f7c7a98917b362c405830c84b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/lib/instrumentation/modules/graphql.js b/lib/instrumentation/modules/graphql.js | |
index 4c680f2f..a59b4ba7 100644 | |
--- a/lib/instrumentation/modules/graphql.js | |
+++ b/lib/instrumentation/modules/graphql.js | |
@@ -41,19 +41,36 @@ module.exports = function (graphql, agent, { version, enabled }) { | |
}) | |
function wrapGraphql (orig) { | |
- return function wrappedGraphql (schema, requestString, rootValue, contextValue, variableValues, operationName) { | |
+ return function wrappedGraphql (args) { | |
agent.logger.debug('intercepted call to graphql.graphql') | |
const span = ins.createSpan('GraphQL: Unknown Query', 'db', 'graphql', 'execute') | |
if (!span) { | |
return orig.apply(this, arguments) | |
} | |
- var source = new graphql.Source(requestString || '', 'GraphQL request') | |
- if (source) { | |
+ let schema | |
+ let source | |
+ let operationName | |
+ if (arguments.length === 1) { | |
+ schema = args.schema | |
+ source = args.source | |
+ operationName = args.operationName | |
+ } else { | |
+ // graphql <=v15 supported positional arguments: | |
+ // function (schema, source, rootValue, contextValue, variableValues, operationName) | |
+ schema = arguments[0] | |
+ source = arguments[1] | |
+ operationName = arguments[5] | |
+ } | |
+ | |
+ const sourceObj = (typeof source === 'string' | |
+ ? new graphql.Source(source || '', 'GraphQL request') | |
+ : source) | |
+ if (sourceObj) { | |
var documentAST | |
try { | |
- documentAST = graphql.parse(source) | |
+ documentAST = graphql.parse(sourceObj) | |
} catch (syntaxError) { | |
agent.logger.debug('graphql.parse(source) failed - skipping graphql query extraction') | |
} | |
@@ -79,9 +96,7 @@ module.exports = function (graphql, agent, { version, enabled }) { | |
} | |
function wrapExecute (orig) { | |
- return function wrappedExecute () { | |
- var { document, operationName } = extractArgs(...arguments) | |
- | |
+ return function wrappedExecute (args) { | |
agent.logger.debug('intercepted call to graphql.execute') | |
const span = ins.createSpan('GraphQL: Unknown Query', 'db', 'graphql', 'execute') | |
if (!span) { | |
@@ -89,6 +104,18 @@ module.exports = function (graphql, agent, { version, enabled }) { | |
return orig.apply(this, arguments) | |
} | |
+ let document | |
+ let operationName | |
+ if (arguments.length === 1) { | |
+ document = args.document | |
+ operationName = args.operationName | |
+ } else { | |
+ // graphql <=v15 supported positional arguments: | |
+ // function (schema, document, rootValue, contextValue, variableValues, operationName) | |
+ document = arguments[1] | |
+ operationName = arguments[5] | |
+ } | |
+ | |
var details = extractDetails(document, operationName) | |
var queries = details.queries | |
operationName = operationName || (details.operation && details.operation.name && details.operation.name.value) | |
@@ -123,20 +150,6 @@ module.exports = function (graphql, agent, { version, enabled }) { | |
} | |
} | |
- function extractArgs (argsOrSchema, document, rootValue, contextValue, variableValues, operationName) { | |
- // Arg object | |
- if (arguments.length === 1) { | |
- return { | |
- document: argsOrSchema.document, | |
- operationName: argsOrSchema.operationName | |
- } | |
- } | |
- return { | |
- document, | |
- operationName | |
- } | |
- } | |
- | |
function extractDetails (document, operationName) { | |
var queries = [] | |
var operation | |
diff --git a/package-lock.json b/package-lock.json | |
index 97b52487..6e0d019d 100644 | |
--- a/package-lock.json | |
+++ b/package-lock.json | |
@@ -83,7 +83,7 @@ | |
"generic-pool": "^3.7.1", | |
"get-port": "^5.1.1", | |
"got": "^9.6.0", | |
- "graphql": "^15.8.0", | |
+ "graphql": "^16.5.0", | |
"handlebars": "^4.7.3", | |
"https-pem": "^3.0.0", | |
"ioredis": "^4.28.0", | |
@@ -8346,12 +8346,12 @@ | |
"dev": true | |
}, | |
"node_modules/graphql": { | |
- "version": "15.8.0", | |
- "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", | |
- "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", | |
+ "version": "16.5.0", | |
+ "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.5.0.tgz", | |
+ "integrity": "sha512-qbHgh8Ix+j/qY+a/ZcJnFQ+j8ezakqPiHwPiZhV/3PgGlgf96QMBB5/f2rkiC9sgLoy/xvT6TSiaf2nTHJh5iA==", | |
"dev": true, | |
"engines": { | |
- "node": ">= 10.x" | |
+ "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" | |
} | |
}, | |
"node_modules/graphql-tag": { | |
@@ -22766,9 +22766,9 @@ | |
"dev": true | |
}, | |
"graphql": { | |
- "version": "15.8.0", | |
- "resolved": "https://registry.npmjs.org/graphql/-/graphql-15.8.0.tgz", | |
- "integrity": "sha512-5gghUc24tP9HRznNpV2+FIoq3xKkj5dTQqf4v0CpdPbFVwFkWoxOM+o+2OC9ZSvjEMTjfmG9QT+gcvggTwW1zw==", | |
+ "version": "16.5.0", | |
+ "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.5.0.tgz", | |
+ "integrity": "sha512-qbHgh8Ix+j/qY+a/ZcJnFQ+j8ezakqPiHwPiZhV/3PgGlgf96QMBB5/f2rkiC9sgLoy/xvT6TSiaf2nTHJh5iA==", | |
"dev": true | |
}, | |
"graphql-tag": { | |
diff --git a/package.json b/package.json | |
index 75129a3e..2105cfdf 100644 | |
--- a/package.json | |
+++ b/package.json | |
@@ -153,7 +153,7 @@ | |
"generic-pool": "^3.7.1", | |
"get-port": "^5.1.1", | |
"got": "^9.6.0", | |
- "graphql": "^15.8.0", | |
+ "graphql": "^16.5.0", | |
"handlebars": "^4.7.3", | |
"https-pem": "^3.0.0", | |
"ioredis": "^4.28.0", | |
diff --git a/test/instrumentation/modules/graphql.test.js b/test/instrumentation/modules/graphql.test.js | |
index 9aa3e51a..d8ea1ab3 100644 | |
--- a/test/instrumentation/modules/graphql.test.js | |
+++ b/test/instrumentation/modules/graphql.test.js | |
@@ -9,17 +9,42 @@ var agent = require('../../..').start({ | |
}) | |
var graphql = require('graphql') | |
-var pkg = require('graphql/package.json') | |
+const graphqlVer = require('graphql/package.json').version | |
var semver = require('semver') | |
var test = require('tape') | |
var mockClient = require('../../_mock_http_client') | |
-test('graphql.graphql', function (t) { | |
+if (semver.lt(graphqlVer, '16.0.0')) { | |
+ // graphql@16 dropped support for positional arguments. | |
+ test('graphql.graphql(...) - positional args', function (t) { | |
+ resetAgent(done(t)) | |
+ | |
+ var schema = graphql.buildSchema('type Query { hello: String }') | |
+ var rootValue = { | |
+ hello () { | |
+ return 'Hello world!' | |
+ } | |
+ } | |
+ var query = '{ hello }' | |
+ | |
+ agent.startTransaction('foo') | |
+ | |
+ graphql.graphql(schema, query, rootValue).then(function (response) { | |
+ t.ok(agent.currentSpan === null, 'no currentSpan .graphql().then(...)') | |
+ agent.endTransaction() | |
+ t.deepLooseEqual(response, { data: { hello: 'Hello world!' } }) | |
+ agent.flush() | |
+ }) | |
+ t.ok(agent.currentSpan === null, 'no currentSpan in sync code after .graphql(...)') | |
+ }) | |
+} | |
+ | |
+test('graphql.graphql(...) - single GraphQLArgs arg', function (t) { | |
resetAgent(done(t)) | |
var schema = graphql.buildSchema('type Query { hello: String }') | |
- var root = { | |
+ var rootValue = { | |
hello () { | |
return 'Hello world!' | |
} | |
@@ -28,7 +53,7 @@ test('graphql.graphql', function (t) { | |
agent.startTransaction('foo') | |
- graphql.graphql(schema, query, root).then(function (response) { | |
+ graphql.graphql({ schema, source: query, rootValue }).then(function (response) { | |
t.ok(agent.currentSpan === null, 'no currentSpan .graphql().then(...)') | |
agent.endTransaction() | |
t.deepLooseEqual(response, { data: { hello: 'Hello world!' } }) | |
@@ -41,7 +66,7 @@ test('graphql.graphql - invalid query', function (t) { | |
resetAgent(done(t, 'Unknown Query')) | |
var schema = graphql.buildSchema('type Query { hello: String }') | |
- var root = { | |
+ var rootValue = { | |
hello () { | |
return 'Hello world!' | |
} | |
@@ -50,7 +75,7 @@ test('graphql.graphql - invalid query', function (t) { | |
agent.startTransaction('foo') | |
- graphql.graphql(schema, query, root).then(function (response) { | |
+ graphql.graphql({ schema, source: query, rootValue }).then(function (response) { | |
t.ok(agent.currentSpan === null, 'no currentSpan .graphql().then(...)') | |
agent.endTransaction() | |
t.deepEqual(Object.keys(response), ['errors']) | |
@@ -75,7 +100,7 @@ test('graphql.graphql - transaction ended', function (t) { | |
}) | |
var schema = graphql.buildSchema('type Query { hello: String }') | |
- var root = { | |
+ var rootValue = { | |
hello () { | |
return 'Hello world!' | |
} | |
@@ -84,36 +109,39 @@ test('graphql.graphql - transaction ended', function (t) { | |
agent.startTransaction('foo').end() | |
- graphql.graphql(schema, query, root).then(function (response) { | |
+ graphql.graphql({ schema, source: query, rootValue }).then(function (response) { | |
t.ok(agent.currentSpan === null, 'no currentSpan .graphql().then(...)') | |
t.deepLooseEqual(response, { data: { hello: 'Hello world!' } }) | |
}) | |
t.ok(agent.currentSpan === null, 'no currentSpan in sync code after .graphql(...)') | |
}) | |
-test('graphql.execute', function (t) { | |
- resetAgent(done(t)) | |
+if (semver.lt(graphqlVer, '16.0.0')) { | |
+ // graphql@16 dropped support for positional arguments. | |
+ test('graphql.execute(...) - positional args', function (t) { | |
+ resetAgent(done(t)) | |
- var schema = graphql.buildSchema('type Query { hello: String }') | |
- var root = { | |
- hello () { | |
- return Promise.resolve('Hello world!') | |
+ var schema = graphql.buildSchema('type Query { hello: String }') | |
+ var rootValue = { | |
+ hello () { | |
+ return Promise.resolve('Hello world!') | |
+ } | |
} | |
- } | |
- var query = '{ hello }' | |
- var source = new graphql.Source(query) | |
- var documentAST = graphql.parse(source) | |
+ var query = '{ hello }' | |
+ var source = new graphql.Source(query) | |
+ var documentAST = graphql.parse(source) | |
- agent.startTransaction('foo') | |
+ agent.startTransaction('foo') | |
- graphql.execute(schema, documentAST, root).then(function (response) { | |
- t.ok(agent.currentSpan === null, 'no currentSpan .execute().then(...)') | |
- agent.endTransaction() | |
- t.deepLooseEqual(response, { data: { hello: 'Hello world!' } }) | |
- agent.flush() | |
+ graphql.execute(schema, documentAST, rootValue).then(function (response) { | |
+ t.ok(agent.currentSpan === null, 'no currentSpan .execute().then(...)') | |
+ agent.endTransaction() | |
+ t.deepLooseEqual(response, { data: { hello: 'Hello world!' } }) | |
+ agent.flush() | |
+ }) | |
+ t.ok(agent.currentSpan === null, 'no currentSpan in sync code after .execute(...)') | |
}) | |
- t.ok(agent.currentSpan === null, 'no currentSpan in sync code after .execute(...)') | |
-}) | |
+} | |
test('graphql.execute - transaction ended', function (t) { | |
t.plan(7) | |
@@ -129,29 +157,29 @@ test('graphql.execute - transaction ended', function (t) { | |
}) | |
var schema = graphql.buildSchema('type Query { hello: String }') | |
- var root = { | |
+ var rootValue = { | |
hello () { | |
return Promise.resolve('Hello world!') | |
} | |
} | |
var query = '{ hello }' | |
var source = new graphql.Source(query) | |
- var documentAST = graphql.parse(source) | |
+ var document = graphql.parse(source) | |
agent.startTransaction('foo').end() | |
- graphql.execute(schema, documentAST, root).then(function (response) { | |
+ graphql.execute({ schema, document, rootValue }).then(function (response) { | |
t.ok(agent.currentSpan === null, 'no currentSpan .execute().then(...)') | |
t.deepLooseEqual(response, { data: { hello: 'Hello world!' } }) | |
}) | |
t.ok(agent.currentSpan === null, 'no currentSpan in sync code after .execute(...)') | |
}) | |
-test('graphql.execute args object', function (t) { | |
+test('graphql.execute(...) - single ExecutionArgs arg', function (t) { | |
resetAgent(done(t)) | |
var schema = graphql.buildSchema('type Query { hello: String }') | |
- var root = { | |
+ var rootValue = { | |
hello () { | |
return Promise.resolve('Hello world!') | |
} | |
@@ -162,7 +190,7 @@ test('graphql.execute args object', function (t) { | |
var args = { | |
schema: schema, | |
document: documentAST, | |
- rootValue: root | |
+ rootValue: rootValue | |
} | |
agent.startTransaction('foo') | |
@@ -176,23 +204,23 @@ test('graphql.execute args object', function (t) { | |
t.ok(agent.currentSpan === null, 'no currentSpan in sync code after .execute(...)') | |
}) | |
-if (semver.satisfies(pkg.version, '>=0.12')) { | |
+if (semver.satisfies(graphqlVer, '>=0.12')) { | |
test('graphql.execute sync', function (t) { | |
resetAgent(done(t)) | |
var schema = graphql.buildSchema('type Query { hello: String }') | |
- var root = { | |
+ var rootValue = { | |
hello () { | |
return 'Hello world!' | |
} | |
} | |
var query = '{ hello }' | |
var source = new graphql.Source(query) | |
- var documentAST = graphql.parse(source) | |
+ var document = graphql.parse(source) | |
agent.startTransaction('foo') | |
- var response = graphql.execute(schema, documentAST, root) | |
+ var response = graphql.execute({ schema, document, rootValue }) | |
t.ok(agent.currentSpan === null, 'no currentSpan in sync code after .execute(...)') | |
agent.endTransaction() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment