Repository: newrelic/newrelic-node-apollo-server-plugin
Pull request #249 (2023-05-24 22:27:50)

feat: provide two callbacks for defining custom attributes
## Proposed Release Notes

* feat: provide two callbacks for defining custom attributes

## Links

* NEWRELIC-8675

## Details

Commit messages follow below. I suggest reviewing this PR commit-by-commit, so that details like the linting don't distract from the functional details.

* chore: upgrade linter and re-run linting

I actually have a purpose in doing this. I need to do optional
chaining, but the current configuration of the linter doesn't allow
it. While I'm updating the config, it makes sense to re-run the
linting as well, put the code up to our standards.

* fix(createPlugin): change its signature to use full API object

I need to use the NR API object in order to call
`addCustomAttributes`, since custom attributes have extra bit of logic
unlike normal attributes. This means that instead of just passing
`newrelic.shim` into `createPlugin`, we need the actual `newrelic` API
object itself.

This is not a breaking change because this is all internal API.
Externally, in `index.js` we use `bind` to hide the first argument
passed into `createPlugin`, so users of this plugin should not see a
difference.

* feat(createPlugin): add two configuration callbacks for custom attributes

Since we create two kinds of spans, there are two callbacks here, one
for each kind of span: operation and resolver spans.

The callbacks are passed the same arguments as the resolver and event
handlers so that they can use that information for building whatever
custom attributes they may want.

* chore(docs): document the two new callbacks

codecov[bot]: ## [Codecov](https://app.codecov.io/gh/newrelic/newrelic-node-apollo-server-plugin/pull/249?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=newrelic) Report
> Merging [#249](https://app.codecov.io/gh/newrelic/newrelic-node-apollo-server-plugin/pull/249?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=newrelic) (8c169d1) into [main](https://app.codecov.io/gh/newrelic/newrelic-node-apollo-server-plugin/commit/0ec37e07f752946ffe2e088744f71cbd0378b184?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=newrelic) (0ec37e0) will **decrease** coverage by `6.72%`.
> The diff coverage is `57.14%`.

```diff
@@            Coverage Diff             @@
##             main     #249      +/-   ##
==========================================
- Coverage   98.92%   92.21%   -6.72%     
==========================================
  Files           4        4              
  Lines         653      668      +15     
==========================================
- Hits          646      616      -30     
- Misses          7       52      +45     
```

| Flag | Coverage Δ | |
|---|---|---|
| integration-tests-14.x | `91.01% <57.14%> (-1.79%)` | :arrow_down: |
| integration-tests-16.x | `91.01% <57.14%> (-1.79%)` | :arrow_down: |
| integration-tests-18.x | `91.01% <57.14%> (-1.79%)` | :arrow_down: |
| unit-tests-14.x | `53.14% <31.42%> (-0.15%)` | :arrow_down: |
| unit-tests-16.x | `53.14% <31.42%> (-0.15%)` | :arrow_down: |
| unit-tests-18.x | `53.14% <31.42%> (-0.15%)` | :arrow_down: |
| versioned-tests-14.x | `?` | |
| versioned-tests-16.x | `?` | |
| versioned-tests-18.x | `?` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=newrelic#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://app.codecov.io/gh/newrelic/newrelic-node-apollo-server-plugin/pull/249?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=newrelic) | Coverage Δ | |
|---|---|---|
| [lib/create-plugin.js](https://app.codecov.io/gh/newrelic/newrelic-node-apollo-server-plugin/pull/249?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=newrelic#diff-bGliL2NyZWF0ZS1wbHVnaW4uanM=) | `91.37% <55.88%> (-7.39%)` | :arrow_down: |
| [index.js](https://app.codecov.io/gh/newrelic/newrelic-node-apollo-server-plugin/pull/249?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=newrelic#diff-aW5kZXguanM=) | `100.00% <100.00%> (ø)` | |

... and [1 file with indirect coverage changes](https://app.codecov.io/gh/newrelic/newrelic-node-apollo-server-plugin/pull/249/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=newrelic)

:mega: We’re building smart automated test selection to slash your CI/CD build times. [Learn more](https://about.codecov.io/iterative-testing/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=newrelic)


Patch:
diff --git a/.eslintrc.js b/.eslintrc.js
index 84c5c26..a179e08 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -5,5 +5,8 @@
 
 'use strict'
 module.exports = {
-  extends: '@newrelic'
+  extends: '@newrelic',
+  parserOptions: {
+    ecmaVersion: '2020'
+  }
 }
diff --git a/README.md b/README.md
index f012c82..e8a2df2 100644
--- a/README.md
+++ b/README.md
@@ -121,7 +121,9 @@ const plugin = createPlugin({
   captureScalars: true,
   captureIntrospectionQueries: true,
   captureServiceDefinitionQueries: true,
-  captureHealthCheckQueries: true
+  captureHealthCheckQueries: true,
+  customResolverAttributes: () => { return { exampleAttribute: 'exampleValue' }},
+  customOperationAttributes: () => { return { exampleAttribute: 'exampleValue' }}
 })
 ```
 
@@ -138,6 +140,28 @@ const plugin = createPlugin({
 
 * `[captureHealthCheckQueries = false]` Enable capture of timings for a [Health Check query](https://www.apollographql.com/docs/federation/api/apollo-gateway/#servicehealthcheck) received from an Apollo Federated Gateway Server.
 
+There are two configuration options for providing callbacks that can be used to define custom attributes. As their names suggest, `customResolverAttributes` will put custom attributes on the resolver segment and `customOperationAttributes` will use the operation segment. 
+
+The `customResolverAttributes` callback gets passed a `resolverContext` object [corresponding to the attributes given to a resolver](https://www.apollographql.com/docs/apollo-server/data/resolvers/#resolver-arguments) in Apollo server. The `customOperationAttributes` callback gets passed [a `requestContext` argument](https://github.com/apollographql/apollo-server/blob/6b4945935a786d06e7ff904be94c0035fe27aeb1/packages/server/src/externalTypes/graphql.ts#L47). These arguments can be used to imbue more details into custom attributes.  Both callbacks must return an object that will be used to define custom attribute key-value pairs. For example,
+
+```js
+const plugin = createPlugin({
+  customResolverAttributes({ source, args, context, info }) {
+    return {
+      allArgs: Object.keys(args).join(','),
+      returnType: info.returnType.name,
+      sourceBranch: source?.branch
+      stage: context.event.requestContext.stage
+    }
+  },
+  customOperationAttributes(requestContext) {
+    return {
+      clientName: requestContext.request.http.headers.get('graphql-client-name')
+    }
+  }
+})
+```
+
 ### Apollo Federation Support
 
 The New Relic plugin will work with an Apollo Federated Server out of the box. Just pass the plugin to the Federated Gateway Apollo Server. With the federated server you will get:
diff --git a/index.js b/index.js
index 72d3dcb..15eb1a0 100644
--- a/index.js
+++ b/index.js
@@ -10,4 +10,4 @@ const createPlugin = require('./lib/create-plugin')
 
 // TODO: need to grab instrumentation API from agent via
 // supported means that will not disappear when agent disabled.
-module.exports = createPlugin.bind(null, newrelic.shim)
+module.exports = createPlugin.bind(null, newrelic)
diff --git a/lib/create-plugin.js b/lib/create-plugin.js
index 48ebd57..87110d2 100644
--- a/lib/create-plugin.js
+++ b/lib/create-plugin.js
@@ -50,16 +50,18 @@ const DESTINATIONS = {
  * NOTE: query/mutation resolvers will always be captured even if returning a scalar type.
  */
 
+/* eslint sonarjs/cognitive-complexity: ["error", 57] -- TODO: https://issues.newrelic.com/browse/NEWRELIC-8797 */
 /**
  * Creates an Apollo Server plugin for capturing timing data
  * via the New Relic Node.js agent.
  * @param {*} instrumentationApi New Relic instrumentation API
  * @param {PluginConfig} [config]
  */
-function createPlugin(instrumentationApi, config = {}) {
-  if (!instrumentationApi) {
+function createPlugin(api, config = {}) {
+  if (!api?.shim) {
     return {}
   }
+  const instrumentationApi = api.shim
 
   const logger = instrumentationApi.logger.child({ component: 'ApolloServerPlugin' })
 
@@ -69,6 +71,8 @@ function createPlugin(instrumentationApi, config = {}) {
   config.captureIntrospectionQueries = config.captureIntrospectionQueries || false
   config.captureServiceDefinitionQueries = config.captureServiceDefinitionQueries || false
   config.captureHealthCheckQueries = config.captureHealthCheckQueries || false
+  config.customResolverAttributes = config.customResolverAttributes || null
+  config.customOperationAttributes = config.customOperationAttributes || null
 
   logger.debug('Plugin configuration: ', config)
 
@@ -126,7 +130,8 @@ function createPlugin(instrumentationApi, config = {}) {
           instrumentationApi.setActiveSegment(operationSegment)
 
           return {
-            willResolveField({ args, info }) {
+            willResolveField(resolverContext) {
+              const { info, args } = resolverContext
               const pathArray = flattenToArray(info.path)
               const formattedPath = pathArray.reverse().join('.')
 
@@ -155,12 +160,16 @@ function createPlugin(instrumentationApi, config = {}) {
               instrumentationApi.setActiveSegment(resolverSegment)
 
               resolverSegment.name = `${RESOLVE_PREFIX}/${formattedPath}`
-
               resolverSegment.addAttribute(FIELD_PATH_ATTR, formattedPath)
               resolverSegment.addAttribute(FIELD_NAME_ATTR, info.fieldName)
               resolverSegment.addAttribute(RETURN_TYPE_ATTR, info.returnType.toString())
               resolverSegment.addAttribute(PARENT_TYPE_ATTR, info.parentType.toString())
 
+              if (instrumentationApi.isFunction(config.customResolverAttributes)) {
+                const customAttributes = config.customResolverAttributes(resolverContext)
+                api.addCustomAttributes(customAttributes)
+              }
+
               // Like our http and framework instrumentation, we add
               // the attributes on the operation segment. We also add
               // the attributes to resolver segments as they help
@@ -202,6 +211,12 @@ function createPlugin(instrumentationApi, config = {}) {
               setTransactionName(operationSegment.transaction, '*')
             }
           }
+
+          if (instrumentationApi.isFunction(config.customOperationAttributes)) {
+            const customAttributes = config.customOperationAttributes(responseContext)
+            api.addCustomAttributes(customAttributes)
+          }
+
           operationSegment.end()
 
           logger.trace('End willSendResponse')
@@ -220,14 +235,12 @@ function getOperationDetails(responseContext) {
 }
 
 function isScalar(fieldInfo) {
-  const result = isScalarType(fieldInfo.returnType) || isNonNullScalarType(fieldInfo.returnType)
-  return result
+  return isScalarType(fieldInfo.returnType) || isNonNullScalarType(fieldInfo.returnType)
 }
 
 function isScalarType(typeInstance) {
   const typeName = typeInstance.constructor.name
-  const result = typeName === 'GraphQLScalarType'
-  return result
+  return typeName === 'GraphQLScalarType'
 }
 
 function isNonNullScalarType(returnType) {
@@ -237,15 +250,12 @@ function isNonNullScalarType(returnType) {
   }
 
   const nestedType = returnType.ofType
-  const result = isScalarType(nestedType)
-
-  return result
+  return isScalarType(nestedType)
 }
 
 function isTopLevelField(fieldInfo) {
   const parentName = fieldInfo.parentType.name
-  const result = parentName === 'Query' || parentName === 'Mutation'
-  return result
+  return parentName === 'Query' || parentName === 'Mutation'
 }
 
 /**
@@ -266,7 +276,7 @@ function getDetailsFromDocument(responseContext) {
 
   // always use context.source so we can get both queries and persisted queries
   // see: https://github.com/apollographql/apollo-server/blob/2bccec2c5f5adaaf785f13ab98b6e52e22d5b22e/packages/apollo-server-core/src/requestPipeline.ts#L232
-  let query = cleanQuery(responseContext.source, pathAndArgs.argLocations)
+  const query = cleanQuery(responseContext.source, pathAndArgs.argLocations)
 
   const deepestUniquePath = pathAndArgs.deepestPath
 
@@ -342,7 +352,7 @@ function isNamedType(selection) {
 function getDeepestPathAndQueryArguments(definition) {
   let deepestPath = []
   let foundDeepestPath = false
-  let argLocations = []
+  const argLocations = []
 
   definition.selectionSet.selections.forEach((selection) => {
     searchSelection(selection)
@@ -492,8 +502,7 @@ function shouldIgnoreTransaction(operation, config, logger) {
   if (!config.captureIntrospectionQueries && isIntrospectionQuery(operation)) {
     logger.trace(
       'Request is an introspection query and ' +
-        '`config.captureIntrospectionQueries` is set to `false`. ' +
-        'Force ignoring the transaction.'
+        '`config.captureIntrospectionQueries` is set to `false`. Force ignoring the transaction.'
     )
 
     return true
@@ -502,8 +511,7 @@ function shouldIgnoreTransaction(operation, config, logger) {
   if (!config.captureServiceDefinitionQueries && isServiceDefinitionQuery(operation)) {
     logger.trace(
       'Request is an Apollo Federated Gateway service definition query and ' +
-        '`config.captureServiceDefinitionQueries` is set to `false`. ' +
-        'Force ignoring the transaction.'
+        '`config.captureServiceDefinitionQueries` is set to `false`. Force ignoring the transaction.'
     )
 
     return true
diff --git a/package-lock.json b/package-lock.json
index 1a25a00..fde3314 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,12 +10,12 @@
       "license": "Apache-2.0",
       "devDependencies": {
         "@apollo/server": "^4.1.1",
-        "@newrelic/eslint-config": "^0.0.2",
+        "@newrelic/eslint-config": "^0.3.0",
         "@newrelic/newrelic-oss-cli": "^0.1.2",
         "@newrelic/test-utilities": "^7.3.1",
         "apollo-server": "^3.11.1",
         "c8": "^7.12.0",
-        "eslint": "^7.32.0",
+        "eslint": "^8.24.0",
         "eslint-config-prettier": "^8.3.0",
         "eslint-plugin-header": "^3.1.1",
         "eslint-plugin-node": "^11.1.0",
@@ -699,23 +699,44 @@
       }
     },
     "node_modules/@eslint/eslintrc": {
-      "version": "0.4.3",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
-      "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==",
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz",
+      "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==",
       "dev": true,
       "dependencies": {
         "ajv": "^6.12.4",
-        "debug": "^4.1.1",
-        "espree": "^7.3.0",
-        "globals": "^13.9.0",
-        "ignore": "^4.0.6",
+        "debug": "^4.3.2",
+        "espree": "^9.4.0",
+        "globals": "^13.19.0",
+        "ignore": "^5.2.0",
         "import-fresh": "^3.2.1",
-        "js-yaml": "^3.13.1",
-        "minimatch": "^3.0.4",
+        "js-yaml": "^4.1.0",
+        "minimatch": "^3.1.2",
         "strip-json-comments": "^3.1.1"
       },
       "engines": {
-        "node": "^10.12.0 || >=12.0.0"
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/@eslint/eslintrc/node_modules/argparse": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+      "dev": true
+    },
+    "node_modules/@eslint/eslintrc/node_modules/js-yaml": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+      "dev": true,
+      "dependencies": {
+        "argparse": "^2.0.1"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
       }
     },
     "node_modules/@graphql-tools/merge": {
@@ -806,12 +827,12 @@
       }
     },
     "node_modules/@humanwhocodes/config-array": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz",
-      "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==",
+      "version": "0.10.7",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz",
+      "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==",
       "dev": true,
       "dependencies": {
-        "@humanwhocodes/object-schema": "^1.2.0",
+        "@humanwhocodes/object-schema": "^1.2.1",
         "debug": "^4.1.1",
         "minimatch": "^3.0.4"
       },
@@ -819,6 +840,29 @@
         "node": ">=10.10.0"
       }
     },
+    "node_modules/@humanwhocodes/gitignore-to-minimatch": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz",
+      "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==",
+      "dev": true,
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/nzakas"
+      }
+    },
+    "node_modules/@humanwhocodes/module-importer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+      "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+      "dev": true,
+      "engines": {
+        "node": ">=12.22"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/nzakas"
+      }
+    },
     "node_modules/@humanwhocodes/object-schema": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
@@ -977,19 +1021,20 @@
       }
     },
     "node_modules/@newrelic/eslint-config": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/@newrelic/eslint-config/-/eslint-config-0.0.2.tgz",
-      "integrity": "sha512-fMn9e4hShInAuZxYg5dV/qmJ48Qj6JE8eQqE6XyPiDsTriEt6A5H88PFQ50V/xmWGrSxnvmmCnXzdWgxUDaqbg==",
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/@newrelic/eslint-config/-/eslint-config-0.3.0.tgz",
+      "integrity": "sha512-woQshi/SB6uGrXPWb4w9G98HkQRCb9nJWfJ9/tlj0WkVOqU4Bsn4VZvEI63Vy5y1cTphajr4u6kjOzIk0kC6DA==",
       "dev": true,
       "engines": {
         "node": ">=12"
       },
       "peerDependencies": {
-        "eslint": "^7.32.0",
+        "eslint": "^8.24.0",
         "eslint-config-prettier": "^8.3.0",
         "eslint-plugin-header": "^3.1.1",
         "eslint-plugin-node": "^11.1.0",
         "eslint-plugin-prettier": "^3.4.0",
+        "eslint-plugin-sonarjs": "^0.18.0",
         "prettier": "^2.3.2"
       }
     },
@@ -3547,9 +3592,9 @@
       }
     },
     "node_modules/acorn": {
-      "version": "7.4.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
-      "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+      "version": "8.8.2",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
+      "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
       "dev": true,
       "bin": {
         "acorn": "bin/acorn"
@@ -5037,57 +5082,56 @@
       }
     },
     "node_modules/eslint": {
-      "version": "7.32.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz",
-      "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==",
+      "version": "8.24.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz",
+      "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==",
       "dev": true,
       "dependencies": {
-        "@babel/code-frame": "7.12.11",
-        "@eslint/eslintrc": "^0.4.3",
-        "@humanwhocodes/config-array": "^0.5.0",
+        "@eslint/eslintrc": "^1.3.2",
+        "@humanwhocodes/config-array": "^0.10.5",
+        "@humanwhocodes/gitignore-to-minimatch": "^1.0.2",
+        "@humanwhocodes/module-importer": "^1.0.1",
         "ajv": "^6.10.0",
         "chalk": "^4.0.0",
         "cross-spawn": "^7.0.2",
-        "debug": "^4.0.1",
+        "debug": "^4.3.2",
         "doctrine": "^3.0.0",
-        "enquirer": "^2.3.5",
         "escape-string-regexp": "^4.0.0",
-        "eslint-scope": "^5.1.1",
-        "eslint-utils": "^2.1.0",
-        "eslint-visitor-keys": "^2.0.0",
-        "espree": "^7.3.1",
+        "eslint-scope": "^7.1.1",
+        "eslint-utils": "^3.0.0",
+        "eslint-visitor-keys": "^3.3.0",
+        "espree": "^9.4.0",
         "esquery": "^1.4.0",
         "esutils": "^2.0.2",
         "fast-deep-equal": "^3.1.3",
         "file-entry-cache": "^6.0.1",
-        "functional-red-black-tree": "^1.0.1",
-        "glob-parent": "^5.1.2",
-        "globals": "^13.6.0",
-        "ignore": "^4.0.6",
+        "find-up": "^5.0.0",
+        "glob-parent": "^6.0.1",
+        "globals": "^13.15.0",
+        "globby": "^11.1.0",
+        "grapheme-splitter": "^1.0.4",
+        "ignore": "^5.2.0",
         "import-fresh": "^3.0.0",
         "imurmurhash": "^0.1.4",
         "is-glob": "^4.0.0",
-        "js-yaml": "^3.13.1",
+        "js-sdsl": "^4.1.4",
+        "js-yaml": "^4.1.0",
         "json-stable-stringify-without-jsonify": "^1.0.1",
         "levn": "^0.4.1",
         "lodash.merge": "^4.6.2",
-        "minimatch": "^3.0.4",
+        "minimatch": "^3.1.2",
         "natural-compare": "^1.4.0",
         "optionator": "^0.9.1",
-        "progress": "^2.0.0",
-        "regexpp": "^3.1.0",
-        "semver": "^7.2.1",
-        "strip-ansi": "^6.0.0",
+        "regexpp": "^3.2.0",
+        "strip-ansi": "^6.0.1",
         "strip-json-comments": "^3.1.0",
-        "table": "^6.0.9",
-        "text-table": "^0.2.0",
-        "v8-compile-cache": "^2.0.3"
+        "text-table": "^0.2.0"
       },
       "bin": {
         "eslint": "bin/eslint.js"
       },
       "engines": {
-        "node": "^10.12.0 || >=12.0.0"
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
       },
       "funding": {
         "url": "https://opencollective.com/eslint"
@@ -5285,15 +5329,6 @@
         "eslint": ">=5.16.0"
       }
     },
-    "node_modules/eslint-plugin-node/node_modules/ignore": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
-      "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
-      "dev": true,
-      "engines": {
-        "node": ">= 4"
-      }
-    },
     "node_modules/eslint-plugin-node/node_modules/semver": {
       "version": "6.3.0",
       "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
@@ -5324,6 +5359,19 @@
         }
       }
     },
+    "node_modules/eslint-plugin-sonarjs": {
+      "version": "0.18.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.18.0.tgz",
+      "integrity": "sha512-DJ3osLnt6KFdT5e9ZuIDOjT5A6wUGSLeiJJT03lPgpdD+7CVWlYAw9Goe3bt7SmbFO3Xh89NOCZAuB9XA7bAUQ==",
+      "dev": true,
+      "peer": true,
+      "engines": {
+        "node": ">=14"
+      },
+      "peerDependencies": {
+        "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0"
+      }
+    },
     "node_modules/eslint-rule-docs": {
       "version": "1.1.235",
       "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.235.tgz",
@@ -5331,16 +5379,19 @@
       "dev": true
     },
     "node_modules/eslint-scope": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
-      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
+      "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
       "dev": true,
       "dependencies": {
         "esrecurse": "^4.3.0",
-        "estraverse": "^4.1.1"
+        "estraverse": "^5.2.0"
       },
       "engines": {
-        "node": ">=8.0.0"
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
     "node_modules/eslint-utils": {
@@ -5368,12 +5419,15 @@
       }
     },
     "node_modules/eslint-visitor-keys": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-      "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
+      "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
       "dev": true,
       "engines": {
-        "node": ">=10"
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
     "node_modules/eslint/node_modules/ansi-styles": {
@@ -5391,6 +5445,12 @@
         "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
+    "node_modules/eslint/node_modules/argparse": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+      "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+      "dev": true
+    },
     "node_modules/eslint/node_modules/chalk": {
       "version": "4.1.2",
       "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -5437,40 +5497,64 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/eslint/node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+    "node_modules/eslint/node_modules/eslint-utils": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
+      "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
       "dev": true,
+      "dependencies": {
+        "eslint-visitor-keys": "^2.0.0"
+      },
       "engines": {
-        "node": ">=8"
+        "node": "^10.0.0 || ^12.0.0 || >= 14.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/mysticatea"
+      },
+      "peerDependencies": {
+        "eslint": ">=5"
       }
     },
-    "node_modules/eslint/node_modules/lru-cache": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
-      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+    "node_modules/eslint/node_modules/eslint-utils/node_modules/eslint-visitor-keys": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+      "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/eslint/node_modules/glob-parent": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
       "dev": true,
       "dependencies": {
-        "yallist": "^4.0.0"
+        "is-glob": "^4.0.3"
       },
       "engines": {
-        "node": ">=10"
+        "node": ">=10.13.0"
       }
     },
-    "node_modules/eslint/node_modules/semver": {
-      "version": "7.3.8",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
-      "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+    "node_modules/eslint/node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/eslint/node_modules/js-yaml": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+      "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
       "dev": true,
       "dependencies": {
-        "lru-cache": "^6.0.0"
+        "argparse": "^2.0.1"
       },
       "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
+        "js-yaml": "bin/js-yaml.js"
       }
     },
     "node_modules/eslint/node_modules/supports-color": {
@@ -5486,26 +5570,20 @@
       }
     },
     "node_modules/espree": {
-      "version": "7.3.1",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
-      "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==",
+      "version": "9.5.2",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
+      "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==",
       "dev": true,
       "dependencies": {
-        "acorn": "^7.4.0",
-        "acorn-jsx": "^5.3.1",
-        "eslint-visitor-keys": "^1.3.0"
+        "acorn": "^8.8.0",
+        "acorn-jsx": "^5.3.2",
+        "eslint-visitor-keys": "^3.4.1"
       },
       "engines": {
-        "node": "^10.12.0 || >=12.0.0"
-      }
-    },
-    "node_modules/espree/node_modules/eslint-visitor-keys": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
-      "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
-      "dev": true,
-      "engines": {
-        "node": ">=4"
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
     "node_modules/esprima": {
@@ -5533,15 +5611,6 @@
         "node": ">=0.10"
       }
     },
-    "node_modules/esquery/node_modules/estraverse": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-      "dev": true,
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
     "node_modules/esrecurse": {
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
@@ -5554,7 +5623,7 @@
         "node": ">=4.0"
       }
     },
-    "node_modules/esrecurse/node_modules/estraverse": {
+    "node_modules/estraverse": {
       "version": "5.3.0",
       "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
       "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
@@ -5563,15 +5632,6 @@
         "node": ">=4.0"
       }
     },
-    "node_modules/estraverse": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
-      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
-      "dev": true,
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
     "node_modules/esutils": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
@@ -6008,12 +6068,6 @@
       "integrity": "sha512-ktIR+O6i/4h+j/ZhZJNdzeI4i9lEPeEK6UPR2EVyTVBqOwcU3Za9xYKLH64ZR9HmcROyRrOkizNyjjtWJzDDkQ==",
       "dev": true
     },
-    "node_modules/functional-red-black-tree": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
-      "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
-      "dev": true
-    },
     "node_modules/gensync": {
       "version": "1.0.0-beta.2",
       "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -6106,9 +6160,9 @@
       }
     },
     "node_modules/globals": {
-      "version": "13.17.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz",
-      "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==",
+      "version": "13.20.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
+      "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
       "dev": true,
       "dependencies": {
         "type-fest": "^0.20.2"
@@ -6140,21 +6194,18 @@
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/globby/node_modules/ignore": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
-      "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
-      "dev": true,
-      "engines": {
-        "node": ">= 4"
-      }
-    },
     "node_modules/graceful-fs": {
       "version": "4.2.10",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
       "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
       "dev": true
     },
+    "node_modules/grapheme-splitter": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+      "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
+      "dev": true
+    },
     "node_modules/graphql": {
       "version": "16.6.0",
       "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.6.0.tgz",
@@ -6367,9 +6418,9 @@
       ]
     },
     "node_modules/ignore": {
-      "version": "4.0.6",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
-      "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+      "version": "5.2.4",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+      "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
       "dev": true,
       "engines": {
         "node": ">= 4"
@@ -6783,6 +6834,16 @@
         "node": ">=8"
       }
     },
+    "node_modules/js-sdsl": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz",
+      "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==",
+      "dev": true,
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/js-sdsl"
+      }
+    },
     "node_modules/js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -7334,12 +7395,6 @@
         "lodash._reinterpolate": "^3.0.0"
       }
     },
-    "node_modules/lodash.truncate": {
-      "version": "4.4.2",
-      "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
-      "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
-      "dev": true
-    },
     "node_modules/log-chopper": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/log-chopper/-/log-chopper-1.0.2.tgz",
@@ -8803,15 +8858,6 @@
         "node": ">=8"
       }
     },
-    "node_modules/progress": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
-      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
     "node_modules/protobufjs": {
       "version": "7.2.2",
       "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.2.tgz",
@@ -9192,15 +9238,6 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/require-from-string": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
-      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
-      "dev": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
     "node_modules/require-main-filename": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
@@ -9903,94 +9940,6 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/table": {
-      "version": "6.8.1",
-      "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz",
-      "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==",
-      "dev": true,
-      "dependencies": {
-        "ajv": "^8.0.1",
-        "lodash.truncate": "^4.4.2",
-        "slice-ansi": "^4.0.0",
-        "string-width": "^4.2.3",
-        "strip-ansi": "^6.0.1"
-      },
-      "engines": {
-        "node": ">=10.0.0"
-      }
-    },
-    "node_modules/table/node_modules/ajv": {
-      "version": "8.11.0",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
-      "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
-      "dev": true,
-      "dependencies": {
-        "fast-deep-equal": "^3.1.1",
-        "json-schema-traverse": "^1.0.0",
-        "require-from-string": "^2.0.2",
-        "uri-js": "^4.2.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
-    },
-    "node_modules/table/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dev": true,
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/table/node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dev": true,
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/table/node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "dev": true
-    },
-    "node_modules/table/node_modules/json-schema-traverse": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
-      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-      "dev": true
-    },
-    "node_modules/table/node_modules/slice-ansi": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
-      "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
-      "dev": true,
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "astral-regex": "^2.0.0",
-        "is-fullwidth-code-point": "^3.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/slice-ansi?sponsor=1"
-      }
-    },
     "node_modules/tap": {
       "version": "16.3.4",
       "resolved": "https://registry.npmjs.org/tap/-/tap-16.3.4.tgz",
@@ -12352,12 +12301,6 @@
         "uuid": "dist/bin/uuid"
       }
     },
-    "node_modules/v8-compile-cache": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
-      "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
-      "dev": true
-    },
     "node_modules/v8-to-istanbul": {
       "version": "9.0.1",
       "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
@@ -13166,20 +13109,37 @@
       }
     },
     "@eslint/eslintrc": {
-      "version": "0.4.3",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
-      "integrity": "sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==",
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz",
+      "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==",
       "dev": true,
       "requires": {
         "ajv": "^6.12.4",
-        "debug": "^4.1.1",
-        "espree": "^7.3.0",
-        "globals": "^13.9.0",
-        "ignore": "^4.0.6",
+        "debug": "^4.3.2",
+        "espree": "^9.4.0",
+        "globals": "^13.19.0",
+        "ignore": "^5.2.0",
         "import-fresh": "^3.2.1",
-        "js-yaml": "^3.13.1",
-        "minimatch": "^3.0.4",
+        "js-yaml": "^4.1.0",
+        "minimatch": "^3.1.2",
         "strip-json-comments": "^3.1.1"
+      },
+      "dependencies": {
+        "argparse": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+          "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+          "dev": true
+        },
+        "js-yaml": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+          "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+          "dev": true,
+          "requires": {
+            "argparse": "^2.0.1"
+          }
+        }
       }
     },
     "@graphql-tools/merge": {
@@ -13249,16 +13209,28 @@
       }
     },
     "@humanwhocodes/config-array": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz",
-      "integrity": "sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==",
+      "version": "0.10.7",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.7.tgz",
+      "integrity": "sha512-MDl6D6sBsaV452/QSdX+4CXIjZhIcI0PELsxUjk4U828yd58vk3bTIvk/6w5FY+4hIy9sLW0sfrV7K7Kc++j/w==",
       "dev": true,
       "requires": {
-        "@humanwhocodes/object-schema": "^1.2.0",
+        "@humanwhocodes/object-schema": "^1.2.1",
         "debug": "^4.1.1",
         "minimatch": "^3.0.4"
       }
     },
+    "@humanwhocodes/gitignore-to-minimatch": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz",
+      "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==",
+      "dev": true
+    },
+    "@humanwhocodes/module-importer": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+      "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+      "dev": true
+    },
     "@humanwhocodes/object-schema": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
@@ -13381,9 +13353,9 @@
       "requires": {}
     },
     "@newrelic/eslint-config": {
-      "version": "0.0.2",
-      "resolved": "https://registry.npmjs.org/@newrelic/eslint-config/-/eslint-config-0.0.2.tgz",
-      "integrity": "sha512-fMn9e4hShInAuZxYg5dV/qmJ48Qj6JE8eQqE6XyPiDsTriEt6A5H88PFQ50V/xmWGrSxnvmmCnXzdWgxUDaqbg==",
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/@newrelic/eslint-config/-/eslint-config-0.3.0.tgz",
+      "integrity": "sha512-woQshi/SB6uGrXPWb4w9G98HkQRCb9nJWfJ9/tlj0WkVOqU4Bsn4VZvEI63Vy5y1cTphajr4u6kjOzIk0kC6DA==",
       "dev": true,
       "requires": {}
     },
@@ -15394,9 +15366,9 @@
       }
     },
     "acorn": {
-      "version": "7.4.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
-      "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
+      "version": "8.8.2",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
+      "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
       "dev": true
     },
     "acorn-jsx": {
@@ -16526,51 +16498,50 @@
       "dev": true
     },
     "eslint": {
-      "version": "7.32.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz",
-      "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==",
+      "version": "8.24.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz",
+      "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==",
       "dev": true,
       "requires": {
-        "@babel/code-frame": "7.12.11",
-        "@eslint/eslintrc": "^0.4.3",
-        "@humanwhocodes/config-array": "^0.5.0",
+        "@eslint/eslintrc": "^1.3.2",
+        "@humanwhocodes/config-array": "^0.10.5",
+        "@humanwhocodes/gitignore-to-minimatch": "^1.0.2",
+        "@humanwhocodes/module-importer": "^1.0.1",
         "ajv": "^6.10.0",
         "chalk": "^4.0.0",
         "cross-spawn": "^7.0.2",
-        "debug": "^4.0.1",
+        "debug": "^4.3.2",
         "doctrine": "^3.0.0",
-        "enquirer": "^2.3.5",
         "escape-string-regexp": "^4.0.0",
-        "eslint-scope": "^5.1.1",
-        "eslint-utils": "^2.1.0",
-        "eslint-visitor-keys": "^2.0.0",
-        "espree": "^7.3.1",
+        "eslint-scope": "^7.1.1",
+        "eslint-utils": "^3.0.0",
+        "eslint-visitor-keys": "^3.3.0",
+        "espree": "^9.4.0",
         "esquery": "^1.4.0",
         "esutils": "^2.0.2",
         "fast-deep-equal": "^3.1.3",
         "file-entry-cache": "^6.0.1",
-        "functional-red-black-tree": "^1.0.1",
-        "glob-parent": "^5.1.2",
-        "globals": "^13.6.0",
-        "ignore": "^4.0.6",
+        "find-up": "^5.0.0",
+        "glob-parent": "^6.0.1",
+        "globals": "^13.15.0",
+        "globby": "^11.1.0",
+        "grapheme-splitter": "^1.0.4",
+        "ignore": "^5.2.0",
         "import-fresh": "^3.0.0",
         "imurmurhash": "^0.1.4",
         "is-glob": "^4.0.0",
-        "js-yaml": "^3.13.1",
+        "js-sdsl": "^4.1.4",
+        "js-yaml": "^4.1.0",
         "json-stable-stringify-without-jsonify": "^1.0.1",
         "levn": "^0.4.1",
         "lodash.merge": "^4.6.2",
-        "minimatch": "^3.0.4",
+        "minimatch": "^3.1.2",
         "natural-compare": "^1.4.0",
         "optionator": "^0.9.1",
-        "progress": "^2.0.0",
-        "regexpp": "^3.1.0",
-        "semver": "^7.2.1",
-        "strip-ansi": "^6.0.0",
+        "regexpp": "^3.2.0",
+        "strip-ansi": "^6.0.1",
         "strip-json-comments": "^3.1.0",
-        "table": "^6.0.9",
-        "text-table": "^0.2.0",
-        "v8-compile-cache": "^2.0.3"
+        "text-table": "^0.2.0"
       },
       "dependencies": {
         "ansi-styles": {
@@ -16582,6 +16553,12 @@
             "color-convert": "^2.0.1"
           }
         },
+        "argparse": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+          "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+          "dev": true
+        },
         "chalk": {
           "version": "4.1.2",
           "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -16613,28 +16590,45 @@
           "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
           "dev": true
         },
+        "eslint-utils": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz",
+          "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==",
+          "dev": true,
+          "requires": {
+            "eslint-visitor-keys": "^2.0.0"
+          },
+          "dependencies": {
+            "eslint-visitor-keys": {
+              "version": "2.1.0",
+              "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
+              "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+              "dev": true
+            }
+          }
+        },
+        "glob-parent": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+          "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+          "dev": true,
+          "requires": {
+            "is-glob": "^4.0.3"
+          }
+        },
         "has-flag": {
           "version": "4.0.0",
           "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
           "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
           "dev": true
         },
-        "lru-cache": {
-          "version": "6.0.0",
-          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
-          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
-          "dev": true,
-          "requires": {
-            "yallist": "^4.0.0"
-          }
-        },
-        "semver": {
-          "version": "7.3.8",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
-          "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+        "js-yaml": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+          "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
           "dev": true,
           "requires": {
-            "lru-cache": "^6.0.0"
+            "argparse": "^2.0.1"
           }
         },
         "supports-color": {
@@ -16778,12 +16772,6 @@
         "semver": "^6.1.0"
       },
       "dependencies": {
-        "ignore": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
-          "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
-          "dev": true
-        },
         "semver": {
           "version": "6.3.0",
           "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
@@ -16801,6 +16789,14 @@
         "prettier-linter-helpers": "^1.0.0"
       }
     },
+    "eslint-plugin-sonarjs": {
+      "version": "0.18.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.18.0.tgz",
+      "integrity": "sha512-DJ3osLnt6KFdT5e9ZuIDOjT5A6wUGSLeiJJT03lPgpdD+7CVWlYAw9Goe3bt7SmbFO3Xh89NOCZAuB9XA7bAUQ==",
+      "dev": true,
+      "peer": true,
+      "requires": {}
+    },
     "eslint-rule-docs": {
       "version": "1.1.235",
       "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.235.tgz",
@@ -16808,13 +16804,13 @@
       "dev": true
     },
     "eslint-scope": {
-      "version": "5.1.1",
-      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
-      "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
+      "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
       "dev": true,
       "requires": {
         "esrecurse": "^4.3.0",
-        "estraverse": "^4.1.1"
+        "estraverse": "^5.2.0"
       }
     },
     "eslint-utils": {
@@ -16835,28 +16831,20 @@
       }
     },
     "eslint-visitor-keys": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz",
-      "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==",
+      "version": "3.4.1",
+      "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
+      "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
       "dev": true
     },
     "espree": {
-      "version": "7.3.1",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
-      "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==",
+      "version": "9.5.2",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz",
+      "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==",
       "dev": true,
       "requires": {
-        "acorn": "^7.4.0",
-        "acorn-jsx": "^5.3.1",
-        "eslint-visitor-keys": "^1.3.0"
-      },
-      "dependencies": {
-        "eslint-visitor-keys": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz",
-          "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==",
-          "dev": true
-        }
+        "acorn": "^8.8.0",
+        "acorn-jsx": "^5.3.2",
+        "eslint-visitor-keys": "^3.4.1"
       }
     },
     "esprima": {
@@ -16872,14 +16860,6 @@
       "dev": true,
       "requires": {
         "estraverse": "^5.1.0"
-      },
-      "dependencies": {
-        "estraverse": {
-          "version": "5.3.0",
-          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-          "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-          "dev": true
-        }
       }
     },
     "esrecurse": {
@@ -16889,20 +16869,12 @@
       "dev": true,
       "requires": {
         "estraverse": "^5.2.0"
-      },
-      "dependencies": {
-        "estraverse": {
-          "version": "5.3.0",
-          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-          "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-          "dev": true
-        }
       }
     },
     "estraverse": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
-      "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
       "dev": true
     },
     "esutils": {
@@ -17255,12 +17227,6 @@
       "integrity": "sha512-ktIR+O6i/4h+j/ZhZJNdzeI4i9lEPeEK6UPR2EVyTVBqOwcU3Za9xYKLH64ZR9HmcROyRrOkizNyjjtWJzDDkQ==",
       "dev": true
     },
-    "functional-red-black-tree": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
-      "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==",
-      "dev": true
-    },
     "gensync": {
       "version": "1.0.0-beta.2",
       "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
@@ -17326,9 +17292,9 @@
       }
     },
     "globals": {
-      "version": "13.17.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz",
-      "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==",
+      "version": "13.20.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
+      "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
       "dev": true,
       "requires": {
         "type-fest": "^0.20.2"
@@ -17346,14 +17312,6 @@
         "ignore": "^5.2.0",
         "merge2": "^1.4.1",
         "slash": "^3.0.0"
-      },
-      "dependencies": {
-        "ignore": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
-          "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
-          "dev": true
-        }
       }
     },
     "graceful-fs": {
@@ -17362,6 +17320,12 @@
       "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
       "dev": true
     },
+    "grapheme-splitter": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+      "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
+      "dev": true
+    },
     "graphql": {
       "version": "16.6.0",
       "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.6.0.tgz",
@@ -17505,9 +17469,9 @@
       "dev": true
     },
     "ignore": {
-      "version": "4.0.6",
-      "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
-      "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+      "version": "5.2.4",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+      "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
       "dev": true
     },
     "import-fresh": {
@@ -17810,6 +17774,12 @@
         "cliui": "^7.0.4"
       }
     },
+    "js-sdsl": {
+      "version": "4.4.0",
+      "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.4.0.tgz",
+      "integrity": "sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==",
+      "dev": true
+    },
     "js-tokens": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -18248,12 +18218,6 @@
         "lodash._reinterpolate": "^3.0.0"
       }
     },
-    "lodash.truncate": {
-      "version": "4.4.2",
-      "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz",
-      "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==",
-      "dev": true
-    },
     "log-chopper": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/log-chopper/-/log-chopper-1.0.2.tgz",
@@ -19363,12 +19327,6 @@
         "fromentries": "^1.2.0"
       }
     },
-    "progress": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
-      "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
-      "dev": true
-    },
     "protobufjs": {
       "version": "7.2.2",
       "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.2.tgz",
@@ -19661,12 +19619,6 @@
       "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
       "dev": true
     },
-    "require-from-string": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
-      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
-      "dev": true
-    },
     "require-main-filename": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
@@ -20214,74 +20166,6 @@
       "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
       "dev": true
     },
-    "table": {
-      "version": "6.8.1",
-      "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz",
-      "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==",
-      "dev": true,
-      "requires": {
-        "ajv": "^8.0.1",
-        "lodash.truncate": "^4.4.2",
-        "slice-ansi": "^4.0.0",
-        "string-width": "^4.2.3",
-        "strip-ansi": "^6.0.1"
-      },
-      "dependencies": {
-        "ajv": {
-          "version": "8.11.0",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz",
-          "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==",
-          "dev": true,
-          "requires": {
-            "fast-deep-equal": "^3.1.1",
-            "json-schema-traverse": "^1.0.0",
-            "require-from-string": "^2.0.2",
-            "uri-js": "^4.2.2"
-          }
-        },
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-          "dev": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-          "dev": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-          "dev": true
-        },
-        "json-schema-traverse": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
-          "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-          "dev": true
-        },
-        "slice-ansi": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
-          "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^4.0.0",
-            "astral-regex": "^2.0.0",
-            "is-fullwidth-code-point": "^3.0.0"
-          }
-        }
-      }
-    },
     "tap": {
       "version": "16.3.4",
       "resolved": "https://registry.npmjs.org/tap/-/tap-16.3.4.tgz",
@@ -21864,12 +21748,6 @@
       "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==",
       "dev": true
     },
-    "v8-compile-cache": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz",
-      "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==",
-      "dev": true
-    },
     "v8-to-istanbul": {
       "version": "9.0.1",
       "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz",
diff --git a/package.json b/package.json
index f4edfdd..f22a771 100644
--- a/package.json
+++ b/package.json
@@ -40,12 +40,12 @@
   },
   "devDependencies": {
     "@apollo/server": "^4.1.1",
-    "@newrelic/eslint-config": "^0.0.2",
+    "@newrelic/eslint-config": "^0.3.0",
     "@newrelic/newrelic-oss-cli": "^0.1.2",
     "@newrelic/test-utilities": "^7.3.1",
     "apollo-server": "^3.11.1",
     "c8": "^7.12.0",
-    "eslint": "^7.32.0",
+    "eslint": "^8.24.0",
     "eslint-config-prettier": "^8.3.0",
     "eslint-plugin-header": "^3.1.1",
     "eslint-plugin-node": "^11.1.0",


Test patch:
diff --git a/tests/agent-testing.js b/tests/agent-testing.js
index 067bda0..b602d2f 100644
--- a/tests/agent-testing.js
+++ b/tests/agent-testing.js
@@ -11,24 +11,20 @@
 // when extracted to a single location in the external module.
 
 function getErrorTraces(agent) {
-  const errorTraces = agent.errors.traceAggregator.errors
-  return errorTraces
+  return agent.errors.traceAggregator.errors
 }
 
 function getSpanEvents(agent) {
-  const spans = agent.spanEventAggregator.getEvents()
-  return spans
+  return agent.spanEventAggregator.getEvents()
 }
 
 function findSpanById(agent, spanId) {
   const spans = getSpanEvents(agent)
 
-  const matchingSpan = spans.find((value) => {
+  return spans.find((value) => {
     const { intrinsics } = value
     return intrinsics.guid === spanId
   })
-
-  return matchingSpan
 }
 
 function findSegmentByName(root, name) {
diff --git a/tests/create-apollo-server-setup.js b/tests/create-apollo-server-setup.js
index 03eebea..f4c1a30 100644
--- a/tests/create-apollo-server-setup.js
+++ b/tests/create-apollo-server-setup.js
@@ -39,9 +39,9 @@ function setupApolloServerTests(loadApolloServer, testDir, options, agentConfig)
       const createPlugin = require('../lib/create-plugin')
       const nrApi = helper.getAgentApi()
 
-      const startingPlugins = initializePlugins(nrApi.shim, options.startingPlugins)
+      const startingPlugins = initializePlugins(nrApi, options.startingPlugins)
 
-      const instrumentationPlugin = createPlugin(nrApi.shim, pluginConfig)
+      const instrumentationPlugin = createPlugin(nrApi, pluginConfig)
 
       // Do after instrumentation to ensure express isn't loaded too soon.
       apolloServerPkg = loadApolloServer()
@@ -89,15 +89,13 @@ function setupApolloServerTests(loadApolloServer, testDir, options, agentConfig)
 
 function initializePlugins(instrumentationApi, plugins) {
   plugins = plugins || []
-  const initializedPlugins = plugins.map((plugin) => {
+  return plugins.map((plugin) => {
     if (typeof plugin === 'function') {
       return plugin(instrumentationApi)
     }
 
     return plugin
   })
-
-  return initializedPlugins
 }
 
 module.exports = createApolloServerSetup
diff --git a/tests/data-definitions.js b/tests/data-definitions.js
index b03adde..90be52a 100644
--- a/tests/data-definitions.js
+++ b/tests/data-definitions.js
@@ -71,7 +71,7 @@ const collection = [
 ]
 
 function getTypeDefs(gql) {
-  const typeDefs = gql`
+  return gql`
     union SearchResult = Book | Magazine
 
     type Library {
@@ -121,7 +121,6 @@ function getTypeDefs(gql) {
       addToCollection(title: String!): Item!
     }
   `
-  return typeDefs
 }
 
 const resolvers = {
@@ -141,14 +140,12 @@ const resolvers = {
       return libraries
     },
     library: (_, { branch }) => {
-      const promise = new Promise((resolve) => {
+      return new Promise((resolve) => {
         setTimeout(() => {
           const filtered = libraries.find((library) => library.branch === branch)
           resolve(filtered)
         }, 0)
       })
-
-      return promise
     },
     searchCollection: (_, { title }) => {
       const item = collection.filter((coll) => coll.title.includes(title))
@@ -162,8 +159,7 @@ const resolvers = {
           resolve(name)
         }, 1)
       })
-      const result = await promise
-      return result
+      return await promise
     },
     addToCollection: async (_, { title }) => {
       return await new Promise((resolve) => {
diff --git a/tests/integration/plugin-state-loss-tester.js b/tests/integration/plugin-state-loss-tester.js
index 0789ccd..162db98 100644
--- a/tests/integration/plugin-state-loss-tester.js
+++ b/tests/integration/plugin-state-loss-tester.js
@@ -5,7 +5,8 @@
 
 'use strict'
 
-function createStateLossPlugin(stateLossConfig, instrumentationApi) {
+function createStateLossPlugin(stateLossConfig, api) {
+  const instrumentationApi = api.shim
   return {
     requestDidStart() {
       triggerStateLoss(stateLossConfig.onRequestDidStart)
diff --git a/tests/test-client.js b/tests/test-client.js
index 6033655..20905f8 100644
--- a/tests/test-client.js
+++ b/tests/test-client.js
@@ -44,7 +44,8 @@ function makeRequest(url, postData, callback) {
   const options = {
     method: 'GET',
     headers: {
-      'Content-Type': 'application/json'
+      'Content-Type': 'application/json',
+      'client-name': 'ApolloTestClient'
     }
   }
 
diff --git a/tests/unit/create-plugin.test.js b/tests/unit/create-plugin.test.js
index 31fd080..907d0b6 100644
--- a/tests/unit/create-plugin.test.js
+++ b/tests/unit/create-plugin.test.js
@@ -22,22 +22,26 @@ tap.test('createPlugin edge cases', (t) => {
     }
 
     instrumentationApi = {
-      logger: {
-        child: sinon
-          .stub()
-          .returns({ info: sinon.stub(), debug: sinon.stub(), trace: sinon.stub() })
-      },
-      agent: {
-        metrics: {
-          getOrCreateMetric: sinon.stub().returns({ incrementCallCount: sinon.stub() })
-        }
+      shim: {
+        logger: {
+          child: sinon
+            .stub()
+            .returns({ info: sinon.stub(), debug: sinon.stub(), trace: sinon.stub() })
+        },
+        agent: {
+          metrics: {
+            getOrCreateMetric: sinon.stub().returns({ incrementCallCount: sinon.stub() })
+          }
+        },
+        getActiveSegment: sinon.stub().returns({}),
+        createSegment: sinon.stub().callsFake((name) => {
+          operationSegment.name = name
+          return operationSegment
+        }),
+        setActiveSegment: sinon.stub(),
+        isFunction: () => false
       },
-      getActiveSegment: sinon.stub().returns({}),
-      createSegment: sinon.stub().callsFake((name) => {
-        operationSegment.name = name
-        return operationSegment
-      }),
-      setActiveSegment: sinon.stub()
+      addCustomAttributes: sinon.stub()
     }
   })
 
diff --git a/tests/versioned/apollo-federation/federated-data-definitions.js b/tests/versioned/apollo-federation/federated-data-definitions.js
index 324381a..4093056 100644
--- a/tests/versioned/apollo-federation/federated-data-definitions.js
+++ b/tests/versioned/apollo-federation/federated-data-definitions.js
@@ -42,7 +42,7 @@ const libraries = [
 ]
 
 function _getLibraryTypeDef(gql) {
-  const typeDefs = gql`
+  return gql`
     type Library @key(fields: "id") {
       id: ID!
       branch: String
@@ -53,13 +53,11 @@ function _getLibraryTypeDef(gql) {
       libraries: [Library]
     }
   `
-
-  return typeDefs
 }
 
 // https://www.apollographql.com/docs/federation/api/apollo-subgraph/#__resolvereference
 function _getLibraryResolvers() {
-  const resolvers = {
+  return {
     Library: {
       __resolveReference(reference) {
         return libraries.find((library) => library.id === reference.id)
@@ -74,8 +72,6 @@ function _getLibraryResolvers() {
       }
     }
   }
-
-  return resolvers
 }
 
 const books = [
@@ -106,7 +102,7 @@ const books = [
 ]
 
 function _getBookTypeDef(gql) {
-  const typeDefs = gql`
+  return gql`
     type Book {
       isbn: ID!
       title: String
@@ -124,11 +120,10 @@ function _getBookTypeDef(gql) {
       books: [Book]
     }
   `
-  return typeDefs
 }
 
 function _getBookResolvers() {
-  const resolvers = {
+  return {
     Book: {
       branch(parent) {
         return { __typename: 'Library', id: parent.branch }
@@ -148,8 +143,6 @@ function _getBookResolvers() {
       }
     }
   }
-
-  return resolvers
 }
 
 const magazines = [
@@ -166,7 +159,7 @@ const magazines = [
 ]
 
 function _getMagazineTypeDef(gql) {
-  const typeDefs = gql`
+  return gql`
     type Magazine {
       issue: ID!
       title: String
@@ -183,12 +176,10 @@ function _getMagazineTypeDef(gql) {
       magazines: [Magazine]
     }
   `
-
-  return typeDefs
 }
 
 function _getMagazineResolvers() {
-  const resolvers = {
+  return {
     Magazine: {
       branch(parent) {
         return { __typename: 'Library', id: parent.branch }
@@ -208,38 +199,30 @@ function _getMagazineResolvers() {
       }
     }
   }
-
-  return resolvers
 }
 
 function getLibraryConfiguration(gql) {
-  const config = {
+  return {
     name: 'Library',
     typeDefs: _getLibraryTypeDef(gql),
     resolvers: _getLibraryResolvers()
   }
-
-  return config
 }
 
 function getBookConfiguration(gql) {
-  const config = {
+  return {
     name: 'Book',
     typeDefs: _getBookTypeDef(gql),
     resolvers: _getBookResolvers()
   }
-
-  return config
 }
 
 function getMagazineConfiguration(gql) {
-  const config = {
+  return {
     name: 'Magazine',
     typeDefs: _getMagazineTypeDef(gql),
     resolvers: _getMagazineResolvers()
   }
-
-  return config
 }
 
 module.exports = {
diff --git a/tests/versioned/apollo-federation/federated-gateway-server-setup.js b/tests/versioned/apollo-federation/federated-gateway-server-setup.js
index de16bc6..535955f 100644
--- a/tests/versioned/apollo-federation/federated-gateway-server-setup.js
+++ b/tests/versioned/apollo-federation/federated-gateway-server-setup.js
@@ -34,14 +34,14 @@ function setupFederatedGatewayServerTests(options, agentConfig) {
       const createPlugin = require('../../../lib/create-plugin')
       const nrApi = helper.getAgentApi()
 
-      const startingPlugins = initializePlugins(nrApi.shim, options.startingPlugins)
+      const startingPlugins = initializePlugins(nrApi, options.startingPlugins)
 
-      const instrumentationPlugin = createPlugin(nrApi.shim, pluginConfig)
+      const instrumentationPlugin = createPlugin(nrApi, pluginConfig)
 
       // Do after instrumentation to ensure express isn't loaded too soon.
       const apollo = require('apollo-server')
 
-      let subGraphPlugins = []
+      const subGraphPlugins = []
 
       if (options.instrumentSubGraphs) {
         subGraphPlugins.push(instrumentationPlugin)
@@ -175,15 +175,13 @@ function createIgnoreTransactionPlugin(nrApi) {
 
 function initializePlugins(instrumentationApi, plugins) {
   plugins = plugins || []
-  const initializedPlugins = plugins.map((plugin) => {
+  return plugins.map((plugin) => {
     if (typeof plugin === 'function') {
       return plugin(instrumentationApi)
     }
 
     return plugin
   })
-
-  return initializedPlugins
 }
 
 module.exports = {
diff --git a/tests/versioned/apollo-federation/segments.test.js b/tests/versioned/apollo-federation/segments.test.js
index f56127d..11451af 100644
--- a/tests/versioned/apollo-federation/segments.test.js
+++ b/tests/versioned/apollo-federation/segments.test.js
@@ -177,7 +177,5 @@ function createFederatedSegmentsTests(t, frameworkName) {
 
 function formatExternalSegment(url) {
   const hostAndPort = url.replace('http://', '')
-  const name = `${EXTERNAL_PREFIX}/${hostAndPort}`
-
-  return name
+  return `${EXTERNAL_PREFIX}/${hostAndPort}`
 }
diff --git a/tests/versioned/apollo-federation/service-definition-and-healthcheck-filtering.test.js b/tests/versioned/apollo-federation/service-definition-and-healthcheck-filtering.test.js
index 614f65d..3d19c24 100644
--- a/tests/versioned/apollo-federation/service-definition-and-healthcheck-filtering.test.js
+++ b/tests/versioned/apollo-federation/service-definition-and-healthcheck-filtering.test.js
@@ -34,7 +34,7 @@ tap.test(
     t.test('Should ignore Service Definiion query by default', async (t) => {
       // load default instrumentation. express being critical
       helper = utils.TestAgent.makeFullyInstrumented(agentConfig)
-      let ignore = true
+      const ignore = true
 
       helper.agent.on('transactionFinished', (transaction) => {
         t.equal(transaction.ignore, ignore, `should set transaction.ignore to ${ignore}`)
@@ -44,7 +44,7 @@ tap.test(
 
       const nrApi = helper.getAgentApi()
 
-      const instrumentationPlugin = createPlugin(nrApi.shim, pluginConfig)
+      const instrumentationPlugin = createPlugin(nrApi, pluginConfig)
       const plugins = [instrumentationPlugin]
 
       // Do after instrumentation to ensure express isn't loaded too soon.
@@ -69,7 +69,7 @@ tap.test(
       async (t) => {
         // load default instrumentation. express being critical
         helper = utils.TestAgent.makeFullyInstrumented(agentConfig)
-        let ignore = false
+        const ignore = false
 
         helper.agent.on('transactionFinished', (transaction) => {
           t.equal(transaction.ignore, ignore, `should set transaction.ignore to ${ignore}`)
@@ -81,7 +81,7 @@ tap.test(
 
         const nrApi = helper.getAgentApi()
 
-        const instrumentationPlugin = createPlugin(nrApi.shim, pluginConfig)
+        const instrumentationPlugin = createPlugin(nrApi, pluginConfig)
         const plugins = [instrumentationPlugin]
 
         // Do after instrumentation to ensure express isn't loaded too soon.
@@ -104,7 +104,7 @@ tap.test(
     t.test('Should ignore Health Check query by default', async (t) => {
       // load default instrumentation. express being critical
       helper = utils.TestAgent.makeFullyInstrumented(agentConfig)
-      let ignore = true
+      const ignore = true
 
       helper.agent.on('transactionFinished', (transaction) => {
         if (transaction.name.includes('__ApolloServiceHealthCheck__')) {
@@ -116,7 +116,7 @@ tap.test(
 
       const nrApi = helper.getAgentApi()
 
-      const instrumentationPlugin = createPlugin(nrApi.shim, pluginConfig)
+      const instrumentationPlugin = createPlugin(nrApi, pluginConfig)
       const plugins = [instrumentationPlugin]
 
       // Do after instrumentation to ensure express isn't loaded too soon.
@@ -143,7 +143,7 @@ tap.test(
       async (t) => {
         // load default instrumentation. express being critical
         helper = utils.TestAgent.makeFullyInstrumented(agentConfig)
-        let ignore = false
+        const ignore = false
 
         helper.agent.on('transactionFinished', (transaction) => {
           if (transaction.name.includes('__ApolloServiceHealthCheck__')) {
@@ -157,7 +157,7 @@ tap.test(
 
         const nrApi = helper.getAgentApi()
 
-        const instrumentationPlugin = createPlugin(nrApi.shim, pluginConfig)
+        const instrumentationPlugin = createPlugin(nrApi, pluginConfig)
         const plugins = [instrumentationPlugin]
 
         // Do after instrumentation to ensure express isn't loaded too soon.
diff --git a/tests/versioned/apollo-federation/sub-graph-transactions.test.js b/tests/versioned/apollo-federation/sub-graph-transactions.test.js
index 33cf091..c7a2f0b 100644
--- a/tests/versioned/apollo-federation/sub-graph-transactions.test.js
+++ b/tests/versioned/apollo-federation/sub-graph-transactions.test.js
@@ -68,7 +68,7 @@ function createFederatedSegmentsTests(t) {
       }
     }`
 
-    let transactions = []
+    const transactions = []
     const expectedTransactions = [
       /WebTransaction\/Expressjs\/POST\/\/query\/SubGraphs__Library__[\d]+\/libraries.branch/,
       /WebTransaction\/Expressjs\/POST\/\/query\/SubGraphs__Book__[\d]+\/_entities<Library>.booksInStock/,
@@ -128,7 +128,7 @@ function createFederatedSegmentsTests(t) {
       }
     }`
 
-    let transactions = []
+    const transactions = []
     const expectedPath = 'libraries.branch'
     const expectedTransaction = `WebTransaction/Expressjs/POST//query/SubGraphs__Library__0/${expectedPath}`
 
diff --git a/tests/versioned/apollo-server-express/apollo-server-express-setup.js b/tests/versioned/apollo-server-express/apollo-server-express-setup.js
index 8fe8120..b0b01cd 100644
--- a/tests/versioned/apollo-server-express/apollo-server-express-setup.js
+++ b/tests/versioned/apollo-server-express/apollo-server-express-setup.js
@@ -34,7 +34,7 @@ function setupApolloServerExpressTests({ suiteName, createTests, pluginConfig },
       const nrApi = helper.getAgentApi()
 
       // TODO: eventually use proper function for instrumenting and not .shim
-      const plugin = createPlugin(nrApi.shim, pluginConfig)
+      const plugin = createPlugin(nrApi, pluginConfig)
 
       const express = require('express')
 
diff --git a/tests/versioned/apollo-server-fastify/apollo-server-fastify-setup.js b/tests/versioned/apollo-server-fastify/apollo-server-fastify-setup.js
index ddaecb8..2ba3b27 100644
--- a/tests/versioned/apollo-server-fastify/apollo-server-fastify-setup.js
+++ b/tests/versioned/apollo-server-fastify/apollo-server-fastify-setup.js
@@ -34,7 +34,7 @@ function setupApolloServerFastifyTests({ suiteName, createTests, pluginConfig },
       app = require('fastify')()
 
       // TODO: eventually use proper function for instrumenting and not .shim
-      const plugin = createPlugin(nrApi.shim, pluginConfig)
+      const plugin = createPlugin(nrApi, pluginConfig)
 
       // Do after instrumentation to ensure hapi isn't loaded too soon.
       const fastifyServerPkg = require('apollo-server-fastify')
diff --git a/tests/versioned/apollo-server-hapi/apollo-server-hapi-setup.js b/tests/versioned/apollo-server-hapi/apollo-server-hapi-setup.js
index 7907db3..0697b9f 100644
--- a/tests/versioned/apollo-server-hapi/apollo-server-hapi-setup.js
+++ b/tests/versioned/apollo-server-hapi/apollo-server-hapi-setup.js
@@ -32,7 +32,7 @@ function setupApolloServerHapiTests({ suiteName, createTests, pluginConfig }, co
       const nrApi = helper.getAgentApi()
 
       // TODO: eventually use proper function for instrumenting and not .shim
-      const plugin = createPlugin(nrApi.shim, pluginConfig)
+      const plugin = createPlugin(nrApi, pluginConfig)
 
       const Hapi = require('@hapi/hapi')
 
diff --git a/tests/versioned/apollo-server-koa/apollo-server-koa-setup.js b/tests/versioned/apollo-server-koa/apollo-server-koa-setup.js
index dccb1b1..1e29122 100644
--- a/tests/versioned/apollo-server-koa/apollo-server-koa-setup.js
+++ b/tests/versioned/apollo-server-koa/apollo-server-koa-setup.js
@@ -37,7 +37,7 @@ function setupApolloServerKoaTests({ suiteName, createTests, pluginConfig }, con
       app = new Koa()
 
       // TODO: eventually use proper function for instrumenting and not .shim
-      const plugin = createPlugin(nrApi.shim, pluginConfig)
+      const plugin = createPlugin(nrApi, pluginConfig)
 
       const graphqlPath = '/gql'
 
diff --git a/tests/versioned/apollo-server-lambda/apollo-server-lambda-setup.js b/tests/versioned/apollo-server-lambda/apollo-server-lambda-setup.js
index 1b1744e..c7b2a77 100644
--- a/tests/versioned/apollo-server-lambda/apollo-server-lambda-setup.js
+++ b/tests/versioned/apollo-server-lambda/apollo-server-lambda-setup.js
@@ -48,7 +48,7 @@ function setupApolloServerLambdaTests({ suiteName, createTests, pluginConfig },
       const nrApi = helper.getAgentApi()
 
       // TODO: eventually use proper function for instrumenting and not .shim
-      const plugin = createPlugin(nrApi.shim, pluginConfig)
+      const plugin = createPlugin(nrApi, pluginConfig)
 
       ;(stubContext = {
         done: () => {},
diff --git a/tests/versioned/apollo-server-lambda/lambda-test-utils.js b/tests/versioned/apollo-server-lambda/lambda-test-utils.js
index 480e284..b716b6e 100644
--- a/tests/versioned/apollo-server-lambda/lambda-test-utils.js
+++ b/tests/versioned/apollo-server-lambda/lambda-test-utils.js
@@ -206,7 +206,7 @@ utils.executeQueryAssertErrors = async function executeQueryAssertErrors({
  * @param {string} query to execute
  */
 utils.createApiEvent = function createApiEvent(query) {
-  const apiGatewayProxyEvent = {
+  return {
     path: '/graphql',
     headers: {
       'Accept': 'application/json',
@@ -256,6 +256,4 @@ utils.createApiEvent = function createApiEvent(query) {
     httpMethod: 'POST',
     body: query
   }
-
-  return apiGatewayProxyEvent
 }
diff --git a/tests/versioned/apollo-server-lambda/query-obfuscation-tests.js b/tests/versioned/apollo-server-lambda/query-obfuscation-tests.js
index b7ff366..12c3d7d 100644
--- a/tests/versioned/apollo-server-lambda/query-obfuscation-tests.js
+++ b/tests/versioned/apollo-server-lambda/query-obfuscation-tests.js
@@ -8,11 +8,13 @@
 const { executeQueryAssertResult } = require('./lambda-test-utils')
 const { findSegmentByName } = require('../../agent-testing')
 
+const SPAN_DESTINATION = 0x10
 const SEGMENT_DESTINATION = 0x20
 
 const QUERY_ATTRIBUTE_NAME = 'graphql.operation.query'
 
 const OPERATION_PREFIX = 'GraphQL/operation/ApolloServer'
+const RESOLVE_PREFIX = 'GraphQL/resolve/ApolloServer'
 
 const { setupApolloServerLambdaTests } = require('./apollo-server-lambda-setup')
 
@@ -20,7 +22,12 @@ setupApolloServerLambdaTests({
   suiteName: 'lambda query obfuscation',
   createTests: createQueryObfuscationTests,
   pluginConfig: {
-    captureScalars: true
+    captureScalars: true,
+    customResolverAttributes({ context }) {
+      return {
+        stage: context.event.requestContext.stage
+      }
+    }
   }
 })
 
@@ -46,6 +53,17 @@ function createQueryObfuscationTests(t) {
       const operationAttributes = operationSegment.attributes.get(SEGMENT_DESTINATION)
 
       t.ok(operationAttributes[QUERY_ATTRIBUTE_NAME].includes('library(***)') > 0)
+
+      const resolverName = `${RESOLVE_PREFIX}/library`
+      const resolverSegment = findSegmentByName(transaction.trace.root, resolverName)
+      const resolverCustomAttributes = resolverSegment
+        .getSpanContext()
+        .customAttributes.get(SPAN_DESTINATION)
+      t.match(
+        resolverCustomAttributes,
+        { stage: 'test' },
+        'should have a contextual custom attribute'
+      )
     })
 
     executeQueryAssertResult({
diff --git a/tests/versioned/attributes-tests.js b/tests/versioned/attributes-tests.js
index 52a4bd5..86e4d5a 100644
--- a/tests/versioned/attributes-tests.js
+++ b/tests/versioned/attributes-tests.js
@@ -9,6 +9,7 @@ const { executeQuery, executeJson } = require('../test-client')
 const { findSegmentByName } = require('../agent-testing')
 
 const SEGMENT_DESTINATION = 0x20
+const SPAN_DESTINATION = 0x10
 
 const ANON_PLACEHOLDER = '<anonymous>'
 
@@ -32,6 +33,8 @@ function createAttributesTests(t) {
       const operationName = `${OPERATION_PREFIX}/query/${ANON_PLACEHOLDER}/hello`
       const operationSegment = findSegmentByName(transaction.trace.root, operationName)
 
+      assertCustomAttributes(t, operationSegment, { clientName: 'ApolloTestClient' })
+
       const expectedOperationAttributes = {
         'graphql.operation.type': 'query'
       }
@@ -53,6 +56,8 @@ function createAttributesTests(t) {
 
       const resolveAttributes = resolveHelloSegment.attributes.get(SEGMENT_DESTINATION)
       t.match(resolveAttributes, expectedResolveAttributes, 'should have field resolve attributes')
+
+      assertCustomAttributes(t, resolveHelloSegment, { returnType: 'String' })
     })
 
     executeQuery(serverUrl, query, (err) => {
@@ -158,6 +163,7 @@ function createAttributesTests(t) {
         expectedBooksAttributes,
         'should have field resolve attributes for books'
       )
+      assertCustomAttributes(t, resolveBooksSegment, { sourceBranch: 'downtown' })
     })
 
     executeQuery(serverUrl, query, (err) => {
@@ -392,6 +398,8 @@ function createAttributesTests(t) {
       }
       const resolveAttributes = resolveHelloSegment.attributes.get(SEGMENT_DESTINATION)
       t.match(resolveAttributes, expectedArgAttributes)
+
+      assertCustomAttributes(t, resolveHelloSegment, { args: 'blah,blee' })
     })
 
     executeJson(serverUrl, queryJson, (err) => {
@@ -573,7 +581,26 @@ function createAttributesTests(t) {
   })
 }
 
+function assertCustomAttributes(t, segment, expected) {
+  const customResolveAttributes = segment.getSpanContext().customAttributes.get(SPAN_DESTINATION)
+  t.match(customResolveAttributes, expected, `should have custom attributes on ${segment.name}`)
+}
+
 module.exports = {
   suiteName: 'attributes',
-  createTests: createAttributesTests
+  createTests: createAttributesTests,
+  pluginConfig: {
+    customResolverAttributes({ source, args, info }) {
+      return {
+        args: Object.keys(args).join(','),
+        returnType: info.returnType.name,
+        sourceBranch: source?.branch
+      }
+    },
+    customOperationAttributes(context) {
+      return {
+        clientName: context.request.http.headers.get('client-name')
+      }
+    }
+  }
 }
diff --git a/tests/versioned/express-segments-default-tests.js b/tests/versioned/express-segments-default-tests.js
index 8689a64..203ca29 100644
--- a/tests/versioned/express-segments-default-tests.js
+++ b/tests/versioned/express-segments-default-tests.js
@@ -74,7 +74,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -113,7 +113,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
       t.segments(transaction.trace.root, expectedSegments)
     })
 
@@ -158,7 +158,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -211,7 +211,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -259,7 +259,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -312,7 +312,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -361,7 +361,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -395,7 +395,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -430,7 +430,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -489,7 +489,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -552,7 +552,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -613,7 +613,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -701,7 +701,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -745,7 +745,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
       t.segments(transaction.trace.root, expectedSegments)
     })
 
@@ -789,7 +789,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
       t.segments(transaction.trace.root, expectedSegments)
     })
 
@@ -828,7 +828,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -877,7 +877,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
diff --git a/tests/versioned/express-segments-scalar-tests.js b/tests/versioned/express-segments-scalar-tests.js
index c257a51..950acd4 100644
--- a/tests/versioned/express-segments-scalar-tests.js
+++ b/tests/versioned/express-segments-scalar-tests.js
@@ -74,7 +74,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -113,7 +113,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -161,7 +161,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -216,7 +216,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -269,7 +269,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -318,7 +318,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -352,7 +352,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -387,7 +387,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -449,7 +449,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -514,7 +514,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -577,7 +577,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -668,7 +668,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -710,7 +710,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
@@ -760,7 +760,7 @@ function createSegmentsTests(t, frameworkName, isApollo4) {
           ]
         }
       ]
-      constructSegments(expectedSegments, operationSegments, isApollo4)
+      constructSegments(expectedSegments, operationSegments)
 
       t.segments(transaction.trace.root, expectedSegments)
     })
diff --git a/tests/versioned/transaction-naming-tests.js b/tests/versioned/transaction-naming-tests.js
index c13e5b7..b224fc6 100644
--- a/tests/versioned/transaction-naming-tests.js
+++ b/tests/versioned/transaction-naming-tests.js
@@ -666,7 +666,7 @@ function createTransactionTests(t, frameworkName) {
     }`
     let count = 0
 
-    let transactionHandler = (transaction) => {
+    const transactionHandler = (transaction) => {
       t.equal(transaction.name, `${EXPECTED_PREFIX}//query/${expectedName}/hello`)
       count++
     }