node-firebird 2.0.1 → 2.2.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/.github/workflows/node.js.yml +20 -0
- package/CI_DEBUGGING_GUIDE.md +148 -0
- package/FIREBIRD_LOG_FEATURE.md +145 -0
- package/MINIMAL_CHANGES_SUMMARY.md +136 -0
- package/PR_SUMMARY.md +88 -131
- package/README.md +142 -22
- package/ROADMAP.md +223 -0
- package/SRP_PROTOCOL.md +480 -0
- package/lib/ieee754-decimal.js +500 -0
- package/lib/index.d.ts +10 -6
- package/lib/wire/connection.js +263 -61
- package/lib/wire/const.js +29 -0
- package/lib/wire/database.js +78 -9
- package/lib/wire/eventConnection.js +6 -3
- package/lib/wire/fbEventManager.js +234 -41
- package/lib/wire/serialize.js +39 -0
- package/lib/wire/service.js +102 -94
- package/lib/wire/statement.js +4 -4
- package/lib/wire/transaction.js +27 -9
- package/lib/wire/xsqlvar.js +176 -0
- package/package.json +5 -4
- package/vitest.config.js +12 -1
- package/0001-fix-attachEvent-host-resolution.patch +0 -72
- package/Roadmap.md +0 -80
- package/diff +0 -62
package/lib/wire/service.js
CHANGED
|
@@ -135,102 +135,110 @@ class ServiceManager extends Events.EventEmitter {
|
|
|
135
135
|
}
|
|
136
136
|
|
|
137
137
|
_processquery(buffer, callback) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
this._processdbinfo(br, res);
|
|
158
|
-
break;
|
|
159
|
-
case Const.isc_info_svc_limbo_trans:
|
|
160
|
-
// not implemented
|
|
161
|
-
for (; tinfo !== isc_info_flag_end; tinfo = br.readByteCode())
|
|
138
|
+
if (!Buffer.isBuffer(buffer)) {
|
|
139
|
+
doError(new Error('Malformed service-manager response: missing BLR buffer'), callback);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
var br = new BlrReader(buffer);
|
|
145
|
+
var tinfo = br.readByteCode();
|
|
146
|
+
var res = {};
|
|
147
|
+
res.result = 0;
|
|
148
|
+
for (; tinfo !== Const.isc_info_end; tinfo = br.readByteCode()) {
|
|
149
|
+
switch (tinfo) {
|
|
150
|
+
case Const.isc_info_svc_server_version:
|
|
151
|
+
case Const.isc_info_svc_implementation:
|
|
152
|
+
case Const.isc_info_svc_user_dbpath:
|
|
153
|
+
case Const.isc_info_svc_get_env:
|
|
154
|
+
case Const.isc_info_svc_get_env_lock:
|
|
155
|
+
case Const.isc_info_svc_get_env_msg:
|
|
156
|
+
res[this._infosmapping[tinfo]] = br.readString();
|
|
162
157
|
break;
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
158
|
+
case Const.isc_info_svc_version:
|
|
159
|
+
res[this._infosmapping[tinfo]] = br.readInt32();
|
|
160
|
+
break;
|
|
161
|
+
case Const.isc_info_svc_svr_db_info:
|
|
162
|
+
this._processdbinfo(br, res);
|
|
163
|
+
break;
|
|
164
|
+
case Const.isc_info_svc_limbo_trans:
|
|
165
|
+
// not implemented
|
|
166
|
+
for (; tinfo !== isc_info_flag_end; tinfo = br.readByteCode())
|
|
167
|
+
break;
|
|
168
|
+
case Const.isc_info_svc_get_users:
|
|
169
|
+
br.pos += 2
|
|
170
|
+
res[this._infosmapping[tinfo]] = [];
|
|
171
|
+
break;
|
|
172
|
+
case Const.isc_spb_sec_username:
|
|
173
|
+
var tuser = res[this._infosmapping[68]];
|
|
174
|
+
tuser.push({});
|
|
175
|
+
tuser[tuser.length - 1].username = br.readString();
|
|
176
|
+
break;
|
|
177
|
+
case Const.isc_spb_sec_firstname:
|
|
178
|
+
var tuser = res[this._infosmapping[68]];
|
|
179
|
+
var user = tuser[tuser.length-1];
|
|
180
|
+
user.firstname = br.readString();
|
|
181
|
+
break;
|
|
182
|
+
case Const.isc_spb_sec_middlename:
|
|
183
|
+
var tuser = res[this._infosmapping[68]];
|
|
184
|
+
var user = tuser[tuser.length-1];
|
|
185
|
+
user.middlename = br.readString();
|
|
186
|
+
break;
|
|
187
|
+
case Const.isc_spb_sec_lastname:
|
|
188
|
+
var tuser = res[this._infosmapping[68]];
|
|
189
|
+
var user = tuser[tuser.length-1];
|
|
190
|
+
user.lastname = br.readString();
|
|
191
|
+
break;
|
|
192
|
+
case Const.isc_spb_sec_groupid:
|
|
193
|
+
var tuser = res[this._infosmapping[68]];
|
|
194
|
+
var user = tuser[tuser.length-1];
|
|
195
|
+
user.groupid = br.readInt32();
|
|
196
|
+
break;
|
|
197
|
+
case Const.isc_spb_sec_userid:
|
|
198
|
+
var tuser = res[this._infosmapping[68]];
|
|
199
|
+
var user = tuser[tuser.length-1];
|
|
200
|
+
user.userid = br.readInt32();
|
|
201
|
+
|
|
202
|
+
break;
|
|
203
|
+
case Const.isc_spb_sec_admin:
|
|
204
|
+
var tuser = res[this._infosmapping[68]];
|
|
205
|
+
var user = tuser[tuser.length-1];
|
|
206
|
+
user.admin = br.readInt32();
|
|
207
|
+
break;
|
|
208
|
+
|
|
209
|
+
case Const.isc_info_svc_line:
|
|
210
|
+
res.line = br.readString();
|
|
211
|
+
break;
|
|
212
|
+
|
|
213
|
+
case Const.isc_info_svc_to_eof:
|
|
214
|
+
res.line = br.readString();
|
|
215
|
+
break;
|
|
216
|
+
|
|
217
|
+
case Const.isc_info_truncated:
|
|
218
|
+
res.result = 1; // too much data for the result buffer increase size of it (buffersize parameter))
|
|
219
|
+
break;
|
|
220
|
+
|
|
221
|
+
case Const.isc_info_data_not_ready:
|
|
222
|
+
res.result = 2;
|
|
223
|
+
break;
|
|
224
|
+
|
|
225
|
+
case Const.isc_info_svc_timeout:
|
|
226
|
+
res.result = 3;
|
|
227
|
+
break;
|
|
228
|
+
|
|
229
|
+
case Const.isc_info_svc_stdin:
|
|
230
|
+
|
|
231
|
+
break;
|
|
232
|
+
|
|
233
|
+
case Const.isc_info_svc_capabilities:
|
|
234
|
+
this._processcapabilities(br, res);
|
|
235
|
+
break;
|
|
236
|
+
}
|
|
231
237
|
}
|
|
238
|
+
callback(null, res);
|
|
239
|
+
} catch (err) {
|
|
240
|
+
doError(new Error('Malformed service-manager response: ' + err.message), callback);
|
|
232
241
|
}
|
|
233
|
-
callback(null, res);
|
|
234
242
|
}
|
|
235
243
|
|
|
236
244
|
detach(callback, force) {
|
|
@@ -1047,4 +1055,4 @@ class ServiceManager extends Events.EventEmitter {
|
|
|
1047
1055
|
ServiceManager.ShutdownMode = ShutdownMode;
|
|
1048
1056
|
ServiceManager.ShutdownKind = ShutdownKind;
|
|
1049
1057
|
|
|
1050
|
-
module.exports = ServiceManager;
|
|
1058
|
+
module.exports = ServiceManager;
|
package/lib/wire/statement.js
CHANGED
|
@@ -25,15 +25,15 @@ class Statement {
|
|
|
25
25
|
this.connection.dropStatement(this, callback);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
execute(transaction, params, callback,
|
|
28
|
+
execute(transaction, params, callback, options) {
|
|
29
29
|
if (params instanceof Function) {
|
|
30
|
-
|
|
30
|
+
options = callback;
|
|
31
31
|
callback = params;
|
|
32
32
|
params = undefined;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
this.
|
|
36
|
-
this.connection.executeStatement(transaction, this, params, callback,
|
|
35
|
+
this.options = options;
|
|
36
|
+
this.connection.executeStatement(transaction, this, params, callback, options);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
fetch(transaction, count, callback) {
|
package/lib/wire/transaction.js
CHANGED
|
@@ -25,9 +25,9 @@ class Transaction {
|
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
execute(query, params, callback,
|
|
28
|
+
execute(query, params, callback, options) {
|
|
29
29
|
if (params instanceof Function) {
|
|
30
|
-
|
|
30
|
+
options = callback;
|
|
31
31
|
callback = params;
|
|
32
32
|
params = undefined;
|
|
33
33
|
}
|
|
@@ -100,13 +100,13 @@ class Transaction {
|
|
|
100
100
|
break;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
-
},
|
|
103
|
+
}, options);
|
|
104
104
|
});
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
sequentially(query, params, on, callback,
|
|
107
|
+
sequentially(query, params, on, callback, options = {}) {
|
|
108
108
|
if (params instanceof Function) {
|
|
109
|
-
|
|
109
|
+
options = callback;
|
|
110
110
|
callback = on;
|
|
111
111
|
on = params;
|
|
112
112
|
params = undefined;
|
|
@@ -117,7 +117,7 @@ class Transaction {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
if (callback instanceof Boolean) {
|
|
120
|
-
|
|
120
|
+
options = callback;
|
|
121
121
|
callback = undefined;
|
|
122
122
|
}
|
|
123
123
|
|
|
@@ -152,11 +152,23 @@ class Transaction {
|
|
|
152
152
|
}
|
|
153
153
|
};
|
|
154
154
|
|
|
155
|
-
|
|
155
|
+
// back compatibility - options parameter is a boolean
|
|
156
|
+
if (typeof options === 'boolean') {
|
|
157
|
+
options = { asObject: !options, asStream: true, on: _on };
|
|
158
|
+
} else {
|
|
159
|
+
options = {
|
|
160
|
+
asStream: true,
|
|
161
|
+
asObject: true,
|
|
162
|
+
on: _on,
|
|
163
|
+
...options,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
self.execute(query, params, callback, options);
|
|
156
168
|
return self;
|
|
157
169
|
}
|
|
158
170
|
|
|
159
|
-
query(query, params, callback) {
|
|
171
|
+
query(query, params, callback, options = {}) {
|
|
160
172
|
if (params instanceof Function) {
|
|
161
173
|
callback = params;
|
|
162
174
|
params = undefined;
|
|
@@ -165,7 +177,13 @@ class Transaction {
|
|
|
165
177
|
if (callback === undefined)
|
|
166
178
|
callback = noop;
|
|
167
179
|
|
|
168
|
-
|
|
180
|
+
options = {
|
|
181
|
+
asObject: true,
|
|
182
|
+
asStream: callback === undefined || callback === null,
|
|
183
|
+
...options,
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
this.execute(query, params, callback, options);
|
|
169
187
|
}
|
|
170
188
|
|
|
171
189
|
commit(callback) {
|
package/lib/wire/xsqlvar.js
CHANGED
|
@@ -199,6 +199,44 @@ class SQLVarInt128 {
|
|
|
199
199
|
|
|
200
200
|
//------------------------------------------------------
|
|
201
201
|
|
|
202
|
+
class SQLVarDecFloat16 {
|
|
203
|
+
decode(data, lowerV13) {
|
|
204
|
+
var ret = data.readDecFloat16();
|
|
205
|
+
|
|
206
|
+
if (!lowerV13 || !data.readInt()) {
|
|
207
|
+
return ret;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
calcBlr(blr) {
|
|
214
|
+
blr.addByte(Const.blr_dec64);
|
|
215
|
+
blr.addShort(0);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
//------------------------------------------------------
|
|
220
|
+
|
|
221
|
+
class SQLVarDecFloat34 {
|
|
222
|
+
decode(data, lowerV13) {
|
|
223
|
+
var ret = data.readDecFloat34();
|
|
224
|
+
|
|
225
|
+
if (!lowerV13 || !data.readInt()) {
|
|
226
|
+
return ret;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
return null;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
calcBlr(blr) {
|
|
233
|
+
blr.addByte(Const.blr_dec128);
|
|
234
|
+
blr.addShort(0);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
//------------------------------------------------------
|
|
239
|
+
|
|
202
240
|
class SQLVarFloat {
|
|
203
241
|
decode(data, lowerV13) {
|
|
204
242
|
var ret = data.readFloat();
|
|
@@ -295,6 +333,92 @@ class SQLVarTimeStamp {
|
|
|
295
333
|
|
|
296
334
|
//------------------------------------------------------
|
|
297
335
|
|
|
336
|
+
class SQLVarTimeTz {
|
|
337
|
+
decode(data, lowerV13) {
|
|
338
|
+
var time = data.readUInt();
|
|
339
|
+
data.readInt(); // skip timezone info
|
|
340
|
+
|
|
341
|
+
if (!lowerV13 || !data.readInt()) {
|
|
342
|
+
var d = new Date(0);
|
|
343
|
+
d.setMilliseconds(Math.floor(time / 10) + d.getTimezoneOffset() * MsPerMinute);
|
|
344
|
+
return d;
|
|
345
|
+
}
|
|
346
|
+
return null;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
calcBlr(blr) {
|
|
350
|
+
blr.addByte(Const.blr_sql_time_tz);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
//------------------------------------------------------
|
|
355
|
+
|
|
356
|
+
class SQLVarTimeTzEx extends SQLVarTimeTz {
|
|
357
|
+
decode(data, lowerV13) {
|
|
358
|
+
var time = data.readUInt();
|
|
359
|
+
data.readInt(); // skip timezone info
|
|
360
|
+
data.readInt(); // skip ext_offset
|
|
361
|
+
|
|
362
|
+
if (!lowerV13 || !data.readInt()) {
|
|
363
|
+
var d = new Date(0);
|
|
364
|
+
d.setMilliseconds(Math.floor(time / 10) + d.getTimezoneOffset() * MsPerMinute);
|
|
365
|
+
return d;
|
|
366
|
+
}
|
|
367
|
+
return null;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
calcBlr(blr) {
|
|
371
|
+
blr.addByte(Const.blr_ex_time_tz);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
//------------------------------------------------------
|
|
376
|
+
|
|
377
|
+
class SQLVarTimeStampTz {
|
|
378
|
+
decode(data, lowerV13) {
|
|
379
|
+
var date = data.readInt();
|
|
380
|
+
var time = data.readUInt();
|
|
381
|
+
data.readInt(); // skip timezone info
|
|
382
|
+
|
|
383
|
+
if (!lowerV13 || !data.readInt()) {
|
|
384
|
+
var d = new Date(0);
|
|
385
|
+
d.setMilliseconds((date - DateOffset) * TimeCoeff + Math.floor(time / 10) + d.getTimezoneOffset() * MsPerMinute);
|
|
386
|
+
return d;
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
calcBlr(blr) {
|
|
393
|
+
blr.addByte(Const.blr_timestamp_tz);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
//------------------------------------------------------
|
|
398
|
+
|
|
399
|
+
class SQLVarTimeStampTzEx extends SQLVarTimeStampTz {
|
|
400
|
+
decode(data, lowerV13) {
|
|
401
|
+
var date = data.readInt();
|
|
402
|
+
var time = data.readUInt();
|
|
403
|
+
data.readInt(); // skip timezone info
|
|
404
|
+
data.readInt(); // skip ext_offset
|
|
405
|
+
|
|
406
|
+
if (!lowerV13 || !data.readInt()) {
|
|
407
|
+
var d = new Date(0);
|
|
408
|
+
d.setMilliseconds((date - DateOffset) * TimeCoeff + Math.floor(time / 10) + d.getTimezoneOffset() * MsPerMinute);
|
|
409
|
+
return d;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
return null;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
calcBlr(blr) {
|
|
416
|
+
blr.addByte(Const.blr_ex_timestamp_tz);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
//------------------------------------------------------
|
|
421
|
+
|
|
298
422
|
class SQLVarBoolean {
|
|
299
423
|
decode(data, lowerV13) {
|
|
300
424
|
var ret = data.readInt();
|
|
@@ -378,6 +502,50 @@ class SQLParamInt128 {
|
|
|
378
502
|
|
|
379
503
|
//------------------------------------------------------
|
|
380
504
|
|
|
505
|
+
class SQLParamDecFloat16 {
|
|
506
|
+
constructor(value) {
|
|
507
|
+
this.value = value;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
calcBlr(blr) {
|
|
511
|
+
blr.addByte(Const.blr_dec64);
|
|
512
|
+
blr.addShort(0);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
encode(data) {
|
|
516
|
+
if (this.value != null) {
|
|
517
|
+
data.addDecFloat16(this.value);
|
|
518
|
+
} else {
|
|
519
|
+
data.addDecFloat16(0);
|
|
520
|
+
data.addInt(1);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
//------------------------------------------------------
|
|
526
|
+
|
|
527
|
+
class SQLParamDecFloat34 {
|
|
528
|
+
constructor(value) {
|
|
529
|
+
this.value = value;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
calcBlr(blr) {
|
|
533
|
+
blr.addByte(Const.blr_dec128);
|
|
534
|
+
blr.addShort(0);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
encode(data) {
|
|
538
|
+
if (this.value != null) {
|
|
539
|
+
data.addDecFloat34(this.value);
|
|
540
|
+
} else {
|
|
541
|
+
data.addDecFloat34(0);
|
|
542
|
+
data.addInt(1);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
//------------------------------------------------------
|
|
548
|
+
|
|
381
549
|
class SQLParamDouble {
|
|
382
550
|
constructor(value) {
|
|
383
551
|
this.value = value;
|
|
@@ -509,6 +677,8 @@ module.exports = {
|
|
|
509
677
|
SQLVarInt,
|
|
510
678
|
SQLVarInt64,
|
|
511
679
|
SQLVarInt128,
|
|
680
|
+
SQLVarDecFloat16,
|
|
681
|
+
SQLVarDecFloat34,
|
|
512
682
|
SQLVarFloat,
|
|
513
683
|
SQLVarNull,
|
|
514
684
|
SQLVarShort,
|
|
@@ -516,12 +686,18 @@ module.exports = {
|
|
|
516
686
|
SQLVarText,
|
|
517
687
|
SQLVarTime,
|
|
518
688
|
SQLVarTimeStamp,
|
|
689
|
+
SQLVarTimeTz,
|
|
690
|
+
SQLVarTimeTzEx,
|
|
691
|
+
SQLVarTimeStampTz,
|
|
692
|
+
SQLVarTimeStampTzEx,
|
|
519
693
|
SQLParamBool,
|
|
520
694
|
SQLParamDate,
|
|
521
695
|
SQLParamDouble,
|
|
522
696
|
SQLParamInt,
|
|
523
697
|
SQLParamInt64,
|
|
524
698
|
SQLParamInt128,
|
|
699
|
+
SQLParamDecFloat16,
|
|
700
|
+
SQLParamDecFloat34,
|
|
525
701
|
SQLParamQuad,
|
|
526
702
|
SQLParamString,
|
|
527
703
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-firebird",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Pure JavaScript and Asynchronous Firebird client for Node.js.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"firebird",
|
|
@@ -25,15 +25,16 @@
|
|
|
25
25
|
"types": "./lib/index.d.ts",
|
|
26
26
|
"license": "MPL-2.0",
|
|
27
27
|
"scripts": {
|
|
28
|
-
"test": "vitest run"
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"lint": "oxlint"
|
|
29
30
|
},
|
|
30
31
|
"dependencies": {
|
|
31
32
|
"big-integer": "^1.6.51",
|
|
32
33
|
"long": "^5.2.3"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
35
|
-
"coveralls-next": "^
|
|
36
|
-
"
|
|
36
|
+
"coveralls-next": "^6.0.1",
|
|
37
|
+
"oxlint": "^0.15.11",
|
|
37
38
|
"vitest": "^4.0.18"
|
|
38
39
|
}
|
|
39
40
|
}
|
package/vitest.config.js
CHANGED
|
@@ -8,6 +8,17 @@ module.exports = defineConfig({
|
|
|
8
8
|
fileParallelism: false,
|
|
9
9
|
maxWorkers: 1,
|
|
10
10
|
isolate: false,
|
|
11
|
-
include: [
|
|
11
|
+
include: [
|
|
12
|
+
'test/arc4.js',
|
|
13
|
+
'test/protocol.js',
|
|
14
|
+
'test/srp.js',
|
|
15
|
+
'test/service.js',
|
|
16
|
+
'test/utf8-user-identification.js',
|
|
17
|
+
'test/index.js',
|
|
18
|
+
'test/db-crypt-config.js',
|
|
19
|
+
'test/timezone.js',
|
|
20
|
+
'test/decfloat.js',
|
|
21
|
+
'test/mock-server.js'
|
|
22
|
+
],
|
|
12
23
|
},
|
|
13
24
|
});
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
2
|
-
From: Gobbo89 <gobbo89@users.noreply.github.com>
|
|
3
|
-
Date: Thu, 19 Feb 2026 00:00:00 +0000
|
|
4
|
-
Subject: [PATCH] fix(events): resolve event channel host from connection options
|
|
5
|
-
|
|
6
|
-
When Firebird is configured with RemoteBindAddress unset (default),
|
|
7
|
-
auxConnection() returns socket_info.host = "0.0.0.0", which is a
|
|
8
|
-
bind-any address and not a routable destination for remote clients.
|
|
9
|
-
|
|
10
|
-
This commit changes the host selection logic in attachEvent to prefer
|
|
11
|
-
connection.options.host (the address that the user explicitly provided
|
|
12
|
-
and that is proven reachable, since the initial DB attach succeeded).
|
|
13
|
-
|
|
14
|
-
Only if options.host is absent does it fall back to socket_info.host,
|
|
15
|
-
and even then only when that host is a concrete routable address (i.e.
|
|
16
|
-
not "0.0.0.0" and not "::"). As a last resort it uses the socket's
|
|
17
|
-
remoteAddress, normalizing IPv6-mapped IPv4 (::ffff:x.x.x.x → x.x.x.x).
|
|
18
|
-
|
|
19
|
-
Fixes #386.
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
lib/wire/database.js | 25 +++++++++++++++++++++++--
|
|
23
|
-
1 file changed, 23 insertions(+), 2 deletions(-)
|
|
24
|
-
|
|
25
|
-
diff --git a/lib/wire/database.js b/lib/wire/database.js
|
|
26
|
-
index xxxxxxx..yyyyyyy 100644
|
|
27
|
-
--- a/lib/wire/database.js
|
|
28
|
-
+++ b/lib/wire/database.js
|
|
29
|
-
@@ -1,3 +1,18 @@
|
|
30
|
-
+/**
|
|
31
|
-
+ * Resolves the host to use for the auxiliary event channel.
|
|
32
|
-
+ *
|
|
33
|
-
+ * Priority:
|
|
34
|
-
+ * 1. connection.options.host – explicitly provided by the caller; known reachable.
|
|
35
|
-
+ * 2. socket_info.host – only when it is a concrete routable address
|
|
36
|
-
+ * (i.e. not "0.0.0.0" and not "::").
|
|
37
|
-
+ * 3. socket.remoteAddress – the OS-level address of the main connection socket,
|
|
38
|
-
+ * with IPv6-mapped IPv4 prefixes stripped.
|
|
39
|
-
+ *
|
|
40
|
-
+ * @param {object} connection The active database connection object.
|
|
41
|
-
+ * @param {string} auxHost The host returned by the auxConnection() call.
|
|
42
|
-
+ * @returns {string} A connectable host string.
|
|
43
|
-
+ */
|
|
44
|
-
+function resolveEventHost(connection, auxHost) {
|
|
45
|
-
+ // 1. Prefer the host the caller explicitly supplied.
|
|
46
|
-
+ if (connection.options && connection.options.host) {
|
|
47
|
-
+ return connection.options.host;
|
|
48
|
-
+ }
|
|
49
|
-
+
|
|
50
|
-
+ // 2. Use auxConnection host only when it is a real address.
|
|
51
|
-
+ var BIND_ANY = ['0.0.0.0', '::'];
|
|
52
|
-
+ if (auxHost && BIND_ANY.indexOf(auxHost) === -1) {
|
|
53
|
-
+ return auxHost;
|
|
54
|
-
+ }
|
|
55
|
-
+
|
|
56
|
-
+ // 3. Fall back to the OS-reported remote address of the main socket,
|
|
57
|
-
+ // normalising IPv6-mapped IPv4 (e.g. "::ffff:10.0.0.1" → "10.0.0.1").
|
|
58
|
-
+ var remoteAddress = connection._socket && connection._socket.remoteAddress;
|
|
59
|
-
+ if (remoteAddress) {
|
|
60
|
-
+ return remoteAddress.replace(/^::ffff:/, '');
|
|
61
|
-
+ }
|
|
62
|
-
+
|
|
63
|
-
+ // Last resort: return whatever auxConnection gave us and let the caller fail
|
|
64
|
-
+ // with a meaningful socket error rather than a silent undefined.
|
|
65
|
-
+ return auxHost;
|
|
66
|
-
+}
|
|
67
|
-
+
|
|
68
|
-
// ... (existing code) ...
|
|
69
|
-
|
|
70
|
-
- var eventConnection = new EventConnection(socket_info.host, socket_info.port, self.connection.options, eventCallback);
|
|
71
|
-
+ var eventHost = resolveEventHost(self.connection, socket_info.host);
|
|
72
|
-
+ var eventConnection = new EventConnection(eventHost, socket_info.port, self.connection.options, eventCallback);
|