UNPKG

pg-server

Version:

Postgres DB server emulator, proxy or honeypot

109 lines 4.33 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createAdvancedProxy = exports.createSimpleProxy = void 0; const net_1 = require("net"); const server_1 = require("./server"); const commands_1 = require("./protocol/commands"); const responses_1 = require("./protocol/responses"); const util_1 = __importDefault(require("util")); const utils_1 = require("./utils"); const response_parser_1 = require("./protocol/response-parser"); const command_writer_1 = require("./protocol/command-writer"); /** * Create a db proxying server which only gives you a chance to intercepts/modify queries on the fly. * * This is a wrapper for @see createLowLevelProxy . * * Must call .listen() to start listening. */ function createSimpleProxy(db, ctor) { return createAdvancedProxy(db, class extends ctor { async onCommand({ command, getRawData }, { client, db }) { var _a; if (command.type === commands_1.CommandCode.parse || command.type === commands_1.CommandCode.query) { try { const _transformed = (_a = this.onQuery(command.query)) !== null && _a !== void 0 ? _a : command.query; let transformed; if ((0, utils_1.isThenable)(_transformed)) { getRawData(); // force get raw data before awaiting transformed = await _transformed; } else { transformed = _transformed; } if (typeof transformed === 'object') { client.error(transformed.error); client.readyForQuery(); return; } if (transformed !== command.query) { command.query = transformed; db.send(command); return; } } catch (e) { client.error(e); client.readyForQuery(); return; } } db.sendRaw(getRawData()); } }); } exports.createSimpleProxy = createSimpleProxy; /** * Create a db proxying server. * * Must call .listen() to start listening. */ function createAdvancedProxy(db, ctor) { return (0, net_1.createServer)(socket => { var _a; const instance = new ctor(); (_a = instance.onConnect) === null || _a === void 0 ? void 0 : _a.call(instance, socket); const dbSock = typeof db === 'function' ? db() : (0, net_1.connect)(db.port, db.host); let parties; // === when receiving a command from client... const { writer } = (0, server_1.bindSocket)(socket, command => { if (instance.onCommand) { // ... either ask the proxy what to do instance.onCommand(command, parties); } else { // ... or just forward it dbSock.write(command.getRawData()); } }); // === when receiving response from db... const parser = new response_parser_1.DbResponseParser(); dbSock.on('data', buffer => { if (instance.onResult) { // ... either ask the proxy what to do parser.parse(buffer, c => { if (utils_1.isDebug) { console.log(' 🕋 db ', (0, responses_1.messageToStr)(c.response.type), c.response); } instance.onResult(c, parties); }); } else { // ... or just forward it socket.write(buffer); } }); parties = { client: writer, db: new command_writer_1.CommandWriter(dbSock) }; // === bind errors dbSock.on('error', e => writer.error(util_1.default.inspect(e))); dbSock.on('close', () => socket.destroy()); dbSock.setNoDelay(true); }); } exports.createAdvancedProxy = createAdvancedProxy; //# sourceMappingURL=proxy.js.map