tedious
Advanced tools
Comparing version 12.3.0-alpha.1 to 12.3.0
@@ -6,3 +6,3 @@ const { createBenchmark } = require('../common'); | ||
const { Readable } = require('readable-stream'); | ||
const { Readable } = require('stream'); | ||
@@ -30,2 +30,3 @@ const bench = createBenchmark(main, { | ||
request.addParameter('value', TYPES.TVP, table); | ||
request.validateParameters(); | ||
@@ -41,10 +42,7 @@ let i = 0; | ||
const payload = new RpcRequestPayload(request, Buffer.alloc(0), {}); | ||
const stream = Readable.from(payload, { objectMode: false }); | ||
const chunks = []; | ||
stream.on('data', (chunk) => { | ||
chunks.push(chunk); | ||
}); | ||
const payload = new RpcRequestPayload(request.sqlTextOrProcedure, request.parameters, Buffer.alloc(0), {}, undefined); | ||
const stream = Readable.from(payload); | ||
stream.on('data', () => {}); | ||
stream.on('end', cb); | ||
})(); | ||
} |
@@ -6,3 +6,3 @@ const { createBenchmark } = require('../common'); | ||
const { Readable } = require('readable-stream'); | ||
const { Readable } = require('stream'); | ||
@@ -33,10 +33,7 @@ const bench = createBenchmark(main, { | ||
const payload = new RpcRequestPayload(request, Buffer.alloc(0), {}); | ||
const stream = Readable.from(payload, { objectMode: false }); | ||
const chunks = []; | ||
stream.on('data', (chunk) => { | ||
chunks.push(chunk); | ||
}); | ||
const payload = new RpcRequestPayload(request.sqlTextOrProcedure, request.parameters, Buffer.alloc(0), {}, undefined); | ||
const stream = Readable.from(payload); | ||
stream.on('data', () => {}); | ||
stream.on('end', cb); | ||
})(); | ||
} |
@@ -8,4 +8,2 @@ "use strict"; | ||
var _jsbi = _interopRequireDefault(require("jsbi")); | ||
var _intn = _interopRequireDefault(require("./intn")); | ||
@@ -49,14 +47,2 @@ | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
const val = typeof value !== 'number' ? parseInt(value) : value; | ||
const buffer = new _writableTrackingBuffer.default(8); | ||
buffer.writeBigInt64LE(_jsbi.default.BigInt(val)); | ||
return buffer.data; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -63,0 +49,0 @@ if (value == null) { |
@@ -64,12 +64,2 @@ "use strict"; | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
return Buffer.isBuffer(value) ? value : Buffer.from(value); | ||
} else { | ||
// PLP NULL | ||
return Buffer.from([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -76,0 +66,0 @@ if (value == null) { |
@@ -42,14 +42,2 @@ "use strict"; | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
const val = value; | ||
const result = Buffer.alloc(8); | ||
result.writeInt8(val ? 1 : 0, 0); | ||
return result; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -56,0 +44,0 @@ if (value == null) { |
@@ -28,6 +28,2 @@ "use strict"; | ||
toBuffer() { | ||
throw new Error('not implemented'); | ||
}, | ||
validate() { | ||
@@ -34,0 +30,0 @@ throw new Error('not implemented'); |
@@ -83,12 +83,2 @@ "use strict"; | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
return value; | ||
} else { | ||
// PLP NULL | ||
return Buffer.from([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]); | ||
} | ||
}, | ||
validate: function (value, collation) { | ||
@@ -95,0 +85,0 @@ if (value == null) { |
@@ -10,6 +10,2 @@ "use strict"; | ||
var _writableTrackingBuffer = _interopRequireDefault(require("../tracking-buffer/writable-tracking-buffer")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
// globalDate is to be used for JavaScript's global 'Date' object to avoid name clashing with the 'Date' constant below | ||
@@ -62,22 +58,2 @@ const globalDate = global.Date; | ||
toBuffer: function (parameter, options) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
let date; | ||
if (options.useUTC) { | ||
date = _core.LocalDate.of(value.getUTCFullYear(), value.getUTCMonth() + 1, value.getUTCDate()); | ||
} else { | ||
date = _core.LocalDate.of(value.getFullYear(), value.getMonth() + 1, value.getDate()); | ||
} | ||
const days = EPOCH_DATE.until(date, _core.ChronoUnit.DAYS); | ||
const buffer = new _writableTrackingBuffer.default(3); | ||
buffer.writeUInt24LE(days); | ||
return buffer.data; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
// TODO: value is techincally of type 'unknown'. | ||
@@ -84,0 +60,0 @@ validate: function (value) { |
@@ -81,45 +81,2 @@ "use strict"; | ||
}, | ||
toBuffer: function (parameter, options) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
let date; | ||
if (options.useUTC) { | ||
date = _core.LocalDate.of(value.getUTCFullYear(), value.getUTCMonth() + 1, value.getUTCDate()); | ||
} else { | ||
date = _core.LocalDate.of(value.getFullYear(), value.getMonth() + 1, value.getDate()); | ||
} | ||
let days = EPOCH_DATE.until(date, _core.ChronoUnit.DAYS); | ||
let milliseconds, threeHundredthsOfSecond; | ||
if (options.useUTC) { | ||
let seconds = value.getUTCHours() * 60 * 60; | ||
seconds += value.getUTCMinutes() * 60; | ||
seconds += value.getUTCSeconds(); | ||
milliseconds = seconds * 1000 + value.getUTCMilliseconds(); | ||
} else { | ||
let seconds = value.getHours() * 60 * 60; | ||
seconds += value.getMinutes() * 60; | ||
seconds += value.getSeconds(); | ||
milliseconds = seconds * 1000 + value.getMilliseconds(); | ||
} | ||
threeHundredthsOfSecond = milliseconds / (3 + 1 / 3); | ||
threeHundredthsOfSecond = Math.round(threeHundredthsOfSecond); // 25920000 equals one day | ||
if (threeHundredthsOfSecond === 25920000) { | ||
days += 1; | ||
threeHundredthsOfSecond = 0; | ||
} | ||
const result = Buffer.alloc(8); | ||
result.writeUInt32LE(days, 0); | ||
result.writeUInt32LE(threeHundredthsOfSecond, 4); | ||
return result; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
// TODO: type 'any' needs to be revisited. | ||
@@ -126,0 +83,0 @@ validate: function (value) { |
@@ -8,6 +8,6 @@ "use strict"; | ||
var _core = require("@js-joda/core"); | ||
var _writableTrackingBuffer = _interopRequireDefault(require("../tracking-buffer/writable-tracking-buffer")); | ||
var _core = require("@js-joda/core"); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -116,36 +116,2 @@ | ||
toBuffer: function (parameter, options) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
const scale = this.resolveScale(parameter); | ||
let timestamp; | ||
if (options.useUTC) { | ||
timestamp = ((value.getUTCHours() * 60 + value.getUTCMinutes()) * 60 + value.getUTCSeconds()) * 1000 + value.getUTCMilliseconds(); | ||
} else { | ||
timestamp = ((value.getHours() * 60 + value.getMinutes()) * 60 + value.getSeconds()) * 1000 + value.getMilliseconds(); | ||
} | ||
timestamp = timestamp * Math.pow(10, scale - 3); | ||
timestamp += (value.nanosecondDelta != null ? value.nanosecondDelta : 0) * Math.pow(10, scale); | ||
timestamp = Math.round(timestamp); | ||
let date; | ||
if (options.useUTC) { | ||
date = _core.LocalDate.of(value.getUTCFullYear(), value.getUTCMonth() + 1, value.getUTCDate()); | ||
} else { | ||
date = _core.LocalDate.of(value.getFullYear(), value.getMonth() + 1, value.getDate()); | ||
} | ||
const days = EPOCH_DATE.until(date, _core.ChronoUnit.DAYS); // encrypted datetime2 must be 8 bytes: 5 for time, 3 for date | ||
const buffer = new _writableTrackingBuffer.default(8); | ||
buffer.writeUInt40LE(timestamp); | ||
buffer.writeUInt24LE(days); | ||
return buffer.data; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -152,0 +118,0 @@ if (value == null) { |
@@ -28,6 +28,2 @@ "use strict"; | ||
toBuffer() { | ||
throw new Error('not implemented'); | ||
}, | ||
validate() { | ||
@@ -34,0 +30,0 @@ throw new Error('not implemented'); |
@@ -8,6 +8,6 @@ "use strict"; | ||
var _core = require("@js-joda/core"); | ||
var _writableTrackingBuffer = _interopRequireDefault(require("../tracking-buffer/writable-tracking-buffer")); | ||
var _core = require("@js-joda/core"); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -106,28 +106,2 @@ | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
const scale = this.resolveScale(parameter); | ||
let timestamp; | ||
timestamp = ((value.getUTCHours() * 60 + value.getUTCMinutes()) * 60 + value.getUTCSeconds()) * 1000 + value.getMilliseconds(); | ||
timestamp = timestamp * Math.pow(10, scale - 3); | ||
timestamp += (value.nanosecondDelta != null ? value.nanosecondDelta : 0) * Math.pow(10, scale); | ||
timestamp = Math.round(timestamp); | ||
const date = _core.LocalDate.of(value.getUTCFullYear(), value.getUTCMonth() + 1, value.getUTCDate()); | ||
const days = EPOCH_DATE.until(date, _core.ChronoUnit.DAYS); | ||
const offset = -value.getTimezoneOffset(); // data size does not matter for encrypted datetimeoffset | ||
// just choose the smallest that maintains full scale (7) | ||
const buffer = new _writableTrackingBuffer.default(10); | ||
buffer.writeUInt40LE(timestamp); | ||
buffer.writeUInt24LE(days); | ||
buffer.writeInt16LE(offset); | ||
return buffer.data; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -134,0 +108,0 @@ if (value == null) { |
@@ -108,20 +108,2 @@ "use strict"; | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
const scale = Decimal.resolveScale(parameter); | ||
const sign = value < 0 ? 0x00 : 0x01; | ||
const mag = Math.round(Math.abs(value * Math.pow(10, scale))); // block size does not matter for encrypted decimal | ||
// just choose the smallest that maintains full precision (18), instead | ||
// of tailoring it for each parameter.precision | ||
const result = new _writableTrackingBuffer.default(16); | ||
result.writeUInt8(sign); | ||
result.writeUInt64LE(mag); | ||
return result.data; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -128,0 +110,0 @@ if (value == null) { |
@@ -28,6 +28,2 @@ "use strict"; | ||
toBuffer() { | ||
throw new Error('not implemented'); | ||
}, | ||
validate() { | ||
@@ -34,0 +30,0 @@ throw new Error('not implemented'); |
@@ -43,14 +43,2 @@ "use strict"; | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
const val = parseFloat(value); | ||
const result = Buffer.alloc(8); | ||
result.writeDoubleLE(val, 0); | ||
return result; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -57,0 +45,0 @@ if (value == null) { |
@@ -28,6 +28,2 @@ "use strict"; | ||
toBuffer() { | ||
throw new Error('not implemented'); | ||
}, | ||
validate() { | ||
@@ -34,0 +30,0 @@ throw new Error('not implemented'); |
@@ -44,14 +44,2 @@ "use strict"; | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
const val = value; | ||
const result = Buffer.alloc(8); | ||
result.writeInt32LE(val, 0); | ||
return result; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -58,0 +46,0 @@ if (value == null) { |
@@ -28,6 +28,2 @@ "use strict"; | ||
toBuffer() { | ||
throw new Error('not implemented'); | ||
}, | ||
validate() { | ||
@@ -34,0 +30,0 @@ throw new Error('not implemented'); |
@@ -8,4 +8,2 @@ "use strict"; | ||
var _writableTrackingBuffer = _interopRequireDefault(require("../tracking-buffer/writable-tracking-buffer")); | ||
var _moneyn = _interopRequireDefault(require("./moneyn")); | ||
@@ -50,14 +48,2 @@ | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
const val = parseFloat(value) * 10000; | ||
const buffer = new _writableTrackingBuffer.default(8); | ||
buffer.writeMoney(val); | ||
return buffer.data; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -64,0 +50,0 @@ if (value == null) { |
@@ -20,6 +20,2 @@ "use strict"; | ||
toBuffer() { | ||
throw new Error('not implemented'); | ||
}, | ||
generateParameterLength() { | ||
@@ -26,0 +22,0 @@ throw new Error('not implemented'); |
@@ -99,12 +99,2 @@ "use strict"; | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
return Buffer.isBuffer(value) ? value : Buffer.from(value, 'ucs2'); | ||
} else { | ||
// PLP NULL | ||
return Buffer.from([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -111,0 +101,0 @@ if (value == null) { |
@@ -107,20 +107,2 @@ "use strict"; | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
const scale = Numeric.resolveScale(parameter); | ||
const sign = value < 0 ? 0x00 : 0x01; | ||
const mag = Math.round(Math.abs(value * Math.pow(10, scale))); // block size does not matter for encrypted numeric | ||
// just choose the smallest that maintains full precision (18), instead | ||
// of tailoring it for each parameter.precision | ||
const result = new _writableTrackingBuffer.default(16); | ||
result.writeUInt8(sign); | ||
result.writeUInt64LE(mag); | ||
return result.data; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -127,0 +109,0 @@ if (value == null) { |
@@ -20,6 +20,2 @@ "use strict"; | ||
toBuffer() { | ||
throw new Error('not implemented'); | ||
}, | ||
generateParameterLength() { | ||
@@ -26,0 +22,0 @@ throw new Error('not implemented'); |
@@ -71,13 +71,2 @@ "use strict"; | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
return Buffer.isBuffer(value) ? value : Buffer.from(value, 'ucs2'); | ||
} else { | ||
// PLP NULL | ||
return Buffer.from([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]); | ||
} | ||
}, | ||
generateParameterLength(parameter, options) { | ||
@@ -84,0 +73,0 @@ if (parameter.value == null) { |
@@ -44,14 +44,2 @@ "use strict"; | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
const val = parseFloat(value); | ||
const result = Buffer.alloc(4); | ||
result.writeFloatLE(val, 0); | ||
return result; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -58,0 +46,0 @@ if (value == null) { |
@@ -57,25 +57,2 @@ "use strict"; | ||
}, | ||
toBuffer: function (parameter, options) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
let days, dstDiff, minutes; | ||
if (options.useUTC) { | ||
days = Math.floor((value.getTime() - UTC_EPOCH_DATE.getTime()) / (1000 * 60 * 60 * 24)); | ||
minutes = value.getUTCHours() * 60 + value.getUTCMinutes(); | ||
} else { | ||
dstDiff = -(value.getTimezoneOffset() - EPOCH_DATE.getTimezoneOffset()) * 60 * 1000; | ||
days = Math.floor((value.getTime() - EPOCH_DATE.getTime() + dstDiff) / (1000 * 60 * 60 * 24)); | ||
minutes = value.getHours() * 60 + value.getMinutes(); | ||
} | ||
const result = Buffer.alloc(4); | ||
result.writeUInt16LE(days, 0); | ||
result.writeUInt16LE(minutes, 2); | ||
return result; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -82,0 +59,0 @@ if (value == null) { |
@@ -44,14 +44,2 @@ "use strict"; | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
const val = value; | ||
const result = Buffer.alloc(8); | ||
result.writeInt16LE(val, 0); | ||
return result; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -58,0 +46,0 @@ if (value == null) { |
@@ -43,15 +43,2 @@ "use strict"; | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
const val = parseFloat(value) * 10000; // SmallMoney is still 8 bytes, but the first 4 are always ignored | ||
const result = Buffer.alloc(8); | ||
result.writeInt32LE(val, 4); | ||
return result; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -58,0 +45,0 @@ if (value == null) { |
@@ -99,28 +99,2 @@ "use strict"; | ||
toBuffer: function (parameter, options) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
const scale = Time.resolveScale(parameter); | ||
const time = new Date(+value); | ||
let timestamp; | ||
if (options.useUTC) { | ||
timestamp = ((time.getUTCHours() * 60 + time.getUTCMinutes()) * 60 + time.getUTCSeconds()) * 1000 + time.getUTCMilliseconds(); | ||
} else { | ||
timestamp = ((time.getHours() * 60 + time.getMinutes()) * 60 + time.getSeconds()) * 1000 + time.getMilliseconds(); | ||
} | ||
timestamp = timestamp * Math.pow(10, scale - 3); | ||
timestamp += (value.nanosecondDelta != null ? value.nanosecondDelta : 0) * Math.pow(10, scale); | ||
timestamp = Math.round(timestamp); // data size does not matter for encrypted time | ||
// just choose the smallest that maintains full scale (7) | ||
const buffer = new _writableTrackingBuffer.default(5); | ||
buffer.writeUInt40LE(timestamp); | ||
return buffer.data; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -127,0 +101,0 @@ if (value == null) { |
@@ -44,14 +44,2 @@ "use strict"; | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
const val = value; | ||
const result = Buffer.alloc(8); | ||
result.writeInt8(val, 0); | ||
return result; | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -58,0 +46,0 @@ if (value == null) { |
@@ -42,11 +42,2 @@ "use strict"; | ||
}, | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
return Buffer.from((0, _guidParser.guidToArray)(value)); | ||
} else { | ||
return Buffer.from([]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -53,0 +44,0 @@ if (value == null) { |
@@ -53,10 +53,4 @@ "use strict"; | ||
if (parameter.length != null && isFinite(parameter.length)) { | ||
const length = parameter.length; | ||
if (length <= this.maximumLength) { | ||
buffer.writeUInt16LE(length, 1); | ||
} else { | ||
buffer.writeUInt16LE(this.maximumLength, 1); | ||
} | ||
if (parameter.length <= this.maximumLength) { | ||
buffer.writeUInt16LE(parameter.length, 1); | ||
} else { | ||
@@ -133,12 +127,2 @@ buffer.writeUInt16LE(MAX, 1); | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
return Buffer.isBuffer(value) ? value : Buffer.from(value); | ||
} else { | ||
// PLP NULL | ||
return Buffer.from([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]); | ||
} | ||
}, | ||
validate: function (value) { | ||
@@ -145,0 +129,0 @@ if (value == null) { |
@@ -112,12 +112,2 @@ "use strict"; | ||
toBuffer: function (parameter) { | ||
const value = parameter.value; | ||
if (value != null) { | ||
return value; | ||
} else { | ||
// PLP NULL | ||
return Buffer.from([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]); | ||
} | ||
}, | ||
validate: function (value, collation) { | ||
@@ -124,0 +114,0 @@ if (value == null) { |
@@ -68,6 +68,2 @@ "use strict"; | ||
}; | ||
const COLUMN_ENCRYPTION_OPTIONS = { | ||
FEATURE_ID: 0x04, | ||
MAX_SUPPORTED_TCE_VERSION: 0x01 | ||
}; | ||
const FEATURE_EXT_TERMINATOR = 0xFF; | ||
@@ -110,3 +106,2 @@ | ||
this.fedAuth = void 0; | ||
this.columnEncryption = void 0; | ||
this.tdsVersion = tdsVersion; | ||
@@ -122,3 +117,2 @@ this.packetSize = packetSize; | ||
this.fedAuth = undefined; | ||
this.columnEncryption = false; | ||
this.userName = undefined; | ||
@@ -370,13 +364,2 @@ this.password = undefined; | ||
const columnEncryption = this.columnEncryption; | ||
if (columnEncryption) { | ||
const buffer = Buffer.alloc(6); | ||
let offset = 0; | ||
offset = buffer.writeUInt8(COLUMN_ENCRYPTION_OPTIONS.FEATURE_ID, offset); | ||
offset = buffer.writeUInt32LE(1, offset); | ||
buffer.writeUInt8(COLUMN_ENCRYPTION_OPTIONS.MAX_SUPPORTED_TCE_VERSION, offset); | ||
buffers.push(buffer); | ||
} | ||
if (this.tdsVersion >= _tdsVersions.versions['7_4']) { | ||
@@ -383,0 +366,0 @@ // Signal UTF-8 support: Value 0x0A, bit 0 must be set to 1. Added in TDS 7.4. |
@@ -63,15 +63,5 @@ "use strict"; | ||
function readFlags(parser, shouldReadFlags, callback) { | ||
if (shouldReadFlags === false) { | ||
callback(0); | ||
} else { | ||
function metadataParse(parser, options, callback) { | ||
(options.tdsVersion < '7_2' ? parser.readUInt16LE : parser.readUInt32LE).call(parser, userType => { | ||
parser.readUInt16LE(flags => { | ||
callback(flags); | ||
}); | ||
} | ||
} | ||
function metadataParse(parser, options, callback, shouldReadFlags = true) { | ||
(options.tdsVersion < '7_2' ? parser.readUInt16LE : parser.readUInt32LE).call(parser, userType => { | ||
readFlags(parser, shouldReadFlags, flags => { | ||
parser.readUInt8(typeNumber => { | ||
@@ -78,0 +68,0 @@ const type = _dataType.TYPE[typeNumber]; |
@@ -237,4 +237,3 @@ "use strict"; | ||
precision, | ||
scale, | ||
forceEncrypt = false | ||
scale | ||
} = options; | ||
@@ -248,4 +247,3 @@ const parameter = { | ||
precision: precision, | ||
scale: scale, | ||
forceEncrypt: forceEncrypt | ||
scale: scale | ||
}; | ||
@@ -252,0 +250,0 @@ this.parameters.push(parameter); |
@@ -12,8 +12,4 @@ "use strict"; | ||
var _keyCrypto = require("./always-encrypted/key-crypto"); | ||
let _Symbol$iterator; | ||
var _varbinary = _interopRequireDefault(require("./data-types/varbinary")); | ||
let _Symbol$asyncIterator; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -28,4 +24,3 @@ | ||
BY_REF_VALUE: 0x01, | ||
DEFAULT_VALUE: 0x02, | ||
ENCRYPTED_VALUE: 0x08 | ||
DEFAULT_VALUE: 0x02 | ||
}; | ||
@@ -36,3 +31,3 @@ /* | ||
_Symbol$asyncIterator = Symbol.asyncIterator; | ||
_Symbol$iterator = Symbol.iterator; | ||
@@ -53,7 +48,7 @@ class RpcRequestPayload { | ||
[_Symbol$asyncIterator]() { | ||
[_Symbol$iterator]() { | ||
return this.generateData(); | ||
} | ||
async *generateData() { | ||
*generateData() { | ||
const buffer = new _writableTrackingBuffer.default(500); | ||
@@ -76,6 +71,6 @@ | ||
yield buffer.data; | ||
const encryptedParams = await this._encryptParameters(this.parameters); | ||
const parametersLength = this.parameters.length; | ||
for (let i = 0; i < this.parameters.length; i++) { | ||
yield* this.generateParameter(encryptedParams[i]); | ||
for (let i = 0; i < parametersLength; i++) { | ||
yield* this.generateParameterData(this.parameters[i]); | ||
} | ||
@@ -88,3 +83,3 @@ } | ||
*generateParameter(parameter) { | ||
*generateParameterData(parameter) { | ||
const buffer = new _writableTrackingBuffer.default(1 + 2 + Buffer.byteLength(parameter.name, 'ucs-2') + 1); | ||
@@ -98,23 +93,7 @@ buffer.writeBVarchar('@' + parameter.name); | ||
if (parameter.cryptoMetadata) { | ||
statusFlags |= STATUS.ENCRYPTED_VALUE; | ||
} | ||
buffer.writeUInt8(statusFlags); | ||
yield buffer.data; | ||
if (parameter.cryptoMetadata) { | ||
yield* this._generateEncryptedParameter(parameter); | ||
} else { | ||
yield* this.generateParameterData(parameter, true); | ||
} | ||
} | ||
*generateParameterData(parameter, writeValue) { | ||
const buffer = new _writableTrackingBuffer.default(1 + 2 + Buffer.byteLength(parameter.name, 'ucs-2') + 1); | ||
const param = { | ||
value: parameter.value, | ||
cryptoMetadata: parameter.cryptoMetadata | ||
value: parameter.value | ||
}; | ||
yield buffer.data; | ||
const type = parameter.type; | ||
@@ -146,76 +125,7 @@ | ||
const typeINfo = type.generateTypeInfo(param, this.options); | ||
yield typeINfo; | ||
if (writeValue) { | ||
yield type.generateParameterLength(param, this.options); | ||
yield* type.generateParameterData(param, this.options); | ||
} | ||
yield type.generateTypeInfo(param, this.options); | ||
yield type.generateParameterLength(param, this.options); | ||
yield* type.generateParameterData(param, this.options); | ||
} | ||
*_generateEncryptedParameter(parameter) { | ||
const encryptedParam = { | ||
value: parameter.encryptedVal, | ||
type: _varbinary.default, | ||
output: parameter.output, | ||
name: parameter.name, | ||
forceEncrypt: parameter.forceEncrypt | ||
}; | ||
yield* this.generateParameterData(encryptedParam, true); | ||
yield* this.generateParameterData(parameter, false); | ||
yield* this._writeEncryptionMetadata(parameter.cryptoMetadata); | ||
} | ||
_encryptParameters(parameters) { | ||
return new Promise(resolve => { | ||
if (this.options.serverSupportsColumnEncryption === true) { | ||
const promises = []; | ||
for (let i = 0, len = parameters.length; i < len; i++) { | ||
const type = parameters[i].type; | ||
const paramValue = parameters[i].value; | ||
if (parameters[i].cryptoMetadata && paramValue !== undefined && paramValue !== null) { | ||
if (!type.toBuffer) { | ||
throw new Error(`Column encryption error. Cannot convert type ${type.name} to buffer.`); | ||
} | ||
const plainTextBuffer = type.toBuffer(parameters[i], this.options); | ||
if (plainTextBuffer) { | ||
promises.push((0, _keyCrypto.encryptWithKey)(plainTextBuffer, parameters[i].cryptoMetadata, this.options).then(encryptedValue => { | ||
parameters[i].encryptedVal = encryptedValue; | ||
})); | ||
} | ||
} | ||
} | ||
Promise.all(promises).then(() => resolve(parameters)); | ||
} else { | ||
resolve(parameters); | ||
} | ||
}); | ||
} | ||
*_writeEncryptionMetadata(cryptoMetadata) { | ||
if (!cryptoMetadata || !cryptoMetadata.cekEntry || !cryptoMetadata.cekEntry.columnEncryptionKeyValues || cryptoMetadata.cekEntry.columnEncryptionKeyValues.length <= 0) { | ||
throw new Error('Invalid Crypto Metadata in _writeEncryptionMetadata'); | ||
} | ||
const buffer = new _writableTrackingBuffer.default(0); | ||
buffer.writeUInt8(cryptoMetadata.cipherAlgorithmId); | ||
if (cryptoMetadata.cipherAlgorithmId === 0) { | ||
buffer.writeBVarchar(cryptoMetadata.cipherAlgorithmName || ''); | ||
} | ||
buffer.writeUInt8(cryptoMetadata.encryptionType); | ||
buffer.writeUInt32LE(cryptoMetadata.cekEntry.columnEncryptionKeyValues[0].dbId); | ||
buffer.writeUInt32LE(cryptoMetadata.cekEntry.columnEncryptionKeyValues[0].keyId); | ||
buffer.writeUInt32LE(cryptoMetadata.cekEntry.columnEncryptionKeyValues[0].keyVersion); | ||
buffer.writeBuffer(cryptoMetadata.cekEntry.columnEncryptionKeyValues[0].mdVersion); | ||
buffer.writeUInt8(cryptoMetadata.normalizationRuleVersion[0]); | ||
yield buffer.data; | ||
} | ||
} | ||
@@ -222,0 +132,0 @@ |
@@ -13,8 +13,2 @@ "use strict"; | ||
}); | ||
Object.defineProperty(exports, "ColumnEncryptionAzureKeyVaultProvider", { | ||
enumerable: true, | ||
get: function () { | ||
return _keystoreProviderAzureKeyVault.ColumnEncryptionAzureKeyVaultProvider; | ||
} | ||
}); | ||
Object.defineProperty(exports, "Connection", { | ||
@@ -66,4 +60,2 @@ enumerable: true, | ||
var _keystoreProviderAzureKeyVault = require("./always-encrypted/keystore-provider-azure-key-vault"); | ||
var _connection = _interopRequireDefault(require("./connection")); | ||
@@ -70,0 +62,0 @@ |
@@ -10,4 +10,2 @@ "use strict"; | ||
var _cekEntry = require("../always-encrypted/cek-entry"); | ||
var _token = require("./token"); | ||
@@ -62,173 +60,24 @@ | ||
function readCryptoMetadataOrdinal(parser, cekList, callback) { | ||
if (cekList) { | ||
parser.readUInt16LE(ordinal => { | ||
callback(ordinal); | ||
}); | ||
} else { | ||
callback(0); | ||
} | ||
} | ||
function readCryptoMetadata(parser, metadata, cekList, options, callback) { | ||
if (options.serverSupportsColumnEncryption === true && 0x0800 === (metadata.flags & 0x0800)) { | ||
readCryptoMetadataOrdinal(parser, cekList, ordinal => { | ||
(0, _metadataParser.default)(parser, options, metadata => { | ||
parser.readUInt8(algorithmId => { | ||
readCustomEncryptionMetadata(parser, algorithmId, algorithmName => { | ||
parser.readUInt8(encryptionType => { | ||
parser.readBuffer(1, normalizationRuleVersion => { | ||
callback({ | ||
cekEntry: cekList ? cekList[ordinal] : undefined, | ||
ordinal, | ||
cipherAlgorithmId: algorithmId, | ||
cipherAlgorithmName: algorithmName, | ||
encryptionType: encryptionType, | ||
normalizationRuleVersion, | ||
baseTypeInfo: metadata | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}, false); | ||
}); | ||
} else { | ||
callback(); | ||
} | ||
} | ||
function readCustomEncryptionMetadata(parser, algorithmId, callback) { | ||
if (algorithmId === 0) { | ||
parser.readUInt8(nameSize => { | ||
parser.readBuffer(nameSize, algorithmNameBuffer => { | ||
const algorithmName = algorithmNameBuffer.toString('ucs2'); | ||
callback(algorithmName); | ||
}); | ||
}); | ||
} else { | ||
callback(''); | ||
} | ||
} | ||
function readColumn(parser, options, index, cekList, callback) { | ||
function readColumn(parser, options, index, callback) { | ||
(0, _metadataParser.default)(parser, options, metadata => { | ||
readTableName(parser, options, metadata, tableName => { | ||
readCryptoMetadata(parser, metadata, cekList, options, cryptoMetadata => { | ||
if (cryptoMetadata && cryptoMetadata.baseTypeInfo) { | ||
cryptoMetadata.baseTypeInfo.flags = metadata.flags; | ||
metadata.collation = cryptoMetadata.baseTypeInfo.collation; | ||
} | ||
readColumnName(parser, options, index, metadata, colName => { | ||
callback({ | ||
userType: metadata.userType, | ||
flags: metadata.flags, | ||
type: metadata.type, | ||
collation: metadata.collation, | ||
precision: metadata.precision, | ||
scale: metadata.scale, | ||
udtInfo: metadata.udtInfo, | ||
dataLength: metadata.dataLength, | ||
schema: metadata.schema, | ||
colName: colName, | ||
tableName: tableName, | ||
cryptoMetadata: options.serverSupportsColumnEncryption === true ? cryptoMetadata : undefined | ||
}); | ||
readColumnName(parser, options, index, metadata, colName => { | ||
callback({ | ||
userType: metadata.userType, | ||
flags: metadata.flags, | ||
type: metadata.type, | ||
collation: metadata.collation, | ||
precision: metadata.precision, | ||
scale: metadata.scale, | ||
udtInfo: metadata.udtInfo, | ||
dataLength: metadata.dataLength, | ||
schema: metadata.schema, | ||
colName: colName, | ||
tableName: tableName | ||
}); | ||
}); | ||
}); | ||
}, true); | ||
} | ||
function readCEKTable(parser, options, callback) { | ||
if (options.serverSupportsColumnEncryption === true) { | ||
parser.readUInt16LE(tableSize => { | ||
if (tableSize > 0) { | ||
const cekList = []; | ||
let i = 0; | ||
function next(done) { | ||
if (i === tableSize) { | ||
return done(); | ||
} | ||
readCEKTableEntry(parser, cekEntry => { | ||
cekList.push(cekEntry); | ||
i++; | ||
next(done); | ||
}); | ||
} | ||
next(() => { | ||
callback(cekList); | ||
}); | ||
} else { | ||
callback(); | ||
} | ||
}); | ||
} else { | ||
return callback(); | ||
} | ||
} | ||
function readCEKTableEntry(parser, callback) { | ||
parser.readUInt32LE(databaseId => { | ||
parser.readUInt32LE(cekId => { | ||
parser.readUInt32LE(cekVersion => { | ||
parser.readBuffer(8, cekMdVersion => { | ||
parser.readUInt8(cekValueCount => { | ||
const cekEntry = new _cekEntry.CEKEntry(cekValueCount); | ||
let i = 0; | ||
function next(done) { | ||
if (i === cekValueCount) { | ||
return done(); | ||
} | ||
readCEKValue(parser, cekEntry, { | ||
databaseId, | ||
cekId, | ||
cekVersion, | ||
cekMdVersion | ||
}, () => { | ||
i++; | ||
next(done); | ||
}); | ||
} | ||
next(() => { | ||
callback(cekEntry); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
} | ||
function readCEKValue(parser, cekEntry, cekTableEntryMetadata, callback) { | ||
parser.readUInt16LE(encryptedCEKLength => { | ||
parser.readBuffer(encryptedCEKLength, encryptedCEK => { | ||
parser.readUInt8(keyStoreNameLength => { | ||
parser.readBuffer(2 * keyStoreNameLength, keyStoreNameBuffer => { | ||
const keyStoreName = keyStoreNameBuffer.toString('ucs2'); | ||
parser.readUInt8(keyPathLength => { | ||
parser.readBuffer(2 * keyPathLength, keyPathBuffer => { | ||
const keyPath = keyPathBuffer.swap16().toString('ucs2'); | ||
parser.readUInt16BE(algorithmNameLength => { | ||
parser.readBuffer(2 * algorithmNameLength, algorithmNameBuffer => { | ||
const algorithmName = algorithmNameBuffer.toString('ucs2'); | ||
cekEntry.add(encryptedCEK, cekTableEntryMetadata.databaseId, cekTableEntryMetadata.cekId, cekTableEntryMetadata.cekVersion, cekTableEntryMetadata.cekMdVersion, keyPath, keyStoreName, algorithmName); | ||
callback(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
} | ||
async function colMetadataParser(parser) { | ||
@@ -241,14 +90,2 @@ while (parser.buffer.length - parser.position < 2) { | ||
parser.position += 2; | ||
let cekList; | ||
readCEKTable(parser, parser.options, c => { | ||
cekList = c; | ||
}); | ||
while (parser.suspended) { | ||
await parser.streamBuffer.waitForChunk(); | ||
parser.suspended = false; | ||
const next = parser.next; | ||
next(); | ||
} | ||
const columns = []; | ||
@@ -258,3 +95,3 @@ | ||
let column; | ||
readColumn(parser, parser.options, i, cekList, c => { | ||
readColumn(parser, parser.options, i, c => { | ||
column = c; | ||
@@ -261,0 +98,0 @@ }); |
@@ -23,3 +23,2 @@ "use strict"; | ||
let utf8Support; | ||
let columnEncryption; | ||
@@ -29,3 +28,3 @@ function next() { | ||
if (featureId === FEATURE_ID.TERMINATOR) { | ||
return callback(new _token.FeatureExtAckToken(fedAuth, utf8Support, columnEncryption)); | ||
return callback(new _token.FeatureExtAckToken(fedAuth, utf8Support)); | ||
} | ||
@@ -43,18 +42,2 @@ | ||
break; | ||
case FEATURE_ID.COLUMNENCRYPTION: | ||
{ | ||
if (1 > featureData.length) { | ||
throw new Error(`Unsupported featureDataLength ${featureData.length} for feature type ${featureId}`); | ||
} | ||
const supportedTceVersion = featureData[0]; | ||
if (0 === supportedTceVersion || supportedTceVersion > 0x01) { | ||
throw new Error(`Unsupported TceVersion ${supportedTceVersion}`); | ||
} | ||
columnEncryption = true; | ||
break; | ||
} | ||
} | ||
@@ -61,0 +44,0 @@ |
@@ -38,4 +38,2 @@ "use strict"; | ||
var _keyCrypto = require("../always-encrypted/key-crypto"); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -70,3 +68,2 @@ | ||
async waitForChunk() { | ||
// console.log('waiting for chunk') | ||
const result = await this.iterator.next(); | ||
@@ -76,5 +73,4 @@ | ||
throw new Error('unexpected end of data'); | ||
} // console.log('>> wait for chunk done!') | ||
} | ||
if (this.position === this.buffer.length) { | ||
@@ -102,7 +98,2 @@ this.buffer = result.value; | ||
parser.colMetadata = colMetadata; | ||
await Promise.all(parser.colMetadata.map(async metadata => { | ||
if (metadata.cryptoMetadata) { | ||
await (0, _keyCrypto.decryptSymmetricKey)(metadata.cryptoMetadata, options); | ||
} | ||
})); | ||
@@ -129,7 +120,2 @@ while (true) { | ||
parser.colMetadata = token.columns; | ||
await Promise.all(parser.colMetadata.map(async metadata => { | ||
if (metadata.cryptoMetadata) { | ||
await (0, _keyCrypto.decryptSymmetricKey)(metadata.cryptoMetadata, options); | ||
} | ||
})); | ||
} | ||
@@ -146,13 +132,4 @@ | ||
if (type === _token.TYPE.COLMETADATA) { | ||
// console.log('>> entering colmetadataParser') | ||
const token = await (0, _colmetadataTokenParser.default)(parser); // console.log('>> done colMetadataParser, starting Promise.all(decryptSymmetricKey)..') | ||
parser.colMetadata = token.columns; // console.log('colMetdata list = ', parser.colMetadata) | ||
await Promise.all(parser.colMetadata.map(async metadata => { | ||
if (metadata.cryptoMetadata) { | ||
await (0, _keyCrypto.decryptSymmetricKey)(metadata.cryptoMetadata, options); | ||
} | ||
})); // console.log('>>> done Promise.all(decryptSymmetricKey)') | ||
const token = await (0, _colmetadataTokenParser.default)(parser); | ||
parser.colMetadata = token.columns; | ||
yield token; | ||
@@ -166,15 +143,8 @@ } else if (type === _token.TYPE.ROW) { | ||
if (!parser.suspended) { | ||
if (token) { | ||
if (token instanceof _token.ColMetadataToken) { | ||
parser.colMetadata = token.columns; | ||
await Promise.all(parser.colMetadata.map(async metadata => { | ||
if (metadata.cryptoMetadata) { | ||
await (0, _keyCrypto.decryptSymmetricKey)(metadata.cryptoMetadata, options); | ||
} | ||
})); | ||
} | ||
if (!parser.suspended && token) { | ||
if (token instanceof _token.ColMetadataToken) { | ||
parser.colMetadata = token.columns; | ||
} | ||
yield token; | ||
} | ||
yield token; | ||
} | ||
@@ -193,4 +163,2 @@ } else { | ||
this.suspended = void 0; | ||
this.processingQueue = void 0; | ||
this.readyToEnd = void 0; | ||
this.next = void 0; | ||
@@ -200,10 +168,6 @@ this.streamBuffer = void 0; | ||
this.colMetadata = []; | ||
this.options = options; // this.buffer = Buffer.alloc(0); | ||
// this.position = 0; | ||
this.options = options; | ||
this.streamBuffer = streamBuffer; | ||
this.suspended = false; | ||
this.next = undefined; | ||
this.readyToEnd = false; | ||
this.processingQueue = 0; | ||
} | ||
@@ -224,3 +188,2 @@ | ||
suspend(next) { | ||
// console.log('suspending') | ||
this.suspended = true; | ||
@@ -492,274 +455,4 @@ this.next = next; | ||
}); | ||
} // ------------------------ TEMP ASYNC ------------------------------ | ||
async suspend_async(next) { | ||
await this.streamBuffer.waitForChunk(); | ||
next(); | ||
} | ||
awaitData_async(length, callback) { | ||
if (this.position + length <= this.buffer.length) { | ||
callback(); | ||
} else { | ||
this.suspend_async(() => { | ||
this.awaitData_async(length, callback); | ||
}); | ||
} | ||
} | ||
readInt8_async(callback) { | ||
this.awaitData_async(1, () => { | ||
const data = this.buffer.readInt8(this.position); | ||
this.position += 1; | ||
callback(data); | ||
}); | ||
} | ||
readUInt8_async(callback) { | ||
this.awaitData_async(1, () => { | ||
const data = this.buffer.readUInt8(this.position); | ||
this.position += 1; | ||
callback(data); | ||
}); | ||
} | ||
readInt16LE_async(callback) { | ||
this.awaitData_async(2, () => { | ||
const data = this.buffer.readInt16LE(this.position); | ||
this.position += 2; | ||
callback(data); | ||
}); | ||
} | ||
readInt16BE_async(callback) { | ||
this.awaitData_async(2, () => { | ||
const data = this.buffer.readInt16BE(this.position); | ||
this.position += 2; | ||
callback(data); | ||
}); | ||
} | ||
readUInt16LE_async(callback) { | ||
this.awaitData_async(2, () => { | ||
const data = this.buffer.readUInt16LE(this.position); | ||
this.position += 2; | ||
callback(data); | ||
}); | ||
} | ||
readUInt16BE_async(callback) { | ||
this.awaitData_async(2, () => { | ||
const data = this.buffer.readUInt16BE(this.position); | ||
this.position += 2; | ||
callback(data); | ||
}); | ||
} | ||
readInt32LE_async(callback) { | ||
this.awaitData_async(4, () => { | ||
const data = this.buffer.readInt32LE(this.position); | ||
this.position += 4; | ||
callback(data); | ||
}); | ||
} | ||
readInt32BE_async(callback) { | ||
this.awaitData_async(4, () => { | ||
const data = this.buffer.readInt32BE(this.position); | ||
this.position += 4; | ||
callback(data); | ||
}); | ||
} | ||
readUInt32LE_async(callback) { | ||
this.awaitData_async(4, () => { | ||
const data = this.buffer.readUInt32LE(this.position); | ||
this.position += 4; | ||
callback(data); | ||
}); | ||
} | ||
readUInt32BE_async(callback) { | ||
this.awaitData_async(4, () => { | ||
const data = this.buffer.readUInt32BE(this.position); | ||
this.position += 4; | ||
callback(data); | ||
}); | ||
} | ||
readBigInt64LE_async(callback) { | ||
this.awaitData_async(8, () => { | ||
const result = _jsbi.default.add(_jsbi.default.leftShift(_jsbi.default.BigInt(this.buffer[this.position + 4] + this.buffer[this.position + 5] * 2 ** 8 + this.buffer[this.position + 6] * 2 ** 16 + (this.buffer[this.position + 7] << 24) // Overflow | ||
), _jsbi.default.BigInt(32)), _jsbi.default.BigInt(this.buffer[this.position] + this.buffer[this.position + 1] * 2 ** 8 + this.buffer[this.position + 2] * 2 ** 16 + this.buffer[this.position + 3] * 2 ** 24)); | ||
this.position += 8; | ||
callback(result); | ||
}); | ||
} | ||
readInt64LE_async(callback) { | ||
this.awaitData_async(8, () => { | ||
const data = Math.pow(2, 32) * this.buffer.readInt32LE(this.position + 4) + ((this.buffer[this.position + 4] & 0x80) === 0x80 ? 1 : -1) * this.buffer.readUInt32LE(this.position); | ||
this.position += 8; | ||
callback(data); | ||
}); | ||
} | ||
readInt64BE_async(callback) { | ||
this.awaitData_async(8, () => { | ||
const data = Math.pow(2, 32) * this.buffer.readInt32BE(this.position) + ((this.buffer[this.position] & 0x80) === 0x80 ? 1 : -1) * this.buffer.readUInt32BE(this.position + 4); | ||
this.position += 8; | ||
callback(data); | ||
}); | ||
} | ||
readBigUInt64LE_async(callback) { | ||
this.awaitData_async(8, () => { | ||
const low = _jsbi.default.BigInt(this.buffer.readUInt32LE(this.position)); | ||
const high = _jsbi.default.BigInt(this.buffer.readUInt32LE(this.position + 4)); | ||
this.position += 8; | ||
callback(_jsbi.default.add(low, _jsbi.default.leftShift(high, _jsbi.default.BigInt(32)))); | ||
}); | ||
} | ||
readUInt64LE_async(callback) { | ||
this.awaitData_async(8, () => { | ||
const data = Math.pow(2, 32) * this.buffer.readUInt32LE(this.position + 4) + this.buffer.readUInt32LE(this.position); | ||
this.position += 8; | ||
callback(data); | ||
}); | ||
} | ||
readUInt64BE_async(callback) { | ||
this.awaitData_async(8, () => { | ||
const data = Math.pow(2, 32) * this.buffer.readUInt32BE(this.position) + this.buffer.readUInt32BE(this.position + 4); | ||
this.position += 8; | ||
callback(data); | ||
}); | ||
} | ||
readFloatLE_async(callback) { | ||
this.awaitData_async(4, () => { | ||
const data = this.buffer.readFloatLE(this.position); | ||
this.position += 4; | ||
callback(data); | ||
}); | ||
} | ||
readFloatBE_async(callback) { | ||
this.awaitData_async(4, () => { | ||
const data = this.buffer.readFloatBE(this.position); | ||
this.position += 4; | ||
callback(data); | ||
}); | ||
} | ||
readDoubleLE_async(callback) { | ||
this.awaitData_async(8, () => { | ||
const data = this.buffer.readDoubleLE(this.position); | ||
this.position += 8; | ||
callback(data); | ||
}); | ||
} | ||
readDoubleBE_async(callback) { | ||
this.awaitData_async(8, () => { | ||
const data = this.buffer.readDoubleBE(this.position); | ||
this.position += 8; | ||
callback(data); | ||
}); | ||
} | ||
readUInt24LE_async(callback) { | ||
this.awaitData_async(3, () => { | ||
const low = this.buffer.readUInt16LE(this.position); | ||
const high = this.buffer.readUInt8(this.position + 2); | ||
this.position += 3; | ||
callback(low | high << 16); | ||
}); | ||
} | ||
readUInt40LE_async(callback) { | ||
this.awaitData_async(5, () => { | ||
const low = this.buffer.readUInt32LE(this.position); | ||
const high = this.buffer.readUInt8(this.position + 4); | ||
this.position += 5; | ||
callback(0x100000000 * high + low); | ||
}); | ||
} | ||
readUNumeric64LE_async(callback) { | ||
this.awaitData_async(8, () => { | ||
const low = this.buffer.readUInt32LE(this.position); | ||
const high = this.buffer.readUInt32LE(this.position + 4); | ||
this.position += 8; | ||
callback(0x100000000 * high + low); | ||
}); | ||
} | ||
readUNumeric96LE_async(callback) { | ||
this.awaitData_async(12, () => { | ||
const dword1 = this.buffer.readUInt32LE(this.position); | ||
const dword2 = this.buffer.readUInt32LE(this.position + 4); | ||
const dword3 = this.buffer.readUInt32LE(this.position + 8); | ||
this.position += 12; | ||
callback(dword1 + 0x100000000 * dword2 + 0x100000000 * 0x100000000 * dword3); | ||
}); | ||
} | ||
readUNumeric128LE_async(callback) { | ||
this.awaitData_async(16, () => { | ||
const dword1 = this.buffer.readUInt32LE(this.position); | ||
const dword2 = this.buffer.readUInt32LE(this.position + 4); | ||
const dword3 = this.buffer.readUInt32LE(this.position + 8); | ||
const dword4 = this.buffer.readUInt32LE(this.position + 12); | ||
this.position += 16; | ||
callback(dword1 + 0x100000000 * dword2 + 0x100000000 * 0x100000000 * dword3 + 0x100000000 * 0x100000000 * 0x100000000 * dword4); | ||
}); | ||
} // Variable length data | ||
readBuffer_async(length, callback) { | ||
this.awaitData_async(length, () => { | ||
const data = this.buffer.slice(this.position, this.position + length); | ||
this.position += length; | ||
callback(data); | ||
}); | ||
} // Read a Unicode String (BVARCHAR) | ||
readBVarChar_async(callback) { | ||
this.readUInt8(length => { | ||
this.readBuffer(length * 2, data => { | ||
callback(data.toString('ucs2')); | ||
}); | ||
}); | ||
} // Read a Unicode String (USVARCHAR) | ||
readUsVarChar_async(callback) { | ||
this.readUInt16LE(length => { | ||
this.readBuffer(length * 2, data => { | ||
callback(data.toString('ucs2')); | ||
}); | ||
}); | ||
} // Read binary data (BVARBYTE) | ||
readBVarByte_async(callback) { | ||
this.readUInt8(length => { | ||
this.readBuffer(length, callback); | ||
}); | ||
} // Read binary data (USVARBYTE) | ||
readUsVarByte_async(callback) { | ||
this.readUInt16LE(length => { | ||
this.readBuffer(length, callback); | ||
}); | ||
} | ||
} | ||
@@ -766,0 +459,0 @@ |
@@ -26,3 +26,2 @@ "use strict"; | ||
this.parser.on('data', token => { | ||
// console.log(token); | ||
if (token.event) { | ||
@@ -29,0 +28,0 @@ this.emit(token.event, token); |
@@ -312,10 +312,8 @@ "use strict"; | ||
* undefined when UTF8_SUPPORT not included in token. */ | ||
constructor(fedAuth, utf8Support, columnEncryption) { | ||
constructor(fedAuth, utf8Support) { | ||
super('FEATUREEXTACK', 'featureExtAck'); | ||
this.fedAuth = void 0; | ||
this.columnEncryption = void 0; | ||
this.utf8Support = void 0; | ||
this.fedAuth = fedAuth; | ||
this.utf8Support = utf8Support; | ||
this.columnEncryption = columnEncryption; | ||
} | ||
@@ -322,0 +320,0 @@ |
@@ -12,6 +12,2 @@ "use strict"; | ||
var _jsbi = _interopRequireDefault(require("jsbi")); | ||
var _events = require("events"); | ||
var _iconvLite = _interopRequireDefault(require("iconv-lite")); | ||
@@ -23,4 +19,2 @@ | ||
var _keyCrypto = require("./always-encrypted/key-crypto"); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
@@ -219,6 +213,2 @@ | ||
case 'Binary': | ||
if (metadata.cryptoMetadata) { | ||
return readEncryptedBinary(parser, metadata, options, callback); | ||
} | ||
if (metadata.dataLength === MAX) { | ||
@@ -748,503 +738,4 @@ return readMaxBinary(parser, callback); | ||
class PreBufferedParser extends _events.EventEmitter { | ||
constructor(buffer) { | ||
super(); | ||
this.buffer = void 0; | ||
this.position = void 0; | ||
this.buffer = buffer; | ||
this.position = 0; | ||
} | ||
readInt8(callback) { | ||
const data = this.buffer.readInt8(this.position); | ||
this.position += 1; | ||
callback(data); | ||
} | ||
readUInt8(callback) { | ||
const data = this.buffer.readUInt8(this.position); | ||
this.position += 1; | ||
callback(data); | ||
} | ||
readInt16LE(callback) { | ||
const data = this.buffer.readInt16LE(this.position); | ||
this.position += 2; | ||
callback(data); | ||
} | ||
readInt16BE(callback) { | ||
const data = this.buffer.readInt16BE(this.position); | ||
this.position += 2; | ||
callback(data); | ||
} | ||
readUInt16LE(callback) { | ||
const data = this.buffer.readUInt16LE(this.position); | ||
this.position += 2; | ||
callback(data); | ||
} | ||
readUInt16BE(callback) { | ||
const data = this.buffer.readUInt16BE(this.position); | ||
this.position += 2; | ||
callback(data); | ||
} | ||
readInt32LE(callback) { | ||
const data = this.buffer.readInt32LE(this.position); | ||
this.position += 4; | ||
callback(data); | ||
} | ||
readInt32BE(callback) { | ||
const data = this.buffer.readInt32BE(this.position); | ||
this.position += 4; | ||
callback(data); | ||
} | ||
readUInt32LE(callback) { | ||
const data = this.buffer.readUInt32LE(this.position); | ||
this.position += 4; | ||
callback(data); | ||
} | ||
readUInt32BE(callback) { | ||
const data = this.buffer.readUInt32BE(this.position); | ||
this.position += 4; | ||
callback(data); | ||
} | ||
readBigInt64LE(callback) { | ||
const result = _jsbi.default.add(_jsbi.default.leftShift(_jsbi.default.BigInt(this.buffer[this.position + 4] + this.buffer[this.position + 5] * 2 ** 8 + this.buffer[this.position + 6] * 2 ** 16 + (this.buffer[this.position + 7] << 24) // Overflow | ||
), _jsbi.default.BigInt(32)), _jsbi.default.BigInt(this.buffer[this.position] + this.buffer[this.position + 1] * 2 ** 8 + this.buffer[this.position + 2] * 2 ** 16 + this.buffer[this.position + 3] * 2 ** 24)); | ||
this.position += 8; | ||
callback(result); | ||
} | ||
readInt64LE(callback) { | ||
const data = Math.pow(2, 32) * this.buffer.readInt32LE(this.position + 4) + ((this.buffer[this.position + 4] & 0x80) === 0x80 ? 1 : -1) * this.buffer.readUInt32LE(this.position); | ||
this.position += 8; | ||
callback(data); | ||
} | ||
readInt64BE(callback) { | ||
const data = Math.pow(2, 32) * this.buffer.readInt32BE(this.position) + ((this.buffer[this.position] & 0x80) === 0x80 ? 1 : -1) * this.buffer.readUInt32BE(this.position + 4); | ||
this.position += 8; | ||
callback(data); | ||
} | ||
readBigUInt64LE(callback) { | ||
const low = _jsbi.default.BigInt(this.buffer.readUInt32LE(this.position)); | ||
const high = _jsbi.default.BigInt(this.buffer.readUInt32LE(this.position + 4)); | ||
this.position += 8; | ||
callback(_jsbi.default.add(low, _jsbi.default.leftShift(high, _jsbi.default.BigInt(32)))); | ||
} | ||
readUInt64LE(callback) { | ||
const data = Math.pow(2, 32) * this.buffer.readUInt32LE(this.position + 4) + this.buffer.readUInt32LE(this.position); | ||
this.position += 8; | ||
callback(data); | ||
} | ||
readUInt64BE(callback) { | ||
const data = Math.pow(2, 32) * this.buffer.readUInt32BE(this.position) + this.buffer.readUInt32BE(this.position + 4); | ||
this.position += 8; | ||
callback(data); | ||
} | ||
readFloatLE(callback) { | ||
const data = this.buffer.readFloatLE(this.position); | ||
this.position += 4; | ||
callback(data); | ||
} | ||
readFloatBE(callback) { | ||
const data = this.buffer.readFloatBE(this.position); | ||
this.position += 4; | ||
callback(data); | ||
} | ||
readDoubleLE(callback) { | ||
const data = this.buffer.readDoubleLE(this.position); | ||
this.position += 8; | ||
callback(data); | ||
} | ||
readDoubleBE(callback) { | ||
const data = this.buffer.readDoubleBE(this.position); | ||
this.position += 8; | ||
callback(data); | ||
} | ||
readUInt24LE(callback) { | ||
const low = this.buffer.readUInt16LE(this.position); | ||
const high = this.buffer.readUInt8(this.position + 2); | ||
this.position += 3; | ||
callback(low | high << 16); | ||
} | ||
readUInt40LE(callback) { | ||
const low = this.buffer.readUInt32LE(this.position); | ||
const high = this.buffer.readUInt8(this.position + 4); | ||
this.position += 5; | ||
callback(0x100000000 * high + low); | ||
} | ||
readUNumeric64LE(callback) { | ||
const low = this.buffer.readUInt32LE(this.position); | ||
const high = this.buffer.readUInt32LE(this.position + 4); | ||
this.position += 8; | ||
callback(0x100000000 * high + low); | ||
} | ||
readUNumeric96LE(callback) { | ||
const dword1 = this.buffer.readUInt32LE(this.position); | ||
const dword2 = this.buffer.readUInt32LE(this.position + 4); | ||
const dword3 = this.buffer.readUInt32LE(this.position + 8); | ||
this.position += 12; | ||
callback(dword1 + 0x100000000 * dword2 + 0x100000000 * 0x100000000 * dword3); | ||
} | ||
readUNumeric128LE(callback) { | ||
const dword1 = this.buffer.readUInt32LE(this.position); | ||
const dword2 = this.buffer.readUInt32LE(this.position + 4); | ||
const dword3 = this.buffer.readUInt32LE(this.position + 8); | ||
const dword4 = this.buffer.readUInt32LE(this.position + 12); | ||
this.position += 16; | ||
callback(dword1 + 0x100000000 * dword2 + 0x100000000 * 0x100000000 * dword3 + 0x100000000 * 0x100000000 * 0x100000000 * dword4); | ||
} // Variable length data | ||
readBuffer(length, callback) { | ||
const data = this.buffer.slice(this.position, this.position + length); | ||
this.position += length; | ||
callback(data); | ||
} // Read a Unicode String (BVARCHAR) | ||
readBVarChar(callback) { | ||
// read the length and buffer separately to ensure it awaits data correctly | ||
this.readUInt8(length => { | ||
this.readBuffer(length * 2, data => { | ||
callback(data.toString('ucs2')); | ||
}); | ||
}); | ||
} // Read a Unicode String (USVARCHAR) | ||
readUsVarChar(callback) { | ||
// read the length and buffer separately to ensure it awaits data correctly | ||
this.readUInt16LE(length => { | ||
this.readBuffer(length * 2, data => { | ||
callback(data.toString('ucs2')); | ||
}); | ||
}); | ||
} // Read binary data (BVARBYTE) | ||
readBVarByte(callback) { | ||
// read the length and buffer separately to ensure it awaits data correctly | ||
this.readUInt8(length => { | ||
this.readBuffer(length, callback); | ||
}); | ||
} // Read binary data (USVARBYTE) | ||
readUsVarByte(callback) { | ||
// read the length and buffer separately to ensure it awaits data correctly | ||
this.readUInt16LE(length => { | ||
this.readBuffer(length, callback); | ||
}); | ||
} | ||
} | ||
function readEncryptedBinary(parser, metadata, options, callback) { | ||
const cryptoMetadata = metadata.cryptoMetadata; // console.log('>!@ metadata', metadata) | ||
const { | ||
normalizationRuleVersion | ||
} = cryptoMetadata; | ||
const baseMetadata = cryptoMetadata.baseTypeInfo; | ||
if (!normalizationRuleVersion.equals(Buffer.from([0x01]))) { | ||
throw new Error(`Normalization version "${normalizationRuleVersion[0]}" received from SQL Server is either invalid or corrupted. Valid normalization versions are: ${0x01}.`); | ||
} | ||
const isNullValue = (decryptedValue, metadata) => { | ||
switch (metadata.type.name) { | ||
case 'VarChar': | ||
case 'Char': | ||
case 'NVarChar': | ||
case 'NChar': | ||
case 'VarBinary': | ||
case 'Binary': | ||
return metadata.dataLength === MAX && decryptedValue.equals(PLP_NULL); | ||
} | ||
return false; | ||
}; | ||
const callbackDecrypted = decryptedValue => { | ||
if (isNullValue(decryptedValue, baseMetadata)) { | ||
return callback(null); | ||
} | ||
const bufferedParser = new PreBufferedParser(decryptedValue); | ||
return denormalizedValue(bufferedParser, decryptedValue.length, baseMetadata, options, value => { | ||
return callback(value); | ||
}); | ||
}; | ||
if (metadata.dataLength === MAX) { | ||
return readMaxBinary(parser, encryptedValue => { | ||
callbackDecrypted((0, _keyCrypto.decryptWithKey)(encryptedValue, cryptoMetadata, options)); | ||
}); | ||
} else { | ||
return parser.readUInt16LE(dataLength => { | ||
if (dataLength === NULL) { | ||
return callback(null); | ||
} | ||
readBinary(parser, dataLength, encryptedValue => { | ||
callbackDecrypted((0, _keyCrypto.decryptWithKey)(encryptedValue, cryptoMetadata, options)); | ||
}); | ||
}); | ||
} | ||
} | ||
function denormalizedValue(parser, valueLength, metadata, options, callback) { | ||
// there are a few notes to be aware of in this implementation: | ||
// 1. for most encrypted blobs, the metadata data-length will not match the | ||
// decrypted value-length, so the parsers here are more lenient for that | ||
// 2. null values are assumed to be handled already, so this implementation | ||
// will denormalize values with the assumption that it is non-null | ||
// 3. max reads are never applicable to encrypted blobs (except for null | ||
// values, which are not handled here) | ||
// for types that do not have a data length, default to the value length | ||
const dataLength = metadata.dataLength || valueLength; | ||
switch (metadata.type.name) { | ||
case 'Null': | ||
return callback(null); | ||
case 'TinyInt': | ||
return readTinyInt(parser, callback); | ||
case 'SmallInt': | ||
return readSmallInt(parser, callback); | ||
case 'Int': | ||
return readInt(parser, callback); | ||
case 'BigInt': | ||
return readBigInt(parser, callback); | ||
case 'IntN': | ||
switch (dataLength) { | ||
case 0: | ||
return callback(null); | ||
case 1: | ||
return readTinyInt(parser, callback); | ||
case 2: | ||
return readSmallInt(parser, callback); | ||
case 4: | ||
return readInt(parser, callback); | ||
case 8: | ||
return readBigInt(parser, callback); | ||
default: | ||
throw new Error('Unsupported dataLength ' + dataLength + ' for IntN'); | ||
} | ||
case 'Real': | ||
return readReal(parser, callback); | ||
case 'Float': | ||
return readFloat(parser, callback); | ||
case 'FloatN': | ||
switch (dataLength) { | ||
case 0: | ||
return callback(null); | ||
case 4: | ||
return readReal(parser, callback); | ||
case 8: | ||
return readFloat(parser, callback); | ||
default: | ||
throw new Error('Unsupported dataLength ' + dataLength + ' for FloatN'); | ||
} | ||
case 'SmallMoney': | ||
// first 4 bytes on small money are always ignored | ||
return parser.readUInt32LE(() => { | ||
return readSmallMoney(parser, callback); | ||
}); | ||
case 'Money': | ||
return readMoney(parser, callback); | ||
case 'MoneyN': | ||
switch (dataLength) { | ||
case 0: | ||
return callback(null); | ||
case 4: | ||
// first 4 bytes on small money are always ignored | ||
return parser.readUInt32LE(() => { | ||
return readSmallMoney(parser, callback); | ||
}); | ||
case 8: | ||
return readMoney(parser, callback); | ||
default: | ||
throw new Error('Unsupported dataLength ' + dataLength + ' for MoneyN'); | ||
} | ||
case 'Bit': | ||
return readBit(parser, callback); | ||
case 'BitN': | ||
switch (dataLength) { | ||
case 0: | ||
return callback(null); | ||
case 1: | ||
return readBit(parser, callback); | ||
default: | ||
throw new Error('Unsupported dataLength ' + dataLength + ' for BitN'); | ||
} | ||
case 'VarChar': | ||
case 'Char': | ||
{ | ||
const codepage = metadata.collation.codepage; // null is assumed to be handled already, so just parse available chars | ||
return readChars(parser, valueLength, codepage, callback); | ||
} | ||
case 'NVarChar': | ||
case 'NChar': | ||
// null is assumed to be handled already, so just parse available nchars | ||
return readNChars(parser, valueLength, callback); | ||
case 'VarBinary': | ||
case 'Binary': | ||
// null is assumed to be handled already, so just parse available binary | ||
return readBinary(parser, valueLength, callback); | ||
case 'SmallDateTime': | ||
return readSmallDateTime(parser, options.useUTC, callback); | ||
case 'DateTime': | ||
return readDateTime(parser, options.useUTC, callback); | ||
case 'DateTimeN': | ||
switch (dataLength) { | ||
case 0: | ||
return callback(null); | ||
case 4: | ||
return readSmallDateTime(parser, options.useUTC, callback); | ||
case 8: | ||
return readDateTime(parser, options.useUTC, callback); | ||
default: | ||
new Error('Unsupported dataLength ' + dataLength + ' for DateTimeN'); | ||
} | ||
break; | ||
case 'Time': | ||
// no padding to worry about for Time, since it has no dataLength | ||
if (dataLength === 0) { | ||
return callback(null); | ||
} else { | ||
return readTime(parser, dataLength, metadata.scale, options.useUTC, callback); | ||
} | ||
case 'Date': | ||
// no padding to worry about for Date, since it has no dataLength | ||
if (dataLength === 0) { | ||
return callback(null); | ||
} else { | ||
return readDate(parser, options.useUTC, callback); | ||
} | ||
case 'DateTime2': | ||
// no padding to worry about for DateTime2, since it has no dataLength | ||
if (dataLength === 0) { | ||
return callback(null); | ||
} else { | ||
return readDateTime2(parser, dataLength, metadata.scale, options.useUTC, callback); | ||
} | ||
case 'DateTimeOffset': | ||
// no padding to worry about for DateTimeOffset, since it has no dataLength | ||
if (dataLength === 0) { | ||
return callback(null); | ||
} else { | ||
return readDateTimeOffset(parser, dataLength, metadata.scale, callback); | ||
} | ||
case 'NumericN': | ||
case 'DecimalN': | ||
if (dataLength === 0) { | ||
return callback(null); | ||
} else { | ||
// encrypted value has variable length, usually fixed in chunks of 8 | ||
// the denormalize handler needs to handle any arbitrary valueLength | ||
const magnitudeSize = valueLength - 1; | ||
const scale = metadata.scale; | ||
return parser.readUInt8(signByte => { | ||
const sign = signByte === 0x01 ? 1 : -1; | ||
return parser.readBuffer(magnitudeSize, data => { | ||
const value = data.reduceRight((acc, byte) => acc * (1 << 8) + byte); | ||
return callback(value * sign / Math.pow(10, scale)); | ||
}); | ||
}); | ||
} | ||
case 'UniqueIdentifier': | ||
// no padding to worry about for UniqueIdentifier, since it has no padding | ||
switch (dataLength) { | ||
case 0: | ||
return callback(null); | ||
case 0x10: | ||
return readUniqueIdentifier(parser, options, callback); | ||
default: | ||
throw new Error((0, _sprintfJs.sprintf)('Unsupported guid size %d', dataLength - 1)); | ||
} | ||
case 'Text': | ||
case 'NText': | ||
case 'Image': | ||
case 'Xml': | ||
case 'UDT': | ||
case 'Variant': | ||
throw new Error((0, _sprintfJs.sprintf)('Unsupported encrypted type %s', metadata.type.name)); | ||
default: | ||
throw new Error((0, _sprintfJs.sprintf)('Unrecognised type %s', metadata.type.name)); | ||
} | ||
} | ||
var _default = valueParse; | ||
exports.default = _default; | ||
module.exports = valueParse; |
@@ -30,3 +30,3 @@ { | ||
"license": "MIT", | ||
"version": "12.3.0-alpha.1", | ||
"version": "12.3.0", | ||
"main": "./lib/tedious.js", | ||
@@ -51,3 +51,2 @@ "repository": { | ||
"depd": "^2.0.0", | ||
"lru-cache": "^5.1.1", | ||
"iconv-lite": "^0.6.3", | ||
@@ -98,5 +97,5 @@ "jsbi": "^3.2.1", | ||
"lint": "eslint src test --ext .js,.ts && tsc", | ||
"test": "mocha 'test/unit/**/*.{ts,js}'", | ||
"test-integration": "mocha 'test/integration/**/*.{ts,js}'", | ||
"test-all": "mocha 'test/**/*.{ts,js}'", | ||
"test": "mocha test/unit test/unit/token test/unit/tracking-buffer", | ||
"test-integration": "mocha test/integration/", | ||
"test-all": "mocha test/unit/ test/unit/token/ test/unit/tracking-buffer test/integration/", | ||
"build": "rimraf lib && babel src --out-dir lib --extensions .js,.ts", | ||
@@ -103,0 +102,0 @@ "prepublish": "npm run build", |
Sorry, the diff of this file is too big to display
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
13
0
487259
119
13402
11
- Removedlru-cache@^5.1.1
- Removedlru-cache@5.1.1(transitive)
- Removedyallist@3.1.1(transitive)