@depup/mysql2 3.19.1-depup.0 → 3.21.0-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 +2 -2
- package/changes.json +5 -0
- package/lib/auth_plugins/caching_sha2_password.js +1 -0
- package/lib/auth_plugins/sha256_password.js +7 -1
- package/lib/base/connection.js +166 -19
- package/lib/base/pool.js +71 -40
- package/lib/commands/execute.js +5 -1
- package/lib/commands/query.js +5 -1
- package/lib/connection_config.js +1 -0
- package/lib/constants/client.js +1 -0
- package/lib/constants/cursor.js +1 -0
- package/lib/packets/encode_parameter.js +69 -0
- package/lib/packets/execute.js +68 -105
- package/lib/packets/query.js +82 -7
- package/lib/packets/resultset_header.js +1 -1
- package/lib/pool_connection.js +71 -2
- package/lib/promise/pool_connection.js +1 -5
- package/lib/tracing.js +81 -0
- package/package.json +22 -19
- package/promise.d.ts +2 -2
- package/promise.js +2 -0
- package/typings/mysql/index.d.ts +12 -3
- package/typings/mysql/lib/Tracing.d.ts +71 -0
- package/typings/mysql/lib/protocol/sequences/Query.d.ts +7 -0
- package/lib/base/pool_connection.js +0 -77
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.
|
|
17
|
-
| Processed | 2026-
|
|
16
|
+
| Original | [mysql2](https://www.npmjs.com/package/mysql2) @ 3.21.0 |
|
|
17
|
+
| Processed | 2026-04-09 |
|
|
18
18
|
| Smoke test | passed |
|
|
19
19
|
| Deps updated | 0 |
|
|
20
20
|
|
package/changes.json
ADDED
|
@@ -13,7 +13,13 @@ const STATE_FINAL = -1;
|
|
|
13
13
|
|
|
14
14
|
function encrypt(password, scramble, key) {
|
|
15
15
|
const stage1 = xorRotating(Buffer.from(`${password}\0`, 'utf8'), scramble);
|
|
16
|
-
return crypto.publicEncrypt(
|
|
16
|
+
return crypto.publicEncrypt(
|
|
17
|
+
{
|
|
18
|
+
key,
|
|
19
|
+
oaepHash: 'sha1',
|
|
20
|
+
},
|
|
21
|
+
stage1
|
|
22
|
+
);
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
module.exports =
|
package/lib/base/connection.js
CHANGED
|
@@ -28,6 +28,15 @@ const Packets = require('../packets/index.js');
|
|
|
28
28
|
const Commands = require('../commands/index.js');
|
|
29
29
|
const ConnectionConfig = require('../connection_config.js');
|
|
30
30
|
const CharsetToEncoding = require('../constants/charset_encodings.js');
|
|
31
|
+
const {
|
|
32
|
+
traceCallback,
|
|
33
|
+
tracePromise,
|
|
34
|
+
getServerContext,
|
|
35
|
+
shouldTrace,
|
|
36
|
+
queryChannel,
|
|
37
|
+
executeChannel,
|
|
38
|
+
connectChannel,
|
|
39
|
+
} = require('../tracing.js');
|
|
31
40
|
|
|
32
41
|
let _connectionId = 0;
|
|
33
42
|
|
|
@@ -141,6 +150,41 @@ class BaseConnection extends EventEmitter {
|
|
|
141
150
|
this._notifyError(err);
|
|
142
151
|
});
|
|
143
152
|
this.addCommand(handshakeCommand);
|
|
153
|
+
|
|
154
|
+
// Trace the connection handshake
|
|
155
|
+
if (shouldTrace(connectChannel)) {
|
|
156
|
+
const config = this.config;
|
|
157
|
+
tracePromise(
|
|
158
|
+
connectChannel,
|
|
159
|
+
() =>
|
|
160
|
+
new Promise((resolve, reject) => {
|
|
161
|
+
/* eslint-disable prefer-const */
|
|
162
|
+
let onConnect, onError;
|
|
163
|
+
onConnect = (param) => {
|
|
164
|
+
this.removeListener('error', onError);
|
|
165
|
+
resolve(param);
|
|
166
|
+
};
|
|
167
|
+
onError = (err) => {
|
|
168
|
+
this.removeListener('connect', onConnect);
|
|
169
|
+
reject(err);
|
|
170
|
+
};
|
|
171
|
+
/* eslint-enable prefer-const */
|
|
172
|
+
this.once('connect', onConnect);
|
|
173
|
+
this.once('error', onError);
|
|
174
|
+
}),
|
|
175
|
+
() => {
|
|
176
|
+
const server = getServerContext(config);
|
|
177
|
+
return {
|
|
178
|
+
database: config.database || '',
|
|
179
|
+
serverAddress: server.serverAddress,
|
|
180
|
+
serverPort: server.serverPort,
|
|
181
|
+
user: config.user || '',
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
).catch(() => {
|
|
185
|
+
// errors are already handled by the handshake error listener
|
|
186
|
+
});
|
|
187
|
+
}
|
|
144
188
|
}
|
|
145
189
|
// in case there was no initial handshake but we need to read sting, assume it utf-8
|
|
146
190
|
// most common example: "Too many connections" error ( packet is sent immediately on connection attempt, we don't know server encoding yet)
|
|
@@ -601,7 +645,57 @@ class BaseConnection extends EventEmitter {
|
|
|
601
645
|
cmdQuery.values !== undefined ? cmdQuery.values : []
|
|
602
646
|
);
|
|
603
647
|
cmdQuery.sql = rawSql;
|
|
604
|
-
|
|
648
|
+
|
|
649
|
+
if (cmdQuery.onResult) {
|
|
650
|
+
// Callback mode: traceCallback wraps the callback with tracing lifecycle, or calls through directly when no subscribers are registered
|
|
651
|
+
traceCallback(
|
|
652
|
+
queryChannel,
|
|
653
|
+
(wrappedCb) => {
|
|
654
|
+
cmdQuery.onResult = wrappedCb;
|
|
655
|
+
this.addCommand(cmdQuery);
|
|
656
|
+
},
|
|
657
|
+
0,
|
|
658
|
+
() => {
|
|
659
|
+
const server = getServerContext(this.config);
|
|
660
|
+
return {
|
|
661
|
+
query: cmdQuery.sql,
|
|
662
|
+
values: cmdQuery.values,
|
|
663
|
+
database: this.config.database || '',
|
|
664
|
+
serverAddress: server.serverAddress,
|
|
665
|
+
serverPort: server.serverPort,
|
|
666
|
+
};
|
|
667
|
+
},
|
|
668
|
+
null,
|
|
669
|
+
cmdQuery.onResult
|
|
670
|
+
);
|
|
671
|
+
} else if (shouldTrace(queryChannel)) {
|
|
672
|
+
// Event-emitter mode: tracePromise wraps the async lifecycle
|
|
673
|
+
tracePromise(
|
|
674
|
+
queryChannel,
|
|
675
|
+
() =>
|
|
676
|
+
new Promise((resolve, reject) => {
|
|
677
|
+
cmdQuery.once('error', reject);
|
|
678
|
+
cmdQuery.once('end', () => resolve());
|
|
679
|
+
this.addCommand(cmdQuery);
|
|
680
|
+
}),
|
|
681
|
+
() => {
|
|
682
|
+
const server = getServerContext(this.config);
|
|
683
|
+
return {
|
|
684
|
+
query: cmdQuery.sql,
|
|
685
|
+
values: cmdQuery.values,
|
|
686
|
+
database: this.config.database || '',
|
|
687
|
+
serverAddress: server.serverAddress,
|
|
688
|
+
serverPort: server.serverPort,
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
).catch(() => {
|
|
692
|
+
// errors are already emitted on the command
|
|
693
|
+
});
|
|
694
|
+
} else {
|
|
695
|
+
this.addCommand(cmdQuery);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
return cmdQuery;
|
|
605
699
|
}
|
|
606
700
|
|
|
607
701
|
pause() {
|
|
@@ -702,25 +796,78 @@ class BaseConnection extends EventEmitter {
|
|
|
702
796
|
});
|
|
703
797
|
}
|
|
704
798
|
const executeCommand = new Commands.Execute(options, cb);
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
799
|
+
|
|
800
|
+
const prepareAndExecute = (errorCb) => {
|
|
801
|
+
const prepareCommand = new Commands.Prepare(options, (err, stmt) => {
|
|
802
|
+
if (err) {
|
|
803
|
+
// skip execute command if prepare failed
|
|
804
|
+
executeCommand.start = function () {
|
|
805
|
+
return null;
|
|
806
|
+
};
|
|
807
|
+
errorCb(err);
|
|
808
|
+
executeCommand.emit('end');
|
|
809
|
+
return;
|
|
716
810
|
}
|
|
717
|
-
executeCommand.
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
executeCommand
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
|
|
811
|
+
executeCommand.statement = stmt;
|
|
812
|
+
});
|
|
813
|
+
this.addCommand(prepareCommand);
|
|
814
|
+
this.addCommand(executeCommand);
|
|
815
|
+
};
|
|
816
|
+
|
|
817
|
+
if (executeCommand.onResult) {
|
|
818
|
+
// Callback mode: traceCallback wraps the callback with tracing lifecycle, or calls through directly when no subscribers are registered
|
|
819
|
+
const origExecCb = executeCommand.onResult;
|
|
820
|
+
traceCallback(
|
|
821
|
+
executeChannel,
|
|
822
|
+
(wrappedCb) => {
|
|
823
|
+
executeCommand.onResult = wrappedCb;
|
|
824
|
+
prepareAndExecute(wrappedCb);
|
|
825
|
+
},
|
|
826
|
+
0,
|
|
827
|
+
() => {
|
|
828
|
+
const server = getServerContext(this.config);
|
|
829
|
+
return {
|
|
830
|
+
query: options.sql,
|
|
831
|
+
values: options.values,
|
|
832
|
+
database: this.config.database || '',
|
|
833
|
+
serverAddress: server.serverAddress,
|
|
834
|
+
serverPort: server.serverPort,
|
|
835
|
+
};
|
|
836
|
+
},
|
|
837
|
+
null,
|
|
838
|
+
origExecCb
|
|
839
|
+
);
|
|
840
|
+
} else if (shouldTrace(executeChannel)) {
|
|
841
|
+
// Event-emitter mode: tracePromise wraps the async lifecycle
|
|
842
|
+
tracePromise(
|
|
843
|
+
executeChannel,
|
|
844
|
+
() =>
|
|
845
|
+
new Promise((resolve, reject) => {
|
|
846
|
+
prepareAndExecute((err) => {
|
|
847
|
+
executeCommand.emit('error', err);
|
|
848
|
+
});
|
|
849
|
+
executeCommand.once('error', reject);
|
|
850
|
+
executeCommand.once('end', () => resolve());
|
|
851
|
+
}),
|
|
852
|
+
() => {
|
|
853
|
+
const server = getServerContext(this.config);
|
|
854
|
+
return {
|
|
855
|
+
query: options.sql,
|
|
856
|
+
values: options.values,
|
|
857
|
+
database: this.config.database || '',
|
|
858
|
+
serverAddress: server.serverAddress,
|
|
859
|
+
serverPort: server.serverPort,
|
|
860
|
+
};
|
|
861
|
+
}
|
|
862
|
+
).catch(() => {
|
|
863
|
+
// errors are already emitted on the command
|
|
864
|
+
});
|
|
865
|
+
} else {
|
|
866
|
+
prepareAndExecute((err) => {
|
|
867
|
+
executeCommand.emit('error', err);
|
|
868
|
+
});
|
|
869
|
+
}
|
|
870
|
+
|
|
724
871
|
return executeCommand;
|
|
725
872
|
}
|
|
726
873
|
|
package/lib/base/pool.js
CHANGED
|
@@ -7,6 +7,11 @@ const PoolConnection = require('../pool_connection.js');
|
|
|
7
7
|
const Queue = require('denque');
|
|
8
8
|
const BaseConnection = require('./connection.js');
|
|
9
9
|
const Errors = require('../constants/errors.js');
|
|
10
|
+
const {
|
|
11
|
+
traceCallback,
|
|
12
|
+
getServerContext,
|
|
13
|
+
poolConnectChannel,
|
|
14
|
+
} = require('../tracing.js');
|
|
10
15
|
|
|
11
16
|
// Source: https://github.com/go-sql-driver/mysql/blob/76c00e35a8d48f8f70f0e7dffe584692bd3fa612/packets.go#L598-L613
|
|
12
17
|
function isReadOnlyError(err) {
|
|
@@ -49,46 +54,69 @@ class BasePool extends EventEmitter {
|
|
|
49
54
|
}
|
|
50
55
|
|
|
51
56
|
getConnection(cb) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return process.nextTick(() => cb(null, connection));
|
|
60
|
-
}
|
|
61
|
-
if (
|
|
62
|
-
this.config.connectionLimit === 0 ||
|
|
63
|
-
this._allConnections.length < this.config.connectionLimit
|
|
64
|
-
) {
|
|
65
|
-
connection = new PoolConnection(this, {
|
|
66
|
-
config: this.config.connectionConfig,
|
|
67
|
-
});
|
|
68
|
-
this._allConnections.push(connection);
|
|
69
|
-
return connection.connect((err) => {
|
|
70
|
-
if (this._closed) {
|
|
71
|
-
return cb(new Error('Pool is closed.'));
|
|
72
|
-
}
|
|
73
|
-
if (err) {
|
|
74
|
-
return cb(err);
|
|
75
|
-
}
|
|
76
|
-
this.emit('connection', connection);
|
|
57
|
+
const _getConnection = (cb) => {
|
|
58
|
+
if (this._closed) {
|
|
59
|
+
return process.nextTick(() => cb(new Error('Pool is closed.')));
|
|
60
|
+
}
|
|
61
|
+
let connection;
|
|
62
|
+
if (this._freeConnections.length > 0) {
|
|
63
|
+
connection = this._freeConnections.pop();
|
|
77
64
|
this.emit('acquire', connection);
|
|
78
|
-
return
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
65
|
+
return process.nextTick(() => {
|
|
66
|
+
connection._released = false;
|
|
67
|
+
cb(null, connection);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
if (
|
|
71
|
+
this.config.connectionLimit === 0 ||
|
|
72
|
+
this._allConnections.length < this.config.connectionLimit
|
|
73
|
+
) {
|
|
74
|
+
connection = new PoolConnection(this, {
|
|
75
|
+
config: this.config.connectionConfig,
|
|
76
|
+
});
|
|
77
|
+
this._allConnections.push(connection);
|
|
78
|
+
return connection.connect((err) => {
|
|
79
|
+
if (this._closed) {
|
|
80
|
+
return cb(new Error('Pool is closed.'));
|
|
81
|
+
}
|
|
82
|
+
if (err) {
|
|
83
|
+
return cb(err);
|
|
84
|
+
}
|
|
85
|
+
this.emit('connection', connection);
|
|
86
|
+
this.emit('acquire', connection);
|
|
87
|
+
return cb(null, connection);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (!this.config.waitForConnections) {
|
|
91
|
+
return process.nextTick(() =>
|
|
92
|
+
cb(new Error('No connections available.'))
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
if (
|
|
96
|
+
this.config.queueLimit &&
|
|
97
|
+
this._connectionQueue.length >= this.config.queueLimit
|
|
98
|
+
) {
|
|
99
|
+
return cb(new Error('Queue limit reached.'));
|
|
100
|
+
}
|
|
101
|
+
this.emit('enqueue');
|
|
102
|
+
return this._connectionQueue.push(cb);
|
|
103
|
+
};
|
|
104
|
+
const config = this.config.connectionConfig;
|
|
105
|
+
traceCallback(
|
|
106
|
+
poolConnectChannel,
|
|
107
|
+
_getConnection,
|
|
108
|
+
0,
|
|
109
|
+
() => {
|
|
110
|
+
const server = getServerContext(config);
|
|
111
|
+
return {
|
|
112
|
+
database: config.database || '',
|
|
113
|
+
serverAddress: server.serverAddress,
|
|
114
|
+
serverPort: server.serverPort,
|
|
115
|
+
};
|
|
116
|
+
},
|
|
117
|
+
null,
|
|
118
|
+
cb
|
|
119
|
+
);
|
|
92
120
|
}
|
|
93
121
|
|
|
94
122
|
releaseConnection(connection) {
|
|
@@ -101,7 +129,10 @@ class BasePool extends EventEmitter {
|
|
|
101
129
|
}
|
|
102
130
|
} else if (this._connectionQueue.length) {
|
|
103
131
|
cb = this._connectionQueue.shift();
|
|
104
|
-
process.nextTick(
|
|
132
|
+
process.nextTick(() => {
|
|
133
|
+
connection._released = false;
|
|
134
|
+
cb(null, connection);
|
|
135
|
+
});
|
|
105
136
|
} else {
|
|
106
137
|
this._freeConnections.push(connection);
|
|
107
138
|
this.emit('release', connection);
|
package/lib/commands/execute.js
CHANGED
|
@@ -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
|
package/lib/commands/query.js
CHANGED
|
@@ -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;
|
package/lib/connection_config.js
CHANGED
package/lib/constants/client.js
CHANGED
|
@@ -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;
|
package/lib/constants/cursor.js
CHANGED
|
@@ -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 };
|