@depup/mysql2 3.20.0-depup.0 → 3.21.1-depup.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,8 +13,8 @@ npm install @depup/mysql2
13
13
 
14
14
  | Field | Value |
15
15
  |-------|-------|
16
- | Original | [mysql2](https://www.npmjs.com/package/mysql2) @ 3.20.0 |
17
- | Processed | 2026-03-16 |
16
+ | Original | [mysql2](https://www.npmjs.com/package/mysql2) @ 3.21.1 |
17
+ | Processed | 2026-04-10 |
18
18
  | Smoke test | passed |
19
19
  | Deps updated | 0 |
20
20
 
package/changes.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "bumped": {},
3
+ "timestamp": "2026-04-10T05:04:40.941Z",
4
+ "totalUpdated": 0
5
+ }
@@ -43,11 +43,15 @@ class Execute extends Command {
43
43
  this._connection = connection;
44
44
  this.options = Object.assign({}, connection.config, this._executeOptions);
45
45
  this._setTimeout();
46
+ const clientFlags =
47
+ connection.config.clientFlags & (connection.serverCapabilityFlags || 0);
46
48
  const executePacket = new Packets.Execute(
47
49
  this.statement.id,
48
50
  this.parameters,
49
51
  connection.config.charsetNumber,
50
- connection.config.timezone
52
+ connection.config.timezone,
53
+ this._executeOptions.attributes,
54
+ clientFlags
51
55
  );
52
56
  //For reasons why this try-catch is here, please see
53
57
  // https://github.com/sidorares/node-mysql2/pull/689
@@ -53,9 +53,13 @@ class Query extends Command {
53
53
  this.options = Object.assign({}, connection.config, this._queryOptions);
54
54
  this._setTimeout();
55
55
 
56
+ const clientFlags =
57
+ connection.config.clientFlags & (connection.serverCapabilityFlags || 0);
56
58
  const cmdPacket = new Packets.Query(
57
59
  this.sql,
58
- connection.config.charsetNumber
60
+ connection.config.charsetNumber,
61
+ this._queryOptions.attributes,
62
+ clientFlags
59
63
  );
60
64
  connection.writePacket(cmdPacket.toPacket(1));
61
65
  return Query.prototype.resultsetHeader;
@@ -35,7 +35,10 @@ class ServerHandshake extends Command {
35
35
 
36
36
  readClientReply(packet, connection) {
37
37
  // check auth here
38
- const clientHelloReply = Packets.HandshakeResponse.fromPacket(packet);
38
+ const clientHelloReply = Packets.HandshakeResponse.fromPacket(
39
+ packet,
40
+ this.args.capabilityFlags
41
+ );
39
42
  // TODO check we don't have something similar already
40
43
  connection.clientHelloReply = clientHelloReply;
41
44
  if (this.args.authCallback) {
@@ -239,6 +239,7 @@ class ConnectionConfig {
239
239
  'TRANSACTIONS',
240
240
  'SESSION_TRACK',
241
241
  'CONNECT_ATTRS',
242
+ 'CLIENT_QUERY_ATTRIBUTES',
242
243
  ];
243
244
  if (options && options.multipleStatements) {
244
245
  defaultFlags.push('MULTI_STATEMENTS');
@@ -31,6 +31,7 @@ exports.CONNECT_ATTRS = 0x00100000; /* permits connection attributes */
31
31
  exports.PLUGIN_AUTH_LENENC_CLIENT_DATA = 0x00200000; /* Understands length-encoded integer for auth response data in Protocol::HandshakeResponse41. */
32
32
  exports.CAN_HANDLE_EXPIRED_PASSWORDS = 0x00400000; /* Announces support for expired password extension. */
33
33
  exports.SESSION_TRACK = 0x00800000; /* Can set SERVER_SESSION_STATE_CHANGED in the Status Flags and send session-state change data after a OK packet. */
34
+ exports.CLIENT_QUERY_ATTRIBUTES = 0x08000000; /* support query attributes in COM_QUERY and COM_STMT_EXECUTE */
34
35
 
35
36
  exports.SSL_VERIFY_SERVER_CERT = 0x40000000;
36
37
  exports.REMEMBER_OPTIONS = 0x80000000;
@@ -5,4 +5,5 @@ module.exports = {
5
5
  READ_ONLY: 1,
6
6
  FOR_UPDATE: 2,
7
7
  SCROLLABLE: 3,
8
+ PARAMETER_COUNT_AVAILABLE: 8,
8
9
  };
@@ -0,0 +1,69 @@
1
+ 'use strict';
2
+
3
+ const Types = require('../constants/types');
4
+ const Packet = require('../packets/packet');
5
+
6
+ function isJSON(value) {
7
+ return (
8
+ Array.isArray(value) ||
9
+ value.constructor === Object ||
10
+ (typeof value.toJSON === 'function' && !Buffer.isBuffer(value))
11
+ );
12
+ }
13
+
14
+ function toParameter(value, encoding, timezone) {
15
+ let type = Types.VAR_STRING;
16
+ let length;
17
+ let writer = function (value) {
18
+ // eslint-disable-next-line no-invalid-this
19
+ return Packet.prototype.writeLengthCodedString.call(this, value, encoding);
20
+ };
21
+ if (value !== null) {
22
+ switch (typeof value) {
23
+ case 'undefined':
24
+ throw new TypeError('Bind parameters must not contain undefined');
25
+
26
+ case 'number':
27
+ type = Types.DOUBLE;
28
+ length = 8;
29
+ writer = Packet.prototype.writeDouble;
30
+ break;
31
+
32
+ case 'boolean':
33
+ value = value | 0;
34
+ type = Types.TINY;
35
+ length = 1;
36
+ writer = Packet.prototype.writeInt8;
37
+ break;
38
+
39
+ case 'object':
40
+ if (Object.prototype.toString.call(value) === '[object Date]') {
41
+ type = Types.DATETIME;
42
+ length = 12;
43
+ writer = function (value) {
44
+ // eslint-disable-next-line no-invalid-this
45
+ return Packet.prototype.writeDate.call(this, value, timezone);
46
+ };
47
+ } else if (isJSON(value)) {
48
+ value = JSON.stringify(value);
49
+ type = Types.JSON;
50
+ } else if (Buffer.isBuffer(value)) {
51
+ length = Packet.lengthCodedNumberLength(value.length) + value.length;
52
+ writer = Packet.prototype.writeLengthCodedBuffer;
53
+ }
54
+ break;
55
+
56
+ default:
57
+ value = value.toString();
58
+ }
59
+ } else {
60
+ value = '';
61
+ type = Types.NULL;
62
+ }
63
+ if (!length) {
64
+ length = Packet.lengthCodedStringLength(value, encoding);
65
+ }
66
+ return { value, type, length, writer };
67
+ }
68
+
69
+ module.exports = { toParameter, isJSON };
@@ -2,83 +2,27 @@
2
2
 
3
3
  const CursorType = require('../constants/cursor');
4
4
  const CommandCodes = require('../constants/commands');
5
+ const ClientConstants = require('../constants/client');
5
6
  const Types = require('../constants/types');
6
7
  const Packet = require('../packets/packet');
7
8
  const CharsetToEncoding = require('../constants/charset_encodings.js');
8
-
9
- function isJSON(value) {
10
- return (
11
- Array.isArray(value) ||
12
- value.constructor === Object ||
13
- (typeof value.toJSON === 'function' && !Buffer.isBuffer(value))
14
- );
15
- }
16
-
17
- /**
18
- * Converts a value to an object describing type, String/Buffer representation and length
19
- * @param {*} value
20
- */
21
- function toParameter(value, encoding, timezone) {
22
- let type = Types.VAR_STRING;
23
- let length;
24
- let writer = function (value) {
25
- // eslint-disable-next-line no-invalid-this
26
- return Packet.prototype.writeLengthCodedString.call(this, value, encoding);
27
- };
28
- if (value !== null) {
29
- switch (typeof value) {
30
- case 'undefined':
31
- throw new TypeError('Bind parameters must not contain undefined');
32
-
33
- case 'number':
34
- type = Types.DOUBLE;
35
- length = 8;
36
- writer = Packet.prototype.writeDouble;
37
- break;
38
-
39
- case 'boolean':
40
- value = value | 0;
41
- type = Types.TINY;
42
- length = 1;
43
- writer = Packet.prototype.writeInt8;
44
- break;
45
-
46
- case 'object':
47
- if (Object.prototype.toString.call(value) === '[object Date]') {
48
- type = Types.DATETIME;
49
- length = 12;
50
- writer = function (value) {
51
- // eslint-disable-next-line no-invalid-this
52
- return Packet.prototype.writeDate.call(this, value, timezone);
53
- };
54
- } else if (isJSON(value)) {
55
- value = JSON.stringify(value);
56
- type = Types.JSON;
57
- } else if (Buffer.isBuffer(value)) {
58
- length = Packet.lengthCodedNumberLength(value.length) + value.length;
59
- writer = Packet.prototype.writeLengthCodedBuffer;
60
- }
61
- break;
62
-
63
- default:
64
- value = value.toString();
65
- }
66
- } else {
67
- value = '';
68
- type = Types.NULL;
69
- }
70
- if (!length) {
71
- length = Packet.lengthCodedStringLength(value, encoding);
72
- }
73
- return { value, type, length, writer };
74
- }
9
+ const { toParameter } = require('./encode_parameter.js');
75
10
 
76
11
  class Execute {
77
- constructor(id, parameters, charsetNumber, timezone) {
12
+ constructor(
13
+ id,
14
+ parameters,
15
+ charsetNumber,
16
+ timezone,
17
+ attributes,
18
+ clientFlags
19
+ ) {
78
20
  this.id = id;
79
21
  this.parameters = parameters;
80
22
  this.encoding = CharsetToEncoding[charsetNumber];
81
23
  this.timezone = timezone;
24
+ this.attributes = attributes;
25
+ this.clientFlags = clientFlags || 0;
82
26
  }
83
27
 
84
28
  static fromPacket(packet, encoding) {
@@ -145,39 +89,48 @@ class Execute {
145
89
  return { stmtId, flags, iterationCount, values };
146
90
  }
147
91
 
148
- toPacket() {
149
- // TODO: don't try to calculate packet length in advance, allocate some big buffer in advance (header + 256 bytes?)
150
- // and copy + reallocate if not enough
151
- // 0 + 4 - length, seqId
152
- // 4 + 1 - COM_EXECUTE
153
- // 5 + 4 - stmtId
154
- // 9 + 1 - flags
155
- // 10 + 4 - iteration-count (always 1)
156
- let length = 14;
157
- let parameters;
158
- if (this.parameters && this.parameters.length > 0) {
159
- length += Math.floor((this.parameters.length + 7) / 8);
160
- length += 1; // new-params-bound-flag
161
- length += 2 * this.parameters.length; // type byte for each parameter if new-params-bound-flag is set
162
- parameters = this.parameters.map((value) =>
163
- toParameter(value, this.encoding, this.timezone)
164
- );
165
- length += parameters.reduce(
166
- (accumulator, parameter) => accumulator + parameter.length,
167
- 0
168
- );
169
- }
170
- const buffer = Buffer.allocUnsafe(length);
171
- const packet = new Packet(0, buffer, 0, length);
92
+ _serializeToBuffer(buffer) {
93
+ const useQueryAttributes =
94
+ this.clientFlags & ClientConstants.CLIENT_QUERY_ATTRIBUTES;
95
+
96
+ const attrNames =
97
+ useQueryAttributes && this.attributes ? Object.keys(this.attributes) : [];
98
+ const numParams = this.parameters ? this.parameters.length : 0;
99
+ const numAttrs = attrNames.length;
100
+ const totalParams = numParams + numAttrs;
101
+
102
+ const packet = new Packet(0, buffer, 0, buffer.length);
172
103
  packet.offset = 4;
173
104
  packet.writeInt8(CommandCodes.STMT_EXECUTE);
174
105
  packet.writeInt32(this.id);
175
- packet.writeInt8(CursorType.NO_CURSOR); // flags
106
+
107
+ let cursorFlags = CursorType.NO_CURSOR;
108
+ if (useQueryAttributes) {
109
+ cursorFlags |= CursorType.PARAMETER_COUNT_AVAILABLE;
110
+ }
111
+ packet.writeInt8(cursorFlags);
176
112
  packet.writeInt32(1); // iteration-count, always 1
177
- if (parameters) {
113
+
114
+ if (useQueryAttributes) {
115
+ packet.writeLengthCodedNumber(totalParams);
116
+ }
117
+
118
+ if (totalParams > 0) {
119
+ const bindParams =
120
+ numParams > 0
121
+ ? this.parameters.map((v) =>
122
+ toParameter(v, this.encoding, this.timezone)
123
+ )
124
+ : [];
125
+ const attrParams = attrNames.map((name) =>
126
+ toParameter(this.attributes[name], this.encoding, this.timezone)
127
+ );
128
+ const allParams = bindParams.concat(attrParams);
129
+
130
+ // null bitmap
178
131
  let bitmap = 0;
179
132
  let bitValue = 1;
180
- parameters.forEach((parameter) => {
133
+ allParams.forEach((parameter) => {
181
134
  if (parameter.type === Types.NULL) {
182
135
  bitmap += bitValue;
183
136
  }
@@ -191,24 +144,34 @@ class Execute {
191
144
  if (bitValue !== 1) {
192
145
  packet.writeInt8(bitmap);
193
146
  }
194
- // TODO: explain meaning of the flag
195
- // afaik, if set n*2 bytes with type of parameter are sent before parameters
196
- // if not, previous execution types are used (TODO prooflink)
147
+
197
148
  packet.writeInt8(1); // new-params-bound-flag
198
- // Write parameter types
199
- parameters.forEach((parameter) => {
200
- packet.writeInt8(parameter.type); // field type
201
- packet.writeInt8(0); // parameter flag
202
- });
203
- // Write parameter values
204
- parameters.forEach((parameter) => {
149
+
150
+ // types (and names for attributes)
151
+ for (let i = 0; i < allParams.length; i++) {
152
+ packet.writeInt8(allParams[i].type);
153
+ packet.writeInt8(0); // unsigned flag
154
+ if (useQueryAttributes) {
155
+ const name = i < numParams ? '' : attrNames[i - numParams];
156
+ packet.writeLengthCodedString(name, this.encoding);
157
+ }
158
+ }
159
+
160
+ // values
161
+ allParams.forEach((parameter) => {
205
162
  if (parameter.type !== Types.NULL) {
206
163
  parameter.writer.call(packet, parameter.value);
207
164
  }
208
165
  });
209
166
  }
167
+
210
168
  return packet;
211
169
  }
170
+
171
+ toPacket() {
172
+ const p = this._serializeToBuffer(Packet.MockBuffer());
173
+ return this._serializeToBuffer(Buffer.allocUnsafe(p.offset));
174
+ }
212
175
  }
213
176
 
214
177
  module.exports = Execute;
@@ -128,11 +128,11 @@ class HandshakeResponse {
128
128
  const p = this.serializeResponse(Packet.MockBuffer());
129
129
  return this.serializeResponse(Buffer.alloc(p.offset));
130
130
  }
131
- static fromPacket(packet) {
131
+ static fromPacket(packet, serverFlags = 0xffffffff) {
132
132
  const args = {};
133
133
  args.clientFlags = packet.readInt32();
134
134
  function isSet(flag) {
135
- return args.clientFlags & ClientConstants[flag];
135
+ return args.clientFlags & serverFlags & ClientConstants[flag];
136
136
  }
137
137
  args.maxPacketSize = packet.readInt32();
138
138
  args.charsetNumber = packet.readInt8();
@@ -155,21 +155,17 @@ class Packet {
155
155
  readInt64() {
156
156
  const word0 = this.readInt32();
157
157
  const word1 = this.readInt32();
158
- let res = new Long(word0, word1, true);
158
+ const res = new Long(word0, word1, true);
159
159
  const resNumber = res.toNumber();
160
- const resString = res.toString();
161
- res = resNumber.toString() === resString ? resNumber : resString;
162
- return res;
160
+ return Number.isSafeInteger(resNumber) ? resNumber : res.toString();
163
161
  }
164
162
 
165
163
  readSInt64() {
166
164
  const word0 = this.readInt32();
167
165
  const word1 = this.readInt32();
168
- let res = new Long(word0, word1, false);
166
+ const res = new Long(word0, word1, false);
169
167
  const resNumber = res.toNumber();
170
- const resString = res.toString();
171
- res = resNumber.toString() === resString ? resNumber : resString;
172
- return res;
168
+ return Number.isSafeInteger(resNumber) ? resNumber : res.toString();
173
169
  }
174
170
 
175
171
  isEOF() {
@@ -223,8 +219,10 @@ class Packet {
223
219
  res = new Long(word0, word1, !signed); // Long need unsigned
224
220
  const resNumber = res.toNumber();
225
221
  const resString = res.toString();
226
- res = resNumber.toString() === resString ? resNumber : resString;
227
- return bigNumberStrings ? resString : res;
222
+ if (bigNumberStrings || !Number.isSafeInteger(resNumber)) {
223
+ return resString;
224
+ }
225
+ return resNumber;
228
226
  }
229
227
 
230
228
  console.trace();
@@ -458,7 +456,7 @@ class Packet {
458
456
  if (numDigits >= 15) {
459
457
  str = this.readString(end - this.offset, 'binary');
460
458
  result = parseInt(str, 10);
461
- if (result.toString() === str) {
459
+ if (Number.isSafeInteger(sign * result)) {
462
460
  return sign * result;
463
461
  }
464
462
  return sign === -1 ? `-${str}` : str;
@@ -480,11 +478,10 @@ class Packet {
480
478
  if (!supportBigNumbers) {
481
479
  return num;
482
480
  }
483
- str = this.buffer.toString('ascii', start, end);
484
- if (num.toString() === str) {
481
+ if (Number.isSafeInteger(num)) {
485
482
  return num;
486
483
  }
487
- return str;
484
+ return this.buffer.toString('ascii', start, end);
488
485
  }
489
486
 
490
487
  // note that if value of inputNumberAsString is bigger than MAX_SAFE_INTEGER
@@ -4,24 +4,99 @@ const Packet = require('../packets/packet.js');
4
4
  const CommandCode = require('../constants/commands.js');
5
5
  const StringParser = require('../parsers/string.js');
6
6
  const CharsetToEncoding = require('../constants/charset_encodings.js');
7
+ const ClientConstants = require('../constants/client.js');
8
+ const Types = require('../constants/types.js');
9
+ const { toParameter } = require('./encode_parameter.js');
7
10
 
8
11
  class Query {
9
- constructor(sql, charsetNumber) {
12
+ constructor(sql, charsetNumber, attributes, clientFlags) {
10
13
  this.query = sql;
11
14
  this.charsetNumber = charsetNumber;
12
15
  this.encoding = CharsetToEncoding[charsetNumber];
16
+ this.attributes = attributes;
17
+ this.clientFlags = clientFlags || 0;
13
18
  }
14
19
 
15
- toPacket() {
16
- const buf = StringParser.encode(this.query, this.encoding);
17
- const length = 5 + buf.length;
18
- const buffer = Buffer.allocUnsafe(length);
19
- const packet = new Packet(0, buffer, 0, length);
20
+ serializeToBuffer(buffer) {
21
+ const useQueryAttributes =
22
+ this.clientFlags & ClientConstants.CLIENT_QUERY_ATTRIBUTES;
23
+ const sqlBuf = StringParser.encode(this.query, this.encoding);
24
+ const packet = new Packet(0, buffer, 0, buffer.length);
20
25
  packet.offset = 4;
21
26
  packet.writeInt8(CommandCode.QUERY);
22
- packet.writeBuffer(buf);
27
+
28
+ if (useQueryAttributes) {
29
+ const attrs = this.attributes;
30
+ const names = attrs ? Object.keys(attrs) : [];
31
+ const paramCount = names.length;
32
+
33
+ packet.writeLengthCodedNumber(paramCount);
34
+ packet.writeLengthCodedNumber(1); // parameter_set_count, always 1
35
+
36
+ if (paramCount > 0) {
37
+ const parameters = names.map((name) =>
38
+ toParameter(attrs[name], this.encoding, 'local')
39
+ );
40
+
41
+ // null bitmap
42
+ let bitmap = 0;
43
+ let bitValue = 1;
44
+ parameters.forEach((parameter) => {
45
+ if (parameter.type === Types.NULL) {
46
+ bitmap += bitValue;
47
+ }
48
+ bitValue *= 2;
49
+ if (bitValue === 256) {
50
+ packet.writeInt8(bitmap);
51
+ bitmap = 0;
52
+ bitValue = 1;
53
+ }
54
+ });
55
+ if (bitValue !== 1) {
56
+ packet.writeInt8(bitmap);
57
+ }
58
+
59
+ packet.writeInt8(1); // new_params_bind_flag
60
+
61
+ // types and names
62
+ for (let i = 0; i < paramCount; i++) {
63
+ packet.writeInt8(parameters[i].type);
64
+ packet.writeInt8(0); // unsigned flag
65
+ packet.writeLengthCodedString(names[i], this.encoding);
66
+ }
67
+
68
+ // values
69
+ parameters.forEach((parameter) => {
70
+ if (parameter.type !== Types.NULL) {
71
+ parameter.writer.call(packet, parameter.value);
72
+ }
73
+ });
74
+ }
75
+ }
76
+
77
+ packet.writeBuffer(sqlBuf);
23
78
  return packet;
24
79
  }
80
+
81
+ toPacket() {
82
+ const useQueryAttributes =
83
+ this.clientFlags & ClientConstants.CLIENT_QUERY_ATTRIBUTES;
84
+
85
+ if (!useQueryAttributes) {
86
+ const buf = StringParser.encode(this.query, this.encoding);
87
+ const length = 5 + buf.length;
88
+ const buffer = Buffer.allocUnsafe(length);
89
+ const packet = new Packet(0, buffer, 0, length);
90
+ packet.offset = 4;
91
+ packet.writeInt8(CommandCode.QUERY);
92
+ packet.writeBuffer(buf);
93
+ return packet;
94
+ }
95
+
96
+ // dry run to calculate required buffer length
97
+ const p = this.serializeToBuffer(Packet.MockBuffer());
98
+ return this.serializeToBuffer(Buffer.allocUnsafe(p.offset));
99
+ }
25
100
  }
26
101
 
27
102
  module.exports = Query;
@@ -39,7 +39,7 @@ class ResultSetHeader {
39
39
  if (isSet('SESSION_TRACK') && packet.offset < packet.end) {
40
40
  this.info = packet.readLengthCodedString(encoding);
41
41
 
42
- if (this.serverStatus && ServerSatusFlags.SERVER_SESSION_STATE_CHANGED) {
42
+ if (this.serverStatus & ServerSatusFlags.SERVER_SESSION_STATE_CHANGED) {
43
43
  // session change info record - see
44
44
  // https://dev.mysql.com/doc/internals/en/packet-OK_Packet.html#cs-sect-packet-ok-sessioninfo
45
45
  let len =
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@depup/mysql2",
3
- "version": "3.20.0-depup.0",
4
- "description": "[DepUp] fast mysql driver. Implements core protocol, prepared statements, ssl and compression in native JS",
3
+ "version": "3.21.1-depup.0",
4
+ "description": "fast mysql driver. Implements core protocol, prepared statements, ssl and compression in native JS (with updated dependencies)",
5
5
  "main": "index.js",
6
6
  "typings": "typings/mysql/index",
7
7
  "type": "commonjs",
@@ -29,10 +29,12 @@
29
29
  },
30
30
  "homepage": "https://sidorares.github.io/node-mysql2/docs",
31
31
  "keywords": [
32
- "depup",
33
- "dependency-bumped",
34
- "updated-deps",
35
32
  "mysql2",
33
+ "depup",
34
+ "updated-dependencies",
35
+ "security",
36
+ "latest",
37
+ "patched",
36
38
  "mysql",
37
39
  "client",
38
40
  "server"
@@ -43,7 +45,9 @@
43
45
  "index.js",
44
46
  "index.d.ts",
45
47
  "promise.js",
46
- "promise.d.ts"
48
+ "promise.d.ts",
49
+ "changes.json",
50
+ "README.md"
47
51
  ],
48
52
  "exports": {
49
53
  ".": "./index.js",
@@ -100,8 +104,8 @@
100
104
  "changes": {},
101
105
  "depsUpdated": 0,
102
106
  "originalPackage": "mysql2",
103
- "originalVersion": "3.20.0",
104
- "processedAt": "2026-03-16T00:39:43.420Z",
107
+ "originalVersion": "3.21.1",
108
+ "processedAt": "2026-04-10T05:04:49.223Z",
105
109
  "smokeTest": "passed"
106
110
  }
107
111
  }
@@ -8,6 +8,8 @@ import {
8
8
  Query as BaseQuery,
9
9
  QueryOptions,
10
10
  QueryError,
11
+ ExecuteValues,
12
+ QueryValues,
11
13
  } from './lib/protocol/sequences/Query.js';
12
14
  import {
13
15
  PoolCluster as BasePoolCluster,
@@ -35,6 +37,8 @@ export {
35
37
  PoolNamespace,
36
38
  QueryOptions,
37
39
  QueryError,
40
+ ExecuteValues,
41
+ QueryValues,
38
42
  PrepareStatementInfo,
39
43
  };
40
44
 
@@ -43,6 +43,13 @@ export interface QueryOptions {
43
43
  */
44
44
  values?: QueryValues;
45
45
 
46
+ /**
47
+ * Query attributes sent alongside the query (MySQL 8.0.25+).
48
+ * Requires the `component_query_attributes` server component to be read via
49
+ * `mysql_query_attribute_string()`.
50
+ */
51
+ attributes?: Record<string, string | number | boolean | null | Buffer | Date>;
52
+
46
53
  /**
47
54
  * This overrides the namedPlaceholders option set at the connection level.
48
55
  */