Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@pgtyped/query

Package Overview
Dependencies
Maintainers
1
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@pgtyped/query - npm Package Compare versions

Comparing version 0.12.0 to 0.13.0

lib/sasl-helpers.d.ts

18

lib/actions.d.ts

@@ -55,2 +55,18 @@ /// <reference types="node" />

export declare function getTypeData(query: string, queue: AsyncQueue): Promise<TypeData>;
declare enum TypeCategory {
ARRAY = "A",
BOOLEAN = "B",
COMPOSITE = "C",
DATE_TIME = "D",
ENUM = "E",
GEOMETRIC = "G",
NETWORK_ADDRESS = "I",
NUMERIC = "N",
PSEUDO = "P",
STRING = "S",
TIMESPAN = "T",
USERDEFINED = "U",
BITSTRING = "V",
UNKNOWN = "X"
}
interface TypeRow {

@@ -61,2 +77,4 @@ oid: string;

enumLabel: string;
typeCategory?: TypeCategory;
elementTypeOid?: string;
}

@@ -63,0 +81,0 @@ export declare function reduceTypeRows(typeRows: TypeRow[]): Record<string, MappableType>;

99

lib/actions.js

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

Object.defineProperty(exports, "__esModule", { value: true });
exports.getTypes = exports.reduceTypeRows = exports.getTypeData = exports.runQuery = exports.startup = exports.generateHash = void 0;
const wire_1 = require("@pgtyped/wire");
const crypto_1 = __importDefault(require("crypto"));
const debug_1 = __importDefault(require("debug"));
const sasl_helpers_1 = require("./sasl-helpers");
const type_1 = require("./type");
const debugQuery = debug_1.default('client:query');
exports.generateHash = (username, password, salt) => {
const debugQuery = (0, debug_1.default)('client:query');
const generateHash = (username, password, salt) => {
const hash = (str) => crypto_1.default.createHash('md5').update(str).digest('hex');

@@ -29,3 +31,5 @@ const shadow = hash(password + username);

};
exports.generateHash = generateHash;
function startup(options, queue) {
var _a;
return __awaiter(this, void 0, void 0, function* () {

@@ -40,3 +44,3 @@ try {

yield queue.send(wire_1.messages.startupMessage, { params: startupParams });
const result = yield queue.reply(wire_1.messages.readyForQuery, wire_1.messages.authenticationCleartextPassword, wire_1.messages.authenticationMD5Password);
const result = yield queue.reply(wire_1.messages.readyForQuery, wire_1.messages.authenticationCleartextPassword, wire_1.messages.authenticationMD5Password, wire_1.messages.authenticationSASL);
if ('trxStatus' in result) {

@@ -47,12 +51,35 @@ // No auth required

if (!options.password) {
throw new Error('password required for MD5 hash auth');
throw new Error('password required for hash auth');
}
let password = options.password;
if ('salt' in result) {
// if MD5 auth scheme
password = exports.generateHash(options.user, password, result.salt);
if ('SASLMechanisms' in result) {
if (((_a = result.SASLMechanisms) === null || _a === void 0 ? void 0 : _a.indexOf('SCRAM-SHA-256')) === -1) {
throw new Error('SASL: Only mechanism SCRAM-SHA-256 is currently supported');
}
const { clientNonce, response: initialSASLResponse } = (0, sasl_helpers_1.createInitialSASLResponse)();
yield queue.send(wire_1.messages.SASLInitialResponse, {
mechanism: 'SCRAM-SHA-256',
responseLength: Buffer.byteLength(initialSASLResponse),
response: initialSASLResponse,
});
const SASLContinueResult = yield queue.reply(wire_1.messages.AuthenticationSASLContinue);
const { response: SASLContinueResponse, calculatedServerSignature } = (0, sasl_helpers_1.createClientSASLContinueResponse)(password, clientNonce, SASLContinueResult.SASLData);
yield queue.send(wire_1.messages.SASLResponse, {
response: SASLContinueResponse,
});
const finalMessage = yield queue.multiMessageReply(wire_1.messages.authenticationSASLFinal, wire_1.messages.authenticationOk, wire_1.messages.parameterStatus, wire_1.messages.backendKeyData, wire_1.messages.readyForQuery);
const finalSASL = finalMessage.AuthenticationSASLFinal;
if ('SASLData' in finalSASL) {
(0, sasl_helpers_1.checkServerFinalMessage)(finalSASL.SASLData, calculatedServerSignature);
}
else {
throw new Error('SASL: No final SASL data returned');
}
}
yield queue.send(wire_1.messages.passwordMessage, { password });
yield queue.reply(wire_1.messages.authenticationOk);
yield queue.reply(wire_1.messages.readyForQuery);
else if ('salt' in result) {
password = (0, exports.generateHash)(options.user, password, result.salt);
yield queue.send(wire_1.messages.passwordMessage, { password });
yield queue.reply(wire_1.messages.authenticationOk);
yield queue.reply(wire_1.messages.readyForQuery);
}
}

@@ -137,14 +164,46 @@ catch (e) {

exports.getTypeData = getTypeData;
var TypeCategory;
(function (TypeCategory) {
TypeCategory["ARRAY"] = "A";
TypeCategory["BOOLEAN"] = "B";
TypeCategory["COMPOSITE"] = "C";
TypeCategory["DATE_TIME"] = "D";
TypeCategory["ENUM"] = "E";
TypeCategory["GEOMETRIC"] = "G";
TypeCategory["NETWORK_ADDRESS"] = "I";
TypeCategory["NUMERIC"] = "N";
TypeCategory["PSEUDO"] = "P";
TypeCategory["STRING"] = "S";
TypeCategory["TIMESPAN"] = "T";
TypeCategory["USERDEFINED"] = "U";
TypeCategory["BITSTRING"] = "V";
TypeCategory["UNKNOWN"] = "X";
})(TypeCategory || (TypeCategory = {}));
// Aggregate rows from database types catalog into MappableTypes
function reduceTypeRows(typeRows) {
return typeRows.reduce((typeMap, { oid, typeName, typeKind, enumLabel }) => {
const enumTypes = typeRows
.filter((r) => r.typeKind === "e" /* Enum */)
.reduce((typeMap, { oid, typeName, enumLabel }) => {
var _a;
const typ = (_a = typeMap[oid]) !== null && _a !== void 0 ? _a : typeName;
// We should get one row per enum value
return Object.assign(Object.assign({}, typeMap), { [oid]: {
name: typeName,
// Merge enum values
enumValues: [...((0, type_1.isEnum)(typ) ? typ.enumValues : []), enumLabel],
} });
}, {});
return typeRows.reduce((typeMap, { oid, typeName, typeCategory, elementTypeOid }) => {
var _a;
// Attempt to merge any partially defined types
const typ = (_a = typeMap[oid]) !== null && _a !== void 0 ? _a : typeName;
if (typeKind === "e" /* Enum */ && enumLabel) {
// We should get one row per enum value
if (oid in enumTypes) {
return Object.assign(Object.assign({}, typeMap), { [oid]: enumTypes[oid] });
}
if (typeCategory === TypeCategory.ARRAY &&
elementTypeOid &&
elementTypeOid in enumTypes) {
return Object.assign(Object.assign({}, typeMap), { [oid]: {
name: typeName,
// Merge enum values
enumValues: [...(type_1.isEnum(typ) ? typ.enumValues : []), enumLabel],
elementType: enumTypes[elementTypeOid],
} });

@@ -161,7 +220,9 @@ }

if (typeOIDs.length > 0) {
const concatenatedTypeOids = typeOIDs.join(',');
rows = yield runQuery(`
SELECT pt.oid, pt.typname, pt.typtype, pe.enumlabel
SELECT pt.oid, pt.typname, pt.typtype, pe.enumlabel, pt.typelem, pt.typcategory
FROM pg_type pt
LEFT JOIN pg_enum pe ON pt.oid = pe.enumtypid
WHERE pt.oid IN (${typeOIDs.join(',')});
WHERE pt.oid IN (${concatenatedTypeOids})
OR pt.oid IN (SELECT typelem FROM pg_type ptn WHERE ptn.oid IN (${concatenatedTypeOids}));
`, queue);

@@ -172,3 +233,3 @@ }

}
return rows.map(([oid, typeName, typeKind, enumLabel]) => ({
return rows.map(([oid, typeName, typeKind, enumLabel, elementTypeOid, typeCategory]) => ({
oid,

@@ -178,2 +239,4 @@ typeName,

enumLabel,
elementTypeOid,
typeCategory,
}));

@@ -180,0 +243,0 @@ });

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

const salt = [0x81, 0xcc, 0x95, 0x8b];
const result = actions_1.generateHash('test', 'example', Buffer.from(salt));
const result = (0, actions_1.generateHash)('test', 'example', Buffer.from(salt));
expect(result).toEqual('md5b73f398d18e98f8e2d46a7f1c548dea3');
});
test('reduce type rows to MappableTypes', () => {
expect(actions_1.reduceTypeRows([
expect((0, actions_1.reduceTypeRows)([
{

@@ -25,3 +25,3 @@ oid: '25',

])).toMatchSnapshot();
expect(actions_1.reduceTypeRows([
expect((0, actions_1.reduceTypeRows)([
{

@@ -58,3 +58,3 @@ oid: '16398',

])).toMatchSnapshot();
expect(actions_1.reduceTypeRows([
expect((0, actions_1.reduceTypeRows)([
{

@@ -91,3 +91,3 @@ oid: '16398',

])).toMatchSnapshot();
expect(actions_1.reduceTypeRows([
expect((0, actions_1.reduceTypeRows)([
{

@@ -130,3 +130,3 @@ oid: '16398',

])).toMatchSnapshot();
expect(actions_1.reduceTypeRows([
expect((0, actions_1.reduceTypeRows)([
{

@@ -157,3 +157,31 @@ oid: '20',

])).toMatchSnapshot();
expect((0, actions_1.reduceTypeRows)([
{
oid: '16398',
typeName: 'notification_type',
typeKind: 'e',
enumLabel: 'notification',
},
{
oid: '16398',
typeName: 'notification_type',
typeKind: 'e',
enumLabel: 'reminder',
},
{
oid: '16398',
typeName: 'notification_type',
typeKind: 'e',
enumLabel: 'deadline',
},
{
oid: '24',
typeName: '_enum',
typeKind: 'b',
enumLabel: '',
typeCategory: 'A',
elementTypeOid: '16398',
},
])).toMatchSnapshot();
});
//# sourceMappingURL=actions.test.js.map

28

lib/index.js
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PreparedQuery = exports.TaggedQuery = exports.sql = exports.prettyPrintEvents = exports.parseSQLFile = exports.parseTypeScriptFile = exports.AsyncQueue = exports.processSQLQueryAST = exports.processTSQueryAST = exports.ParamTransform = exports.startup = exports.getTypes = void 0;
var actions_1 = require("./actions");
exports.getTypes = actions_1.getTypes;
exports.startup = actions_1.startup;
Object.defineProperty(exports, "getTypes", { enumerable: true, get: function () { return actions_1.getTypes; } });
Object.defineProperty(exports, "startup", { enumerable: true, get: function () { return actions_1.startup; } });
var preprocessor_1 = require("./preprocessor");
exports.ParamTransform = preprocessor_1.ParamTransform;
Object.defineProperty(exports, "ParamTransform", { enumerable: true, get: function () { return preprocessor_1.ParamTransform; } });
var preprocessor_ts_1 = require("./preprocessor-ts");
exports.processTSQueryAST = preprocessor_ts_1.processTSQueryAST;
Object.defineProperty(exports, "processTSQueryAST", { enumerable: true, get: function () { return preprocessor_ts_1.processTSQueryAST; } });
var preprocessor_sql_1 = require("./preprocessor-sql");
exports.processSQLQueryAST = preprocessor_sql_1.processSQLQueryAST;
Object.defineProperty(exports, "processSQLQueryAST", { enumerable: true, get: function () { return preprocessor_sql_1.processSQLQueryAST; } });
var wire_1 = require("@pgtyped/wire");
exports.AsyncQueue = wire_1.AsyncQueue;
Object.defineProperty(exports, "AsyncQueue", { enumerable: true, get: function () { return wire_1.AsyncQueue; } });
var typescript_1 = require("./loader/typescript");
exports.parseTypeScriptFile = typescript_1.default;
Object.defineProperty(exports, "parseTypeScriptFile", { enumerable: true, get: function () { return __importDefault(typescript_1).default; } });
var sql_1 = require("./loader/sql");
exports.parseSQLFile = sql_1.default;
exports.prettyPrintEvents = sql_1.prettyPrintEvents;
Object.defineProperty(exports, "parseSQLFile", { enumerable: true, get: function () { return __importDefault(sql_1).default; } });
Object.defineProperty(exports, "prettyPrintEvents", { enumerable: true, get: function () { return sql_1.prettyPrintEvents; } });
var tag_1 = require("./tag");
exports.sql = tag_1.default;
exports.TaggedQuery = tag_1.TaggedQuery;
exports.PreparedQuery = tag_1.PreparedQuery;
Object.defineProperty(exports, "sql", { enumerable: true, get: function () { return __importDefault(tag_1).default; } });
Object.defineProperty(exports, "TaggedQuery", { enumerable: true, get: function () { return tag_1.TaggedQuery; } });
Object.defineProperty(exports, "PreparedQuery", { enumerable: true, get: function () { return tag_1.PreparedQuery; } });
//# sourceMappingURL=index.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.prettyPrintEvents = exports.assert = exports.TransformType = void 0;
const antlr4ts_1 = require("antlr4ts");

@@ -193,4 +194,4 @@ const ParseTreeWalker_1 = require("antlr4ts/tree/ParseTreeWalker");

var logger_2 = require("./logger");
exports.prettyPrintEvents = logger_2.prettyPrintEvents;
Object.defineProperty(exports, "prettyPrintEvents", { enumerable: true, get: function () { return logger_2.prettyPrintEvents; } });
exports.default = parseText;
//# sourceMappingURL=index.js.map

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

SELECT * FROM users;`;
const parseTree = index_1.default(text);
const parseTree = (0, index_1.default)(text);
expect(parseTree).toMatchSnapshot();

@@ -19,3 +19,3 @@ });

SELECT id, name FROM users;`;
const parseTree = index_1.default(text);
const parseTree = (0, index_1.default)(text);
expect(parseTree).toMatchSnapshot();

@@ -27,3 +27,3 @@ });

SELECT * FROM users WHERE userId = :userId;`;
const parseTree = index_1.default(text);
const parseTree = (0, index_1.default)(text);
expect(parseTree).toMatchSnapshot();

@@ -35,3 +35,3 @@ });

SELECT * FROM users WHERE userId = :userId or parentId = :userId;`;
const parseTree = index_1.default(text);
const parseTree = (0, index_1.default)(text);
expect(parseTree).toMatchSnapshot();

@@ -47,3 +47,3 @@ });

VALUES :customers;`;
const parseTree = index_1.default(text);
const parseTree = (0, index_1.default)(text);
expect(parseTree).toMatchSnapshot();

@@ -59,3 +59,3 @@ });

VALUES :customers, :customers;`;
const parseTree = index_1.default(text);
const parseTree = (0, index_1.default)(text);
expect(parseTree).toMatchSnapshot();

@@ -71,3 +71,3 @@ });

SELECT * FROM users;`;
const parseTree = index_1.default(text);
const parseTree = (0, index_1.default)(text);
expect(parseTree).toMatchSnapshot();

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

WHERE a.first_name || ' ' || a.last_name = :authorName;`;
const parseTree = index_1.default(text);
const parseTree = (0, index_1.default)(text);
expect(parseTree).toMatchSnapshot();

@@ -89,3 +89,3 @@ });

SELECT u."rank" FROM users u where name = 'some-name';`;
const parseTree = index_1.default(text);
const parseTree = (0, index_1.default)(text);
expect(parseTree).toMatchSnapshot();

@@ -97,3 +97,3 @@ });

SELECT u."rank" FROM users u where name = :name::text;`;
const parseTree = index_1.default(text);
const parseTree = (0, index_1.default)(text);
expect(parseTree).toMatchSnapshot();

@@ -108,5 +108,5 @@ });

`;
const parseTree = index_1.default(text);
const parseTree = (0, index_1.default)(text);
expect(parseTree).toMatchSnapshot();
});
//# sourceMappingURL=index.test.js.map

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

Object.defineProperty(exports, "__esModule", { value: true });
exports.Logger = exports.prettyPrintEvents = exports.ParseEventType = exports.ParseWarningType = void 0;
const chalk_1 = __importDefault(require("chalk"));

@@ -8,0 +9,0 @@ var ParseWarningType;

"use strict";
// Generated from src/loader/sql/grammar/SQLLexer.g4 by ANTLR 4.9.0-SNAPSHOT
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SQLLexer = void 0;
const ATNDeserializer_1 = require("antlr4ts/atn/ATNDeserializer");

@@ -113,3 +126,3 @@ const Lexer_1 = require("antlr4ts/Lexer");

",\x02\x12.\x02\x130\x02\x142\x02\x15\x04\x02\x03\x07\x05\x02C\\aac|\x06" +
"\x022;C\\aac|\t\x02#(*1>B]]_`bb}\x80\x05\x02\v\f\x0F\x0F\"\"\x03\x02^" +
"\x022;C\\aac|\t\x02$(*1>B]]_`bb}\x80\x05\x02\v\f\x0F\x0F\"\"\x03\x02^" +
"^\x02\xA5\x02\b\x03\x02\x02\x02\x02\n\x03\x02\x02\x02\x02\f\x03\x02\x02" +

@@ -116,0 +129,0 @@ "\x02\x02\x0E\x03\x02\x02\x02\x02\x10\x03\x02\x02\x02\x02\x12\x03\x02\x02" +

@@ -153,2 +153,3 @@ import { ATN } from "antlr4ts/atn/ATN";

STRING(): TerminalNode | undefined;
S_REQUIRED_MARK(): TerminalNode | undefined;
constructor(parent: ParserRuleContext | undefined, invokingState: number);

@@ -155,0 +156,0 @@ get ruleIndex(): number;

"use strict";
// Generated from src/loader/sql/grammar/SQLParser.g4 by ANTLR 4.9.0-SNAPSHOT
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ParamNameContext = exports.QueryNameContext = exports.KeyContext = exports.SpreadPickTransformContext = exports.PickTransformContext = exports.SpreadTransformContext = exports.TransformRuleContext = exports.ParamTransformContext = exports.ParamTagContext = exports.NameTagContext = exports.ParamIdContext = exports.ParamContext = exports.WordContext = exports.StatementBodyContext = exports.StatementContext = exports.IgnoredCommentContext = exports.QueryDefContext = exports.QueryContext = exports.InputContext = exports.SQLParser = void 0;
const ATN_1 = require("antlr4ts/atn/ATN");

@@ -270,3 +283,3 @@ const ATNDeserializer_1 = require("antlr4ts/atn/ATNDeserializer");

_la = this._input.LA(1);
while ((((_la) & ~0x1F) === 0 && ((1 << _la) & ((1 << SQLParser.ID) | (1 << SQLParser.OPEN_COMMENT) | (1 << SQLParser.WORD) | (1 << SQLParser.STRING) | (1 << SQLParser.PARAM_MARK))) !== 0)) {
while ((((_la) & ~0x1F) === 0 && ((1 << _la) & ((1 << SQLParser.ID) | (1 << SQLParser.OPEN_COMMENT) | (1 << SQLParser.S_REQUIRED_MARK) | (1 << SQLParser.WORD) | (1 << SQLParser.STRING) | (1 << SQLParser.PARAM_MARK))) !== 0)) {
{

@@ -289,2 +302,3 @@ this.state = 80;

case SQLParser.ID:
case SQLParser.S_REQUIRED_MARK:
case SQLParser.WORD:

@@ -332,3 +346,3 @@ case SQLParser.STRING:

_la = this._input.LA(1);
if (!((((_la) & ~0x1F) === 0 && ((1 << _la) & ((1 << SQLParser.ID) | (1 << SQLParser.WORD) | (1 << SQLParser.STRING))) !== 0))) {
if (!((((_la) & ~0x1F) === 0 && ((1 << _la) & ((1 << SQLParser.ID) | (1 << SQLParser.S_REQUIRED_MARK) | (1 << SQLParser.WORD) | (1 << SQLParser.STRING))) !== 0))) {
this._errHandler.recoverInline(this);

@@ -392,3 +406,2 @@ }

this.enterRule(_localctx, 16, SQLParser.RULE_paramId);
let _la;
try {

@@ -401,8 +414,9 @@ this.enterOuterAlt(_localctx, 1);

this._errHandler.sync(this);
_la = this._input.LA(1);
if (_la === SQLParser.S_REQUIRED_MARK) {
{
this.state = 91;
this.match(SQLParser.S_REQUIRED_MARK);
}
switch (this.interpreter.adaptivePredict(this._input, 6, this._ctx)) {
case 1:
{
this.state = 91;
this.match(SQLParser.S_REQUIRED_MARK);
}
break;
}

@@ -850,3 +864,3 @@ }

"\x0E\x02\x10\x02\x12\x02\x14\x02\x16\x02\x18\x02\x1A\x02\x1C\x02\x1E\x02" +
" \x02\"\x02$\x02&\x02\x02\x04\x03\x02\x0E\x0E\x05\x02\x03\x03\x06\x06" +
" \x02\"\x02$\x02&\x02\x02\x04\x03\x02\x0E\x0E\x05\x02\x03\x03\x05\x06" +
"\t\t\x02\x88\x02/\x03\x02\x02\x02\x045\x03\x02\x02\x02\x068\x03\x02\x02" +

@@ -1141,2 +1155,3 @@ "\x02\bB\x03\x02\x02\x02\nK\x03\x02\x02\x02\fN\x03\x02\x02\x02\x0EW\x03" +

STRING() { return this.tryGetToken(SQLParser.STRING, 0); }
S_REQUIRED_MARK() { return this.tryGetToken(SQLParser.S_REQUIRED_MARK, 0); }
constructor(parent, invokingState) {

@@ -1143,0 +1158,0 @@ super(parent, invokingState);

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;

@@ -13,2 +25,3 @@ };

Object.defineProperty(exports, "__esModule", { value: true });
exports.parseFile = exports.parseTSQuery = void 0;
const ts = __importStar(require("typescript"));

@@ -42,3 +55,3 @@ const query_1 = __importDefault(require("./query"));

for (const node of foundNodes) {
const { query, events: qEvents } = query_1.default(node.queryText, node.queryName);
const { query, events: qEvents } = (0, query_1.default)(node.queryText, node.queryName);
queries.push(query);

@@ -45,0 +58,0 @@ events.push(...qEvents);

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

`;
const result = index_1.default(fileContent);
const result = (0, index_1.default)(fileContent);
expect(result).toMatchSnapshot();

@@ -27,5 +27,5 @@ });

`;
const result = index_1.default(fileContent);
const result = (0, index_1.default)(fileContent);
expect(result).toMatchSnapshot();
});
//# sourceMappingURL=index.test.js.map
"use strict";
// Generated from src/loader/typescript/grammar/QueryLexer.g4 by ANTLR 4.9.0-SNAPSHOT
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.QueryLexer = void 0;
const ATNDeserializer_1 = require("antlr4ts/atn/ATNDeserializer");

@@ -12,0 +25,0 @@ const Lexer_1 = require("antlr4ts/Lexer");

"use strict";
// Generated from src/loader/typescript/grammar/QueryParser.g4 by ANTLR 4.9.0-SNAPSHOT
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PickKeyContext = exports.ParamNameContext = exports.ScalarParamNameContext = exports.ArrayParamContext = exports.ArrayPickParamContext = exports.PickParamContext = exports.ScalarParamContext = exports.IgnoredContext = exports.ParamContext = exports.QueryContext = exports.InputContext = exports.QueryParser = void 0;
const ATN_1 = require("antlr4ts/atn/ATN");

@@ -12,0 +25,0 @@ const ATNDeserializer_1 = require("antlr4ts/atn/ATNDeserializer");

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.assert = exports.ParamType = void 0;
const antlr4ts_1 = require("antlr4ts");

@@ -4,0 +5,0 @@ const ParseTreeWalker_1 = require("antlr4ts/tree/ParseTreeWalker");

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

const query = `select * from users where id = $id and title= $title`;
const result = query_1.default(query);
const result = (0, query_1.default)(query);
expect(result).toMatchSnapshot();

@@ -15,3 +15,3 @@ });

const query = `select * from users where id in $activeUsers(userOne, userTwo)`;
const result = query_1.default(query);
const result = (0, query_1.default)(query);
expect(result).toMatchSnapshot();

@@ -21,3 +21,3 @@ });

const query = `select * from users where id in $$ids`;
const result = query_1.default(query);
const result = (0, query_1.default)(query);
expect(result).toMatchSnapshot();

@@ -28,5 +28,5 @@ });

VALUES $$customers(customerName, contactName, address)`;
const result = query_1.default(query);
const result = (0, query_1.default)(query);
expect(result).toMatchSnapshot();
});
//# sourceMappingURL=query.test.js.map

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

import { SQLQueryAST } from './loader/sql';
import { IInterpolatedQuery, IQueryParameters } from './preprocessor';
export declare const processSQLQueryAST: (query: import("./loader/sql").Query, passedParams?: IQueryParameters | undefined) => IInterpolatedQuery;
export declare const processSQLQueryAST: (query: SQLQueryAST, passedParams?: IQueryParameters | undefined) => IInterpolatedQuery;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.processSQLQueryAST = void 0;
const sql_1 = require("./loader/sql");
const preprocessor_1 = require("./preprocessor");
/* Processes query AST formed by new parser from pure SQL files */
exports.processSQLQueryAST = (query, passedParams) => {
const processSQLQueryAST = (query, passedParams) => {
const bindings = [];

@@ -80,3 +81,3 @@ const paramMapping = [];

.map((entity) => {
sql_1.assert(usedParam.transform.type === sql_1.TransformType.PickArraySpread);
(0, sql_1.assert)(usedParam.transform.type === sql_1.TransformType.PickArraySpread);
const ssub = usedParam.transform.keys

@@ -132,3 +133,3 @@ .map(({ name }) => {

}
const flatStr = preprocessor_1.replaceIntervals(query.statement.body, intervals);
const flatStr = (0, preprocessor_1.replaceIntervals)(query.statement.body, intervals);
return {

@@ -140,2 +141,3 @@ mapping: paramMapping,

};
exports.processSQLQueryAST = processSQLQueryAST;
//# sourceMappingURL=preprocessor-sql.js.map

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

SELECT id, name FROM users;`;
const fileAST = sql_1.default(query);
const fileAST = (0, sql_1.default)(query);
const parameters = {};

@@ -21,7 +21,31 @@ const expectedResult = {

};
const interpolationResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0], parameters);
const mappingResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0]);
const interpolationResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0], parameters);
const mappingResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0]);
expect(interpolationResult).toEqual(expectedResult);
expect(mappingResult).toEqual(expectedResult);
});
test('(SQL) two scalar params, one forced as non-null', () => {
const query = `
/*
@name UpdateBooksRankNotNull
*/
UPDATE books
SET
rank = :rank!,
name = :name
WHERE id = :id!;`;
const fileAST = (0, sql_1.default)(query);
const parameters = {
rank: 123,
name: 'name',
id: 'id',
};
const expectedInterpolationResult = {
query: 'UPDATE books\n SET\n rank = $1,\n name = $2\n WHERE id = $3',
mapping: [],
bindings: [123, 'name', 'id'],
};
const interpolationResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0], parameters);
expect(interpolationResult).toEqual(expectedInterpolationResult);
});
test('(SQL) two scalar params', () => {

@@ -31,3 +55,3 @@ const query = `

SELECT id, name from users where id = :id and age > :age;`;
const fileAST = sql_1.default(query);
const fileAST = (0, sql_1.default)(query);
const parameters = {

@@ -60,4 +84,4 @@ id: '123',

};
const interpolationResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0], parameters);
const mappingResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0]);
const interpolationResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0], parameters);
const mappingResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0]);
expect(interpolationResult).toEqual(expectedInterpolationResult);

@@ -70,3 +94,3 @@ expect(mappingResult).toEqual(expectedMappingResult);

SELECT id, name from users where id = :id or parent_id = :id;`;
const fileAST = sql_1.default(query);
const fileAST = (0, sql_1.default)(query);
const parameters = {

@@ -92,4 +116,4 @@ id: '123',

};
const interpolationResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0], parameters);
const mappingResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0]);
const interpolationResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0], parameters);
const mappingResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0]);
expect(interpolationResult).toEqual(expectedInterpolationResult);

@@ -105,3 +129,3 @@ expect(mappingResult).toEqual(expectedMappingResult);

SELECT FROM users WHERE age in :ages;`;
const fileAST = sql_1.default(query);
const fileAST = (0, sql_1.default)(query);
const parameters = {

@@ -127,4 +151,4 @@ ages: [23, 27, 50],

};
const interpolationResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0], parameters);
const mappingResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0]);
const interpolationResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0], parameters);
const mappingResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0]);
expect(interpolationResult).toEqual(expectedInterpolationResult);

@@ -140,3 +164,3 @@ expect(mappingResult).toEqual(expectedMappingResult);

SELECT FROM users WHERE age in :ages or age in :ages;`;
const fileAST = sql_1.default(query);
const fileAST = (0, sql_1.default)(query);
const parameters = {

@@ -162,4 +186,4 @@ ages: [23, 27, 50],

};
const interpolationResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0], parameters);
const mappingResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0]);
const interpolationResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0], parameters);
const mappingResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0]);
expect(interpolationResult).toEqual(expectedInterpolationResult);

@@ -175,3 +199,3 @@ expect(mappingResult).toEqual(expectedMappingResult);

SELECT FROM users WHERE age in :ages and id = :userId;`;
const fileAST = sql_1.default(query);
const fileAST = (0, sql_1.default)(query);
const parameters = {

@@ -204,4 +228,4 @@ ages: [23, 27, 50],

};
const interpolationResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0], parameters);
const mappingResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0]);
const interpolationResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0], parameters);
const mappingResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0]);
expect(interpolationResult).toEqual(expectedInterpolationResult);

@@ -217,3 +241,3 @@ expect(mappingResult).toEqual(expectedMappingResult);

INSERT INTO users (name, age) VALUES :user RETURNING id;`;
const fileAST = sql_1.default(query);
const fileAST = (0, sql_1.default)(query);
const parameters = {

@@ -251,5 +275,5 @@ user: { name: 'Bob', age: 12 },

};
const interpolationResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0], parameters);
const interpolationResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0], parameters);
expect(interpolationResult).toEqual(expectedInterpolationResult);
const mappingResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0]);
const mappingResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0]);
expect(mappingResult).toEqual(expectedMappingResult);

@@ -264,3 +288,3 @@ });

INSERT INTO users (name, age) VALUES :user, :user RETURNING id;`;
const fileAST = sql_1.default(query);
const fileAST = (0, sql_1.default)(query);
const parameters = {

@@ -298,5 +322,5 @@ user: { name: 'Bob', age: 12 },

};
const interpolationResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0], parameters);
const interpolationResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0], parameters);
expect(interpolationResult).toEqual(expectedInterpolationResult);
const mappingResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0]);
const mappingResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0]);
expect(mappingResult).toEqual(expectedMappingResult);

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

INSERT INTO users (name, age) VALUES :users RETURNING id;`;
const fileAST = sql_1.default(query);
const fileAST = (0, sql_1.default)(query);
const parameters = {

@@ -349,4 +373,4 @@ users: [

};
const interpolationResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0], parameters);
const mappingResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0]);
const interpolationResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0], parameters);
const mappingResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0]);
expect(interpolationResult).toEqual(expectedInterpolationResult);

@@ -362,3 +386,3 @@ expect(mappingResult).toEqual(expectedMappingResult);

INSERT INTO users (name, age) VALUES :users, :users RETURNING id;`;
const fileAST = sql_1.default(query);
const fileAST = (0, sql_1.default)(query);
const parameters = {

@@ -400,4 +424,4 @@ users: [

};
const interpolationResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0], parameters);
const mappingResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0]);
const interpolationResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0], parameters);
const mappingResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0]);
expect(interpolationResult).toEqual(expectedInterpolationResult);

@@ -410,3 +434,3 @@ expect(mappingResult).toEqual(expectedMappingResult);

SELECT id, name from users where id = :id! and user_id = :id;`;
const fileAST = sql_1.default(query);
const fileAST = (0, sql_1.default)(query);
const parameters = {

@@ -432,4 +456,4 @@ id: '123',

};
const interpolationResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0], parameters);
const mappingResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0]);
const interpolationResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0], parameters);
const mappingResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0]);
expect(interpolationResult).toEqual(expectedInterpolationResult);

@@ -445,3 +469,3 @@ expect(mappingResult).toEqual(expectedMappingResult);

INSERT INTO users (name, age) VALUES :user RETURNING id;`;
const fileAST = sql_1.default(query);
const fileAST = (0, sql_1.default)(query);
const parameters = {

@@ -479,5 +503,5 @@ user: { name: 'Bob', age: 12 },

};
const interpolationResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0], parameters);
const interpolationResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0], parameters);
expect(interpolationResult).toEqual(expectedInterpolationResult);
const mappingResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0]);
const mappingResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0]);
expect(mappingResult).toEqual(expectedMappingResult);

@@ -492,3 +516,3 @@ });

SELECT FROM users WHERE age in :ages!;`;
const fileAST = sql_1.default(query);
const fileAST = (0, sql_1.default)(query);
const parameters = {

@@ -514,4 +538,4 @@ ages: [23, 27, 50],

};
const interpolationResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0], parameters);
const mappingResult = preprocessor_sql_1.processSQLQueryAST(fileAST.queries[0]);
const interpolationResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0], parameters);
const mappingResult = (0, preprocessor_sql_1.processSQLQueryAST)(fileAST.queries[0]);
expect(interpolationResult).toEqual(expectedInterpolationResult);

@@ -518,0 +542,0 @@ expect(mappingResult).toEqual(expectedMappingResult);

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

import { TSQueryAST } from './loader/typescript';
import { IInterpolatedQuery, IQueryParameters } from './preprocessor';
export declare const processTSQueryAST: (query: import("./loader/typescript/query").Query, parameters?: IQueryParameters | undefined) => IInterpolatedQuery;
export declare const processTSQueryAST: (query: TSQueryAST, parameters?: IQueryParameters | undefined) => IInterpolatedQuery;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.processTSQueryAST = void 0;
const query_1 = require("./loader/typescript/query");

@@ -134,3 +135,3 @@ const sql_1 = require("./loader/sql");

/* Processes query strings produced by old parser from SQL-in-TS statements */
exports.processTSQueryAST = (query, parameters) => {
const processTSQueryAST = (query, parameters) => {
const bindings = [];

@@ -169,3 +170,3 @@ const baseMap = {};

}
sql_1.assert(result);
(0, sql_1.assert)(result);
({

@@ -181,3 +182,3 @@ config,

}
const flatStr = preprocessor_1.replaceIntervals(query.text, intervals);
const flatStr = (0, preprocessor_1.replaceIntervals)(query.text, intervals);
return {

@@ -189,2 +190,3 @@ mapping: parameters ? [] : Object.values(baseMap),

};
exports.processTSQueryAST = processTSQueryAST;
//# sourceMappingURL=preprocessor-ts.js.map

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

const query = 'SELECT id, name from users where id = $id and age > $age';
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const parameters = {

@@ -19,3 +19,3 @@ id: '123',

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query, parameters);
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query, parameters);
expect(result).toEqual(expectedResult);

@@ -28,3 +28,3 @@ });

`;
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const parameters = {

@@ -44,3 +44,3 @@ notification: {

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query, parameters);
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query, parameters);
expect(result).toEqual(expectedResult);

@@ -53,3 +53,3 @@ });

`;
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const parameters = {

@@ -71,3 +71,3 @@ params: [

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query, parameters);
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query, parameters);
expect(result).toEqual(expectedResult);

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

const query = 'SELECT id, name from users where id = $id and parent_id = $id';
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const parameters = {

@@ -87,3 +87,3 @@ id: '123',

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query, parameters);
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query, parameters);
expect(result).toEqual(expectedResult);

@@ -93,3 +93,3 @@ });

const query = 'SELECT id, name from users where id = $id and age > $age and parent_id = $id';
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const expectedResult = {

@@ -100,3 +100,3 @@ query: 'SELECT id, name from users where id = $1 and age > $2 and parent_id = $1',

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query, {
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query, {
id: '1234-1235',

@@ -109,3 +109,3 @@ age: 33,

const query = 'INSERT INTO users (name, age) VALUES $user(name, age) RETURNING id';
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const expectedResult = {

@@ -135,3 +135,3 @@ query: 'INSERT INTO users (name, age) VALUES ($1, $2) RETURNING id',

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query);
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query);
expect(result).toEqual(expectedResult);

@@ -141,3 +141,3 @@ });

const query = 'INSERT INTO users (name, age) VALUES $user(name, age) BOGUS $user(name, id) RETURNING id';
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const parameters = {

@@ -155,3 +155,3 @@ user: {

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query, parameters);
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query, parameters);
expect(result).toEqual(expectedResult);

@@ -161,3 +161,3 @@ });

const query = 'SELECT FROM users where (age in $$ages and age in $$ages) or (age in $$otherAges)';
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const expectedResult = {

@@ -181,3 +181,3 @@ query: 'SELECT FROM users where (age in ($1) and age in ($1)) or (age in ($2))',

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query);
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query);
expect(result).toEqual(expectedResult);

@@ -187,3 +187,3 @@ });

const query = 'SELECT FROM users where age in $$ages or parent_age in $$ages';
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const parameters = {

@@ -197,3 +197,3 @@ ages: [23, 27, 50],

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query, parameters);
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query, parameters);
expect(result).toEqual(expectedResult);

@@ -203,3 +203,3 @@ });

const query = 'INSERT INTO users (name, age) VALUES $$users(name, age) RETURNING id';
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const expectedResult = {

@@ -229,3 +229,3 @@ query: 'INSERT INTO users (name, age) VALUES ($1, $2) RETURNING id',

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query);
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query);
expect(result).toEqual(expectedResult);

@@ -235,3 +235,3 @@ });

const query = 'INSERT INTO users (name, age) VALUES $$users(name, age), $$users(name) RETURNING id';
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const expectedResult = {

@@ -261,3 +261,3 @@ query: 'INSERT INTO users (name, age) VALUES ($1, $2), ($1) RETURNING id',

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query);
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query);
expect(result).toEqual(expectedResult);

@@ -267,3 +267,3 @@ });

const query = 'INSERT INTO users (name, age) VALUES $$users(name, age) RETURNING id';
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const parameters = {

@@ -280,3 +280,3 @@ users: [

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query, parameters);
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query, parameters);
expect(result).toEqual(expectedResult);

@@ -286,3 +286,3 @@ });

const query = 'INSERT INTO users (name, age) VALUES $$users(name, age), $$users(name, age) RETURNING id';
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const parameters = {

@@ -299,3 +299,3 @@ users: [

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query, parameters);
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query, parameters);
expect(result).toEqual(expectedResult);

@@ -305,3 +305,3 @@ });

const query = `UPDATE notifications SET payload = '{"a": "b"}'::jsonb`;
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const expectedResult = {

@@ -312,3 +312,3 @@ query: `UPDATE notifications SET payload = '{"a": "b"}'::jsonb`,

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query);
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query);
expect(result).toEqual(expectedResult);

@@ -318,3 +318,3 @@ });

const query = `SELECT * FROM users WHERE id IN $$ids`;
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const expectedResult = {

@@ -325,3 +325,3 @@ query: `SELECT * FROM users WHERE id IN ()`,

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query, { ids: [] });
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query, { ids: [] });
expect(result).toEqual(expectedResult);

@@ -331,3 +331,3 @@ });

const query = `INSERT INTO data.action_log (id, name) VALUES $$params(id, name)`;
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const expectedResult = {

@@ -338,3 +338,3 @@ query: `INSERT INTO data.action_log (id, name) VALUES ()`,

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query, { params: [] });
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query, { params: [] });
expect(result).toEqual(expectedResult);

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

const query = `INSERT INTO data.action_log (_id, _name) VALUES $$_params(_id, _name)`;
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const expectedResult = {

@@ -351,3 +351,3 @@ query: `INSERT INTO data.action_log (_id, _name) VALUES ($1, $2)`,

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query, {
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query, {
_params: [{ _id: 'one', _name: 'two' }],

@@ -359,3 +359,3 @@ });

const query = 'SELECT $userId $age! $userId $$users $age $user(id) $$users $user(id, parentId, age) $$comments(id!, text) $user(age!)';
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const expectedResult = {

@@ -427,3 +427,3 @@ query: 'SELECT $1 $2 $1 ($3) $2 ($4) ($3) ($4, $5, $6) ($7, $8) ($6)',

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query);
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query);
expect(result).toEqual(expectedResult);

@@ -433,3 +433,3 @@ });

const query = 'SELECT $$users!';
const parsedQuery = typescript_1.parseTSQuery(query);
const parsedQuery = (0, typescript_1.parseTSQuery)(query);
const expectedResult = {

@@ -447,5 +447,5 @@ query: 'SELECT ($1)',

};
const result = preprocessor_ts_1.processTSQueryAST(parsedQuery.query);
const result = (0, preprocessor_ts_1.processTSQueryAST)(parsedQuery.query);
expect(result).toEqual(expectedResult);
});
//# sourceMappingURL=preprocessor-ts.test.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.replaceIntervals = exports.ParamTransform = void 0;
var ParamTransform;

@@ -4,0 +5,0 @@ (function (ParamTransform) {

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

Object.defineProperty(exports, "__esModule", { value: true });
exports.PreparedQuery = exports.TaggedQuery = void 0;
const preprocessor_ts_1 = require("./preprocessor-ts");

@@ -21,3 +22,3 @@ const preprocessor_sql_1 = require("./preprocessor-sql");

this.run = (params, connection) => __awaiter(this, void 0, void 0, function* () {
const { query: processedQuery, bindings } = preprocessor_ts_1.processTSQueryAST(this.query, params);
const { query: processedQuery, bindings } = (0, preprocessor_ts_1.processTSQueryAST)(this.query, params);
const result = yield connection.query(processedQuery, bindings);

@@ -30,3 +31,3 @@ return result.rows;

const sql = (stringsArray) => {
const { query } = typescript_1.parseTSQuery(stringsArray[0]);
const { query } = (0, typescript_1.parseTSQuery)(stringsArray[0]);
return new TaggedQuery(query);

@@ -39,3 +40,3 @@ };

this.run = (params, connection) => __awaiter(this, void 0, void 0, function* () {
const { query: processedQuery, bindings } = preprocessor_sql_1.processSQLQueryAST(this.query, params);
const { query: processedQuery, bindings } = (0, preprocessor_sql_1.processSQLQueryAST)(this.query, params);
const result = yield connection.query(processedQuery, bindings);

@@ -42,0 +43,0 @@ return result.rows;

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

export declare type Type = NamedType | ImportedType | AliasedType | EnumType;
export declare type Type = NamedType | ImportedType | AliasedType | EnumType | EnumArrayType;
export declare type MappableType = string | Type;

@@ -17,5 +17,10 @@ export interface NamedType {

}
export interface EnumArrayType extends NamedType {
name: string;
elementType: EnumType;
}
export declare function isImport(typ: Type): typ is ImportedType;
export declare function isAlias(typ: Type): typ is AliasedType;
export declare function isEnum(typ: MappableType): typ is EnumType;
export declare function isEnumArray(typ: MappableType): typ is EnumArrayType;
export declare const enum DatabaseTypeKind {

@@ -22,0 +27,0 @@ Base = "b",

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isEnumArray = exports.isEnum = exports.isAlias = exports.isImport = void 0;
function isImport(typ) {

@@ -15,2 +16,6 @@ return 'from' in typ;

exports.isEnum = isEnum;
function isEnumArray(typ) {
return typeof typ !== 'string' && 'elementType' in typ;
}
exports.isEnumArray = isEnumArray;
//# sourceMappingURL=type.js.map
{
"name": "@pgtyped/query",
"version": "0.12.0",
"version": "0.13.0",
"main": "lib/index.js",

@@ -28,3 +28,3 @@ "types": "lib/index.d.ts",

"dependencies": {
"@pgtyped/wire": "^0.12.0",
"@pgtyped/wire": "^0.13.0",
"@types/chalk": "^2.2.0",

@@ -42,3 +42,3 @@ "@types/debug": "^4.1.4",

},
"gitHead": "e8bd84256ec0ec6d37ba89c7fca21f9a3360d763"
"gitHead": "e0cdcab201339ecc9a70de1c203813cf03d521f7"
}

@@ -166,2 +166,33 @@ import { generateHash, reduceTypeRows } from './actions';

).toMatchSnapshot();
expect(
reduceTypeRows([
{
oid: '16398',
typeName: 'notification_type',
typeKind: 'e',
enumLabel: 'notification',
},
{
oid: '16398',
typeName: 'notification_type',
typeKind: 'e',
enumLabel: 'reminder',
},
{
oid: '16398',
typeName: 'notification_type',
typeKind: 'e',
enumLabel: 'deadline',
},
{
oid: '24',
typeName: '_enum',
typeKind: 'b',
enumLabel: '',
typeCategory: 'A' as any,
elementTypeOid: '16398',
},
]),
).toMatchSnapshot();
});
import { AsyncQueue, messages, PreparedObjectType } from '@pgtyped/wire';
import crypto from 'crypto';
import debugBase from 'debug';
import * as tls from 'tls';
import debugBase from 'debug';
import { IInterpolatedQuery, QueryParam } from './preprocessor';
import {
checkServerFinalMessage,
createClientSASLContinueResponse,
createInitialSASLResponse,
} from './sasl-helpers';
import { DatabaseTypeKind, isEnum, MappableType } from './type';

@@ -48,2 +52,3 @@

messages.authenticationMD5Password,
messages.authenticationSASL,
);

@@ -55,15 +60,58 @@ if ('trxStatus' in result) {

if (!options.password) {
throw new Error('password required for MD5 hash auth');
throw new Error('password required for hash auth');
}
let password = options.password;
if ('salt' in result) {
// if MD5 auth scheme
if ('SASLMechanisms' in result) {
if (result.SASLMechanisms?.indexOf('SCRAM-SHA-256') === -1) {
throw new Error(
'SASL: Only mechanism SCRAM-SHA-256 is currently supported',
);
}
const { clientNonce, response: initialSASLResponse } =
createInitialSASLResponse();
await queue.send(messages.SASLInitialResponse, {
mechanism: 'SCRAM-SHA-256',
responseLength: Buffer.byteLength(initialSASLResponse),
response: initialSASLResponse,
});
const SASLContinueResult = await queue.reply(
messages.AuthenticationSASLContinue,
);
const { response: SASLContinueResponse, calculatedServerSignature } =
createClientSASLContinueResponse(
password,
clientNonce,
SASLContinueResult.SASLData,
);
await queue.send(messages.SASLResponse, {
response: SASLContinueResponse,
});
const finalMessage = await queue.multiMessageReply(
messages.authenticationSASLFinal,
messages.authenticationOk,
messages.parameterStatus,
messages.backendKeyData,
messages.readyForQuery,
);
const finalSASL = finalMessage.AuthenticationSASLFinal;
if ('SASLData' in finalSASL) {
checkServerFinalMessage(finalSASL.SASLData, calculatedServerSignature);
} else {
throw new Error('SASL: No final SASL data returned');
}
} else if ('salt' in result) {
password = generateHash(options.user, password, result.salt);
await queue.send(messages.passwordMessage, { password });
await queue.reply(messages.authenticationOk);
await queue.reply(messages.readyForQuery);
}
await queue.send(messages.passwordMessage, { password });
await queue.reply(messages.authenticationOk);
await queue.reply(messages.readyForQuery);
} catch (e) {
// tslint:disable-next-line:no-console
console.error(`Connection failed: ${e.message}`);
console.error(`Connection failed: ${(e as any).message}`);
process.exit(1);

@@ -195,2 +243,19 @@ }

enum TypeCategory {
ARRAY = 'A',
BOOLEAN = 'B',
COMPOSITE = 'C',
DATE_TIME = 'D',
ENUM = 'E',
GEOMETRIC = 'G',
NETWORK_ADDRESS = 'I',
NUMERIC = 'N',
PSEUDO = 'P',
STRING = 'S',
TIMESPAN = 'T',
USERDEFINED = 'U',
BITSTRING = 'V',
UNKNOWN = 'X',
}
interface TypeRow {

@@ -201,2 +266,4 @@ oid: string;

enumLabel: string;
typeCategory?: TypeCategory;
elementTypeOid?: string;
}

@@ -208,7 +275,7 @@

): Record<string, MappableType> {
return typeRows.reduce((typeMap, { oid, typeName, typeKind, enumLabel }) => {
// Attempt to merge any partially defined types
const typ = typeMap[oid] ?? typeName;
const enumTypes = typeRows
.filter((r) => r.typeKind === DatabaseTypeKind.Enum)
.reduce((typeMap, { oid, typeName, enumLabel }) => {
const typ = typeMap[oid] ?? typeName;
if (typeKind === DatabaseTypeKind.Enum && enumLabel) {
// We should get one row per enum value

@@ -223,6 +290,30 @@ return {

};
}
}, {} as Record<string, MappableType>);
return typeRows.reduce(
(typeMap, { oid, typeName, typeCategory, elementTypeOid }) => {
// Attempt to merge any partially defined types
const typ = typeMap[oid] ?? typeName;
return { ...typeMap, [oid]: typ };
}, {} as Record<string, MappableType>);
if (oid in enumTypes) {
return { ...typeMap, [oid]: enumTypes[oid] };
}
if (
typeCategory === TypeCategory.ARRAY &&
elementTypeOid &&
elementTypeOid in enumTypes
) {
return {
...typeMap,
[oid]: {
name: typeName,
elementType: enumTypes[elementTypeOid],
},
};
}
return { ...typeMap, [oid]: typ };
},
{} as Record<string, MappableType>,
);
}

@@ -237,8 +328,10 @@

if (typeOIDs.length > 0) {
const concatenatedTypeOids = typeOIDs.join(',');
rows = await runQuery(
`
SELECT pt.oid, pt.typname, pt.typtype, pe.enumlabel
SELECT pt.oid, pt.typname, pt.typtype, pe.enumlabel, pt.typelem, pt.typcategory
FROM pg_type pt
LEFT JOIN pg_enum pe ON pt.oid = pe.enumtypid
WHERE pt.oid IN (${typeOIDs.join(',')});
WHERE pt.oid IN (${concatenatedTypeOids})
OR pt.oid IN (SELECT typelem FROM pg_type ptn WHERE ptn.oid IN (${concatenatedTypeOids}));
`,

@@ -250,8 +343,12 @@ queue,

}
return rows.map(([oid, typeName, typeKind, enumLabel]) => ({
oid,
typeName,
typeKind,
enumLabel,
}));
return rows.map(
([oid, typeName, typeKind, enumLabel, elementTypeOid, typeCategory]) => ({
oid,
typeName,
typeKind,
enumLabel,
elementTypeOid,
typeCategory,
}),
);
}

@@ -258,0 +355,0 @@

@@ -121,3 +121,3 @@ // Generated from src/loader/sql/grammar/SQLLexer.g4 by ANTLR 4.9.0-SNAPSHOT

",\x02\x12.\x02\x130\x02\x142\x02\x15\x04\x02\x03\x07\x05\x02C\\aac|\x06" +
"\x022;C\\aac|\t\x02#(*1>B]]_`bb}\x80\x05\x02\v\f\x0F\x0F\"\"\x03\x02^" +
"\x022;C\\aac|\t\x02$(*1>B]]_`bb}\x80\x05\x02\v\f\x0F\x0F\"\"\x03\x02^" +
"^\x02\xA5\x02\b\x03\x02\x02\x02\x02\n\x03\x02\x02\x02\x02\f\x03\x02\x02" +

@@ -124,0 +124,0 @@ "\x02\x02\x0E\x03\x02\x02\x02\x02\x10\x03\x02\x02\x02\x02\x12\x03\x02\x02" +

@@ -338,3 +338,3 @@ // Generated from src/loader/sql/grammar/SQLParser.g4 by ANTLR 4.9.0-SNAPSHOT

_la = this._input.LA(1);
while ((((_la) & ~0x1F) === 0 && ((1 << _la) & ((1 << SQLParser.ID) | (1 << SQLParser.OPEN_COMMENT) | (1 << SQLParser.WORD) | (1 << SQLParser.STRING) | (1 << SQLParser.PARAM_MARK))) !== 0)) {
while ((((_la) & ~0x1F) === 0 && ((1 << _la) & ((1 << SQLParser.ID) | (1 << SQLParser.OPEN_COMMENT) | (1 << SQLParser.S_REQUIRED_MARK) | (1 << SQLParser.WORD) | (1 << SQLParser.STRING) | (1 << SQLParser.PARAM_MARK))) !== 0)) {
{

@@ -357,2 +357,3 @@ this.state = 80;

case SQLParser.ID:
case SQLParser.S_REQUIRED_MARK:
case SQLParser.WORD:

@@ -399,3 +400,3 @@ case SQLParser.STRING:

_la = this._input.LA(1);
if (!((((_la) & ~0x1F) === 0 && ((1 << _la) & ((1 << SQLParser.ID) | (1 << SQLParser.WORD) | (1 << SQLParser.STRING))) !== 0))) {
if (!((((_la) & ~0x1F) === 0 && ((1 << _la) & ((1 << SQLParser.ID) | (1 << SQLParser.S_REQUIRED_MARK) | (1 << SQLParser.WORD) | (1 << SQLParser.STRING))) !== 0))) {
this._errHandler.recoverInline(this);

@@ -457,3 +458,2 @@ } else {

this.enterRule(_localctx, 16, SQLParser.RULE_paramId);
let _la: number;
try {

@@ -466,4 +466,4 @@ this.enterOuterAlt(_localctx, 1);

this._errHandler.sync(this);
_la = this._input.LA(1);
if (_la === SQLParser.S_REQUIRED_MARK) {
switch ( this.interpreter.adaptivePredict(this._input, 6, this._ctx) ) {
case 1:
{

@@ -473,4 +473,4 @@ this.state = 91;

}
break;
}
}

@@ -846,3 +846,3 @@ }

"\x0E\x02\x10\x02\x12\x02\x14\x02\x16\x02\x18\x02\x1A\x02\x1C\x02\x1E\x02" +
" \x02\"\x02$\x02&\x02\x02\x04\x03\x02\x0E\x0E\x05\x02\x03\x03\x06\x06" +
" \x02\"\x02$\x02&\x02\x02\x04\x03\x02\x0E\x0E\x05\x02\x03\x03\x05\x06" +
"\t\t\x02\x88\x02/\x03\x02\x02\x02\x045\x03\x02\x02\x02\x068\x03\x02\x02" +

@@ -1155,2 +1155,3 @@ "\x02\bB\x03\x02\x02\x02\nK\x03\x02\x02\x02\fN\x03\x02\x02\x02\x0EW\x03" +

public STRING(): TerminalNode | undefined { return this.tryGetToken(SQLParser.STRING, 0); }
public S_REQUIRED_MARK(): TerminalNode | undefined { return this.tryGetToken(SQLParser.S_REQUIRED_MARK, 0); }
constructor(parent: ParserRuleContext | undefined, invokingState: number) {

@@ -1157,0 +1158,0 @@ super(parent, invokingState);

@@ -29,2 +29,35 @@ import parseSQLQuery from './loader/sql';

test('(SQL) two scalar params, one forced as non-null', () => {
const query = `
/*
@name UpdateBooksRankNotNull
*/
UPDATE books
SET
rank = :rank!,
name = :name
WHERE id = :id!;`;
const fileAST = parseSQLQuery(query);
const parameters = {
rank: 123,
name: 'name',
id: 'id',
};
const expectedInterpolationResult = {
query:
'UPDATE books\n SET\n rank = $1,\n name = $2\n WHERE id = $3',
mapping: [],
bindings: [123, 'name', 'id'],
};
const interpolationResult = processSQLQueryAST(
fileAST.queries[0],
parameters,
);
expect(interpolationResult).toEqual(expectedInterpolationResult);
});
test('(SQL) two scalar params', () => {

@@ -31,0 +64,0 @@ const query = `

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

export type Type = NamedType | ImportedType | AliasedType | EnumType;
export type Type =
| NamedType
| ImportedType
| AliasedType
| EnumType
| EnumArrayType;
// May be a database source type name (string) or a typescript destination type (Type)

@@ -23,2 +28,7 @@ export type MappableType = string | Type;

export interface EnumArrayType extends NamedType {
name: string;
elementType: EnumType;
}
export function isImport(typ: Type): typ is ImportedType {

@@ -36,2 +46,6 @@ return 'from' in typ;

export function isEnumArray(typ: MappableType): typ is EnumArrayType {
return typeof typ !== 'string' && 'elementType' in typ;
}
export const enum DatabaseTypeKind {

@@ -38,0 +52,0 @@ Base = 'b',

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

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

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