dd-trace 6.13.0 → 6.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-3rdparty.csv +3 -1
- package/ci/init.js +8 -3
- package/ci/test-optimization-validation/ci-package-scripts.js +2 -2
- package/ci/test-optimization-validation/ci-remediation.js +6 -6
- package/ci/test-optimization-validation/command-blocker.js +7 -5
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +1 -1
- package/ci/test-optimization-validation/framework-adapters/vitest.js +3 -3
- package/ci/test-optimization-validation/package-check.js +1 -1
- package/ci/test-optimization-validation/report-writer.js +7 -5
- package/ci/vitest-no-worker-init-runner-setup.mjs +8 -0
- package/ci/vitest-no-worker-init-setup.mjs +13 -13
- package/ci/vitest-no-worker-init-v5-setup.mjs +4 -0
- package/index.d.ts +8 -0
- package/package.json +13 -10
- package/packages/datadog-esbuild/index.js +3 -1
- package/packages/datadog-instrumentations/src/cypress-config.js +19 -17
- package/packages/datadog-instrumentations/src/fs.js +24 -20
- package/packages/datadog-instrumentations/src/google-cloud-vertexai.js +2 -2
- package/packages/datadog-instrumentations/src/graphql.js +16 -16
- package/packages/datadog-instrumentations/src/helpers/graphql-jit-runtime.js +504 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/helpers/pool-acquire.js +265 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/compiler.js +1 -2
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +95 -30
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/ai.js +0 -25
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql-jit.js +83 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/graphql.js +85 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/mercurius.js +30 -12
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/playwright.js +14 -5
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +251 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +11 -1
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +562 -27
- package/packages/datadog-instrumentations/src/jest.js +166 -45
- package/packages/datadog-instrumentations/src/knex.js +76 -0
- package/packages/datadog-instrumentations/src/mariadb.js +6 -0
- package/packages/datadog-instrumentations/src/mocha/common.js +59 -2
- package/packages/datadog-instrumentations/src/mocha/main.js +66 -20
- package/packages/datadog-instrumentations/src/mocha/utils.js +2 -1
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +98 -0
- package/packages/datadog-instrumentations/src/mocha/worker.js +12 -8
- package/packages/datadog-instrumentations/src/net.js +14 -17
- package/packages/datadog-instrumentations/src/next.js +212 -62
- package/packages/datadog-instrumentations/src/openai.js +42 -40
- package/packages/datadog-instrumentations/src/pg.js +15 -0
- package/packages/datadog-instrumentations/src/playwright.js +113 -13
- package/packages/datadog-instrumentations/src/rum-browser-scripts.js +40 -0
- package/packages/datadog-instrumentations/src/sequelize.js +94 -2
- package/packages/datadog-instrumentations/src/undici.js +53 -4
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +37 -3
- package/packages/datadog-instrumentations/src/vitest-main.js +92 -9
- package/packages/datadog-instrumentations/src/vitest-worker.js +71 -14
- package/packages/datadog-instrumentations/src/webdriverio.js +965 -6
- package/packages/datadog-plugin-amqp10/src/consumer.js +3 -1
- package/packages/datadog-plugin-amqp10/src/producer.js +3 -1
- package/packages/datadog-plugin-amqp10/src/util.js +2 -1
- package/packages/datadog-plugin-avsc/src/schema_iterator.js +6 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +16 -5
- package/packages/datadog-plugin-cassandra-driver/src/index.js +8 -3
- package/packages/datadog-plugin-cucumber/src/index.js +0 -2
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +262 -48
- package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +4 -1
- package/packages/datadog-plugin-graphql/src/execute.js +998 -196
- package/packages/datadog-plugin-graphql/src/index.js +27 -7
- package/packages/datadog-plugin-graphql/src/jit.js +136 -0
- package/packages/datadog-plugin-graphql/src/request.js +18 -27
- package/packages/datadog-plugin-graphql/src/resolve-error.js +108 -0
- package/packages/datadog-plugin-graphql/src/tools/signature.js +1 -2
- package/packages/datadog-plugin-graphql/src/tools/transforms.js +45 -3
- package/packages/datadog-plugin-graphql/src/utils.js +208 -120
- package/packages/datadog-plugin-graphql/src/validate.js +10 -23
- package/packages/datadog-plugin-jest/src/index.js +0 -6
- package/packages/datadog-plugin-langchain/src/tracing.js +7 -0
- package/packages/datadog-plugin-mocha/src/index.js +403 -75
- package/packages/datadog-plugin-mongodb-core/src/query.js +6 -0
- package/packages/datadog-plugin-mysql/src/index.js +41 -15
- package/packages/datadog-plugin-net/src/tcp.js +3 -1
- package/packages/datadog-plugin-next/src/index.js +63 -29
- package/packages/datadog-plugin-playwright/src/index.js +167 -27
- package/packages/datadog-plugin-undici/src/index.js +27 -41
- package/packages/datadog-plugin-vitest/src/index.js +6 -12
- package/packages/dd-trace/src/aiguard/evaluation.js +2 -1
- package/packages/dd-trace/src/aiguard/messages/anthropic.js +8 -1
- package/packages/dd-trace/src/aiguard/messages/openai.js +8 -1
- package/packages/dd-trace/src/aiguard/messages/vercel-ai.js +20 -6
- package/packages/dd-trace/src/appsec/api_security/index.js +23 -6
- package/packages/dd-trace/src/appsec/api_security/sampler.js +99 -40
- package/packages/dd-trace/src/appsec/graphql.js +6 -2
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +3 -3
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +2 -1
- package/packages/dd-trace/src/appsec/iast/telemetry/span-tags.js +8 -2
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/command-sensitive-analyzer.js +3 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/sql-sensitive-analyzer.js +531 -95
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/url-sensitive-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/lambda.js +44 -26
- package/packages/dd-trace/src/ci-visibility/encode/json-encoder.js +32 -2
- package/packages/dd-trace/src/ci-visibility/exporters/agent-proxy/index.js +8 -8
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/coverage-writer.js +6 -4
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/di-logs-writer.js +20 -4
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/request-tracker.js +5 -173
- package/packages/dd-trace/src/ci-visibility/exporters/agentless/writer.js +7 -6
- package/packages/dd-trace/src/ci-visibility/exporters/agents.js +54 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/writer.js +1 -2
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +394 -225
- package/packages/dd-trace/src/ci-visibility/exporters/limits.js +9 -0
- package/packages/dd-trace/src/ci-visibility/exporters/request.js +323 -31
- package/packages/dd-trace/src/ci-visibility/exporters/settings-cache-key.js +42 -0
- package/packages/dd-trace/src/ci-visibility/final-flush.js +2 -1
- package/packages/dd-trace/src/ci-visibility/requests/fs-cache.js +57 -18
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +0 -3
- package/packages/dd-trace/src/ci-visibility/requests/request.js +11 -0
- package/packages/dd-trace/src/ci-visibility/requests/upload-test-screenshot.js +164 -71
- package/packages/dd-trace/src/ci-visibility/requests/video-request.js +180 -0
- package/packages/dd-trace/src/ci-visibility/telemetry.js +10 -7
- package/packages/dd-trace/src/ci-visibility/test-video.js +61 -0
- package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -0
- package/packages/dd-trace/src/config/index.js +73 -13
- package/packages/dd-trace/src/config/parsers.js +11 -1
- package/packages/dd-trace/src/config/stable.js +3 -3
- package/packages/dd-trace/src/config/supported-configurations.json +22 -2
- package/packages/dd-trace/src/crashtracking/crashtracker.js +82 -18
- package/packages/dd-trace/src/debugger/config.js +12 -1
- package/packages/dd-trace/src/debugger/constants.js +1 -0
- package/packages/dd-trace/src/debugger/devtools_client/breakpoints.js +2 -1
- package/packages/dd-trace/src/debugger/devtools_client/request-options.js +28 -0
- package/packages/dd-trace/src/debugger/devtools_client/send.js +7 -40
- package/packages/dd-trace/src/debugger/devtools_client/status.js +11 -6
- package/packages/dd-trace/src/debugger/devtools_client/tags.js +41 -0
- package/packages/dd-trace/src/debugger/index.js +23 -3
- package/packages/dd-trace/src/dogstatsd.js +510 -76
- package/packages/dd-trace/src/encode/0.4-cross-payload.js +170 -0
- package/packages/dd-trace/src/encode/0.4.js +5 -5
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +9 -8
- package/packages/dd-trace/src/evp_proxy/direct.js +3 -25
- package/packages/dd-trace/src/exporters/agent/index.js +2 -1
- package/packages/dd-trace/src/exporters/agent/writer.js +24 -7
- package/packages/dd-trace/src/exporters/agentless/index.js +7 -9
- package/packages/dd-trace/src/exporters/agentless/writer.js +103 -119
- package/packages/dd-trace/src/exporters/common/agents.js +28 -6
- package/packages/dd-trace/src/exporters/common/buffering-exporter.js +2 -2
- package/packages/dd-trace/src/exporters/common/final-flush-request-tracker.js +191 -0
- package/packages/dd-trace/src/exporters/common/proxy.js +52 -0
- package/packages/dd-trace/src/exporters/common/request.js +42 -14
- package/packages/dd-trace/src/exporters/common/url.js +40 -1
- package/packages/dd-trace/src/exporters/common/writer.js +9 -7
- package/packages/dd-trace/src/flush.js +6 -3
- package/packages/dd-trace/src/id.js +14 -0
- package/packages/dd-trace/src/index.js +5 -2
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +2 -1
- package/packages/dd-trace/src/llmobs/index.js +32 -32
- package/packages/dd-trace/src/llmobs/plugins/ai/ddTelemetry.js +22 -71
- package/packages/dd-trace/src/llmobs/plugins/ai/vercelTelemetry.js +23 -13
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +7 -0
- package/packages/dd-trace/src/llmobs/util.js +0 -33
- package/packages/dd-trace/src/llmobs/writers/base.js +49 -32
- package/packages/dd-trace/src/log/index.js +7 -1
- package/packages/dd-trace/src/{ci-visibility/log-submission → log-submission}/log-submission-plugin.js +48 -19
- package/packages/dd-trace/src/openfeature/writers/base.js +14 -12
- package/packages/dd-trace/src/openfeature/writers/util.js +1 -1
- package/packages/dd-trace/src/opentelemetry/logs/index.js +5 -24
- package/packages/dd-trace/src/opentelemetry/logs/otlp_http_log_exporter.js +14 -4
- package/packages/dd-trace/src/opentelemetry/metrics/index.js +15 -22
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_http_metric_exporter.js +14 -4
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_span_stats_exporter.js +10 -0
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_http_exporter_base.js +5 -0
- package/packages/dd-trace/src/opentelemetry/otlp/otlp_transformer_base.js +19 -4
- package/packages/dd-trace/src/opentelemetry/resource-attributes.js +55 -0
- package/packages/dd-trace/src/opentelemetry/trace/index.js +6 -1
- package/packages/dd-trace/src/opentelemetry/trace/otlp_http_trace_exporter.js +10 -0
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +101 -20
- package/packages/dd-trace/src/payload-tagging/index.js +2 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +1 -6
- package/packages/dd-trace/src/plugins/tracing.js +12 -10
- package/packages/dd-trace/src/plugins/util/ci.js +3 -1
- package/packages/dd-trace/src/plugins/util/inferred_proxy.js +16 -15
- package/packages/dd-trace/src/plugins/util/test.js +83 -20
- package/packages/dd-trace/src/plugins/util/url.js +2 -2
- package/packages/dd-trace/src/plugins/util/web.js +4 -9
- package/packages/dd-trace/src/priority_sampler.js +4 -0
- package/packages/dd-trace/src/profiling/config.js +1 -0
- package/packages/dd-trace/src/profiling/oom.js +7 -2
- package/packages/dd-trace/src/profiling/profiler.js +23 -13
- package/packages/dd-trace/src/profiling/profilers/space.js +38 -11
- package/packages/dd-trace/src/profiling/webspan-utils.js +7 -4
- package/packages/dd-trace/src/proxy.js +75 -5
- package/packages/dd-trace/src/remote_config/index.js +319 -101
- package/packages/dd-trace/src/remote_config/scheduler.js +37 -12
- package/packages/dd-trace/src/runtime_metrics/client.js +37 -8
- package/packages/dd-trace/src/runtime_metrics/otlp_runtime_metrics.js +5 -1
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +5 -1
- package/packages/dd-trace/src/sampling_rule.js +39 -10
- package/packages/dd-trace/src/serverless/telemetry-delivery-tracker.js +4 -8
- package/packages/dd-trace/src/serverless/vercel.js +53 -20
- package/packages/dd-trace/src/serverless.js +10 -3
- package/packages/dd-trace/src/service-naming/schemas/util.js +1 -1
- package/packages/dd-trace/src/span_processor.js +18 -3
- package/packages/dd-trace/src/span_stats.js +24 -28
- package/packages/dd-trace/src/startup-log.js +3 -2
- package/packages/dd-trace/src/telemetry/agentless-url.js +28 -0
- package/packages/dd-trace/src/telemetry/send-data.js +23 -20
- package/packages/dd-trace/src/telemetry/session-propagation.js +3 -2
- package/packages/dd-trace/src/tracer.js +4 -5
- package/packages/dd-trace/src/tracer_metadata.js +11 -3
- package/vendor/dist/@datadog/sketches-js/index.js +1 -1
- package/vendor/dist/protobufjs/index.js +1 -1
- package/vendor/dist/protobufjs/minimal/index.js +1 -1
- package/packages/datadog-instrumentations/src/playwright-browser-scripts.js +0 -27
- package/packages/dd-trace/src/encode/agentless-json.js +0 -210
|
@@ -10,14 +10,71 @@
|
|
|
10
10
|
|
|
11
11
|
const assert = require('node:assert')
|
|
12
12
|
|
|
13
|
-
const
|
|
13
|
+
const createRfdc = require('../../../../../vendor/dist/rfdc')
|
|
14
|
+
const clone = createRfdc({ proto: false, circles: false })
|
|
14
15
|
|
|
15
16
|
const { parse, query } = require('./compiler')
|
|
16
17
|
|
|
17
18
|
const functionTypes = new Set(['ArrowFunctionExpression', 'FunctionDeclaration', 'FunctionExpression'])
|
|
18
19
|
const identifierPattern = /^[$A-Z_a-z][$\w]*$/
|
|
19
20
|
|
|
20
|
-
module.exports = {
|
|
21
|
+
module.exports = {
|
|
22
|
+
awaitContextCallback,
|
|
23
|
+
awaitContextCallbackAtFunctionStart,
|
|
24
|
+
awaitContextCallbackAtTryStart,
|
|
25
|
+
configureGraphqlJitCompileObject,
|
|
26
|
+
configureGraphqlJitDeferredField,
|
|
27
|
+
configureGraphqlJitExecute,
|
|
28
|
+
configureGraphqlJitRuntime,
|
|
29
|
+
configureGraphqlFastPath,
|
|
30
|
+
configureMercuriusRequest,
|
|
31
|
+
waitForAsyncEnd,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Awaits an optional context callback at the start of the matched node's enclosing async function.
|
|
36
|
+
*
|
|
37
|
+
* @param {Parameters<typeof awaitContextCallback>[0]} state
|
|
38
|
+
* @param {import('estree').Node} node
|
|
39
|
+
* @param {import('estree').Node} _parent
|
|
40
|
+
* @param {import('estree').Node[]} ancestry
|
|
41
|
+
* @returns {void}
|
|
42
|
+
*/
|
|
43
|
+
function awaitContextCallbackAtFunctionStart (state, node, _parent, ancestry) {
|
|
44
|
+
let enclosingFunction = functionTypes.has(node.type)
|
|
45
|
+
? node
|
|
46
|
+
: ancestry.find(ancestor => functionTypes.has(ancestor.type))
|
|
47
|
+
let callbackAncestry = ancestry
|
|
48
|
+
|
|
49
|
+
if (enclosingFunction === node) {
|
|
50
|
+
callbackAncestry = [node, ...ancestry]
|
|
51
|
+
if (!node.async) {
|
|
52
|
+
// Function queries create a synchronous trace wrapper before custom transforms run.
|
|
53
|
+
const [wrappedFunction] = query(node,
|
|
54
|
+
'VariableDeclarator[id.name="__apm$traced"] > ArrowFunctionExpression > BlockStatement > ' +
|
|
55
|
+
'VariableDeclaration > VariableDeclarator[id.name="__apm$wrapped"] > ' +
|
|
56
|
+
':matches(FunctionDeclaration, FunctionExpression)[async=true]')
|
|
57
|
+
if (wrappedFunction) {
|
|
58
|
+
enclosingFunction = wrappedFunction
|
|
59
|
+
callbackAncestry.unshift(wrappedFunction)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
assert(enclosingFunction?.async && enclosingFunction.body?.type === 'BlockStatement',
|
|
64
|
+
'awaitContextCallbackAtFunctionStart: expected an enclosing async function with a block body')
|
|
65
|
+
|
|
66
|
+
const generatedCallback = createAwaitedContextCallback(
|
|
67
|
+
state,
|
|
68
|
+
enclosingFunction.body,
|
|
69
|
+
callbackAncestry,
|
|
70
|
+
'awaitContextCallbackAtFunctionStart'
|
|
71
|
+
)
|
|
72
|
+
if (!generatedCallback) return
|
|
73
|
+
|
|
74
|
+
let insertionIndex = 0
|
|
75
|
+
while (typeof enclosingFunction.body.body[insertionIndex]?.directive === 'string') insertionIndex++
|
|
76
|
+
enclosingFunction.body.body.splice(insertionIndex, 0, ...generatedCallback.callbackStatements)
|
|
77
|
+
}
|
|
21
78
|
|
|
22
79
|
/**
|
|
23
80
|
* Awaits an optional context callback before continuing through a matched conditional branch.
|
|
@@ -28,7 +85,8 @@ module.exports = { awaitContextCallback, waitForAsyncEnd }
|
|
|
28
85
|
* @param {{
|
|
29
86
|
* transformOptions?: {
|
|
30
87
|
* callbackArgumentNames?: string[],
|
|
31
|
-
* callbackName?: string
|
|
88
|
+
* callbackName?: string,
|
|
89
|
+
* callbackThis?: boolean
|
|
32
90
|
* }
|
|
33
91
|
* }} state
|
|
34
92
|
* @param {import('estree').IfStatement} node
|
|
@@ -40,11 +98,74 @@ function awaitContextCallback (state, node, _parent, ancestry) {
|
|
|
40
98
|
assert(node.type === 'IfStatement' && node.consequent?.type === 'BlockStatement',
|
|
41
99
|
'awaitContextCallback: expected an if statement with a block body')
|
|
42
100
|
|
|
43
|
-
const
|
|
101
|
+
const originalStatements = node.consequent.body
|
|
102
|
+
const generatedCallback = createAwaitedContextCallback(
|
|
103
|
+
state,
|
|
104
|
+
node.consequent,
|
|
105
|
+
ancestry,
|
|
106
|
+
'awaitContextCallback'
|
|
107
|
+
)
|
|
108
|
+
if (!generatedCallback) return
|
|
109
|
+
|
|
110
|
+
const { callbackStatements, callbackVariable } = generatedCallback
|
|
111
|
+
const callbackBranch = parse(`
|
|
112
|
+
if (typeof ${callbackVariable} === 'function') {
|
|
113
|
+
} else {
|
|
114
|
+
}
|
|
115
|
+
`).body[0]
|
|
116
|
+
callbackBranch.consequent.body.push(clone(node))
|
|
117
|
+
callbackBranch.alternate = {
|
|
118
|
+
type: 'BlockStatement',
|
|
119
|
+
body: originalStatements,
|
|
120
|
+
}
|
|
121
|
+
node.consequent.body = [...callbackStatements, callbackBranch]
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Awaits an optional context callback before entering the matched node's enclosing try block.
|
|
126
|
+
*
|
|
127
|
+
* @param {Parameters<typeof awaitContextCallback>[0]} state
|
|
128
|
+
* @param {import('estree').Node} node
|
|
129
|
+
* @param {import('estree').Node} _parent
|
|
130
|
+
* @param {import('estree').Node[]} ancestry
|
|
131
|
+
* @returns {void}
|
|
132
|
+
*/
|
|
133
|
+
function awaitContextCallbackAtTryStart (state, node, _parent, ancestry) {
|
|
134
|
+
let tryStatement = node.type === 'TryStatement' ? node : undefined
|
|
135
|
+
for (const ancestor of ancestry) {
|
|
136
|
+
if (tryStatement || functionTypes.has(ancestor.type)) break
|
|
137
|
+
if (ancestor.type === 'TryStatement') tryStatement = ancestor
|
|
138
|
+
}
|
|
139
|
+
assert(tryStatement?.block?.type === 'BlockStatement',
|
|
140
|
+
'awaitContextCallbackAtTryStart: expected an enclosing try statement with a block body')
|
|
141
|
+
|
|
142
|
+
const generatedCallback = createAwaitedContextCallback(
|
|
143
|
+
state,
|
|
144
|
+
tryStatement.block,
|
|
145
|
+
ancestry,
|
|
146
|
+
'awaitContextCallbackAtTryStart'
|
|
147
|
+
)
|
|
148
|
+
if (!generatedCallback) return
|
|
149
|
+
|
|
150
|
+
tryStatement.block.body.unshift(...generatedCallback.callbackStatements)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @param {Parameters<typeof awaitContextCallback>[0]} state
|
|
155
|
+
* @param {import('estree').BlockStatement} insertionTarget
|
|
156
|
+
* @param {import('estree').Node[]} ancestry
|
|
157
|
+
* @param {string} transformName
|
|
158
|
+
* @returns {{
|
|
159
|
+
* callbackStatements: import('estree').Statement[],
|
|
160
|
+
* callbackVariable: string
|
|
161
|
+
* }|undefined}
|
|
162
|
+
*/
|
|
163
|
+
function createAwaitedContextCallback (state, insertionTarget, ancestry, transformName) {
|
|
164
|
+
const { callbackArgumentNames = [], callbackName, callbackThis = false } = state.transformOptions ?? {}
|
|
44
165
|
|
|
45
|
-
assert(identifierPattern.test(callbackName),
|
|
46
|
-
assert(callbackArgumentNames.every(name => identifierPattern.test(name)),
|
|
47
|
-
|
|
166
|
+
assert(identifierPattern.test(callbackName), `${transformName}: callbackName must be an identifier`)
|
|
167
|
+
assert(Array.isArray(callbackArgumentNames) && callbackArgumentNames.every(name => identifierPattern.test(name)),
|
|
168
|
+
`${transformName}: callbackArgumentNames must be identifiers`)
|
|
48
169
|
|
|
49
170
|
let enclosingFunction
|
|
50
171
|
let hasTraceWrapper = false
|
|
@@ -67,35 +188,449 @@ function awaitContextCallback (state, node, _parent, ancestry) {
|
|
|
67
188
|
hasTraceWrapper ||= hasContextBinding && hasTracedBinding
|
|
68
189
|
}
|
|
69
190
|
|
|
70
|
-
assert(enclosingFunction?.async,
|
|
71
|
-
assert(hasTraceWrapper,
|
|
191
|
+
assert(enclosingFunction?.async, `${transformName}: expected an enclosing async function`)
|
|
192
|
+
assert(hasTraceWrapper, `${transformName}: expected an enclosing trace wrapper`)
|
|
72
193
|
|
|
73
194
|
const callbackVariable = `__apm$${callbackName}`
|
|
74
|
-
if (query(
|
|
75
|
-
return
|
|
76
|
-
}
|
|
195
|
+
if (query(insertionTarget, `[id.name="${callbackVariable}"]`).length > 0) return
|
|
77
196
|
|
|
78
|
-
const
|
|
197
|
+
const callbackArguments = callbackArgumentNames.join(', ')
|
|
198
|
+
const callbackInvocation = callbackThis
|
|
199
|
+
? `${callbackVariable}.call(this${callbackArguments ? `, ${callbackArguments}` : ''})`
|
|
200
|
+
: `${callbackVariable}(${callbackArguments})`
|
|
79
201
|
const callbackStatements = parse(`
|
|
80
202
|
async function wrapper () {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
203
|
+
let ${callbackVariable};
|
|
204
|
+
try {
|
|
205
|
+
${callbackVariable} = __apm$ctx.${callbackName};
|
|
206
|
+
if (typeof ${callbackVariable} === 'function') {
|
|
207
|
+
await ${callbackInvocation};
|
|
208
|
+
}
|
|
209
|
+
} catch {}
|
|
210
|
+
}
|
|
211
|
+
`).body[0].body.body
|
|
212
|
+
|
|
213
|
+
return {
|
|
214
|
+
callbackStatements,
|
|
215
|
+
callbackVariable,
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* @param {object} _state
|
|
221
|
+
* @param {import('estree').FunctionDeclaration} node
|
|
222
|
+
*/
|
|
223
|
+
function configureGraphqlJitCompileObject (_state, node) {
|
|
224
|
+
const resolverConditions = query(node, 'IfStatement[test.name="resolver"]')
|
|
225
|
+
const compileTypeCalls = query(node, 'CallExpression[callee.name="compileType"]')
|
|
226
|
+
|
|
227
|
+
assert.strictEqual(
|
|
228
|
+
resolverConditions.length,
|
|
229
|
+
1,
|
|
230
|
+
'configureGraphqlJitCompileObject: resolver condition not found'
|
|
231
|
+
)
|
|
232
|
+
assert.strictEqual(
|
|
233
|
+
compileTypeCalls.length,
|
|
234
|
+
1,
|
|
235
|
+
'configureGraphqlJitCompileObject: inline compile call not found'
|
|
236
|
+
)
|
|
237
|
+
|
|
238
|
+
const [resolverCondition] = resolverConditions
|
|
239
|
+
const [compileTypeCall] = compileTypeCalls
|
|
240
|
+
const inlineCompileCall = clone(compileTypeCall)
|
|
241
|
+
const argumentProperties = query(resolverCondition.consequent, 'Property[key.name="args"]')
|
|
242
|
+
assert.strictEqual(
|
|
243
|
+
argumentProperties.length,
|
|
244
|
+
1,
|
|
245
|
+
'configureGraphqlJitCompileObject: argument compiler not found'
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
const defaultSetup = parse(`
|
|
249
|
+
const ddTraceDefault = context.ddTraceDefaultResolvers && !resolver && alwaysDefer === false
|
|
250
|
+
const ddTraceArguments = ddTraceDefault ? DD_ARGUMENTS : undefined
|
|
251
|
+
`).body
|
|
252
|
+
replaceIdentifier(defaultSetup[1], 'DD_ARGUMENTS', argumentProperties[0].value)
|
|
253
|
+
const [inlineField] = parse(`
|
|
254
|
+
const ddTraceInline = ddTraceDefault
|
|
255
|
+
? context.ddTraceRuntime.compileDefaultField(
|
|
256
|
+
context,
|
|
257
|
+
DD_PATH,
|
|
258
|
+
type,
|
|
259
|
+
field,
|
|
260
|
+
DD_FIELD_NODES,
|
|
261
|
+
originPaths,
|
|
262
|
+
ddTraceArguments,
|
|
263
|
+
objectStringify(ddTraceArguments.values),
|
|
264
|
+
DD_COMPILED
|
|
265
|
+
)
|
|
266
|
+
: undefined
|
|
267
|
+
`).body
|
|
268
|
+
replaceIdentifier(inlineField, 'DD_PATH', clone(compileTypeCall.arguments[6]))
|
|
269
|
+
replaceIdentifier(inlineField, 'DD_FIELD_NODES', clone(compileTypeCall.arguments[3]))
|
|
270
|
+
replaceIdentifier(inlineField, 'DD_COMPILED', inlineCompileCall)
|
|
271
|
+
|
|
272
|
+
assert(
|
|
273
|
+
insertBeforeStatement(node.body, resolverCondition, [...defaultSetup, inlineField]),
|
|
274
|
+
'configureGraphqlJitCompileObject: could not insert default field setup'
|
|
275
|
+
)
|
|
276
|
+
resolverCondition.test = parse('resolver || ddTraceDefault').body[0].expression
|
|
277
|
+
|
|
278
|
+
const includedConditions = query(resolverCondition.consequent, 'IfStatement[test.name="alwaysIncluded"]')
|
|
279
|
+
let defaultBody
|
|
280
|
+
if (includedConditions.length === 1) {
|
|
281
|
+
defaultBody = parse(`
|
|
282
|
+
if (alwaysIncluded) {
|
|
283
|
+
body(ddTraceInline)
|
|
87
284
|
} else {
|
|
285
|
+
body(\`? \${ddTraceInline} : undefined\`)
|
|
88
286
|
}
|
|
287
|
+
`).body
|
|
288
|
+
} else {
|
|
289
|
+
assert.strictEqual(
|
|
290
|
+
includedConditions.length,
|
|
291
|
+
0,
|
|
292
|
+
'configureGraphqlJitCompileObject: ambiguous included condition'
|
|
293
|
+
)
|
|
294
|
+
defaultBody = parse(`
|
|
295
|
+
body(\`? \${ddTraceInline} : undefined\`)
|
|
296
|
+
`).body
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
const originalResolverBody = resolverCondition.consequent
|
|
300
|
+
const [defaultCondition] = parse(`
|
|
301
|
+
if (ddTraceDefault) {}
|
|
302
|
+
`).body
|
|
303
|
+
defaultCondition.consequent.body.push(...defaultBody)
|
|
304
|
+
defaultCondition.alternate = originalResolverBody
|
|
305
|
+
resolverCondition.consequent = {
|
|
306
|
+
type: 'BlockStatement',
|
|
307
|
+
body: [defaultCondition],
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* @param {import('estree').Node} root
|
|
313
|
+
* @param {string} name
|
|
314
|
+
* @param {import('estree').Node} replacement
|
|
315
|
+
*/
|
|
316
|
+
function replaceIdentifier (root, name, replacement) {
|
|
317
|
+
for (const key of Object.keys(root)) {
|
|
318
|
+
const value = root[key]
|
|
319
|
+
if (!value || typeof value !== 'object') continue
|
|
320
|
+
if (value.type === 'Identifier' && value.name === name) {
|
|
321
|
+
root[key] = clone(replacement)
|
|
322
|
+
} else {
|
|
323
|
+
replaceIdentifier(value, name, replacement)
|
|
89
324
|
}
|
|
90
|
-
|
|
325
|
+
}
|
|
326
|
+
}
|
|
91
327
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
328
|
+
/**
|
|
329
|
+
* @param {import('estree').Node} root
|
|
330
|
+
* @param {import('estree').Node} target
|
|
331
|
+
* @param {import('estree').Node[]} statements
|
|
332
|
+
* @returns {boolean}
|
|
333
|
+
*/
|
|
334
|
+
function insertBeforeStatement (root, target, statements) {
|
|
335
|
+
for (const key of Object.keys(root)) {
|
|
336
|
+
const value = root[key]
|
|
337
|
+
if (Array.isArray(value)) {
|
|
338
|
+
const index = value.indexOf(target)
|
|
339
|
+
if (index !== -1) {
|
|
340
|
+
value.splice(index, 0, ...statements)
|
|
341
|
+
return true
|
|
342
|
+
}
|
|
343
|
+
for (const entry of value) {
|
|
344
|
+
if (entry && typeof entry === 'object' && insertBeforeStatement(entry, target, statements)) return true
|
|
345
|
+
}
|
|
346
|
+
} else if (value && typeof value === 'object' && insertBeforeStatement(value, target, statements)) {
|
|
347
|
+
return true
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return false
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* @param {import('estree').Node} root
|
|
355
|
+
* @param {string} selector
|
|
356
|
+
* @returns {import('estree').Node}
|
|
357
|
+
*/
|
|
358
|
+
function queryOne (root, selector) {
|
|
359
|
+
const matches = query(root, selector)
|
|
360
|
+
assert.strictEqual(matches.length, 1, `expected one match for ${selector}`)
|
|
361
|
+
return matches[0]
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* @param {object} _state
|
|
366
|
+
* @param {import('estree').FunctionDeclaration} node
|
|
367
|
+
* @param {import('estree').Node} parent
|
|
368
|
+
* @param {import('estree').Node[]} ancestry
|
|
369
|
+
*/
|
|
370
|
+
function configureGraphqlFastPath (_state, node, parent, ancestry) {
|
|
371
|
+
assert.strictEqual(node.type, 'FunctionDeclaration', 'configureGraphqlFastPath: expected a function declaration')
|
|
372
|
+
assert(identifierPattern.test(node.id?.name), 'configureGraphqlFastPath: expected a named function')
|
|
373
|
+
|
|
374
|
+
const insertionRoot = Array.isArray(parent?.body)
|
|
375
|
+
? parent
|
|
376
|
+
: ancestry.find(ancestor => Array.isArray(ancestor?.body) && ancestor.body.includes(parent))
|
|
377
|
+
assert(insertionRoot, 'configureGraphqlFastPath: expected an enclosing statement list')
|
|
378
|
+
const insertionTarget = insertionRoot === parent ? node : parent
|
|
379
|
+
|
|
380
|
+
const originalName = `__apm$original_${node.id.name}`
|
|
381
|
+
assert.strictEqual(
|
|
382
|
+
query(insertionRoot, `VariableDeclarator[id.name="${originalName}"]`).length,
|
|
383
|
+
0,
|
|
384
|
+
'configureGraphqlFastPath: original function binding already exists'
|
|
385
|
+
)
|
|
386
|
+
configureGraphqlTraceFastPath(
|
|
387
|
+
node,
|
|
388
|
+
insertionRoot,
|
|
389
|
+
insertionTarget,
|
|
390
|
+
originalName,
|
|
391
|
+
'configureGraphqlFastPath'
|
|
392
|
+
)
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* @param {import('estree').Function} node
|
|
397
|
+
* @param {import('estree').Node} insertionRoot
|
|
398
|
+
* @param {import('estree').Node} insertionTarget
|
|
399
|
+
* @param {string} originalName
|
|
400
|
+
* @param {string} transformName
|
|
401
|
+
*/
|
|
402
|
+
function configureGraphqlTraceFastPath (node, insertionRoot, insertionTarget, originalName, transformName) {
|
|
403
|
+
const tracedDeclaration = queryOne(
|
|
404
|
+
node,
|
|
405
|
+
'VariableDeclaration:has(VariableDeclarator[id.name="__apm$traced"])'
|
|
406
|
+
)
|
|
407
|
+
const tracedBody = queryOne(
|
|
408
|
+
tracedDeclaration,
|
|
409
|
+
'VariableDeclarator[id.name="__apm$traced"] > ArrowFunctionExpression > BlockStatement'
|
|
410
|
+
)
|
|
411
|
+
const wrappedDeclaration = queryOne(
|
|
412
|
+
tracedBody,
|
|
413
|
+
'VariableDeclaration:has(VariableDeclarator[id.name="__apm$wrapped"])'
|
|
414
|
+
)
|
|
415
|
+
const wrapped = queryOne(wrappedDeclaration, 'VariableDeclarator[id.name="__apm$wrapped"]')
|
|
416
|
+
const subscriberGuard = queryOne(
|
|
417
|
+
node,
|
|
418
|
+
'IfStatement[test.operator="!"][consequent.type="ReturnStatement"]' +
|
|
419
|
+
':has(CallExpression[callee.name="__apm$traced"])'
|
|
420
|
+
)
|
|
421
|
+
const fastCall = subscriberGuard.consequent.argument
|
|
422
|
+
const tracedCalls = query(node, 'CallExpression[callee.name="__apm$traced"]')
|
|
423
|
+
assert.strictEqual(tracedCalls.length, 2, `${transformName}: expected inactive and active traced calls`)
|
|
424
|
+
const activeCall = tracedCalls.find(call => call !== fastCall)
|
|
425
|
+
assert(activeCall, `${transformName}: active traced call not found`)
|
|
426
|
+
assert(functionTypes.has(wrapped.init?.type), `${transformName}: expected a wrapped function`)
|
|
427
|
+
|
|
428
|
+
wrapped.id.name = originalName
|
|
429
|
+
assert(
|
|
430
|
+
insertBeforeStatement(insertionRoot, insertionTarget, [wrappedDeclaration]),
|
|
431
|
+
`${transformName}: could not hoist original function`
|
|
432
|
+
)
|
|
433
|
+
|
|
434
|
+
fastCall.callee = parse(`${originalName}.apply`).body[0].expression
|
|
435
|
+
fastCall.arguments = parse('call(this, arguments)').body[0].expression.arguments
|
|
436
|
+
subscriberGuard.consequent = { type: 'BlockStatement', body: [subscriberGuard.consequent] }
|
|
437
|
+
activeCall.callee = parse(`${originalName}.apply`).body[0].expression
|
|
438
|
+
activeCall.arguments = parse('call(this, __apm$arguments)').body[0].expression.arguments
|
|
439
|
+
|
|
440
|
+
const statements = node.body.body
|
|
441
|
+
const subscriberGuardIndex = statements.indexOf(subscriberGuard)
|
|
442
|
+
const tracedDeclarationIndex = statements.indexOf(tracedDeclaration)
|
|
443
|
+
assert.notStrictEqual(subscriberGuardIndex, -1, `${transformName}: subscriber guard is not top-level`)
|
|
444
|
+
assert.notStrictEqual(tracedDeclarationIndex, -1, `${transformName}: traced declaration is not top-level`)
|
|
445
|
+
statements.splice(subscriberGuardIndex, 1)
|
|
446
|
+
statements.splice(statements.indexOf(tracedDeclaration), 1)
|
|
447
|
+
statements.unshift(subscriberGuard)
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* @param {object} _state
|
|
452
|
+
* @param {import('estree').FunctionExpression} node
|
|
453
|
+
* @param {import('estree').Node} _parent
|
|
454
|
+
* @param {import('estree').Node[]} ancestry
|
|
455
|
+
*/
|
|
456
|
+
function configureGraphqlJitExecute (_state, node, _parent, ancestry) {
|
|
457
|
+
const context = queryOne(node, 'VariableDeclarator[id.name="__apm$ctx"] > ObjectExpression')
|
|
458
|
+
const wrapped = queryOne(node, 'VariableDeclarator[id.name="__apm$wrapped"]')
|
|
459
|
+
|
|
460
|
+
const createBoundQuery = ancestry.find(ancestor =>
|
|
461
|
+
ancestor.type === 'FunctionDeclaration' && ancestor.id?.name === 'createBoundQuery'
|
|
462
|
+
)
|
|
463
|
+
assert(createBoundQuery, 'configureGraphqlJitExecute: createBoundQuery not found')
|
|
464
|
+
|
|
465
|
+
const retDeclaration = queryOne(
|
|
466
|
+
createBoundQuery,
|
|
467
|
+
'VariableDeclaration:has(VariableDeclarator[id.name="ret"])'
|
|
468
|
+
)
|
|
469
|
+
assert.strictEqual(
|
|
470
|
+
query(createBoundQuery, 'VariableDeclarator[id.name="__apm$wrapped"]').length,
|
|
471
|
+
1,
|
|
472
|
+
'configureGraphqlJitExecute: ambiguous wrapped query declaration'
|
|
473
|
+
)
|
|
474
|
+
assert.strictEqual(
|
|
475
|
+
query(wrapped.init, 'ThisExpression, Super, MetaProperty, Identifier[name="arguments"]').length,
|
|
476
|
+
0,
|
|
477
|
+
'configureGraphqlJitExecute: original query depends on its invocation scope'
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
const bindings = parse(`
|
|
481
|
+
const ddResolvers = compilationContext.resolvers
|
|
482
|
+
const ddSchema = compilationContext.schema
|
|
483
|
+
`).body
|
|
484
|
+
const properties = parse(`({
|
|
485
|
+
ddDocument: document,
|
|
486
|
+
ddOperationName: operationName,
|
|
487
|
+
ddPlan,
|
|
488
|
+
ddResolvers,
|
|
489
|
+
ddSchema
|
|
490
|
+
})`).body[0].expression.properties
|
|
491
|
+
|
|
492
|
+
context.properties.push(...properties)
|
|
493
|
+
|
|
494
|
+
assert(
|
|
495
|
+
insertBeforeStatement(createBoundQuery.body, retDeclaration, bindings),
|
|
496
|
+
'configureGraphqlJitExecute: could not insert query bindings'
|
|
497
|
+
)
|
|
498
|
+
configureGraphqlTraceFastPath(
|
|
499
|
+
node,
|
|
500
|
+
createBoundQuery.body,
|
|
501
|
+
retDeclaration,
|
|
502
|
+
'__apm$wrapped',
|
|
503
|
+
'configureGraphqlJitExecute'
|
|
504
|
+
)
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
* @param {object} _state
|
|
509
|
+
* @param {import('estree').FunctionDeclaration} node
|
|
510
|
+
*/
|
|
511
|
+
function configureGraphqlJitDeferredField (_state, node) {
|
|
512
|
+
const declarations = query(node, 'VariableDeclaration:has(VariableDeclarator[id.name="resolverCall"])')
|
|
513
|
+
const resolverCalls = query(node, 'VariableDeclarator[id.name="resolverCall"]')
|
|
514
|
+
const executionErrorDeclarations = query(
|
|
515
|
+
node,
|
|
516
|
+
'VariableDeclaration:has(VariableDeclarator[id.name="executionError"])'
|
|
517
|
+
)
|
|
518
|
+
const executionErrors = query(node, 'VariableDeclarator[id.name="executionError"]')
|
|
519
|
+
const emptyErrors = query(node, 'VariableDeclarator[id.name="emptyError"]')
|
|
520
|
+
assert.strictEqual(
|
|
521
|
+
declarations.length,
|
|
522
|
+
1,
|
|
523
|
+
'configureGraphqlJitDeferredField: resolver call declaration not found'
|
|
524
|
+
)
|
|
525
|
+
assert.strictEqual(
|
|
526
|
+
resolverCalls.length,
|
|
527
|
+
1,
|
|
528
|
+
'configureGraphqlJitDeferredField: resolver call not found'
|
|
529
|
+
)
|
|
530
|
+
assert.strictEqual(
|
|
531
|
+
executionErrorDeclarations.length,
|
|
532
|
+
1,
|
|
533
|
+
'configureGraphqlJitDeferredField: execution error declaration not found'
|
|
534
|
+
)
|
|
535
|
+
assert.strictEqual(executionErrors.length, 1, 'configureGraphqlJitDeferredField: execution error not found')
|
|
536
|
+
assert.strictEqual(emptyErrors.length, 1, 'configureGraphqlJitDeferredField: empty error not found')
|
|
537
|
+
|
|
538
|
+
const [resolverCall] = resolverCalls
|
|
539
|
+
assertGraphqlJitResolverCall(resolverCall.init)
|
|
540
|
+
|
|
541
|
+
const [descriptor] = parse(`
|
|
542
|
+
const ddTraceDescriptorId = context.ddTraceRuntime?.registerField(context, responsePath, {
|
|
543
|
+
fieldName,
|
|
544
|
+
fieldNodes,
|
|
545
|
+
returnType: fieldType,
|
|
546
|
+
parentType
|
|
547
|
+
})
|
|
548
|
+
`).body
|
|
549
|
+
assert(
|
|
550
|
+
insertBeforeStatement(node.body, executionErrorDeclarations[0], [descriptor]),
|
|
551
|
+
'configureGraphqlJitDeferredField: could not insert descriptor'
|
|
552
|
+
)
|
|
553
|
+
|
|
554
|
+
executionErrors[0].init.arguments[4] = parse(`
|
|
555
|
+
ddTraceDescriptorId === undefined
|
|
556
|
+
? 'err'
|
|
557
|
+
: '(__context.ddTrace?.jitRuntime.recordResolverError(__context.ddTrace, ' +
|
|
558
|
+
ddTraceDescriptorId + ', err), err)'
|
|
559
|
+
`).body[0].expression
|
|
560
|
+
emptyErrors[0].init.arguments[3] = parse(`
|
|
561
|
+
ddTraceDescriptorId === undefined
|
|
562
|
+
? '""'
|
|
563
|
+
: '(__context.ddTrace?.jitRuntime.recordResolverError(__context.ddTrace, ' +
|
|
564
|
+
ddTraceDescriptorId + ', err), "")'
|
|
565
|
+
`).body[0].expression
|
|
566
|
+
|
|
567
|
+
const replacement = parse(`
|
|
568
|
+
context.ddTraceRuntime === undefined
|
|
569
|
+
? DD_CALL
|
|
570
|
+
: context.ddTraceRuntime.compileResolverCall(context, DD_CALL, resolverName, ddTraceDescriptorId)
|
|
571
|
+
`).body[0].expression
|
|
572
|
+
replaceIdentifier(replacement, 'DD_CALL', resolverCall.init)
|
|
573
|
+
resolverCall.init = replacement
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
/**
|
|
577
|
+
* @param {import('estree').Expression | null} source
|
|
578
|
+
*/
|
|
579
|
+
function assertGraphqlJitResolverCall (source) {
|
|
580
|
+
assert.strictEqual(source?.type, 'TemplateLiteral', 'configureGraphqlJitDeferredField: unsupported resolver call')
|
|
581
|
+
|
|
582
|
+
const { expressions, quasis } = source
|
|
583
|
+
assert.ok(expressions.length >= 2, 'configureGraphqlJitDeferredField: resolver call expressions not found')
|
|
584
|
+
assert.ok(quasis.length >= 3, 'configureGraphqlJitDeferredField: resolver call segments not found')
|
|
585
|
+
assert.strictEqual(
|
|
586
|
+
expressions[0].name,
|
|
587
|
+
'GLOBAL_EXECUTION_CONTEXT',
|
|
588
|
+
'configureGraphqlJitDeferredField: execution context not found'
|
|
589
|
+
)
|
|
590
|
+
assert.strictEqual(
|
|
591
|
+
quasis[1].value.raw,
|
|
592
|
+
'.resolvers.',
|
|
593
|
+
'configureGraphqlJitDeferredField: resolver map access not found'
|
|
594
|
+
)
|
|
595
|
+
assert.strictEqual(
|
|
596
|
+
expressions[1].name,
|
|
597
|
+
'resolverName',
|
|
598
|
+
'configureGraphqlJitDeferredField: resolver name not found'
|
|
599
|
+
)
|
|
600
|
+
assert.ok(quasis[2].value.raw.startsWith('('), 'configureGraphqlJitDeferredField: resolver call not found')
|
|
601
|
+
assert.ok(quasis.at(-1).value.raw.endsWith(')'), 'configureGraphqlJitDeferredField: resolver call end not found')
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* @param {object} _state
|
|
606
|
+
* @param {import('estree').FunctionDeclaration} node
|
|
607
|
+
*/
|
|
608
|
+
function configureGraphqlJitRuntime (_state, node) {
|
|
609
|
+
node.body.body.unshift(...parse(`
|
|
610
|
+
const ddTraceRuntime = compilationContext.ddTraceRuntime
|
|
611
|
+
const ddPlan = ddTraceRuntime?.finalizeCompilation(compilationContext)
|
|
612
|
+
`).body)
|
|
613
|
+
|
|
614
|
+
const contexts = query(node, 'VariableDeclarator[id.name="executionContext"] > ObjectExpression')
|
|
615
|
+
assert.strictEqual(
|
|
616
|
+
contexts.length,
|
|
617
|
+
1,
|
|
618
|
+
'configureGraphqlJitRuntime: execution context not found'
|
|
619
|
+
)
|
|
620
|
+
|
|
621
|
+
const properties = parse(`({
|
|
622
|
+
ddTrace: ddTraceRuntime?.startExecution(parsedVariables.coerced)
|
|
623
|
+
})`).body[0].expression.properties
|
|
624
|
+
contexts[0].properties.push(...properties)
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/**
|
|
628
|
+
* @param {object} _state
|
|
629
|
+
* @param {import('estree').ObjectExpression} node
|
|
630
|
+
*/
|
|
631
|
+
function configureMercuriusRequest (_state, node) {
|
|
632
|
+
const properties = parse('({ ddCacheLimit: opts.cache })').body[0].expression.properties
|
|
633
|
+
node.properties.push(...properties)
|
|
99
634
|
}
|
|
100
635
|
|
|
101
636
|
/**
|