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
package/LICENSE-3rdparty.csv
CHANGED
|
@@ -14,6 +14,7 @@ require,import-in-the-middle,Apache license 2.0,Copyright 2021 Datadog Inc.
|
|
|
14
14
|
require,int64-buffer,MIT,Copyright 2015-2016 Yusuke Kawasaki
|
|
15
15
|
require,ipaddr.js,MIT,Copyright 2011-2017 whitequark
|
|
16
16
|
require,istanbul-lib-coverage,BSD-3-Clause,Copyright 2012-2015 Yahoo! Inc.
|
|
17
|
+
require,jest-docblock,MIT,Copyright Meta Platforms, Inc. and affiliates.
|
|
17
18
|
require,koalas,MIT,Copyright 2013-2017 Brian Woodward
|
|
18
19
|
require,limiter,MIT,Copyright 2011 John Hurliman
|
|
19
20
|
require,lodash.kebabcase,MIT,Copyright JS Foundation and other contributors
|
|
@@ -32,6 +33,7 @@ require,retry,MIT,Copyright 2011 Tim Koschützki Felix Geisendörfer
|
|
|
32
33
|
require,semver,ISC,Copyright Isaac Z. Schlueter and Contributors
|
|
33
34
|
dev,@types/node,MIT,Copyright Authors
|
|
34
35
|
dev,autocannon,MIT,Copyright 2016 Matteo Collina
|
|
36
|
+
dev,aws-sdk,Apache 2.0,Copyright 2012-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
35
37
|
dev,axios,MIT,Copyright 2014-present Matt Zabriskie
|
|
36
38
|
dev,benchmark,MIT,Copyright 2010-2016 Mathias Bynens Robert Kieffer John-David Dalton
|
|
37
39
|
dev,body-parser,MIT,Copyright 2014 Jonathan Ong 2014-2015 Douglas Christopher Wilson
|
package/ext/tags.d.ts
CHANGED
package/ext/tags.js
CHANGED
package/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dd-trace",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.17.0",
|
|
4
4
|
"description": "Datadog APM tracing client for JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"typings": "index.d.ts",
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
"test:integration:cypress": "mocha --colors --timeout 30000 \"integration-tests/cypress/*.spec.js\"",
|
|
38
38
|
"test:integration:playwright": "mocha --colors --timeout 30000 \"integration-tests/playwright/*.spec.js\"",
|
|
39
39
|
"test:integration:serverless": "mocha --colors --timeout 30000 \"integration-tests/serverless/*.spec.js\"",
|
|
40
|
-
"test:integration:plugins": "mocha --colors --
|
|
40
|
+
"test:integration:plugins": "mocha --colors --exit -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/datadog-plugin-@($(echo $PLUGINS))/test/integration-test/**/*.spec.js\"",
|
|
41
|
+
"test:unit:plugins": "mocha --colors --exit -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/datadog-instrumentations/test/@($(echo $PLUGINS)).spec.js\" \"packages/datadog-plugin-@($(echo $PLUGINS))/test/**/*.spec.js\" --exclude \"packages/datadog-plugin-@($(echo $PLUGINS))/test/integration-test/**/*.spec.js\"",
|
|
41
42
|
"test:shimmer": "mocha --colors 'packages/datadog-shimmer/test/**/*.spec.js'",
|
|
42
43
|
"test:shimmer:ci": "nyc --no-clean --include 'packages/datadog-shimmer/src/**/*.js' -- npm run test:shimmer",
|
|
43
44
|
"leak:core": "node ./scripts/install_plugin_modules && (cd packages/memwatch && yarn) && NODE_PATH=./packages/memwatch/node_modules node --no-warnings ./node_modules/.bin/tape 'packages/dd-trace/test/leak/**/*.js'",
|
|
@@ -58,7 +59,7 @@
|
|
|
58
59
|
"apm"
|
|
59
60
|
],
|
|
60
61
|
"author": "Datadog Inc. <info@datadoghq.com>",
|
|
61
|
-
"license": "BSD-3-Clause",
|
|
62
|
+
"license": "(Apache-2.0 OR BSD-3-Clause)",
|
|
62
63
|
"bugs": {
|
|
63
64
|
"url": "https://github.com/DataDog/dd-trace-js/issues"
|
|
64
65
|
},
|
|
@@ -67,11 +68,11 @@
|
|
|
67
68
|
"node": ">=16"
|
|
68
69
|
},
|
|
69
70
|
"dependencies": {
|
|
70
|
-
"@datadog/native-appsec": "^
|
|
71
|
+
"@datadog/native-appsec": "^4.0.0",
|
|
71
72
|
"@datadog/native-iast-rewriter": "2.1.3",
|
|
72
|
-
"@datadog/native-iast-taint-tracking": "1.
|
|
73
|
+
"@datadog/native-iast-taint-tracking": "1.6.1",
|
|
73
74
|
"@datadog/native-metrics": "^2.0.0",
|
|
74
|
-
"@datadog/pprof": "
|
|
75
|
+
"@datadog/pprof": "4.0.0",
|
|
75
76
|
"@datadog/sketches-js": "^2.1.0",
|
|
76
77
|
"@opentelemetry/api": "^1.0.0",
|
|
77
78
|
"@opentelemetry/core": "^1.14.0",
|
|
@@ -82,6 +83,7 @@
|
|
|
82
83
|
"int64-buffer": "^0.1.9",
|
|
83
84
|
"ipaddr.js": "^2.1.0",
|
|
84
85
|
"istanbul-lib-coverage": "3.2.0",
|
|
86
|
+
"jest-docblock": "^29.7.0",
|
|
85
87
|
"koalas": "^1.0.2",
|
|
86
88
|
"limiter": "^1.1.4",
|
|
87
89
|
"lodash.kebabcase": "^4.1.1",
|
|
@@ -102,6 +104,7 @@
|
|
|
102
104
|
"devDependencies": {
|
|
103
105
|
"@types/node": ">=16",
|
|
104
106
|
"autocannon": "^4.5.2",
|
|
107
|
+
"aws-sdk": "^2.1446.0",
|
|
105
108
|
"axios": "^0.21.2",
|
|
106
109
|
"benchmark": "^2.1.4",
|
|
107
110
|
"body-parser": "^1.20.2",
|
|
@@ -23,11 +23,12 @@ for (const instrumentation of Object.values(instrumentations)) {
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
const NAMESPACE = 'datadog'
|
|
27
26
|
const NM = 'node_modules/'
|
|
28
27
|
const INSTRUMENTED = Object.keys(instrumentations)
|
|
29
28
|
const RAW_BUILTINS = require('module').builtinModules
|
|
30
29
|
const CHANNEL = 'dd-trace:bundler:load'
|
|
30
|
+
const path = require('path')
|
|
31
|
+
const fs = require('fs')
|
|
31
32
|
|
|
32
33
|
const builtins = new Set()
|
|
33
34
|
|
|
@@ -109,55 +110,59 @@ module.exports.setup = function (build) {
|
|
|
109
110
|
// https://esbuild.github.io/plugins/#on-resolve-arguments
|
|
110
111
|
return {
|
|
111
112
|
path: fullPathToModule,
|
|
112
|
-
namespace: NAMESPACE,
|
|
113
113
|
pluginData: {
|
|
114
114
|
version: packageJson.version,
|
|
115
115
|
pkg: extracted.pkg,
|
|
116
116
|
path: extracted.path,
|
|
117
117
|
full: fullPathToModule,
|
|
118
118
|
raw: args.path,
|
|
119
|
+
pkgOfInterest: true,
|
|
119
120
|
internal
|
|
120
121
|
}
|
|
121
122
|
}
|
|
122
|
-
} else if (args.namespace === NAMESPACE) {
|
|
123
|
-
// The datadog namespace is used when requiring files that are injected during the onLoad stage
|
|
124
|
-
|
|
125
|
-
if (builtins.has(args.path)) return
|
|
126
|
-
|
|
127
|
-
return {
|
|
128
|
-
path: require.resolve(args.path, { paths: [ args.resolveDir ] }),
|
|
129
|
-
namespace: 'file'
|
|
130
|
-
}
|
|
131
123
|
}
|
|
132
124
|
})
|
|
133
125
|
|
|
134
|
-
build.onLoad({ filter:
|
|
126
|
+
build.onLoad({ filter: /.*/ }, args => {
|
|
127
|
+
if (!args.pluginData?.pkgOfInterest) {
|
|
128
|
+
return
|
|
129
|
+
}
|
|
130
|
+
|
|
135
131
|
const data = args.pluginData
|
|
136
132
|
|
|
137
133
|
if (DEBUG) console.log(`LOAD: ${data.pkg}@${data.version}, pkg "${data.path}"`)
|
|
138
134
|
|
|
139
|
-
const
|
|
135
|
+
const pkgPath = data.raw !== data.pkg
|
|
140
136
|
? `${data.pkg}/${data.path}`
|
|
141
137
|
: data.pkg
|
|
142
138
|
|
|
139
|
+
// Read the content of the module file of interest
|
|
140
|
+
const fileCode = fs.readFileSync(args.path, 'utf8')
|
|
141
|
+
|
|
143
142
|
const contents = `
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
143
|
+
(function() {
|
|
144
|
+
${fileCode}
|
|
145
|
+
})(...arguments);
|
|
146
|
+
{
|
|
147
|
+
const dc = require('diagnostics_channel');
|
|
148
|
+
const ch = dc.channel('${CHANNEL}');
|
|
149
|
+
const mod = module.exports
|
|
150
|
+
const payload = {
|
|
151
|
+
module: mod,
|
|
152
|
+
version: '${data.version}',
|
|
153
|
+
package: '${data.pkg}',
|
|
154
|
+
path: '${pkgPath}'
|
|
155
|
+
};
|
|
156
|
+
ch.publish(payload);
|
|
157
|
+
module.exports = payload.module;
|
|
158
|
+
}
|
|
155
159
|
`
|
|
156
160
|
|
|
157
161
|
// https://esbuild.github.io/plugins/#on-load-results
|
|
158
162
|
return {
|
|
159
163
|
contents,
|
|
160
|
-
loader: 'js'
|
|
164
|
+
loader: 'js',
|
|
165
|
+
resolveDir: path.dirname(args.path)
|
|
161
166
|
}
|
|
162
167
|
})
|
|
163
168
|
}
|
|
@@ -10,13 +10,14 @@ function publishRequestBodyAndNext (req, res, next) {
|
|
|
10
10
|
return function () {
|
|
11
11
|
if (bodyParserReadCh.hasSubscribers && req) {
|
|
12
12
|
const abortController = new AbortController()
|
|
13
|
+
const body = req.body
|
|
13
14
|
|
|
14
|
-
bodyParserReadCh.publish({ req, res, abortController })
|
|
15
|
+
bodyParserReadCh.publish({ req, res, body, abortController })
|
|
15
16
|
|
|
16
17
|
if (abortController.signal.aborted) return
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
next.apply(this, arguments)
|
|
20
|
+
return next.apply(this, arguments)
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
|
|
@@ -27,6 +28,6 @@ addHook({
|
|
|
27
28
|
}, read => {
|
|
28
29
|
return shimmer.wrap(read, function (req, res, next) {
|
|
29
30
|
arguments[2] = publishRequestBodyAndNext(req, res, next)
|
|
30
|
-
read.apply(this, arguments)
|
|
31
|
+
return read.apply(this, arguments)
|
|
31
32
|
})
|
|
32
33
|
})
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { AbortController } = require('node-abort-controller') // AbortController is not available in node <15
|
|
4
|
+
const shimmer = require('../../datadog-shimmer')
|
|
5
|
+
const { channel, addHook } = require('./helpers/instrument')
|
|
6
|
+
|
|
7
|
+
const cookieParserReadCh = channel('datadog:cookie-parser:read:finish')
|
|
8
|
+
|
|
9
|
+
function publishRequestCookieAndNext (req, res, next) {
|
|
10
|
+
return function cookieParserWrapper () {
|
|
11
|
+
if (cookieParserReadCh.hasSubscribers && req) {
|
|
12
|
+
const abortController = new AbortController()
|
|
13
|
+
|
|
14
|
+
const mergedCookies = Object.assign({}, req.cookies, req.signedCookies)
|
|
15
|
+
|
|
16
|
+
cookieParserReadCh.publish({ req, res, abortController, cookies: mergedCookies })
|
|
17
|
+
|
|
18
|
+
if (abortController.signal.aborted) return
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return next.apply(this, arguments)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
addHook({
|
|
26
|
+
name: 'cookie-parser',
|
|
27
|
+
versions: ['>=1.0.0']
|
|
28
|
+
}, cookieParser => {
|
|
29
|
+
return shimmer.wrap(cookieParser, function () {
|
|
30
|
+
const cookieMiddleware = cookieParser.apply(this, arguments)
|
|
31
|
+
|
|
32
|
+
return shimmer.wrap(cookieMiddleware, function (req, res, next) {
|
|
33
|
+
arguments[2] = publishRequestCookieAndNext(req, res, next)
|
|
34
|
+
return cookieMiddleware.apply(this, arguments)
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
})
|
|
@@ -31,6 +31,10 @@ const {
|
|
|
31
31
|
getTestSuitePath
|
|
32
32
|
} = require('../../dd-trace/src/plugins/util/test')
|
|
33
33
|
|
|
34
|
+
const isMarkedAsUnskippable = (pickle) => {
|
|
35
|
+
return !!pickle.tags.find(tag => tag.name === '@datadog:unskippable')
|
|
36
|
+
}
|
|
37
|
+
|
|
34
38
|
// We'll preserve the original coverage here
|
|
35
39
|
const originalCoverageMap = createCoverageMap()
|
|
36
40
|
|
|
@@ -39,6 +43,9 @@ const patched = new WeakSet()
|
|
|
39
43
|
|
|
40
44
|
let pickleByFile = {}
|
|
41
45
|
const pickleResultByFile = {}
|
|
46
|
+
let skippableSuites = []
|
|
47
|
+
let isForcedToRun = false
|
|
48
|
+
let isUnskippable = false
|
|
42
49
|
|
|
43
50
|
function getSuiteStatusFromTestStatuses (testStatuses) {
|
|
44
51
|
if (testStatuses.some(status => status === 'fail')) {
|
|
@@ -91,7 +98,11 @@ function wrapRun (pl, isLatestVersion) {
|
|
|
91
98
|
const testSuiteFullPath = this.pickle.uri
|
|
92
99
|
|
|
93
100
|
if (!pickleResultByFile[testSuiteFullPath]) { // first test in suite
|
|
94
|
-
|
|
101
|
+
isUnskippable = isMarkedAsUnskippable(this.pickle)
|
|
102
|
+
const testSuitePath = getTestSuitePath(testSuiteFullPath, process.cwd())
|
|
103
|
+
isForcedToRun = isUnskippable && skippableSuites.includes(testSuitePath)
|
|
104
|
+
|
|
105
|
+
testSuiteStartCh.publish({ testSuitePath, isUnskippable, isForcedToRun })
|
|
95
106
|
}
|
|
96
107
|
|
|
97
108
|
const testSourceLine = this.gherkinDocument &&
|
|
@@ -221,8 +232,11 @@ function getFilteredPickles (runtime, suitesToSkip) {
|
|
|
221
232
|
return runtime.pickleIds.reduce((acc, pickleId) => {
|
|
222
233
|
const test = runtime.eventDataCollector.getPickle(pickleId)
|
|
223
234
|
const testSuitePath = getTestSuitePath(test.uri, process.cwd())
|
|
235
|
+
|
|
236
|
+
const isUnskippable = isMarkedAsUnskippable(test)
|
|
224
237
|
const isSkipped = suitesToSkip.includes(testSuitePath)
|
|
225
|
-
|
|
238
|
+
|
|
239
|
+
if (isSkipped && !isUnskippable) {
|
|
226
240
|
acc.skippedSuites.add(testSuitePath)
|
|
227
241
|
} else {
|
|
228
242
|
acc.picklesToRun.push(pickleId)
|
|
@@ -270,7 +284,11 @@ addHook({
|
|
|
270
284
|
skippableSuitesCh.publish({ onDone })
|
|
271
285
|
})
|
|
272
286
|
|
|
273
|
-
const
|
|
287
|
+
const skippableResponse = await skippableSuitesPromise
|
|
288
|
+
|
|
289
|
+
const err = skippableResponse.err
|
|
290
|
+
skippableSuites = skippableResponse.skippableSuites
|
|
291
|
+
|
|
274
292
|
let skippedSuites = []
|
|
275
293
|
let isSuitesSkipped = false
|
|
276
294
|
|
|
@@ -315,7 +333,9 @@ addHook({
|
|
|
315
333
|
status: success ? 'pass' : 'fail',
|
|
316
334
|
isSuitesSkipped,
|
|
317
335
|
testCodeCoverageLinesTotal,
|
|
318
|
-
numSkippedSuites: skippedSuites.length
|
|
336
|
+
numSkippedSuites: skippedSuites.length,
|
|
337
|
+
hasUnskippableSuites: isUnskippable,
|
|
338
|
+
hasForcedToRunSuites: isForcedToRun
|
|
319
339
|
})
|
|
320
340
|
})
|
|
321
341
|
return success
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
channel,
|
|
5
|
+
addHook
|
|
6
|
+
} = require('./helpers/instrument')
|
|
7
|
+
const shimmer = require('../../datadog-shimmer')
|
|
8
|
+
|
|
9
|
+
const sanitizeMethodFinished = channel('datadog:express-mongo-sanitize:sanitize:finish')
|
|
10
|
+
const sanitizeMiddlewareFinished = channel('datadog:express-mongo-sanitize:filter:finish')
|
|
11
|
+
|
|
12
|
+
const propertiesToSanitize = ['body', 'params', 'headers', 'query']
|
|
13
|
+
|
|
14
|
+
addHook({ name: 'express-mongo-sanitize', versions: ['>=1.0.0'] }, expressMongoSanitize => {
|
|
15
|
+
shimmer.wrap(expressMongoSanitize, 'sanitize', sanitize => function () {
|
|
16
|
+
const sanitizedObject = sanitize.apply(this, arguments)
|
|
17
|
+
|
|
18
|
+
if (sanitizeMethodFinished.hasSubscribers) {
|
|
19
|
+
sanitizeMethodFinished.publish({ sanitizedObject })
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return sanitizedObject
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
return shimmer.wrap(expressMongoSanitize, function () {
|
|
26
|
+
const middleware = expressMongoSanitize.apply(this, arguments)
|
|
27
|
+
|
|
28
|
+
return shimmer.wrap(middleware, function (req, res, next) {
|
|
29
|
+
if (!sanitizeMiddlewareFinished.hasSubscribers) {
|
|
30
|
+
return middleware.apply(this, arguments)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const wrappedNext = shimmer.wrap(next, function () {
|
|
34
|
+
sanitizeMiddlewareFinished.publish({
|
|
35
|
+
sanitizedProperties: propertiesToSanitize,
|
|
36
|
+
req
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
return next.apply(this, arguments)
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
return middleware.call(this, req, res, wrappedNext)
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
})
|
|
@@ -33,13 +33,14 @@ function publishQueryParsedAndNext (req, res, next) {
|
|
|
33
33
|
return function () {
|
|
34
34
|
if (queryParserReadCh.hasSubscribers && req) {
|
|
35
35
|
const abortController = new AbortController()
|
|
36
|
+
const query = req.query
|
|
36
37
|
|
|
37
|
-
queryParserReadCh.publish({ req, res, abortController })
|
|
38
|
+
queryParserReadCh.publish({ req, res, query, abortController })
|
|
38
39
|
|
|
39
40
|
if (abortController.signal.aborted) return
|
|
40
41
|
}
|
|
41
42
|
|
|
42
|
-
next.apply(this, arguments)
|
|
43
|
+
return next.apply(this, arguments)
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
46
|
|
|
@@ -350,6 +350,11 @@ function finishResolvers ({ fields }) {
|
|
|
350
350
|
})
|
|
351
351
|
}
|
|
352
352
|
|
|
353
|
+
addHook({ name: '@graphql-tools/executor', file: 'cjs/execution/execute.js', versions: ['>=0.0.14'] }, execute => {
|
|
354
|
+
shimmer.wrap(execute, 'execute', wrapExecute(execute))
|
|
355
|
+
return execute
|
|
356
|
+
})
|
|
357
|
+
|
|
353
358
|
addHook({ name: 'graphql', file: 'execution/execute.js', versions: ['>=0.10'] }, execute => {
|
|
354
359
|
shimmer.wrap(execute, 'execute', wrapExecute(execute))
|
|
355
360
|
return execute
|
|
@@ -7,6 +7,7 @@ module.exports = {
|
|
|
7
7
|
'@elastic/elasticsearch': () => require('../elasticsearch'),
|
|
8
8
|
'@elastic/transport': () => require('../elasticsearch'),
|
|
9
9
|
'@google-cloud/pubsub': () => require('../google-cloud-pubsub'),
|
|
10
|
+
'@graphql-tools/executor': () => require('../graphql'),
|
|
10
11
|
'@grpc/grpc-js': () => require('../grpc'),
|
|
11
12
|
'@hapi/hapi': () => require('../hapi'),
|
|
12
13
|
'@jest/core': () => require('../jest'),
|
|
@@ -30,12 +31,14 @@ module.exports = {
|
|
|
30
31
|
'node:child_process': () => require('../child-process'),
|
|
31
32
|
'connect': () => require('../connect'),
|
|
32
33
|
'cookie': () => require('../cookie'),
|
|
34
|
+
'cookie-parser': () => require('../cookie-parser'),
|
|
33
35
|
'couchbase': () => require('../couchbase'),
|
|
34
36
|
'crypto': () => require('../crypto'),
|
|
35
37
|
'cypress': () => require('../cypress'),
|
|
36
38
|
'dns': () => require('../dns'),
|
|
37
39
|
'elasticsearch': () => require('../elasticsearch'),
|
|
38
40
|
'express': () => require('../express'),
|
|
41
|
+
'express-mongo-sanitize': () => require('../express-mongo-sanitize'),
|
|
39
42
|
'fastify': () => require('../fastify'),
|
|
40
43
|
'find-my-way': () => require('../find-my-way'),
|
|
41
44
|
'fs': () => require('../fs'),
|
|
@@ -66,7 +69,7 @@ module.exports = {
|
|
|
66
69
|
'mocha': () => require('../mocha'),
|
|
67
70
|
'mocha-each': () => require('../mocha'),
|
|
68
71
|
'moleculer': () => require('../moleculer'),
|
|
69
|
-
'mongodb': () => require('../mongodb
|
|
72
|
+
'mongodb': () => require('../mongodb'),
|
|
70
73
|
'mongodb-core': () => require('../mongodb-core'),
|
|
71
74
|
'mongoose': () => require('../mongoose'),
|
|
72
75
|
'mysql': () => require('../mysql'),
|
|
@@ -81,6 +84,7 @@ module.exports = {
|
|
|
81
84
|
'pg': () => require('../pg'),
|
|
82
85
|
'pino': () => require('../pino'),
|
|
83
86
|
'pino-pretty': () => require('../pino'),
|
|
87
|
+
'playwright': () => require('../playwright'),
|
|
84
88
|
'promise-js': () => require('../promise-js'),
|
|
85
89
|
'promise': () => require('../promise'),
|
|
86
90
|
'q': () => require('../q'),
|
|
@@ -46,6 +46,8 @@ let isCodeCoverageEnabled = false
|
|
|
46
46
|
let isSuitesSkippingEnabled = false
|
|
47
47
|
let isSuitesSkipped = false
|
|
48
48
|
let numSkippedSuites = 0
|
|
49
|
+
let hasUnskippableSuites = false
|
|
50
|
+
let hasForcedToRunSuites = false
|
|
49
51
|
|
|
50
52
|
const sessionAsyncResource = new AsyncResource('bound-anonymous-fn')
|
|
51
53
|
|
|
@@ -205,15 +207,17 @@ addHook({
|
|
|
205
207
|
const [test] = shardedTests
|
|
206
208
|
const rootDir = test && test.context && test.context.config && test.context.config.rootDir
|
|
207
209
|
|
|
208
|
-
const
|
|
210
|
+
const jestSuitesToRun = getJestSuitesToRun(skippableSuites, shardedTests, rootDir || process.cwd())
|
|
211
|
+
hasUnskippableSuites = jestSuitesToRun.hasUnskippableSuites
|
|
212
|
+
hasForcedToRunSuites = jestSuitesToRun.hasForcedToRunSuites
|
|
209
213
|
|
|
210
|
-
isSuitesSkipped = suitesToRun.length !== shardedTests.length
|
|
211
|
-
numSkippedSuites = skippedSuites.length
|
|
214
|
+
isSuitesSkipped = jestSuitesToRun.suitesToRun.length !== shardedTests.length
|
|
215
|
+
numSkippedSuites = jestSuitesToRun.skippedSuites.length
|
|
212
216
|
|
|
213
|
-
itrSkippedSuitesCh.publish({ skippedSuites, frameworkVersion })
|
|
217
|
+
itrSkippedSuitesCh.publish({ skippedSuites: jestSuitesToRun.skippedSuites, frameworkVersion })
|
|
214
218
|
|
|
215
219
|
skippableSuites = []
|
|
216
|
-
return suitesToRun
|
|
220
|
+
return jestSuitesToRun.suitesToRun
|
|
217
221
|
})
|
|
218
222
|
return sequencerPackage
|
|
219
223
|
})
|
|
@@ -285,7 +289,9 @@ function cliWrapper (cli, jestVersion) {
|
|
|
285
289
|
isSuitesSkippingEnabled,
|
|
286
290
|
isCodeCoverageEnabled,
|
|
287
291
|
testCodeCoverageLinesTotal,
|
|
288
|
-
numSkippedSuites
|
|
292
|
+
numSkippedSuites,
|
|
293
|
+
hasUnskippableSuites,
|
|
294
|
+
hasForcedToRunSuites
|
|
289
295
|
})
|
|
290
296
|
})
|
|
291
297
|
|
|
@@ -500,16 +506,19 @@ addHook({
|
|
|
500
506
|
const testPaths = await getTestPaths.apply(this, arguments)
|
|
501
507
|
const { tests } = testPaths
|
|
502
508
|
|
|
503
|
-
const
|
|
509
|
+
const jestSuitesToRun = getJestSuitesToRun(skippableSuites, tests, rootDir)
|
|
504
510
|
|
|
505
|
-
|
|
506
|
-
|
|
511
|
+
hasUnskippableSuites = jestSuitesToRun.hasUnskippableSuites
|
|
512
|
+
hasForcedToRunSuites = jestSuitesToRun.hasForcedToRunSuites
|
|
507
513
|
|
|
508
|
-
|
|
514
|
+
isSuitesSkipped = jestSuitesToRun.suitesToRun.length !== tests.length
|
|
515
|
+
numSkippedSuites = jestSuitesToRun.skippedSuites.length
|
|
516
|
+
|
|
517
|
+
itrSkippedSuitesCh.publish({ skippedSuites: jestSuitesToRun.skippedSuites, frameworkVersion })
|
|
509
518
|
|
|
510
519
|
skippableSuites = []
|
|
511
520
|
|
|
512
|
-
return { ...testPaths, tests: suitesToRun }
|
|
521
|
+
return { ...testPaths, tests: jestSuitesToRun.suitesToRun }
|
|
513
522
|
})
|
|
514
523
|
|
|
515
524
|
return searchSourcePackage
|
|
@@ -1,9 +1,12 @@
|
|
|
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 shimmer = require('../../datadog-shimmer')
|
|
6
6
|
|
|
7
|
+
const startRawQueryCh = channel('datadog:knex:raw:start')
|
|
8
|
+
const finishRawQueryCh = channel('datadog:knex:raw:finish')
|
|
9
|
+
|
|
7
10
|
patch('lib/query/builder.js')
|
|
8
11
|
patch('lib/raw.js')
|
|
9
12
|
patch('lib/schema/builder.js')
|
|
@@ -18,3 +21,61 @@ function patch (file) {
|
|
|
18
21
|
return Builder
|
|
19
22
|
})
|
|
20
23
|
}
|
|
24
|
+
|
|
25
|
+
addHook({
|
|
26
|
+
name: 'knex',
|
|
27
|
+
versions: ['>=2'],
|
|
28
|
+
file: 'lib/knex-builder/Knex.js'
|
|
29
|
+
}, Knex => {
|
|
30
|
+
shimmer.wrap(Knex.Client.prototype, 'raw', raw => function () {
|
|
31
|
+
if (!startRawQueryCh.hasSubscribers) {
|
|
32
|
+
return raw.apply(this, arguments)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const sql = arguments[0]
|
|
36
|
+
|
|
37
|
+
// Skip query done by Knex to get the value used for undefined
|
|
38
|
+
if (sql === 'DEFAULT') {
|
|
39
|
+
return raw.apply(this, arguments)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function finish () {
|
|
43
|
+
finishRawQueryCh.publish()
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
startRawQueryCh.publish({ sql, dialect: this.dialect })
|
|
47
|
+
|
|
48
|
+
const rawResult = raw.apply(this, arguments)
|
|
49
|
+
|
|
50
|
+
shimmer.wrap(rawResult, 'then', originalThen => function () {
|
|
51
|
+
arguments[0] = wrapCallbackWithFinish(arguments[0], finish)
|
|
52
|
+
arguments[1] = wrapCallbackWithFinish(arguments[1], finish)
|
|
53
|
+
|
|
54
|
+
const originalThenResult = originalThen.apply(this, arguments)
|
|
55
|
+
|
|
56
|
+
shimmer.wrap(originalThenResult, 'catch', originalCatch => function () {
|
|
57
|
+
arguments[0] = wrapCallbackWithFinish(arguments[0], finish)
|
|
58
|
+
return originalCatch.apply(this, arguments)
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
return originalThenResult
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
shimmer.wrap(rawResult, 'asCallback', originalAsCallback => function () {
|
|
65
|
+
arguments[0] = wrapCallbackWithFinish(arguments[0], finish)
|
|
66
|
+
return originalAsCallback.apply(this, arguments)
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
return rawResult
|
|
70
|
+
})
|
|
71
|
+
return Knex
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
function wrapCallbackWithFinish (callback, finish) {
|
|
75
|
+
if (typeof callback !== 'function') return callback
|
|
76
|
+
|
|
77
|
+
return function () {
|
|
78
|
+
finish()
|
|
79
|
+
callback.apply(this, arguments)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
const { createCoverageMap } = require('istanbul-lib-coverage')
|
|
2
2
|
|
|
3
|
+
const { isMarkedAsUnskippable } = require('../../datadog-plugin-jest/src/util')
|
|
4
|
+
|
|
3
5
|
const { addHook, channel, AsyncResource } = require('./helpers/instrument')
|
|
4
6
|
const shimmer = require('../../datadog-shimmer')
|
|
5
7
|
const log = require('../../dd-trace/src/log')
|
|
6
|
-
|
|
7
8
|
const {
|
|
8
9
|
getCoveredFilenamesFromCoverage,
|
|
9
10
|
resetCoverage,
|
|
@@ -50,6 +51,8 @@ let suitesToSkip = []
|
|
|
50
51
|
let frameworkVersion
|
|
51
52
|
let isSuitesSkipped = false
|
|
52
53
|
let skippedSuites = []
|
|
54
|
+
const unskippableSuites = []
|
|
55
|
+
let isForcedToRun = false
|
|
53
56
|
|
|
54
57
|
function getSuitesByTestFile (root) {
|
|
55
58
|
const suitesByTestFile = {}
|
|
@@ -104,7 +107,8 @@ function getFilteredSuites (originalSuites) {
|
|
|
104
107
|
return originalSuites.reduce((acc, suite) => {
|
|
105
108
|
const testPath = getTestSuitePath(suite.file, process.cwd())
|
|
106
109
|
const shouldSkip = suitesToSkip.includes(testPath)
|
|
107
|
-
|
|
110
|
+
const isUnskippable = unskippableSuites.includes(suite.file)
|
|
111
|
+
if (shouldSkip && !isUnskippable) {
|
|
108
112
|
acc.skippedSuites.add(testPath)
|
|
109
113
|
} else {
|
|
110
114
|
acc.suitesToRun.push(suite)
|
|
@@ -151,7 +155,9 @@ function mochaHook (Runner) {
|
|
|
151
155
|
status,
|
|
152
156
|
isSuitesSkipped,
|
|
153
157
|
testCodeCoverageLinesTotal,
|
|
154
|
-
numSkippedSuites: skippedSuites.length
|
|
158
|
+
numSkippedSuites: skippedSuites.length,
|
|
159
|
+
hasForcedToRunSuites: isForcedToRun,
|
|
160
|
+
hasUnskippableSuites: !!unskippableSuites.length
|
|
155
161
|
})
|
|
156
162
|
}))
|
|
157
163
|
|
|
@@ -172,8 +178,10 @@ function mochaHook (Runner) {
|
|
|
172
178
|
if (!asyncResource) {
|
|
173
179
|
asyncResource = new AsyncResource('bound-anonymous-fn')
|
|
174
180
|
testFileToSuiteAr.set(suite.file, asyncResource)
|
|
181
|
+
const isUnskippable = unskippableSuites.includes(suite.file)
|
|
182
|
+
isForcedToRun = isUnskippable && suitesToSkip.includes(getTestSuitePath(suite.file, process.cwd()))
|
|
175
183
|
asyncResource.runInAsyncScope(() => {
|
|
176
|
-
testSuiteStartCh.publish(suite)
|
|
184
|
+
testSuiteStartCh.publish({ testSuite: suite.file, isUnskippable, isForcedToRun })
|
|
177
185
|
})
|
|
178
186
|
}
|
|
179
187
|
})
|
|
@@ -370,6 +378,13 @@ addHook({
|
|
|
370
378
|
|
|
371
379
|
const runner = run.apply(this, arguments)
|
|
372
380
|
|
|
381
|
+
this.files.forEach(path => {
|
|
382
|
+
const isUnskippable = isMarkedAsUnskippable({ path })
|
|
383
|
+
if (isUnskippable) {
|
|
384
|
+
unskippableSuites.push(path)
|
|
385
|
+
}
|
|
386
|
+
})
|
|
387
|
+
|
|
373
388
|
const onReceivedSkippableSuites = ({ err, skippableSuites }) => {
|
|
374
389
|
if (err) {
|
|
375
390
|
suitesToSkip = []
|