dd-trace 3.15.0 → 3.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.
Files changed (180) hide show
  1. package/LICENSE-3rdparty.csv +2 -2
  2. package/README.md +53 -0
  3. package/ci/init.js +9 -1
  4. package/ext/exporters.d.ts +2 -1
  5. package/ext/exporters.js +2 -1
  6. package/index.d.ts +6 -2
  7. package/package.json +24 -19
  8. package/packages/datadog-esbuild/index.js +104 -0
  9. package/packages/datadog-instrumentations/src/cucumber.js +80 -3
  10. package/packages/datadog-instrumentations/src/google-cloud-pubsub.js +100 -27
  11. package/packages/datadog-instrumentations/src/helpers/hook.js +13 -3
  12. package/packages/datadog-instrumentations/src/helpers/hooks.js +1 -0
  13. package/packages/datadog-instrumentations/src/helpers/instrument.js +6 -0
  14. package/packages/datadog-instrumentations/src/helpers/register.js +2 -2
  15. package/packages/datadog-instrumentations/src/jest.js +35 -3
  16. package/packages/datadog-instrumentations/src/mariadb.js +130 -11
  17. package/packages/datadog-instrumentations/src/mocha.js +30 -6
  18. package/packages/datadog-instrumentations/src/mongodb-core.js +8 -2
  19. package/packages/datadog-instrumentations/src/mongoose.js +1 -1
  20. package/packages/datadog-instrumentations/src/next.js +32 -4
  21. package/packages/datadog-instrumentations/src/pg.js +16 -11
  22. package/packages/datadog-instrumentations/src/playwright.js +2 -2
  23. package/packages/datadog-plugin-amqp10/src/consumer.js +1 -1
  24. package/packages/datadog-plugin-amqp10/src/index.js +1 -1
  25. package/packages/datadog-plugin-amqp10/src/producer.js +3 -2
  26. package/packages/datadog-plugin-amqplib/src/client.js +3 -2
  27. package/packages/datadog-plugin-amqplib/src/consumer.js +1 -1
  28. package/packages/datadog-plugin-amqplib/src/index.js +1 -1
  29. package/packages/datadog-plugin-amqplib/src/producer.js +3 -2
  30. package/packages/datadog-plugin-aws-sdk/src/base.js +7 -2
  31. package/packages/datadog-plugin-aws-sdk/src/index.js +1 -1
  32. package/packages/datadog-plugin-aws-sdk/src/services/cloudwatchlogs.js +2 -0
  33. package/packages/datadog-plugin-aws-sdk/src/services/dynamodb.js +2 -0
  34. package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -0
  35. package/packages/datadog-plugin-aws-sdk/src/services/kinesis.js +2 -0
  36. package/packages/datadog-plugin-aws-sdk/src/services/lambda.js +2 -0
  37. package/packages/datadog-plugin-aws-sdk/src/services/redshift.js +2 -0
  38. package/packages/datadog-plugin-aws-sdk/src/services/s3.js +2 -0
  39. package/packages/datadog-plugin-aws-sdk/src/services/sns.js +2 -0
  40. package/packages/datadog-plugin-aws-sdk/src/services/sqs.js +2 -0
  41. package/packages/datadog-plugin-bunyan/src/index.js +1 -1
  42. package/packages/datadog-plugin-cassandra-driver/src/index.js +3 -2
  43. package/packages/datadog-plugin-connect/src/index.js +1 -1
  44. package/packages/datadog-plugin-couchbase/src/index.js +1 -1
  45. package/packages/datadog-plugin-cucumber/src/index.js +33 -6
  46. package/packages/datadog-plugin-cypress/src/index.js +1 -1
  47. package/packages/datadog-plugin-cypress/src/plugin.js +40 -33
  48. package/packages/datadog-plugin-dns/src/index.js +1 -1
  49. package/packages/datadog-plugin-dns/src/lookup.js +1 -1
  50. package/packages/datadog-plugin-dns/src/lookup_service.js +1 -1
  51. package/packages/datadog-plugin-dns/src/resolve.js +1 -1
  52. package/packages/datadog-plugin-dns/src/reverse.js +1 -1
  53. package/packages/datadog-plugin-elasticsearch/src/index.js +1 -1
  54. package/packages/datadog-plugin-express/src/index.js +1 -1
  55. package/packages/datadog-plugin-fastify/src/index.js +1 -1
  56. package/packages/datadog-plugin-find-my-way/src/index.js +1 -1
  57. package/packages/datadog-plugin-fs/src/index.js +1 -1
  58. package/packages/datadog-plugin-google-cloud-pubsub/src/client.js +5 -5
  59. package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +1 -1
  60. package/packages/datadog-plugin-google-cloud-pubsub/src/index.js +1 -1
  61. package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +7 -6
  62. package/packages/datadog-plugin-graphql/src/execute.js +1 -1
  63. package/packages/datadog-plugin-graphql/src/index.js +1 -1
  64. package/packages/datadog-plugin-graphql/src/parse.js +1 -1
  65. package/packages/datadog-plugin-graphql/src/resolve.js +1 -1
  66. package/packages/datadog-plugin-graphql/src/validate.js +1 -1
  67. package/packages/datadog-plugin-grpc/src/client.js +1 -1
  68. package/packages/datadog-plugin-grpc/src/index.js +1 -1
  69. package/packages/datadog-plugin-grpc/src/server.js +1 -1
  70. package/packages/datadog-plugin-hapi/src/index.js +1 -1
  71. package/packages/datadog-plugin-http/src/client.js +2 -2
  72. package/packages/datadog-plugin-http/src/index.js +1 -1
  73. package/packages/datadog-plugin-http/src/server.js +2 -2
  74. package/packages/datadog-plugin-http2/src/client.js +4 -3
  75. package/packages/datadog-plugin-http2/src/index.js +1 -1
  76. package/packages/datadog-plugin-http2/src/server.js +2 -2
  77. package/packages/datadog-plugin-ioredis/src/index.js +1 -1
  78. package/packages/datadog-plugin-jest/src/index.js +53 -19
  79. package/packages/datadog-plugin-kafkajs/src/consumer.js +1 -1
  80. package/packages/datadog-plugin-kafkajs/src/index.js +1 -1
  81. package/packages/datadog-plugin-kafkajs/src/producer.js +1 -1
  82. package/packages/datadog-plugin-koa/src/index.js +1 -1
  83. package/packages/datadog-plugin-mariadb/src/index.js +18 -1
  84. package/packages/datadog-plugin-memcached/src/index.js +3 -2
  85. package/packages/datadog-plugin-microgateway-core/src/index.js +1 -1
  86. package/packages/datadog-plugin-mocha/src/index.js +13 -9
  87. package/packages/datadog-plugin-moleculer/src/client.js +1 -1
  88. package/packages/datadog-plugin-moleculer/src/index.js +1 -1
  89. package/packages/datadog-plugin-moleculer/src/server.js +1 -1
  90. package/packages/datadog-plugin-mongodb-core/src/index.js +1 -1
  91. package/packages/datadog-plugin-mysql/src/index.js +3 -2
  92. package/packages/datadog-plugin-mysql2/src/index.js +1 -1
  93. package/packages/datadog-plugin-net/src/index.js +9 -75
  94. package/packages/datadog-plugin-net/src/ipc.js +1 -1
  95. package/packages/datadog-plugin-net/src/tcp.js +3 -2
  96. package/packages/datadog-plugin-next/src/index.js +3 -3
  97. package/packages/datadog-plugin-opensearch/src/index.js +1 -1
  98. package/packages/datadog-plugin-oracledb/src/index.js +3 -2
  99. package/packages/datadog-plugin-paperplane/src/index.js +1 -1
  100. package/packages/datadog-plugin-paperplane/src/logger.js +1 -1
  101. package/packages/datadog-plugin-paperplane/src/server.js +1 -1
  102. package/packages/datadog-plugin-pg/src/index.js +3 -2
  103. package/packages/datadog-plugin-pino/src/index.js +1 -1
  104. package/packages/datadog-plugin-playwright/src/index.js +5 -4
  105. package/packages/datadog-plugin-redis/src/index.js +3 -2
  106. package/packages/datadog-plugin-restify/src/index.js +1 -1
  107. package/packages/datadog-plugin-rhea/src/consumer.js +1 -1
  108. package/packages/datadog-plugin-rhea/src/index.js +1 -1
  109. package/packages/datadog-plugin-rhea/src/producer.js +3 -2
  110. package/packages/datadog-plugin-router/src/index.js +8 -8
  111. package/packages/datadog-plugin-sharedb/src/index.js +1 -1
  112. package/packages/datadog-plugin-tedious/src/index.js +3 -2
  113. package/packages/datadog-plugin-web/src/index.js +1 -1
  114. package/packages/datadog-plugin-winston/src/index.js +1 -1
  115. package/packages/dd-trace/src/appsec/{templates/blocked.html → blocked_templates.js} +19 -1
  116. package/packages/dd-trace/src/appsec/blocking.js +9 -24
  117. package/packages/dd-trace/src/appsec/gateway/engine/runner.js +2 -1
  118. package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +2 -0
  119. package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +12 -0
  120. package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +1 -1
  121. package/packages/dd-trace/src/appsec/iast/analyzers/vulnerability-analyzer.js +11 -5
  122. package/packages/dd-trace/src/appsec/iast/iast-log.js +111 -0
  123. package/packages/dd-trace/src/appsec/iast/index.js +8 -4
  124. package/packages/dd-trace/src/appsec/iast/path-line.js +3 -6
  125. package/packages/dd-trace/src/appsec/iast/taint-tracking/index.js +11 -2
  126. package/packages/dd-trace/src/appsec/iast/taint-tracking/operations.js +11 -0
  127. package/packages/dd-trace/src/appsec/iast/taint-tracking/origin-types.js +2 -0
  128. package/packages/dd-trace/src/appsec/iast/taint-tracking/plugin.js +2 -0
  129. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +5 -3
  130. package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +5 -3
  131. package/packages/dd-trace/src/appsec/iast/telemetry/log_collector.js +96 -0
  132. package/packages/dd-trace/src/appsec/iast/telemetry/logs.js +87 -0
  133. package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +27 -2
  134. package/packages/dd-trace/src/appsec/index.js +4 -18
  135. package/packages/dd-trace/src/appsec/recommended.json +43 -14
  136. package/packages/dd-trace/src/appsec/remote_config/index.js +1 -1
  137. package/packages/dd-trace/src/appsec/sdk/index.js +2 -2
  138. package/packages/dd-trace/src/ci-visibility/encode/json-encoder.js +27 -0
  139. package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +2 -9
  140. package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +7 -7
  141. package/packages/dd-trace/src/ci-visibility/exporters/jest-worker/index.js +33 -0
  142. package/packages/dd-trace/src/ci-visibility/exporters/jest-worker/writer.js +37 -0
  143. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-itr-configuration.js +8 -2
  144. package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +8 -2
  145. package/packages/dd-trace/src/config.js +44 -22
  146. package/packages/dd-trace/src/constants.js +2 -1
  147. package/packages/dd-trace/src/datastreams/encoding.js +80 -0
  148. package/packages/dd-trace/src/dcitm.js +51 -0
  149. package/packages/dd-trace/src/exporter.js +7 -9
  150. package/packages/dd-trace/src/exporters/common/agents.js +42 -0
  151. package/packages/dd-trace/src/exporters/common/docker.js +4 -1
  152. package/packages/dd-trace/src/exporters/common/request.js +1 -4
  153. package/packages/dd-trace/src/lambda/handler.js +14 -6
  154. package/packages/dd-trace/src/opentracing/propagation/log.js +23 -7
  155. package/packages/dd-trace/src/opentracing/propagation/text_map.js +28 -2
  156. package/packages/dd-trace/src/opentracing/span.js +19 -3
  157. package/packages/dd-trace/src/opentracing/span_context.js +3 -1
  158. package/packages/dd-trace/src/opentracing/tracer.js +3 -1
  159. package/packages/dd-trace/src/plugin_manager.js +7 -7
  160. package/packages/dd-trace/src/plugins/ci_plugin.js +16 -16
  161. package/packages/dd-trace/src/plugins/index.js +1 -0
  162. package/packages/dd-trace/src/plugins/log_plugin.js +1 -1
  163. package/packages/dd-trace/src/plugins/outgoing.js +2 -1
  164. package/packages/dd-trace/src/plugins/tracing.js +1 -1
  165. package/packages/dd-trace/src/plugins/util/ci.js +12 -0
  166. package/packages/dd-trace/src/plugins/util/ip_extractor.js +23 -27
  167. package/packages/dd-trace/src/plugins/util/test.js +26 -7
  168. package/packages/dd-trace/src/profiling/config.js +87 -20
  169. package/packages/dd-trace/src/profiling/constants.js +16 -0
  170. package/packages/dd-trace/src/profiling/exporter_cli.js +62 -0
  171. package/packages/dd-trace/src/profiling/exporters/agent.js +2 -1
  172. package/packages/dd-trace/src/profiling/profiler.js +21 -8
  173. package/packages/dd-trace/src/profiling/profilers/space.js +21 -1
  174. package/packages/dd-trace/src/span_sampler.js +3 -2
  175. package/packages/dd-trace/src/telemetry/index.js +16 -2
  176. package/packages/dd-trace/src/util.js +10 -1
  177. package/scripts/install_plugin_modules.js +5 -1
  178. package/packages/dd-trace/src/appsec/templates/blocked.json +0 -8
  179. package/scripts/junit_report.js +0 -25
  180. package/scripts/tdd.js +0 -34
@@ -36,6 +36,7 @@ dev,chalk,MIT,Copyright Sindre Sorhus
36
36
  dev,checksum,MIT,Copyright Daniel D. Shaw
37
37
  dev,cli-table3,MIT,Copyright 2014 James Talmage
38
38
  dev,dotenv,BSD-2-Clause,Copyright 2015 Scott Motte
39
+ dev,esbuild,MIT,Copyright (c) 2020 Evan Wallace
39
40
  dev,eslint,MIT,Copyright JS Foundation and other contributors https://js.foundation
40
41
  dev,eslint-config-standard,MIT,Copyright Feross Aboukhadijeh
41
42
  dev,eslint-plugin-import,MIT,Copyright 2015 Ben Mosher
@@ -51,8 +52,6 @@ dev,int64-buffer,MIT,Copyright 2015-2016 Yusuke Kawasaki
51
52
  dev,jszip,MIT,Copyright 2015-2016 Stuart Knightley and contributors
52
53
  dev,mkdirp,MIT,Copyright 2010 James Halliday
53
54
  dev,mocha,MIT,Copyright 2011-2018 JS Foundation and contributors https://js.foundation
54
- dev,mocha-junit-reporter,MIT,Copyright (c) 2015 Michael Allen
55
- dev,mocha-multi-reporters,MIT,Copyright 2019 Yousaf Nabi and 2015 Stanley Ng
56
55
  dev,multer,MIT,Copyright 2014 Hage Yaapa
57
56
  dev,msgpack-lite,MIT,Copyright 2015 Yusuke Kawasaki
58
57
  dev,nock,MIT,Copyright 2017 Pedro Teixeira and other contributors
@@ -62,6 +61,7 @@ dev,proxyquire,MIT,Copyright 2013 Thorsten Lorenz
62
61
  dev,rimraf,ISC,Copyright Isaac Z. Schlueter and Contributors
63
62
  dev,sinon,BSD-3-Clause,Copyright 2010-2017 Christian Johansen
64
63
  dev,sinon-chai,WTFPL and BSD-2-Clause,Copyright 2004 Sam Hocevar 2012–2017 Domenic Denicola
64
+ dev,tap,ISC,Copyright 2011-2022 Isaac Z. Schlueter and Contributors
65
65
  dev,tape,MIT,Copyright James Halliday
66
66
  dev,wait-on,MIT,Copyright 2015 Jeff Barczewski
67
67
  file,aws-lambda-nodejs-runtime-interface-client,Apache 2.0,Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
package/README.md CHANGED
@@ -93,6 +93,10 @@ $ docker-compose up -d -V --remove-orphans --force-recreate
93
93
  $ yarn services
94
94
  ```
95
95
 
96
+ > **Note**
97
+ > The `couchbase`, `grpc` and `oracledb` instrumentations rely on native modules
98
+ > that do not compile on ARM64 devices (for example M1/M2 Mac) - their tests
99
+ > cannot be run locally on these devices.
96
100
 
97
101
  ### Unit Tests
98
102
 
@@ -147,6 +151,19 @@ $ yarn lint
147
151
  ```
148
152
 
149
153
 
154
+ ### Experimental ESM Support
155
+
156
+ ESM support is currently in the experimental stages, while CJS has been supported
157
+ since inception. This means that code loaded using `require()` should work fine
158
+ but code loaded using `import` might not always work.
159
+
160
+ Use the following command to enable experimental ESM support with your application:
161
+
162
+ ```sh
163
+ node --loader dd-trace/loader-hook.mjs entrypoint.js
164
+ ```
165
+
166
+
150
167
  ### Benchmarks
151
168
 
152
169
  Our microbenchmarks live in `benchmark/sirun`. Each directory in there
@@ -171,6 +188,42 @@ That said, even if your application runs on Lambda, any core instrumentation iss
171
188
  Regardless of where you open the issue, someone at Datadog will try to help.
172
189
 
173
190
 
191
+ ## Bundling
192
+
193
+ Generally, `dd-trace` works by intercepting `require()` calls that a Node.js application makes when loading modules. This includes modules that are built-in to Node.js, like the `fs` module for accessing the filesystem, as well as modules installed from the npm registry, like the `pg` database module.
194
+
195
+ Also generally, bundlers work by crawling all of the `require()` calls that an application makes to files on disk, replacing the `require()` calls with custom code, and then concatenating all of the resulting JavaScript into one "bundled" file. When a built-in module is loaded, like `require('fs')`, that call can then remain the same in the resulting bundle.
196
+
197
+ Fundamentally APM tools like `dd-trace` stop working at this point. Perhaps they continue to intercept the calls for built-in modules but don't intercept calls to third party libraries. This means that by default when you bundle a `dd-trace` app with a bundler it is likely to capture information about disk access (via `fs`) and outbound HTTP requests (via `http`), but will otherwise omit calls to third party libraries (like extracting incoming request route information for the `express` framework or showing which query is run for the `mysql` database client).
198
+
199
+ To get around this, one can treat all third party modules, or at least third party modules that the APM needs to instrument, as being "external" to the bundler. With this setting the instrumented modules remain on disk and continue to be loaded via `require()` while the non-instrumented modules are bundled. Sadly this results in a build with many extraneous files and starts to defeat the purpose of bundling.
200
+
201
+ For these reasons it's necessary to have custom-built bundler plugins. Such plugins are able to instruct the bundler on how to behave, injecting intermediary code and otherwise intercepting the "translated" `require()` calls. The result is that many more packages are then included in the bundled JavaScript file. Some applications can have 100% of modules bundled, however native modules still need to remain external to the bundle.
202
+
203
+ ### Esbuild Support
204
+
205
+ This library provides experimental esbuild support in the form of an esbuild plugin, and currently requires at least Node.js v16.17 or v18.7. To use the plugin, make sure you have `dd-trace@3+` installed, and then require the `dd-trace/esbuild` module when building your bundle.
206
+
207
+ Here's an example of how one might use `dd-trace` with esbuild:
208
+
209
+ ```javascript
210
+ const ddPlugin = require('dd-trace/esbuild')
211
+ const esbuild = require('esbuild')
212
+
213
+ esbuild.build({
214
+ entryPoints: ['app.js'],
215
+ bundle: true,
216
+ outfile: 'out.js',
217
+ plugins: [ddPlugin],
218
+ platform: 'node', // allows built-in modules to be required
219
+ target: ['node16']
220
+ }).catch((err) => {
221
+ console.error(err)
222
+ process.exit(1)
223
+ })
224
+ ```
225
+
226
+
174
227
  ## Security Vulnerabilities
175
228
 
176
229
  If you have found a security issue, please contact the security team directly at [security@datadoghq.com](mailto:security@datadoghq.com).
package/ci/init.js CHANGED
@@ -3,13 +3,15 @@ const tracer = require('../packages/dd-trace')
3
3
  const { ORIGIN_KEY } = require('../packages/dd-trace/src/constants')
4
4
  const { isTrue } = require('../packages/dd-trace/src/util')
5
5
 
6
+ const isJestWorker = !!process.env.JEST_WORKER_ID
7
+
6
8
  const options = {
7
9
  startupLogs: false,
8
10
  tags: {
9
11
  [ORIGIN_KEY]: 'ciapp-test'
10
12
  },
11
13
  isCiVisibility: true,
12
- flushInterval: 5000
14
+ flushInterval: isJestWorker ? 0 : 5000
13
15
  }
14
16
 
15
17
  let shouldInit = true
@@ -33,6 +35,12 @@ so dd-trace will not be initialized.`)
33
35
  }
34
36
  }
35
37
 
38
+ if (isJestWorker) {
39
+ options.experimental = {
40
+ exporter: 'jest_worker'
41
+ }
42
+ }
43
+
36
44
  if (shouldInit) {
37
45
  tracer.init(options)
38
46
  tracer.use('fs', false)
@@ -2,7 +2,8 @@ declare const exporters: {
2
2
  LOG: 'log',
3
3
  AGENT: 'agent',
4
4
  DATADOG: 'datadog',
5
- AGENT_PROXY: 'agent_proxy'
5
+ AGENT_PROXY: 'agent_proxy',
6
+ JEST_WORKER: 'jest_worker'
6
7
  }
7
8
 
8
9
  export = exporters
package/ext/exporters.js CHANGED
@@ -3,5 +3,6 @@ module.exports = {
3
3
  LOG: 'log',
4
4
  AGENT: 'agent',
5
5
  DATADOG: 'datadog',
6
- AGENT_PROXY: 'agent_proxy'
6
+ AGENT_PROXY: 'agent_proxy',
7
+ JEST_WORKER: 'jest_worker'
7
8
  }
package/index.d.ts CHANGED
@@ -98,7 +98,7 @@ export declare interface Tracer extends opentracing.Tracer {
98
98
  * * The function doesn't accept a callback and doesn't return a promise, in
99
99
  * which case the span will finish at the end of the function execution.
100
100
  */
101
- wrap<T = (...args: any[]) => any> (name: string, fn: T, requiresParent?: boolean): T;
101
+ wrap<T = (...args: any[]) => any> (name: string, fn: T): T;
102
102
  wrap<T = (...args: any[]) => any> (name: string, options: TraceOptions & SpanOptions, fn: T): T;
103
103
  wrap<T = (...args: any[]) => any> (name: string, options: (...args: any[]) => TraceOptions & SpanOptions, fn: T): T;
104
104
 
@@ -438,7 +438,11 @@ export declare interface TracerOptions {
438
438
  * Controls how many code vulnerabilities can be detected in the same request
439
439
  * @default 2
440
440
  */
441
- maxContextOperations?: number
441
+ maxContextOperations?: number,
442
+ /**
443
+ * Whether to enable vulnerability deduplication
444
+ */
445
+ deduplicationEnabled?: boolean
442
446
  }
443
447
  };
444
448
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "3.15.0",
3
+ "version": "3.17.0",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -14,27 +14,32 @@
14
14
  "type:test": "cd docs && yarn && yarn test",
15
15
  "lint": "node scripts/check_licenses.js && eslint . && yarn audit --groups dependencies",
16
16
  "services": "node ./scripts/install_plugin_modules && node packages/dd-trace/test/setup/services",
17
- "tdd": "node scripts/tdd.js",
18
17
  "test": "SERVICES=* yarn services && mocha --colors --exit --expose-gc 'packages/dd-trace/test/setup/node.js' 'packages/*/test/**/*.spec.js'",
19
- "test:trace:core": "mocha --colors --exit --expose-gc --file packages/dd-trace/test/setup/core.js --exclude \"packages/dd-trace/test/lambda/**/*.spec.js\" --exclude \"packages/dd-trace/test/profiling/**/*.spec.js\" --exclude \"packages/dd-trace/test/appsec/iast/**/*.plugin.spec.js\" \"packages/dd-trace/test/**/*.spec.js\"",
20
- "test:trace:core:ci": "nyc --no-clean --include \"packages/dd-trace/src/**/*.js\" --exclude \"packages/dd-trace/src/lambda/**/*.spec.js\" --exclude \"packages/dd-trace/src/profiling/**/*.js\" --exclude \"packages/dd-trace/test/appsec/iast/**/*.plugin.spec.js\" -- npm run test:trace:core -- --reporter mocha-multi-reporters --reporter-options configFile=mocha-reporter.json",
21
- "test:instrumentations": "mocha --colors --file 'packages/dd-trace/test/setup/core.js' 'packages/datadog-instrumentations/test/**/*.spec.js'",
18
+ "test:appsec": "mocha --colors --exit -r \"packages/dd-trace/test/setup/mocha.js\" --exclude \"packages/dd-trace/test/appsec/iast/**/*.plugin.spec.js\" \"packages/dd-trace/test/appsec/**/*.spec.js\"",
19
+ "test:appsec:ci": "nyc --no-clean --include \"packages/dd-trace/src/appsec/**/*.js\" --exclude \"packages/dd-trace/test/appsec/iast/**/*.plugin.spec.js\" -- npm run test:appsec",
20
+ "test:appsec:plugins": "mocha --colors --exit -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/dd-trace/test/appsec/iast/**/*.@($(echo $PLUGINS)).plugin.spec.js\"",
21
+ "test:appsec:plugins:ci": "yarn services && nyc --no-clean --include \"packages/dd-trace/test/appsec/iast/**/*.@($(echo $PLUGINS)).plugin.spec.js\" -- npm run test:appsec:plugins",
22
+ "test:trace:core": "tap packages/dd-trace/test/*.spec.js \"packages/dd-trace/test/{ci-visibility,encode,exporters,opentracing,plugins,telemetry}/**/*.spec.js\"",
23
+ "test:trace:core:ci": "npm run test:trace:core -- --coverage --nyc-arg=--include=\"packages/dd-trace/src/**/*.js\"",
24
+ "test:instrumentations": "mocha --colors -r 'packages/dd-trace/test/setup/mocha.js' 'packages/datadog-instrumentations/test/**/*.spec.js'",
22
25
  "test:instrumentations:ci": "nyc --no-clean --include 'packages/datadog-instrumentations/src/**/*.js' -- npm run test:instrumentations",
23
- "test:core": "mocha --colors --file packages/datadog-core/test/setup.js 'packages/datadog-core/test/**/*.spec.js'",
24
- "test:core:ci": "nyc --no-clean --include 'packages/datadog-core/src/**/*.js' -- npm run test:core",
25
- "test:lambda": "mocha --colors --exit --file \"packages/dd-trace/test/setup/core.js\" \"packages/dd-trace/test/lambda/**/*.spec.js\"",
26
+ "test:core": "tap \"packages/datadog-core/test/**/*.spec.js\"",
27
+ "test:core:ci": "npm run test:core -- --coverage --nyc-arg=--include=\"packages/datadog-core/src/**/*.js\"",
28
+ "test:lambda": "mocha --colors --exit -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/dd-trace/test/lambda/**/*.spec.js\"",
26
29
  "test:lambda:ci": "nyc --no-clean --include \"packages/dd-trace/src/lambda/**/*.js\" -- npm run test:lambda",
27
- "test:plugins": "mocha --colors --exit --file \"packages/dd-trace/test/setup/core.js\" \"packages/datadog-instrumentations/test/@($(echo $PLUGINS)).spec.js\" \"packages/datadog-plugin-@($(echo $PLUGINS))/test/**/*.spec.js\" \"packages/dd-trace/test/appsec/iast/**/*.@($(echo $PLUGINS)).plugin.spec.js\"",
28
- "test:plugins:ci": "yarn services && nyc --no-clean --include \"packages/datadog-instrumentations/src/@($(echo $PLUGINS)).js\" --include \"packages/datadog-instrumentations/src/@($(echo $PLUGINS))/**/*.js\" --include \"packages/datadog-plugin-@($(echo $PLUGINS))/src/**/*.js\" --include \"packages/dd-trace/test/appsec/iast/**/*.@($(echo $PLUGINS)).plugin.spec.js\" -- npm run test:plugins",
30
+ "test: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\"",
31
+ "test:plugins:ci": "yarn services && nyc --no-clean --include \"packages/datadog-instrumentations/src/@($(echo $PLUGINS)).js\" --include \"packages/datadog-instrumentations/src/@($(echo $PLUGINS))/**/*.js\" --include \"packages/datadog-plugin-@($(echo $PLUGINS))/src/**/*.js\" -- npm run test:plugins",
29
32
  "test:plugins:upstream": "node ./packages/dd-trace/test/plugins/suite.js",
30
- "test:profiler": "mocha --colors --exit --file \"packages/dd-trace/test/setup/core.js\" \"packages/dd-trace/test/profiling/**/*.spec.js\"",
31
- "test:profiler:ci": "nyc --no-clean --include \"packages/dd-trace/src/profiling/**/*.js\" -- npm run test:profiler",
32
- "test:integration": "mocha --colors --timeout 30000 \"integration-tests/**/*.spec.js\"",
33
+ "test:profiler": "tap \"packages/dd-trace/test/profiling/**/*.spec.js\"",
34
+ "test:profiler:ci": "npm run test:profiler -- --coverage --nyc-arg=--include=\"packages/dd-trace/src/profiling/**/*.js\"",
35
+ "test:integration": "mocha --colors --timeout 30000 \"integration-tests/*.spec.js\"",
36
+ "test:integration:cucumber": "mocha --colors --timeout 30000 \"integration-tests/cucumber/*.spec.js\"",
37
+ "test:integration:cypress": "mocha --colors --timeout 30000 \"integration-tests/cypress/*.spec.js\"",
38
+ "test:integration:playwright": "mocha --colors --timeout 30000 \"integration-tests/playwright/*.spec.js\"",
33
39
  "test:shimmer": "mocha --colors 'packages/datadog-shimmer/test/**/*.spec.js'",
34
40
  "test:shimmer:ci": "nyc --no-clean --include 'packages/datadog-shimmer/src/**/*.js' -- npm run test:shimmer",
35
41
  "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'",
36
- "leak:plugins": "yarn services && (cd packages/memwatch && yarn) && NODE_PATH=./packages/memwatch/node_modules node --no-warnings ./node_modules/.bin/tape \"packages/datadog-plugin-@($(echo $PLUGINS))/test/leak.js\"",
37
- "junit:upload": "node ./scripts/junit_report.js"
42
+ "leak:plugins": "yarn services && (cd packages/memwatch && yarn) && NODE_PATH=./packages/memwatch/node_modules node --no-warnings ./node_modules/.bin/tape \"packages/datadog-plugin-@($(echo $PLUGINS))/test/leak.js\""
38
43
  },
39
44
  "repository": {
40
45
  "type": "git",
@@ -62,9 +67,9 @@
62
67
  "dependencies": {
63
68
  "@datadog/native-appsec": "2.0.0",
64
69
  "@datadog/native-iast-rewriter": "2.0.1",
65
- "@datadog/native-iast-taint-tracking": "1.1.1",
70
+ "@datadog/native-iast-taint-tracking": "1.3.1",
66
71
  "@datadog/native-metrics": "^1.5.0",
67
- "@datadog/pprof": "^2.0.0",
72
+ "@datadog/pprof": "^2.1.0",
68
73
  "@datadog/sketches-js": "^2.1.0",
69
74
  "crypto-randomuuid": "^1.0.0",
70
75
  "diagnostics_channel": "^1.1.0",
@@ -99,6 +104,7 @@
99
104
  "checksum": "^0.1.1",
100
105
  "cli-table3": "^0.5.1",
101
106
  "dotenv": "8.2.0",
107
+ "esbuild": "0.16.12",
102
108
  "eslint": "^8.23.0",
103
109
  "eslint-config-standard": "^11.0.0-beta.0",
104
110
  "eslint-plugin-import": "^2.8.0",
@@ -114,8 +120,6 @@
114
120
  "jszip": "^3.5.0",
115
121
  "mkdirp": "^0.5.1",
116
122
  "mocha": "8",
117
- "mocha-junit-reporter": "^2.1.0",
118
- "mocha-multi-reporters": "^1.5.1",
119
123
  "msgpack-lite": "^0.1.26",
120
124
  "multer": "^1.4.5-lts.1",
121
125
  "nock": "^11.3.3",
@@ -125,6 +129,7 @@
125
129
  "rimraf": "^3.0.0",
126
130
  "sinon": "^11.1.2",
127
131
  "sinon-chai": "^3.7.0",
132
+ "tap": "^16.3.4",
128
133
  "tape": "^4.9.1",
129
134
  "wait-on": "^5.0.0"
130
135
  }
@@ -0,0 +1,104 @@
1
+ 'use strict'
2
+
3
+ /* eslint-disable no-console */
4
+
5
+ const NAMESPACE = 'datadog'
6
+
7
+ const instrumented = Object.keys(require('../datadog-instrumentations/src/helpers/hooks.js'))
8
+ const rawBuiltins = require('module').builtinModules
9
+
10
+ warnIfUnsupported()
11
+
12
+ const builtins = new Set()
13
+
14
+ for (const builtin of rawBuiltins) {
15
+ builtins.add(builtin)
16
+ builtins.add(`node:${builtin}`)
17
+ }
18
+
19
+ const packagesOfInterest = new Set()
20
+
21
+ const DEBUG = !!process.env.DD_TRACE_DEBUG
22
+
23
+ // We don't want to handle any built-in packages via DCITM
24
+ // Those packages will still be handled via RITM
25
+ // Attempting to instrument them would fail as they have no package.json file
26
+ for (const pkg of instrumented) {
27
+ if (builtins.has(pkg)) continue
28
+ if (pkg.startsWith('node:')) continue
29
+ packagesOfInterest.add(pkg)
30
+ }
31
+
32
+ const DC_CHANNEL = 'dd-trace:bundledModuleLoadStart'
33
+
34
+ module.exports.name = 'datadog-esbuild'
35
+
36
+ module.exports.setup = function (build) {
37
+ build.onResolve({ filter: /.*/ }, args => {
38
+ const packageName = args.path
39
+
40
+ if (args.namespace === 'file' && packagesOfInterest.has(packageName)) {
41
+ // The file namespace is used when requiring files from disk in userland
42
+ const pathToPackageJson = require.resolve(`${packageName}/package.json`, { paths: [ args.resolveDir ] })
43
+ const pkg = require(pathToPackageJson)
44
+
45
+ if (DEBUG) {
46
+ console.log(`resolve ${packageName}@${pkg.version}`)
47
+ }
48
+
49
+ // https://esbuild.github.io/plugins/#on-resolve-arguments
50
+ return {
51
+ path: packageName,
52
+ namespace: NAMESPACE,
53
+ pluginData: {
54
+ version: pkg.version
55
+ }
56
+ }
57
+ } else if (args.namespace === 'datadog') {
58
+ // The datadog namespace is used when requiring files that are injected during the onLoad stage
59
+ // see note in onLoad
60
+
61
+ if (builtins.has(packageName)) return
62
+
63
+ return {
64
+ path: require.resolve(packageName, { paths: [ args.resolveDir ] }),
65
+ namespace: 'file'
66
+ }
67
+ }
68
+ })
69
+
70
+ build.onLoad({ filter: /.*/, namespace: NAMESPACE }, args => {
71
+ if (DEBUG) {
72
+ console.log(`load ${args.path}@${args.pluginData.version}`)
73
+ }
74
+
75
+ // JSON.stringify adds double quotes. For perf gain could simply add in quotes when we know it's safe.
76
+ const contents = `
77
+ const dc = require('diagnostics_channel');
78
+ const ch = dc.channel(${JSON.stringify(DC_CHANNEL + ':' + args.path)});
79
+ const mod = require(${JSON.stringify(args.path)});
80
+ const payload = {
81
+ module: mod,
82
+ path: ${JSON.stringify(args.path)},
83
+ version: ${JSON.stringify(args.pluginData.version)}
84
+ };
85
+ ch.publish(payload);
86
+ module.exports = payload.module;
87
+ `
88
+ // https://esbuild.github.io/plugins/#on-load-results
89
+ return {
90
+ contents,
91
+ loader: 'js'
92
+ }
93
+ })
94
+ }
95
+
96
+ function warnIfUnsupported () {
97
+ const [major, minor] = process.versions.node.split('.').map(Number)
98
+ if (major < 14 || (major === 14 && minor < 17)) {
99
+ console.error('WARNING: Esbuild support isn\'t available for older versions of Node.js.')
100
+ console.error(`Expected: Node.js >= v14.17. Actual: Node.js = ${process.version}.`)
101
+ console.error('This application may build properly with this version of Node.js, but unless a')
102
+ console.error('more recent version is used at runtime, third party packages won\'t be instrumented.')
103
+ }
104
+ }
@@ -1,4 +1,5 @@
1
1
  'use strict'
2
+ const { createCoverageMap } = require('istanbul-lib-coverage')
2
3
 
3
4
  const { addHook, channel, AsyncResource } = require('./helpers/instrument')
4
5
  const shimmer = require('../../datadog-shimmer')
@@ -12,10 +13,24 @@ const errorCh = channel('ci:cucumber:error')
12
13
 
13
14
  const testSuiteStartCh = channel('ci:cucumber:test-suite:start')
14
15
  const testSuiteFinishCh = channel('ci:cucumber:test-suite:finish')
16
+ const testSuiteCodeCoverageCh = channel('ci:cucumber:test-suite:code-coverage')
15
17
 
18
+ const itrConfigurationCh = channel('ci:cucumber:itr-configuration')
19
+ const skippableSuitesCh = channel('ci:cucumber:test-suite:skippable')
16
20
  const sessionStartCh = channel('ci:cucumber:session:start')
17
21
  const sessionFinishCh = channel('ci:cucumber:session:finish')
18
22
 
23
+ const {
24
+ getCoveredFilenamesFromCoverage,
25
+ resetCoverage,
26
+ mergeCoverage,
27
+ fromCoverageMapToCoverage,
28
+ getTestSuitePath
29
+ } = require('../../dd-trace/src/plugins/util/test')
30
+
31
+ // We'll preserve the original coverage here
32
+ const originalCoverageMap = createCoverageMap()
33
+
19
34
  // TODO: remove in a later major version
20
35
  const patched = new WeakSet()
21
36
 
@@ -88,12 +103,25 @@ function wrapRun (pl, isLatestVersion) {
88
103
  } else {
89
104
  pickleResultByFile[testSuiteFullPath].push(status)
90
105
  }
106
+ testFinishCh.publish({ status, skipReason, errorMessage })
91
107
  // last test in suite
92
108
  if (pickleResultByFile[testSuiteFullPath].length === pickleByFile[testSuiteFullPath].length) {
93
109
  const testSuiteStatus = getSuiteStatusFromTestStatuses(pickleResultByFile[testSuiteFullPath])
110
+ if (global.__coverage__) {
111
+ const coverageFiles = getCoveredFilenamesFromCoverage(global.__coverage__)
112
+
113
+ testSuiteCodeCoverageCh.publish({
114
+ coverageFiles,
115
+ suiteFile: testSuiteFullPath
116
+ })
117
+ // We need to reset coverage to get a code coverage per suite
118
+ // Before that, we preserve the original coverage
119
+ mergeCoverage(global.__coverage__, originalCoverageMap)
120
+ resetCoverage(global.__coverage__)
121
+ }
122
+
94
123
  testSuiteFinishCh.publish(testSuiteStatus)
95
124
  }
96
- testFinishCh.publish({ status, skipReason, errorMessage })
97
125
  })
98
126
  return promise
99
127
  } catch (err) {
@@ -164,6 +192,13 @@ addHook({
164
192
  file: 'lib/runtime/test_case_runner.js'
165
193
  }, testCaseHook)
166
194
 
195
+ function getPicklesToRun (runtime, suitesToSkip) {
196
+ return runtime.pickleIds.filter((pickleId) => {
197
+ const test = runtime.eventDataCollector.getPickle(pickleId)
198
+ return !suitesToSkip.includes(getTestSuitePath(test.uri, process.cwd()))
199
+ }, {})
200
+ }
201
+
167
202
  function getPickleByFile (runtime) {
168
203
  return runtime.pickleIds.reduce((acc, pickleId) => {
169
204
  const test = runtime.eventDataCollector.getPickle(pickleId)
@@ -182,19 +217,61 @@ addHook({
182
217
  file: 'lib/runtime/index.js'
183
218
  }, (runtimePackage, cucumberVersion) => {
184
219
  shimmer.wrap(runtimePackage.default.prototype, 'start', start => async function () {
220
+ const asyncResource = new AsyncResource('bound-anonymous-fn')
221
+ let onDone
222
+
223
+ const configPromise = new Promise(resolve => {
224
+ onDone = resolve
225
+ })
226
+
227
+ asyncResource.runInAsyncScope(() => {
228
+ itrConfigurationCh.publish({ onDone })
229
+ })
230
+
231
+ await configPromise
232
+
233
+ const skippableSuitesPromise = new Promise(resolve => {
234
+ onDone = resolve
235
+ })
236
+
237
+ asyncResource.runInAsyncScope(() => {
238
+ skippableSuitesCh.publish({ onDone })
239
+ })
240
+
241
+ const { err, skippableSuites } = await skippableSuitesPromise
242
+
243
+ if (!err) {
244
+ this.pickleIds = getPicklesToRun(this, skippableSuites)
245
+ }
246
+
185
247
  pickleByFile = getPickleByFile(this)
186
248
 
187
249
  const processArgv = process.argv.slice(2).join(' ')
188
250
  const command = process.env.npm_lifecycle_script || `cucumber-js ${processArgv}`
189
251
 
190
- const asyncResource = new AsyncResource('bound-anonymous-fn')
191
252
  asyncResource.runInAsyncScope(() => {
192
253
  sessionStartCh.publish({ command, frameworkVersion: cucumberVersion })
193
254
  })
194
255
  const success = await start.apply(this, arguments)
195
256
 
257
+ let testCodeCoverageLinesTotal
258
+
259
+ if (global.__coverage__) {
260
+ try {
261
+ testCodeCoverageLinesTotal = originalCoverageMap.getCoverageSummary().lines.pct
262
+ } catch (e) {
263
+ // ignore errors
264
+ }
265
+ // restore the original coverage
266
+ global.__coverage__ = fromCoverageMapToCoverage(originalCoverageMap)
267
+ }
268
+
196
269
  asyncResource.runInAsyncScope(() => {
197
- sessionFinishCh.publish(success ? 'pass' : 'fail')
270
+ sessionFinishCh.publish({
271
+ status: success ? 'pass' : 'fail',
272
+ isSuitesSkipped: skippableSuites ? !!skippableSuites.length : false,
273
+ testCodeCoverageLinesTotal
274
+ })
198
275
  })
199
276
  return success
200
277
  })
@@ -15,46 +15,106 @@ const receiveStartCh = channel(`apm:google-cloud-pubsub:receive:start`)
15
15
  const receiveFinishCh = channel('apm:google-cloud-pubsub:receive:finish')
16
16
  const receiveErrorCh = channel('apm:google-cloud-pubsub:receive:error')
17
17
 
18
- addHook({ name: '@google-cloud/pubsub', versions: ['>=1.2'] }, (obj) => {
19
- const PubSub = obj.PubSub
20
- const Subscription = obj.Subscription
21
-
22
- shimmer.wrap(PubSub.prototype, 'request', request => function (cfg = { reqOpts: {} }, cb) {
23
- if (!requestStartCh.hasSubscribers) {
24
- return request.apply(this, arguments)
25
- }
18
+ const publisherMethods = [
19
+ 'createTopic',
20
+ 'updateTopic',
21
+ 'publish',
22
+ 'getTopic',
23
+ 'listTopics',
24
+ 'listTopicSubscriptions',
25
+ 'listTopicSnapshots',
26
+ 'deleteTopic',
27
+ 'detachSubscription'
28
+ ]
29
+
30
+ const schemaServiceMethods = [
31
+ 'createSchema',
32
+ 'getSchema',
33
+ 'listSchemas',
34
+ 'listSchemaRevisions',
35
+ 'commitSchema',
36
+ 'rollbackSchema',
37
+ 'deleteSchemaRevision',
38
+ 'deleteSchema',
39
+ 'validateSchema',
40
+ 'validateMessage'
41
+ ]
42
+
43
+ const subscriberMethods = [
44
+ 'createSubscription',
45
+ 'getSubscription',
46
+ 'updateSubscription',
47
+ 'listSubscriptions',
48
+ 'deleteSubscription',
49
+ 'modifyAckDeadline',
50
+ 'acknowledge',
51
+ 'pull',
52
+ 'streamingPull',
53
+ 'modifyPushConfig',
54
+ 'getSnapshot',
55
+ 'listSnapshots',
56
+ 'createSnapshot',
57
+ 'updateSnapshot',
58
+ 'deleteSnapshot',
59
+ 'seek'
60
+ ]
61
+
62
+ function wrapMethod (method) {
63
+ const api = method.name
64
+
65
+ return function (request) {
66
+ if (!requestStartCh.hasSubscribers) return method.apply(this, arguments)
26
67
 
27
68
  const innerAsyncResource = new AsyncResource('bound-anonymous-fn')
28
- const outerAsyncResource = new AsyncResource('bound-anonymous-fn')
29
69
 
30
70
  return innerAsyncResource.runInAsyncScope(() => {
31
- let messages = []
32
- if (cfg.reqOpts && cfg.method === 'publish') {
33
- messages = cfg.reqOpts.messages
34
- }
71
+ const projectId = this.auth._cachedProjectId
72
+ const cb = arguments[arguments.length - 1]
73
+
74
+ requestStartCh.publish({ request, api, projectId })
35
75
 
36
- requestStartCh.publish({ cfg, projectId: this.projectId, messages })
37
- cb = outerAsyncResource.bind(cb)
76
+ if (typeof cb === 'function') {
77
+ const outerAsyncResource = new AsyncResource('bound-anonymous-fn')
38
78
 
39
- const fn = () => {
40
- arguments[1] = innerAsyncResource.bind(function (error) {
79
+ arguments[arguments.length - 1] = innerAsyncResource.bind(function (error) {
41
80
  if (error) {
42
81
  requestErrorCh.publish(error)
43
82
  }
44
- requestFinishCh.publish(undefined)
45
- return cb.apply(this, arguments)
83
+
84
+ requestFinishCh.publish()
85
+
86
+ return outerAsyncResource.runInAsyncScope(() => cb.apply(this, arguments))
46
87
  })
47
- return request.apply(this, arguments)
48
- }
49
88
 
50
- try {
51
- return fn.apply(this, arguments)
52
- } catch (e) {
53
- requestErrorCh.publish(e)
54
- throw e
89
+ return method.apply(this, arguments)
90
+ } else {
91
+ return method.apply(this, arguments)
92
+ .then(
93
+ response => {
94
+ requestFinishCh.publish()
95
+ return response
96
+ },
97
+ error => {
98
+ requestErrorCh.publish(error)
99
+ requestFinishCh.publish()
100
+ throw error
101
+ }
102
+ )
55
103
  }
56
104
  })
57
- })
105
+ }
106
+ }
107
+
108
+ function massWrap (obj, methods, wrapper) {
109
+ for (const method of methods) {
110
+ if (typeof obj[method] === 'function') {
111
+ shimmer.wrap(obj, method, wrapper)
112
+ }
113
+ }
114
+ }
115
+
116
+ addHook({ name: '@google-cloud/pubsub', versions: ['>=1.2'] }, (obj) => {
117
+ const Subscription = obj.Subscription
58
118
 
59
119
  shimmer.wrap(Subscription.prototype, 'emit', emit => function (eventName, message) {
60
120
  if (eventName !== 'message' || !message) return emit.apply(this, arguments)
@@ -98,3 +158,16 @@ addHook({ name: '@google-cloud/pubsub', versions: ['>=1.2'], file: 'build/src/le
98
158
 
99
159
  return obj
100
160
  })
161
+
162
+ addHook({ name: '@google-cloud/pubsub', versions: ['>=1.2'] }, (obj) => {
163
+ const { PublisherClient, SchemaServiceClient, SubscriberClient } = obj.v1
164
+
165
+ massWrap(PublisherClient.prototype, publisherMethods, wrapMethod)
166
+ massWrap(SubscriberClient.prototype, subscriberMethods, wrapMethod)
167
+
168
+ if (SchemaServiceClient) {
169
+ massWrap(SchemaServiceClient.prototype, schemaServiceMethods, wrapMethod)
170
+ }
171
+
172
+ return obj
173
+ })