dd-trace 4.11.1 → 4.16.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.
Files changed (78) hide show
  1. package/LICENSE-3rdparty.csv +1 -0
  2. package/README.md +4 -9
  3. package/ext/tags.d.ts +1 -0
  4. package/ext/tags.js +1 -0
  5. package/index.d.ts +44 -0
  6. package/package.json +9 -6
  7. package/packages/datadog-esbuild/index.js +57 -32
  8. package/packages/datadog-instrumentations/src/body-parser.js +2 -2
  9. package/packages/datadog-instrumentations/src/cookie-parser.js +37 -0
  10. package/packages/datadog-instrumentations/src/cucumber.js +30 -11
  11. package/packages/datadog-instrumentations/src/express.js +1 -1
  12. package/packages/datadog-instrumentations/src/graphql.js +10 -4
  13. package/packages/datadog-instrumentations/src/helpers/hooks.js +3 -0
  14. package/packages/datadog-instrumentations/src/http/server.js +1 -1
  15. package/packages/datadog-instrumentations/src/jest.js +22 -11
  16. package/packages/datadog-instrumentations/src/kafkajs.js +3 -4
  17. package/packages/datadog-instrumentations/src/mocha.js +33 -8
  18. package/packages/datadog-instrumentations/src/mysql.js +39 -1
  19. package/packages/datadog-instrumentations/src/next.js +47 -19
  20. package/packages/datadog-instrumentations/src/openai.js +1 -1
  21. package/packages/datadog-instrumentations/src/pg.js +60 -15
  22. package/packages/datadog-instrumentations/src/playwright.js +15 -3
  23. package/packages/datadog-plugin-cucumber/src/index.js +14 -2
  24. package/packages/datadog-plugin-cypress/src/plugin.js +49 -13
  25. package/packages/datadog-plugin-graphql/src/index.js +3 -3
  26. package/packages/datadog-plugin-graphql/src/resolve.js +27 -2
  27. package/packages/datadog-plugin-jest/src/index.js +10 -2
  28. package/packages/datadog-plugin-jest/src/util.js +10 -4
  29. package/packages/datadog-plugin-mocha/src/index.js +14 -2
  30. package/packages/datadog-plugin-mongodb-core/src/index.js +6 -2
  31. package/packages/datadog-plugin-mysql/src/index.js +2 -2
  32. package/packages/datadog-plugin-next/src/index.js +22 -5
  33. package/packages/datadog-plugin-pg/src/index.js +2 -2
  34. package/packages/dd-trace/src/appsec/addresses.js +1 -0
  35. package/packages/dd-trace/src/appsec/channels.js +2 -0
  36. package/packages/dd-trace/src/appsec/iast/analyzers/ldap-injection-analyzer.js +7 -0
  37. package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +29 -18
  38. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +19 -1
  39. package/packages/dd-trace/src/appsec/iast/path-line.js +1 -0
  40. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +1 -1
  41. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +48 -5
  42. package/packages/dd-trace/src/appsec/iast/telemetry/index.js +14 -5
  43. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/evidence-redaction/sensitive-handler.js +131 -10
  44. package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/index.js +0 -1
  45. package/packages/dd-trace/src/appsec/index.js +42 -7
  46. package/packages/dd-trace/src/appsec/recommended.json +655 -31
  47. package/packages/dd-trace/src/appsec/remote_config/capabilities.js +2 -1
  48. package/packages/dd-trace/src/appsec/remote_config/index.js +2 -0
  49. package/packages/dd-trace/src/appsec/reporter.js +26 -0
  50. package/packages/dd-trace/src/appsec/telemetry.js +132 -0
  51. package/packages/dd-trace/src/appsec/waf/index.js +1 -1
  52. package/packages/dd-trace/src/appsec/waf/waf_context_wrapper.js +13 -5
  53. package/packages/dd-trace/src/appsec/waf/waf_manager.js +12 -14
  54. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +1 -14
  55. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +1 -13
  56. package/packages/dd-trace/src/datastreams/processor.js +6 -2
  57. package/packages/dd-trace/src/dogstatsd.js +108 -8
  58. package/packages/dd-trace/src/exporters/agent/writer.js +9 -9
  59. package/packages/dd-trace/src/exporters/common/request.js +13 -4
  60. package/packages/dd-trace/src/format.js +6 -1
  61. package/packages/dd-trace/src/opentracing/propagation/text_map.js +2 -2
  62. package/packages/dd-trace/src/opentracing/span.js +13 -13
  63. package/packages/dd-trace/src/opentracing/tracer.js +3 -5
  64. package/packages/dd-trace/src/plugin_manager.js +1 -2
  65. package/packages/dd-trace/src/plugins/ci_plugin.js +22 -1
  66. package/packages/dd-trace/src/plugins/database.js +14 -4
  67. package/packages/dd-trace/src/plugins/index.js +1 -0
  68. package/packages/dd-trace/src/plugins/outbound.js +4 -3
  69. package/packages/dd-trace/src/plugins/tracing.js +1 -1
  70. package/packages/dd-trace/src/plugins/util/test.js +20 -3
  71. package/packages/dd-trace/src/profiling/config.js +3 -1
  72. package/packages/dd-trace/src/profiling/profilers/wall.js +31 -7
  73. package/packages/dd-trace/src/proxy.js +13 -2
  74. package/packages/dd-trace/src/ritm.js +10 -2
  75. package/packages/dd-trace/src/{metrics.js → runtime_metrics.js} +1 -32
  76. package/packages/dd-trace/src/telemetry/dependencies.js +15 -0
  77. package/packages/dd-trace/src/telemetry/index.js +21 -2
  78. package/packages/dd-trace/src/util.js +1 -1
@@ -32,6 +32,7 @@ require,retry,MIT,Copyright 2011 Tim Koschützki Felix Geisendörfer
32
32
  require,semver,ISC,Copyright Isaac Z. Schlueter and Contributors
33
33
  dev,@types/node,MIT,Copyright Authors
34
34
  dev,autocannon,MIT,Copyright 2016 Matteo Collina
35
+ dev,aws-sdk,Apache 2.0,Copyright 2012-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
35
36
  dev,axios,MIT,Copyright 2014-present Matt Zabriskie
36
37
  dev,benchmark,MIT,Copyright 2010-2016 Mathias Bynens Robert Kieffer John-David Dalton
37
38
  dev,body-parser,MIT,Copyright 2014 Jonathan Ong 2014-2015 Douglas Christopher Wilson
package/README.md CHANGED
@@ -2,8 +2,6 @@
2
2
 
3
3
  [![npm v4](https://img.shields.io/npm/v/dd-trace/latest?color=blue&label=dd-trace%40v4&logo=npm)](https://www.npmjs.com/package/dd-trace)
4
4
  [![npm v3](https://img.shields.io/npm/v/dd-trace/latest-node14?color=blue&label=dd-trace%40v3&logo=npm)](https://www.npmjs.com/package/dd-trace/v/latest-node12)
5
- [![npm v2](https://img.shields.io/npm/v/dd-trace/latest-node12?color=blue&label=dd-trace%40v2&logo=npm)](https://www.npmjs.com/package/dd-trace/v/latest-node12)
6
- [![npm dev](https://img.shields.io/npm/v/dd-trace/dev?color=orange&label=dd-trace%40dev&logo=npm)](https://www.npmjs.com/package/dd-trace/v/dev)
7
5
  [![codecov](https://codecov.io/gh/DataDog/dd-trace-js/branch/master/graph/badge.svg)](https://codecov.io/gh/DataDog/dd-trace-js)
8
6
 
9
7
  <img align="right" src="https://user-images.githubusercontent.com/551402/208212084-1d0c07e2-4135-4c61-b2da-8f2fddbc66ed.png" alt="Bits the dog JavaScript" width="200px"/>
@@ -28,12 +26,12 @@ Most of the documentation for `dd-trace` is available on these webpages:
28
26
  | Release Line | Latest Version | Node.js | Status |Initial Release | End of Life |
29
27
  | :---: | :---: | :---: | :---: | :---: | :---: |
30
28
  | [`v1`](https://github.com/DataDog/dd-trace-js/tree/v1.x) | ![npm v1](https://img.shields.io/npm/v/dd-trace/legacy-v1?color=white&label=%20&style=flat-square) | `>= v12` | **End of Life** | 2021-07-13 | 2022-02-25 |
31
- | [`v2`](https://github.com/DataDog/dd-trace-js/tree/v2.x) | ![npm v2](https://img.shields.io/npm/v/dd-trace/latest-node12?color=white&label=%20&style=flat-square) | `>= v12` | **Maintenance** | 2022-01-28 | 2023-08-15 |
29
+ | [`v2`](https://github.com/DataDog/dd-trace-js/tree/v2.x) | ![npm v2](https://img.shields.io/npm/v/dd-trace/latest-node12?color=white&label=%20&style=flat-square) | `>= v12` | **End of Life** | 2022-01-28 | 2023-08-15 |
32
30
  | [`v3`](https://github.com/DataDog/dd-trace-js/tree/v3.x) | ![npm v3](https://img.shields.io/npm/v/dd-trace/latest-node14?color=white&label=%20&style=flat-square) | `>= v14` | **Maintenance** | 2022-08-15 | 2024-05-15 |
33
31
  | [`v4`](https://github.com/DataDog/dd-trace-js/tree/v4.x) | ![npm v4](https://img.shields.io/npm/v/dd-trace/latest?color=white&label=%20&style=flat-square) | `>= v16` | **Current** | 2023-05-12 | Unknown |
34
32
 
35
- We currently maintain three release lines, namely `v2`, `v3` and `v4`.
36
- Features and bug fixes that are merged are released to the `v4` line and, if appropriate, also the `v2` and `v3` line.
33
+ We currently maintain two release lines, namely `v3` and `v4`.
34
+ Features and bug fixes that are merged are released to the `v4` line and, if appropriate, also the `v3` line.
37
35
 
38
36
  For any new projects it is recommended to use the `v4` release line:
39
37
 
@@ -42,15 +40,12 @@ $ npm install dd-trace
42
40
  $ yarn add dd-trace
43
41
  ```
44
42
 
45
- However, existing projects that already use the `v2` or `v3` release lines, or projects that need to support EOL versions of Node.js, may continue to use these release lines.
43
+ However, existing projects that already use the `v3` release line, or projects that need to support EOL versions of Node.js, may continue to use these release lines.
46
44
  This is done by specifying the version when installing the package.
47
- Note that we also publish to npm using a `latest-node12` and `latest-node14` tag that can also be used for install:
48
45
 
49
46
  ```sh
50
47
  $ npm install dd-trace@3
51
48
  $ yarn add dd-trace@3
52
- $ npm install dd-trace@latest-node14
53
- $ yarn add dd-trace@latest-node14
54
49
  ```
55
50
 
56
51
  Any backwards-breaking functionality that is introduced into the library will result in an increase of the major version of the library and therefore a new release line.
package/ext/tags.d.ts CHANGED
@@ -9,6 +9,7 @@ declare const tags: {
9
9
  MANUAL_KEEP: 'manual.keep'
10
10
  MANUAL_DROP: 'manual.drop'
11
11
  MEASURED: '_dd.measured'
12
+ BASE_SERVICE: '_dd.base_service'
12
13
  HTTP_URL: 'http.url'
13
14
  HTTP_METHOD: 'http.method'
14
15
  HTTP_STATUS_CODE: 'http.status_code'
package/ext/tags.js CHANGED
@@ -12,6 +12,7 @@ const tags = {
12
12
  MANUAL_KEEP: 'manual.keep',
13
13
  MANUAL_DROP: 'manual.drop',
14
14
  MEASURED: '_dd.measured',
15
+ BASE_SERVICE: '_dd.base_service',
15
16
 
16
17
  // HTTP
17
18
  HTTP_URL: 'http.url',
package/index.d.ts CHANGED
@@ -121,6 +121,8 @@ export declare interface Tracer extends opentracing.Tracer {
121
121
  appsec: Appsec;
122
122
 
123
123
  TracerProvider: opentelemetry.TracerProvider;
124
+
125
+ dogstatsd: DogStatsD;
124
126
  }
125
127
 
126
128
  export declare interface TraceOptions extends Analyzable {
@@ -642,6 +644,47 @@ export declare interface User {
642
644
  [key: string]: string | undefined
643
645
  }
644
646
 
647
+ export declare interface DogStatsD {
648
+ /**
649
+ * Increments a metric by the specified value, optionally specifying tags.
650
+ * @param {string} stat The dot-separated metric name.
651
+ * @param {number} value The amount to increment the stat by.
652
+ * @param {[tag:string]:string|number} tags Tags to pass along, such as `{ foo: 'bar' }`. Values are combined with config.tags.
653
+ */
654
+ increment(stat: string, value?: number, tags?: { [tag: string]: string|number }): void
655
+
656
+ /**
657
+ * Decrements a metric by the specified value, optionally specifying tags.
658
+ * @param {string} stat The dot-separated metric name.
659
+ * @param {number} value The amount to decrement the stat by.
660
+ * @param {[tag:string]:string|number} tags Tags to pass along, such as `{ foo: 'bar' }`. Values are combined with config.tags.
661
+ */
662
+ decrement(stat: string, value?: number, tags?: { [tag: string]: string|number }): void
663
+
664
+ /**
665
+ * Sets a distribution value, optionally specifying tags.
666
+ * @param {string} stat The dot-separated metric name.
667
+ * @param {number} value The amount to increment the stat by.
668
+ * @param {[tag:string]:string|number} tags Tags to pass along, such as `{ foo: 'bar' }`. Values are combined with config.tags.
669
+ */
670
+ distribution(stat: string, value?: number, tags?: { [tag: string]: string|number }): void
671
+
672
+ /**
673
+ * Sets a gauge value, optionally specifying tags.
674
+ * @param {string} stat The dot-separated metric name.
675
+ * @param {number} value The amount to increment the stat by.
676
+ * @param {[tag:string]:string|number} tags Tags to pass along, such as `{ foo: 'bar' }`. Values are combined with config.tags.
677
+ */
678
+ gauge(stat: string, value?: number, tags?: { [tag: string]: string|number }): void
679
+
680
+ /**
681
+ * Forces any unsent metrics to be sent
682
+ *
683
+ * @beta This method is experimental and could be removed in future versions.
684
+ */
685
+ flush(): void
686
+ }
687
+
645
688
  export declare interface Appsec {
646
689
  /**
647
690
  * Links a successful login event to the current trace. Will link the passed user to the current trace with Appsec.setUser() internally.
@@ -786,6 +829,7 @@ interface Plugins {
786
829
  "mysql2": plugins.mysql2;
787
830
  "net": plugins.net;
788
831
  "next": plugins.next;
832
+ "openai": plugins.openai;
789
833
  "opensearch": plugins.opensearch;
790
834
  "oracledb": plugins.oracledb;
791
835
  "paperplane": plugins.paperplane;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "4.11.1",
3
+ "version": "4.16.0",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -18,7 +18,7 @@
18
18
  "test:appsec": "mocha --colors --exit -r \"packages/dd-trace/test/setup/mocha.js\" --exclude \"packages/dd-trace/test/appsec/**/*.plugin.spec.js\" \"packages/dd-trace/test/appsec/**/*.spec.js\"",
19
19
  "test:appsec:ci": "nyc --no-clean --include \"packages/dd-trace/src/appsec/**/*.js\" --exclude \"packages/dd-trace/test/appsec/**/*.plugin.spec.js\" -- npm run test:appsec",
20
20
  "test:appsec:plugins": "mocha --colors --exit -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/dd-trace/test/appsec/**/*.@($(echo $PLUGINS)).plugin.spec.js\"",
21
- "test:appsec:plugins:ci": "yarn services && nyc --no-clean --include \"packages/dd-trace/test/appsec/**/*.@($(echo $PLUGINS)).plugin.spec.js\" -- npm run test:appsec:plugins",
21
+ "test:appsec:plugins:ci": "yarn services && nyc --no-clean --include \"packages/dd-trace/src/appsec/**/*.js\" -- npm run test:appsec:plugins",
22
22
  "test:trace:core": "tap packages/dd-trace/test/*.spec.js \"packages/dd-trace/test/{ci-visibility,encode,exporters,opentelemetry,opentracing,plugins,service-naming,telemetry}/**/*.spec.js\"",
23
23
  "test:trace:core:ci": "npm run test:trace:core -- --coverage --nyc-arg=--include=\"packages/dd-trace/src/**/*.js\"",
24
24
  "test:instrumentations": "mocha --colors -r 'packages/dd-trace/test/setup/mocha.js' 'packages/datadog-instrumentations/test/**/*.spec.js'",
@@ -37,6 +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 --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\"",
40
42
  "test:shimmer": "mocha --colors 'packages/datadog-shimmer/test/**/*.spec.js'",
41
43
  "test:shimmer:ci": "nyc --no-clean --include 'packages/datadog-shimmer/src/**/*.js' -- npm run test:shimmer",
42
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'",
@@ -57,7 +59,7 @@
57
59
  "apm"
58
60
  ],
59
61
  "author": "Datadog Inc. <info@datadoghq.com>",
60
- "license": "BSD-3-Clause",
62
+ "license": "(Apache-2.0 OR BSD-3-Clause)",
61
63
  "bugs": {
62
64
  "url": "https://github.com/DataDog/dd-trace-js/issues"
63
65
  },
@@ -66,11 +68,11 @@
66
68
  "node": ">=16"
67
69
  },
68
70
  "dependencies": {
69
- "@datadog/native-appsec": "^3.2.0",
70
- "@datadog/native-iast-rewriter": "2.0.1",
71
+ "@datadog/native-appsec": "^4.0.0",
72
+ "@datadog/native-iast-rewriter": "2.1.3",
71
73
  "@datadog/native-iast-taint-tracking": "1.5.0",
72
74
  "@datadog/native-metrics": "^2.0.0",
73
- "@datadog/pprof": "3.1.0",
75
+ "@datadog/pprof": "3.2.0",
74
76
  "@datadog/sketches-js": "^2.1.0",
75
77
  "@opentelemetry/api": "^1.0.0",
76
78
  "@opentelemetry/core": "^1.14.0",
@@ -101,6 +103,7 @@
101
103
  "devDependencies": {
102
104
  "@types/node": ">=16",
103
105
  "autocannon": "^4.5.2",
106
+ "aws-sdk": "^2.1446.0",
104
107
  "axios": "^0.21.2",
105
108
  "benchmark": "^2.1.4",
106
109
  "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
 
@@ -50,21 +51,41 @@ for (const pkg of INSTRUMENTED) {
50
51
  module.exports.name = 'datadog-esbuild'
51
52
 
52
53
  module.exports.setup = function (build) {
54
+ const externalModules = new Set(build.initialOptions.external || [])
53
55
  build.onResolve({ filter: /.*/ }, args => {
56
+ if (externalModules.has(args.path)) {
57
+ // Internal Node.js packages will still be instrumented via require()
58
+ if (DEBUG) console.log(`EXTERNAL: ${args.path}`)
59
+ return
60
+ }
61
+
62
+ // TODO: Should this also check for namespace === 'file'?
63
+ if (args.path.startsWith('.') && !args.importer.includes('node_modules/')) {
64
+ // This is local application code, not an instrumented package
65
+ if (DEBUG) console.log(`LOCAL: ${args.path}`)
66
+ return
67
+ }
68
+
69
+ // TODO: Should this also check for namespace === 'file'?
70
+ if (args.path.startsWith('@') && !args.importer.includes('node_modules/')) {
71
+ // This is the Next.js convention for loading local files
72
+ if (DEBUG) console.log(`@LOCAL: ${args.path}`)
73
+ return
74
+ }
75
+
54
76
  let fullPathToModule
55
77
  try {
56
78
  fullPathToModule = dotFriendlyResolve(args.path, args.resolveDir)
57
79
  } catch (err) {
58
- console.warn(`Unable to find "${args.path}". Is the package dead code?`)
80
+ console.warn(`MISSING: Unable to find "${args.path}". Is the package dead code?`)
59
81
  return
60
82
  }
61
83
  const extracted = extractPackageAndModulePath(fullPathToModule)
62
- const packageName = args.path
63
84
 
64
85
  const internal = builtins.has(args.path)
65
86
 
66
87
  if (args.namespace === 'file' && (
67
- modulesOfInterest.has(packageName) || modulesOfInterest.has(`${extracted.pkg}/${extracted.path}`))
88
+ modulesOfInterest.has(args.path) || modulesOfInterest.has(`${extracted.pkg}/${extracted.path}`))
68
89
  ) {
69
90
  // The file namespace is used when requiring files from disk in userland
70
91
 
@@ -74,7 +95,7 @@ module.exports.setup = function (build) {
74
95
  } catch (err) {
75
96
  if (err.code === 'MODULE_NOT_FOUND') {
76
97
  if (!internal) {
77
- console.warn(`Unable to find "${extracted.pkg}/package.json". Is the package dead code?`)
98
+ console.warn(`MISSING: Unable to find "${extracted.pkg}/package.json". Is the package dead code?`)
78
99
  }
79
100
  return
80
101
  } else {
@@ -84,60 +105,64 @@ module.exports.setup = function (build) {
84
105
 
85
106
  const packageJson = require(pathToPackageJson)
86
107
 
87
- if (DEBUG) console.log(`RESOLVE ${packageName}@${packageJson.version}`)
108
+ if (DEBUG) console.log(`RESOLVE: ${args.path}@${packageJson.version}`)
88
109
 
89
110
  // https://esbuild.github.io/plugins/#on-resolve-arguments
90
111
  return {
91
112
  path: fullPathToModule,
92
- namespace: NAMESPACE,
93
113
  pluginData: {
94
114
  version: packageJson.version,
95
115
  pkg: extracted.pkg,
96
116
  path: extracted.path,
97
117
  full: fullPathToModule,
98
- raw: packageName,
118
+ raw: args.path,
119
+ pkgOfInterest: true,
99
120
  internal
100
121
  }
101
122
  }
102
- } else if (args.namespace === NAMESPACE) {
103
- // The datadog namespace is used when requiring files that are injected during the onLoad stage
104
-
105
- if (builtins.has(packageName)) return
106
-
107
- return {
108
- path: require.resolve(packageName, { paths: [ args.resolveDir ] }),
109
- namespace: 'file'
110
- }
111
123
  }
112
124
  })
113
125
 
114
- build.onLoad({ filter: /.*/, namespace: NAMESPACE }, args => {
126
+ build.onLoad({ filter: /.*/ }, args => {
127
+ if (!args.pluginData?.pkgOfInterest) {
128
+ return
129
+ }
130
+
115
131
  const data = args.pluginData
116
132
 
117
- if (DEBUG) console.log(`LOAD ${data.pkg}@${data.version}, pkg "${data.path}"`)
133
+ if (DEBUG) console.log(`LOAD: ${data.pkg}@${data.version}, pkg "${data.path}"`)
118
134
 
119
- const path = data.raw !== data.pkg
135
+ const pkgPath = data.raw !== data.pkg
120
136
  ? `${data.pkg}/${data.path}`
121
137
  : data.pkg
122
138
 
139
+ // Read the content of the module file of interest
140
+ const fileCode = fs.readFileSync(args.path, 'utf8')
141
+
123
142
  const contents = `
124
- const dc = require('diagnostics_channel');
125
- const ch = dc.channel('${CHANNEL}');
126
- const mod = require('${args.path}');
127
- const payload = {
128
- module: mod,
129
- version: '${data.version}',
130
- package: '${data.pkg}',
131
- path: '${path}'
132
- };
133
- ch.publish(payload);
134
- module.exports = payload.module;
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
+ }
135
159
  `
136
160
 
137
161
  // https://esbuild.github.io/plugins/#on-load-results
138
162
  return {
139
163
  contents,
140
- loader: 'js'
164
+ loader: 'js',
165
+ resolveDir: path.dirname(args.path)
141
166
  }
142
167
  })
143
168
  }
@@ -16,7 +16,7 @@ function publishRequestBodyAndNext (req, res, next) {
16
16
  if (abortController.signal.aborted) return
17
17
  }
18
18
 
19
- next.apply(this, arguments)
19
+ return next.apply(this, arguments)
20
20
  }
21
21
  }
22
22
 
@@ -27,6 +27,6 @@ addHook({
27
27
  }, read => {
28
28
  return shimmer.wrap(read, function (req, res, next) {
29
29
  arguments[2] = publishRequestBodyAndNext(req, res, next)
30
- read.apply(this, arguments)
30
+ return read.apply(this, arguments)
31
31
  })
32
32
  })
@@ -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
+ })
@@ -21,6 +21,8 @@ const skippableSuitesCh = channel('ci:cucumber:test-suite:skippable')
21
21
  const sessionStartCh = channel('ci:cucumber:session:start')
22
22
  const sessionFinishCh = channel('ci:cucumber:session:finish')
23
23
 
24
+ const itrSkippedSuitesCh = channel('ci:cucumber:itr:skipped-suites')
25
+
24
26
  const {
25
27
  getCoveredFilenamesFromCoverage,
26
28
  resetCoverage,
@@ -37,7 +39,6 @@ const patched = new WeakSet()
37
39
 
38
40
  let pickleByFile = {}
39
41
  const pickleResultByFile = {}
40
- let isSuitesSkipped = false
41
42
 
42
43
  function getSuiteStatusFromTestStatuses (testStatuses) {
43
44
  if (testStatuses.some(status => status === 'fail')) {
@@ -216,11 +217,18 @@ addHook({
216
217
  file: 'lib/runtime/test_case_runner.js'
217
218
  }, testCaseHook)
218
219
 
219
- function getPicklesToRun (runtime, suitesToSkip) {
220
- return runtime.pickleIds.filter((pickleId) => {
220
+ function getFilteredPickles (runtime, suitesToSkip) {
221
+ return runtime.pickleIds.reduce((acc, pickleId) => {
221
222
  const test = runtime.eventDataCollector.getPickle(pickleId)
222
- return !suitesToSkip.includes(getTestSuitePath(test.uri, process.cwd()))
223
- }, {})
223
+ const testSuitePath = getTestSuitePath(test.uri, process.cwd())
224
+ const isSkipped = suitesToSkip.includes(testSuitePath)
225
+ if (isSkipped) {
226
+ acc.skippedSuites.add(testSuitePath)
227
+ } else {
228
+ acc.picklesToRun.push(pickleId)
229
+ }
230
+ return acc
231
+ }, { skippedSuites: new Set(), picklesToRun: [] })
224
232
  }
225
233
 
226
234
  function getPickleByFile (runtime) {
@@ -239,7 +247,7 @@ addHook({
239
247
  name: '@cucumber/cucumber',
240
248
  versions: ['>=7.0.0'],
241
249
  file: 'lib/runtime/index.js'
242
- }, (runtimePackage, cucumberVersion) => {
250
+ }, (runtimePackage, frameworkVersion) => {
243
251
  shimmer.wrap(runtimePackage.default.prototype, 'start', start => async function () {
244
252
  const asyncResource = new AsyncResource('bound-anonymous-fn')
245
253
  let onDone
@@ -263,11 +271,16 @@ addHook({
263
271
  })
264
272
 
265
273
  const { err, skippableSuites } = await skippableSuitesPromise
274
+ let skippedSuites = []
275
+ let isSuitesSkipped = false
266
276
 
267
277
  if (!err) {
268
- const newPickleIds = getPicklesToRun(this, skippableSuites)
269
- isSuitesSkipped = newPickleIds.length !== this.pickleIds.length
270
- this.pickleIds = newPickleIds
278
+ const filteredPickles = getFilteredPickles(this, skippableSuites)
279
+ const { picklesToRun } = filteredPickles
280
+ isSuitesSkipped = picklesToRun.length !== this.pickleIds.length
281
+ this.pickleIds = picklesToRun
282
+
283
+ skippedSuites = Array.from(filteredPickles.skippedSuites)
271
284
  }
272
285
 
273
286
  pickleByFile = getPickleByFile(this)
@@ -276,8 +289,13 @@ addHook({
276
289
  const command = process.env.npm_lifecycle_script || `cucumber-js ${processArgv}`
277
290
 
278
291
  asyncResource.runInAsyncScope(() => {
279
- sessionStartCh.publish({ command, frameworkVersion: cucumberVersion })
292
+ sessionStartCh.publish({ command, frameworkVersion })
280
293
  })
294
+
295
+ if (!err && skippedSuites.length) {
296
+ itrSkippedSuitesCh.publish({ skippedSuites, frameworkVersion })
297
+ }
298
+
281
299
  const success = await start.apply(this, arguments)
282
300
 
283
301
  let testCodeCoverageLinesTotal
@@ -296,7 +314,8 @@ addHook({
296
314
  sessionFinishCh.publish({
297
315
  status: success ? 'pass' : 'fail',
298
316
  isSuitesSkipped,
299
- testCodeCoverageLinesTotal
317
+ testCodeCoverageLinesTotal,
318
+ numSkippedSuites: skippedSuites.length
300
319
  })
301
320
  })
302
321
  return success
@@ -39,7 +39,7 @@ function publishQueryParsedAndNext (req, res, next) {
39
39
  if (abortController.signal.aborted) return
40
40
  }
41
41
 
42
- next.apply(this, arguments)
42
+ return next.apply(this, arguments)
43
43
  }
44
44
  }
45
45
 
@@ -188,7 +188,7 @@ function wrapExecute (execute) {
188
188
  executeErrorCh.publish(error)
189
189
  }
190
190
 
191
- finishExecuteCh.publish({ res, args })
191
+ finishExecuteCh.publish({ res, args, context })
192
192
  })
193
193
  })
194
194
  }
@@ -205,7 +205,7 @@ function wrapResolve (resolve) {
205
205
 
206
206
  if (!context) return resolve.apply(this, arguments)
207
207
 
208
- const field = assertField(context, info)
208
+ const field = assertField(context, info, args)
209
209
 
210
210
  return callInAsyncScope(resolve, field.asyncResource, this, arguments, (err) => {
211
211
  updateFieldCh.publish({ field, info, err })
@@ -250,7 +250,7 @@ function pathToArray (path) {
250
250
  return flattened.reverse()
251
251
  }
252
252
 
253
- function assertField (context, info) {
253
+ function assertField (context, info, args) {
254
254
  const pathInfo = info && info.path
255
255
 
256
256
  const path = pathToArray(pathInfo)
@@ -272,7 +272,8 @@ function assertField (context, info) {
272
272
  childResource.runInAsyncScope(() => {
273
273
  startResolveCh.publish({
274
274
  info,
275
- context
275
+ context,
276
+ args
276
277
  })
277
278
  })
278
279
 
@@ -349,6 +350,11 @@ function finishResolvers ({ fields }) {
349
350
  })
350
351
  }
351
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
+
352
358
  addHook({ name: 'graphql', file: 'execution/execute.js', versions: ['>=0.10'] }, execute => {
353
359
  shimmer.wrap(execute, 'execute', wrapExecute(execute))
354
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,6 +31,7 @@ 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'),
@@ -81,6 +83,7 @@ module.exports = {
81
83
  'pg': () => require('../pg'),
82
84
  'pino': () => require('../pino'),
83
85
  'pino-pretty': () => require('../pino'),
86
+ 'playwright': () => require('../playwright'),
84
87
  'promise-js': () => require('../promise-js'),
85
88
  'promise': () => require('../promise'),
86
89
  'q': () => require('../q'),
@@ -29,7 +29,7 @@ addHook({ name: 'http' }, http => {
29
29
 
30
30
  function wrapResponseEmit (emit) {
31
31
  return function (eventName, event) {
32
- if (!startServerCh.hasSubscribers) {
32
+ if (!finishServerCh.hasSubscribers) {
33
33
  return emit.apply(this, arguments)
34
34
  }
35
35