dd-trace 5.68.0 → 5.69.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 (45) hide show
  1. package/LICENSE-3rdparty.csv +6 -1
  2. package/index.d.ts +193 -1
  3. package/package.json +10 -1
  4. package/packages/datadog-core/src/storage.js +14 -13
  5. package/packages/datadog-esbuild/index.js +62 -26
  6. package/packages/datadog-instrumentations/src/helpers/instrument.js +4 -3
  7. package/packages/datadog-plugin-confluentinc-kafka-javascript/src/index.js +6 -0
  8. package/packages/datadog-plugin-cypress/src/cypress-plugin.js +0 -1
  9. package/packages/datadog-plugin-mongodb-core/src/index.js +18 -5
  10. package/packages/dd-trace/src/aiguard/client.js +25 -0
  11. package/packages/dd-trace/src/aiguard/noop.js +9 -0
  12. package/packages/dd-trace/src/aiguard/sdk.js +173 -0
  13. package/packages/dd-trace/src/aiguard/tags.js +11 -0
  14. package/packages/dd-trace/src/appsec/iast/path-line.js +21 -4
  15. package/packages/dd-trace/src/appsec/iast/taint-tracking/rewriter.js +6 -3
  16. package/packages/dd-trace/src/appsec/stack_trace.js +20 -1
  17. package/packages/dd-trace/src/config-helper.js +8 -1
  18. package/packages/dd-trace/src/config.js +23 -0
  19. package/packages/dd-trace/src/config_defaults.js +5 -0
  20. package/packages/dd-trace/src/datastreams/index.js +23 -1
  21. package/packages/dd-trace/src/llmobs/plugins/ai/index.js +11 -1
  22. package/packages/dd-trace/src/llmobs/plugins/ai/util.js +8 -6
  23. package/packages/dd-trace/src/log/index.js +4 -4
  24. package/packages/dd-trace/src/noop/proxy.js +4 -0
  25. package/packages/dd-trace/src/opentracing/span.js +1 -1
  26. package/packages/dd-trace/src/payload-tagging/config/index.js +16 -0
  27. package/packages/dd-trace/src/payload-tagging/index.js +26 -15
  28. package/packages/dd-trace/src/payload-tagging/tagging.js +17 -8
  29. package/packages/dd-trace/src/pkg.js +3 -1
  30. package/packages/dd-trace/src/plugins/composite.js +3 -0
  31. package/packages/dd-trace/src/plugins/plugin.js +67 -0
  32. package/packages/dd-trace/src/plugins/util/git.js +1 -1
  33. package/packages/dd-trace/src/plugins/util/test.js +19 -0
  34. package/packages/dd-trace/src/priority_sampler.js +70 -46
  35. package/packages/dd-trace/src/proxy.js +15 -0
  36. package/packages/dd-trace/src/rate_limiter.js +26 -1
  37. package/packages/dd-trace/src/sampling_rule.js +124 -2
  38. package/packages/dd-trace/src/span_sampler.js +19 -0
  39. package/packages/dd-trace/src/standalone/product.js +9 -0
  40. package/packages/dd-trace/src/standalone/tracesource.js +16 -1
  41. package/packages/dd-trace/src/standalone/tracesource_priority_sampler.js +13 -0
  42. package/packages/dd-trace/src/startup-log.js +19 -1
  43. package/packages/dd-trace/src/supported-configurations.json +6 -0
  44. package/packages/dd-trace/src/util.js +1 -1
  45. package/version.js +4 -2
@@ -33,7 +33,11 @@ require,shell-quote,mit,Copyright (c) 2013 James Halliday
33
33
  require,source-map,BSD-3-Clause,Copyright (c) 2009-2011, Mozilla Foundation and contributors
34
34
  require,ttl-set,MIT,Copyright (c) 2024 Thomas Watson
35
35
  dev,@babel/helpers,MIT,Copyright (c) 2014-present Sebastian McKenzie and other contributors
36
- dev,@types/node,MIT,Copyright Authors
36
+ dev,@types/chai,MIT,Copyright (c) Microsoft Corp.
37
+ dev,@types/mocha,MIT,Copyright (c) Microsoft Corp.
38
+ dev,@types/node,MIT,Copyright (c) Microsoft Corp.
39
+ dev,@types/sinon,MIT,Copyright (c) Microsoft Corp.
40
+ dev,@types/tap,MIT,Copyright (c) Microsoft Corp.
37
41
  dev,@eslint/eslintrc,MIT,Copyright OpenJS Foundation and other contributors, <www.openjsf.org>
38
42
  dev,@eslint/js,MIT,Copyright OpenJS Foundation and other contributors, <www.openjsf.org>
39
43
  dev,@msgpack/msgpack,ISC,Copyright 2019 The MessagePack Community
@@ -65,6 +69,7 @@ dev,sinon,BSD-3-Clause,Copyright 2010-2017 Christian Johansen
65
69
  dev,sinon-chai,WTFPL and BSD-2-Clause,Copyright 2004 Sam Hocevar 2012–2017 Domenic Denicola
66
70
  dev,tap,ISC,Copyright 2011-2022 Isaac Z. Schlueter and Contributors
67
71
  dev,tiktoken,MIT,Copyright (c) 2022 OpenAI, Shantanu Jain
72
+ dev,typescript,Apache license 2.0,Copyright Microsoft Corp.
68
73
  dev,workerpool,Apache license 2.0,Copyright (C) 2014-2024 Jos de Jong wjosdejong@gmail.com
69
74
  dev,yaml,ISC,Copyright Eemeli Aro <eemeli@gmail.com>
70
75
  dev,yarn-deduplicate,Apache license 2.0,Copyright [yyyy] [name of copyright owner]
package/index.d.ts CHANGED
@@ -139,6 +139,11 @@ interface Tracer extends opentracing.Tracer {
139
139
  */
140
140
  llmobs: tracer.llmobs.LLMObs;
141
141
 
142
+ /**
143
+ * AI Guard SDK
144
+ */
145
+ aiguard: tracer.aiguard.AIGuard;
146
+
142
147
  /**
143
148
  * @experimental
144
149
  * Provide same functionality as OpenTelemetry Baggage:
@@ -593,6 +598,29 @@ declare namespace tracer {
593
598
  */
594
599
  enabled?: boolean
595
600
  }
601
+ },
602
+
603
+ aiguard?: {
604
+ /**
605
+ * Set to `true` to enable the SDK.
606
+ */
607
+ enabled?: boolean,
608
+ /**
609
+ * URL of the AI Guard REST API.
610
+ */
611
+ endpoint?: string,
612
+ /**
613
+ * Timeout used in calls to the AI Guard REST API in milliseconds (default 5000)
614
+ */
615
+ timeout?: number,
616
+ /**
617
+ * Maximum number of conversational messages allowed to be set in the meta-struct
618
+ */
619
+ maxMessagesLength?: number,
620
+ /**
621
+ * Max size of the content property set in the meta-struct
622
+ */
623
+ maxContentSize?: number
596
624
  }
597
625
  };
598
626
 
@@ -907,7 +935,7 @@ declare namespace tracer {
907
935
  scope?: string,
908
936
 
909
937
  /**
910
- * Custom fields to attach to the user (RBAC, Oauth, etc).
938
+ * Custom fields to attach to the user (RBAC, Oauth, etc...).
911
939
  */
912
940
  [key: string]: string | undefined
913
941
  }
@@ -1059,6 +1087,170 @@ declare namespace tracer {
1059
1087
  eventTrackingV2: EventTrackingV2
1060
1088
  }
1061
1089
 
1090
+ export namespace aiguard {
1091
+
1092
+ /**
1093
+ * Represents a tool call made by an AI assistant in an agentic workflow.
1094
+ */
1095
+ export interface ToolCall {
1096
+ /**
1097
+ * Unique identifier for this specific tool call instance used to correlate the call with its response.
1098
+ */
1099
+ id: string;
1100
+ /**
1101
+ * Details about the function being invoked.
1102
+ */
1103
+ function: {
1104
+ /**
1105
+ * The name of the tool/function to be called.
1106
+ */
1107
+ name: string;
1108
+ /**
1109
+ * String containing the arguments to pass to the tool.
1110
+ */
1111
+ arguments: string;
1112
+ };
1113
+ }
1114
+
1115
+ /**
1116
+ * A standard conversational message exchanged with a Large Language Model (LLM).
1117
+ */
1118
+ export interface TextMessage {
1119
+ /**
1120
+ * The role of the message sender in the conversation (e.g.: 'system', 'user', 'assistant').
1121
+ */
1122
+ role: string;
1123
+ /**
1124
+ * The textual content of the message.
1125
+ */
1126
+ content: string;
1127
+ }
1128
+
1129
+ /**
1130
+ * A message from an AI assistant containing only textual content.
1131
+ */
1132
+ export interface AssistantTextMessage {
1133
+ /**
1134
+ * The role identifier, always set to 'assistant'
1135
+ */
1136
+ role: "assistant";
1137
+ /**
1138
+ * The textual response content from the assistant.
1139
+ */
1140
+ content: string;
1141
+ /**
1142
+ * Explicitly excluded when content is present to maintain type safety.
1143
+ */
1144
+ tool_calls?: never;
1145
+ }
1146
+
1147
+ /**
1148
+ * A message from an AI assistant that initiates one or more tool calls.
1149
+ */
1150
+ export interface AssistantToolCallMessage {
1151
+ /**
1152
+ * The role identifier, always set to 'assistant'
1153
+ */
1154
+ role: "assistant";
1155
+ /**
1156
+ * Array of tool calls that the assistant wants to execute.
1157
+ */
1158
+ tool_calls: ToolCall[];
1159
+ /**
1160
+ * Explicitly excluded when tool calls are present to maintain type safety.
1161
+ */
1162
+ content?: never;
1163
+ }
1164
+
1165
+ /**
1166
+ * A message containing the result of a tool invocation.
1167
+ */
1168
+ export interface ToolMessage {
1169
+ /**
1170
+ * The role identifier, always set to 'tool' for tool execution results.
1171
+ */
1172
+ role: "tool";
1173
+ /**
1174
+ * The unique identifier linking this result to the original tool call.
1175
+ * Must correspond to a ToolCall.id from a previous AssistantToolCallMessage.
1176
+ */
1177
+ tool_call_id: string;
1178
+ /**
1179
+ * The output returned by the tool execution.
1180
+ */
1181
+ content: string;
1182
+ }
1183
+
1184
+ export type Message =
1185
+ | TextMessage
1186
+ | AssistantTextMessage
1187
+ | AssistantToolCallMessage
1188
+ | ToolMessage;
1189
+
1190
+ /**
1191
+ * The result returned by AI Guard after evaluating a conversation.
1192
+ */
1193
+ export interface Evaluation {
1194
+ /**
1195
+ * The security action determined by AI Guard:
1196
+ * - 'ALLOW': The conversation is safe to proceed
1197
+ * - 'DENY': The current conversation exchange should be blocked
1198
+ * - 'ABORT': The full workflow should be terminated immediately
1199
+ */
1200
+ action: 'ALLOW' | 'DENY' | 'ABORT';
1201
+ /**
1202
+ * Human-readable explanation for why this action was chosen.
1203
+ */
1204
+ reason: string;
1205
+ }
1206
+
1207
+ /**
1208
+ * Error thrown when AI Guard evaluation determines that a conversation should be blocked
1209
+ * and the client is configured to enforce blocking mode.
1210
+ */
1211
+ export interface AIGuardAbortError extends Error {
1212
+ /**
1213
+ * Human-readable explanation from AI Guard describing why the conversation was blocked.
1214
+ */
1215
+ reason: string;
1216
+ }
1217
+
1218
+ /**
1219
+ * Error thrown when the AI Guard SDK encounters communication failures or API errors while attempting to
1220
+ * evaluate conversations.
1221
+ */
1222
+ export interface AIGuardClientError extends Error {
1223
+ /**
1224
+ * Detailed error information returned by the AI Guard API, formatted according to the JSON:API error
1225
+ * specification.
1226
+ */
1227
+ errors?: unknown[];
1228
+ /**
1229
+ * The underlying error that caused the communication failure, such as network timeouts, connection refused,
1230
+ * or JSON parsing errors.
1231
+ */
1232
+ cause?: Error;
1233
+ }
1234
+
1235
+ /**
1236
+ * AI Guard security client for evaluating AI conversations.
1237
+ */
1238
+ export interface AIGuard {
1239
+ /**
1240
+ * Evaluates a conversation thread.
1241
+ *
1242
+ * @param messages - Array of conversation messages
1243
+ * @param opts - Optional configuration object:
1244
+ * - `block`: When true, throws an exception if evaluation result is not 'ALLOW'
1245
+ * and the AI Guard service has blocking mode enabled (default: false).
1246
+ * @returns Promise resolving to an Evaluation with the security decision and reasoning.
1247
+ * The promise rejects with AIGuardAbortError when `opts.block` is true and the evaluation result would block the request.
1248
+ * The promise rejects with AIGuardClientError when communication with the AI Guard service fails.
1249
+ */
1250
+ evaluate (messages: Message[], opts?: { block?: boolean }): Promise<Evaluation>;
1251
+ }
1252
+ }
1253
+
1062
1254
  /** @hidden */
1063
1255
  type anyObject = {
1064
1256
  [key: string]: any;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-trace",
3
- "version": "5.68.0",
3
+ "version": "5.69.0",
4
4
  "description": "Datadog APM tracing client for JavaScript",
5
5
  "main": "index.js",
6
6
  "typings": "index.d.ts",
@@ -10,6 +10,7 @@
10
10
  "bench": "node benchmark/index.js",
11
11
  "bench:e2e:test-optimization": "node benchmark/e2e-test-optimization/benchmark-run.js",
12
12
  "dependencies:dedupe": "yarn-deduplicate yarn.lock",
13
+ "type:check": "tsc --noEmit -p tsconfig.json",
13
14
  "type:doc": "cd docs && yarn && yarn build",
14
15
  "type:test": "cd docs && yarn && yarn test",
15
16
  "lint": "node scripts/check_licenses.js && eslint . --concurrency=auto --max-warnings 0",
@@ -18,6 +19,8 @@
18
19
  "release:proposal": "node scripts/release/proposal",
19
20
  "services": "node ./scripts/install_plugin_modules && node packages/dd-trace/test/setup/services",
20
21
  "test": "SERVICES=* yarn services && mocha --expose-gc 'packages/dd-trace/test/setup/node.js' 'packages/*/test/**/*.spec.js'",
22
+ "test:aiguard": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/dd-trace/test/aiguard/**/*.spec.js\"",
23
+ "test:aiguard:ci": "nyc --no-clean --include \"packages/dd-trace/src/aiguard/**/*.js\" -- npm run test:aiguard",
21
24
  "test:appsec": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" --exclude \"packages/dd-trace/test/appsec/**/*.plugin.spec.js\" \"packages/dd-trace/test/appsec/**/*.spec.js\"",
22
25
  "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",
23
26
  "test:appsec:plugins": "mocha -r \"packages/dd-trace/test/setup/mocha.js\" \"packages/dd-trace/test/appsec/**/*.@($(echo $PLUGINS)).plugin.spec.js\"",
@@ -47,6 +50,7 @@
47
50
  "test:profiler": "tap \"packages/dd-trace/test/profiling/**/*.spec.js\"",
48
51
  "test:profiler:ci": "npm run test:profiler -- --coverage --nyc-arg=--include=\"packages/dd-trace/src/profiling/**/*.js\"",
49
52
  "test:integration": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/*.spec.js\"",
53
+ "test:integration:aiguard": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/aiguard/*.spec.js\"",
50
54
  "test:integration:appsec": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/appsec/*.spec.js\"",
51
55
  "test:integration:cucumber": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/cucumber/*.spec.js\"",
52
56
  "test:integration:cypress": "mocha --timeout 60000 -r \"packages/dd-trace/test/setup/core.js\" \"integration-tests/cypress/*.spec.js\"",
@@ -153,7 +157,11 @@
153
157
  "@eslint/js": "^9.29.0",
154
158
  "@msgpack/msgpack": "^3.1.2",
155
159
  "@stylistic/eslint-plugin": "^5.0.0",
160
+ "@types/chai": "^4.3.16",
161
+ "@types/mocha": "^10.0.10",
156
162
  "@types/node": "^18.19.106",
163
+ "@types/sinon": "^17.0.4",
164
+ "@types/tap": "^15.0.12",
157
165
  "axios": "^1.12.2",
158
166
  "benchmark": "^2.1.4",
159
167
  "body-parser": "^2.2.0",
@@ -181,6 +189,7 @@
181
189
  "sinon-chai": "^3.7.0",
182
190
  "tap": "^16.3.10",
183
191
  "tiktoken": "^1.0.21",
192
+ "typescript": "^5.9.2",
184
193
  "workerpool": "^9.2.0",
185
194
  "yaml": "^2.8.0",
186
195
  "yarn-deduplicate": "^6.0.2"
@@ -10,12 +10,13 @@ const { AsyncLocalStorage } = require('async_hooks')
10
10
  * a "handle" object, which is used as a key in a WeakMap, where the values
11
11
  * are the real store objects.
12
12
  *
13
- * @template T
13
+ * @typedef {Record<string, unknown>} Store
14
14
  */
15
15
  class DatadogStorage extends AsyncLocalStorage {
16
16
  /**
17
17
  *
18
- * @param store {DatadogStorage}
18
+ * @param store {Store}
19
+ * @override
19
20
  */
20
21
  enterWith (store) {
21
22
  const handle = {}
@@ -34,7 +35,7 @@ class DatadogStorage extends AsyncLocalStorage {
34
35
  *
35
36
  * TODO: Refactor the Scope class to use a span-only store and remove this.
36
37
  *
37
- * @returns {{}}
38
+ * @returns {Store}
38
39
  */
39
40
  getHandle () {
40
41
  return super.getStore()
@@ -46,9 +47,9 @@ class DatadogStorage extends AsyncLocalStorage {
46
47
  * retrieved through `getHandle()` can also be passed in to be used as the
47
48
  * key. This is useful if you've stashed a handle somewhere and want to
48
49
  * retrieve the store with it.
49
- *
50
- * @param [handle] {{}}
51
- * @returns {T | undefined}
50
+ * @param {{}} [handle]
51
+ * @returns {Store | undefined}
52
+ * @override
52
53
  */
53
54
  getStore (handle) {
54
55
  if (!handle) {
@@ -66,11 +67,12 @@ class DatadogStorage extends AsyncLocalStorage {
66
67
  * when dealing with the parent store, so that we don't have to access the
67
68
  * WeakMap.
68
69
  * @template R
69
- * @template TArgs extends any[]
70
- * @param store {DatadogStorage}
71
- * @param fn {() => R}
72
- * @param args {TArgs}
73
- * @returns {void}
70
+ * @template TArgs = unknown[]
71
+ * @param {Store} store
72
+ * @param {() => R} fn
73
+ * @param {...TArgs} args
74
+ * @returns {R}
75
+ * @override
74
76
  */
75
77
  run (store, fn, ...args) {
76
78
  const prior = super.getStore()
@@ -85,8 +87,7 @@ class DatadogStorage extends AsyncLocalStorage {
85
87
 
86
88
  /**
87
89
  * This is the map from handles to real stores, used in the class above.
88
- * @template T
89
- * @type {WeakMap<WeakKey, T>}
90
+ * @type {WeakMap<WeakKey, Store>}
90
91
  */
91
92
  const stores = new WeakMap()
92
93
 
@@ -8,6 +8,8 @@ const extractPackageAndModulePath = require(
8
8
  '../datadog-instrumentations/src/helpers/extract-package-and-module-path.js'
9
9
  )
10
10
 
11
+ let rewriter
12
+
11
13
  for (const hook of Object.values(hooks)) {
12
14
  if (typeof hook === 'object') {
13
15
  hook.fn()
@@ -43,6 +45,7 @@ for (const builtin of RAW_BUILTINS) {
43
45
  }
44
46
 
45
47
  const DEBUG = !!process.env.DD_TRACE_DEBUG
48
+ const DD_IAST_ENABLED = process.env.DD_IAST_ENABLED?.toLowerCase() === 'true' || process.env.DD_IAST_ENABLED === '1'
46
49
 
47
50
  // We don't want to handle any built-in packages
48
51
  // Those packages will still be handled via RITM
@@ -96,10 +99,23 @@ function getGitMetadata () {
96
99
  }
97
100
 
98
101
  module.exports.setup = function (build) {
102
+ if (DD_IAST_ENABLED) {
103
+ const iastRewriter = require('../dd-trace/src/appsec/iast/taint-tracking/rewriter')
104
+ rewriter = iastRewriter.getRewriter()
105
+ }
106
+
107
+ const isSourceMapEnabled = !!build.initialOptions.sourcemap ||
108
+ ['internal', 'both'].includes(build.initialOptions.sourcemap)
99
109
  const externalModules = new Set(build.initialOptions.external || [])
110
+ build.initialOptions.banner ??= {}
111
+ build.initialOptions.banner.js ??= ''
112
+ if (DD_IAST_ENABLED) {
113
+ build.initialOptions.banner.js =
114
+ `globalThis.__DD_ESBUILD_IAST_${isSourceMapEnabled ? 'WITH_SM' : 'WITH_NO_SM'} = true;
115
+ ${isSourceMapEnabled ? `globalThis.__DD_ESBUILD_BASEPATH = '${require('../dd-trace/src/util').ddBasePath}';` : ''}
116
+ ${build.initialOptions.banner.js}`
117
+ }
100
118
  if (isESMBuild(build)) {
101
- build.initialOptions.banner ??= {}
102
- build.initialOptions.banner.js ??= ''
103
119
  if (!build.initialOptions.banner.js.includes('import { createRequire as $dd_createRequire } from \'module\'')) {
104
120
  build.initialOptions.banner.js = `import { createRequire as $dd_createRequire } from 'module';
105
121
  import { fileURLToPath as $dd_fileURLToPath } from 'url';
@@ -140,13 +156,6 @@ ${build.initialOptions.banner.js}`
140
156
  return
141
157
  }
142
158
 
143
- // TODO: Should this also check for namespace === 'file'?
144
- if (args.path.startsWith('.') && !args.importer.includes('node_modules/')) {
145
- // This is local application code, not an instrumented package
146
- if (DEBUG) console.log(`LOCAL: ${args.path}`)
147
- return
148
- }
149
-
150
159
  // TODO: Should this also check for namespace === 'file'?
151
160
  if (!modulesOfInterest.has(args.path) &&
152
161
  args.path.startsWith('@') &&
@@ -166,6 +175,21 @@ ${build.initialOptions.banner.js}`
166
175
  }
167
176
  return
168
177
  }
178
+
179
+ if (args.path.startsWith('.') && !args.importer.includes('node_modules/')) {
180
+ // It is local application code, not an instrumented package
181
+ if (DEBUG) console.log(`APP: ${args.path}`)
182
+
183
+ return {
184
+ path: fullPathToModule,
185
+ pluginData: {
186
+ path: args.path,
187
+ full: fullPathToModule,
188
+ applicationFile: true
189
+ }
190
+ }
191
+ }
192
+
169
193
  const extracted = extractPackageAndModulePath(fullPathToModule)
170
194
 
171
195
  const internal = builtins.has(args.path)
@@ -215,22 +239,19 @@ ${build.initialOptions.banner.js}`
215
239
  })
216
240
 
217
241
  build.onLoad({ filter: /.*/ }, args => {
218
- if (!args.pluginData?.pkgOfInterest) {
219
- return
220
- }
221
-
222
- const data = args.pluginData
242
+ if (args.pluginData?.pkgOfInterest) {
243
+ const data = args.pluginData
223
244
 
224
- if (DEBUG) console.log(`LOAD: ${data.pkg}@${data.version}, pkg "${data.path}"`)
245
+ if (DEBUG) console.log(`LOAD: ${data.pkg}@${data.version}, pkg "${data.path}"`)
225
246
 
226
- const pkgPath = data.raw !== data.pkg
227
- ? `${data.pkg}/${data.path}`
228
- : data.pkg
247
+ const pkgPath = data.raw !== data.pkg
248
+ ? `${data.pkg}/${data.path}`
249
+ : data.pkg
229
250
 
230
- // Read the content of the module file of interest
231
- const fileCode = fs.readFileSync(args.path, 'utf8')
251
+ // Read the content of the module file of interest
252
+ const fileCode = fs.readFileSync(args.path, 'utf8')
232
253
 
233
- const contents = `
254
+ const contents = `
234
255
  (function() {
235
256
  ${fileCode}
236
257
  })(...arguments);
@@ -248,12 +269,27 @@ ${build.initialOptions.banner.js}`
248
269
  module.exports = payload.module;
249
270
  }
250
271
  `
272
+ // https://esbuild.github.io/plugins/#on-load-results
273
+ return {
274
+ contents,
275
+ loader: 'js',
276
+ resolveDir: path.dirname(args.path)
277
+ }
278
+ }
279
+
280
+ if (DD_IAST_ENABLED && args.pluginData?.applicationFile) {
281
+ const ext = path.extname(args.path).toLowerCase()
282
+ const isJs = /^\.(js|mjs|cjs)$/.test(ext)
283
+ if (!isJs) return
251
284
 
252
- // https://esbuild.github.io/plugins/#on-load-results
253
- return {
254
- contents,
255
- loader: 'js',
256
- resolveDir: path.dirname(args.path)
285
+ if (DEBUG) console.log(`REWRITE: ${args.path}`)
286
+ const fileCode = fs.readFileSync(args.path, 'utf8')
287
+ const rewritten = rewriter.rewrite(fileCode, args.path, ['iast'])
288
+ return {
289
+ contents: rewritten.content,
290
+ loader: 'js',
291
+ resolveDir: path.dirname(args.path)
292
+ }
257
293
  }
258
294
  })
259
295
  }
@@ -23,10 +23,11 @@ exports.tracingChannel = function (name) {
23
23
  }
24
24
 
25
25
  /**
26
- * @param {string} args.name module name
26
+ * @param {object} args
27
+ * @param {string|string[]} args.name module name
27
28
  * @param {string[]} args.versions array of semver range strings
28
- * @param {string} args.file path to file within package to instrument
29
- * @param {string} args.filePattern pattern to match files within package to instrument
29
+ * @param {string} [args.file='index.js'] path to file within package to instrument
30
+ * @param {string} [args.filePattern] pattern to match files within package to instrument
30
31
  * @param Function hook
31
32
  */
32
33
  exports.addHook = function addHook ({ name, versions, file, filePattern, patchDefault }, hook) {
@@ -6,7 +6,13 @@ const BatchConsumerPlugin = require('./batch-consumer')
6
6
  const KafkajsPlugin = require('../../datadog-plugin-kafkajs/src/index')
7
7
 
8
8
  class ConfluentKafkaJsPlugin extends KafkajsPlugin {
9
+ /**
10
+ * @override
11
+ */
9
12
  static id = 'confluentinc-kafka-javascript'
13
+ /**
14
+ * @override
15
+ */
10
16
  static get plugins () {
11
17
  return {
12
18
  producer: ProducerPlugin,
@@ -389,7 +389,6 @@ class CypressPlugin {
389
389
 
390
390
  getTestSpan ({ testName, testSuite, isUnskippable, isForcedToRun, testSourceFile, isDisabled, isQuarantined }) {
391
391
  const testSuiteTags = {
392
- [TEST_COMMAND]: this.command,
393
392
  [TEST_COMMAND]: this.command,
394
393
  [TEST_MODULE]: TEST_FRAMEWORK_NAME
395
394
  }
@@ -9,8 +9,14 @@ class MongodbCorePlugin extends DatabasePlugin {
9
9
  static component = 'mongodb'
10
10
  // avoid using db.name for peer.service since it includes the collection name
11
11
  // should be removed if one day this will be fixed
12
+ /**
13
+ * @override
14
+ */
12
15
  static peerServicePrecursors = []
13
16
 
17
+ /**
18
+ * @override
19
+ */
14
20
  configure (config) {
15
21
  super.configure(config)
16
22
 
@@ -51,11 +57,18 @@ class MongodbCorePlugin extends DatabasePlugin {
51
57
  return ctx.currentStore
52
58
  }
53
59
 
60
+ /**
61
+ * @override
62
+ */
54
63
  getPeerService (tags) {
55
- const ns = tags['db.name']
64
+ let ns = tags['db.name']
56
65
  if (ns && tags['peer.service'] === undefined) {
66
+ const dotIndex = ns.indexOf('.')
67
+ if (dotIndex !== -1) {
68
+ ns = ns.slice(0, dotIndex)
69
+ }
57
70
  // the mongo ns is either dbName either dbName.collection. So we keep the first part
58
- tags['peer.service'] = ns.split('.', 1)[0]
71
+ tags['peer.service'] = ns
59
72
  }
60
73
  return super.getPeerService(tags)
61
74
  }
@@ -111,13 +124,13 @@ function getQuery (cmd) {
111
124
  }
112
125
 
113
126
  function getResource (plugin, ns, query, operationName) {
114
- const parts = [operationName, ns]
127
+ let resource = `${operationName} ${ns}`
115
128
 
116
129
  if (plugin.config.queryInResourceName && query) {
117
- parts.push(query)
130
+ resource += ` ${query}`
118
131
  }
119
132
 
120
- return parts.join(' ')
133
+ return resource
121
134
  }
122
135
 
123
136
  function truncate (input) {
@@ -0,0 +1,25 @@
1
+ 'use strict'
2
+
3
+ async function executeRequest (body, opts) {
4
+ const postData = JSON.stringify(body)
5
+ const headers = {
6
+ 'Content-Type': 'application/json',
7
+ 'Content-Length': Buffer.byteLength(postData),
8
+ ...opts.headers
9
+ }
10
+
11
+ const response = await fetch(opts.url, {
12
+ method: 'POST',
13
+ headers,
14
+ body: postData,
15
+ signal: AbortSignal.timeout(opts.timeout)
16
+ })
17
+
18
+ const responseBody = await response.json()
19
+ return {
20
+ status: response.status,
21
+ body: responseBody
22
+ }
23
+ }
24
+
25
+ module.exports = executeRequest
@@ -0,0 +1,9 @@
1
+ 'use strict'
2
+
3
+ class NoopAIGuard {
4
+ evaluate (messages, opts) {
5
+ return Promise.resolve({ action: 'ALLOW', reason: 'AI Guard is not enabled' })
6
+ }
7
+ }
8
+
9
+ module.exports = NoopAIGuard