dd-trace 4.15.0 → 4.17.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 +2 -0
- package/ext/tags.d.ts +1 -0
- package/ext/tags.js +1 -0
- package/index.d.ts +1 -0
- package/package.json +9 -6
- package/packages/datadog-esbuild/index.js +30 -25
- package/packages/datadog-instrumentations/src/body-parser.js +4 -3
- package/packages/datadog-instrumentations/src/cookie-parser.js +37 -0
- package/packages/datadog-instrumentations/src/cucumber.js +24 -4
- package/packages/datadog-instrumentations/src/express-mongo-sanitize.js +45 -0
- package/packages/datadog-instrumentations/src/express.js +3 -2
- package/packages/datadog-instrumentations/src/graphql.js +5 -0
- package/packages/datadog-instrumentations/src/helpers/hooks.js +5 -1
- package/packages/datadog-instrumentations/src/http/server.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +20 -11
- package/packages/datadog-instrumentations/src/knex.js +62 -1
- package/packages/datadog-instrumentations/src/mocha.js +19 -4
- package/packages/datadog-instrumentations/src/mongodb.js +63 -0
- package/packages/datadog-instrumentations/src/mongoose.js +140 -1
- package/packages/datadog-instrumentations/src/next.js +62 -80
- package/packages/datadog-instrumentations/src/pg.js +14 -15
- package/packages/datadog-instrumentations/src/playwright.js +26 -5
- package/packages/datadog-plugin-cucumber/src/index.js +17 -5
- package/packages/datadog-plugin-cypress/src/plugin.js +38 -8
- package/packages/datadog-plugin-jest/src/index.js +19 -4
- package/packages/datadog-plugin-jest/src/util.js +45 -2
- package/packages/datadog-plugin-memcached/src/index.js +10 -5
- package/packages/datadog-plugin-mocha/src/index.js +19 -6
- package/packages/datadog-plugin-mysql/src/index.js +2 -2
- package/packages/datadog-plugin-next/src/index.js +14 -5
- package/packages/datadog-plugin-pg/src/index.js +2 -2
- package/packages/dd-trace/src/appsec/channels.js +4 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/nosql-injection-mongodb-analyzer.js +166 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +21 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/unvalidated-redirect-analyzer.js +3 -3
- package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +1 -2
- package/packages/dd-trace/src/appsec/iast/iast-plugin.js +4 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +25 -12
- package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +4 -4
- package/packages/dd-trace/src/appsec/iast/taint-tracking/secure-marks-generator.js +13 -0
- package/packages/dd-trace/src/appsec/iast/taint-tracking/source-types.js +2 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-analyzers/json-sensitive-analyzer.js +16 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +3 -4
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-regex.js +9 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +13 -1
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +169 -0
- package/packages/dd-trace/src/appsec/iast/vulnerabilities.js +1 -0
- package/packages/dd-trace/src/appsec/index.js +45 -14
- package/packages/dd-trace/src/appsec/recommended.json +549 -24
- package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -1
- package/packages/dd-trace/src/appsec/remote_config/index.js +2 -0
- package/packages/dd-trace/src/appsec/remote_config/manager.js +11 -3
- package/packages/dd-trace/src/appsec/reporter.js +7 -5
- package/packages/dd-trace/src/appsec/telemetry.js +2 -2
- package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +18 -5
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +5 -4
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +1 -14
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +1 -13
- package/packages/dd-trace/src/config.js +8 -0
- package/packages/dd-trace/src/datastreams/processor.js +6 -2
- package/packages/dd-trace/src/format.js +9 -1
- package/packages/dd-trace/src/opentracing/propagation/text_map.js +2 -2
- package/packages/dd-trace/src/opentracing/tracer.js +0 -2
- package/packages/dd-trace/src/plugin_manager.js +4 -3
- package/packages/dd-trace/src/plugins/database.js +14 -4
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/outbound.js +4 -3
- package/packages/dd-trace/src/plugins/util/ci.js +17 -0
- package/packages/dd-trace/src/plugins/util/git.js +26 -4
- package/packages/dd-trace/src/plugins/util/test.js +16 -1
- package/packages/dd-trace/src/profiling/config.js +36 -5
- package/packages/dd-trace/src/profiling/profilers/wall.js +7 -1
- package/packages/dd-trace/src/service-naming/extra-services.js +24 -0
- package/packages/dd-trace/src/telemetry/index.js +10 -1
- package/packages/dd-trace/src/telemetry/metrics.js +0 -5
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
require('./mongodb-core')
|
|
4
|
+
|
|
5
|
+
const {
|
|
6
|
+
channel,
|
|
7
|
+
addHook,
|
|
8
|
+
AsyncResource
|
|
9
|
+
} = require('./helpers/instrument')
|
|
10
|
+
const shimmer = require('../../datadog-shimmer')
|
|
11
|
+
|
|
12
|
+
// collection methods with filter
|
|
13
|
+
const collectionMethodsWithFilter = [
|
|
14
|
+
'count',
|
|
15
|
+
'countDocuments',
|
|
16
|
+
'deleteMany',
|
|
17
|
+
'deleteOne',
|
|
18
|
+
'find',
|
|
19
|
+
'findOneAndDelete',
|
|
20
|
+
'findOneAndReplace',
|
|
21
|
+
'replaceOne'
|
|
22
|
+
] // findOne is ignored because it calls to find
|
|
23
|
+
|
|
24
|
+
const collectionMethodsWithTwoFilters = [
|
|
25
|
+
'findOneAndUpdate',
|
|
26
|
+
'updateMany',
|
|
27
|
+
'updateOne'
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
const startCh = channel('datadog:mongodb:collection:filter:start')
|
|
31
|
+
|
|
32
|
+
addHook({ name: 'mongodb', versions: ['>=3.3 <5', '5', '>=6'] }, mongodb => {
|
|
33
|
+
[...collectionMethodsWithFilter, ...collectionMethodsWithTwoFilters].forEach(methodName => {
|
|
34
|
+
if (!(methodName in mongodb.Collection.prototype)) return
|
|
35
|
+
|
|
36
|
+
const useTwoArguments = collectionMethodsWithTwoFilters.includes(methodName)
|
|
37
|
+
|
|
38
|
+
shimmer.wrap(mongodb.Collection.prototype, methodName, method => {
|
|
39
|
+
return function () {
|
|
40
|
+
if (!startCh.hasSubscribers) {
|
|
41
|
+
return method.apply(this, arguments)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
45
|
+
|
|
46
|
+
return asyncResource.runInAsyncScope(() => {
|
|
47
|
+
const filters = [arguments[0]]
|
|
48
|
+
if (useTwoArguments) {
|
|
49
|
+
filters.push(arguments[1])
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
startCh.publish({
|
|
53
|
+
filters,
|
|
54
|
+
methodName
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
return method.apply(this, arguments)
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
})
|
|
62
|
+
return mongodb
|
|
63
|
+
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
const { addHook } = require('./helpers/instrument')
|
|
3
|
+
const { addHook, channel } = require('./helpers/instrument')
|
|
4
4
|
const { wrapThen } = require('./helpers/promise')
|
|
5
5
|
const { AsyncResource } = require('./helpers/instrument')
|
|
6
6
|
const shimmer = require('../../datadog-shimmer')
|
|
@@ -26,5 +26,144 @@ addHook({
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
shimmer.wrap(mongoose.Collection.prototype, 'addQueue', wrapAddQueue)
|
|
29
|
+
|
|
29
30
|
return mongoose
|
|
30
31
|
})
|
|
32
|
+
|
|
33
|
+
const startCh = channel('datadog:mongoose:model:filter:start')
|
|
34
|
+
const finishCh = channel('datadog:mongoose:model:filter:finish')
|
|
35
|
+
|
|
36
|
+
const collectionMethodsWithFilter = [
|
|
37
|
+
'count',
|
|
38
|
+
'countDocuments',
|
|
39
|
+
'deleteMany',
|
|
40
|
+
'deleteOne',
|
|
41
|
+
'find',
|
|
42
|
+
'findOne',
|
|
43
|
+
'findOneAndDelete',
|
|
44
|
+
'findOneAndReplace',
|
|
45
|
+
'replaceOne',
|
|
46
|
+
'remove'
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
const collectionMethodsWithTwoFilters = [
|
|
50
|
+
'findOneAndUpdate',
|
|
51
|
+
'updateMany',
|
|
52
|
+
'updateOne'
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
addHook({
|
|
56
|
+
name: 'mongoose',
|
|
57
|
+
versions: ['>=4.6.4 <5', '5', '6', '>=7'],
|
|
58
|
+
file: 'lib/model.js'
|
|
59
|
+
}, Model => {
|
|
60
|
+
[...collectionMethodsWithFilter, ...collectionMethodsWithTwoFilters].forEach(methodName => {
|
|
61
|
+
const useTwoArguments = collectionMethodsWithTwoFilters.includes(methodName)
|
|
62
|
+
if (!(methodName in Model)) return
|
|
63
|
+
|
|
64
|
+
shimmer.wrap(Model, methodName, method => {
|
|
65
|
+
return function wrappedModelMethod () {
|
|
66
|
+
if (!startCh.hasSubscribers) {
|
|
67
|
+
return method.apply(this, arguments)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
71
|
+
|
|
72
|
+
const filters = [arguments[0]]
|
|
73
|
+
if (useTwoArguments) {
|
|
74
|
+
filters.push(arguments[1])
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const finish = asyncResource.bind(function () {
|
|
78
|
+
finishCh.publish()
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
let callbackWrapped = false
|
|
82
|
+
const lastArgumentIndex = arguments.length - 1
|
|
83
|
+
|
|
84
|
+
if (typeof arguments[lastArgumentIndex] === 'function') {
|
|
85
|
+
// is a callback, wrap it to execute finish()
|
|
86
|
+
shimmer.wrap(arguments, lastArgumentIndex, originalCb => {
|
|
87
|
+
return function () {
|
|
88
|
+
finish()
|
|
89
|
+
|
|
90
|
+
return originalCb.apply(this, arguments)
|
|
91
|
+
}
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
callbackWrapped = true
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return asyncResource.runInAsyncScope(() => {
|
|
98
|
+
startCh.publish({
|
|
99
|
+
filters,
|
|
100
|
+
methodName
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
const res = method.apply(this, arguments)
|
|
104
|
+
|
|
105
|
+
// if it is not callback, wrap exec method and its then
|
|
106
|
+
if (!callbackWrapped) {
|
|
107
|
+
shimmer.wrap(res, 'exec', originalExec => {
|
|
108
|
+
return function wrappedExec () {
|
|
109
|
+
const execResult = originalExec.apply(this, arguments)
|
|
110
|
+
|
|
111
|
+
// wrap them method, wrap resolve and reject methods
|
|
112
|
+
shimmer.wrap(execResult, 'then', originalThen => {
|
|
113
|
+
return function wrappedThen () {
|
|
114
|
+
const resolve = arguments[0]
|
|
115
|
+
const reject = arguments[1]
|
|
116
|
+
|
|
117
|
+
// not using shimmer here because resolve/reject could be empty
|
|
118
|
+
arguments[0] = function wrappedResolve () {
|
|
119
|
+
finish()
|
|
120
|
+
|
|
121
|
+
if (resolve) {
|
|
122
|
+
return resolve.apply(this, arguments)
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
arguments[1] = function wrappedReject () {
|
|
127
|
+
finish()
|
|
128
|
+
|
|
129
|
+
if (reject) {
|
|
130
|
+
return reject.apply(this, arguments)
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return originalThen.apply(this, arguments)
|
|
135
|
+
}
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
return execResult
|
|
139
|
+
}
|
|
140
|
+
})
|
|
141
|
+
}
|
|
142
|
+
return res
|
|
143
|
+
})
|
|
144
|
+
}
|
|
145
|
+
})
|
|
146
|
+
})
|
|
147
|
+
|
|
148
|
+
return Model
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
const sanitizeFilterFinishCh = channel('datadog:mongoose:sanitize-filter:finish')
|
|
152
|
+
|
|
153
|
+
addHook({
|
|
154
|
+
name: 'mongoose',
|
|
155
|
+
versions: ['6', '>=7'],
|
|
156
|
+
file: 'lib/helpers/query/sanitizeFilter.js'
|
|
157
|
+
}, sanitizeFilter => {
|
|
158
|
+
return shimmer.wrap(sanitizeFilter, function wrappedSanitizeFilter () {
|
|
159
|
+
const sanitizedObject = sanitizeFilter.apply(this, arguments)
|
|
160
|
+
|
|
161
|
+
if (sanitizeFilterFinishCh.hasSubscribers) {
|
|
162
|
+
sanitizeFilterFinishCh.publish({
|
|
163
|
+
sanitizedObject
|
|
164
|
+
})
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return sanitizedObject
|
|
168
|
+
})
|
|
169
|
+
})
|
|
@@ -10,9 +10,10 @@ const startChannel = channel('apm:next:request:start')
|
|
|
10
10
|
const finishChannel = channel('apm:next:request:finish')
|
|
11
11
|
const errorChannel = channel('apm:next:request:error')
|
|
12
12
|
const pageLoadChannel = channel('apm:next:page:load')
|
|
13
|
+
const bodyParsedChannel = channel('apm:next:body-parsed')
|
|
14
|
+
const queryParsedChannel = channel('apm:next:query-parsed')
|
|
13
15
|
|
|
14
16
|
const requests = new WeakSet()
|
|
15
|
-
const requestToNextjsPagePath = new WeakMap()
|
|
16
17
|
|
|
17
18
|
function wrapHandleRequest (handleRequest) {
|
|
18
19
|
return function (req, res, pathname, query) {
|
|
@@ -29,9 +30,9 @@ function wrapHandleApiRequest (handleApiRequest) {
|
|
|
29
30
|
if (!handled) return handled
|
|
30
31
|
|
|
31
32
|
return this.hasPage(pathname).then(pageFound => {
|
|
32
|
-
const
|
|
33
|
+
const pageData = pageFound ? { page: pathname } : getPageFromPath(pathname, this.dynamicRoutes)
|
|
33
34
|
|
|
34
|
-
pageLoadChannel.publish(
|
|
35
|
+
pageLoadChannel.publish(pageData)
|
|
35
36
|
|
|
36
37
|
return handled
|
|
37
38
|
})
|
|
@@ -84,15 +85,19 @@ function wrapFindPageComponents (findPageComponents) {
|
|
|
84
85
|
const result = findPageComponents.apply(this, arguments)
|
|
85
86
|
|
|
86
87
|
if (result) {
|
|
87
|
-
pageLoadChannel.publish(
|
|
88
|
+
pageLoadChannel.publish(getPagePath(pathname))
|
|
88
89
|
}
|
|
89
90
|
|
|
90
91
|
return result
|
|
91
92
|
}
|
|
92
93
|
}
|
|
93
94
|
|
|
94
|
-
function getPagePath (
|
|
95
|
-
|
|
95
|
+
function getPagePath (maybePage) {
|
|
96
|
+
if (typeof maybePage !== 'object') return { page: maybePage }
|
|
97
|
+
|
|
98
|
+
const isAppPath = maybePage.isAppPath
|
|
99
|
+
const page = maybePage.pathname || maybePage.page
|
|
100
|
+
return { page, isAppPath }
|
|
96
101
|
}
|
|
97
102
|
|
|
98
103
|
function getPageFromPath (page, dynamicRoutes = []) {
|
|
@@ -133,57 +138,16 @@ function instrument (req, res, handler) {
|
|
|
133
138
|
})
|
|
134
139
|
}
|
|
135
140
|
|
|
136
|
-
function
|
|
137
|
-
return function (
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function wrapInitialize (initialize) {
|
|
144
|
-
return async function () {
|
|
145
|
-
const result = await initialize.apply(this, arguments)
|
|
146
|
-
if (Array.isArray(result)) {
|
|
147
|
-
const requestHandler = result[0]
|
|
148
|
-
result[0] = shimmer.wrap(requestHandler, wrapRequestHandler(requestHandler))
|
|
149
|
-
}
|
|
150
|
-
return result
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
function wrapRequestHandler (requestHandler) {
|
|
155
|
-
return function (req, res) {
|
|
156
|
-
return instrument(req, res, async () => {
|
|
157
|
-
const result = await requestHandler.apply(this, arguments) // apply here first to get page path association
|
|
158
|
-
|
|
159
|
-
const page = requestToNextjsPagePath.get(req)
|
|
160
|
-
if (page && pageLoadChannel.hasSubscribers) pageLoadChannel.publish({ page })
|
|
141
|
+
function wrapServeStatic (serveStatic) {
|
|
142
|
+
return function (req, res, path) {
|
|
143
|
+
return instrument(req, res, () => {
|
|
144
|
+
if (pageLoadChannel.hasSubscribers && path) pageLoadChannel.publish({ page: path })
|
|
161
145
|
|
|
162
|
-
return
|
|
146
|
+
return serveStatic.apply(this, arguments)
|
|
163
147
|
})
|
|
164
148
|
}
|
|
165
149
|
}
|
|
166
150
|
|
|
167
|
-
// these two functions make sure we get path groups for routes in standalone,
|
|
168
|
-
// as it doesn't route through `next-server`/`base-server`
|
|
169
|
-
function wrapGetResolveRoutes (getResolveRoutes) {
|
|
170
|
-
return function () {
|
|
171
|
-
const result = getResolveRoutes.apply(this, arguments)
|
|
172
|
-
return shimmer.wrap(result, wrapResolveRoutes(result))
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
function wrapResolveRoutes (resolveRoutes) {
|
|
177
|
-
return async function (req) {
|
|
178
|
-
const result = await resolveRoutes.apply(this, arguments)
|
|
179
|
-
if (result && result.matchedOutput) {
|
|
180
|
-
const path = result.matchedOutput.itemPath
|
|
181
|
-
requestToNextjsPagePath.set(req, path)
|
|
182
|
-
}
|
|
183
|
-
return result
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
151
|
function finish (ctx, result, err) {
|
|
188
152
|
if (err) {
|
|
189
153
|
ctx.error = err
|
|
@@ -201,25 +165,21 @@ function finish (ctx, result, err) {
|
|
|
201
165
|
|
|
202
166
|
addHook({
|
|
203
167
|
name: 'next',
|
|
204
|
-
versions: ['>=
|
|
205
|
-
file: 'dist/server/
|
|
206
|
-
},
|
|
207
|
-
|
|
208
|
-
addHook({
|
|
209
|
-
name: 'next',
|
|
210
|
-
versions: ['13.4.13'],
|
|
211
|
-
file: 'dist/server/lib/setup-server-worker.js'
|
|
212
|
-
}, setupServerWorker => shimmer.wrap(setupServerWorker, 'initializeServerWorker', wrapSetupServerWorker))
|
|
168
|
+
versions: ['>=11.1'],
|
|
169
|
+
file: 'dist/server/serve-static.js'
|
|
170
|
+
}, serveStatic => shimmer.wrap(serveStatic, 'serveStatic', wrapServeStatic))
|
|
213
171
|
|
|
214
172
|
addHook({
|
|
215
173
|
name: 'next',
|
|
216
|
-
versions: ['>=
|
|
217
|
-
file: 'dist/server/
|
|
218
|
-
},
|
|
174
|
+
versions: DD_MAJOR >= 4 ? ['>=10.2 <11.1'] : ['>=9.5 <11.1'],
|
|
175
|
+
file: 'dist/next-server/server/serve-static.js'
|
|
176
|
+
}, serveStatic => shimmer.wrap(serveStatic, 'serveStatic', wrapServeStatic))
|
|
219
177
|
|
|
220
178
|
addHook({ name: 'next', versions: ['>=13.2'], file: 'dist/server/next-server.js' }, nextServer => {
|
|
221
179
|
const Server = nextServer.default
|
|
222
180
|
|
|
181
|
+
shimmer.wrap(Server.prototype, 'handleRequest', wrapHandleRequest)
|
|
182
|
+
shimmer.wrap(Server.prototype, 'handleApiRequest', wrapHandleApiRequestWithMatch)
|
|
223
183
|
shimmer.wrap(Server.prototype, 'renderToResponse', wrapRenderToResponse)
|
|
224
184
|
shimmer.wrap(Server.prototype, 'renderErrorToResponse', wrapRenderErrorToResponse)
|
|
225
185
|
shimmer.wrap(Server.prototype, 'findPageComponents', wrapFindPageComponents)
|
|
@@ -227,22 +187,6 @@ addHook({ name: 'next', versions: ['>=13.2'], file: 'dist/server/next-server.js'
|
|
|
227
187
|
return nextServer
|
|
228
188
|
})
|
|
229
189
|
|
|
230
|
-
// these functions wrapped in all versions above 13.2 except:
|
|
231
|
-
// 13.4.13 due to tests failing when these functions are wrapped
|
|
232
|
-
// 13.4.14 due to it not being in the NPM registry/officially released
|
|
233
|
-
addHook({
|
|
234
|
-
name: 'next',
|
|
235
|
-
versions: ['>=13.2 <13.4.13', '>=13.4.15'],
|
|
236
|
-
file: 'dist/server/next-server.js'
|
|
237
|
-
}, nextServer => {
|
|
238
|
-
const Server = nextServer.default
|
|
239
|
-
|
|
240
|
-
shimmer.wrap(Server.prototype, 'handleRequest', wrapHandleRequest)
|
|
241
|
-
shimmer.wrap(Server.prototype, 'handleApiRequest', wrapHandleApiRequestWithMatch)
|
|
242
|
-
|
|
243
|
-
return nextServer
|
|
244
|
-
})
|
|
245
|
-
|
|
246
190
|
addHook({ name: 'next', versions: ['>=11.1 <13.2'], file: 'dist/server/next-server.js' }, nextServer => {
|
|
247
191
|
const Server = nextServer.default
|
|
248
192
|
|
|
@@ -270,3 +214,41 @@ addHook({
|
|
|
270
214
|
|
|
271
215
|
return nextServer
|
|
272
216
|
})
|
|
217
|
+
|
|
218
|
+
addHook({
|
|
219
|
+
name: 'next',
|
|
220
|
+
versions: ['>=13'],
|
|
221
|
+
file: 'dist/server/web/spec-extension/request.js'
|
|
222
|
+
}, request => {
|
|
223
|
+
const nextUrlDescriptor = Object.getOwnPropertyDescriptor(request.NextRequest.prototype, 'nextUrl')
|
|
224
|
+
shimmer.wrap(nextUrlDescriptor, 'get', function (originalGet) {
|
|
225
|
+
return function wrappedGet () {
|
|
226
|
+
const nextUrl = originalGet.apply(this, arguments)
|
|
227
|
+
if (queryParsedChannel.hasSubscribers) {
|
|
228
|
+
const query = {}
|
|
229
|
+
for (const key of nextUrl.searchParams.keys()) {
|
|
230
|
+
if (!query[key]) {
|
|
231
|
+
query[key] = nextUrl.searchParams.getAll(key)
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
queryParsedChannel.publish({ query })
|
|
236
|
+
}
|
|
237
|
+
return nextUrl
|
|
238
|
+
}
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
Object.defineProperty(request.NextRequest.prototype, 'nextUrl', nextUrlDescriptor)
|
|
242
|
+
|
|
243
|
+
shimmer.massWrap(request.NextRequest.prototype, ['text', 'json'], function (originalMethod) {
|
|
244
|
+
return async function wrappedJson () {
|
|
245
|
+
const body = await originalMethod.apply(this, arguments)
|
|
246
|
+
bodyParsedChannel.publish({
|
|
247
|
+
body
|
|
248
|
+
})
|
|
249
|
+
return body
|
|
250
|
+
}
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
return request
|
|
254
|
+
})
|
|
@@ -39,28 +39,27 @@ function wrapQuery (query) {
|
|
|
39
39
|
? arguments[0]
|
|
40
40
|
: { text: arguments[0] }
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
//
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
42
|
+
const textProp = Object.getOwnPropertyDescriptor(pgQuery, 'text')
|
|
43
|
+
|
|
44
|
+
// Only alter `text` property if safe to do so.
|
|
45
|
+
if (!textProp || textProp.configurable) {
|
|
46
|
+
const originalText = pgQuery.text
|
|
47
|
+
|
|
48
|
+
Object.defineProperty(pgQuery, 'text', {
|
|
49
|
+
get () {
|
|
50
|
+
return this?.__ddInjectableQuery || originalText
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
53
|
}
|
|
54
|
-
Object.setPrototypeOf(newQuery, pgQuery)
|
|
55
54
|
|
|
56
55
|
return asyncResource.runInAsyncScope(() => {
|
|
57
56
|
startCh.publish({
|
|
58
57
|
params: this.connectionParameters,
|
|
59
|
-
query:
|
|
58
|
+
query: pgQuery,
|
|
60
59
|
processId
|
|
61
60
|
})
|
|
62
61
|
|
|
63
|
-
arguments[0] =
|
|
62
|
+
arguments[0] = pgQuery
|
|
64
63
|
|
|
65
64
|
const finish = asyncResource.bind(function (error) {
|
|
66
65
|
if (error) {
|
|
@@ -73,7 +72,7 @@ function wrapQuery (query) {
|
|
|
73
72
|
const queryQueue = this.queryQueue || this._queryQueue
|
|
74
73
|
const activeQuery = this.activeQuery || this._activeQuery
|
|
75
74
|
|
|
76
|
-
newQuery = queryQueue[queryQueue.length - 1] || activeQuery
|
|
75
|
+
const newQuery = queryQueue[queryQueue.length - 1] || activeQuery
|
|
77
76
|
|
|
78
77
|
if (!newQuery) {
|
|
79
78
|
return retval
|
|
@@ -181,6 +181,15 @@ function dispatcherHook (dispatcherExport) {
|
|
|
181
181
|
return dispatcherExport
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
+
function getTestByTestId (dispatcher, testId) {
|
|
185
|
+
if (dispatcher._testById) {
|
|
186
|
+
return dispatcher._testById.get(testId)?.test
|
|
187
|
+
}
|
|
188
|
+
if (dispatcher._allTests) {
|
|
189
|
+
return dispatcher._allTests.find(({ id }) => id === testId)
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
184
193
|
function dispatcherHookNew (dispatcherExport, runWrapper) {
|
|
185
194
|
shimmer.wrap(dispatcherExport.Dispatcher.prototype, 'run', runWrapper)
|
|
186
195
|
shimmer.wrap(dispatcherExport.Dispatcher.prototype, '_createWorker', createWorker => function () {
|
|
@@ -188,11 +197,11 @@ function dispatcherHookNew (dispatcherExport, runWrapper) {
|
|
|
188
197
|
const worker = createWorker.apply(this, arguments)
|
|
189
198
|
|
|
190
199
|
worker.on('testBegin', ({ testId }) => {
|
|
191
|
-
const
|
|
200
|
+
const test = getTestByTestId(dispatcher, testId)
|
|
192
201
|
testBeginHandler(test)
|
|
193
202
|
})
|
|
194
203
|
worker.on('testEnd', ({ testId, status, errors }) => {
|
|
195
|
-
const
|
|
204
|
+
const test = getTestByTestId(dispatcher, testId)
|
|
196
205
|
|
|
197
206
|
testEndHandler(test, STATUS_TO_TEST_STATUS[status], errors && errors[0])
|
|
198
207
|
})
|
|
@@ -254,7 +263,7 @@ addHook({
|
|
|
254
263
|
addHook({
|
|
255
264
|
name: '@playwright/test',
|
|
256
265
|
file: 'lib/dispatcher.js',
|
|
257
|
-
versions: ['>=1.18.0
|
|
266
|
+
versions: ['>=1.18.0 <1.30.0']
|
|
258
267
|
}, dispatcherHook)
|
|
259
268
|
|
|
260
269
|
addHook({
|
|
@@ -266,11 +275,23 @@ addHook({
|
|
|
266
275
|
addHook({
|
|
267
276
|
name: '@playwright/test',
|
|
268
277
|
file: 'lib/runner/dispatcher.js',
|
|
269
|
-
versions: ['>=1.31.0']
|
|
278
|
+
versions: ['>=1.31.0 <1.38.0']
|
|
270
279
|
}, (dispatcher) => dispatcherHookNew(dispatcher, dispatcherRunWrapperNew))
|
|
271
280
|
|
|
272
281
|
addHook({
|
|
273
282
|
name: '@playwright/test',
|
|
274
283
|
file: 'lib/runner/runner.js',
|
|
275
|
-
versions: ['>=1.31.0']
|
|
284
|
+
versions: ['>=1.31.0 <1.38.0']
|
|
276
285
|
}, runnerHook)
|
|
286
|
+
|
|
287
|
+
// From >=1.38.0
|
|
288
|
+
addHook({
|
|
289
|
+
name: 'playwright',
|
|
290
|
+
file: 'lib/runner/runner.js',
|
|
291
|
+
versions: ['>=1.38.0']
|
|
292
|
+
}, runnerHook)
|
|
293
|
+
addHook({
|
|
294
|
+
name: 'playwright',
|
|
295
|
+
file: 'lib/runner/dispatcher.js',
|
|
296
|
+
versions: ['>=1.38.0']
|
|
297
|
+
}, (dispatcher) => dispatcherHookNew(dispatcher, dispatcherRunWrapperNew))
|
|
@@ -10,7 +10,9 @@ const {
|
|
|
10
10
|
finishAllTraceSpans,
|
|
11
11
|
getTestSuitePath,
|
|
12
12
|
getTestSuiteCommonTags,
|
|
13
|
-
addIntelligentTestRunnerSpanTags
|
|
13
|
+
addIntelligentTestRunnerSpanTags,
|
|
14
|
+
TEST_ITR_UNSKIPPABLE,
|
|
15
|
+
TEST_ITR_FORCED_RUN
|
|
14
16
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
15
17
|
const { RESOURCE_NAME } = require('../../../ext/tags')
|
|
16
18
|
const { COMPONENT, ERROR_MESSAGE } = require('../../dd-trace/src/constants')
|
|
@@ -29,7 +31,9 @@ class CucumberPlugin extends CiPlugin {
|
|
|
29
31
|
status,
|
|
30
32
|
isSuitesSkipped,
|
|
31
33
|
numSkippedSuites,
|
|
32
|
-
testCodeCoverageLinesTotal
|
|
34
|
+
testCodeCoverageLinesTotal,
|
|
35
|
+
hasUnskippableSuites,
|
|
36
|
+
hasForcedToRunSuites
|
|
33
37
|
}) => {
|
|
34
38
|
const { isSuitesSkippingEnabled, isCodeCoverageEnabled } = this.itrConfig || {}
|
|
35
39
|
addIntelligentTestRunnerSpanTags(
|
|
@@ -41,7 +45,9 @@ class CucumberPlugin extends CiPlugin {
|
|
|
41
45
|
isCodeCoverageEnabled,
|
|
42
46
|
testCodeCoverageLinesTotal,
|
|
43
47
|
skippingCount: numSkippedSuites,
|
|
44
|
-
skippingType: 'suite'
|
|
48
|
+
skippingType: 'suite',
|
|
49
|
+
hasUnskippableSuites,
|
|
50
|
+
hasForcedToRunSuites
|
|
45
51
|
}
|
|
46
52
|
)
|
|
47
53
|
|
|
@@ -55,13 +61,19 @@ class CucumberPlugin extends CiPlugin {
|
|
|
55
61
|
this.tracer._exporter.flush()
|
|
56
62
|
})
|
|
57
63
|
|
|
58
|
-
this.addSub('ci:cucumber:test-suite:start', (
|
|
64
|
+
this.addSub('ci:cucumber:test-suite:start', ({ testSuitePath, isUnskippable, isForcedToRun }) => {
|
|
59
65
|
const testSuiteMetadata = getTestSuiteCommonTags(
|
|
60
66
|
this.command,
|
|
61
67
|
this.frameworkVersion,
|
|
62
|
-
|
|
68
|
+
testSuitePath,
|
|
63
69
|
'cucumber'
|
|
64
70
|
)
|
|
71
|
+
if (isUnskippable) {
|
|
72
|
+
testSuiteMetadata[TEST_ITR_UNSKIPPABLE] = 'true'
|
|
73
|
+
}
|
|
74
|
+
if (isForcedToRun) {
|
|
75
|
+
testSuiteMetadata[TEST_ITR_FORCED_RUN] = 'true'
|
|
76
|
+
}
|
|
65
77
|
this.testSuiteSpan = this.tracer.startSpan('cucumber.test_suite', {
|
|
66
78
|
childOf: this.testModuleSpan,
|
|
67
79
|
tags: {
|