Socket
Socket
Sign inDemoInstall

pg-protocol

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

pg-protocol - npm Package Compare versions

Comparing version 1.2.1 to 1.2.2

2

dist/b.js
"use strict";
// file for microbenchmarking
// file for microbenchmarking
Object.defineProperty(exports, "__esModule", { value: true });

@@ -4,0 +4,0 @@ const buffer_writer_1 = require("./buffer-writer");

@@ -39,3 +39,2 @@ "use strict";

while (this.buffer[end++] !== 0) { }
;
this.offset = end;

@@ -42,0 +41,0 @@ return this.buffer.toString(this.encoding, start, end - 1);

@@ -24,6 +24,6 @@ "use strict";

this.ensure(4);
this.buffer[this.offset++] = (num >>> 24 & 0xFF);
this.buffer[this.offset++] = (num >>> 16 & 0xFF);
this.buffer[this.offset++] = (num >>> 8 & 0xFF);
this.buffer[this.offset++] = (num >>> 0 & 0xFF);
this.buffer[this.offset++] = (num >>> 24) & 0xff;
this.buffer[this.offset++] = (num >>> 16) & 0xff;
this.buffer[this.offset++] = (num >>> 8) & 0xff;
this.buffer[this.offset++] = (num >>> 0) & 0xff;
return this;

@@ -33,4 +33,4 @@ }

this.ensure(2);
this.buffer[this.offset++] = (num >>> 8 & 0xFF);
this.buffer[this.offset++] = (num >>> 0 & 0xFF);
this.buffer[this.offset++] = (num >>> 8) & 0xff;
this.buffer[this.offset++] = (num >>> 0) & 0xff;
return this;

@@ -51,3 +51,3 @@ }

}
addString(string = "") {
addString(string = '') {
var len = Buffer.byteLength(string);

@@ -54,0 +54,0 @@ this.ensure(len);

@@ -29,3 +29,4 @@ "use strict";

var addRow = function (bufferList, name, offset) {
return bufferList.addCString(name) // field name
return bufferList
.addCString(name) // field name
.addInt32(offset++) // table id

@@ -45,7 +46,9 @@ .addInt16(offset++) // attribute of column number

typeModifier: 5,
formatCode: 0
formatCode: 0,
};
var oneRowDescBuff = test_buffers_1.default.rowDescription([row1]);
row1.name = 'bang';
var twoRowBuf = test_buffers_1.default.rowDescription([row1, {
var twoRowBuf = test_buffers_1.default.rowDescription([
row1,
{
name: 'whoah',

@@ -57,7 +60,6 @@ tableID: 10,

typeModifier: 14,
formatCode: 0
}]);
var emptyRowFieldBuf = new buffer_list_1.default()
.addInt16(0)
.join(true, 'D');
formatCode: 0,
},
]);
var emptyRowFieldBuf = new buffer_list_1.default().addInt16(0).join(true, 'D');
var emptyRowFieldBuf = test_buffers_1.default.dataRow([]);

@@ -72,3 +74,3 @@ var oneFieldBuf = new buffer_list_1.default()

name: 'authenticationOk',
length: 8
length: 8,
};

@@ -79,3 +81,3 @@ var expectedParameterStatusMessage = {

parameterValue: 'UTF8',
length: 25
length: 25,
};

@@ -85,3 +87,3 @@ var expectedBackendKeyDataMessage = {

processID: 1,
secretKey: 2
secretKey: 2,
};

@@ -91,3 +93,3 @@ var expectedReadyForQueryMessage = {

length: 5,
status: 'I'
status: 'I',
};

@@ -97,3 +99,3 @@ var expectedCommandCompleteMessage = {

length: 13,
text: 'SELECT 3'
text: 'SELECT 3',
};

@@ -113,3 +115,4 @@ var emptyRowDescriptionBuffer = new buffer_list_1.default()

fieldCount: 1,
fields: [{
fields: [
{
name: 'id',

@@ -121,4 +124,5 @@ tableID: 1,

dataTypeModifier: 5,
format: 'text'
}]
format: 'text',
},
],
};

@@ -129,3 +133,4 @@ var expectedTwoRowMessage = {

fieldCount: 2,
fields: [{
fields: [
{
name: 'bang',

@@ -137,3 +142,3 @@ tableID: 1,

dataTypeModifier: 5,
format: 'text'
format: 'text',
},

@@ -147,4 +152,5 @@ {

dataTypeModifier: 14,
format: 'text'
}]
format: 'text',
},
],
};

@@ -166,11 +172,11 @@ var testForMessage = function (buffer, expectedMessage) {

var expectedPlainPasswordMessage = {
name: 'authenticationCleartextPassword'
name: 'authenticationCleartextPassword',
};
var expectedMD5PasswordMessage = {
name: 'authenticationMD5Password',
salt: Buffer.from([1, 2, 3, 4])
salt: Buffer.from([1, 2, 3, 4]),
};
var expectedSASLMessage = {
name: 'authenticationSASL',
mechanisms: ['SCRAM-SHA-256']
mechanisms: ['SCRAM-SHA-256'],
};

@@ -190,3 +196,3 @@ var expectedSASLContinueMessage = {

channel: 'hi',
payload: 'boom'
payload: 'boom',
};

@@ -220,3 +226,3 @@ const parseBuffers = (buffers) => __awaiter(void 0, void 0, void 0, function* () {

testForMessage(Buffer.from([0x6e, 0, 0, 0, 4]), {
name: 'noData'
name: 'noData',
});

@@ -232,3 +238,3 @@ describe('rowDescription messages', function () {

name: 'dataRow',
fieldCount: 0
fieldCount: 0,
});

@@ -240,3 +246,3 @@ });

fieldCount: 1,
fields: ['test']
fields: ['test'],
});

@@ -250,49 +256,63 @@ });

name: 'notice',
code: 'code'
code: 'code',
});
});
testForMessage(test_buffers_1.default.error([]), {
name: 'error'
name: 'error',
});
describe('with all the fields', function () {
var buffer = test_buffers_1.default.error([{
var buffer = test_buffers_1.default.error([
{
type: 'S',
value: 'ERROR'
}, {
value: 'ERROR',
},
{
type: 'C',
value: 'code'
}, {
value: 'code',
},
{
type: 'M',
value: 'message'
}, {
value: 'message',
},
{
type: 'D',
value: 'details'
}, {
value: 'details',
},
{
type: 'H',
value: 'hint'
}, {
value: 'hint',
},
{
type: 'P',
value: '100'
}, {
value: '100',
},
{
type: 'p',
value: '101'
}, {
value: '101',
},
{
type: 'q',
value: 'query'
}, {
value: 'query',
},
{
type: 'W',
value: 'where'
}, {
value: 'where',
},
{
type: 'F',
value: 'file'
}, {
value: 'file',
},
{
type: 'L',
value: 'line'
}, {
value: 'line',
},
{
type: 'R',
value: 'routine'
}, {
value: 'routine',
},
{
type: 'Z',
value: 'alsdkf'
}]);
value: 'alsdkf',
},
]);
testForMessage(buffer, {

@@ -311,20 +331,20 @@ name: 'error',

line: 'line',
routine: 'routine'
routine: 'routine',
});
});
testForMessage(parseCompleteBuffer, {
name: 'parseComplete'
name: 'parseComplete',
});
testForMessage(bindCompleteBuffer, {
name: 'bindComplete'
name: 'bindComplete',
});
testForMessage(bindCompleteBuffer, {
name: 'bindComplete'
name: 'bindComplete',
});
testForMessage(test_buffers_1.default.closeComplete(), {
name: 'closeComplete'
name: 'closeComplete',
});
describe('parses portal suspended message', function () {
testForMessage(portalSuspendedBuffer, {
name: 'portalSuspended'
name: 'portalSuspended',
});

@@ -335,3 +355,3 @@ });

name: 'replicationStart',
length: 4
length: 4,
});

@@ -344,3 +364,3 @@ });

binary: false,
columnTypes: []
columnTypes: [],
});

@@ -351,3 +371,3 @@ testForMessage(test_buffers_1.default.copyIn(2), {

binary: false,
columnTypes: [0, 1]
columnTypes: [0, 1],
});

@@ -358,3 +378,3 @@ testForMessage(test_buffers_1.default.copyOut(0), {

binary: false,
columnTypes: []
columnTypes: [],
});

@@ -365,3 +385,3 @@ testForMessage(test_buffers_1.default.copyOut(3), {

binary: false,
columnTypes: [0, 1, 2]
columnTypes: [0, 1, 2],
});

@@ -375,3 +395,3 @@ testForMessage(test_buffers_1.default.copyDone(), {

length: 7,
chunk: Buffer.from([5, 6, 7])
chunk: Buffer.from([5, 6, 7]),
});

@@ -436,3 +456,3 @@ });

length: 11,
fields: ['!']
fields: ['!'],
});

@@ -443,3 +463,3 @@ assert_1.default.equal(messages[0].fields[0], '!');

length: 5,
status: 'I'
status: 'I',
});

@@ -472,10 +492,7 @@ };

splitAndVerifyTwoMessages(fullBuffer.length - 4),
splitAndVerifyTwoMessages(fullBuffer.length - 6)
splitAndVerifyTwoMessages(fullBuffer.length - 6),
]);
});
it('at the end', function () {
return Promise.all([
splitAndVerifyTwoMessages(8),
splitAndVerifyTwoMessages(1)
]);
return Promise.all([splitAndVerifyTwoMessages(8), splitAndVerifyTwoMessages(1)]);
});

@@ -482,0 +499,0 @@ });

@@ -17,3 +17,3 @@ "use strict";

name: "noData" /* noData */,
length: 5
length: 5,
};

@@ -20,0 +20,0 @@ exports.portalSuspended = {

@@ -13,3 +13,3 @@ "use strict";

user: 'brian',
database: 'bang'
database: 'bang',
});

@@ -25,3 +25,4 @@ assert_1.default.deepEqual(actual, new buffer_list_1.default()

.addCString("'utf-8'")
.addCString('').join(true));
.addCString('')
.join(true));
});

@@ -53,6 +54,3 @@ it('builds password message', function () {

const actual = serializer_1.serialize.parse({ text: '!' });
var expected = new buffer_list_1.default()
.addCString('')
.addCString('!')
.addInt16(0).join(true, 'P');
var expected = new buffer_list_1.default().addCString('').addCString('!').addInt16(0).join(true, 'P');
assert_1.default.deepEqual(actual, expected);

@@ -64,8 +62,5 @@ });

text: 'select * from boom',
types: []
types: [],
});
var expected = new buffer_list_1.default()
.addCString('boom')
.addCString('select * from boom')
.addInt16(0).join(true, 'P');
var expected = new buffer_list_1.default().addCString('boom').addCString('select * from boom').addInt16(0).join(true, 'P');
assert_1.default.deepEqual(actual, expected);

@@ -77,3 +72,3 @@ });

text: 'select * from bang where name = $1',
types: [1, 2, 3, 4]
types: [1, 2, 3, 4],
});

@@ -87,3 +82,4 @@ var expected = new buffer_list_1.default()

.addInt32(3)
.addInt32(4).join(true, 'P');
.addInt32(4)
.join(true, 'P');
assert_1.default.deepEqual(actual, expected);

@@ -108,3 +104,3 @@ });

statement: 'woo',
values: ['1', 'hi', null, 'zing']
values: ['1', 'hi', null, 'zing'],
});

@@ -132,3 +128,3 @@ var expectedBuffer = new buffer_list_1.default()

statement: 'woo',
values: ['1', 'hi', null, Buffer.from('zing', 'utf8')]
values: ['1', 'hi', null, Buffer.from('zing', 'utf8')],
});

@@ -158,6 +154,3 @@ var expectedBuffer = new buffer_list_1.default()

const actual = serializer_1.serialize.execute();
var expectedBuffer = new buffer_list_1.default()
.addCString('')
.addInt32(0)
.join(true, 'E');
var expectedBuffer = new buffer_list_1.default().addCString('').addInt32(0).join(true, 'E');
assert_1.default.deepEqual(actual, expectedBuffer);

@@ -168,8 +161,5 @@ });

portal: 'my favorite portal',
rows: 100
rows: 100,
});
var expectedBuffer = new buffer_list_1.default()
.addCString('my favorite portal')
.addInt32(100)
.join(true, 'E');
var expectedBuffer = new buffer_list_1.default().addCString('my favorite portal').addInt32(100).join(true, 'E');
assert_1.default.deepEqual(actual, expectedBuffer);

@@ -176,0 +166,0 @@ });

@@ -34,3 +34,3 @@ "use strict";

let offset = 0;
while ((offset + HEADER_LENGTH) <= combinedBuffer.byteLength) {
while (offset + HEADER_LENGTH <= combinedBuffer.byteLength) {
// code is 1 byte long - it identifies the message type

@@ -240,3 +240,5 @@ const code = combinedBuffer[offset];

const messageValue = fields.M;
const message = name === "notice" /* notice */ ? new messages_1.NoticeMessage(length, messageValue) : new messages_1.DatabaseError(messageValue, length, name);
const message = name === "notice" /* notice */
? new messages_1.NoticeMessage(length, messageValue)
: new messages_1.DatabaseError(messageValue, length, name);
message.severity = fields.S;

@@ -243,0 +245,0 @@ message.code = fields.C;

@@ -15,6 +15,3 @@ "use strict";

var length = bodyBuffer.length + 4;
return new buffer_writer_1.Writer()
.addInt32(length)
.add(bodyBuffer)
.flush();
return new buffer_writer_1.Writer().addInt32(length).add(bodyBuffer).flush();
};

@@ -32,6 +29,3 @@ const requestSsl = () => {

// 0x70 = 'p'
writer
.addCString(mechanism)
.addInt32(Buffer.byteLength(initialResponse))
.addString(initialResponse);
writer.addCString(mechanism).addInt32(Buffer.byteLength(initialResponse)).addString(initialResponse);
return writer.flush(112 /* startup */);

@@ -83,5 +77,3 @@ };

}
var buffer = writer
.addCString(portal)
.addCString(statement);
var buffer = writer.addCString(portal).addCString(statement);
if (!useBinary) {

@@ -123,3 +115,3 @@ buffer.addInt16(0);

// this is the happy path for most queries
if (!config || !config.portal && !config.rows) {
if (!config || (!config.portal && !config.rows)) {
return emptyExecute;

@@ -163,7 +155,7 @@ }

const describe = (msg) => {
return msg.name ?
cstringMessage(68 /* describe */, `${msg.type}${msg.name || ''}`) :
msg.type === 'P' ?
emptyDescribePortal :
emptyDescribeStatement;
return msg.name
? cstringMessage(68 /* describe */, `${msg.type}${msg.name || ''}`)
: msg.type === 'P'
? emptyDescribePortal
: emptyDescribeStatement;
};

@@ -203,5 +195,5 @@ const close = (msg) => {

copyFail,
cancel
cancel,
};
exports.serialize = serialize;
//# sourceMappingURL=serializer.js.map

@@ -12,3 +12,3 @@ "use strict";

addInt16(val, front) {
return this.add(Buffer.from([(val >>> 8), (val >>> 0)]), front);
return this.add(Buffer.from([val >>> 8, val >>> 0]), front);
}

@@ -21,8 +21,3 @@ getByteLength(initial) {

addInt32(val, first) {
return this.add(Buffer.from([
(val >>> 24 & 0xFF),
(val >>> 16 & 0xFF),
(val >>> 8 & 0xFF),
(val >>> 0 & 0xFF)
]), first);
return this.add(Buffer.from([(val >>> 24) & 0xff, (val >>> 16) & 0xff, (val >>> 8) & 0xff, (val >>> 0) & 0xff]), first);
}

@@ -29,0 +24,0 @@ addCString(val, front) {

@@ -10,15 +10,9 @@ "use strict";

readyForQuery: function () {
return new buffer_list_1.default()
.add(Buffer.from('I'))
.join(true, 'Z');
return new buffer_list_1.default().add(Buffer.from('I')).join(true, 'Z');
},
authenticationOk: function () {
return new buffer_list_1.default()
.addInt32(0)
.join(true, 'R');
return new buffer_list_1.default().addInt32(0).join(true, 'R');
},
authenticationCleartextPassword: function () {
return new buffer_list_1.default()
.addInt32(3)
.join(true, 'R');
return new buffer_list_1.default().addInt32(3).join(true, 'R');
},

@@ -32,36 +26,18 @@ authenticationMD5Password: function () {

authenticationSASL: function () {
return new buffer_list_1.default()
.addInt32(10)
.addCString('SCRAM-SHA-256')
.addCString('')
.join(true, 'R');
return new buffer_list_1.default().addInt32(10).addCString('SCRAM-SHA-256').addCString('').join(true, 'R');
},
authenticationSASLContinue: function () {
return new buffer_list_1.default()
.addInt32(11)
.addString('data')
.join(true, 'R');
return new buffer_list_1.default().addInt32(11).addString('data').join(true, 'R');
},
authenticationSASLFinal: function () {
return new buffer_list_1.default()
.addInt32(12)
.addString('data')
.join(true, 'R');
return new buffer_list_1.default().addInt32(12).addString('data').join(true, 'R');
},
parameterStatus: function (name, value) {
return new buffer_list_1.default()
.addCString(name)
.addCString(value)
.join(true, 'S');
return new buffer_list_1.default().addCString(name).addCString(value).join(true, 'S');
},
backendKeyData: function (processID, secretKey) {
return new buffer_list_1.default()
.addInt32(processID)
.addInt32(secretKey)
.join(true, 'K');
return new buffer_list_1.default().addInt32(processID).addInt32(secretKey).join(true, 'K');
},
commandComplete: function (string) {
return new buffer_list_1.default()
.addCString(string)
.join(true, 'C');
return new buffer_list_1.default().addCString(string).join(true, 'C');
},

@@ -73,3 +49,4 @@ rowDescription: function (fields) {

fields.forEach(function (field) {
buf.addCString(field.name)
buf
.addCString(field.name)
.addInt32(field.tableID || 0)

@@ -122,7 +99,3 @@ .addInt16(field.attributeNumber || 0)

notification: function (id, channel, payload) {
return new buffer_list_1.default()
.addInt32(id)
.addCString(channel)
.addCString(payload)
.join(true, 'A');
return new buffer_list_1.default().addInt32(id).addCString(channel).addCString(payload).join(true, 'A');
},

@@ -165,5 +138,5 @@ emptyQuery: function () {

return new buffer_list_1.default().join(true, 'c');
}
},
};
exports.default = buffers;
//# sourceMappingURL=test-buffers.js.map
{
"name": "pg-protocol",
"version": "1.2.1",
"version": "1.2.2",
"description": "The postgres client/server binary protocol, implemented in TypeScript",

@@ -25,3 +25,3 @@ "main": "dist/index.js",

},
"gitHead": "da03b3f9050c85a7722413a03c199cc3bdbcf5bf"
"gitHead": "35328807e3612cb267bee86dccb2551ad186624a"
}

@@ -1,2 +0,2 @@

// file for microbenchmarking
// file for microbenchmarking

@@ -18,6 +18,6 @@ import { Writer } from './buffer-writer'

console.log(Date.now() - start)
return;
return
}
count++
for(let i = 0; i < LOOPS; i++) {
for (let i = 0; i < LOOPS; i++) {
reader.setBuffer(0, buffer)

@@ -24,0 +24,0 @@ reader.cstring()

@@ -1,54 +0,53 @@

const emptyBuffer = Buffer.allocUnsafe(0);
const emptyBuffer = Buffer.allocUnsafe(0)
export class BufferReader {
private buffer: Buffer = emptyBuffer;
private buffer: Buffer = emptyBuffer
// TODO(bmc): support non-utf8 encoding?
private encoding: string = 'utf-8';
private encoding: string = 'utf-8'
constructor(private offset: number = 0) {
}
constructor(private offset: number = 0) {}
public setBuffer(offset: number, buffer: Buffer): void {
this.offset = offset;
this.buffer = buffer;
this.offset = offset
this.buffer = buffer
}
public int16(): number {
const result = this.buffer.readInt16BE(this.offset);
this.offset += 2;
return result;
const result = this.buffer.readInt16BE(this.offset)
this.offset += 2
return result
}
public byte(): number {
const result = this.buffer[this.offset];
this.offset++;
return result;
const result = this.buffer[this.offset]
this.offset++
return result
}
public int32(): number {
const result = this.buffer.readInt32BE(this.offset);
this.offset += 4;
return result;
const result = this.buffer.readInt32BE(this.offset)
this.offset += 4
return result
}
public string(length: number): string {
const result = this.buffer.toString(this.encoding, this.offset, this.offset + length);
this.offset += length;
return result;
const result = this.buffer.toString(this.encoding, this.offset, this.offset + length)
this.offset += length
return result
}
public cstring(): string {
const start = this.offset;
const start = this.offset
let end = start
while(this.buffer[end++] !== 0) { };
this.offset = end;
return this.buffer.toString(this.encoding, start, end - 1);
while (this.buffer[end++] !== 0) {}
this.offset = end
return this.buffer.toString(this.encoding, start, end - 1)
}
public bytes(length: number): Buffer {
const result = this.buffer.slice(this.offset, this.offset + length);
this.offset += length;
return result;
const result = this.buffer.slice(this.offset, this.offset + length)
this.offset += length
return result
}
}
//binary data writer tuned for encoding binary specific to the postgres binary protocol
export class Writer {
private buffer: Buffer;
private offset: number = 5;
private headerPosition: number = 0;
private buffer: Buffer
private offset: number = 5
private headerPosition: number = 0
constructor(private size = 256) {

@@ -12,10 +12,10 @@ this.buffer = Buffer.alloc(size)

private ensure(size: number): void {
var remaining = this.buffer.length - this.offset;
var remaining = this.buffer.length - this.offset
if (remaining < size) {
var oldBuffer = this.buffer;
var oldBuffer = this.buffer
// exponential growth factor of around ~ 1.5
// https://stackoverflow.com/questions/2269063/buffer-growth-strategy
var newSize = oldBuffer.length + (oldBuffer.length >> 1) + size;
this.buffer = Buffer.alloc(newSize);
oldBuffer.copy(this.buffer);
var newSize = oldBuffer.length + (oldBuffer.length >> 1) + size
this.buffer = Buffer.alloc(newSize)
oldBuffer.copy(this.buffer)
}

@@ -25,45 +25,44 @@ }

public addInt32(num: number): Writer {
this.ensure(4);
this.buffer[this.offset++] = (num >>> 24 & 0xFF);
this.buffer[this.offset++] = (num >>> 16 & 0xFF);
this.buffer[this.offset++] = (num >>> 8 & 0xFF);
this.buffer[this.offset++] = (num >>> 0 & 0xFF);
return this;
this.ensure(4)
this.buffer[this.offset++] = (num >>> 24) & 0xff
this.buffer[this.offset++] = (num >>> 16) & 0xff
this.buffer[this.offset++] = (num >>> 8) & 0xff
this.buffer[this.offset++] = (num >>> 0) & 0xff
return this
}
public addInt16(num: number): Writer {
this.ensure(2);
this.buffer[this.offset++] = (num >>> 8 & 0xFF);
this.buffer[this.offset++] = (num >>> 0 & 0xFF);
return this;
this.ensure(2)
this.buffer[this.offset++] = (num >>> 8) & 0xff
this.buffer[this.offset++] = (num >>> 0) & 0xff
return this
}
public addCString(string: string): Writer {
if (!string) {
this.ensure(1);
this.ensure(1)
} else {
var len = Buffer.byteLength(string);
this.ensure(len + 1); // +1 for null terminator
var len = Buffer.byteLength(string)
this.ensure(len + 1) // +1 for null terminator
this.buffer.write(string, this.offset, 'utf-8')
this.offset += len;
this.offset += len
}
this.buffer[this.offset++] = 0; // null terminator
return this;
this.buffer[this.offset++] = 0 // null terminator
return this
}
public addString(string: string = ""): Writer {
var len = Buffer.byteLength(string);
this.ensure(len);
this.buffer.write(string, this.offset);
this.offset += len;
return this;
public addString(string: string = ''): Writer {
var len = Buffer.byteLength(string)
this.ensure(len)
this.buffer.write(string, this.offset)
this.offset += len
return this
}
public add(otherBuffer: Buffer): Writer {
this.ensure(otherBuffer.length);
otherBuffer.copy(this.buffer, this.offset);
this.offset += otherBuffer.length;
return this;
this.ensure(otherBuffer.length)
otherBuffer.copy(this.buffer, this.offset)
this.offset += otherBuffer.length
return this
}

@@ -73,3 +72,3 @@

if (code) {
this.buffer[this.headerPosition] = code;
this.buffer[this.headerPosition] = code
//length is everything in this packet minus the code

@@ -79,13 +78,12 @@ const length = this.offset - (this.headerPosition + 1)

}
return this.buffer.slice(code ? 0 : 5, this.offset);
return this.buffer.slice(code ? 0 : 5, this.offset)
}
public flush(code?: number): Buffer {
var result = this.join(code);
this.offset = 5;
this.headerPosition = 0;
var result = this.join(code)
this.offset = 5
this.headerPosition = 0
this.buffer = Buffer.allocUnsafe(this.size)
return result;
return result
}
}

@@ -18,3 +18,4 @@ import buffers from './testing/test-buffers'

var addRow = function (bufferList: BufferList, name: string, offset: number) {
return bufferList.addCString(name) // field name
return bufferList
.addCString(name) // field name
.addInt32(offset++) // table id

@@ -35,3 +36,3 @@ .addInt16(offset++) // attribute of column number

typeModifier: 5,
formatCode: 0
formatCode: 0,
}

@@ -41,15 +42,16 @@ var oneRowDescBuff = buffers.rowDescription([row1])

var twoRowBuf = buffers.rowDescription([row1, {
name: 'whoah',
tableID: 10,
attributeNumber: 11,
dataTypeID: 12,
dataTypeSize: 13,
typeModifier: 14,
formatCode: 0
}])
var twoRowBuf = buffers.rowDescription([
row1,
{
name: 'whoah',
tableID: 10,
attributeNumber: 11,
dataTypeID: 12,
dataTypeSize: 13,
typeModifier: 14,
formatCode: 0,
},
])
var emptyRowFieldBuf = new BufferList()
.addInt16(0)
.join(true, 'D')
var emptyRowFieldBuf = new BufferList().addInt16(0).join(true, 'D')

@@ -68,3 +70,3 @@ var emptyRowFieldBuf = buffers.dataRow([])

name: 'authenticationOk',
length: 8
length: 8,
}

@@ -76,3 +78,3 @@

parameterValue: 'UTF8',
length: 25
length: 25,
}

@@ -83,3 +85,3 @@

processID: 1,
secretKey: 2
secretKey: 2,
}

@@ -90,3 +92,3 @@

length: 5,
status: 'I'
status: 'I',
}

@@ -97,3 +99,3 @@

length: 13,
text: 'SELECT 3'
text: 'SELECT 3',
}

@@ -114,11 +116,13 @@ var emptyRowDescriptionBuffer = new BufferList()

fieldCount: 1,
fields: [{
name: 'id',
tableID: 1,
columnID: 2,
dataTypeID: 3,
dataTypeSize: 4,
dataTypeModifier: 5,
format: 'text'
}]
fields: [
{
name: 'id',
tableID: 1,
columnID: 2,
dataTypeID: 3,
dataTypeSize: 4,
dataTypeModifier: 5,
format: 'text',
},
],
}

@@ -130,20 +134,22 @@

fieldCount: 2,
fields: [{
name: 'bang',
tableID: 1,
columnID: 2,
dataTypeID: 3,
dataTypeSize: 4,
dataTypeModifier: 5,
format: 'text'
},
{
name: 'whoah',
tableID: 10,
columnID: 11,
dataTypeID: 12,
dataTypeSize: 13,
dataTypeModifier: 14,
format: 'text'
}]
fields: [
{
name: 'bang',
tableID: 1,
columnID: 2,
dataTypeID: 3,
dataTypeSize: 4,
dataTypeModifier: 5,
format: 'text',
},
{
name: 'whoah',
tableID: 10,
columnID: 11,
dataTypeID: 12,
dataTypeSize: 13,
dataTypeModifier: 14,
format: 'text',
},
],
}

@@ -154,3 +160,3 @@

const messages = await parseBuffers([buffer])
const [lastMessage] = messages;
const [lastMessage] = messages

@@ -170,3 +176,3 @@ for (const key in expectedMessage) {

var expectedPlainPasswordMessage = {
name: 'authenticationCleartextPassword'
name: 'authenticationCleartextPassword',
}

@@ -176,3 +182,3 @@

name: 'authenticationMD5Password',
salt: Buffer.from([1, 2, 3, 4])
salt: Buffer.from([1, 2, 3, 4]),
}

@@ -182,3 +188,3 @@

name: 'authenticationSASL',
mechanisms: ['SCRAM-SHA-256']
mechanisms: ['SCRAM-SHA-256'],
}

@@ -201,11 +207,9 @@

channel: 'hi',
payload: 'boom'
payload: 'boom',
}
const parseBuffers = async (buffers: Buffer[]): Promise<BackendMessage[]> => {
const stream = new PassThrough();
const stream = new PassThrough()
for (const buffer of buffers) {
stream.write(buffer);
stream.write(buffer)
}

@@ -237,3 +241,3 @@ stream.end()

testForMessage(Buffer.from([0x6e, 0, 0, 0, 4]), {
name: 'noData'
name: 'noData',
})

@@ -251,3 +255,3 @@

name: 'dataRow',
fieldCount: 0
fieldCount: 0,
})

@@ -260,3 +264,3 @@ })

fieldCount: 1,
fields: ['test']
fields: ['test'],
})

@@ -271,3 +275,3 @@ })

name: 'notice',
code: 'code'
code: 'code',
})

@@ -277,46 +281,60 @@ })

testForMessage(buffers.error([]), {
name: 'error'
name: 'error',
})
describe('with all the fields', function () {
var buffer = buffers.error([{
type: 'S',
value: 'ERROR'
}, {
type: 'C',
value: 'code'
}, {
type: 'M',
value: 'message'
}, {
type: 'D',
value: 'details'
}, {
type: 'H',
value: 'hint'
}, {
type: 'P',
value: '100'
}, {
type: 'p',
value: '101'
}, {
type: 'q',
value: 'query'
}, {
type: 'W',
value: 'where'
}, {
type: 'F',
value: 'file'
}, {
type: 'L',
value: 'line'
}, {
type: 'R',
value: 'routine'
}, {
type: 'Z', // ignored
value: 'alsdkf'
}])
var buffer = buffers.error([
{
type: 'S',
value: 'ERROR',
},
{
type: 'C',
value: 'code',
},
{
type: 'M',
value: 'message',
},
{
type: 'D',
value: 'details',
},
{
type: 'H',
value: 'hint',
},
{
type: 'P',
value: '100',
},
{
type: 'p',
value: '101',
},
{
type: 'q',
value: 'query',
},
{
type: 'W',
value: 'where',
},
{
type: 'F',
value: 'file',
},
{
type: 'L',
value: 'line',
},
{
type: 'R',
value: 'routine',
},
{
type: 'Z', // ignored
value: 'alsdkf',
},
])

@@ -336,3 +354,3 @@ testForMessage(buffer, {

line: 'line',
routine: 'routine'
routine: 'routine',
})

@@ -342,15 +360,15 @@ })

testForMessage(parseCompleteBuffer, {
name: 'parseComplete'
name: 'parseComplete',
})
testForMessage(bindCompleteBuffer, {
name: 'bindComplete'
name: 'bindComplete',
})
testForMessage(bindCompleteBuffer, {
name: 'bindComplete'
name: 'bindComplete',
})
testForMessage(buffers.closeComplete(), {
name: 'closeComplete'
name: 'closeComplete',
})

@@ -360,3 +378,3 @@

testForMessage(portalSuspendedBuffer, {
name: 'portalSuspended'
name: 'portalSuspended',
})

@@ -368,3 +386,3 @@ })

name: 'replicationStart',
length: 4
length: 4,
})

@@ -378,3 +396,3 @@ })

binary: false,
columnTypes: []
columnTypes: [],
})

@@ -386,3 +404,3 @@

binary: false,
columnTypes: [0, 1]
columnTypes: [0, 1],
})

@@ -394,3 +412,3 @@

binary: false,
columnTypes: []
columnTypes: [],
})

@@ -402,3 +420,3 @@

binary: false,
columnTypes: [0, 1, 2]
columnTypes: [0, 1, 2],
})

@@ -414,7 +432,6 @@

length: 7,
chunk: Buffer.from([5, 6, 7])
chunk: Buffer.from([5, 6, 7]),
})
})
// since the data message on a stream can randomly divide the incomming

@@ -427,3 +444,3 @@ // tcp packets anywhere, we need to make sure we can parse every single

it('parses when full buffer comes in', async function () {
const messages = await parseBuffers([fullBuffer]);
const messages = await parseBuffers([fullBuffer])
const message = messages[0] as any

@@ -443,3 +460,3 @@ assert.equal(message.fields.length, 5)

fullBuffer.copy(secondBuffer, 0, firstBuffer.length)
const messages = await parseBuffers([fullBuffer]);
const messages = await parseBuffers([fullBuffer])
const message = messages[0] as any

@@ -482,3 +499,3 @@ assert.equal(message.fields.length, 5)

length: 11,
fields: ['!']
fields: ['!'],
})

@@ -489,3 +506,3 @@ assert.equal(messages[0].fields[0], '!')

length: 5,
status: 'I'
status: 'I',
})

@@ -516,3 +533,3 @@ }

splitAndVerifyTwoMessages(fullBuffer.length - 4),
splitAndVerifyTwoMessages(fullBuffer.length - 6)
splitAndVerifyTwoMessages(fullBuffer.length - 6),
])

@@ -522,10 +539,6 @@ })

it('at the end', function () {
return Promise.all([
splitAndVerifyTwoMessages(8),
splitAndVerifyTwoMessages(1)
])
return Promise.all([splitAndVerifyTwoMessages(8), splitAndVerifyTwoMessages(1)])
})
})
})
})

@@ -1,3 +0,3 @@

import { BackendMessage } from './messages';
import { serialize } from './serializer';
import { BackendMessage } from './messages'
import { serialize } from './serializer'
import { Parser, MessageCallback } from './parser'

@@ -11,2 +11,2 @@

export { serialize };
export { serialize }

@@ -1,2 +0,2 @@

export type Mode = 'text' | 'binary';
export type Mode = 'text' | 'binary'

@@ -33,4 +33,4 @@ export const enum MessageName {

export interface BackendMessage {
name: MessageName;
length: number;
name: MessageName
length: number
}

@@ -41,3 +41,3 @@

length: 5,
};
}

@@ -56,3 +56,3 @@ export const bindComplete: BackendMessage = {

name: MessageName.noData,
length: 5
length: 5,
}

@@ -81,38 +81,38 @@

interface NoticeOrError {
message: string | undefined;
severity: string | undefined;
code: string | undefined;
detail: string | undefined;
hint: string | undefined;
position: string | undefined;
internalPosition: string | undefined;
internalQuery: string | undefined;
where: string | undefined;
schema: string | undefined;
table: string | undefined;
column: string | undefined;
dataType: string | undefined;
constraint: string | undefined;
file: string | undefined;
line: string | undefined;
routine: string | undefined;
message: string | undefined
severity: string | undefined
code: string | undefined
detail: string | undefined
hint: string | undefined
position: string | undefined
internalPosition: string | undefined
internalQuery: string | undefined
where: string | undefined
schema: string | undefined
table: string | undefined
column: string | undefined
dataType: string | undefined
constraint: string | undefined
file: string | undefined
line: string | undefined
routine: string | undefined
}
export class DatabaseError extends Error implements NoticeOrError {
public severity: string | undefined;
public code: string | undefined;
public detail: string | undefined;
public hint: string | undefined;
public position: string | undefined;
public internalPosition: string | undefined;
public internalQuery: string | undefined;
public where: string | undefined;
public schema: string | undefined;
public table: string | undefined;
public column: string | undefined;
public dataType: string | undefined;
public constraint: string | undefined;
public file: string | undefined;
public line: string | undefined;
public routine: string | undefined;
public severity: string | undefined
public code: string | undefined
public detail: string | undefined
public hint: string | undefined
public position: string | undefined
public internalPosition: string | undefined
public internalQuery: string | undefined
public where: string | undefined
public schema: string | undefined
public table: string | undefined
public column: string | undefined
public dataType: string | undefined
public constraint: string | undefined
public file: string | undefined
public line: string | undefined
public routine: string | undefined
constructor(message: string, public readonly length: number, public readonly name: MessageName) {

@@ -124,12 +124,15 @@ super(message)

export class CopyDataMessage {
public readonly name = MessageName.copyData;
constructor(public readonly length: number, public readonly chunk: Buffer) {
}
public readonly name = MessageName.copyData
constructor(public readonly length: number, public readonly chunk: Buffer) {}
}
export class CopyResponse {
public readonly columnTypes: number[];
constructor(public readonly length: number, public readonly name: MessageName, public readonly binary: boolean, columnCount: number) {
this.columnTypes = new Array(columnCount);
public readonly columnTypes: number[]
constructor(
public readonly length: number,
public readonly name: MessageName,
public readonly binary: boolean,
columnCount: number
) {
this.columnTypes = new Array(columnCount)
}

@@ -139,9 +142,16 @@ }

export class Field {
constructor(public readonly name: string, public readonly tableID: number, public readonly columnID: number, public readonly dataTypeID: number, public readonly dataTypeSize: number, public readonly dataTypeModifier: number, public readonly format: Mode) {
}
constructor(
public readonly name: string,
public readonly tableID: number,
public readonly columnID: number,
public readonly dataTypeID: number,
public readonly dataTypeSize: number,
public readonly dataTypeModifier: number,
public readonly format: Mode
) {}
}
export class RowDescriptionMessage {
public readonly name: MessageName = MessageName.rowDescription;
public readonly fields: Field[];
public readonly name: MessageName = MessageName.rowDescription
public readonly fields: Field[]
constructor(public readonly length: number, public readonly fieldCount: number) {

@@ -153,30 +163,33 @@ this.fields = new Array(this.fieldCount)

export class ParameterStatusMessage {
public readonly name: MessageName = MessageName.parameterStatus;
constructor(public readonly length: number, public readonly parameterName: string, public readonly parameterValue: string) {
}
public readonly name: MessageName = MessageName.parameterStatus
constructor(
public readonly length: number,
public readonly parameterName: string,
public readonly parameterValue: string
) {}
}
export class AuthenticationMD5Password implements BackendMessage {
public readonly name: MessageName = MessageName.authenticationMD5Password;
constructor(public readonly length: number, public readonly salt: Buffer) {
}
public readonly name: MessageName = MessageName.authenticationMD5Password
constructor(public readonly length: number, public readonly salt: Buffer) {}
}
export class BackendKeyDataMessage {
public readonly name: MessageName = MessageName.backendKeyData;
constructor(public readonly length: number, public readonly processID: number, public readonly secretKey: number) {
}
public readonly name: MessageName = MessageName.backendKeyData
constructor(public readonly length: number, public readonly processID: number, public readonly secretKey: number) {}
}
export class NotificationResponseMessage {
public readonly name: MessageName = MessageName.notification;
constructor(public readonly length: number, public readonly processId: number, public readonly channel: string, public readonly payload: string) {
}
public readonly name: MessageName = MessageName.notification
constructor(
public readonly length: number,
public readonly processId: number,
public readonly channel: string,
public readonly payload: string
) {}
}
export class ReadyForQueryMessage {
public readonly name: MessageName = MessageName.readyForQuery;
constructor(public readonly length: number, public readonly status: string) {
}
public readonly name: MessageName = MessageName.readyForQuery
constructor(public readonly length: number, public readonly status: string) {}
}

@@ -186,11 +199,10 @@

public readonly name: MessageName = MessageName.commandComplete
constructor(public readonly length: number, public readonly text: string) {
}
constructor(public readonly length: number, public readonly text: string) {}
}
export class DataRowMessage {
public readonly fieldCount: number;
public readonly fieldCount: number
public readonly name: MessageName = MessageName.dataRow
constructor(public length: number, public fields: any[]) {
this.fieldCount = fields.length;
this.fieldCount = fields.length
}

@@ -201,19 +213,19 @@ }

constructor(public readonly length: number, public readonly message: string | undefined) {}
public readonly name = MessageName.notice;
public severity: string | undefined;
public code: string | undefined;
public detail: string | undefined;
public hint: string | undefined;
public position: string | undefined;
public internalPosition: string | undefined;
public internalQuery: string | undefined;
public where: string | undefined;
public schema: string | undefined;
public table: string | undefined;
public column: string | undefined;
public dataType: string | undefined;
public constraint: string | undefined;
public file: string | undefined;
public line: string | undefined;
public routine: string | undefined;
public readonly name = MessageName.notice
public severity: string | undefined
public code: string | undefined
public detail: string | undefined
public hint: string | undefined
public position: string | undefined
public internalPosition: string | undefined
public internalQuery: string | undefined
public where: string | undefined
public schema: string | undefined
public table: string | undefined
public column: string | undefined
public dataType: string | undefined
public constraint: string | undefined
public file: string | undefined
public line: string | undefined
public routine: string | undefined
}

@@ -9,14 +9,18 @@ import assert from 'assert'

user: 'brian',
database: 'bang'
database: 'bang',
})
assert.deepEqual(actual, new BufferList()
.addInt16(3)
.addInt16(0)
.addCString('user')
.addCString('brian')
.addCString('database')
.addCString('bang')
.addCString('client_encoding')
.addCString("'utf-8'")
.addCString('').join(true))
assert.deepEqual(
actual,
new BufferList()
.addInt16(3)
.addInt16(0)
.addCString('user')
.addCString('brian')
.addCString('database')
.addCString('bang')
.addCString('client_encoding')
.addCString("'utf-8'")
.addCString('')
.join(true)
)
})

@@ -32,3 +36,3 @@

const expected = new BufferList().addInt32(80877103).join(true)
assert.deepEqual(actual, expected);
assert.deepEqual(actual, expected)
})

@@ -41,3 +45,2 @@

it('builds SCRAMClientFinalMessage message', function () {

@@ -48,3 +51,2 @@ const actual = serialize.sendSCRAMClientFinalMessage('data')

it('builds query message', function () {

@@ -56,11 +58,6 @@ var txt = 'select * from boom'

describe('parse message', () => {
it('builds parse message', function () {
const actual = serialize.parse({ text: '!' })
var expected = new BufferList()
.addCString('')
.addCString('!')
.addInt16(0).join(true, 'P')
var expected = new BufferList().addCString('').addCString('!').addInt16(0).join(true, 'P')
assert.deepEqual(actual, expected)

@@ -73,8 +70,5 @@ })

text: 'select * from boom',
types: []
types: [],
})
var expected = new BufferList()
.addCString('boom')
.addCString('select * from boom')
.addInt16(0).join(true, 'P')
var expected = new BufferList().addCString('boom').addCString('select * from boom').addInt16(0).join(true, 'P')
assert.deepEqual(actual, expected)

@@ -87,3 +81,3 @@ })

text: 'select * from bang where name = $1',
types: [1, 2, 3, 4]
types: [1, 2, 3, 4],
})

@@ -97,9 +91,8 @@ var expected = new BufferList()

.addInt32(3)
.addInt32(4).join(true, 'P')
.addInt32(4)
.join(true, 'P')
assert.deepEqual(actual, expected)
})
})
describe('bind messages', function () {

@@ -123,6 +116,6 @@ it('with no values', function () {

statement: 'woo',
values: ['1', 'hi', null, 'zing']
values: ['1', 'hi', null, 'zing'],
})
var expectedBuffer = new BufferList()
.addCString('bang') // portal name
.addCString('bang') // portal name
.addCString('woo') // statement name

@@ -148,12 +141,12 @@ .addInt16(0)

statement: 'woo',
values: ['1', 'hi', null, Buffer.from('zing', 'utf8')]
values: ['1', 'hi', null, Buffer.from('zing', 'utf8')],
})
var expectedBuffer = new BufferList()
.addCString('bang') // portal name
.addCString('bang') // portal name
.addCString('woo') // statement name
.addInt16(4)// value count
.addInt16(0)// string
.addInt16(0)// string
.addInt16(0)// string
.addInt16(1)// binary
.addInt16(4) // value count
.addInt16(0) // string
.addInt16(0) // string
.addInt16(0) // string
.addInt16(1) // binary
.addInt16(4)

@@ -175,6 +168,3 @@ .addInt32(1)

const actual = serialize.execute()
var expectedBuffer = new BufferList()
.addCString('')
.addInt32(0)
.join(true, 'E')
var expectedBuffer = new BufferList().addCString('').addInt32(0).join(true, 'E')
assert.deepEqual(actual, expectedBuffer)

@@ -186,8 +176,5 @@ })

portal: 'my favorite portal',
rows: 100
rows: 100,
})
var expectedBuffer = new BufferList()
.addCString('my favorite portal')
.addInt32(100)
.join(true, 'E')
var expectedBuffer = new BufferList().addCString('my favorite portal').addInt32(100).join(true, 'E')
assert.deepEqual(actual, expectedBuffer)

@@ -246,3 +233,3 @@ })

const actual = serialize.copyData(Buffer.from([1, 2, 3]))
const expected = new BufferList().add(Buffer.from([1, 2,3 ])).join(true, 'd')
const expected = new BufferList().add(Buffer.from([1, 2, 3])).join(true, 'd')
assert.deepEqual(actual, expected)

@@ -249,0 +236,0 @@ })

@@ -1,20 +0,45 @@

import { TransformOptions } from 'stream';
import { Mode, bindComplete, parseComplete, closeComplete, noData, portalSuspended, copyDone, replicationStart, emptyQuery, ReadyForQueryMessage, CommandCompleteMessage, CopyDataMessage, CopyResponse, NotificationResponseMessage, RowDescriptionMessage, Field, DataRowMessage, ParameterStatusMessage, BackendKeyDataMessage, DatabaseError, BackendMessage, MessageName, AuthenticationMD5Password, NoticeMessage } from './messages';
import { BufferReader } from './buffer-reader';
import { TransformOptions } from 'stream'
import {
Mode,
bindComplete,
parseComplete,
closeComplete,
noData,
portalSuspended,
copyDone,
replicationStart,
emptyQuery,
ReadyForQueryMessage,
CommandCompleteMessage,
CopyDataMessage,
CopyResponse,
NotificationResponseMessage,
RowDescriptionMessage,
Field,
DataRowMessage,
ParameterStatusMessage,
BackendKeyDataMessage,
DatabaseError,
BackendMessage,
MessageName,
AuthenticationMD5Password,
NoticeMessage,
} from './messages'
import { BufferReader } from './buffer-reader'
import assert from 'assert'
// every message is prefixed with a single bye
const CODE_LENGTH = 1;
const CODE_LENGTH = 1
// every message has an int32 length which includes itself but does
// NOT include the code in the length
const LEN_LENGTH = 4;
const LEN_LENGTH = 4
const HEADER_LENGTH = CODE_LENGTH + LEN_LENGTH;
const HEADER_LENGTH = CODE_LENGTH + LEN_LENGTH
export type Packet = {
code: number;
packet: Buffer;
code: number
packet: Buffer
}
const emptyBuffer = Buffer.allocUnsafe(0);
const emptyBuffer = Buffer.allocUnsafe(0)

@@ -49,8 +74,8 @@ type StreamOptions = TransformOptions & {

export type MessageCallback = (msg: BackendMessage) => void;
export type MessageCallback = (msg: BackendMessage) => void
export class Parser {
private remainingBuffer: Buffer = emptyBuffer;
private reader = new BufferReader();
private mode: Mode;
private remainingBuffer: Buffer = emptyBuffer
private reader = new BufferReader()
private mode: Mode

@@ -61,28 +86,28 @@ constructor(opts?: StreamOptions) {

}
this.mode = opts?.mode || 'text';
this.mode = opts?.mode || 'text'
}
public parse(buffer: Buffer, callback: MessageCallback) {
let combinedBuffer = buffer;
let combinedBuffer = buffer
if (this.remainingBuffer.byteLength) {
combinedBuffer = Buffer.allocUnsafe(this.remainingBuffer.byteLength + buffer.byteLength);
combinedBuffer = Buffer.allocUnsafe(this.remainingBuffer.byteLength + buffer.byteLength)
this.remainingBuffer.copy(combinedBuffer)
buffer.copy(combinedBuffer, this.remainingBuffer.byteLength)
}
let offset = 0;
while ((offset + HEADER_LENGTH) <= combinedBuffer.byteLength) {
let offset = 0
while (offset + HEADER_LENGTH <= combinedBuffer.byteLength) {
// code is 1 byte long - it identifies the message type
const code = combinedBuffer[offset];
const code = combinedBuffer[offset]
// length is 1 Uint32BE - it is the length of the message EXCLUDING the code
const length = combinedBuffer.readUInt32BE(offset + CODE_LENGTH);
const length = combinedBuffer.readUInt32BE(offset + CODE_LENGTH)
const fullMessageLength = CODE_LENGTH + length;
const fullMessageLength = CODE_LENGTH + length
if (fullMessageLength + offset <= combinedBuffer.byteLength) {
const message = this.handlePacket(offset + HEADER_LENGTH, code, length, combinedBuffer);
const message = this.handlePacket(offset + HEADER_LENGTH, code, length, combinedBuffer)
callback(message)
offset += fullMessageLength;
offset += fullMessageLength
} else {
break;
break
}

@@ -92,7 +117,6 @@ }

if (offset === combinedBuffer.byteLength) {
this.remainingBuffer = emptyBuffer;
this.remainingBuffer = emptyBuffer
} else {
this.remainingBuffer = combinedBuffer.slice(offset)
}
}

@@ -103,43 +127,43 @@

case MessageCodes.BindComplete:
return bindComplete;
return bindComplete
case MessageCodes.ParseComplete:
return parseComplete;
return parseComplete
case MessageCodes.CloseComplete:
return closeComplete;
return closeComplete
case MessageCodes.NoData:
return noData;
return noData
case MessageCodes.PortalSuspended:
return portalSuspended;
return portalSuspended
case MessageCodes.CopyDone:
return copyDone;
return copyDone
case MessageCodes.ReplicationStart:
return replicationStart;
return replicationStart
case MessageCodes.EmptyQuery:
return emptyQuery;
return emptyQuery
case MessageCodes.DataRow:
return this.parseDataRowMessage(offset, length, bytes);
return this.parseDataRowMessage(offset, length, bytes)
case MessageCodes.CommandComplete:
return this.parseCommandCompleteMessage(offset, length, bytes);
return this.parseCommandCompleteMessage(offset, length, bytes)
case MessageCodes.ReadyForQuery:
return this.parseReadyForQueryMessage(offset, length, bytes);
return this.parseReadyForQueryMessage(offset, length, bytes)
case MessageCodes.NotificationResponse:
return this.parseNotificationMessage(offset, length, bytes);
return this.parseNotificationMessage(offset, length, bytes)
case MessageCodes.AuthenticationResponse:
return this.parseAuthenticationResponse(offset, length, bytes);
return this.parseAuthenticationResponse(offset, length, bytes)
case MessageCodes.ParameterStatus:
return this.parseParameterStatusMessage(offset, length, bytes);
return this.parseParameterStatusMessage(offset, length, bytes)
case MessageCodes.BackendKeyData:
return this.parseBackendKeyData(offset, length, bytes);
return this.parseBackendKeyData(offset, length, bytes)
case MessageCodes.ErrorMessage:
return this.parseErrorMessage(offset, length, bytes, MessageName.error);
return this.parseErrorMessage(offset, length, bytes, MessageName.error)
case MessageCodes.NoticeMessage:
return this.parseErrorMessage(offset, length, bytes, MessageName.notice);
return this.parseErrorMessage(offset, length, bytes, MessageName.notice)
case MessageCodes.RowDescriptionMessage:
return this.parseRowDescriptionMessage(offset, length, bytes);
return this.parseRowDescriptionMessage(offset, length, bytes)
case MessageCodes.CopyIn:
return this.parseCopyInMessage(offset, length, bytes);
return this.parseCopyInMessage(offset, length, bytes)
case MessageCodes.CopyOut:
return this.parseCopyOutMessage(offset, length, bytes);
return this.parseCopyOutMessage(offset, length, bytes)
case MessageCodes.CopyData:
return this.parseCopyData(offset, length, bytes);
return this.parseCopyData(offset, length, bytes)
default:

@@ -151,4 +175,4 @@ assert.fail(`unknown message code: ${code.toString(16)}`)

private parseReadyForQueryMessage(offset: number, length: number, bytes: Buffer) {
this.reader.setBuffer(offset, bytes);
const status = this.reader.string(1);
this.reader.setBuffer(offset, bytes)
const status = this.reader.string(1)
return new ReadyForQueryMessage(length, status)

@@ -158,10 +182,10 @@ }

private parseCommandCompleteMessage(offset: number, length: number, bytes: Buffer) {
this.reader.setBuffer(offset, bytes);
const text = this.reader.cstring();
return new CommandCompleteMessage(length, text);
this.reader.setBuffer(offset, bytes)
const text = this.reader.cstring()
return new CommandCompleteMessage(length, text)
}
private parseCopyData(offset: number, length: number, bytes: Buffer) {
const chunk = bytes.slice(offset, offset + (length - 4));
return new CopyDataMessage(length, chunk);
const chunk = bytes.slice(offset, offset + (length - 4))
return new CopyDataMessage(length, chunk)
}

@@ -178,28 +202,28 @@

private parseCopyMessage(offset: number, length: number, bytes: Buffer, messageName: MessageName) {
this.reader.setBuffer(offset, bytes);
const isBinary = this.reader.byte() !== 0;
this.reader.setBuffer(offset, bytes)
const isBinary = this.reader.byte() !== 0
const columnCount = this.reader.int16()
const message = new CopyResponse(length, messageName, isBinary, columnCount);
const message = new CopyResponse(length, messageName, isBinary, columnCount)
for (let i = 0; i < columnCount; i++) {
message.columnTypes[i] = this.reader.int16();
message.columnTypes[i] = this.reader.int16()
}
return message;
return message
}
private parseNotificationMessage(offset: number, length: number, bytes: Buffer) {
this.reader.setBuffer(offset, bytes);
const processId = this.reader.int32();
const channel = this.reader.cstring();
const payload = this.reader.cstring();
return new NotificationResponseMessage(length, processId, channel, payload);
this.reader.setBuffer(offset, bytes)
const processId = this.reader.int32()
const channel = this.reader.cstring()
const payload = this.reader.cstring()
return new NotificationResponseMessage(length, processId, channel, payload)
}
private parseRowDescriptionMessage(offset: number, length: number, bytes: Buffer) {
this.reader.setBuffer(offset, bytes);
this.reader.setBuffer(offset, bytes)
const fieldCount = this.reader.int16()
const message = new RowDescriptionMessage(length, fieldCount);
const message = new RowDescriptionMessage(length, fieldCount)
for (let i = 0; i < fieldCount; i++) {
message.fields[i] = this.parseField()
}
return message;
return message
}

@@ -214,3 +238,3 @@

const dataTypeModifier = this.reader.int32()
const mode = this.reader.int16() === 0 ? 'text' : 'binary';
const mode = this.reader.int16() === 0 ? 'text' : 'binary'
return new Field(name, tableID, columnID, dataTypeID, dataTypeSize, dataTypeModifier, mode)

@@ -220,16 +244,16 @@ }

private parseDataRowMessage(offset: number, length: number, bytes: Buffer) {
this.reader.setBuffer(offset, bytes);
const fieldCount = this.reader.int16();
const fields: any[] = new Array(fieldCount);
this.reader.setBuffer(offset, bytes)
const fieldCount = this.reader.int16()
const fields: any[] = new Array(fieldCount)
for (let i = 0; i < fieldCount; i++) {
const len = this.reader.int32();
const len = this.reader.int32()
// a -1 for length means the value of the field is null
fields[i] = len === -1 ? null : this.reader.string(len)
}
return new DataRowMessage(length, fields);
return new DataRowMessage(length, fields)
}
private parseParameterStatusMessage(offset: number, length: number, bytes: Buffer) {
this.reader.setBuffer(offset, bytes);
const name = this.reader.cstring();
this.reader.setBuffer(offset, bytes)
const name = this.reader.cstring()
const value = this.reader.cstring()

@@ -240,3 +264,3 @@ return new ParameterStatusMessage(length, name, value)

private parseBackendKeyData(offset: number, length: number, bytes: Buffer) {
this.reader.setBuffer(offset, bytes);
this.reader.setBuffer(offset, bytes)
const processID = this.reader.int32()

@@ -247,5 +271,4 @@ const secretKey = this.reader.int32()

public parseAuthenticationResponse(offset: number, length: number, bytes: Buffer) {
this.reader.setBuffer(offset, bytes);
this.reader.setBuffer(offset, bytes)
const code = this.reader.int32()

@@ -256,7 +279,7 @@ // TODO(bmc): maybe better types here

length,
};
}
switch (code) {
case 0: // AuthenticationOk
break;
break
case 3: // AuthenticationCleartextPassword

@@ -270,4 +293,4 @@ if (message.length === 8) {

message.name = MessageName.authenticationMD5Password
const salt = this.reader.bytes(4);
return new AuthenticationMD5Password(length, salt);
const salt = this.reader.bytes(4)
return new AuthenticationMD5Password(length, salt)
}

@@ -278,3 +301,3 @@ break

message.mechanisms = []
let mechanism: string;
let mechanism: string
do {

@@ -287,19 +310,19 @@ mechanism = this.reader.cstring()

} while (mechanism)
break;
break
case 11: // AuthenticationSASLContinue
message.name = MessageName.authenticationSASLContinue
message.data = this.reader.string(length - 4)
break;
break
case 12: // AuthenticationSASLFinal
message.name = MessageName.authenticationSASLFinal
message.data = this.reader.string(length - 4)
break;
break
default:
throw new Error('Unknown authenticationOk message type ' + code)
}
return message;
return message
}
private parseErrorMessage(offset: number, length: number, bytes: Buffer, name: MessageName) {
this.reader.setBuffer(offset, bytes);
this.reader.setBuffer(offset, bytes)
const fields: Record<string, string> = {}

@@ -314,3 +337,6 @@ let fieldType = this.reader.string(1)

const message = name === MessageName.notice ? new NoticeMessage(length, messageValue) : new DatabaseError(messageValue, length, name)
const message =
name === MessageName.notice
? new NoticeMessage(length, messageValue)
: new DatabaseError(messageValue, length, name)

@@ -333,4 +359,4 @@ message.severity = fields.S

message.routine = fields.R
return message;
return message
}
}

@@ -16,3 +16,3 @@ import { Writer } from './buffer-writer'

copyDone = 0x63,
copyFail = 0x66
copyFail = 0x66,
}

@@ -36,6 +36,3 @@

return new Writer()
.addInt32(length)
.add(bodyBuffer)
.flush()
return new Writer().addInt32(length).add(bodyBuffer).flush()
}

@@ -45,3 +42,3 @@

const response = Buffer.allocUnsafe(8)
response.writeInt32BE(8, 0);
response.writeInt32BE(8, 0)
response.writeInt32BE(80877103, 4)

@@ -57,6 +54,3 @@ return response

// 0x70 = 'p'
writer
.addCString(mechanism)
.addInt32(Buffer.byteLength(initialResponse))
.addString(initialResponse)
writer.addCString(mechanism).addInt32(Buffer.byteLength(initialResponse)).addString(initialResponse)

@@ -75,5 +69,5 @@ return writer.flush(code.startup)

type ParseOpts = {
name?: string;
types?: number[];
text: string;
name?: string
types?: number[]
text: string
}

@@ -116,6 +110,6 @@

type BindOpts = {
portal?: string;
binary?: boolean;
statement?: string;
values?: any[];
portal?: string
binary?: boolean
statement?: string
values?: any[]
}

@@ -137,5 +131,3 @@

var buffer = writer
.addCString(portal)
.addCString(statement)
var buffer = writer.addCString(portal).addCString(statement)
if (!useBinary) {

@@ -173,4 +165,4 @@ buffer.addInt16(0)

type ExecOpts = {
portal?: string;
rows?: number;
portal?: string
rows?: number
}

@@ -182,4 +174,4 @@

// this is the happy path for most queries
if (!config || !config.portal && !config.rows) {
return emptyExecute;
if (!config || (!config.portal && !config.rows)) {
return emptyExecute
}

@@ -197,5 +189,5 @@

buff.write(portal, 5, 'utf-8')
buff[portalLength + 5] = 0; // null terminate portal cString
buff[portalLength + 5] = 0 // null terminate portal cString
buff.writeUInt32BE(rows, buff.length - 4)
return buff;
return buff
}

@@ -210,8 +202,8 @@

buffer.writeInt32BE(secretKey, 12)
return buffer;
return buffer
}
type PortalOpts = {
type: 'S' | 'P',
name?: string;
type: 'S' | 'P'
name?: string
}

@@ -235,7 +227,7 @@

const describe = (msg: PortalOpts): Buffer => {
return msg.name ?
cstringMessage(code.describe,`${msg.type}${msg.name || ''}`) :
msg.type === 'P' ?
emptyDescribePortal :
emptyDescribeStatement;
return msg.name
? cstringMessage(code.describe, `${msg.type}${msg.name || ''}`)
: msg.type === 'P'
? emptyDescribePortal
: emptyDescribeStatement
}

@@ -253,3 +245,3 @@

const copyFail = (message: string): Buffer => {
return cstringMessage(code.copyFail, message);
return cstringMessage(code.copyFail, message)
}

@@ -282,5 +274,5 @@

copyFail,
cancel
cancel,
}
export { serialize }
export default class BufferList {
constructor(public buffers: Buffer[] = []) {
constructor(public buffers: Buffer[] = []) {}
}
public add(buffer: Buffer, front?: boolean) {

@@ -12,3 +10,3 @@ this.buffers[front ? 'unshift' : 'push'](buffer)

public addInt16(val: number, front?: boolean) {
return this.add(Buffer.from([(val >>> 8), (val >>> 0)]), front)
return this.add(Buffer.from([val >>> 8, val >>> 0]), front)
}

@@ -23,8 +21,6 @@

public addInt32(val: number, first?: boolean) {
return this.add(Buffer.from([
(val >>> 24 & 0xFF),
(val >>> 16 & 0xFF),
(val >>> 8 & 0xFF),
(val >>> 0 & 0xFF)
]), first)
return this.add(
Buffer.from([(val >>> 24) & 0xff, (val >>> 16) & 0xff, (val >>> 8) & 0xff, (val >>> 0) & 0xff]),
first
)
}

@@ -31,0 +27,0 @@

@@ -6,17 +6,11 @@ // http://developer.postgresql.org/pgdocs/postgres/protocol-message-formats.html

readyForQuery: function () {
return new BufferList()
.add(Buffer.from('I'))
.join(true, 'Z')
return new BufferList().add(Buffer.from('I')).join(true, 'Z')
},
authenticationOk: function () {
return new BufferList()
.addInt32(0)
.join(true, 'R')
return new BufferList().addInt32(0).join(true, 'R')
},
authenticationCleartextPassword: function () {
return new BufferList()
.addInt32(3)
.join(true, 'R')
return new BufferList().addInt32(3).join(true, 'R')
},

@@ -32,41 +26,23 @@

authenticationSASL: function () {
return new BufferList()
.addInt32(10)
.addCString('SCRAM-SHA-256')
.addCString('')
.join(true, 'R')
return new BufferList().addInt32(10).addCString('SCRAM-SHA-256').addCString('').join(true, 'R')
},
authenticationSASLContinue: function () {
return new BufferList()
.addInt32(11)
.addString('data')
.join(true, 'R')
return new BufferList().addInt32(11).addString('data').join(true, 'R')
},
authenticationSASLFinal: function () {
return new BufferList()
.addInt32(12)
.addString('data')
.join(true, 'R')
return new BufferList().addInt32(12).addString('data').join(true, 'R')
},
parameterStatus: function (name: string, value: string) {
return new BufferList()
.addCString(name)
.addCString(value)
.join(true, 'S')
return new BufferList().addCString(name).addCString(value).join(true, 'S')
},
backendKeyData: function (processID: number, secretKey: number) {
return new BufferList()
.addInt32(processID)
.addInt32(secretKey)
.join(true, 'K')
return new BufferList().addInt32(processID).addInt32(secretKey).join(true, 'K')
},
commandComplete: function (string: string) {
return new BufferList()
.addCString(string)
.join(true, 'C')
return new BufferList().addCString(string).join(true, 'C')
},

@@ -79,3 +55,4 @@

fields.forEach(function (field) {
buf.addCString(field.name)
buf
.addCString(field.name)
.addInt32(field.tableID || 0)

@@ -122,3 +99,3 @@ .addInt16(field.attributeNumber || 0)

})
return buf.add(Buffer.from([0]))// terminator
return buf.add(Buffer.from([0])) // terminator
},

@@ -135,7 +112,3 @@

notification: function (id: number, channel: string, payload: string) {
return new BufferList()
.addInt32(id)
.addCString(channel)
.addCString(payload)
.join(true, 'A')
return new BufferList().addInt32(id).addCString(channel).addCString(payload).join(true, 'A')
},

@@ -160,5 +133,5 @@

// column count
.addInt16(cols);
.addInt16(cols)
for (let i = 0; i < cols; i++) {
list.addInt16(i);
list.addInt16(i)
}

@@ -173,5 +146,5 @@ return list.join(true, 'G')

// column count
.addInt16(cols);
.addInt16(cols)
for (let i = 0; i < cols; i++) {
list.addInt16(i);
list.addInt16(i)
}

@@ -182,3 +155,3 @@ return list.join(true, 'H')

copyData: function (bytes: Buffer) {
return new BufferList().add(bytes).join(true, 'd');
return new BufferList().add(bytes).join(true, 'd')
},

@@ -188,5 +161,5 @@

return new BufferList().join(true, 'c')
}
},
}
export default buffers

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc