@tachybase/module-multi-app 1.6.0 → 1.6.2

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 (105) hide show
  1. package/README.md +34 -34
  2. package/README.zh-CN.md +34 -34
  3. package/client.d.ts +1 -1
  4. package/client.js +1 -1
  5. package/dist/externalVersion.js +5 -5
  6. package/dist/locale/en-US.json +48 -48
  7. package/dist/locale/es-ES.json +9 -9
  8. package/dist/locale/ko_KR.json +11 -11
  9. package/dist/locale/pt-BR.json +9 -9
  10. package/dist/locale/zh-CN.json +58 -58
  11. package/dist/node_modules/mariadb/callback.js +43 -8
  12. package/dist/node_modules/mariadb/check-node.js +30 -0
  13. package/dist/node_modules/mariadb/lib/cluster-callback.js +84 -0
  14. package/dist/node_modules/mariadb/lib/cluster.js +446 -0
  15. package/dist/node_modules/mariadb/lib/cmd/batch-bulk.js +576 -177
  16. package/dist/node_modules/mariadb/lib/cmd/change-user.js +54 -44
  17. package/dist/node_modules/mariadb/lib/cmd/class/ok-packet.js +3 -2
  18. package/dist/node_modules/mariadb/lib/cmd/class/prepare-cache-wrapper.js +46 -0
  19. package/dist/node_modules/mariadb/lib/cmd/class/prepare-result-packet.js +141 -0
  20. package/dist/node_modules/mariadb/lib/cmd/class/prepare-wrapper.js +70 -0
  21. package/dist/node_modules/mariadb/lib/cmd/close-prepare.js +38 -0
  22. package/dist/node_modules/mariadb/lib/cmd/column-definition.js +145 -47
  23. package/dist/node_modules/mariadb/lib/cmd/command.js +41 -75
  24. package/dist/node_modules/mariadb/lib/cmd/decoder/binary-decoder.js +282 -0
  25. package/dist/node_modules/mariadb/lib/cmd/decoder/text-decoder.js +210 -0
  26. package/dist/node_modules/mariadb/lib/cmd/{common-binary-cmd.js → encoder/binary-encoder.js} +34 -77
  27. package/dist/node_modules/mariadb/lib/cmd/encoder/text-encoder.js +311 -0
  28. package/dist/node_modules/mariadb/lib/cmd/execute-stream.js +61 -0
  29. package/dist/node_modules/mariadb/lib/cmd/execute.js +338 -0
  30. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/caching-sha2-password-auth.js +25 -62
  31. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/clear-password-auth.js +39 -6
  32. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/ed25519-password-auth.js +48 -16
  33. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/handshake.js +198 -0
  34. package/dist/node_modules/mariadb/lib/cmd/handshake/{initial-handshake.js → auth/initial-handshake.js} +10 -8
  35. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/native-password-auth.js +22 -9
  36. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/pam-password-auth.js +9 -4
  37. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/parsec-auth.js +115 -0
  38. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/plugin-auth.js +12 -5
  39. package/dist/node_modules/mariadb/lib/cmd/handshake/auth/sha256-password-auth.js +44 -33
  40. package/dist/node_modules/mariadb/lib/cmd/handshake/authentication.js +335 -0
  41. package/dist/node_modules/mariadb/lib/cmd/handshake/client-capabilities.js +20 -19
  42. package/dist/node_modules/mariadb/lib/cmd/handshake/ssl-request.js +6 -3
  43. package/dist/node_modules/mariadb/lib/cmd/parser.js +861 -0
  44. package/dist/node_modules/mariadb/lib/cmd/ping.js +17 -18
  45. package/dist/node_modules/mariadb/lib/cmd/prepare.js +170 -0
  46. package/dist/node_modules/mariadb/lib/cmd/query.js +281 -144
  47. package/dist/node_modules/mariadb/lib/cmd/quit.js +9 -6
  48. package/dist/node_modules/mariadb/lib/cmd/reset.js +15 -19
  49. package/dist/node_modules/mariadb/lib/cmd/stream.js +21 -6
  50. package/dist/node_modules/mariadb/lib/config/cluster-options.js +23 -0
  51. package/dist/node_modules/mariadb/lib/config/connection-options.js +196 -132
  52. package/dist/node_modules/mariadb/lib/config/pool-options.js +27 -19
  53. package/dist/node_modules/mariadb/lib/connection-callback.js +492 -120
  54. package/dist/node_modules/mariadb/lib/connection-promise.js +372 -0
  55. package/dist/node_modules/mariadb/lib/connection.js +1739 -1016
  56. package/dist/node_modules/mariadb/lib/const/capabilities.js +36 -30
  57. package/dist/node_modules/mariadb/lib/const/collations.js +972 -36
  58. package/dist/node_modules/mariadb/lib/const/connection_status.js +3 -0
  59. package/dist/node_modules/mariadb/lib/const/error-code.js +35 -11
  60. package/dist/node_modules/mariadb/lib/const/field-detail.js +3 -0
  61. package/dist/node_modules/mariadb/lib/const/field-type.js +7 -4
  62. package/dist/node_modules/mariadb/lib/const/server-status.js +4 -1
  63. package/dist/node_modules/mariadb/lib/const/state-change.js +3 -0
  64. package/dist/node_modules/mariadb/lib/filtered-cluster-callback.js +136 -0
  65. package/dist/node_modules/mariadb/lib/filtered-cluster.js +118 -0
  66. package/dist/node_modules/mariadb/lib/io/compression-input-stream.js +14 -13
  67. package/dist/node_modules/mariadb/lib/io/compression-output-stream.js +21 -18
  68. package/dist/node_modules/mariadb/lib/io/packet-input-stream.js +75 -64
  69. package/dist/node_modules/mariadb/lib/io/packet-node-encoded.js +13 -9
  70. package/dist/node_modules/mariadb/lib/io/packet-node-iconv.js +12 -10
  71. package/dist/node_modules/mariadb/lib/io/packet-output-stream.js +402 -134
  72. package/dist/node_modules/mariadb/lib/io/packet.js +287 -202
  73. package/dist/node_modules/mariadb/lib/lru-prepare-cache.js +84 -0
  74. package/dist/node_modules/mariadb/lib/misc/connection-information.js +15 -32
  75. package/dist/node_modules/mariadb/lib/misc/errors.js +68 -25
  76. package/dist/node_modules/mariadb/lib/misc/parse.js +207 -711
  77. package/dist/node_modules/mariadb/lib/misc/utils.js +34 -62
  78. package/dist/node_modules/mariadb/lib/pool-callback.js +213 -174
  79. package/dist/node_modules/mariadb/lib/pool-promise.js +228 -94
  80. package/dist/node_modules/mariadb/lib/pool.js +951 -0
  81. package/dist/node_modules/mariadb/package.json +1 -1
  82. package/dist/node_modules/mariadb/promise.js +1 -34
  83. package/dist/node_modules/mariadb/types/callback.d.ts +207 -0
  84. package/dist/node_modules/mariadb/types/index.d.ts +94 -674
  85. package/dist/node_modules/mariadb/types/share.d.ts +804 -0
  86. package/dist/node_modules/qs/package.json +1 -1
  87. package/dist/server/actions/apps.js +2 -2
  88. package/dist/server/app-lifecycle.d.ts +1 -1
  89. package/dist/server/app-lifecycle.js +4 -4
  90. package/dist/server/models/application.d.ts +1 -1
  91. package/package.json +7 -7
  92. package/server.d.ts +2 -2
  93. package/server.js +1 -1
  94. package/dist/node_modules/mariadb/lib/cmd/batch-rewrite.js +0 -372
  95. package/dist/node_modules/mariadb/lib/cmd/common-text-cmd.js +0 -427
  96. package/dist/node_modules/mariadb/lib/cmd/handshake/client-handshake-response.js +0 -126
  97. package/dist/node_modules/mariadb/lib/cmd/handshake/handshake.js +0 -292
  98. package/dist/node_modules/mariadb/lib/cmd/resultset.js +0 -607
  99. package/dist/node_modules/mariadb/lib/config/pool-cluster-options.js +0 -19
  100. package/dist/node_modules/mariadb/lib/filtered-pool-cluster.js +0 -81
  101. package/dist/node_modules/mariadb/lib/io/bulk-packet.js +0 -590
  102. package/dist/node_modules/mariadb/lib/io/rewrite-packet.js +0 -481
  103. package/dist/node_modules/mariadb/lib/pool-base.js +0 -611
  104. package/dist/node_modules/mariadb/lib/pool-cluster-callback.js +0 -66
  105. package/dist/node_modules/mariadb/lib/pool-cluster.js +0 -407
@@ -0,0 +1,23 @@
1
+ // SPDX-License-Identifier: LGPL-2.1-or-later
2
+ // Copyright (c) 2015-2024 MariaDB Corporation Ab
3
+
4
+ 'use strict';
5
+
6
+ class ClusterOptions {
7
+ constructor(opts) {
8
+ if (opts) {
9
+ this.canRetry = opts.canRetry === undefined ? true : Boolean(opts.canRetry);
10
+ this.removeNodeErrorCount =
11
+ opts.removeNodeErrorCount === undefined ? Number.POSITIVE_INFINITY : Number(opts.removeNodeErrorCount);
12
+ this.restoreNodeTimeout = opts.restoreNodeTimeout === undefined ? 1000 : Number(opts.restoreNodeTimeout);
13
+ this.defaultSelector = opts.defaultSelector || 'RR';
14
+ } else {
15
+ this.canRetry = true;
16
+ this.removeNodeErrorCount = Number.POSITIVE_INFINITY;
17
+ this.restoreNodeTimeout = 1000;
18
+ this.defaultSelector = 'RR';
19
+ }
20
+ }
21
+ }
22
+
23
+ module.exports = ClusterOptions;
@@ -1,9 +1,10 @@
1
+ // SPDX-License-Identifier: LGPL-2.1-or-later
2
+ // Copyright (c) 2015-2025 MariaDB Corporation Ab
3
+
1
4
  'use strict';
2
5
 
3
6
  const Collations = require('../const/collations.js');
4
7
  const urlFormat = /mariadb:\/\/(([^/@:]+)?(:([^/]+))?@)?(([^/:]+)(:([0-9]+))?)\/([^?]+)(\?(.*))?$/;
5
- const moment = require('moment-timezone');
6
- const Errors = require('../misc/errors');
7
8
 
8
9
  /**
9
10
  * Default option similar to mysql driver.
@@ -24,199 +25,264 @@ class ConnectionOptions {
24
25
 
25
26
  if (!opts) opts = {};
26
27
  this.host = opts.host || 'localhost';
27
- this.port = opts.port || 3306;
28
+ this.port = opts.port ? Number(opts.port) : 3306;
29
+ this.keepEof = Boolean(opts.keepEof) || false;
28
30
  this.user = opts.user || process.env.USERNAME;
29
31
  this.password = opts.password;
30
32
  this.database = opts.database;
33
+ this.stream = opts.stream;
34
+ this.fullResult = opts.fullResult;
35
+
36
+ // log
37
+ this.debug = Boolean(opts.debug) || false;
38
+ this.debugCompress = Boolean(opts.debugCompress) || false;
39
+ this.debugLen = opts.debugLen ? Number(opts.debugLen) : 256;
40
+ this.logParam = opts.logParam === undefined ? true : Boolean(opts.logParam);
41
+ if (opts.logger) {
42
+ if (typeof opts.logger === 'function') {
43
+ this.logger = {
44
+ network: opts.logger,
45
+ query: opts.logger,
46
+ error: opts.logger,
47
+ warning: opts.logger
48
+ };
49
+ } else {
50
+ this.logger = {
51
+ network: opts.logger.network,
52
+ query: opts.logger.query,
53
+ error: opts.logger.error,
54
+ warning: opts.logger.warning || console.log
55
+ };
56
+ if (opts.logger.logParam !== undefined) this.logParam = Boolean(opts.logger.logParam);
57
+ }
58
+ } else {
59
+ this.logger = {
60
+ network: this.debug || this.debugCompress ? console.log : null,
61
+ query: null,
62
+ error: null,
63
+ warning: console.log
64
+ };
65
+ }
66
+ this.debug = !!this.logger.network;
67
+
31
68
  if (opts.charset && typeof opts.charset === 'string') {
32
69
  this.collation = Collations.fromCharset(opts.charset.toLowerCase());
33
70
  if (this.collation === undefined) {
34
71
  this.collation = Collations.fromName(opts.charset.toUpperCase());
35
72
  if (this.collation !== undefined) {
36
- console.log(
73
+ this.logger.warning(
37
74
  "warning: please use option 'collation' " +
38
75
  "in replacement of 'charset' when using a collation name ('" +
39
76
  opts.charset +
40
77
  "')\n" +
41
78
  "(collation looks like 'UTF8MB4_UNICODE_CI', charset like 'utf8')."
42
79
  );
80
+ } else {
81
+ this.charset = opts.charset;
43
82
  }
44
83
  }
45
- if (this.collation === undefined)
46
- throw new RangeError("Unknown charset '" + opts.charset + "'");
47
84
  } else if (opts.collation && typeof opts.collation === 'string') {
48
85
  this.collation = Collations.fromName(opts.collation.toUpperCase());
49
- if (this.collation === undefined)
50
- throw new RangeError("Unknown collation '" + opts.collation + "'");
86
+ if (this.collation === undefined) throw new RangeError("Unknown collation '" + opts.collation + "'");
51
87
  } else {
52
- this.collation = Collations.fromIndex(opts.charsetNumber) || Collations.fromIndex(224); //UTF8MB4_UNICODE_CI;
88
+ this.collation = opts.charsetNumber ? Collations.fromIndex(Number(opts.charsetNumber)) : undefined;
53
89
  }
54
90
 
55
91
  // connection options
56
92
  this.initSql = opts.initSql;
57
- this.connectTimeout = opts.connectTimeout === undefined ? 1000 : opts.connectTimeout;
93
+ this.connectTimeout = opts.connectTimeout === undefined ? 1000 : Number(opts.connectTimeout);
58
94
  this.connectAttributes = opts.connectAttributes || false;
59
- this.compress = opts.compress || false;
95
+ this.compress = Boolean(opts.compress) || false;
60
96
  this.rsaPublicKey = opts.rsaPublicKey;
61
97
  this.cachingRsaPublicKey = opts.cachingRsaPublicKey;
62
- this.allowPublicKeyRetrieval = opts.allowPublicKeyRetrieval || false;
63
- this.forceVersionCheck = opts.forceVersionCheck || false;
64
- this.maxAllowedPacket = opts.maxAllowedPacket;
65
- this.permitConnectionWhenExpired = opts.permitConnectionWhenExpired || false;
98
+ this.allowPublicKeyRetrieval = Boolean(opts.allowPublicKeyRetrieval) || false;
99
+ this.forceVersionCheck = Boolean(opts.forceVersionCheck) || false;
100
+ this.maxAllowedPacket = opts.maxAllowedPacket ? Number(opts.maxAllowedPacket) : undefined;
101
+ this.permitConnectionWhenExpired = Boolean(opts.permitConnectionWhenExpired) || false;
66
102
  this.pipelining = opts.pipelining;
67
103
  this.timezone = opts.timezone || 'local';
68
104
  this.socketPath = opts.socketPath;
69
105
  this.sessionVariables = opts.sessionVariables;
106
+ this.infileStreamFactory = opts.infileStreamFactory;
70
107
  this.ssl = opts.ssl;
71
108
  if (opts.ssl) {
72
109
  if (typeof opts.ssl !== 'boolean' && typeof opts.ssl !== 'string') {
73
110
  this.ssl.rejectUnauthorized = opts.ssl.rejectUnauthorized !== false;
74
111
  }
75
112
  }
113
+ this.permitRedirect =
114
+ opts.permitRedirect === undefined
115
+ ? !!this.ssl && this.ssl.rejectUnauthorized !== false
116
+ : Boolean(opts.permitRedirect);
76
117
 
77
118
  // socket
78
- this.queryTimeout = opts.queryTimeout === undefined ? 0 : opts.queryTimeout;
79
- this.socketTimeout = opts.socketTimeout === undefined ? 0 : opts.socketTimeout;
80
- this.keepAliveDelay = opts.keepAliveDelay === undefined ? 0 : opts.keepAliveDelay;
81
-
82
- // log
83
- this.debug = opts.debug || false;
84
- this.debugCompress = opts.debugCompress || false;
85
- this.debugLen = opts.debugLen || 256;
86
- this.logPackets = opts.logPackets || false;
87
- this.trace = opts.trace || false;
119
+ this.queryTimeout = isNaN(opts.queryTimeout) || Number(opts.queryTimeout) < 0 ? 0 : Number(opts.queryTimeout);
120
+ this.socketTimeout = isNaN(opts.socketTimeout) || Number(opts.socketTimeout) < 0 ? 0 : Number(opts.socketTimeout);
121
+ this.keepAliveDelay = opts.keepAliveDelay === undefined ? 0 : Number(opts.keepAliveDelay);
122
+ if (!opts.keepAliveDelay) {
123
+ // for mysql2 compatibility, check keepAliveInitialDelay/enableKeepAlive options.
124
+ if (opts.enableKeepAlive === true && opts.keepAliveInitialDelay !== undefined) {
125
+ this.keepAliveDelay = Number(opts.keepAliveInitialDelay);
126
+ }
127
+ }
128
+ this.trace = Boolean(opts.trace) || false;
88
129
 
89
130
  // result-set
90
- this.checkDuplicate = opts.checkDuplicate === undefined ? true : opts.checkDuplicate;
91
- this.dateStrings = opts.dateStrings || false;
92
- this.foundRows = opts.foundRows === undefined || opts.foundRows;
93
- this.metaAsArray = opts.metaAsArray || false;
94
- this.multipleStatements = opts.multipleStatements || false;
95
- this.namedPlaceholders = opts.namedPlaceholders || false;
131
+ this.checkDuplicate = opts.checkDuplicate === undefined ? true : Boolean(opts.checkDuplicate);
132
+ this.dateStrings = Boolean(opts.dateStrings) || false;
133
+ this.foundRows = opts.foundRows === undefined || Boolean(opts.foundRows);
134
+ this.metaAsArray = Boolean(opts.metaAsArray) || false;
135
+ this.metaEnumerable = Boolean(opts.metaEnumerable) || false;
136
+ this.multipleStatements = Boolean(opts.multipleStatements) || false;
137
+ this.namedPlaceholders = Boolean(opts.namedPlaceholders) || false;
96
138
  this.nestTables = opts.nestTables;
97
- this.autoJsonMap = opts.autoJsonMap === undefined ? true : opts.autoJsonMap;
98
- this.arrayParenthesis = opts.arrayParenthesis || false;
99
- this.permitSetMultiParamEntries = opts.permitSetMultiParamEntries || false;
100
- this.rowsAsArray = opts.rowsAsArray || false;
101
- this.supportBigNumbers = opts.supportBigNumbers || false;
102
- this.supportBigInt = opts.supportBigInt || false;
103
- this.skipSetTimezone = opts.skipSetTimezone || false;
139
+ this.autoJsonMap = opts.autoJsonMap === undefined ? true : Boolean(opts.autoJsonMap);
140
+ this.jsonStrings = Boolean(opts.jsonStrings) || false;
141
+ if (opts.jsonStrings !== undefined) {
142
+ this.autoJsonMap = !this.jsonStrings;
143
+ }
144
+ this.bitOneIsBoolean = opts.bitOneIsBoolean === undefined ? true : Boolean(opts.bitOneIsBoolean);
145
+ this.arrayParenthesis = Boolean(opts.arrayParenthesis) || false;
146
+ this.permitSetMultiParamEntries = Boolean(opts.permitSetMultiParamEntries) || false;
147
+ this.rowsAsArray = Boolean(opts.rowsAsArray) || false;
104
148
  this.typeCast = opts.typeCast;
105
149
  if (this.typeCast !== undefined && typeof this.typeCast !== 'function') {
106
150
  this.typeCast = undefined;
107
151
  }
108
- this.bigNumberStrings = opts.bigNumberStrings || false;
109
- this.bulk = opts.bulk === undefined || opts.bulk;
152
+ this.bulk = opts.bulk === undefined || Boolean(opts.bulk);
153
+ this.checkNumberRange = Boolean(opts.checkNumberRange) || false;
110
154
 
111
155
  // coherence check
112
156
  if (opts.pipelining === undefined) {
113
- this.permitLocalInfile = opts.permitLocalInfile || false;
157
+ this.permitLocalInfile = Boolean(opts.permitLocalInfile) || false;
114
158
  this.pipelining = !this.permitLocalInfile;
115
159
  } else {
116
- this.pipelining = opts.pipelining;
160
+ this.pipelining = Boolean(opts.pipelining);
117
161
  if (opts.permitLocalInfile === true && this.pipelining) {
118
162
  throw new Error(
119
163
  'enabling options `permitLocalInfile` and `pipelining` is not possible, options are incompatible.'
120
164
  );
121
165
  }
122
- this.permitLocalInfile = this.pipelining ? false : opts.permitLocalInfile || false;
123
- }
124
- if (this.maxAllowedPacket && !Number.isInteger(this.maxAllowedPacket)) {
125
- throw new RangeError(
126
- "maxAllowedPacket must be an integer. was '" + this.maxAllowedPacket + "'"
127
- );
166
+ this.permitLocalInfile = this.pipelining ? false : Boolean(opts.permitLocalInfile) || false;
128
167
  }
129
- if (this.timezone && this.timezone !== 'local' && this.timezone !== 'auto') {
130
- let tzName = this.timezone;
131
- if (this.timezone === 'Z') {
132
- tzName = 'Etc/UTC';
133
- } else {
134
- const matched = this.timezone.match(/([+\-\s])(\d\d):?(\d\d)?/);
135
- if (matched) {
136
- const hour = (matched[1] === '-' ? 1 : -1) * Number.parseInt(matched[2], 10);
137
- const minutes = matched.length > 2 && matched[3] ? Number.parseInt(matched[3], 10) : 0;
138
- if (minutes > 0) {
139
- throw new RangeError(
140
- "timezone format incompatible with IANA standard timezone format was '" +
141
- this.timezone +
142
- "'"
143
- );
144
- }
145
- if (hour == 0) {
146
- tzName = 'Etc/UTC';
147
- } else {
148
- tzName = 'Etc/GMT' + (matched[1] === '-' ? '+' : '') + hour;
149
- }
150
- }
151
- }
152
- this._localTz = moment.tz.guess();
153
- if (tzName === this._localTz) {
154
- this.tz = null;
155
- } else {
156
- this.tz = tzName;
157
- if (!moment.tz.zone(tzName)) {
158
- throw Errors.createError(
159
- "Unknown IANA timezone '" + tzName + "'.",
160
- null,
161
- true,
162
- null,
163
- '08S01',
164
- Errors.ER_WRONG_IANA_TIMEZONE
165
- );
166
- }
168
+ this.prepareCacheLength = opts.prepareCacheLength === undefined ? 256 : Number(opts.prepareCacheLength);
169
+ this.restrictedAuth = opts.restrictedAuth;
170
+ if (this.restrictedAuth != null) {
171
+ if (!Array.isArray(this.restrictedAuth)) {
172
+ this.restrictedAuth = this.restrictedAuth.split(',');
167
173
  }
168
174
  }
175
+
176
+ // for compatibility with 2.x version and mysql/mysql2
177
+ this.bigIntAsNumber = Boolean(opts.bigIntAsNumber) || false;
178
+ this.insertIdAsNumber = Boolean(opts.insertIdAsNumber) || false;
179
+ this.decimalAsNumber = Boolean(opts.decimalAsNumber) || false;
180
+ this.supportBigNumbers = Boolean(opts.supportBigNumbers) || false;
181
+ this.bigNumberStrings = Boolean(opts.bigNumberStrings) || false;
182
+
183
+ if (opts.maxAllowedPacket && isNaN(this.maxAllowedPacket)) {
184
+ throw new RangeError(`maxAllowedPacket must be an integer. was '${opts.maxAllowedPacket}'`);
185
+ }
169
186
  }
170
187
 
171
188
  /**
172
189
  * When parsing from String, correcting type.
173
190
  *
174
- * @param opts options
175
- * @return {opts}
191
+ * @param {object} opts - options
192
+ * @return {object} options with corrected data types
176
193
  */
177
194
  static parseOptionDataType(opts) {
178
- if (opts.bigNumberStrings) opts.bigNumberStrings = opts.bigNumberStrings == 'true';
179
- if (opts.bulk) opts.bulk = opts.bulk == 'true';
180
- if (opts.rsaPublicKey) opts.rsaPublicKey = opts.rsaPublicKey;
181
- if (opts.cachingRsaPublicKey) opts.cachingRsaPublicKey = opts.cachingRsaPublicKey;
182
- if (opts.logPackets) opts.logPackets = opts.logPackets == 'true';
183
- if (opts.allowPublicKeyRetrieval)
184
- opts.allowPublicKeyRetrieval = opts.allowPublicKeyRetrieval == 'true';
195
+ // Convert boolean strings to boolean values
196
+ const booleanOptions = [
197
+ 'bulk',
198
+ 'allowPublicKeyRetrieval',
199
+ 'insertIdAsNumber',
200
+ 'decimalAsNumber',
201
+ 'bigIntAsNumber',
202
+ 'permitRedirect',
203
+ 'logParam',
204
+ 'compress',
205
+ 'dateStrings',
206
+ 'debug',
207
+ 'autoJsonMap',
208
+ 'arrayParenthesis',
209
+ 'checkDuplicate',
210
+ 'debugCompress',
211
+ 'foundRows',
212
+ 'metaAsArray',
213
+ 'metaEnumerable',
214
+ 'multipleStatements',
215
+ 'namedPlaceholders',
216
+ 'nestTables',
217
+ 'permitSetMultiParamEntries',
218
+ 'pipelining',
219
+ 'forceVersionCheck',
220
+ 'rowsAsArray',
221
+ 'trace',
222
+ 'bitOneIsBoolean',
223
+ 'jsonStrings',
224
+ 'enableKeepAlive',
225
+ 'supportBigNumbers',
226
+ 'bigNumberStrings',
227
+ 'keepEof',
228
+ 'permitLocalInfile',
229
+ 'permitConnectionWhenExpired'
230
+ ];
231
+
232
+ booleanOptions.forEach((option) => {
233
+ if (opts[option] !== undefined && typeof opts[option] === 'string') {
234
+ opts[option] = opts[option] === 'true';
235
+ }
236
+ });
237
+
238
+ // Convert numeric strings to numbers
239
+ const numericOptions = [
240
+ 'charsetNumber',
241
+ 'connectTimeout',
242
+ 'keepAliveDelay',
243
+ 'socketTimeout',
244
+ 'debugLen',
245
+ 'prepareCacheLength',
246
+ 'queryTimeout',
247
+ 'maxAllowedPacket',
248
+ 'keepAliveInitialDelay',
249
+ 'port'
250
+ ];
251
+
252
+ numericOptions.forEach((option) => {
253
+ if (opts[option] !== undefined && typeof opts[option] === 'string') {
254
+ const parsedValue = parseInt(opts[option], 10);
255
+ if (!isNaN(parsedValue)) {
256
+ opts[option] = parsedValue;
257
+ }
258
+ }
259
+ });
185
260
 
186
- if (opts.charsetNumber && !isNaN(Number.parseInt(opts.charsetNumber))) {
187
- opts.charsetNumber = Number.parseInt(opts.charsetNumber);
261
+ // Handle special case for SSL
262
+ if (opts.ssl !== undefined && typeof opts.ssl === 'string') {
263
+ opts.ssl = opts.ssl === 'true';
264
+ }
265
+
266
+ // Handle special case for connectAttributes (JSON parsing)
267
+ if (opts.connectAttributes !== undefined && typeof opts.connectAttributes === 'string') {
268
+ try {
269
+ opts.connectAttributes = JSON.parse(opts.connectAttributes);
270
+ } catch (e) {
271
+ throw new Error(`Failed to parse connectAttributes as JSON: ${e.message}`);
272
+ }
273
+ }
274
+
275
+ // Handle special case for sessionVariables (JSON parsing if it's a string and looks like JSON)
276
+ if (opts.sessionVariables !== undefined && typeof opts.sessionVariables === 'string') {
277
+ if (opts.sessionVariables.trim().startsWith('{')) {
278
+ try {
279
+ opts.sessionVariables = JSON.parse(opts.sessionVariables);
280
+ } catch (e) {
281
+ // If it fails to parse, keep it as a string
282
+ }
283
+ }
188
284
  }
189
- if (opts.compress) opts.compress = opts.compress == 'true';
190
- if (opts.connectAttributes) opts.connectAttributes = JSON.parse(opts.connectAttributes);
191
- if (opts.connectTimeout) opts.connectTimeout = parseInt(opts.connectTimeout);
192
- if (opts.keepAliveDelay) opts.keepAliveDelay = parseInt(opts.keepAliveDelay);
193
- if (opts.socketTimeout) opts.socketTimeout = parseInt(opts.socketTimeout);
194
- if (opts.dateStrings) opts.dateStrings = opts.dateStrings == 'true';
195
- if (opts.debug) opts.debug = opts.debug == 'true';
196
- if (opts.autoJsonMap) opts.autoJsonMap = opts.autoJsonMap == 'true';
197
- if (opts.arrayParenthesis) opts.arrayParenthesis = opts.arrayParenthesis == 'true';
198
- if (opts.skipSetTimezone) opts.skipSetTimezone = opts.skipSetTimezone == 'true';
199
285
 
200
- if (opts.checkDuplicate) opts.checkDuplicate = opts.checkDuplicate == 'true';
201
- if (opts.debugCompress) opts.debugCompress = opts.debugCompress == 'true';
202
- if (opts.debugLen) opts.debugLen = parseInt(opts.debugLen);
203
- if (opts.queryTimeout) opts.queryTimeout = parseInt(opts.queryTimeout);
204
- if (opts.foundRows) opts.foundRows = opts.foundRows == 'true';
205
- if (opts.maxAllowedPacket && !isNaN(Number.parseInt(opts.maxAllowedPacket)))
206
- opts.maxAllowedPacket = parseInt(opts.maxAllowedPacket);
207
- if (opts.metaAsArray) opts.metaAsArray = opts.metaAsArray == 'true';
208
- if (opts.multipleStatements) opts.multipleStatements = opts.multipleStatements == 'true';
209
- if (opts.namedPlaceholders) opts.namedPlaceholders = opts.namedPlaceholders == 'true';
210
- if (opts.nestTables) opts.nestTables = opts.nestTables == 'true';
211
- if (opts.permitSetMultiParamEntries)
212
- opts.permitSetMultiParamEntries = opts.permitSetMultiParamEntries == 'true';
213
- if (opts.pipelining) opts.pipelining = opts.pipelining == 'true';
214
- if (opts.forceVersionCheck) opts.forceVersionCheck = opts.forceVersionCheck == 'true';
215
- if (opts.rowsAsArray) opts.rowsAsArray = opts.rowsAsArray == 'true';
216
- if (opts.supportBigNumbers) opts.supportBigNumbers = opts.supportBigNumbers == 'true';
217
- if (opts.supportBigInt) opts.supportBigInt = opts.supportBigInt == 'true';
218
- if (opts.trace) opts.trace = opts.trace == 'true';
219
- if (opts.ssl && (opts.ssl == 'true' || opts.ssl == 'false')) opts.ssl = opts.ssl == 'true';
220
286
  return opts;
221
287
  }
222
288
 
@@ -225,9 +291,7 @@ class ConnectionOptions {
225
291
 
226
292
  if (!matchResults) {
227
293
  throw new Error(
228
- "error parsing connection string '" +
229
- opts +
230
- "'. format must be 'mariadb://[<user>[:<password>]@]<host>[:<port>]/[<db>[?<opt1>=<value1>[&<opt2>=<value2>]]]'"
294
+ `error parsing connection string '${opts}'. format must be 'mariadb://[<user>[:<password>]@]<host>[:<port>]/[<db>[?<opt1>=<value1>[&<opt2>=<value2>]]]'`
231
295
  );
232
296
  }
233
297
  const options = {
@@ -240,8 +304,8 @@ class ConnectionOptions {
240
304
 
241
305
  const variousOptsString = matchResults[11];
242
306
  if (variousOptsString) {
243
- const keyVals = variousOptsString.split('&');
244
- keyVals.forEach(function (keyVal) {
307
+ const keyValues = variousOptsString.split('&');
308
+ keyValues.forEach(function (keyVal) {
245
309
  const equalIdx = keyVal.indexOf('=');
246
310
  if (equalIdx !== 1) {
247
311
  let val = keyVal.substring(equalIdx + 1);
@@ -1,3 +1,6 @@
1
+ // SPDX-License-Identifier: LGPL-2.1-or-later
2
+ // Copyright (c) 2015-2024 MariaDB Corporation Ab
3
+
1
4
  'use strict';
2
5
 
3
6
  let ConnOptions = require('./connection-options');
@@ -7,37 +10,42 @@ class PoolOptions {
7
10
  if (typeof opts === 'string') {
8
11
  opts = ConnOptions.parse(opts);
9
12
 
10
- //set data type
13
+ // Set data type
14
+ // These conversions will be replaced with explicit type casting in the main assignment below
11
15
  if (opts.acquireTimeout) opts.acquireTimeout = parseInt(opts.acquireTimeout);
12
16
  if (opts.connectionLimit) opts.connectionLimit = parseInt(opts.connectionLimit);
13
17
  if (opts.idleTimeout) opts.idleTimeout = parseInt(opts.idleTimeout);
14
- if (opts.leakDetectionTimeout)
15
- opts.leakDetectionTimeout = parseInt(opts.leakDetectionTimeout);
16
- if (opts.initializationTimeout)
17
- opts.initializationTimeout = parseInt(opts.initializationTimeout);
18
+ if (opts.leakDetectionTimeout) opts.leakDetectionTimeout = parseInt(opts.leakDetectionTimeout);
19
+ if (opts.initializationTimeout) opts.initializationTimeout = parseInt(opts.initializationTimeout);
18
20
  if (opts.minDelayValidation) opts.minDelayValidation = parseInt(opts.minDelayValidation);
19
21
  if (opts.minimumIdle) opts.minimumIdle = parseInt(opts.minimumIdle);
20
- if (opts.noControlAfterUse) opts.noControlAfterUse = opts.noControlAfterUse == 'true';
21
- if (opts.resetAfterUse) opts.resetAfterUse = opts.resetAfterUse == 'true';
22
+ if (opts.noControlAfterUse) opts.noControlAfterUse = opts.noControlAfterUse === 'true';
23
+ if (opts.resetAfterUse) opts.resetAfterUse = opts.resetAfterUse === 'true';
22
24
  if (opts.pingTimeout) opts.pingTimeout = parseInt(opts.pingTimeout);
23
25
  }
24
26
 
25
- this.acquireTimeout = opts.acquireTimeout === undefined ? 10000 : opts.acquireTimeout;
26
- this.connectionLimit = opts.connectionLimit === undefined ? 10 : opts.connectionLimit;
27
- this.idleTimeout = opts.idleTimeout || 1800;
28
- this.leakDetectionTimeout = opts.leakDetectionTimeout || 0;
27
+ // Apply explicit type conversion for all numeric options
28
+ this.acquireTimeout = opts.acquireTimeout === undefined ? 10000 : Number(opts.acquireTimeout);
29
+ this.connectionLimit = opts.connectionLimit === undefined ? 10 : Number(opts.connectionLimit);
30
+ this.idleTimeout = opts.idleTimeout === undefined ? 1800 : Number(opts.idleTimeout);
31
+ this.leakDetectionTimeout = Number(opts.leakDetectionTimeout) || 0;
29
32
  this.initializationTimeout =
30
- opts.initializationTimeout === undefined ? 30000 : opts.initializationTimeout;
31
- this.minDelayValidation = opts.minDelayValidation === undefined ? 500 : opts.minDelayValidation;
33
+ opts.initializationTimeout === undefined
34
+ ? Math.max(100, this.acquireTimeout - 100)
35
+ : Number(opts.initializationTimeout);
36
+ this.minDelayValidation = opts.minDelayValidation === undefined ? 500 : Number(opts.minDelayValidation);
32
37
  this.minimumIdle =
33
- opts.minimumIdle === undefined
34
- ? this.connectionLimit
35
- : Math.min(opts.minimumIdle, this.connectionLimit);
36
- this.noControlAfterUse = opts.noControlAfterUse || false;
37
- this.resetAfterUse = opts.resetAfterUse === undefined ? true : opts.resetAfterUse;
38
- this.pingTimeout = opts.pingTimeout || 250;
38
+ opts.minimumIdle === undefined ? this.connectionLimit : Math.min(Number(opts.minimumIdle), this.connectionLimit);
39
+
40
+ // Apply explicit type conversion for boolean options
41
+ this.noControlAfterUse = Boolean(opts.noControlAfterUse) || false;
42
+ this.resetAfterUse = Boolean(opts.resetAfterUse) || false;
43
+ this.pingTimeout = Number(opts.pingTimeout) || 250;
44
+
45
+ // Create connection options
39
46
  this.connOptions = new ConnOptions(opts);
40
47
 
48
+ // Adjust connectTimeout if acquireTimeout is smaller
41
49
  if (this.acquireTimeout > 0 && this.connOptions.connectTimeout > this.acquireTimeout) {
42
50
  this.connOptions.connectTimeout = this.acquireTimeout;
43
51
  }