From 88aafd73fa02c35b7469bb6e38f6bef59d03825e Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 5 Jul 2014 16:22:20 -0700 Subject: [PATCH 01/58] Initial commit --- .gitignore | 25 +++++++++++++++++++++++++ LICENSE | 21 +++++++++++++++++++++ README.md | 4 ++++ 3 files changed, 50 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..da23d0d4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# Logs +logs +*.log + +# Runtime data +pids +*.pid +*.seed + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directory +# Deployed apps should consider commenting this line out: +# see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git +node_modules diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..b068a6cb --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2014 Iced Development + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 00000000..46afa27d --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +pg-connection-string +==================== + +Functions for dealing with a PostgresSQL connection string From 92c1fede8e7e3582b7040557cf2cb30705f59ad6 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 5 Jul 2014 16:43:58 -0700 Subject: [PATCH 02/58] initial commit --- .travis.yml | 3 ++ README.md | 14 ++++++++ index.js | 54 +++++++++++++++++++++++++++++++ package.json | 29 +++++++++++++++++ test/parse.js | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 189 insertions(+) create mode 100644 .travis.yml create mode 100644 index.js create mode 100644 package.json create mode 100644 test/parse.js diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..244b7e88 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,3 @@ +language: node_js +node_js: + - '0.10' diff --git a/README.md b/README.md index 46afa27d..49862702 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,18 @@ pg-connection-string ==================== +[![Build Status](https://travis-ci.org/iceddev/pg-connection-string.svg?branch=master)](https://travis-ci.org/iceddev/pg-connection-string) + Functions for dealing with a PostgresSQL connection string + +`parse` method taken from [node-postgres](https://github.com/brianc/node-postgres.git) +Copyright (c) 2010-2014 Brian Carlson (brian.m.carlson@gmail.com) +MIT License + +## Usage + +```js +var parse = require('pg-connection-string').parse; + +var config = parse('postgres://someuser:somepassword@somehost:381/sometable') +``` diff --git a/index.js b/index.js new file mode 100644 index 00000000..6c8fb68d --- /dev/null +++ b/index.js @@ -0,0 +1,54 @@ +'use strict'; + +var url = require('url'); + +//Parse method copied from https://github.com/brianc/node-postgres +//Copyright (c) 2010-2014 Brian Carlson (brian.m.carlson@gmail.com) +//MIT License + +//parses a connection string +function parse(str) { + var config; + //unix socket + if(str.charAt(0) === '/') { + config = str.split(' '); + return { host: config[0], database: config[1] }; + } + // url parse expects spaces encoded as %20 + if(/ |%[^a-f0-9]|%[a-f0-9][^a-f0-9]/i.test(str)) { + str = encodeURI(str).replace(/\%25(\d\d)/g, "%$1"); + } + var result = url.parse(str, true); + config = {}; + + if (result.query.application_name) { + config.application_name = result.query.application_name; + } + if (result.query.fallback_application_name) { + config.fallback_application_name = result.query.fallback_application_name; + } + + if(result.protocol == 'socket:') { + config.host = decodeURI(result.pathname); + config.database = result.query.db; + config.client_encoding = result.query.encoding; + return config; + } + config.host = result.hostname; + config.database = result.pathname ? decodeURI(result.pathname.slice(1)) : null; + var auth = (result.auth || ':').split(':'); + config.user = auth[0]; + config.password = auth[1]; + config.port = result.port; + + var ssl = result.query.ssl; + if (ssl === 'true' || ssl === '1') { + config.ssl = true; + } + + return config; +} + +module.exports = { + parse: parse +}; diff --git a/package.json b/package.json new file mode 100644 index 00000000..56f535dd --- /dev/null +++ b/package.json @@ -0,0 +1,29 @@ +{ + "name": "pg-connection-string", + "version": "0.1.0", + "description": "Functions for dealing with a PostgresSQL connection string", + "main": "index.js", + "scripts": { + "test": "tap ./test" + }, + "repository": { + "type": "git", + "url": "https://github.com/iceddev/pg-connection-string" + }, + "keywords": [ + "pg", + "connection", + "string", + "parse" + ], + "author": "Blaine Bublitz (http://iceddev.com/)", + "license": "MIT", + "bugs": { + "url": "https://github.com/iceddev/pg-connection-string/issues" + }, + "homepage": "https://github.com/iceddev/pg-connection-string", + "dependencies": {}, + "devDependencies": { + "tap": "^0.4.11" + } +} diff --git a/test/parse.js b/test/parse.js new file mode 100644 index 00000000..1b9b203c --- /dev/null +++ b/test/parse.js @@ -0,0 +1,89 @@ +'use strict'; + +var test = require('tap').test; + +var parse = require('../').parse; + +test('using connection string in client constructor', function(t){ + var subject = parse('postgres://brian:pw@boom:381/lala'); + t.equal(subject.user,'brian'); + t.equal(subject.password, 'pw'); + t.equal(subject.host, 'boom'); + t.equal(subject.port, '381'); + t.equal(subject.database, 'lala'); + t.end(); +}); + +test('escape spaces if present', function(t){ + var subject = parse('postgres://localhost/post gres'); + t.equal(subject.database, 'post gres'); + t.end(); +}); + +test('do not double escape spaces', function(t){ + var subject = parse('postgres://localhost/post%20gres'); + t.equal(subject.database, 'post gres'); + t.end(); +}); + +test('initializing with unix domain socket', function(t){ + var subject = parse('/var/run/'); + t.equal(subject.host, '/var/run/'); + t.end(); +}); + +test('initializing with unix domain socket and a specific database, the simple way', function(t){ + var subject = parse('/var/run/ mydb'); + t.equal(subject.host, '/var/run/'); + t.equal(subject.database, 'mydb'); + t.end(); +}); + +test('initializing with unix domain socket, the health way', function(t){ + var subject = parse('socket:/some path/?db=my[db]&encoding=utf8'); + t.equal(subject.host, '/some path/'); + t.equal(subject.database, 'my[db]', 'must to be escaped and unescaped trough "my%5Bdb%5D"'); + t.equal(subject.client_encoding, 'utf8'); + t.end(); +}); + +test('initializing with unix domain socket, the escaped health way', function(t){ + var subject = parse('socket:/some%20path/?db=my%2Bdb&encoding=utf8'); + t.equal(subject.host, '/some path/'); + t.equal(subject.database, 'my+db'); + t.equal(subject.client_encoding, 'utf8'); + t.end(); +}); + +test('password contains < and/or > characters', function(t){ + var sourceConfig = { + user:'brian', + password: 'helloe', + port: 5432, + host: 'localhost', + database: 'postgres' + }; + var connectionString = 'postgres://' + sourceConfig.user + ':' + sourceConfig.password + '@' + sourceConfig.host + ':' + sourceConfig.port + '/' + sourceConfig.database; + var subject = parse(connectionString); + t.equal(subject.password, sourceConfig.password); + t.end(); +}); + +test('username or password contains weird characters', function(t){ + var strang = 'pg://my f%irst name:is&%awesome!@localhost:9000'; + var subject = parse(strang); + t.equal(subject.user, 'my f%irst name'); + t.equal(subject.password, 'is&%awesome!'); + t.equal(subject.host, 'localhost'); + t.end(); +}); + +test('url is properly encoded', function(t){ + var encoded = 'pg://bi%25na%25%25ry%20:s%40f%23@localhost/%20u%2520rl'; + var subject = parse(encoded); + t.equal(subject.user, 'bi%na%%ry '); + t.equal(subject.password, 's@f#'); + t.equal(subject.host, 'localhost'); + t.equal(subject.database, ' u%20rl'); + t.end(); +}); From df2a24c55550d48afe9d6b57dff7b7c027ba124e Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 6 Jul 2014 16:33:53 -0700 Subject: [PATCH 03/58] attach port always - ref brianc/node-postgres#604 --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 6c8fb68d..afb36996 100644 --- a/index.js +++ b/index.js @@ -28,6 +28,7 @@ function parse(str) { config.fallback_application_name = result.query.fallback_application_name; } + config.port = result.port; if(result.protocol == 'socket:') { config.host = decodeURI(result.pathname); config.database = result.query.db; @@ -39,7 +40,6 @@ function parse(str) { var auth = (result.auth || ':').split(':'); config.user = auth[0]; config.password = auth[1]; - config.port = result.port; var ssl = result.query.ssl; if (ssl === 'true' || ssl === '1') { From cb9bee1bc9d65366d516fd2808726f285c9ad72f Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sun, 6 Jul 2014 16:34:14 -0700 Subject: [PATCH 04/58] 0.1.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 56f535dd..2cb8d962 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pg-connection-string", - "version": "0.1.0", + "version": "0.1.1", "description": "Functions for dealing with a PostgresSQL connection string", "main": "index.js", "scripts": { From ba511f7803dd159447ca7801177dd9008b9958b3 Mon Sep 17 00:00:00 2001 From: "matthew.blasius" Date: Fri, 12 Sep 2014 11:21:33 -0400 Subject: [PATCH 05/58] Support usage of relative urls to set database on the default host --- index.js | 10 +++++++++- test/parse.js | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index afb36996..b041a208 100644 --- a/index.js +++ b/index.js @@ -36,7 +36,15 @@ function parse(str) { return config; } config.host = result.hostname; - config.database = result.pathname ? decodeURI(result.pathname.slice(1)) : null; + + // result.pathname is not always guaranteed to have a '/' prefix (e.g. relative urls) + // only strip the slash if it is present. + var pathname = result.pathname; + if (pathname && pathname.charAt(0) === '/') { + pathname = result.pathname.slice(1) || null; + } + config.database = pathname && decodeURI(pathname); + var auth = (result.auth || ':').split(':'); config.user = auth[0]; config.password = auth[1]; diff --git a/test/parse.js b/test/parse.js index 1b9b203c..89269429 100644 --- a/test/parse.js +++ b/test/parse.js @@ -87,3 +87,26 @@ test('url is properly encoded', function(t){ t.equal(subject.database, ' u%20rl'); t.end(); }); + +test('relative url sets database', function(t){ + var relative = 'different_db_on_default_host'; + var subject = parse(relative); + t.equal(subject.database, 'different_db_on_default_host'); + t.end(); +}); + +test('no pathname returns null database', function (t) { + var subject = parse('pg://myhost'); + t.equal(subject.host, 'myhost'); + t.type(subject.database, 'null'); + + t.end(); +}); + +test('pathname of "/" returns null database', function (t) { + var subject = parse('pg://myhost/'); + t.equal(subject.host, 'myhost'); + t.type(subject.database, 'null'); + + t.end(); +}); From 245abd6daf838d6d2e0424debcfffc2e8b3e3508 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 13 Sep 2014 09:20:28 -0700 Subject: [PATCH 06/58] 0.1.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2cb8d962..ebac6ca4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pg-connection-string", - "version": "0.1.1", + "version": "0.1.2", "description": "Functions for dealing with a PostgresSQL connection string", "main": "index.js", "scripts": { From fbdd033d6c90cf5f9c2f6f258bc77a2184345f20 Mon Sep 17 00:00:00 2001 From: Ivan Sorokin Date: Fri, 26 Sep 2014 15:59:57 +0300 Subject: [PATCH 07/58] Add supporting password with colon --- index.js | 2 +- test/parse.js | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index b041a208..ac2fd64c 100644 --- a/index.js +++ b/index.js @@ -47,7 +47,7 @@ function parse(str) { var auth = (result.auth || ':').split(':'); config.user = auth[0]; - config.password = auth[1]; + config.password = auth.splice(1).join(':'); var ssl = result.query.ssl; if (ssl === 'true' || ssl === '1') { diff --git a/test/parse.js b/test/parse.js index 89269429..c1494c31 100644 --- a/test/parse.js +++ b/test/parse.js @@ -69,6 +69,20 @@ test('password contains < and/or > characters', function(t){ t.end(); }); +test('password contains colons', function(t){ + var sourceConfig = { + user:'brian', + password: 'hello:pass:world', + port: 5432, + host: 'localhost', + database: 'postgres' + }; + var connectionString = 'postgres://' + sourceConfig.user + ':' + sourceConfig.password + '@' + sourceConfig.host + ':' + sourceConfig.port + '/' + sourceConfig.database; + var subject = parse(connectionString); + t.equal(subject.password, sourceConfig.password); + t.end(); +}); + test('username or password contains weird characters', function(t){ var strang = 'pg://my f%irst name:is&%awesome!@localhost:9000'; var subject = parse(strang); From 4c151b9403420c1c9a9682facef1fcdbb9b79b3b Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Fri, 26 Sep 2014 14:22:46 -0700 Subject: [PATCH 08/58] 0.1.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ebac6ca4..c6d4512d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pg-connection-string", - "version": "0.1.2", + "version": "0.1.3", "description": "Functions for dealing with a PostgresSQL connection string", "main": "index.js", "scripts": { From c612dfabd58071e9896b1e9ba0b5e5bcbb0c2f6b Mon Sep 17 00:00:00 2001 From: Mike He Date: Tue, 13 Oct 2015 09:19:26 +1100 Subject: [PATCH 09/58] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 49862702..ddf9bfcb 100644 --- a/README.md +++ b/README.md @@ -14,5 +14,5 @@ MIT License ```js var parse = require('pg-connection-string').parse; -var config = parse('postgres://someuser:somepassword@somehost:381/sometable') +var config = parse('postgres://someuser:somepassword@somehost:381/somedatabase') ``` From cdf06edd14d7b4b1df4c7e3cf438e8d9eeeaf271 Mon Sep 17 00:00:00 2001 From: Moti Zilberman Date: Wed, 30 Dec 2015 15:16:38 +0200 Subject: [PATCH 10/58] Copy all but special-cased params from URL query string to config --- index.js | 19 +++++++++------ test/parse.js | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index ac2fd64c..b2863dde 100644 --- a/index.js +++ b/index.js @@ -21,13 +21,6 @@ function parse(str) { var result = url.parse(str, true); config = {}; - if (result.query.application_name) { - config.application_name = result.query.application_name; - } - if (result.query.fallback_application_name) { - config.fallback_application_name = result.query.fallback_application_name; - } - config.port = result.port; if(result.protocol == 'socket:') { config.host = decodeURI(result.pathname); @@ -54,6 +47,18 @@ function parse(str) { config.ssl = true; } + ['db', 'database', 'encoding', 'client_encoding', 'host', 'port', 'user', 'password', 'ssl'] + .forEach(function(key) { + delete result.query[key]; + }); + + Object.getOwnPropertyNames(result.query).forEach(function(key) { + var value = result.query[key]; + if (Array.isArray(value)) + value = value[value.length-1]; + config[key] = value; + }); + return config; } diff --git a/test/parse.js b/test/parse.js index c1494c31..bd1171ba 100644 --- a/test/parse.js +++ b/test/parse.js @@ -124,3 +124,67 @@ test('pathname of "/" returns null database', function (t) { t.end(); }); + +test('configuration parameter application_name', function(t){ + var connectionString = 'pg:///?application_name=TheApp'; + var subject = parse(connectionString); + t.equal(subject.application_name, 'TheApp'); + t.end(); +}); + +test('configuration parameter fallback_application_name', function(t){ + var connectionString = 'pg:///?fallback_application_name=TheAppFallback'; + var subject = parse(connectionString); + t.equal(subject.fallback_application_name, 'TheAppFallback'); + t.end(); +}); + +test('configuration parameter fallback_application_name', function(t){ + var connectionString = 'pg:///?fallback_application_name=TheAppFallback'; + var subject = parse(connectionString); + t.equal(subject.fallback_application_name, 'TheAppFallback'); + t.end(); +}); + +test('configuration parameter ssl=true', function(t){ + var connectionString = 'pg:///?ssl=true'; + var subject = parse(connectionString); + t.equal(subject.ssl, true); + t.end(); +}); + +test('configuration parameter ssl=1', function(t){ + var connectionString = 'pg:///?ssl=1'; + var subject = parse(connectionString); + t.equal(subject.ssl, true); + t.end(); +}); + +test('configuration parameter keepalives', function(t){ + var connectionString = 'pg:///?keepalives=1'; + var subject = parse(connectionString); + t.equal(subject.keepalives, '1'); + t.end(); +}); + +test('unknown configuration parameter is passed into client', function(t){ + var connectionString = 'pg:///?ThereIsNoSuchPostgresParameter=1234'; + var subject = parse(connectionString); + t.equal(subject.ThereIsNoSuchPostgresParameter, '1234'); + t.end(); +}); + +test('do not override a config field with value from query string', function(t){ + var subject = parse('socket:/some path/?db=my[db]&encoding=utf8&client_encoding=bogus'); + t.equal(subject.host, '/some path/'); + t.equal(subject.database, 'my[db]', 'must to be escaped and unescaped trough "my%5Bdb%5D"'); + t.equal(subject.client_encoding, 'utf8'); + t.end(); +}); + +test('return last value of repeated parameter', function(t){ + var connectionString = 'pg:///?keepalives=1&keepalives=0'; + var subject = parse(connectionString); + t.equal(subject.keepalives, '0'); + t.end(); +}); \ No newline at end of file From 54c204441629b65754dade6cb58a443566fefb22 Mon Sep 17 00:00:00 2001 From: Attila Olah Date: Thu, 27 Apr 2017 12:41:30 +0200 Subject: [PATCH 11/58] feat: add basic typings To make this app consumable by Typescript apps a typings file must be present. --- index.d.ts | 14 ++++++++++++++ package.json | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 index.d.ts diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 00000000..55637511 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,14 @@ +export function parse(connectionString: string): ConnectionOptions; + +export interface ConnectionOptions { + host: string | null; + password: string | null; + user: string | null; + port: number | null; + database: string | null; + client_encoding: string | null; + ssl: boolean | null; + + application_name: string | null; + fallback_application_name: string | null; +} diff --git a/package.json b/package.json index c6d4512d..f3b14c90 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,8 @@ "name": "pg-connection-string", "version": "0.1.3", "description": "Functions for dealing with a PostgresSQL connection string", - "main": "index.js", + "main": "./index.js", + "types": "./index.d.ts", "scripts": { "test": "tap ./test" }, From 9ab62ff9f3050bc8d1096cd6f1258cd288be75fd Mon Sep 17 00:00:00 2001 From: caub Date: Sat, 1 Jul 2017 11:32:37 +0200 Subject: [PATCH 12/58] allow min/max params for pg-pool --- .gitignore | 1 + .travis.yml | 2 ++ index.js | 36 +++++++++++++----------------------- package.json | 2 +- test/parse.js | 18 +++++++++++++++++- 5 files changed, 34 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index da23d0d4..f28f01f7 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ build/Release # Deployed apps should consider commenting this line out: # see https://npmjs.org/doc/faq.html#Should-I-check-my-node_modules-folder-into-git node_modules +package-lock.json \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 244b7e88..202c3078 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ language: node_js node_js: - '0.10' + - '6.9' + - '8' diff --git a/index.js b/index.js index b2863dde..0042faec 100644 --- a/index.js +++ b/index.js @@ -8,18 +8,20 @@ var url = require('url'); //parses a connection string function parse(str) { - var config; //unix socket if(str.charAt(0) === '/') { - config = str.split(' '); + var config = str.split(' '); return { host: config[0], database: config[1] }; } + // url parse expects spaces encoded as %20 - if(/ |%[^a-f0-9]|%[a-f0-9][^a-f0-9]/i.test(str)) { - str = encodeURI(str).replace(/\%25(\d\d)/g, "%$1"); + var result = url.parse(/ |%[^a-f0-9]|%[a-f0-9][^a-f0-9]/i.test(str) ? encodeURI(str).replace(/\%25(\d\d)/g, "%$1") : str, true); + var config = result.query; + for (var k in config) { + if (Array.isArray(config[k])) { + config[k] = config[k][config[k].length-1]; + } } - var result = url.parse(str, true); - config = {}; config.port = result.port; if(result.protocol == 'socket:') { @@ -42,26 +44,14 @@ function parse(str) { config.user = auth[0]; config.password = auth.splice(1).join(':'); - var ssl = result.query.ssl; - if (ssl === 'true' || ssl === '1') { + if (config.ssl === 'true' || config.ssl === '1') { config.ssl = true; } - ['db', 'database', 'encoding', 'client_encoding', 'host', 'port', 'user', 'password', 'ssl'] - .forEach(function(key) { - delete result.query[key]; - }); - - Object.getOwnPropertyNames(result.query).forEach(function(key) { - var value = result.query[key]; - if (Array.isArray(value)) - value = value[value.length-1]; - config[key] = value; - }); - return config; } -module.exports = { - parse: parse -}; + +module.exports = parse; + +parse.parse = parse; diff --git a/package.json b/package.json index f3b14c90..9b0e62ec 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,6 @@ "homepage": "https://github.com/iceddev/pg-connection-string", "dependencies": {}, "devDependencies": { - "tap": "^0.4.11" + "tap": "^10.3.3" } } diff --git a/test/parse.js b/test/parse.js index bd1171ba..8f4bcb43 100644 --- a/test/parse.js +++ b/test/parse.js @@ -160,6 +160,20 @@ test('configuration parameter ssl=1', function(t){ t.end(); }); +test('set ssl', function (t) { + var subject = parse('pg://myhost/db?ssl=1'); + t.equal(subject.ssl, true); + t.end(); + }); + + test('allow other params like max, ...', function (t) { + var subject = parse('pg://myhost/db?max=18&min=4'); + t.equal(subject.max, '18'); + t.equal(subject.min, '4'); + t.end(); + }); + + test('configuration parameter keepalives', function(t){ var connectionString = 'pg:///?keepalives=1'; var subject = parse(connectionString); @@ -182,9 +196,11 @@ test('do not override a config field with value from query string', function(t){ t.end(); }); + test('return last value of repeated parameter', function(t){ var connectionString = 'pg:///?keepalives=1&keepalives=0'; var subject = parse(connectionString); t.equal(subject.keepalives, '0'); t.end(); -}); \ No newline at end of file +}); + From 13687353c9ecc4b2ea736ee0784a6a158a40a951 Mon Sep 17 00:00:00 2001 From: Luis Montes Date: Wed, 30 Aug 2017 13:58:52 -0700 Subject: [PATCH 13/58] Use mocha, istanbul, and coveralls (#16) * some tests * coveralls and mocha * coveralls post test hook * remove done calls --- .coveralls.yml | 2 + .travis.yml | 1 + README.md | 3 + package.json | 8 +- test/parse.js | 376 +++++++++++++++++++++++-------------------------- 5 files changed, 188 insertions(+), 202 deletions(-) create mode 100644 .coveralls.yml diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 00000000..0709f6e0 --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1,2 @@ +service_name: travis-pro +repo_token: 5F6dODinz9L9uFR6HatKmtsYDoV1A5S2N diff --git a/.travis.yml b/.travis.yml index 202c3078..daf50ba6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,3 +3,4 @@ node_js: - '0.10' - '6.9' - '8' +after_success: 'npm run coveralls' diff --git a/README.md b/README.md index ddf9bfcb..2228b80e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ pg-connection-string ==================== +[![NPM](https://nodei.co/npm/pg-connection-string.png?compact=true)](https://nodei.co/npm/pg-connection-string/) + [![Build Status](https://travis-ci.org/iceddev/pg-connection-string.svg?branch=master)](https://travis-ci.org/iceddev/pg-connection-string) +[![Coverage Status](https://coveralls.io/repos/iceddev/pg-connection-string/badge.svg?branch=master)](https://coveralls.io/r/iceddev/pg-connection-string?branch=master) Functions for dealing with a PostgresSQL connection string diff --git a/package.json b/package.json index 9b0e62ec..f6ff6e51 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,9 @@ "main": "./index.js", "types": "./index.d.ts", "scripts": { - "test": "tap ./test" + "test": "istanbul cover _mocha && npm run check-coverage", + "check-coverage": "istanbul check-coverage --statements 100 --branches 100 --lines 100 --functions 100", + "coveralls": "cat ./coverage/lcov.info | ./node_modules/.bin/coveralls" }, "repository": { "type": "git", @@ -25,6 +27,8 @@ "homepage": "https://github.com/iceddev/pg-connection-string", "dependencies": {}, "devDependencies": { - "tap": "^10.3.3" + "chai": "^4.1.1", + "istanbul": "^0.4.5", + "mocha": "^3.5.0" } } diff --git a/test/parse.js b/test/parse.js index 8f4bcb43..8ff3ee81 100644 --- a/test/parse.js +++ b/test/parse.js @@ -1,206 +1,182 @@ 'use strict'; -var test = require('tap').test; +var chai = require('chai'); +var expect = chai.expect; +chai.should(); var parse = require('../').parse; -test('using connection string in client constructor', function(t){ - var subject = parse('postgres://brian:pw@boom:381/lala'); - t.equal(subject.user,'brian'); - t.equal(subject.password, 'pw'); - t.equal(subject.host, 'boom'); - t.equal(subject.port, '381'); - t.equal(subject.database, 'lala'); - t.end(); +describe('parse', function(){ + + it('using connection string in client constructor', function(){ + var subject = parse('postgres://brian:pw@boom:381/lala'); + subject.user.should.equal('brian'); + subject.password.should.equal( 'pw'); + subject.host.should.equal( 'boom'); + subject.port.should.equal( '381'); + subject.database.should.equal( 'lala'); + }); + + it('escape spaces if present', function(){ + var subject = parse('postgres://localhost/post gres'); + subject.database.should.equal('post gres'); + }); + + it('do not double escape spaces', function(){ + var subject = parse('postgres://localhost/post%20gres'); + subject.database.should.equal('post gres'); + }); + + it('initializing with unix domain socket', function(){ + var subject = parse('/var/run/'); + subject.host.should.equal('/var/run/'); + }); + + it('initializing with unix domain socket and a specific database, the simple way', function(){ + var subject = parse('/var/run/ mydb'); + subject.host.should.equal('/var/run/'); + subject.database.should.equal('mydb'); + }); + + it('initializing with unix domain socket, the health way', function(){ + var subject = parse('socket:/some path/?db=my[db]&encoding=utf8'); + subject.host.should.equal('/some path/'); + subject.database.should.equal('my[db]', 'must to be escaped and unescaped trough "my%5Bdb%5D"'); + subject.client_encoding.should.equal('utf8'); + }); + + it('initializing with unix domain socket, the escaped health way', function(){ + var subject = parse('socket:/some%20path/?db=my%2Bdb&encoding=utf8'); + subject.host.should.equal('/some path/'); + subject.database.should.equal('my+db'); + subject.client_encoding.should.equal('utf8'); + }); + + it('password contains < and/or > characters', function(){ + var sourceConfig = { + user:'brian', + password: 'helloe', + port: 5432, + host: 'localhost', + database: 'postgres' + }; + var connectionString = 'postgres://' + sourceConfig.user + ':' + sourceConfig.password + '@' + sourceConfig.host + ':' + sourceConfig.port + '/' + sourceConfig.database; + var subject = parse(connectionString); + subject.password.should.equal(sourceConfig.password); + }); + + it('password contains colons', function(){ + var sourceConfig = { + user:'brian', + password: 'hello:pass:world', + port: 5432, + host: 'localhost', + database: 'postgres' + }; + var connectionString = 'postgres://' + sourceConfig.user + ':' + sourceConfig.password + '@' + sourceConfig.host + ':' + sourceConfig.port + '/' + sourceConfig.database; + var subject = parse(connectionString); + subject.password.should.equal(sourceConfig.password); + }); + + it('username or password contains weird characters', function(){ + var strang = 'pg://my f%irst name:is&%awesome!@localhost:9000'; + var subject = parse(strang); + subject.user.should.equal('my f%irst name'); + subject.password.should.equal('is&%awesome!'); + subject.host.should.equal('localhost'); + }); + + it('url is properly encoded', function(){ + var encoded = 'pg://bi%25na%25%25ry%20:s%40f%23@localhost/%20u%2520rl'; + var subject = parse(encoded); + subject.user.should.equal('bi%na%%ry '); + subject.password.should.equal('s@f#'); + subject.host.should.equal('localhost'); + subject.database.should.equal(' u%20rl'); + }); + + it('relative url sets database', function(){ + var relative = 'different_db_on_default_host'; + var subject = parse(relative); + subject.database.should.equal('different_db_on_default_host'); + }); + + it('no pathname returns null database', function () { + var subject = parse('pg://myhost'); + (subject.database === null).should.equal(true); + }); + + it('pathname of "/" returns null database', function () { + var subject = parse('pg://myhost/'); + subject.host.should.equal('myhost'); + (subject.database === null).should.equal(true); + }); + + it('configuration parameter application_name', function(){ + var connectionString = 'pg:///?application_name=TheApp'; + var subject = parse(connectionString); + subject.application_name.should.equal('TheApp'); + }); + + it('configuration parameter fallback_application_name', function(){ + var connectionString = 'pg:///?fallback_application_name=TheAppFallback'; + var subject = parse(connectionString); + subject.fallback_application_name.should.equal('TheAppFallback'); + }); + + it('configuration parameter fallback_application_name', function(){ + var connectionString = 'pg:///?fallback_application_name=TheAppFallback'; + var subject = parse(connectionString); + subject.fallback_application_name.should.equal('TheAppFallback'); + }); + + it('configuration parameter ssl=true', function(){ + var connectionString = 'pg:///?ssl=true'; + var subject = parse(connectionString); + subject.ssl.should.equal(true); + }); + + it('configuration parameter ssl=1', function(){ + var connectionString = 'pg:///?ssl=1'; + var subject = parse(connectionString); + subject.ssl.should.equal(true); + }); + + it('set ssl', function () { + var subject = parse('pg://myhost/db?ssl=1'); + subject.ssl.should.equal(true); + }); + + it('allow other params like max, ...', function () { + var subject = parse('pg://myhost/db?max=18&min=4'); + subject.max.should.equal('18'); + subject.min.should.equal('4'); + }); + + + it('configuration parameter keepalives', function(){ + var connectionString = 'pg:///?keepalives=1'; + var subject = parse(connectionString); + subject.keepalives.should.equal('1'); + }); + + it('unknown configuration parameter is passed into client', function(){ + var connectionString = 'pg:///?ThereIsNoSuchPostgresParameter=1234'; + var subject = parse(connectionString); + subject.ThereIsNoSuchPostgresParameter.should.equal('1234'); + }); + + it('do not override a config field with value from query string', function(){ + var subject = parse('socket:/some path/?db=my[db]&encoding=utf8&client_encoding=bogus'); + subject.host.should.equal('/some path/'); + subject.database.should.equal('my[db]', 'must to be escaped and unescaped through "my%5Bdb%5D"'); + subject.client_encoding.should.equal('utf8'); + }); + + + it('return last value of repeated parameter', function(){ + var connectionString = 'pg:///?keepalives=1&keepalives=0'; + var subject = parse(connectionString); + subject.keepalives.should.equal('0'); + }); }); - -test('escape spaces if present', function(t){ - var subject = parse('postgres://localhost/post gres'); - t.equal(subject.database, 'post gres'); - t.end(); -}); - -test('do not double escape spaces', function(t){ - var subject = parse('postgres://localhost/post%20gres'); - t.equal(subject.database, 'post gres'); - t.end(); -}); - -test('initializing with unix domain socket', function(t){ - var subject = parse('/var/run/'); - t.equal(subject.host, '/var/run/'); - t.end(); -}); - -test('initializing with unix domain socket and a specific database, the simple way', function(t){ - var subject = parse('/var/run/ mydb'); - t.equal(subject.host, '/var/run/'); - t.equal(subject.database, 'mydb'); - t.end(); -}); - -test('initializing with unix domain socket, the health way', function(t){ - var subject = parse('socket:/some path/?db=my[db]&encoding=utf8'); - t.equal(subject.host, '/some path/'); - t.equal(subject.database, 'my[db]', 'must to be escaped and unescaped trough "my%5Bdb%5D"'); - t.equal(subject.client_encoding, 'utf8'); - t.end(); -}); - -test('initializing with unix domain socket, the escaped health way', function(t){ - var subject = parse('socket:/some%20path/?db=my%2Bdb&encoding=utf8'); - t.equal(subject.host, '/some path/'); - t.equal(subject.database, 'my+db'); - t.equal(subject.client_encoding, 'utf8'); - t.end(); -}); - -test('password contains < and/or > characters', function(t){ - var sourceConfig = { - user:'brian', - password: 'helloe', - port: 5432, - host: 'localhost', - database: 'postgres' - }; - var connectionString = 'postgres://' + sourceConfig.user + ':' + sourceConfig.password + '@' + sourceConfig.host + ':' + sourceConfig.port + '/' + sourceConfig.database; - var subject = parse(connectionString); - t.equal(subject.password, sourceConfig.password); - t.end(); -}); - -test('password contains colons', function(t){ - var sourceConfig = { - user:'brian', - password: 'hello:pass:world', - port: 5432, - host: 'localhost', - database: 'postgres' - }; - var connectionString = 'postgres://' + sourceConfig.user + ':' + sourceConfig.password + '@' + sourceConfig.host + ':' + sourceConfig.port + '/' + sourceConfig.database; - var subject = parse(connectionString); - t.equal(subject.password, sourceConfig.password); - t.end(); -}); - -test('username or password contains weird characters', function(t){ - var strang = 'pg://my f%irst name:is&%awesome!@localhost:9000'; - var subject = parse(strang); - t.equal(subject.user, 'my f%irst name'); - t.equal(subject.password, 'is&%awesome!'); - t.equal(subject.host, 'localhost'); - t.end(); -}); - -test('url is properly encoded', function(t){ - var encoded = 'pg://bi%25na%25%25ry%20:s%40f%23@localhost/%20u%2520rl'; - var subject = parse(encoded); - t.equal(subject.user, 'bi%na%%ry '); - t.equal(subject.password, 's@f#'); - t.equal(subject.host, 'localhost'); - t.equal(subject.database, ' u%20rl'); - t.end(); -}); - -test('relative url sets database', function(t){ - var relative = 'different_db_on_default_host'; - var subject = parse(relative); - t.equal(subject.database, 'different_db_on_default_host'); - t.end(); -}); - -test('no pathname returns null database', function (t) { - var subject = parse('pg://myhost'); - t.equal(subject.host, 'myhost'); - t.type(subject.database, 'null'); - - t.end(); -}); - -test('pathname of "/" returns null database', function (t) { - var subject = parse('pg://myhost/'); - t.equal(subject.host, 'myhost'); - t.type(subject.database, 'null'); - - t.end(); -}); - -test('configuration parameter application_name', function(t){ - var connectionString = 'pg:///?application_name=TheApp'; - var subject = parse(connectionString); - t.equal(subject.application_name, 'TheApp'); - t.end(); -}); - -test('configuration parameter fallback_application_name', function(t){ - var connectionString = 'pg:///?fallback_application_name=TheAppFallback'; - var subject = parse(connectionString); - t.equal(subject.fallback_application_name, 'TheAppFallback'); - t.end(); -}); - -test('configuration parameter fallback_application_name', function(t){ - var connectionString = 'pg:///?fallback_application_name=TheAppFallback'; - var subject = parse(connectionString); - t.equal(subject.fallback_application_name, 'TheAppFallback'); - t.end(); -}); - -test('configuration parameter ssl=true', function(t){ - var connectionString = 'pg:///?ssl=true'; - var subject = parse(connectionString); - t.equal(subject.ssl, true); - t.end(); -}); - -test('configuration parameter ssl=1', function(t){ - var connectionString = 'pg:///?ssl=1'; - var subject = parse(connectionString); - t.equal(subject.ssl, true); - t.end(); -}); - -test('set ssl', function (t) { - var subject = parse('pg://myhost/db?ssl=1'); - t.equal(subject.ssl, true); - t.end(); - }); - - test('allow other params like max, ...', function (t) { - var subject = parse('pg://myhost/db?max=18&min=4'); - t.equal(subject.max, '18'); - t.equal(subject.min, '4'); - t.end(); - }); - - -test('configuration parameter keepalives', function(t){ - var connectionString = 'pg:///?keepalives=1'; - var subject = parse(connectionString); - t.equal(subject.keepalives, '1'); - t.end(); -}); - -test('unknown configuration parameter is passed into client', function(t){ - var connectionString = 'pg:///?ThereIsNoSuchPostgresParameter=1234'; - var subject = parse(connectionString); - t.equal(subject.ThereIsNoSuchPostgresParameter, '1234'); - t.end(); -}); - -test('do not override a config field with value from query string', function(t){ - var subject = parse('socket:/some path/?db=my[db]&encoding=utf8&client_encoding=bogus'); - t.equal(subject.host, '/some path/'); - t.equal(subject.database, 'my[db]', 'must to be escaped and unescaped trough "my%5Bdb%5D"'); - t.equal(subject.client_encoding, 'utf8'); - t.end(); -}); - - -test('return last value of repeated parameter', function(t){ - var connectionString = 'pg:///?keepalives=1&keepalives=0'; - var subject = parse(connectionString); - t.equal(subject.keepalives, '0'); - t.end(); -}); - From eafb7acd951b4ee606d41c0d1ba66b34e72119a3 Mon Sep 17 00:00:00 2001 From: Luis Montes Date: Wed, 30 Aug 2017 14:25:59 -0700 Subject: [PATCH 14/58] 2.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f6ff6e51..5b75ea37 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pg-connection-string", - "version": "0.1.3", + "version": "2.0.0", "description": "Functions for dealing with a PostgresSQL connection string", "main": "./index.js", "types": "./index.d.ts", From 279fdeae2fdd331197d74d6f31a201bba1bdf7cf Mon Sep 17 00:00:00 2001 From: Youngwook Kim Date: Wed, 22 Nov 2017 10:17:22 +0900 Subject: [PATCH 15/58] Add supporting username and password for socket connections This fix adds the ability to use username and password even when using a socket. --- index.js | 8 ++++---- test/parse.js | 8 ++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 0042faec..3e04f547 100644 --- a/index.js +++ b/index.js @@ -23,6 +23,10 @@ function parse(str) { } } + var auth = (result.auth || ':').split(':'); + config.user = auth[0]; + config.password = auth.splice(1).join(':'); + config.port = result.port; if(result.protocol == 'socket:') { config.host = decodeURI(result.pathname); @@ -40,10 +44,6 @@ function parse(str) { } config.database = pathname && decodeURI(pathname); - var auth = (result.auth || ':').split(':'); - config.user = auth[0]; - config.password = auth.splice(1).join(':'); - if (config.ssl === 'true' || config.ssl === '1') { config.ssl = true; } diff --git a/test/parse.js b/test/parse.js index 8ff3ee81..42936733 100644 --- a/test/parse.js +++ b/test/parse.js @@ -52,6 +52,14 @@ describe('parse', function(){ subject.client_encoding.should.equal('utf8'); }); + it('initializing with unix domain socket, username and password', function(){ + var subject = parse('socket://brian:pw@/var/run/?db=mydb'); + subject.user.should.equal('brian'); + subject.password.should.equal('pw'); + subject.host.should.equal('/var/run/'); + subject.database.should.equal('mydb'); + }); + it('password contains < and/or > characters', function(){ var sourceConfig = { user:'brian', From 929fcb73c3f5128e2d1d50eb5d62a6481d098754 Mon Sep 17 00:00:00 2001 From: benny-medflyt Date: Wed, 13 Dec 2017 11:20:29 +0200 Subject: [PATCH 16/58] Fix typings --- index.d.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/index.d.ts b/index.d.ts index 55637511..d0fc7214 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,14 +1,14 @@ export function parse(connectionString: string): ConnectionOptions; export interface ConnectionOptions { - host: string | null; - password: string | null; - user: string | null; - port: number | null; - database: string | null; - client_encoding: string | null; - ssl: boolean | null; + host: string; + password?: string; + user?: string; + port: string | null; + database: string | null | undefined; + client_encoding?: string | undefined; + ssl?: boolean; - application_name: string | null; - fallback_application_name: string | null; + application_name?: string; + fallback_application_name?: string; } From ece764518774690ea8ee58360ae0b6ca7b248d4d Mon Sep 17 00:00:00 2001 From: benny-medflyt Date: Wed, 13 Dec 2017 11:23:28 +0200 Subject: [PATCH 17/58] typings: turns out "host" can actually be `null` --- index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.d.ts b/index.d.ts index d0fc7214..2a657460 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,7 +1,7 @@ export function parse(connectionString: string): ConnectionOptions; export interface ConnectionOptions { - host: string; + host: string | null; password?: string; user?: string; port: string | null; From c11dbb1c2b3409964372721666d3a2898dd2097e Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 18 Apr 2019 14:46:36 +0100 Subject: [PATCH 18/58] Only publish the required files Details: https://docs.npmjs.com/files/package.json#files --- package.json | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 5b75ea37..b625a16d 100644 --- a/package.json +++ b/package.json @@ -30,5 +30,9 @@ "chai": "^4.1.1", "istanbul": "^0.4.5", "mocha": "^3.5.0" - } + }, + "files": [ + "index.js", + "index.d.ts" + ] } From e9270e89af6c6e5b84b8c668bf206c8f9ab97a45 Mon Sep 17 00:00:00 2001 From: "Herman J. Radtke III" Date: Fri, 17 May 2019 07:38:25 -0700 Subject: [PATCH 19/58] Add support for TLS parameters in URI The connection string now supports the following parameters: - sslcert - sslkey - sslrootcert Fixes #25. --- index.js | 17 +++++++++++++++++ test/example.ca | 1 + test/example.cert | 1 + test/example.key | 1 + test/parse.js | 24 ++++++++++++++++++++++++ 5 files changed, 44 insertions(+) create mode 100644 test/example.ca create mode 100644 test/example.cert create mode 100644 test/example.key diff --git a/index.js b/index.js index 0042faec..981bdcda 100644 --- a/index.js +++ b/index.js @@ -1,6 +1,7 @@ 'use strict'; var url = require('url'); +var fs = require('fs'); //Parse method copied from https://github.com/brianc/node-postgres //Copyright (c) 2010-2014 Brian Carlson (brian.m.carlson@gmail.com) @@ -48,6 +49,22 @@ function parse(str) { config.ssl = true; } + if (config.sslcert || config.sslkey || config.sslrootcert) { + config.ssl = {}; + } + + if (config.sslcert) { + config.ssl.cert = fs.readFileSync(config.sslcert).toString(); + } + + if (config.sslkey) { + config.ssl.key = fs.readFileSync(config.sslkey).toString(); + } + + if (config.sslrootcert) { + config.ssl.ca = fs.readFileSync(config.sslrootcert).toString(); + } + return config; } diff --git a/test/example.ca b/test/example.ca new file mode 100644 index 00000000..0a6dcf40 --- /dev/null +++ b/test/example.ca @@ -0,0 +1 @@ +example ca diff --git a/test/example.cert b/test/example.cert new file mode 100644 index 00000000..7693b3fe --- /dev/null +++ b/test/example.cert @@ -0,0 +1 @@ +example cert diff --git a/test/example.key b/test/example.key new file mode 100644 index 00000000..1aef9935 --- /dev/null +++ b/test/example.key @@ -0,0 +1 @@ +example key diff --git a/test/parse.js b/test/parse.js index 8ff3ee81..6632cc71 100644 --- a/test/parse.js +++ b/test/parse.js @@ -147,6 +147,30 @@ describe('parse', function(){ subject.ssl.should.equal(true); }); + it('configuration parameter sslcert=/path/to/cert', function(){ + var connectionString = 'pg:///?sslcert=' + __dirname + '/example.cert'; + var subject = parse(connectionString); + subject.ssl.should.eql({ + cert: 'example cert\n' + }); + }); + + it('configuration parameter sslkey=/path/to/key', function(){ + var connectionString = 'pg:///?sslkey=' + __dirname + '/example.key'; + var subject = parse(connectionString); + subject.ssl.should.eql({ + key: 'example key\n' + }); + }); + + it('configuration parameter sslrootcert=/path/to/ca', function(){ + var connectionString = 'pg:///?sslrootcert=' + __dirname + '/example.ca'; + var subject = parse(connectionString); + subject.ssl.should.eql({ + ca: 'example ca\n' + }); + }); + it('allow other params like max, ...', function () { var subject = parse('pg://myhost/db?max=18&min=4'); subject.max.should.equal('18'); From 7b62226d573bdde749e4c94ed21d67c74d1f3bd2 Mon Sep 17 00:00:00 2001 From: "Herman J. Radtke III" Date: Thu, 23 May 2019 14:23:55 -0700 Subject: [PATCH 20/58] ssl=0 is now parses to false Fixes #20 --- index.js | 4 ++++ test/parse.js | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/index.js b/index.js index 66798401..3cabb372 100644 --- a/index.js +++ b/index.js @@ -49,6 +49,10 @@ function parse(str) { config.ssl = true; } + if (config.ssl === '0') { + config.ssl = false; + } + if (config.sslcert || config.sslkey || config.sslrootcert) { config.ssl = {}; } diff --git a/test/parse.js b/test/parse.js index abf2c4f9..4de28719 100644 --- a/test/parse.js +++ b/test/parse.js @@ -150,6 +150,12 @@ describe('parse', function(){ subject.ssl.should.equal(true); }); + it('configuration parameter ssl=0', function(){ + var connectionString = 'pg:///?ssl=0'; + var subject = parse(connectionString); + subject.ssl.should.equal(false); + }); + it('set ssl', function () { var subject = parse('pg://myhost/db?ssl=1'); subject.ssl.should.equal(true); From 726f6202fa7eb89096bf6cb8d32526ebacf4be49 Mon Sep 17 00:00:00 2001 From: benny-medflyt Date: Mon, 27 May 2019 08:30:21 -0400 Subject: [PATCH 21/58] Update index.d.ts --- index.d.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.d.ts b/index.d.ts index 2a657460..1d2f1606 100644 --- a/index.d.ts +++ b/index.d.ts @@ -4,10 +4,10 @@ export interface ConnectionOptions { host: string | null; password?: string; user?: string; - port: string | null; + port?: string | null; database: string | null | undefined; - client_encoding?: string | undefined; - ssl?: boolean; + client_encoding?: string; + ssl?: boolean | string; application_name?: string; fallback_application_name?: string; From 06c46ac12b2a9540483450305f841938a759ba4d Mon Sep 17 00:00:00 2001 From: Andrew Bowerman Date: Tue, 18 Jun 2019 20:12:03 -0700 Subject: [PATCH 22/58] 2.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b625a16d..c39da5f2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pg-connection-string", - "version": "2.0.0", + "version": "2.1.0", "description": "Functions for dealing with a PostgresSQL connection string", "main": "./index.js", "types": "./index.d.ts", From c9ee9cd19970c93dda8ce66b2dd7fd1efa6b056f Mon Sep 17 00:00:00 2001 From: Andrew Bowerman Date: Tue, 18 Jun 2019 20:25:32 -0700 Subject: [PATCH 23/58] Update coveralls badge Closes #15 --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 2228b80e..cb4b1acc 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,7 @@ pg-connection-string [![NPM](https://nodei.co/npm/pg-connection-string.png?compact=true)](https://nodei.co/npm/pg-connection-string/) [![Build Status](https://travis-ci.org/iceddev/pg-connection-string.svg?branch=master)](https://travis-ci.org/iceddev/pg-connection-string) -[![Coverage Status](https://coveralls.io/repos/iceddev/pg-connection-string/badge.svg?branch=master)](https://coveralls.io/r/iceddev/pg-connection-string?branch=master) - +[![Coverage Status](https://coveralls.io/repos/github/iceddev/pg-connection-string/badge.svg?branch=master)](https://coveralls.io/github/iceddev/pg-connection-string?branch=master) Functions for dealing with a PostgresSQL connection string `parse` method taken from [node-postgres](https://github.com/brianc/node-postgres.git) From c75c3929654401fbf8654f6df3613ef2748c1428 Mon Sep 17 00:00:00 2001 From: Andrew Bowerman Date: Tue, 18 Jun 2019 20:41:10 -0700 Subject: [PATCH 24/58] fix readme newline typo --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index cb4b1acc..4943d885 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,7 @@ pg-connection-string [![Build Status](https://travis-ci.org/iceddev/pg-connection-string.svg?branch=master)](https://travis-ci.org/iceddev/pg-connection-string) [![Coverage Status](https://coveralls.io/repos/github/iceddev/pg-connection-string/badge.svg?branch=master)](https://coveralls.io/github/iceddev/pg-connection-string?branch=master) + Functions for dealing with a PostgresSQL connection string `parse` method taken from [node-postgres](https://github.com/brianc/node-postgres.git) From e4c1002e2e9413636c32929236e96f893010a317 Mon Sep 17 00:00:00 2001 From: Andrew Bowerman Date: Tue, 18 Jun 2019 20:49:39 -0700 Subject: [PATCH 25/58] actually include coveralls --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index c39da5f2..415638f0 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "dependencies": {}, "devDependencies": { "chai": "^4.1.1", + "coveralls": "^3.0.4", "istanbul": "^0.4.5", "mocha": "^3.5.0" }, From 0ff40e733b58096dd3e14a7a1c787a22058f54a1 Mon Sep 17 00:00:00 2001 From: Daniel Rozenberg Date: Tue, 28 Jan 2020 19:28:03 -0500 Subject: [PATCH 26/58] host= query param takes precedence --- index.js | 5 ++++- test/parse.js | 13 +++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 3cabb372..29d3653c 100644 --- a/index.js +++ b/index.js @@ -35,7 +35,10 @@ function parse(str) { config.client_encoding = result.query.encoding; return config; } - config.host = result.hostname; + if (!config.host) { + // Only set the host if there is no equivalent query param. + config.host = result.hostname; + } // result.pathname is not always guaranteed to have a '/' prefix (e.g. relative urls) // only strip the slash if it is present. diff --git a/test/parse.js b/test/parse.js index 4de28719..c973fb5c 100644 --- a/test/parse.js +++ b/test/parse.js @@ -120,6 +120,19 @@ describe('parse', function(){ (subject.database === null).should.equal(true); }); + it('configuration parameter host', function() { + var subject = parse('pg://user:pass@/dbname?host=/unix/socket'); + subject.user.should.equal('user'); + subject.password.should.equal('pass'); + subject.host.should.equal('/unix/socket'); + subject.database.should.equal('dbname'); + }); + + it('configuration parameter host overrides url host', function() { + var subject = parse('pg://user:pass@localhost/dbname?host=/unix/socket'); + subject.host.should.equal('/unix/socket'); + }); + it('configuration parameter application_name', function(){ var connectionString = 'pg:///?application_name=TheApp'; var subject = parse(connectionString); From b309db074ff545ed93c6396a98029b5cce7b943d Mon Sep 17 00:00:00 2001 From: Daniel Rozenberg Date: Tue, 28 Jan 2020 19:29:38 -0500 Subject: [PATCH 27/58] Support URL-encoded socket names --- index.js | 10 ++++++++-- test/parse.js | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 29d3653c..7cfc8293 100644 --- a/index.js +++ b/index.js @@ -40,11 +40,17 @@ function parse(str) { config.host = result.hostname; } + // If the host is missing it might be a URL-encoded path to a socket. + var pathname = result.pathname; + if (!config.host && pathname && pathname.toLowerCase().startsWith('%2f')) { + var pathnameSplit = pathname.split('/'); + config.host = decodeURIComponent(pathnameSplit[0]); + pathname = pathnameSplit.splice(1).join('/'); + } // result.pathname is not always guaranteed to have a '/' prefix (e.g. relative urls) // only strip the slash if it is present. - var pathname = result.pathname; if (pathname && pathname.charAt(0) === '/') { - pathname = result.pathname.slice(1) || null; + pathname = pathname.slice(1) || null; } config.database = pathname && decodeURI(pathname); diff --git a/test/parse.js b/test/parse.js index c973fb5c..07f886e1 100644 --- a/test/parse.js +++ b/test/parse.js @@ -133,6 +133,30 @@ describe('parse', function(){ subject.host.should.equal('/unix/socket'); }); + it('url with encoded socket', function() { + var subject = parse('pg://user:pass@%2Funix%2Fsocket/dbname'); + subject.user.should.equal('user'); + subject.password.should.equal('pass'); + subject.host.should.equal('/unix/socket'); + subject.database.should.equal('dbname'); + }); + + it('url with real host and an encoded db name', function() { + var subject = parse('pg://user:pass@localhost/%2Fdbname'); + subject.user.should.equal('user'); + subject.password.should.equal('pass'); + subject.host.should.equal('localhost'); + subject.database.should.equal('%2Fdbname'); + }); + + it('configuration parameter host treats encoded socket as part of the db name', function() { + var subject = parse('pg://user:pass@%2Funix%2Fsocket/dbname?host=localhost'); + subject.user.should.equal('user'); + subject.password.should.equal('pass'); + subject.host.should.equal('localhost'); + subject.database.should.equal('%2Funix%2Fsocket/dbname'); + }); + it('configuration parameter application_name', function(){ var connectionString = 'pg:///?application_name=TheApp'; var subject = parse(connectionString); From 7ec9b70180b5aaadb75c4fde3f35ff86031ce279 Mon Sep 17 00:00:00 2001 From: Daniel Rozenberg Date: Tue, 28 Jan 2020 19:40:51 -0500 Subject: [PATCH 28/58] Use regex instead of startsWith which is unsupported in node 0.10 --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 7cfc8293..7e914ba1 100644 --- a/index.js +++ b/index.js @@ -42,7 +42,7 @@ function parse(str) { // If the host is missing it might be a URL-encoded path to a socket. var pathname = result.pathname; - if (!config.host && pathname && pathname.toLowerCase().startsWith('%2f')) { + if (!config.host && pathname && /^%2f/i.test(pathname)) { var pathnameSplit = pathname.split('/'); config.host = decodeURIComponent(pathnameSplit[0]); pathname = pathnameSplit.splice(1).join('/'); From b4e0ba329ade3d976e0804dd0d79438274e7233f Mon Sep 17 00:00:00 2001 From: "Dustin J. Mitchell" Date: Sun, 16 Feb 2020 12:30:46 -0500 Subject: [PATCH 29/58] Include documentation on the URL format in the README This summarizes the common forms, but omits some of the more particular, and unnecessary forms, such as specifying UNIX domain sockets with `pg://` URLs. --- README.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/README.md b/README.md index 4943d885..d5b45ab9 100644 --- a/README.md +++ b/README.md @@ -19,3 +19,54 @@ var parse = require('pg-connection-string').parse; var config = parse('postgres://someuser:somepassword@somehost:381/somedatabase') ``` + +The resulting config contains a subset of the following properties: + +* `host` - Postgres server hostname or, for UNIX doamain sockets, the socket filename +* `port` - port on which to connect +* `user` - User with which to authenticate to the server +* `password` - Corresponding password +* `database` - Database name within the server +* `client_encoding` - string encoding the client will use +* `ssl`, either a boolean or an object with properties + * `cert` + * `key` + * `ca` +* any other query parameters (for example, `application_name`) are preserved intact. + +## Connection Strings + +The short summary of acceptable URLs is: + + * `socket:?` - UNIX domain socket + * `postgres://:@:/?` - TCP connection + +But see below for more details. + +### UNIX Domain Sockets + +When user and password are not given, the socket path follows `socket:`, as in `socket:/var/run/pgsql`. +This form can be shortened to just a path: `/var/run/pgsql`. + +When user and password are given, they are included in the typical URL positions, with an empty `host`, as in `socket://user:pass@/var/run/pgsql`. + +Query parameters follow a `?` character, including the following special query parameters: + + * `db=` - sets the database name (urlencoded) + * `encoding=` - sets the `client_encoding` property + +### TCP Connections + +TCP connections to the Postgres server are indicated with `pg:` or `postgres:` schemes (in fact, any scheme but `socket:` is accepted). +If username and password are included, they should be urlencoded. +The database name, however, should *not* be urlencoded. + +Query parameters follow a `?` character, including the following special query parameters: + * `host=` - sets `host` property, overriding the URL's host + * `encoding=` - sets the `client_encoding` property + * `ssl=1`, `ssl=true`, `ssl=0`, `ssl=false` - sets `ssl` to true or false, accordingly + * `sslcert=` - reads data from the given file and includes the result as `ssl.cert` + * `sslkey=` - reads data from the given file and includes the result as `ssl.key` + * `sslrootcert=` - reads data from the given file and includes the result as `ssl.ca` + +A bare relative URL, such as `salesdata`, will indicate a database name while leaving other properties empty. From 5233b3e77e396a368130709e762fca836290a528 Mon Sep 17 00:00:00 2001 From: "Herman J. Radtke III" Date: Thu, 19 Mar 2020 21:56:45 -0700 Subject: [PATCH 30/58] Release v2.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 415638f0..49345369 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pg-connection-string", - "version": "2.1.0", + "version": "2.2.0", "description": "Functions for dealing with a PostgresSQL connection string", "main": "./index.js", "types": "./index.d.ts", From a86cb900434291f8c5c5f474cc543ee9d771db99 Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Wed, 22 Apr 2020 11:04:14 -0500 Subject: [PATCH 31/58] lockfile --- yarn.lock | 204 ++---------------------------------------------------- 1 file changed, 6 insertions(+), 198 deletions(-) diff --git a/yarn.lock b/yarn.lock index f309fe97..0d936097 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1098,14 +1098,6 @@ array-ify@^1.0.0: resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" integrity sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4= -array-includes@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.0.tgz#48a929ef4c6bb1fa6dc4a92c9b023a261b0ca404" - integrity sha512-ONOEQoKrvXPKk7Su92Co0YMqYO32FfqJTzkKU9u2UpIXyYZIzLSvpdg4AwvSw4mSUW0czu6inK+zby6Oj6gDjQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.0" - array-union@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -1123,14 +1115,6 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= -array.prototype.flat@^1.2.1: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz#0de82b426b0318dbfdb940089e38b043d37f6c7b" - integrity sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" @@ -1637,11 +1621,6 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= -contains-path@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" - integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= - conventional-changelog-angular@^5.0.3: version "5.0.6" resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-5.0.6.tgz#269540c624553aded809c29a3508fdc2b544c059" @@ -1818,7 +1797,7 @@ debug@3.2.6, debug@^3.1.0: dependencies: ms "^2.1.1" -debug@^2.2.0, debug@^2.3.3, debug@^2.6.9: +debug@^2.2.0, debug@^2.3.3: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -1953,14 +1932,6 @@ dir-glob@^2.2.2: dependencies: path-type "^3.0.0" -doctrine@1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa" - integrity sha1-N53Ocw9hZvds76TmcHoVmwLFpvo= - dependencies: - esutils "^2.0.2" - isarray "^1.0.0" - doctrine@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" @@ -2046,7 +2017,7 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.0-next.0, es-abstract@^1.17.0-next.1: +es-abstract@^1.17.0-next.1: version "1.17.0-next.1" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.0-next.1.tgz#94acc93e20b05a6e96dacb5ab2f1cb3a81fc2172" integrity sha512-7MmGr03N7Rnuid6+wyhD9sHNE2n4tFSwExnU2lQl3lIo2ShXWGePY80zYaoMOmILWv57H0amMjZGHNzzGG70Rw== @@ -2096,35 +2067,6 @@ eslint-config-prettier@^6.10.1: dependencies: get-stdin "^6.0.0" -eslint-config-standard@^13.0.1: - version "13.0.1" - resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-13.0.1.tgz#c9c6ffe0cfb8a51535bc5c7ec9f70eafb8c6b2c0" - integrity sha512-zLKp4QOgq6JFgRm1dDCVv1Iu0P5uZ4v5Wa4DTOkg2RFMxdCX/9Qf7lz9ezRj2dBRa955cWQF/O/LWEiYWAHbTw== - -eslint-import-resolver-node@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz#58f15fb839b8d0576ca980413476aab2472db66a" - integrity sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q== - dependencies: - debug "^2.6.9" - resolve "^1.5.0" - -eslint-module-utils@^2.4.1: - version "2.5.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.5.0.tgz#cdf0b40d623032274ccd2abd7e64c4e524d6e19c" - integrity sha512-kCo8pZaNz2dsAW7nCUjuVoI11EBXXpIzfNxmaoLhXoRDOnqXLC4iSGVRdZPhOitfbdEfMEfKOiENaK6wDPZEGw== - dependencies: - debug "^2.6.9" - pkg-dir "^2.0.0" - -eslint-plugin-es@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-1.4.1.tgz#12acae0f4953e76ba444bfd1b2271081ac620998" - integrity sha512-5fa/gR2yR3NxQf+UXkeLeP8FBBl6tSgdrAz1+cF84v1FMM4twGwQoqTnn+QxFLcPOrF4pdKEJKDB/q9GoyJrCA== - dependencies: - eslint-utils "^1.4.2" - regexpp "^2.0.1" - eslint-plugin-es@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.0.tgz#98cb1bc8ab0aa807977855e11ad9d1c9422d014b" @@ -2133,24 +2075,6 @@ eslint-plugin-es@^3.0.0: eslint-utils "^2.0.0" regexpp "^3.0.0" -eslint-plugin-import@^2.18.1: - version "2.19.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.19.1.tgz#5654e10b7839d064dd0d46cd1b88ec2133a11448" - integrity sha512-x68131aKoCZlCae7rDXKSAQmbT5DQuManyXo2sK6fJJ0aK5CWAkv6A6HJZGgqC8IhjQxYPgo6/IY4Oz8AFsbBw== - dependencies: - array-includes "^3.0.3" - array.prototype.flat "^1.2.1" - contains-path "^0.1.0" - debug "^2.6.9" - doctrine "1.5.0" - eslint-import-resolver-node "^0.3.2" - eslint-module-utils "^2.4.1" - has "^1.0.3" - minimatch "^3.0.4" - object.values "^1.1.0" - read-pkg-up "^2.0.0" - resolve "^1.12.0" - eslint-plugin-node@^11.1.0: version "11.1.0" resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" @@ -2163,18 +2087,6 @@ eslint-plugin-node@^11.1.0: resolve "^1.10.1" semver "^6.1.0" -eslint-plugin-node@^9.1.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-9.2.0.tgz#b1911f111002d366c5954a6d96d3cd5bf2a3036a" - integrity sha512-2abNmzAH/JpxI4gEOwd6K8wZIodK3BmHbTxz4s79OIYwwIt2gkpEXlAouJXu4H1c9ySTnRso0tsuthSOZbUMlA== - dependencies: - eslint-plugin-es "^1.4.1" - eslint-utils "^1.4.2" - ignore "^5.1.1" - minimatch "^3.0.4" - resolve "^1.10.1" - semver "^6.1.0" - eslint-plugin-prettier@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.2.tgz#432e5a667666ab84ce72f945c72f77d996a5c9ba" @@ -2187,16 +2099,6 @@ eslint-plugin-promise@^3.5.0: resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-3.8.0.tgz#65ebf27a845e3c1e9d6f6a5622ddd3801694b621" integrity sha512-JiFL9UFR15NKpHyGii1ZcvmtIqa3UTwiDAGb8atSffe43qJ3+1czVGN6UtkklpcJ2DVnqvTMzEKRaJdBkAL2aQ== -eslint-plugin-promise@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz#845fd8b2260ad8f82564c1222fce44ad71d9418a" - integrity sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw== - -eslint-plugin-standard@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz#ff0519f7ffaff114f76d1bd7c3996eef0f6e20b4" - integrity sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ== - eslint-scope@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" @@ -2205,7 +2107,7 @@ eslint-scope@^5.0.0: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint-utils@^1.4.2, eslint-utils@^1.4.3: +eslint-utils@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== @@ -2224,49 +2126,6 @@ eslint-visitor-keys@^1.1.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== -eslint@^6.0.1: - version "6.7.2" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.7.2.tgz#c17707ca4ad7b2d8af986a33feba71e18a9fecd1" - integrity sha512-qMlSWJaCSxDFr8fBPvJM9kJwbazrhNcBU3+DszDW1OlEwKBBRWsJc7NJFelvwQpanHCR14cOLD41x8Eqvo3Nng== - dependencies: - "@babel/code-frame" "^7.0.0" - ajv "^6.10.0" - chalk "^2.1.0" - cross-spawn "^6.0.5" - debug "^4.0.1" - doctrine "^3.0.0" - eslint-scope "^5.0.0" - eslint-utils "^1.4.3" - eslint-visitor-keys "^1.1.0" - espree "^6.1.2" - esquery "^1.0.1" - esutils "^2.0.2" - file-entry-cache "^5.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.0.0" - globals "^12.1.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - inquirer "^7.0.0" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.3.0" - lodash "^4.17.14" - minimatch "^3.0.4" - mkdirp "^0.5.1" - natural-compare "^1.4.0" - optionator "^0.8.3" - progress "^2.0.0" - regexpp "^2.0.1" - semver "^6.1.2" - strip-ansi "^5.2.0" - strip-json-comments "^3.0.1" - table "^5.2.3" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - eslint@^6.8.0: version "6.8.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.8.0.tgz#62262d6729739f9275723824302fb227c8c93ffb" @@ -2520,7 +2379,7 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" -find-up@^2.0.0, find-up@^2.1.0: +find-up@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= @@ -3351,7 +3210,7 @@ is-windows@^1.0.0, is-windows@^1.0.2: resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: +isarray@1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= @@ -3519,16 +3378,6 @@ load-json-file@^1.0.0: pinkie-promise "^2.0.0" strip-bom "^2.0.0" -load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - load-json-file@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" @@ -4224,16 +4073,6 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -object.values@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.1.tgz#68a99ecde356b7e9295a3c5e0ce31dc8c953de5e" - integrity sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.0-next.1" - function-bind "^1.1.1" - has "^1.0.3" - octokit-pagination-methods@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz#cf472edc9d551055f9ef73f6e42b4dbb4c80bea4" @@ -4490,13 +4329,6 @@ path-type@^1.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= - dependencies: - pify "^2.0.0" - path-type@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" @@ -4579,13 +4411,6 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= -pkg-dir@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" - integrity sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s= - dependencies: - find-up "^2.1.0" - pkg-dir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" @@ -4775,14 +4600,6 @@ read-pkg-up@^1.0.1: find-up "^1.0.0" read-pkg "^1.0.0" -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - read-pkg-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" @@ -4800,15 +4617,6 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - read-pkg@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" @@ -4973,7 +4781,7 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.5.0: +resolve@^1.10.0, resolve@^1.10.1: version "1.14.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.14.0.tgz#6d14c6f9db9f8002071332b600039abf82053f64" integrity sha512-uviWSi5N67j3t3UKFxej1loCH0VZn5XuqdNxoLShPcYPw6cUZn74K1VRj+9myynRX03bxIBEkwlkob/ujLsJVw== From 35328807e3612cb267bee86dccb2551ad186624a Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Wed, 22 Apr 2020 11:04:51 -0500 Subject: [PATCH 32/58] Publish - pg-cursor@2.1.10 - pg-pool@3.1.1 - pg-protocol@1.2.2 - pg-query-stream@3.0.7 - pg@8.0.3 --- packages/pg-cursor/package.json | 4 ++-- packages/pg-pool/package.json | 2 +- packages/pg-protocol/package.json | 2 +- packages/pg-query-stream/package.json | 6 +++--- packages/pg/package.json | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/pg-cursor/package.json b/packages/pg-cursor/package.json index 3ce12975..d4bbec5c 100644 --- a/packages/pg-cursor/package.json +++ b/packages/pg-cursor/package.json @@ -1,6 +1,6 @@ { "name": "pg-cursor", - "version": "2.1.9", + "version": "2.1.10", "description": "Query cursor extension for node-postgres", "main": "index.js", "directories": { @@ -17,6 +17,6 @@ "license": "MIT", "devDependencies": { "mocha": "^6.2.2", - "pg": "^8.0.2" + "pg": "^8.0.3" } } diff --git a/packages/pg-pool/package.json b/packages/pg-pool/package.json index 4eb998ed..fdb95a96 100644 --- a/packages/pg-pool/package.json +++ b/packages/pg-pool/package.json @@ -1,6 +1,6 @@ { "name": "pg-pool", - "version": "3.1.0", + "version": "3.1.1", "description": "Connection pool for node-postgres", "main": "index.js", "directories": { diff --git a/packages/pg-protocol/package.json b/packages/pg-protocol/package.json index 476941dd..60bc2027 100644 --- a/packages/pg-protocol/package.json +++ b/packages/pg-protocol/package.json @@ -1,6 +1,6 @@ { "name": "pg-protocol", - "version": "1.2.1", + "version": "1.2.2", "description": "The postgres client/server binary protocol, implemented in TypeScript", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/pg-query-stream/package.json b/packages/pg-query-stream/package.json index 05a3f970..fd828f82 100644 --- a/packages/pg-query-stream/package.json +++ b/packages/pg-query-stream/package.json @@ -1,6 +1,6 @@ { "name": "pg-query-stream", - "version": "3.0.6", + "version": "3.0.7", "description": "Postgres query result returned as readable stream", "main": "index.js", "scripts": { @@ -26,12 +26,12 @@ "concat-stream": "~1.0.1", "eslint-plugin-promise": "^3.5.0", "mocha": "^6.2.2", - "pg": "^8.0.2", + "pg": "^8.0.3", "stream-spec": "~0.3.5", "stream-tester": "0.0.5", "through": "~2.3.4" }, "dependencies": { - "pg-cursor": "^2.1.9" + "pg-cursor": "^2.1.10" } } diff --git a/packages/pg/package.json b/packages/pg/package.json index 5386ec2e..da8a75f2 100644 --- a/packages/pg/package.json +++ b/packages/pg/package.json @@ -1,6 +1,6 @@ { "name": "pg", - "version": "8.0.2", + "version": "8.0.3", "description": "PostgreSQL client - pure javascript & libpq with the same API", "keywords": [ "database", @@ -22,8 +22,8 @@ "buffer-writer": "2.0.0", "packet-reader": "1.0.0", "pg-connection-string": "0.1.3", - "pg-pool": "^3.1.0", - "pg-protocol": "^1.2.1", + "pg-pool": "^3.1.1", + "pg-protocol": "^1.2.2", "pg-types": "^2.1.0", "pgpass": "1.x", "semver": "4.3.2" From 3a831fc77c8f65353e72d3120be5e3d8d197a1b3 Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Tue, 28 Apr 2020 10:02:38 -0500 Subject: [PATCH 33/58] Run lint --fix --- packages/pg-connection-string/index.d.ts | 20 +- packages/pg-connection-string/index.js | 72 ++-- packages/pg-connection-string/test/parse.js | 429 ++++++++++---------- yarn.lock | 336 ++++++++++++++- 4 files changed, 598 insertions(+), 259 deletions(-) diff --git a/packages/pg-connection-string/index.d.ts b/packages/pg-connection-string/index.d.ts index 1d2f1606..b1b7abd9 100644 --- a/packages/pg-connection-string/index.d.ts +++ b/packages/pg-connection-string/index.d.ts @@ -1,14 +1,14 @@ -export function parse(connectionString: string): ConnectionOptions; +export function parse(connectionString: string): ConnectionOptions export interface ConnectionOptions { - host: string | null; - password?: string; - user?: string; - port?: string | null; - database: string | null | undefined; - client_encoding?: string; - ssl?: boolean | string; + host: string | null + password?: string + user?: string + port?: string | null + database: string | null | undefined + client_encoding?: string + ssl?: boolean | string - application_name?: string; - fallback_application_name?: string; + application_name?: string + fallback_application_name?: string } diff --git a/packages/pg-connection-string/index.js b/packages/pg-connection-string/index.js index 7e914ba1..65951c37 100644 --- a/packages/pg-connection-string/index.js +++ b/packages/pg-connection-string/index.js @@ -1,7 +1,7 @@ -'use strict'; +'use strict' -var url = require('url'); -var fs = require('fs'); +var url = require('url') +var fs = require('fs') //Parse method copied from https://github.com/brianc/node-postgres //Copyright (c) 2010-2014 Brian Carlson (brian.m.carlson@gmail.com) @@ -10,78 +10,80 @@ var fs = require('fs'); //parses a connection string function parse(str) { //unix socket - if(str.charAt(0) === '/') { - var config = str.split(' '); - return { host: config[0], database: config[1] }; + if (str.charAt(0) === '/') { + var config = str.split(' ') + return { host: config[0], database: config[1] } } // url parse expects spaces encoded as %20 - var result = url.parse(/ |%[^a-f0-9]|%[a-f0-9][^a-f0-9]/i.test(str) ? encodeURI(str).replace(/\%25(\d\d)/g, "%$1") : str, true); - var config = result.query; + var result = url.parse( + / |%[^a-f0-9]|%[a-f0-9][^a-f0-9]/i.test(str) ? encodeURI(str).replace(/\%25(\d\d)/g, '%$1') : str, + true + ) + var config = result.query for (var k in config) { if (Array.isArray(config[k])) { - config[k] = config[k][config[k].length-1]; + config[k] = config[k][config[k].length - 1] } } - var auth = (result.auth || ':').split(':'); - config.user = auth[0]; - config.password = auth.splice(1).join(':'); + var auth = (result.auth || ':').split(':') + config.user = auth[0] + config.password = auth.splice(1).join(':') - config.port = result.port; - if(result.protocol == 'socket:') { - config.host = decodeURI(result.pathname); - config.database = result.query.db; - config.client_encoding = result.query.encoding; - return config; + config.port = result.port + if (result.protocol == 'socket:') { + config.host = decodeURI(result.pathname) + config.database = result.query.db + config.client_encoding = result.query.encoding + return config } if (!config.host) { // Only set the host if there is no equivalent query param. - config.host = result.hostname; + config.host = result.hostname } // If the host is missing it might be a URL-encoded path to a socket. - var pathname = result.pathname; + var pathname = result.pathname if (!config.host && pathname && /^%2f/i.test(pathname)) { - var pathnameSplit = pathname.split('/'); - config.host = decodeURIComponent(pathnameSplit[0]); - pathname = pathnameSplit.splice(1).join('/'); + var pathnameSplit = pathname.split('/') + config.host = decodeURIComponent(pathnameSplit[0]) + pathname = pathnameSplit.splice(1).join('/') } // result.pathname is not always guaranteed to have a '/' prefix (e.g. relative urls) // only strip the slash if it is present. if (pathname && pathname.charAt(0) === '/') { - pathname = pathname.slice(1) || null; + pathname = pathname.slice(1) || null } - config.database = pathname && decodeURI(pathname); + config.database = pathname && decodeURI(pathname) if (config.ssl === 'true' || config.ssl === '1') { - config.ssl = true; + config.ssl = true } if (config.ssl === '0') { - config.ssl = false; + config.ssl = false } if (config.sslcert || config.sslkey || config.sslrootcert) { - config.ssl = {}; + config.ssl = {} } if (config.sslcert) { - config.ssl.cert = fs.readFileSync(config.sslcert).toString(); + config.ssl.cert = fs.readFileSync(config.sslcert).toString() } if (config.sslkey) { - config.ssl.key = fs.readFileSync(config.sslkey).toString(); + config.ssl.key = fs.readFileSync(config.sslkey).toString() } if (config.sslrootcert) { - config.ssl.ca = fs.readFileSync(config.sslrootcert).toString(); + config.ssl.ca = fs.readFileSync(config.sslrootcert).toString() } - return config; + return config } +module.exports = parse -module.exports = parse; - -parse.parse = parse; +parse.parse = parse diff --git a/packages/pg-connection-string/test/parse.js b/packages/pg-connection-string/test/parse.js index 07f886e1..957f0644 100644 --- a/packages/pg-connection-string/test/parse.js +++ b/packages/pg-connection-string/test/parse.js @@ -1,257 +1,274 @@ -'use strict'; +'use strict' -var chai = require('chai'); -var expect = chai.expect; -chai.should(); +var chai = require('chai') +var expect = chai.expect +chai.should() -var parse = require('../').parse; +var parse = require('../').parse -describe('parse', function(){ +describe('parse', function () { + it('using connection string in client constructor', function () { + var subject = parse('postgres://brian:pw@boom:381/lala') + subject.user.should.equal('brian') + subject.password.should.equal('pw') + subject.host.should.equal('boom') + subject.port.should.equal('381') + subject.database.should.equal('lala') + }) - it('using connection string in client constructor', function(){ - var subject = parse('postgres://brian:pw@boom:381/lala'); - subject.user.should.equal('brian'); - subject.password.should.equal( 'pw'); - subject.host.should.equal( 'boom'); - subject.port.should.equal( '381'); - subject.database.should.equal( 'lala'); - }); + it('escape spaces if present', function () { + var subject = parse('postgres://localhost/post gres') + subject.database.should.equal('post gres') + }) - it('escape spaces if present', function(){ - var subject = parse('postgres://localhost/post gres'); - subject.database.should.equal('post gres'); - }); + it('do not double escape spaces', function () { + var subject = parse('postgres://localhost/post%20gres') + subject.database.should.equal('post gres') + }) - it('do not double escape spaces', function(){ - var subject = parse('postgres://localhost/post%20gres'); - subject.database.should.equal('post gres'); - }); + it('initializing with unix domain socket', function () { + var subject = parse('/var/run/') + subject.host.should.equal('/var/run/') + }) - it('initializing with unix domain socket', function(){ - var subject = parse('/var/run/'); - subject.host.should.equal('/var/run/'); - }); + it('initializing with unix domain socket and a specific database, the simple way', function () { + var subject = parse('/var/run/ mydb') + subject.host.should.equal('/var/run/') + subject.database.should.equal('mydb') + }) - it('initializing with unix domain socket and a specific database, the simple way', function(){ - var subject = parse('/var/run/ mydb'); - subject.host.should.equal('/var/run/'); - subject.database.should.equal('mydb'); - }); + it('initializing with unix domain socket, the health way', function () { + var subject = parse('socket:/some path/?db=my[db]&encoding=utf8') + subject.host.should.equal('/some path/') + subject.database.should.equal('my[db]', 'must to be escaped and unescaped trough "my%5Bdb%5D"') + subject.client_encoding.should.equal('utf8') + }) - it('initializing with unix domain socket, the health way', function(){ - var subject = parse('socket:/some path/?db=my[db]&encoding=utf8'); - subject.host.should.equal('/some path/'); - subject.database.should.equal('my[db]', 'must to be escaped and unescaped trough "my%5Bdb%5D"'); - subject.client_encoding.should.equal('utf8'); - }); + it('initializing with unix domain socket, the escaped health way', function () { + var subject = parse('socket:/some%20path/?db=my%2Bdb&encoding=utf8') + subject.host.should.equal('/some path/') + subject.database.should.equal('my+db') + subject.client_encoding.should.equal('utf8') + }) - it('initializing with unix domain socket, the escaped health way', function(){ - var subject = parse('socket:/some%20path/?db=my%2Bdb&encoding=utf8'); - subject.host.should.equal('/some path/'); - subject.database.should.equal('my+db'); - subject.client_encoding.should.equal('utf8'); - }); + it('initializing with unix domain socket, username and password', function () { + var subject = parse('socket://brian:pw@/var/run/?db=mydb') + subject.user.should.equal('brian') + subject.password.should.equal('pw') + subject.host.should.equal('/var/run/') + subject.database.should.equal('mydb') + }) - it('initializing with unix domain socket, username and password', function(){ - var subject = parse('socket://brian:pw@/var/run/?db=mydb'); - subject.user.should.equal('brian'); - subject.password.should.equal('pw'); - subject.host.should.equal('/var/run/'); - subject.database.should.equal('mydb'); - }); - - it('password contains < and/or > characters', function(){ + it('password contains < and/or > characters', function () { var sourceConfig = { - user:'brian', + user: 'brian', password: 'helloe', port: 5432, host: 'localhost', - database: 'postgres' - }; - var connectionString = 'postgres://' + sourceConfig.user + ':' + sourceConfig.password + '@' + sourceConfig.host + ':' + sourceConfig.port + '/' + sourceConfig.database; - var subject = parse(connectionString); - subject.password.should.equal(sourceConfig.password); - }); + database: 'postgres', + } + var connectionString = + 'postgres://' + + sourceConfig.user + + ':' + + sourceConfig.password + + '@' + + sourceConfig.host + + ':' + + sourceConfig.port + + '/' + + sourceConfig.database + var subject = parse(connectionString) + subject.password.should.equal(sourceConfig.password) + }) - it('password contains colons', function(){ + it('password contains colons', function () { var sourceConfig = { - user:'brian', + user: 'brian', password: 'hello:pass:world', port: 5432, host: 'localhost', - database: 'postgres' - }; - var connectionString = 'postgres://' + sourceConfig.user + ':' + sourceConfig.password + '@' + sourceConfig.host + ':' + sourceConfig.port + '/' + sourceConfig.database; - var subject = parse(connectionString); - subject.password.should.equal(sourceConfig.password); - }); + database: 'postgres', + } + var connectionString = + 'postgres://' + + sourceConfig.user + + ':' + + sourceConfig.password + + '@' + + sourceConfig.host + + ':' + + sourceConfig.port + + '/' + + sourceConfig.database + var subject = parse(connectionString) + subject.password.should.equal(sourceConfig.password) + }) - it('username or password contains weird characters', function(){ - var strang = 'pg://my f%irst name:is&%awesome!@localhost:9000'; - var subject = parse(strang); - subject.user.should.equal('my f%irst name'); - subject.password.should.equal('is&%awesome!'); - subject.host.should.equal('localhost'); - }); + it('username or password contains weird characters', function () { + var strang = 'pg://my f%irst name:is&%awesome!@localhost:9000' + var subject = parse(strang) + subject.user.should.equal('my f%irst name') + subject.password.should.equal('is&%awesome!') + subject.host.should.equal('localhost') + }) - it('url is properly encoded', function(){ - var encoded = 'pg://bi%25na%25%25ry%20:s%40f%23@localhost/%20u%2520rl'; - var subject = parse(encoded); - subject.user.should.equal('bi%na%%ry '); - subject.password.should.equal('s@f#'); - subject.host.should.equal('localhost'); - subject.database.should.equal(' u%20rl'); - }); + it('url is properly encoded', function () { + var encoded = 'pg://bi%25na%25%25ry%20:s%40f%23@localhost/%20u%2520rl' + var subject = parse(encoded) + subject.user.should.equal('bi%na%%ry ') + subject.password.should.equal('s@f#') + subject.host.should.equal('localhost') + subject.database.should.equal(' u%20rl') + }) - it('relative url sets database', function(){ - var relative = 'different_db_on_default_host'; - var subject = parse(relative); - subject.database.should.equal('different_db_on_default_host'); - }); + it('relative url sets database', function () { + var relative = 'different_db_on_default_host' + var subject = parse(relative) + subject.database.should.equal('different_db_on_default_host') + }) it('no pathname returns null database', function () { - var subject = parse('pg://myhost'); - (subject.database === null).should.equal(true); - }); + var subject = parse('pg://myhost') + ;(subject.database === null).should.equal(true) + }) it('pathname of "/" returns null database', function () { - var subject = parse('pg://myhost/'); - subject.host.should.equal('myhost'); - (subject.database === null).should.equal(true); - }); + var subject = parse('pg://myhost/') + subject.host.should.equal('myhost') + ;(subject.database === null).should.equal(true) + }) - it('configuration parameter host', function() { - var subject = parse('pg://user:pass@/dbname?host=/unix/socket'); - subject.user.should.equal('user'); - subject.password.should.equal('pass'); - subject.host.should.equal('/unix/socket'); - subject.database.should.equal('dbname'); - }); + it('configuration parameter host', function () { + var subject = parse('pg://user:pass@/dbname?host=/unix/socket') + subject.user.should.equal('user') + subject.password.should.equal('pass') + subject.host.should.equal('/unix/socket') + subject.database.should.equal('dbname') + }) - it('configuration parameter host overrides url host', function() { - var subject = parse('pg://user:pass@localhost/dbname?host=/unix/socket'); - subject.host.should.equal('/unix/socket'); - }); + it('configuration parameter host overrides url host', function () { + var subject = parse('pg://user:pass@localhost/dbname?host=/unix/socket') + subject.host.should.equal('/unix/socket') + }) - it('url with encoded socket', function() { - var subject = parse('pg://user:pass@%2Funix%2Fsocket/dbname'); - subject.user.should.equal('user'); - subject.password.should.equal('pass'); - subject.host.should.equal('/unix/socket'); - subject.database.should.equal('dbname'); - }); + it('url with encoded socket', function () { + var subject = parse('pg://user:pass@%2Funix%2Fsocket/dbname') + subject.user.should.equal('user') + subject.password.should.equal('pass') + subject.host.should.equal('/unix/socket') + subject.database.should.equal('dbname') + }) - it('url with real host and an encoded db name', function() { - var subject = parse('pg://user:pass@localhost/%2Fdbname'); - subject.user.should.equal('user'); - subject.password.should.equal('pass'); - subject.host.should.equal('localhost'); - subject.database.should.equal('%2Fdbname'); - }); + it('url with real host and an encoded db name', function () { + var subject = parse('pg://user:pass@localhost/%2Fdbname') + subject.user.should.equal('user') + subject.password.should.equal('pass') + subject.host.should.equal('localhost') + subject.database.should.equal('%2Fdbname') + }) - it('configuration parameter host treats encoded socket as part of the db name', function() { - var subject = parse('pg://user:pass@%2Funix%2Fsocket/dbname?host=localhost'); - subject.user.should.equal('user'); - subject.password.should.equal('pass'); - subject.host.should.equal('localhost'); - subject.database.should.equal('%2Funix%2Fsocket/dbname'); - }); + it('configuration parameter host treats encoded socket as part of the db name', function () { + var subject = parse('pg://user:pass@%2Funix%2Fsocket/dbname?host=localhost') + subject.user.should.equal('user') + subject.password.should.equal('pass') + subject.host.should.equal('localhost') + subject.database.should.equal('%2Funix%2Fsocket/dbname') + }) - it('configuration parameter application_name', function(){ - var connectionString = 'pg:///?application_name=TheApp'; - var subject = parse(connectionString); - subject.application_name.should.equal('TheApp'); - }); + it('configuration parameter application_name', function () { + var connectionString = 'pg:///?application_name=TheApp' + var subject = parse(connectionString) + subject.application_name.should.equal('TheApp') + }) - it('configuration parameter fallback_application_name', function(){ - var connectionString = 'pg:///?fallback_application_name=TheAppFallback'; - var subject = parse(connectionString); - subject.fallback_application_name.should.equal('TheAppFallback'); - }); + it('configuration parameter fallback_application_name', function () { + var connectionString = 'pg:///?fallback_application_name=TheAppFallback' + var subject = parse(connectionString) + subject.fallback_application_name.should.equal('TheAppFallback') + }) - it('configuration parameter fallback_application_name', function(){ - var connectionString = 'pg:///?fallback_application_name=TheAppFallback'; - var subject = parse(connectionString); - subject.fallback_application_name.should.equal('TheAppFallback'); - }); + it('configuration parameter fallback_application_name', function () { + var connectionString = 'pg:///?fallback_application_name=TheAppFallback' + var subject = parse(connectionString) + subject.fallback_application_name.should.equal('TheAppFallback') + }) - it('configuration parameter ssl=true', function(){ - var connectionString = 'pg:///?ssl=true'; - var subject = parse(connectionString); - subject.ssl.should.equal(true); - }); + it('configuration parameter ssl=true', function () { + var connectionString = 'pg:///?ssl=true' + var subject = parse(connectionString) + subject.ssl.should.equal(true) + }) - it('configuration parameter ssl=1', function(){ - var connectionString = 'pg:///?ssl=1'; - var subject = parse(connectionString); - subject.ssl.should.equal(true); - }); + it('configuration parameter ssl=1', function () { + var connectionString = 'pg:///?ssl=1' + var subject = parse(connectionString) + subject.ssl.should.equal(true) + }) - it('configuration parameter ssl=0', function(){ - var connectionString = 'pg:///?ssl=0'; - var subject = parse(connectionString); - subject.ssl.should.equal(false); - }); + it('configuration parameter ssl=0', function () { + var connectionString = 'pg:///?ssl=0' + var subject = parse(connectionString) + subject.ssl.should.equal(false) + }) it('set ssl', function () { - var subject = parse('pg://myhost/db?ssl=1'); - subject.ssl.should.equal(true); - }); + var subject = parse('pg://myhost/db?ssl=1') + subject.ssl.should.equal(true) + }) - it('configuration parameter sslcert=/path/to/cert', function(){ - var connectionString = 'pg:///?sslcert=' + __dirname + '/example.cert'; - var subject = parse(connectionString); + it('configuration parameter sslcert=/path/to/cert', function () { + var connectionString = 'pg:///?sslcert=' + __dirname + '/example.cert' + var subject = parse(connectionString) subject.ssl.should.eql({ - cert: 'example cert\n' - }); - }); + cert: 'example cert\n', + }) + }) - it('configuration parameter sslkey=/path/to/key', function(){ - var connectionString = 'pg:///?sslkey=' + __dirname + '/example.key'; - var subject = parse(connectionString); + it('configuration parameter sslkey=/path/to/key', function () { + var connectionString = 'pg:///?sslkey=' + __dirname + '/example.key' + var subject = parse(connectionString) subject.ssl.should.eql({ - key: 'example key\n' - }); - }); + key: 'example key\n', + }) + }) - it('configuration parameter sslrootcert=/path/to/ca', function(){ - var connectionString = 'pg:///?sslrootcert=' + __dirname + '/example.ca'; - var subject = parse(connectionString); + it('configuration parameter sslrootcert=/path/to/ca', function () { + var connectionString = 'pg:///?sslrootcert=' + __dirname + '/example.ca' + var subject = parse(connectionString) subject.ssl.should.eql({ - ca: 'example ca\n' - }); - }); + ca: 'example ca\n', + }) + }) - it('allow other params like max, ...', function () { - var subject = parse('pg://myhost/db?max=18&min=4'); - subject.max.should.equal('18'); - subject.min.should.equal('4'); - }); + it('allow other params like max, ...', function () { + var subject = parse('pg://myhost/db?max=18&min=4') + subject.max.should.equal('18') + subject.min.should.equal('4') + }) + it('configuration parameter keepalives', function () { + var connectionString = 'pg:///?keepalives=1' + var subject = parse(connectionString) + subject.keepalives.should.equal('1') + }) - it('configuration parameter keepalives', function(){ - var connectionString = 'pg:///?keepalives=1'; - var subject = parse(connectionString); - subject.keepalives.should.equal('1'); - }); + it('unknown configuration parameter is passed into client', function () { + var connectionString = 'pg:///?ThereIsNoSuchPostgresParameter=1234' + var subject = parse(connectionString) + subject.ThereIsNoSuchPostgresParameter.should.equal('1234') + }) - it('unknown configuration parameter is passed into client', function(){ - var connectionString = 'pg:///?ThereIsNoSuchPostgresParameter=1234'; - var subject = parse(connectionString); - subject.ThereIsNoSuchPostgresParameter.should.equal('1234'); - }); + it('do not override a config field with value from query string', function () { + var subject = parse('socket:/some path/?db=my[db]&encoding=utf8&client_encoding=bogus') + subject.host.should.equal('/some path/') + subject.database.should.equal('my[db]', 'must to be escaped and unescaped through "my%5Bdb%5D"') + subject.client_encoding.should.equal('utf8') + }) - it('do not override a config field with value from query string', function(){ - var subject = parse('socket:/some path/?db=my[db]&encoding=utf8&client_encoding=bogus'); - subject.host.should.equal('/some path/'); - subject.database.should.equal('my[db]', 'must to be escaped and unescaped through "my%5Bdb%5D"'); - subject.client_encoding.should.equal('utf8'); - }); - - - it('return last value of repeated parameter', function(){ - var connectionString = 'pg:///?keepalives=1&keepalives=0'; - var subject = parse(connectionString); - subject.keepalives.should.equal('0'); - }); -}); + it('return last value of repeated parameter', function () { + var connectionString = 'pg:///?keepalives=1&keepalives=0' + var subject = parse(connectionString) + subject.keepalives.should.equal('0') + }) +}) diff --git a/yarn.lock b/yarn.lock index 0d936097..796307ce 100644 --- a/yarn.lock +++ b/yarn.lock @@ -948,6 +948,11 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abbrev@1.0.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" + integrity sha1-kbR5JYinc4wl813W9jdSovh3YTU= + acorn-jsx@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384" @@ -989,6 +994,11 @@ ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + ansi-colors@3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" @@ -1166,6 +1176,11 @@ async@0.9.0: resolved "https://registry.yarnpkg.com/async/-/async-0.9.0.tgz#ac3613b1da9bed1b47510bb4651b8931e47146c7" integrity sha1-rDYTsdqb7RtHUQu0ZRuJMeRxRsc= +async@1.x: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" @@ -1273,6 +1288,11 @@ braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + integrity sha1-81HTKWnTL6XXpVZxVCY9korjvR8= + browser-stdout@1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" @@ -1410,7 +1430,7 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -chai@^4.2.0: +chai@^4.1.1, chai@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== @@ -1558,6 +1578,13 @@ commander@2.15.1: resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== +commander@2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q= + dependencies: + graceful-readlink ">= 1.0.0" + commander@~2.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -1736,6 +1763,17 @@ cosmiconfig@^5.1.0: js-yaml "^3.13.1" parse-json "^4.0.0" +coveralls@^3.0.4: + version "3.1.0" + resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-3.1.0.tgz#13c754d5e7a2dd8b44fe5269e21ca394fb4d615b" + integrity sha512-sHxOu2ELzW8/NC1UP5XVLbZDzO4S3VxfFye3XYCznopHy02YjNkHcj5bKaVw2O7hVaBdBjEdQGpie4II1mWhuQ== + dependencies: + js-yaml "^3.13.1" + lcov-parse "^1.0.0" + log-driver "^1.2.7" + minimist "^1.2.5" + request "^2.88.2" + cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -1783,6 +1821,13 @@ dateformat@^3.0.0: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== +debug@2.6.8: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + integrity sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw= + dependencies: + ms "2.0.0" + debug@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" @@ -1915,6 +1960,11 @@ dezalgo@^1.0.0: asap "^2.0.0" wrappy "1" +diff@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" + integrity sha1-yc45Okt8vQsFinJck98pkCeGj/k= + diff@3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -2060,6 +2110,18 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escodegen@1.8.x: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + integrity sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg= + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + eslint-config-prettier@^6.10.1: version "6.10.1" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.10.1.tgz#129ef9ec575d5ddc0e269667bf09defcd898642a" @@ -2178,6 +2240,11 @@ espree@^6.1.2: acorn-jsx "^5.1.0" eslint-visitor-keys "^1.1.0" +esprima@2.7.x, esprima@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= + esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -2197,6 +2264,11 @@ esrecurse@^4.1.0: dependencies: estraverse "^4.1.0" +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + integrity sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q= + estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" @@ -2642,6 +2714,18 @@ glob-to-regexp@^0.3.0: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= +glob@7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + integrity sha1-gFIR3wT6rxxjo2ADBs31reULLsg= + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" @@ -2666,6 +2750,17 @@ glob@7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^5.0.15: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" @@ -2704,11 +2799,33 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= + growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== +growl@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + integrity sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8= + +handlebars@^4.0.1: + version "4.7.6" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.6.tgz#d4c05c1baf90e9945f77aa68a7a219aa4a7df74e" + integrity sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.0" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + handlebars@^4.4.0: version "4.5.3" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.3.tgz#5cf75bd8714f7605713511a56be7c349becb0482" @@ -2725,7 +2842,7 @@ har-schema@^2.0.0: resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= -har-validator@~5.1.0: +har-validator@~5.1.0, har-validator@~5.1.3: version "5.1.3" resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080" integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g== @@ -2733,6 +2850,11 @@ har-validator@~5.1.0: ajv "^6.5.5" har-schema "^2.0.0" +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -3242,12 +3364,32 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= +istanbul@^0.4.5: + version "0.4.5" + resolved "https://registry.yarnpkg.com/istanbul/-/istanbul-0.4.5.tgz#65c7d73d4c4da84d4f3ac310b918fb0b8033733b" + integrity sha1-ZcfXPUxNqE1POsMQuRj7C4Azczs= + dependencies: + abbrev "1.0.x" + async "1.x" + escodegen "1.8.x" + esprima "2.7.x" + glob "^5.0.15" + handlebars "^4.0.1" + js-yaml "3.x" + mkdirp "0.5.x" + nopt "3.x" + once "1.x" + resolve "1.1.x" + supports-color "^3.1.0" + which "^1.1.1" + wordwrap "^1.0.0" + js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@3.13.1, js-yaml@^3.13.1: +js-yaml@3.13.1, js-yaml@3.x, js-yaml@^3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== @@ -3285,6 +3427,11 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= +json3@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE= + jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -3336,6 +3483,11 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== +lcov-parse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcov-parse/-/lcov-parse-1.0.0.tgz#eb0d46b54111ebc561acb4c408ef9363bdc8f7e0" + integrity sha1-6w1GtUER68VhrLTECO+TY73I9+A= + lerna@^3.19.0: version "3.19.0" resolved "https://registry.yarnpkg.com/lerna/-/lerna-3.19.0.tgz#6d53b613eca7da426ab1e97c01ce6fb39754da6c" @@ -3415,6 +3567,34 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + integrity sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4= + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY= + +lodash._basecreate@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" + integrity sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE= + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw= + lodash._reinterpolate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" @@ -3425,16 +3605,44 @@ lodash.clonedeep@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= +lodash.create@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" + integrity sha1-1/KEnw29p+BGgruM1yqwIkYd6+c= + dependencies: + lodash._baseassign "^3.0.0" + lodash._basecreate "^3.0.0" + lodash._isiterateecall "^3.0.0" + lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= + lodash.ismatch@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" integrity sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc= +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + lodash.set@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" @@ -3470,6 +3678,11 @@ lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.2. resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +log-driver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" + integrity sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg== + log-symbols@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" @@ -3653,7 +3866,7 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -minimatch@3.0.4, minimatch@^3.0.4: +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -3678,6 +3891,11 @@ minimist@^1.1.3, minimist@^1.2.0: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= +minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + minimist@~0.0.1: version "0.0.10" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" @@ -3736,6 +3954,31 @@ mkdirp@*, mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1: dependencies: minimist "0.0.8" +mkdirp@0.5.x: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + +mocha@^3.5.0: + version "3.5.3" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.5.3.tgz#1e0480fe36d2da5858d1eb6acc38418b26eaa20d" + integrity sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg== + dependencies: + browser-stdout "1.3.0" + commander "2.9.0" + debug "2.6.8" + diff "3.2.0" + escape-string-regexp "1.0.5" + glob "7.1.1" + growl "1.9.2" + he "1.1.1" + json3 "3.3.2" + lodash.create "3.1.1" + mkdirp "0.5.1" + supports-color "3.1.2" + mocha@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" @@ -3914,6 +4157,13 @@ node-gyp@^5.0.2: tar "^4.4.12" which "^1.3.1" +nopt@3.x: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" @@ -4078,7 +4328,7 @@ octokit-pagination-methods@^1.1.0: resolved "https://registry.yarnpkg.com/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz#cf472edc9d551055f9ef73f6e42b4dbb4c80bea4" integrity sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ== -once@^1.3.0, once@^1.3.1, once@^1.4.0: +once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -4107,7 +4357,7 @@ optimist@^0.6.1: minimist "~0.0.1" wordwrap "~0.0.2" -optionator@^0.8.3: +optionator@^0.8.1, optionator@^0.8.3: version "0.8.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== @@ -4514,6 +4764,11 @@ psl@^1.1.24: resolved "https://registry.yarnpkg.com/psl/-/psl-1.6.0.tgz#60557582ee23b6c43719d9890fb4170ecd91e110" integrity sha512-SYKKmVel98NCOYXpkwUqZqh0ahZeeKfmisiLIcEZdsb+WbLv02g/dI5BUmZnIyOe7RzZtLax81nnb2HbvC2tzA== +psl@^1.1.28: + version "1.8.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" + integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== + pump@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" @@ -4544,7 +4799,7 @@ punycode@^1.4.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" integrity sha1-wNWmOycYgArY4esPpSachN1BhF4= -punycode@^2.1.0: +punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== @@ -4749,6 +5004,32 @@ request@^2.88.0: tunnel-agent "^0.6.0" uuid "^3.3.2" +request@^2.88.2: + version "2.88.2" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -4781,6 +5062,11 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= +resolve@1.1.x: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + resolve@^1.10.0, resolve@^1.10.1: version "1.14.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.14.0.tgz#6d14c6f9db9f8002071332b600039abf82053f64" @@ -5036,6 +5322,13 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + integrity sha1-2rc/vPwrqBm03gO9b26qSBZLP50= + dependencies: + amdefine ">=0.0.4" + spdx-correct@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" @@ -5288,6 +5581,13 @@ strong-log-transformer@^2.0.0: minimist "^1.2.0" through "^2.3.4" +supports-color@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" + integrity sha1-cqJiiU2dQIuVbKBf83su2KbiotU= + dependencies: + has-flag "^1.0.0" + supports-color@5.4.0: version "5.4.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" @@ -5302,6 +5602,13 @@ supports-color@6.0.0: dependencies: has-flag "^3.0.0" +supports-color@^3.1.0: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -5443,6 +5750,14 @@ tough-cookie@~2.4.3: psl "^1.1.24" punycode "^1.4.1" +tough-cookie@~2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" + integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== + dependencies: + psl "^1.1.28" + punycode "^2.1.1" + tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" @@ -5702,7 +6017,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@1.3.1, which@^1.2.9, which@^1.3.1: +which@1.3.1, which@^1.1.1, which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -5728,6 +6043,11 @@ word-wrap@~1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + wordwrap@~0.0.2: version "0.0.3" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" From 16344cbfcdcd6fdaa8cc637f63b4ec65e652859e Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Tue, 28 Apr 2020 10:07:12 -0500 Subject: [PATCH 34/58] Update test command for travis I think the new syntax I'm using here is compatible with `sh`...let's see. --- .eslintrc | 14 +++----------- package.json | 2 +- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/.eslintrc b/.eslintrc index 57948b71..e0368034 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,16 +1,8 @@ { - "plugins": [ - "prettier" - ], + "plugins": ["prettier"], "parser": "@typescript-eslint/parser", - "extends": [ - "plugin:prettier/recommended", - "prettier/@typescript-eslint" - ], - "ignorePatterns": [ - "node_modules", - "packages/pg-protocol/dist/**/*" - ], + "extends": ["plugin:prettier/recommended", "prettier/@typescript-eslint"], + "ignorePatterns": ["node_modules", "coverage", "packages/pg-protocol/dist/**/*"], "parserOptions": { "ecmaVersion": 2017, "sourceType": "module" diff --git a/package.json b/package.json index dd32e85b..5fb9b187 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "test": "yarn lint && yarn lerna exec yarn test", "build": "yarn lerna exec --scope pg-protocol yarn build", "pretest": "yarn build", - "lint": "!([[ -e node_modules/.bin/prettier ]]) || eslint '*/**/*.{js,ts,tsx}'" + "lint": "if [ -x ./node_modules/.bin/eslint ]; then eslint '*/**/*.{js,ts,tsx}'; fi;" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^2.27.0", From ddf81128ab5a7c0920da02ff027dd9a0356bd8b9 Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Tue, 28 Apr 2020 10:20:22 -0500 Subject: [PATCH 35/58] Check for the correct binary --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 5fb9b187..282ca937 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "test": "yarn lint && yarn lerna exec yarn test", "build": "yarn lerna exec --scope pg-protocol yarn build", "pretest": "yarn build", - "lint": "if [ -x ./node_modules/.bin/eslint ]; then eslint '*/**/*.{js,ts,tsx}'; fi;" + "lint": "if [ -x ./node_modules/.bin/prettier ]; then eslint '*/**/*.{js,ts,tsx}'; fi;" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^2.27.0", From afd14cb5f9517baaf72d8a0c27ebf18f9c8acdb6 Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Tue, 28 Apr 2020 21:56:25 -0500 Subject: [PATCH 36/58] Publish - pg-connection-string@2.2.1 --- packages/pg-connection-string/package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/pg-connection-string/package.json b/packages/pg-connection-string/package.json index 49345369..a2f7f07d 100644 --- a/packages/pg-connection-string/package.json +++ b/packages/pg-connection-string/package.json @@ -1,6 +1,6 @@ { "name": "pg-connection-string", - "version": "2.2.0", + "version": "2.2.1", "description": "Functions for dealing with a PostgresSQL connection string", "main": "./index.js", "types": "./index.d.ts", @@ -25,7 +25,6 @@ "url": "https://github.com/iceddev/pg-connection-string/issues" }, "homepage": "https://github.com/iceddev/pg-connection-string", - "dependencies": {}, "devDependencies": { "chai": "^4.1.1", "coveralls": "^3.0.4", From abb1f34020abfc9eaa006aaa36d4c44d5fb43fa7 Mon Sep 17 00:00:00 2001 From: Andreas Lind Date: Tue, 5 May 2020 09:26:42 +0200 Subject: [PATCH 37/58] Fix repository field in package.json --- packages/pg-connection-string/package.json | 2 +- packages/pg-cursor/package.json | 2 +- packages/pg-pool/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/pg-connection-string/package.json b/packages/pg-connection-string/package.json index a2f7f07d..4968c709 100644 --- a/packages/pg-connection-string/package.json +++ b/packages/pg-connection-string/package.json @@ -11,7 +11,7 @@ }, "repository": { "type": "git", - "url": "https://github.com/iceddev/pg-connection-string" + "url": "git://github.com/brianc/node-postgres.git" }, "keywords": [ "pg", diff --git a/packages/pg-cursor/package.json b/packages/pg-cursor/package.json index d4bbec5c..f242ebb0 100644 --- a/packages/pg-cursor/package.json +++ b/packages/pg-cursor/package.json @@ -11,7 +11,7 @@ }, "repository": { "type": "git", - "url": "git://github.com/brianc/node-pg-cursor.git" + "url": "git://github.com/brianc/node-postgres.git" }, "author": "Brian M. Carlson", "license": "MIT", diff --git a/packages/pg-pool/package.json b/packages/pg-pool/package.json index fdb95a96..7c954127 100644 --- a/packages/pg-pool/package.json +++ b/packages/pg-pool/package.json @@ -11,7 +11,7 @@ }, "repository": { "type": "git", - "url": "git://github.com/brianc/node-pg-pool.git" + "url": "git://github.com/brianc/node-postgres.git" }, "keywords": [ "pg", From 6937a2428b6e54c4ebe93fa54899631bae861ec3 Mon Sep 17 00:00:00 2001 From: Ben Salili-James Date: Tue, 5 May 2020 13:24:11 +0100 Subject: [PATCH 38/58] Add `PGSSLMODE=noverify` support to opt-out of rejecting self-signed certs --- packages/pg/lib/connection-parameters.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/pg/lib/connection-parameters.js b/packages/pg/lib/connection-parameters.js index b34e0df5..71161e2c 100644 --- a/packages/pg/lib/connection-parameters.js +++ b/packages/pg/lib/connection-parameters.js @@ -34,6 +34,8 @@ var useSsl = function () { case 'verify-ca': case 'verify-full': return true + case 'no-verify': + return { rejectUnauthorized: false } } return defaults.ssl } From 698993ec6d082ccd8be87404be3995364c08c7fa Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Tue, 5 May 2020 09:43:31 -0500 Subject: [PATCH 39/58] Use monorepo connection string --- packages/pg/package.json | 2 +- yarn.lock | 5 ----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/pg/package.json b/packages/pg/package.json index da8a75f2..7e7803a7 100644 --- a/packages/pg/package.json +++ b/packages/pg/package.json @@ -21,7 +21,7 @@ "dependencies": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", - "pg-connection-string": "0.1.3", + "pg-connection-string": "^2.2.1", "pg-pool": "^3.1.1", "pg-protocol": "^1.2.2", "pg-types": "^2.1.0", diff --git a/yarn.lock b/yarn.lock index 796307ce..a1f07fa3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4596,11 +4596,6 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -pg-connection-string@0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-0.1.3.tgz#da1847b20940e42ee1492beaf65d49d91b245df7" - integrity sha1-2hhHsglA5C7hSSvq9l1J2RskXfc= - pg-copy-streams@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/pg-copy-streams/-/pg-copy-streams-0.3.0.tgz#a4fbc2a3b788d4e9da6f77ceb35422d8d7043b7f" From 3a2af0f52c66624d28557c51003732bd75806f2a Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Tue, 5 May 2020 09:50:53 -0500 Subject: [PATCH 40/58] Fix relative path import Closes #2188 --- packages/pg/lib/connection-fast.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/pg/lib/connection-fast.js b/packages/pg/lib/connection-fast.js index 6344b417..54e628ff 100644 --- a/packages/pg/lib/connection-fast.js +++ b/packages/pg/lib/connection-fast.js @@ -11,8 +11,7 @@ var net = require('net') var EventEmitter = require('events').EventEmitter var util = require('util') -// eslint-disable-next-line -const { parse, serialize } = require('../../pg-protocol/dist') +const { parse, serialize } = require('pg-protocol/dist') // TODO(bmc) support binary mode here // var BINARY_MODE = 1 From 9e11004e8a50e6011df5c33cef9521af8c71ff6d Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Tue, 5 May 2020 09:53:56 -0500 Subject: [PATCH 41/58] No need to import from dist --- packages/pg/lib/connection-fast.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/pg/lib/connection-fast.js b/packages/pg/lib/connection-fast.js index 54e628ff..7cc2ed8c 100644 --- a/packages/pg/lib/connection-fast.js +++ b/packages/pg/lib/connection-fast.js @@ -11,10 +11,9 @@ var net = require('net') var EventEmitter = require('events').EventEmitter var util = require('util') -const { parse, serialize } = require('pg-protocol/dist') +const { parse, serialize } = require('pg-protocol') -// TODO(bmc) support binary mode here -// var BINARY_MODE = 1 +// TODO(bmc) support binary mode at some point console.log('***using faster connection***') var Connection = function (config) { EventEmitter.call(this) From b89eb0f81df36b32d28bf94d8cbc31186ed66574 Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Tue, 5 May 2020 10:58:34 -0500 Subject: [PATCH 42/58] Write tests & unify treatment of no-verify --- packages/pg/lib/connection-parameters.js | 14 ++++- .../environment-variable-tests.js | 59 ++++++++++++------- 2 files changed, 48 insertions(+), 25 deletions(-) diff --git a/packages/pg/lib/connection-parameters.js b/packages/pg/lib/connection-parameters.js index 71161e2c..eead3c39 100644 --- a/packages/pg/lib/connection-parameters.js +++ b/packages/pg/lib/connection-parameters.js @@ -25,8 +25,15 @@ var val = function (key, config, envVar) { return config[key] || envVar || defaults[key] } -var useSsl = function () { - switch (process.env.PGSSLMODE) { +var useSsl = function (modeFromConfig) { + // if the ssl parameter passed to config is not a string, just return it + // directly (it will be passed directly to tls.connect) + if (modeFromConfig !== undefined && typeof modeFromConfig !== 'string') { + return modeFromConfig + } + const mode = modeFromConfig || process.env.PGSSLMODE + + switch (mode) { case 'disable': return false case 'prefer': @@ -70,7 +77,8 @@ var ConnectionParameters = function (config) { }) this.binary = val('binary', config) - this.ssl = typeof config.ssl === 'undefined' ? useSsl() : config.ssl + // this.ssl = typeof config.ssl === 'undefined' ? useSsl() : config.ssl + this.ssl = useSsl(config.ssl) this.client_encoding = val('client_encoding', config) this.replication = val('replication', config) // a domain socket begins with '/' diff --git a/packages/pg/test/unit/connection-parameters/environment-variable-tests.js b/packages/pg/test/unit/connection-parameters/environment-variable-tests.js index 45d481e3..c64edee8 100644 --- a/packages/pg/test/unit/connection-parameters/environment-variable-tests.js +++ b/packages/pg/test/unit/connection-parameters/environment-variable-tests.js @@ -1,5 +1,7 @@ 'use strict' var helper = require(__dirname + '/../test-helper') +const Suite = require('../../suite') + var assert = require('assert') var ConnectionParameters = require(__dirname + '/../../../lib/connection-parameters') var defaults = require(__dirname + '/../../../lib').defaults @@ -11,7 +13,17 @@ for (var key in process.env) { delete process.env[key] } -test('ConnectionParameters initialized from environment variables', function (t) { +const suite = new Suite('ConnectionParameters') + +const clearEnv = () => { + // clear process.env + for (var key in process.env) { + delete process.env[key] + } +} + +suite.test('ConnectionParameters initialized from environment variables', function () { + clearEnv() process.env['PGHOST'] = 'local' process.env['PGUSER'] = 'bmc2' process.env['PGPORT'] = 7890 @@ -26,7 +38,13 @@ test('ConnectionParameters initialized from environment variables', function (t) assert.equal(subject.password, 'open', 'env password') }) -test('ConnectionParameters initialized from mix', function (t) { +suite.test('ConnectionParameters initialized from mix', function () { + clearEnv() + process.env['PGHOST'] = 'local' + process.env['PGUSER'] = 'bmc2' + process.env['PGPORT'] = 7890 + process.env['PGDATABASE'] = 'allyerbase' + process.env['PGPASSWORD'] = 'open' delete process.env['PGPASSWORD'] delete process.env['PGDATABASE'] var subject = new ConnectionParameters({ @@ -40,12 +58,8 @@ test('ConnectionParameters initialized from mix', function (t) { assert.equal(subject.password, defaults.password, 'defaults password') }) -// clear process.env -for (var key in process.env) { - delete process.env[key] -} - -test('connection string parsing', function (t) { +suite.test('connection string parsing', function () { + clearEnv() var string = 'postgres://brian:pw@boom:381/lala' var subject = new ConnectionParameters(string) assert.equal(subject.host, 'boom', 'string host') @@ -55,7 +69,10 @@ test('connection string parsing', function (t) { assert.equal(subject.database, 'lala', 'string database') }) -test('connection string parsing - ssl', function (t) { +suite.test('connection string parsing - ssl', function () { + // clear process.env + clearEnv() + var string = 'postgres://brian:pw@boom:381/lala?ssl=true' var subject = new ConnectionParameters(string) assert.equal(subject.ssl, true, 'ssl') @@ -75,27 +92,24 @@ test('connection string parsing - ssl', function (t) { string = 'postgres://brian:pw@boom:381/lala' subject = new ConnectionParameters(string) assert.equal(!!subject.ssl, false, 'ssl') + + string = 'postgres://brian:pw@boom:381/lala?ssl=no-verify' + subject = new ConnectionParameters(string) + assert.deepStrictEqual(subject.ssl, { rejectUnauthorized: false }, 'ssl') }) -// clear process.env -for (var key in process.env) { - delete process.env[key] -} - -test('ssl is false by default', function () { +suite.test('ssl is false by default', function () { + clearEnv() var subject = new ConnectionParameters() assert.equal(subject.ssl, false) }) var testVal = function (mode, expected) { - // clear process.env - for (var key in process.env) { - delete process.env[key] - } - process.env.PGSSLMODE = mode - test('ssl is ' + expected + ' when $PGSSLMODE=' + mode, function () { + suite.test('ssl is ' + expected + ' when $PGSSLMODE=' + mode, function () { + clearEnv() + process.env.PGSSLMODE = mode var subject = new ConnectionParameters() - assert.equal(subject.ssl, expected) + assert.deepStrictEqual(subject.ssl, expected) }) } @@ -106,6 +120,7 @@ testVal('prefer', true) testVal('require', true) testVal('verify-ca', true) testVal('verify-full', true) +testVal('no-verify', { rejectUnauthorized: false }) // restore process.env for (var key in realEnv) { From e9073f5a00f225670899b2a466fe18b5b047201d Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Tue, 5 May 2020 11:03:29 -0500 Subject: [PATCH 43/58] Cleanup & comments --- packages/pg/lib/connection-parameters.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/packages/pg/lib/connection-parameters.js b/packages/pg/lib/connection-parameters.js index eead3c39..83aa1e4e 100644 --- a/packages/pg/lib/connection-parameters.js +++ b/packages/pg/lib/connection-parameters.js @@ -25,9 +25,11 @@ var val = function (key, config, envVar) { return config[key] || envVar || defaults[key] } -var useSsl = function (modeFromConfig) { +var normalizeSSLConfig = function (modeFromConfig) { // if the ssl parameter passed to config is not a string, just return it // directly (it will be passed directly to tls.connect) + // this way you can pass all the ssl params in via constructor: + // new Client({ ssl: { minDHSize: 1024 } }) etc if (modeFromConfig !== undefined && typeof modeFromConfig !== 'string') { return modeFromConfig } @@ -41,6 +43,11 @@ var useSsl = function (modeFromConfig) { case 'verify-ca': case 'verify-full': return true + // no-verify is not standard to libpq but allows specifying + // you require ssl but want to bypass server certificate validation. + // this is a very common way to connect in heroku so we support it + // vai both environment variables (PGSSLMODE=no-verify) as well + // as in connection string params ?ssl=no-verify case 'no-verify': return { rejectUnauthorized: false } } @@ -77,8 +84,8 @@ var ConnectionParameters = function (config) { }) this.binary = val('binary', config) - // this.ssl = typeof config.ssl === 'undefined' ? useSsl() : config.ssl - this.ssl = useSsl(config.ssl) + + this.ssl = normalizeSSLConfig(config.ssl) this.client_encoding = val('client_encoding', config) this.replication = val('replication', config) // a domain socket begins with '/' From 18649107782196d67b16871bcf2172241c80dda7 Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Tue, 5 May 2020 11:08:05 -0500 Subject: [PATCH 44/58] Add test for no-verify string config option --- packages/pg/test/unit/client/configuration-tests.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/pg/test/unit/client/configuration-tests.js b/packages/pg/test/unit/client/configuration-tests.js index e6cbc0dc..d4b16d10 100644 --- a/packages/pg/test/unit/client/configuration-tests.js +++ b/packages/pg/test/unit/client/configuration-tests.js @@ -1,5 +1,6 @@ 'use strict' require(__dirname + '/test-helper') +var assert = require('assert') var pguser = process.env['PGUSER'] || process.env.USER var pgdatabase = process.env['PGDATABASE'] || process.env.USER @@ -43,6 +44,11 @@ test('client settings', function () { assert.equal(client.ssl, true) }) + test('ssl no-verify', function () { + var client = new Client({ ssl: 'no-verify' }) + assert.deepStrictEqual(client.ssl, { rejectUnauthorized: false }) + }) + test('custom ssl force off', function () { var old = process.env.PGSSLMODE process.env.PGSSLMODE = 'prefer' From 8d1b200a3acb0915fb677fc124d175d9aa9b4ef9 Mon Sep 17 00:00:00 2001 From: Brian C Date: Wed, 6 May 2020 11:54:39 -0500 Subject: [PATCH 45/58] Update SPONSORS.md --- SPONSORS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/SPONSORS.md b/SPONSORS.md index 9b043165..d01c1090 100644 --- a/SPONSORS.md +++ b/SPONSORS.md @@ -7,6 +7,7 @@ node-postgres is made possible by the helpful contributors from the community as - [Timescale](https://timescale.com) - [Nafundi](https://nafundi.com) - [CrateDB](https://crate.io/) +- [BitMEX](https://www.bitmex.com/app/trade/XBTUSD) # Supporters From a7aa1bbb1d4b9d42706a807bd4feb7bbab7f8898 Mon Sep 17 00:00:00 2001 From: Julien Bouquillon Date: Wed, 6 May 2020 18:56:16 +0200 Subject: [PATCH 46/58] doc: add pg-connection-string in readme packages --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d963edc2..34aceea3 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ This repo is a monorepo which contains the core [pg](https://github.com/brianc/n - [pg-pool](https://github.com/brianc/node-postgres/tree/master/packages/pg-pool) - [pg-cursor](https://github.com/brianc/node-postgres/tree/master/packages/pg-cursor) - [pg-query-stream](https://github.com/brianc/node-postgres/tree/master/packages/pg-query-stream) +- [pg-connection-string](https://github.com/brianc/node-postgres/tree/master/packages/pg-connection-string) ## Documenation From 7929f6ae44a63b76b2ea58e5d9fc016a2d3f14df Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Thu, 7 May 2020 11:36:39 -0500 Subject: [PATCH 47/58] Make change less invasive and fully backwards compatible for native binding config --- packages/pg/lib/connection-parameters.js | 26 +++++++------------ .../test/unit/client/configuration-tests.js | 5 ---- 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/packages/pg/lib/connection-parameters.js b/packages/pg/lib/connection-parameters.js index 83aa1e4e..e1d83892 100644 --- a/packages/pg/lib/connection-parameters.js +++ b/packages/pg/lib/connection-parameters.js @@ -25,17 +25,8 @@ var val = function (key, config, envVar) { return config[key] || envVar || defaults[key] } -var normalizeSSLConfig = function (modeFromConfig) { - // if the ssl parameter passed to config is not a string, just return it - // directly (it will be passed directly to tls.connect) - // this way you can pass all the ssl params in via constructor: - // new Client({ ssl: { minDHSize: 1024 } }) etc - if (modeFromConfig !== undefined && typeof modeFromConfig !== 'string') { - return modeFromConfig - } - const mode = modeFromConfig || process.env.PGSSLMODE - - switch (mode) { +var readSSLConfigFromEnvironment = function () { + switch (process.env.PGSSLMODE) { case 'disable': return false case 'prefer': @@ -43,11 +34,6 @@ var normalizeSSLConfig = function (modeFromConfig) { case 'verify-ca': case 'verify-full': return true - // no-verify is not standard to libpq but allows specifying - // you require ssl but want to bypass server certificate validation. - // this is a very common way to connect in heroku so we support it - // vai both environment variables (PGSSLMODE=no-verify) as well - // as in connection string params ?ssl=no-verify case 'no-verify': return { rejectUnauthorized: false } } @@ -85,7 +71,13 @@ var ConnectionParameters = function (config) { this.binary = val('binary', config) - this.ssl = normalizeSSLConfig(config.ssl) + this.ssl = typeof config.ssl === 'undefined' ? readSSLConfigFromEnvironment() : config.ssl + + // support passing in ssl=no-verify via connection string + if (this.ssl === 'no-verify') { + this.ssl = { rejectUnauthorized: false } + } + this.client_encoding = val('client_encoding', config) this.replication = val('replication', config) // a domain socket begins with '/' diff --git a/packages/pg/test/unit/client/configuration-tests.js b/packages/pg/test/unit/client/configuration-tests.js index d4b16d10..e604513b 100644 --- a/packages/pg/test/unit/client/configuration-tests.js +++ b/packages/pg/test/unit/client/configuration-tests.js @@ -44,11 +44,6 @@ test('client settings', function () { assert.equal(client.ssl, true) }) - test('ssl no-verify', function () { - var client = new Client({ ssl: 'no-verify' }) - assert.deepStrictEqual(client.ssl, { rejectUnauthorized: false }) - }) - test('custom ssl force off', function () { var old = process.env.PGSSLMODE process.env.PGSSLMODE = 'prefer' From 3f5bc58a86cda3b4812addc1e42a06d61d31e614 Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Fri, 8 May 2020 10:42:57 -0500 Subject: [PATCH 48/58] Publish - pg-connection-string@2.2.2 - pg-cursor@2.1.11 - pg-pool@3.2.0 - pg-query-stream@3.0.8 - pg@8.1.0 --- packages/pg-connection-string/package.json | 2 +- packages/pg-cursor/package.json | 4 ++-- packages/pg-pool/package.json | 2 +- packages/pg-query-stream/package.json | 6 +++--- packages/pg/package.json | 6 +++--- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/pg-connection-string/package.json b/packages/pg-connection-string/package.json index 4968c709..cdbbf527 100644 --- a/packages/pg-connection-string/package.json +++ b/packages/pg-connection-string/package.json @@ -1,6 +1,6 @@ { "name": "pg-connection-string", - "version": "2.2.1", + "version": "2.2.2", "description": "Functions for dealing with a PostgresSQL connection string", "main": "./index.js", "types": "./index.d.ts", diff --git a/packages/pg-cursor/package.json b/packages/pg-cursor/package.json index f242ebb0..14af348e 100644 --- a/packages/pg-cursor/package.json +++ b/packages/pg-cursor/package.json @@ -1,6 +1,6 @@ { "name": "pg-cursor", - "version": "2.1.10", + "version": "2.1.11", "description": "Query cursor extension for node-postgres", "main": "index.js", "directories": { @@ -17,6 +17,6 @@ "license": "MIT", "devDependencies": { "mocha": "^6.2.2", - "pg": "^8.0.3" + "pg": "^8.1.0" } } diff --git a/packages/pg-pool/package.json b/packages/pg-pool/package.json index 7c954127..176a3e41 100644 --- a/packages/pg-pool/package.json +++ b/packages/pg-pool/package.json @@ -1,6 +1,6 @@ { "name": "pg-pool", - "version": "3.1.1", + "version": "3.2.0", "description": "Connection pool for node-postgres", "main": "index.js", "directories": { diff --git a/packages/pg-query-stream/package.json b/packages/pg-query-stream/package.json index fd828f82..d6c8e96b 100644 --- a/packages/pg-query-stream/package.json +++ b/packages/pg-query-stream/package.json @@ -1,6 +1,6 @@ { "name": "pg-query-stream", - "version": "3.0.7", + "version": "3.0.8", "description": "Postgres query result returned as readable stream", "main": "index.js", "scripts": { @@ -26,12 +26,12 @@ "concat-stream": "~1.0.1", "eslint-plugin-promise": "^3.5.0", "mocha": "^6.2.2", - "pg": "^8.0.3", + "pg": "^8.1.0", "stream-spec": "~0.3.5", "stream-tester": "0.0.5", "through": "~2.3.4" }, "dependencies": { - "pg-cursor": "^2.1.10" + "pg-cursor": "^2.1.11" } } diff --git a/packages/pg/package.json b/packages/pg/package.json index 7e7803a7..1fda0dae 100644 --- a/packages/pg/package.json +++ b/packages/pg/package.json @@ -1,6 +1,6 @@ { "name": "pg", - "version": "8.0.3", + "version": "8.1.0", "description": "PostgreSQL client - pure javascript & libpq with the same API", "keywords": [ "database", @@ -21,8 +21,8 @@ "dependencies": { "buffer-writer": "2.0.0", "packet-reader": "1.0.0", - "pg-connection-string": "^2.2.1", - "pg-pool": "^3.1.1", + "pg-connection-string": "^2.2.2", + "pg-pool": "^3.2.0", "pg-protocol": "^1.2.2", "pg-types": "^2.1.0", "pgpass": "1.x", From bd7caf57427e28eea8552b660cc2161e9aaca811 Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Fri, 8 May 2020 10:51:08 -0500 Subject: [PATCH 49/58] Remove sponsor logo --- CHANGELOG.md | 379 ------------------------------------------ packages/pg/README.md | 69 ++++---- 2 files changed, 32 insertions(+), 416 deletions(-) delete mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index ab356e0f..00000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,379 +0,0 @@ -All major and minor releases are briefly explained below. - -For richer information consult the commit log on github with referenced pull requests. - -We do not include break-fix version release in this file. - -### pg-pool@3.1.0 - -- Add [maxUses](https://github.com/brianc/node-postgres/pull/2157) config option. - -### pg@8.0.0 - -#### note: for detailed release notes please [check here](https://node-postgres.com/announcements#2020-02-25) - -- Remove versions of node older than `6 lts` from the test matrix. `pg>=8.0` may still work on older versions but it is no longer officially supported. -- Change default behavior when not specifying `rejectUnauthorized` with the SSL connection parameters. Previously we defaulted to `rejectUnauthorized: false` when it was not specifically included. We now default to `rejectUnauthorized: true.` Manually specify `{ ssl: { rejectUnauthorized: false } }` for old behavior. -- Change [default database](https://github.com/brianc/node-postgres/pull/1679) when not specified to use the `user` config option if available. Previously `process.env.USER` was used. -- Change `pg.Pool` and `pg.Query` to [be](https://github.com/brianc/node-postgres/pull/2126) an [es6 class](https://github.com/brianc/node-postgres/pull/2063). -- Make `pg.native` non enumerable. -- `notice` messages are [no longer instances](https://github.com/brianc/node-postgres/pull/2090) of `Error`. -- Passwords no longer [show up](https://github.com/brianc/node-postgres/pull/2070) when instances of clients or pools are logged. - -### pg@7.18.0 - -- This will likely be the last minor release before pg@8.0. -- This version contains a few bug fixes and adds a deprecation warning for [a pending change in 8.0](https://github.com/brianc/node-postgres/issues/2009#issuecomment-579371651) which will flip the default behavior over SSL from `rejectUnauthorized` from `false` to `true` making things more secure in the general use case. - -### pg-query-stream@3.0.0 - -- [Rewrote stream internals](https://github.com/brianc/node-postgres/pull/2051) to better conform to node stream semantics. This should make pg-query-stream much better at respecting [highWaterMark](https://nodejs.org/api/stream.html#stream_new_stream_readable_options) and getting rid of some edge case bugs when using pg-query-stream as an async iterator. Due to the size and nature of this change (effectively a full re-write) it's safest to bump the semver major here, though almost all tests remain untouched and still passing, which brings us to a breaking change to the API.... -- Changed `stream.close` to `stream.destroy` which is the [official](https://nodejs.org/api/stream.html#stream_readable_destroy_error) way to terminate a readable stream. This is a __breaking change__ if you rely on the `stream.close` method on pg-query-stream...though should be just a find/replace type operation to upgrade as the semantics remain very similar (not exactly the same, since internals are rewritten, but more in line with how streams are "supposed" to behave). -- Unified the `config.batchSize` and `config.highWaterMark` to both do the same thing: control how many rows are buffered in memory. The `ReadableStream` will manage exactly how many rows are requested from the cursor at a time. This should give better out of the box performance and help with efficient async iteration. - -### pg@7.17.0 - -- Add support for `idle_in_transaction_session_timeout` [option](https://github.com/brianc/node-postgres/pull/2049). - -### 7.16.0 -- Add optional, opt-in behavior to test new, [faster query pipeline](https://github.com/brianc/node-postgres/pull/2044). This is experimental, and not documented yet. The pipeline changes will grow significantly after the 8.0 release. - -### 7.15.0 - -- Change repository structure to support lerna & future monorepo [development](https://github.com/brianc/node-postgres/pull/2014). -- [Warn about deprecation](https://github.com/brianc/node-postgres/pull/2021) for calling constructors without `new`. - -### 7.14.0 - -- Reverts 7.13.0 as it contained [an accidental breaking change](https://github.com/brianc/node-postgres/pull/2010) for self-signed SSL cert verification. 7.14.0 is identical to 7.12.1. - -### 7.13.0 - -- Add support for [all tls.connect()](https://github.com/brianc/node-postgres/pull/1996) options. - -### 7.12.0 - -- Add support for [async password lookup](https://github.com/brianc/node-postgres/pull/1926). - -### 7.11.0 - -- Add support for [connection_timeout](https://github.com/brianc/node-postgres/pull/1847/files#diff-5391bde944956870128be1136e7bc176R63) and [keepalives_idle](https://github.com/brianc/node-postgres/pull/1847). - -### 7.10.0 - -- Add support for [per-query types](https://github.com/brianc/node-postgres/pull/1825). - -### 7.9.0 - -- Add support for [sasl/scram authentication](https://github.com/brianc/node-postgres/pull/1835). - -### 7.8.0 - -- Add support for passing [secureOptions](https://github.com/brianc/node-postgres/pull/1804) SSL config. -- Upgrade [pg-types](https://github.com/brianc/node-postgres/pull/1806) to 2.0. - -### 7.7.0 - -- Add support for configurable [query timeout](https://github.com/brianc/node-postgres/pull/1760) on a client level. - -### 7.6.0 - -- Add support for ["bring your own promise"](https://github.com/brianc/node-postgres/pull/1518) - -### 7.5.0 - -- Better [error message](https://github.com/brianc/node-postgres/commit/11a4793452d618c53e019416cc886ad38deb1aa7) when passing `null` or `undefined` to `client.query`. -- Better [error handling](https://github.com/brianc/node-postgres/pull/1503) on queued queries. - -### 7.4.0 - -- Add support for [Uint8Array](https://github.com/brianc/node-postgres/pull/1448) values. - -### 7.3.0 - -- Add support for [statement timeout](https://github.com/brianc/node-postgres/pull/1436). - -### 7.2.0 - -- Pinned pg-pool and pg-types to a tighter semver range. This is likely not a noticeable change for you unless you were specifically installing older versions of those libraries for some reason, but making it a minor bump here just in case it could cause any confusion. - -### 7.1.0 - -#### Enhancements - -- [You can now supply both a connection string and additional config options to clients.](https://github.com/brianc/node-postgres/pull/1363) - -### 7.0.0 - -#### Breaking Changes - -- Drop support for node < `4.x`. -- Remove `pg.connect` `pg.end` and `pg.cancel` singleton methods. -- `Client#connect(callback)` now returns `undefined`. It used to return an event emitter. -- Upgrade [pg-pool](https://github.com/brianc/node-pg-pool) to `2.x`. -- Upgrade [pg-native](https://github.com/brianc/node-pg-native) to `2.x`. -- Standardize error message fields between JS and native driver. The only breaking changes were in the native driver as its field names were brought into alignment with the existing JS driver field names. -- Result from multi-statement text queries such as `SELECT 1; SELECT 2;` are now returned as an array of results instead of a single result with 1 array containing rows from both queries. - -[Please see here for a migration guide](https://node-postgres.com/guides/upgrading) - -#### Enhancements - -- Overhauled documentation: [https://node-postgres.com](https://node-postgres.com). -- Add `Client#connect() => Promise` and `Client#end() => Promise` calls. Promises are now returned from all async methods on clients _if and only if_ no callback was supplied to the method. -- Add `connectionTimeoutMillis` to pg-pool. - -### v6.2.0 - -- Add support for [parsing `replicationStart` messages](https://github.com/brianc/node-postgres/pull/1271/files). - -### v6.1.0 - -- Add optional callback parameter to the pure JavaScript `client.end` method. The native client already supported this. - -### v6.0.0 - -#### Breaking Changes - -- Remove `pg.pools`. There is still a reference kept to the pools created & tracked by `pg.connect` but it has been renamed, is considered private, and should not be used. Accessing this API directly was uncommon and was _supposed_ to be private but was incorrectly documented on the wiki. Therefore, it is a breaking change of an (unintentionally) public interface to remove it by renaming it & making it private. Eventually `pg.connect` itself will be deprecated in favor of instantiating pools directly via `new pg.Pool()` so this property should become completely moot at some point. In the mean time...check out the new features... - -#### New features - -- Replace internal pooling code with [pg-pool](https://github.com/brianc/node-pg-pool). This is the first step in eventually deprecating and removing the singleton `pg.connect`. The pg-pool constructor is exported from node-postgres at `require('pg').Pool`. It provides a backwards compatible interface with `pg.connect` as well as a promise based interface & additional niceties. - -You can now create an instance of a pool and don't have to rely on the `pg` singleton for anything: - -``` -var pg = require('pg') - -var pool = new pg.Pool() - -// your friendly neighborhood pool interface, without the singleton -pool.connect(function(err, client, done) { - // ... -}) -``` - -Promise support & other goodness lives now in [pg-pool](https://github.com/brianc/node-pg-pool). - -**Please** read the readme at [pg-pool](https://github.com/brianc/node-pg-pool) for the full api. - -- Included support for tcp keep alive. Enable it as follows: - -```js -var client = new Client({ keepAlive: true }); -``` - -This should help with backends incorrectly considering idle clients to be dead and prematurely disconnecting them. - -### v5.1.0 - -- Make the query object returned from `client.query` implement the promise interface. This is the first step towards promisifying more of the node-postgres api. - -Example: - -```js -var client = new Client(); -client.connect(); -client.query("SELECT $1::text as name", ["brianc"]).then(function(res) { - console.log("hello from", res.rows[0]); - client.end(); -}); -``` - -### v5.0.0 - -#### Breaking Changes - -- `require('pg').native` now returns null if the native bindings cannot be found; previously, this threw an exception. - -#### New Features - -- better error message when passing `undefined` as a query parameter -- support for `defaults.connectionString` -- support for `returnToHead` being passed to [generic pool](https://github.com/coopernurse/node-pool) - -### v4.5.0 - -- Add option to parse JS date objects in query parameters as [UTC](https://github.com/brianc/node-postgres/pull/943) - -### v4.4.0 - -- Warn to `stderr` if a named query exceeds 63 characters which is the max length supported by postgres. - -### v4.3.0 - -- Unpin `pg-types` semver. Allow it to float against `pg-types@1.x`. - -### v4.2.0 - -- Support for additional error fields in postgres >= 9.3 if available. - -### v4.1.0 - -- Allow type parser overrides on a [per-client basis](https://github.com/brianc/node-postgres/pull/679) - -### v4.0.0 - -- Make [native bindings](https://github.com/brianc/node-pg-native.git) an optional install with `npm install pg-native` -- No longer surround query result callback with `try/catch` block. -- Remove built in COPY IN / COPY OUT support - better implementations provided by [pg-copy-streams](https://github.com/brianc/node-pg-copy-streams.git) and [pg-native](https://github.com/brianc/node-pg-native.git) - -### v3.6.0 - -- Include support for (parsing JSONB)[https://github.com/brianc/node-pg-types/pull/13] (supported in postgres 9.4) - -### v3.5.0 - -- Include support for parsing boolean arrays - -### v3.4.0 - -- Include port as connection parameter to [unix sockets](https://github.com/brianc/node-postgres/pull/604) -- Better support for odd [date parsing](https://github.com/brianc/node-pg-types/pull/8) - -### v3.2.0 - -- Add support for parsing [date arrays](https://github.com/brianc/node-pg-types/pull/3) -- Expose array parsers on [pg.types](https://github.com/brianc/node-pg-types/pull/2) -- Allow [pool](https://github.com/brianc/node-postgres/pull/591) to be configured - -### v3.1.0 - -- Add [count of the number of times a client has been checked out from the pool](https://github.com/brianc/node-postgres/pull/556) -- Emit `end` from `pg` object [when a pool is drained](https://github.com/brianc/node-postgres/pull/571) - -### v3.0.0 - -#### Breaking changes - -- [Parse the DATE PostgreSQL type as local time](https://github.com/brianc/node-postgres/pull/514) - -After [some discussion](https://github.com/brianc/node-postgres/issues/510) it was decided node-postgres was non-compliant in how it was handling DATE results. They were being converted to UTC, but the PostgreSQL documentation specifies they should be returned in the client timezone. This is a breaking change, and if you use the `date` type you might want to examine your code and make sure nothing is impacted. - -- [Fix possible numeric precision loss on numeric & int8 arrays](https://github.com/brianc/node-postgres/pull/501) - -pg@v2.0 included changes to not convert large integers into their JavaScript number representation because of possibility for numeric precision loss. The same types in arrays were not taken into account. This fix applies the same type of type-coercion rules to arrays of those types, so there will be no more possible numeric loss on an array of very large int8s for example. This is a breaking change because now a return type from a query of `int8[]` will contain _string_ representations -of the integers. Use your favorite JavaScript bignum module to represent them without precision loss, or punch over the type converter to return the old style arrays again. - -- [Fix to input array of dates being improperly converted to utc](https://github.com/benesch/node-postgres/commit/c41eedc3e01e5527a3d5c242fa1896f02ef0b261#diff-7172adb1fec2457a2700ed29008a8e0aR108) - -Single `date` parameters were properly sent to the PostgreSQL server properly in local time, but an input array of dates was being changed into utc dates. This is a violation of what PostgreSQL expects. Small breaking change, but none-the-less something you should check out if you are inserting an array of dates. - -- [Query no longer emits `end` event if it ends due to an error](https://github.com/brianc/node-postgres/commit/357b64d70431ec5ca721eb45a63b082c18e6ffa3) - -This is a small change to bring the semantics of query more in line with other EventEmitters. The tests all passed after this change, but I suppose it could still be a breaking change in certain use cases. If you are doing clever things with the `end` and `error` events of a query object you might want to check to make sure its still behaving normally, though it is most likely not an issue. - -#### New features - -- [Supercharge `prepareValue`](https://github.com/brianc/node-postgres/pull/555) - -The long & short of it is now any object you supply in the list of query values will be inspected for a `.toPostgres` method. If the method is present it will be called and its result used as the raw text value sent to PostgreSQL for that value. This allows the same type of custom type coercion on query parameters as was previously afforded to query result values. - -- [Domain aware connection pool](https://github.com/brianc/node-postgres/pull/531) - -If domains are active node-postgres will honor them and do everything it can to ensure all callbacks are properly fired in the active domain. If you have tried to use domains with node-postgres (or many other modules which pool long lived event emitters) you may have run into an issue where the active domain changes before and after a callback. This has been a longstanding footgun within node-postgres and I am happy to get it fixed. - -- [Disconnected clients now removed from pool](https://github.com/brianc/node-postgres/pull/543) - -Avoids a scenario where your pool could fill up with disconnected & unusable clients. - -- [Break type parsing code into separate module](https://github.com/brianc/node-postgres/pull/541) - -To provide better documentation and a clearer explanation of how to override the query result parsing system we broke the type converters [into their own module](https://github.com/brianc/node-pg-types). There is still work around removing the 'global-ness' of the type converters so each query or connection can return types differently, but this is a good first step and allow a lot more obvious way to return int8 results as JavaScript numbers, for example - -### v2.11.0 - -- Add support for [application_name](https://github.com/brianc/node-postgres/pull/497) - -### v2.10.0 - -- Add support for [the password file](http://www.postgresql.org/docs/9.3/static/libpq-pgpass.html) - -### v2.9.0 - -- Add better support for [unix domain socket](https://github.com/brianc/node-postgres/pull/487) connections - -### v2.8.0 - -- Add support for parsing JSON[] and UUID[] result types - -### v2.7.0 - -- Use single row mode in native bindings when available [@rpedela] - - reduces memory consumption when handling row values in 'row' event -- Automatically bind buffer type parameters as binary [@eugeneware] - -### v2.6.0 - -- Respect PGSSLMODE environment variable - -### v2.5.0 - -- Ability to opt-in to int8 parsing via `pg.defaults.parseInt8 = true` - -### v2.4.0 - -- Use eval in the result set parser to increase performance - -### v2.3.0 - -- Remove built-in support for binary Int64 parsing. - _Due to the low usage & required compiled dependency this will be pushed into a 3rd party add-on_ - -### v2.2.0 - -- [Add support for excapeLiteral and escapeIdentifier in both JavaScript and the native bindings](https://github.com/brianc/node-postgres/pull/396) - -### v2.1.0 - -- Add support for SSL connections in JavaScript driver -- this means you can connect to heroku postgres from your local machine without the native bindings! -- [Add field metadata to result object](https://github.com/brianc/node-postgres/blob/master/test/integration/client/row-description-on-results-tests.js) -- [Add ability for rows to be returned as arrays instead of objects](https://github.com/brianc/node-postgres/blob/master/test/integration/client/results-as-array-tests.js) - -### v2.0.0 - -- Properly handle various PostgreSQL to JavaScript type conversions to avoid data loss: - -``` -PostgreSQL | pg@v2.0 JavaScript | pg@v1.0 JavaScript ---------------------------------|---------------- -float4 | number (float) | string -float8 | number (float) | string -int8 | string | number (int) -numeric | string | number (float) -decimal | string | number (float) -``` - -For more information see https://github.com/brianc/node-postgres/pull/353 -If you are unhappy with these changes you can always [override the built in type parsing fairly easily](https://github.com/brianc/node-pg-parse-float). - -### v1.3.0 - -- Make client_encoding configurable and optional - -### v1.2.0 - -- return field metadata on result object: access via result.fields[i].name/dataTypeID - -### v1.1.0 - -- built in support for `JSON` data type for PostgreSQL Server @ v9.2.0 or greater - -### v1.0.0 - -- remove deprecated functionality - - Callback function passed to `pg.connect` now **requires** 3 arguments - - Client#pauseDrain() / Client#resumeDrain removed - - numeric, decimal, and float data types no longer parsed into float before being returned. Will be returned from query results as `String` - -### v0.15.0 - -- client now emits `end` when disconnected from back-end server -- if client is disconnected in the middle of a query, query receives an error - -### v0.14.0 - -- add deprecation warnings in prep for v1.0 -- fix read/write failures in native module under node v0.9.x diff --git a/packages/pg/README.md b/packages/pg/README.md index 0d7953f4..0d471dd4 100644 --- a/packages/pg/README.md +++ b/packages/pg/README.md @@ -5,7 +5,7 @@ NPM version NPM downloads -Non-blocking PostgreSQL client for Node.js. Pure JavaScript and optional native libpq bindings. +Non-blocking PostgreSQL client for Node.js. Pure JavaScript and optional native libpq bindings. ## Install @@ -14,30 +14,31 @@ $ npm install pg ``` --- -## :star: [Documentation](https://node-postgres.com) :star: +## :star: [Documentation](https://node-postgres.com) :star: ### Features -* Pure JavaScript client and native libpq bindings share _the same API_ -* Connection pooling -* Extensible JS ↔ PostgreSQL data-type coercion -* Supported PostgreSQL features - * Parameterized queries - * Named statements with query plan caching - * Async notifications with `LISTEN/NOTIFY` - * Bulk import & export with `COPY TO/COPY FROM` +- Pure JavaScript client and native libpq bindings share _the same API_ +- Connection pooling +- Extensible JS ↔ PostgreSQL data-type coercion +- Supported PostgreSQL features + - Parameterized queries + - Named statements with query plan caching + - Async notifications with `LISTEN/NOTIFY` + - Bulk import & export with `COPY TO/COPY FROM` ### Extras -node-postgres is by design pretty light on abstractions. These are some handy modules we've been using over the years to complete the picture. +node-postgres is by design pretty light on abstractions. These are some handy modules we've been using over the years to complete the picture. The entire list can be found on our [wiki](https://github.com/brianc/node-postgres/wiki/Extras). ## Support -node-postgres is free software. If you encounter a bug with the library please open an issue on the [GitHub repo](https://github.com/brianc/node-postgres). If you have questions unanswered by the documentation please open an issue pointing out how the documentation was unclear & I will do my best to make it better! +node-postgres is free software. If you encounter a bug with the library please open an issue on the [GitHub repo](https://github.com/brianc/node-postgres). If you have questions unanswered by the documentation please open an issue pointing out how the documentation was unclear & I will do my best to make it better! When you open an issue please provide: + - version of Node - version of Postgres - smallest possible snippet of code to reproduce the problem @@ -49,10 +50,6 @@ You can also follow me [@briancarlson](https://twitter.com/briancarlson) if that node-postgres's continued development has been made possible in part by generous finanical support from [the community](https://github.com/brianc/node-postgres/blob/master/SPONSORS.md) and these featured sponsors:
- - - - @@ -60,19 +57,18 @@ node-postgres's continued development has been made possible in part by generous If you or your company are benefiting from node-postgres and would like to help keep the project financially sustainable [please consider supporting](https://github.com/sponsors/brianc) its development. - ## Contributing -__:heart: contributions!__ +**:heart: contributions!** -I will __happily__ accept your pull request if it: -- __has tests__ +I will **happily** accept your pull request if it: + +- **has tests** - looks reasonable - does not break backwards compatibility If your change involves breaking backwards compatibility please please point that out in the pull request & we can discuss & plan when and how to release it and what type of documentation or communicate it will require. - ## Troubleshooting and FAQ The causes and solutions to common errors can be found among the [Frequently Asked Questions (FAQ)](https://github.com/brianc/node-postgres/wiki/FAQ) @@ -81,21 +77,20 @@ The causes and solutions to common errors can be found among the [Frequently Ask Copyright (c) 2010-2020 Brian Carlson (brian.m.carlson@gmail.com) - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. From c55758fca09e4ef6fcee60b4a9ac0469e46f98ba Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Fri, 8 May 2020 10:51:13 -0500 Subject: [PATCH 50/58] Update changelog --- CHANGELOG.md | 389 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..6e92a7b0 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,389 @@ +All major and minor releases are briefly explained below. + +For richer information consult the commit log on github with referenced pull requests. + +We do not include break-fix version release in this file. + +### pg@8.1.0 + +- Switch to using [monorepo](https://github.com/brianc/node-postgres/tree/master/packages/pg-connection-string) version of `pg-connection-string`. This includes better support for SSL argument parsing from connection strings and ensures continuity of support. +- Add `&ssl=no-verify` option to connection string and `PGSSLMODE=no-verify` environment variable support for the pure JS driver. This is equivalent of passing `{ ssl: { rejectUnauthorize: false } }` to the client/pool constructor. The advantage of having support in connection strings and environment variables is it can be "externally" configured via environment variables and CLI arguments much more easily, and should remove the need to directly edit any application code for [the SSL default changes in 8.0](https://node-postgres.com/announcements#2020-02-25). This should make using `pg@8.x` significantly less difficult on environments like Heroku for example. + +### pg-pool@3.2.0 + +- Same changes to `pg` impact `pg-pool` as they both use the same connection parameter and connection string parsing code for configuring SSL. + +### pg-pool@3.1.0 + +- Add [maxUses](https://github.com/brianc/node-postgres/pull/2157) config option. + +### pg@8.0.0 + +#### note: for detailed release notes please [check here](https://node-postgres.com/announcements#2020-02-25) + +- Remove versions of node older than `6 lts` from the test matrix. `pg>=8.0` may still work on older versions but it is no longer officially supported. +- Change default behavior when not specifying `rejectUnauthorized` with the SSL connection parameters. Previously we defaulted to `rejectUnauthorized: false` when it was not specifically included. We now default to `rejectUnauthorized: true.` Manually specify `{ ssl: { rejectUnauthorized: false } }` for old behavior. +- Change [default database](https://github.com/brianc/node-postgres/pull/1679) when not specified to use the `user` config option if available. Previously `process.env.USER` was used. +- Change `pg.Pool` and `pg.Query` to [be](https://github.com/brianc/node-postgres/pull/2126) an [es6 class](https://github.com/brianc/node-postgres/pull/2063). +- Make `pg.native` non enumerable. +- `notice` messages are [no longer instances](https://github.com/brianc/node-postgres/pull/2090) of `Error`. +- Passwords no longer [show up](https://github.com/brianc/node-postgres/pull/2070) when instances of clients or pools are logged. + +### pg@7.18.0 + +- This will likely be the last minor release before pg@8.0. +- This version contains a few bug fixes and adds a deprecation warning for [a pending change in 8.0](https://github.com/brianc/node-postgres/issues/2009#issuecomment-579371651) which will flip the default behavior over SSL from `rejectUnauthorized` from `false` to `true` making things more secure in the general use case. + +### pg-query-stream@3.0.0 + +- [Rewrote stream internals](https://github.com/brianc/node-postgres/pull/2051) to better conform to node stream semantics. This should make pg-query-stream much better at respecting [highWaterMark](https://nodejs.org/api/stream.html#stream_new_stream_readable_options) and getting rid of some edge case bugs when using pg-query-stream as an async iterator. Due to the size and nature of this change (effectively a full re-write) it's safest to bump the semver major here, though almost all tests remain untouched and still passing, which brings us to a breaking change to the API.... +- Changed `stream.close` to `stream.destroy` which is the [official](https://nodejs.org/api/stream.html#stream_readable_destroy_error) way to terminate a readable stream. This is a **breaking change** if you rely on the `stream.close` method on pg-query-stream...though should be just a find/replace type operation to upgrade as the semantics remain very similar (not exactly the same, since internals are rewritten, but more in line with how streams are "supposed" to behave). +- Unified the `config.batchSize` and `config.highWaterMark` to both do the same thing: control how many rows are buffered in memory. The `ReadableStream` will manage exactly how many rows are requested from the cursor at a time. This should give better out of the box performance and help with efficient async iteration. + +### pg@7.17.0 + +- Add support for `idle_in_transaction_session_timeout` [option](https://github.com/brianc/node-postgres/pull/2049). + +### 7.16.0 + +- Add optional, opt-in behavior to test new, [faster query pipeline](https://github.com/brianc/node-postgres/pull/2044). This is experimental, and not documented yet. The pipeline changes will grow significantly after the 8.0 release. + +### 7.15.0 + +- Change repository structure to support lerna & future monorepo [development](https://github.com/brianc/node-postgres/pull/2014). +- [Warn about deprecation](https://github.com/brianc/node-postgres/pull/2021) for calling constructors without `new`. + +### 7.14.0 + +- Reverts 7.13.0 as it contained [an accidental breaking change](https://github.com/brianc/node-postgres/pull/2010) for self-signed SSL cert verification. 7.14.0 is identical to 7.12.1. + +### 7.13.0 + +- Add support for [all tls.connect()](https://github.com/brianc/node-postgres/pull/1996) options. + +### 7.12.0 + +- Add support for [async password lookup](https://github.com/brianc/node-postgres/pull/1926). + +### 7.11.0 + +- Add support for [connection_timeout](https://github.com/brianc/node-postgres/pull/1847/files#diff-5391bde944956870128be1136e7bc176R63) and [keepalives_idle](https://github.com/brianc/node-postgres/pull/1847). + +### 7.10.0 + +- Add support for [per-query types](https://github.com/brianc/node-postgres/pull/1825). + +### 7.9.0 + +- Add support for [sasl/scram authentication](https://github.com/brianc/node-postgres/pull/1835). + +### 7.8.0 + +- Add support for passing [secureOptions](https://github.com/brianc/node-postgres/pull/1804) SSL config. +- Upgrade [pg-types](https://github.com/brianc/node-postgres/pull/1806) to 2.0. + +### 7.7.0 + +- Add support for configurable [query timeout](https://github.com/brianc/node-postgres/pull/1760) on a client level. + +### 7.6.0 + +- Add support for ["bring your own promise"](https://github.com/brianc/node-postgres/pull/1518) + +### 7.5.0 + +- Better [error message](https://github.com/brianc/node-postgres/commit/11a4793452d618c53e019416cc886ad38deb1aa7) when passing `null` or `undefined` to `client.query`. +- Better [error handling](https://github.com/brianc/node-postgres/pull/1503) on queued queries. + +### 7.4.0 + +- Add support for [Uint8Array](https://github.com/brianc/node-postgres/pull/1448) values. + +### 7.3.0 + +- Add support for [statement timeout](https://github.com/brianc/node-postgres/pull/1436). + +### 7.2.0 + +- Pinned pg-pool and pg-types to a tighter semver range. This is likely not a noticeable change for you unless you were specifically installing older versions of those libraries for some reason, but making it a minor bump here just in case it could cause any confusion. + +### 7.1.0 + +#### Enhancements + +- [You can now supply both a connection string and additional config options to clients.](https://github.com/brianc/node-postgres/pull/1363) + +### 7.0.0 + +#### Breaking Changes + +- Drop support for node < `4.x`. +- Remove `pg.connect` `pg.end` and `pg.cancel` singleton methods. +- `Client#connect(callback)` now returns `undefined`. It used to return an event emitter. +- Upgrade [pg-pool](https://github.com/brianc/node-pg-pool) to `2.x`. +- Upgrade [pg-native](https://github.com/brianc/node-pg-native) to `2.x`. +- Standardize error message fields between JS and native driver. The only breaking changes were in the native driver as its field names were brought into alignment with the existing JS driver field names. +- Result from multi-statement text queries such as `SELECT 1; SELECT 2;` are now returned as an array of results instead of a single result with 1 array containing rows from both queries. + +[Please see here for a migration guide](https://node-postgres.com/guides/upgrading) + +#### Enhancements + +- Overhauled documentation: [https://node-postgres.com](https://node-postgres.com). +- Add `Client#connect() => Promise` and `Client#end() => Promise` calls. Promises are now returned from all async methods on clients _if and only if_ no callback was supplied to the method. +- Add `connectionTimeoutMillis` to pg-pool. + +### v6.2.0 + +- Add support for [parsing `replicationStart` messages](https://github.com/brianc/node-postgres/pull/1271/files). + +### v6.1.0 + +- Add optional callback parameter to the pure JavaScript `client.end` method. The native client already supported this. + +### v6.0.0 + +#### Breaking Changes + +- Remove `pg.pools`. There is still a reference kept to the pools created & tracked by `pg.connect` but it has been renamed, is considered private, and should not be used. Accessing this API directly was uncommon and was _supposed_ to be private but was incorrectly documented on the wiki. Therefore, it is a breaking change of an (unintentionally) public interface to remove it by renaming it & making it private. Eventually `pg.connect` itself will be deprecated in favor of instantiating pools directly via `new pg.Pool()` so this property should become completely moot at some point. In the mean time...check out the new features... + +#### New features + +- Replace internal pooling code with [pg-pool](https://github.com/brianc/node-pg-pool). This is the first step in eventually deprecating and removing the singleton `pg.connect`. The pg-pool constructor is exported from node-postgres at `require('pg').Pool`. It provides a backwards compatible interface with `pg.connect` as well as a promise based interface & additional niceties. + +You can now create an instance of a pool and don't have to rely on the `pg` singleton for anything: + +``` +var pg = require('pg') + +var pool = new pg.Pool() + +// your friendly neighborhood pool interface, without the singleton +pool.connect(function(err, client, done) { + // ... +}) +``` + +Promise support & other goodness lives now in [pg-pool](https://github.com/brianc/node-pg-pool). + +**Please** read the readme at [pg-pool](https://github.com/brianc/node-pg-pool) for the full api. + +- Included support for tcp keep alive. Enable it as follows: + +```js +var client = new Client({ keepAlive: true }) +``` + +This should help with backends incorrectly considering idle clients to be dead and prematurely disconnecting them. + +### v5.1.0 + +- Make the query object returned from `client.query` implement the promise interface. This is the first step towards promisifying more of the node-postgres api. + +Example: + +```js +var client = new Client() +client.connect() +client.query('SELECT $1::text as name', ['brianc']).then(function (res) { + console.log('hello from', res.rows[0]) + client.end() +}) +``` + +### v5.0.0 + +#### Breaking Changes + +- `require('pg').native` now returns null if the native bindings cannot be found; previously, this threw an exception. + +#### New Features + +- better error message when passing `undefined` as a query parameter +- support for `defaults.connectionString` +- support for `returnToHead` being passed to [generic pool](https://github.com/coopernurse/node-pool) + +### v4.5.0 + +- Add option to parse JS date objects in query parameters as [UTC](https://github.com/brianc/node-postgres/pull/943) + +### v4.4.0 + +- Warn to `stderr` if a named query exceeds 63 characters which is the max length supported by postgres. + +### v4.3.0 + +- Unpin `pg-types` semver. Allow it to float against `pg-types@1.x`. + +### v4.2.0 + +- Support for additional error fields in postgres >= 9.3 if available. + +### v4.1.0 + +- Allow type parser overrides on a [per-client basis](https://github.com/brianc/node-postgres/pull/679) + +### v4.0.0 + +- Make [native bindings](https://github.com/brianc/node-pg-native.git) an optional install with `npm install pg-native` +- No longer surround query result callback with `try/catch` block. +- Remove built in COPY IN / COPY OUT support - better implementations provided by [pg-copy-streams](https://github.com/brianc/node-pg-copy-streams.git) and [pg-native](https://github.com/brianc/node-pg-native.git) + +### v3.6.0 + +- Include support for (parsing JSONB)[https://github.com/brianc/node-pg-types/pull/13] (supported in postgres 9.4) + +### v3.5.0 + +- Include support for parsing boolean arrays + +### v3.4.0 + +- Include port as connection parameter to [unix sockets](https://github.com/brianc/node-postgres/pull/604) +- Better support for odd [date parsing](https://github.com/brianc/node-pg-types/pull/8) + +### v3.2.0 + +- Add support for parsing [date arrays](https://github.com/brianc/node-pg-types/pull/3) +- Expose array parsers on [pg.types](https://github.com/brianc/node-pg-types/pull/2) +- Allow [pool](https://github.com/brianc/node-postgres/pull/591) to be configured + +### v3.1.0 + +- Add [count of the number of times a client has been checked out from the pool](https://github.com/brianc/node-postgres/pull/556) +- Emit `end` from `pg` object [when a pool is drained](https://github.com/brianc/node-postgres/pull/571) + +### v3.0.0 + +#### Breaking changes + +- [Parse the DATE PostgreSQL type as local time](https://github.com/brianc/node-postgres/pull/514) + +After [some discussion](https://github.com/brianc/node-postgres/issues/510) it was decided node-postgres was non-compliant in how it was handling DATE results. They were being converted to UTC, but the PostgreSQL documentation specifies they should be returned in the client timezone. This is a breaking change, and if you use the `date` type you might want to examine your code and make sure nothing is impacted. + +- [Fix possible numeric precision loss on numeric & int8 arrays](https://github.com/brianc/node-postgres/pull/501) + +pg@v2.0 included changes to not convert large integers into their JavaScript number representation because of possibility for numeric precision loss. The same types in arrays were not taken into account. This fix applies the same type of type-coercion rules to arrays of those types, so there will be no more possible numeric loss on an array of very large int8s for example. This is a breaking change because now a return type from a query of `int8[]` will contain _string_ representations +of the integers. Use your favorite JavaScript bignum module to represent them without precision loss, or punch over the type converter to return the old style arrays again. + +- [Fix to input array of dates being improperly converted to utc](https://github.com/benesch/node-postgres/commit/c41eedc3e01e5527a3d5c242fa1896f02ef0b261#diff-7172adb1fec2457a2700ed29008a8e0aR108) + +Single `date` parameters were properly sent to the PostgreSQL server properly in local time, but an input array of dates was being changed into utc dates. This is a violation of what PostgreSQL expects. Small breaking change, but none-the-less something you should check out if you are inserting an array of dates. + +- [Query no longer emits `end` event if it ends due to an error](https://github.com/brianc/node-postgres/commit/357b64d70431ec5ca721eb45a63b082c18e6ffa3) + +This is a small change to bring the semantics of query more in line with other EventEmitters. The tests all passed after this change, but I suppose it could still be a breaking change in certain use cases. If you are doing clever things with the `end` and `error` events of a query object you might want to check to make sure its still behaving normally, though it is most likely not an issue. + +#### New features + +- [Supercharge `prepareValue`](https://github.com/brianc/node-postgres/pull/555) + +The long & short of it is now any object you supply in the list of query values will be inspected for a `.toPostgres` method. If the method is present it will be called and its result used as the raw text value sent to PostgreSQL for that value. This allows the same type of custom type coercion on query parameters as was previously afforded to query result values. + +- [Domain aware connection pool](https://github.com/brianc/node-postgres/pull/531) + +If domains are active node-postgres will honor them and do everything it can to ensure all callbacks are properly fired in the active domain. If you have tried to use domains with node-postgres (or many other modules which pool long lived event emitters) you may have run into an issue where the active domain changes before and after a callback. This has been a longstanding footgun within node-postgres and I am happy to get it fixed. + +- [Disconnected clients now removed from pool](https://github.com/brianc/node-postgres/pull/543) + +Avoids a scenario where your pool could fill up with disconnected & unusable clients. + +- [Break type parsing code into separate module](https://github.com/brianc/node-postgres/pull/541) + +To provide better documentation and a clearer explanation of how to override the query result parsing system we broke the type converters [into their own module](https://github.com/brianc/node-pg-types). There is still work around removing the 'global-ness' of the type converters so each query or connection can return types differently, but this is a good first step and allow a lot more obvious way to return int8 results as JavaScript numbers, for example + +### v2.11.0 + +- Add support for [application_name](https://github.com/brianc/node-postgres/pull/497) + +### v2.10.0 + +- Add support for [the password file](http://www.postgresql.org/docs/9.3/static/libpq-pgpass.html) + +### v2.9.0 + +- Add better support for [unix domain socket](https://github.com/brianc/node-postgres/pull/487) connections + +### v2.8.0 + +- Add support for parsing JSON[] and UUID[] result types + +### v2.7.0 + +- Use single row mode in native bindings when available [@rpedela] + - reduces memory consumption when handling row values in 'row' event +- Automatically bind buffer type parameters as binary [@eugeneware] + +### v2.6.0 + +- Respect PGSSLMODE environment variable + +### v2.5.0 + +- Ability to opt-in to int8 parsing via `pg.defaults.parseInt8 = true` + +### v2.4.0 + +- Use eval in the result set parser to increase performance + +### v2.3.0 + +- Remove built-in support for binary Int64 parsing. + _Due to the low usage & required compiled dependency this will be pushed into a 3rd party add-on_ + +### v2.2.0 + +- [Add support for excapeLiteral and escapeIdentifier in both JavaScript and the native bindings](https://github.com/brianc/node-postgres/pull/396) + +### v2.1.0 + +- Add support for SSL connections in JavaScript driver +- this means you can connect to heroku postgres from your local machine without the native bindings! +- [Add field metadata to result object](https://github.com/brianc/node-postgres/blob/master/test/integration/client/row-description-on-results-tests.js) +- [Add ability for rows to be returned as arrays instead of objects](https://github.com/brianc/node-postgres/blob/master/test/integration/client/results-as-array-tests.js) + +### v2.0.0 + +- Properly handle various PostgreSQL to JavaScript type conversions to avoid data loss: + +``` +PostgreSQL | pg@v2.0 JavaScript | pg@v1.0 JavaScript +--------------------------------|---------------- +float4 | number (float) | string +float8 | number (float) | string +int8 | string | number (int) +numeric | string | number (float) +decimal | string | number (float) +``` + +For more information see https://github.com/brianc/node-postgres/pull/353 +If you are unhappy with these changes you can always [override the built in type parsing fairly easily](https://github.com/brianc/node-pg-parse-float). + +### v1.3.0 + +- Make client_encoding configurable and optional + +### v1.2.0 + +- return field metadata on result object: access via result.fields[i].name/dataTypeID + +### v1.1.0 + +- built in support for `JSON` data type for PostgreSQL Server @ v9.2.0 or greater + +### v1.0.0 + +- remove deprecated functionality + - Callback function passed to `pg.connect` now **requires** 3 arguments + - Client#pauseDrain() / Client#resumeDrain removed + - numeric, decimal, and float data types no longer parsed into float before being returned. Will be returned from query results as `String` + +### v0.15.0 + +- client now emits `end` when disconnected from back-end server +- if client is disconnected in the middle of a query, query receives an error + +### v0.14.0 + +- add deprecation warnings in prep for v1.0 +- fix read/write failures in native module under node v0.9.x From 4a80468a8a2eec92ee0240c37b18300590410d96 Mon Sep 17 00:00:00 2001 From: Sehrope Sarkuni Date: Sat, 9 May 2020 15:44:24 -0400 Subject: [PATCH 51/58] test: Add sasl-scram-tests.js Adds tests for SCRAM if SCRAM_TEST_PGUSER and SCRAM_TEST_PGPASSWORD are defined. If not the tests are skipped (default). --- .../integration/client/sasl-scram-tests.js | 100 ++++++++++++------ 1 file changed, 67 insertions(+), 33 deletions(-) diff --git a/packages/pg/test/integration/client/sasl-scram-tests.js b/packages/pg/test/integration/client/sasl-scram-tests.js index f5326d8a..debc2868 100644 --- a/packages/pg/test/integration/client/sasl-scram-tests.js +++ b/packages/pg/test/integration/client/sasl-scram-tests.js @@ -1,41 +1,75 @@ 'use strict' -var helper = require(__dirname + '/../test-helper') -var pg = helper.pg +const helper = require('./../test-helper') +const pg = helper.pg +const suite = new helper.Suite() +const { native } = helper.args -var suite = new helper.Suite() +/** + * This test only executes if the env variables SCRAM_TEST_PGUSER and + * SCRAM_TEST_PGPASSWORD are defined. You can override additional values + * for the host, port and database with other SCRAM_TEST_ prefixed vars. + * If the variables are not defined the test will be skipped. + * + * SQL to create test role: + * + * SET password_encryption = 'scram-sha-256'; + * CREATE ROLE scram_test login password 'test4scram'; + * + * Add the following entries to pg_hba.conf: + * + * host all scram_test ::1/128 scram-sha-256 + * host all scram_test 0.0.0.0/0 scram-sha-256 + * + * Then run this file with after exporting: + * + * SCRAM_TEST_PGUSER=scram_test + * SCRAM_TEST_PGPASSWORD=test4scram + */ -/* -SQL to create test role: +// Base config for SCRAM tests +const config = { + user: process.env.SCRAM_TEST_PGUSER, + password: process.env.SCRAM_TEST_PGPASSWORD, + host: process.env.SCRAM_TEST_PGHOST, // optional + port: process.env.SCRAM_TEST_PGPORT, // optional + database: process.env.SCRAM_TEST_PGDATABASE, // optional +} -set password_encryption = 'scram-sha-256'; -create role npgtest login password 'test'; +if (native) { + suite.testAsync('skipping SCRAM tests (on native)', () => {}) + return +} +if (!config.user || !config.password) { + suite.testAsync('skipping SCRAM tests (missing env)', () => {}) + return +} -pg_hba: -host all npgtest ::1/128 scram-sha-256 -host all npgtest 0.0.0.0/0 scram-sha-256 - - -*/ -/* -suite.test('can connect using sasl/scram', function () { - var connectionString = 'pg://npgtest:test@localhost/postgres' - const pool = new pg.Pool({ connectionString: connectionString }) - pool.connect( - assert.calls(function (err, client, done) { - assert.ifError(err, 'should have connected') - done() - }) - ) +suite.testAsync('can connect using sasl/scram', async () => { + const client = new pg.Client(config) + let usingSasl = false + client.connection.once('authenticationSASL', () => { + usingSasl = true + }) + await client.connect() + assert.ok(usingSasl, 'Should be using SASL for authentication') + await client.end() }) -suite.test('sasl/scram fails when password is wrong', function () { - var connectionString = 'pg://npgtest:bad@localhost/postgres' - const pool = new pg.Pool({ connectionString: connectionString }) - pool.connect( - assert.calls(function (err, client, done) { - assert.ok(err, 'should have a connection error') - done() - }) - ) +suite.testAsync('sasl/scram fails when password is wrong', async () => { + const client = new pg.Client({ + ...config, + password: config.password + 'append-something-to-make-it-bad', + }) + let usingSasl = false + client.connection.once('authenticationSASL', () => { + usingSasl = true + }) + await assert.rejects( + () => client.connect(), + { + code: '28P01', + }, + 'Error code should be for a password error' + ) + assert.ok(usingSasl, 'Should be using SASL for authentication') }) -*/ From c25e88916a1757491bbf0ebcb30a8332b4a24377 Mon Sep 17 00:00:00 2001 From: Sehrope Sarkuni Date: Sat, 9 May 2020 16:17:54 -0400 Subject: [PATCH 52/58] test: Enable scram tests on travis --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 0518579d..9629156e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -27,7 +27,7 @@ matrix: # Run tests/paths that require password authentication - node_js: lts/erbium env: - - CC=clang CXX=clang++ npm_config_clang=1 PGUSER=postgres PGDATABASE=postgres PGPASSWORD=test-password + - CC=clang CXX=clang++ npm_config_clang=1 PGUSER=postgres PGDATABASE=postgres PGPASSWORD=test-password SCRAM_TEST_PGUSER=scram_test SCRAM_TEST_PGPASSWORD=test4scram before_script: | sudo -u postgres sed -i \ -e '/^local/ s/trust$/peer/' \ @@ -36,6 +36,9 @@ matrix: sudo -u postgres psql -c "ALTER ROLE postgres PASSWORD 'test-password'; SELECT pg_reload_conf()" yarn build node packages/pg/script/create-test-tables.js postgresql:/// + sudo -u postgres -- psql \ + -c "SET password_encryption = 'scram-sha-256'" \ + -c "CREATE ROLE scram_test login password 'test4scram'" - node_js: lts/carbon addons: From 520bd3531990f32c3e00b20020c67f6ac6c70261 Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Tue, 12 May 2020 10:56:14 -0500 Subject: [PATCH 53/58] Switch internals to use faster connection This switches the internals to use faster protocol parsing & serializing. This results in a significant (30% - 50%) speed up in some common query patterns. There is quite a bit more performance work I need to do, but this takes care of some initial stuff & removes a big fork in the code. --- .travis.yml | 18 +- packages/pg/lib/client.js | 3 - packages/pg/lib/connection-fast.js | 214 ------- packages/pg/lib/connection.js | 550 ++---------------- .../unit/connection/outbound-sending-tests.js | 205 ------- 5 files changed, 51 insertions(+), 939 deletions(-) delete mode 100644 packages/pg/lib/connection-fast.js delete mode 100644 packages/pg/test/unit/connection/outbound-sending-tests.js diff --git a/.travis.yml b/.travis.yml index 9629156e..7987f761 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,20 +7,18 @@ before_script: | env: - CC=clang CXX=clang++ npm_config_clang=1 PGUSER=postgres PGDATABASE=postgres - # test w/ new faster parsing code - - CC=clang CXX=clang++ npm_config_clang=1 PGUSER=postgres PGDATABASE=postgres PG_FAST_CONNECTION=true node_js: - lts/dubnium - lts/erbium # node 13.7 seems to have changed behavior of async iterators exiting early on streams # if 13.8 still has this problem when it comes down I'll talk to the node team about the change - # in the mean time...peg to 13.6 + # in the mean time...peg to 13.6 - 13.6 - 14 addons: - postgresql: "10" + postgresql: '10' matrix: include: @@ -42,25 +40,25 @@ matrix: - node_js: lts/carbon addons: - postgresql: "9.5" + postgresql: '9.5' dist: precise # different PostgreSQL versions on Node LTS - node_js: lts/erbium addons: - postgresql: "9.3" + postgresql: '9.3' - node_js: lts/erbium addons: - postgresql: "9.4" + postgresql: '9.4' - node_js: lts/erbium addons: - postgresql: "9.5" + postgresql: '9.5' - node_js: lts/erbium addons: - postgresql: "9.6" + postgresql: '9.6' # PostgreSQL 9.2 only works on precise - node_js: lts/carbon addons: - postgresql: "9.2" + postgresql: '9.2' dist: precise diff --git a/packages/pg/lib/client.js b/packages/pg/lib/client.js index 76906712..2c12f2cc 100644 --- a/packages/pg/lib/client.js +++ b/packages/pg/lib/client.js @@ -18,9 +18,6 @@ var ConnectionParameters = require('./connection-parameters') var Query = require('./query') var defaults = require('./defaults') var Connection = require('./connection') -if (process.env.PG_FAST_CONNECTION) { - Connection = require('./connection-fast') -} var Client = function (config) { EventEmitter.call(this) diff --git a/packages/pg/lib/connection-fast.js b/packages/pg/lib/connection-fast.js deleted file mode 100644 index 7cc2ed8c..00000000 --- a/packages/pg/lib/connection-fast.js +++ /dev/null @@ -1,214 +0,0 @@ -'use strict' -/** - * Copyright (c) 2010-2017 Brian Carlson (brian.m.carlson@gmail.com) - * All rights reserved. - * - * This source code is licensed under the MIT license found in the - * README.md file in the root directory of this source tree. - */ - -var net = require('net') -var EventEmitter = require('events').EventEmitter -var util = require('util') - -const { parse, serialize } = require('pg-protocol') - -// TODO(bmc) support binary mode at some point -console.log('***using faster connection***') -var Connection = function (config) { - EventEmitter.call(this) - config = config || {} - this.stream = config.stream || new net.Socket() - this.stream.setNoDelay(true) - this._keepAlive = config.keepAlive - this._keepAliveInitialDelayMillis = config.keepAliveInitialDelayMillis - this.lastBuffer = false - this.parsedStatements = {} - this.ssl = config.ssl || false - this._ending = false - this._emitMessage = false - var self = this - this.on('newListener', function (eventName) { - if (eventName === 'message') { - self._emitMessage = true - } - }) -} - -util.inherits(Connection, EventEmitter) - -Connection.prototype.connect = function (port, host) { - var self = this - - this._connecting = true - this.stream.connect(port, host) - - this.stream.once('connect', function () { - if (self._keepAlive) { - self.stream.setKeepAlive(true, self._keepAliveInitialDelayMillis) - } - self.emit('connect') - }) - - const reportStreamError = function (error) { - // errors about disconnections should be ignored during disconnect - if (self._ending && (error.code === 'ECONNRESET' || error.code === 'EPIPE')) { - return - } - self.emit('error', error) - } - this.stream.on('error', reportStreamError) - - this.stream.on('close', function () { - self.emit('end') - }) - - if (!this.ssl) { - return this.attachListeners(this.stream) - } - - this.stream.once('data', function (buffer) { - var responseCode = buffer.toString('utf8') - switch (responseCode) { - case 'S': // Server supports SSL connections, continue with a secure connection - break - case 'N': // Server does not support SSL connections - self.stream.end() - return self.emit('error', new Error('The server does not support SSL connections')) - default: - // Any other response byte, including 'E' (ErrorResponse) indicating a server error - self.stream.end() - return self.emit('error', new Error('There was an error establishing an SSL connection')) - } - var tls = require('tls') - const options = Object.assign( - { - socket: self.stream, - }, - self.ssl - ) - if (net.isIP(host) === 0) { - options.servername = host - } - self.stream = tls.connect(options) - self.attachListeners(self.stream) - self.stream.on('error', reportStreamError) - - self.emit('sslconnect') - }) -} - -Connection.prototype.attachListeners = function (stream) { - stream.on('end', () => { - this.emit('end') - }) - parse(stream, (msg) => { - var eventName = msg.name === 'error' ? 'errorMessage' : msg.name - if (this._emitMessage) { - this.emit('message', msg) - } - this.emit(eventName, msg) - }) -} - -Connection.prototype.requestSsl = function () { - this.stream.write(serialize.requestSsl()) -} - -Connection.prototype.startup = function (config) { - this.stream.write(serialize.startup(config)) -} - -Connection.prototype.cancel = function (processID, secretKey) { - this._send(serialize.cancel(processID, secretKey)) -} - -Connection.prototype.password = function (password) { - this._send(serialize.password(password)) -} - -Connection.prototype.sendSASLInitialResponseMessage = function (mechanism, initialResponse) { - this._send(serialize.sendSASLInitialResponseMessage(mechanism, initialResponse)) -} - -Connection.prototype.sendSCRAMClientFinalMessage = function (additionalData) { - this._send(serialize.sendSCRAMClientFinalMessage(additionalData)) -} - -Connection.prototype._send = function (buffer) { - if (!this.stream.writable) { - return false - } - return this.stream.write(buffer) -} - -Connection.prototype.query = function (text) { - this._send(serialize.query(text)) -} - -// send parse message -Connection.prototype.parse = function (query) { - this._send(serialize.parse(query)) -} - -// send bind message -// "more" === true to buffer the message until flush() is called -Connection.prototype.bind = function (config) { - this._send(serialize.bind(config)) -} - -// send execute message -// "more" === true to buffer the message until flush() is called -Connection.prototype.execute = function (config) { - this._send(serialize.execute(config)) -} - -const flushBuffer = serialize.flush() -Connection.prototype.flush = function () { - if (this.stream.writable) { - this.stream.write(flushBuffer) - } -} - -const syncBuffer = serialize.sync() -Connection.prototype.sync = function () { - this._ending = true - this._send(syncBuffer) - this._send(flushBuffer) -} - -const endBuffer = serialize.end() - -Connection.prototype.end = function () { - // 0x58 = 'X' - this._ending = true - if (!this._connecting || !this.stream.writable) { - this.stream.end() - return - } - return this.stream.write(endBuffer, () => { - this.stream.end() - }) -} - -Connection.prototype.close = function (msg) { - this._send(serialize.close(msg)) -} - -Connection.prototype.describe = function (msg) { - this._send(serialize.describe(msg)) -} - -Connection.prototype.sendCopyFromChunk = function (chunk) { - this._send(serialize.copyData(chunk)) -} - -Connection.prototype.endCopyFrom = function () { - this._send(serialize.copyDone()) -} - -Connection.prototype.sendCopyFail = function (msg) { - this._send(serialize.copyFail(msg)) -} - -module.exports = Connection diff --git a/packages/pg/lib/connection.js b/packages/pg/lib/connection.js index c3f30aa0..bce18348 100644 --- a/packages/pg/lib/connection.js +++ b/packages/pg/lib/connection.js @@ -11,11 +11,9 @@ var net = require('net') var EventEmitter = require('events').EventEmitter var util = require('util') -var Writer = require('buffer-writer') -var Reader = require('packet-reader') +const { parse, serialize } = require('pg-protocol') -var TEXT_MODE = 0 -var BINARY_MODE = 1 +// TODO(bmc) support binary mode at some point var Connection = function (config) { EventEmitter.call(this) config = config || {} @@ -23,20 +21,10 @@ var Connection = function (config) { this._keepAlive = config.keepAlive this._keepAliveInitialDelayMillis = config.keepAliveInitialDelayMillis this.lastBuffer = false - this.lastOffset = 0 - this.buffer = null - this.offset = null - this.encoding = config.encoding || 'utf8' this.parsedStatements = {} - this.writer = new Writer() this.ssl = config.ssl || false this._ending = false - this._mode = TEXT_MODE this._emitMessage = false - this._reader = new Reader({ - headerSize: 1, - lengthPadding: -4, - }) var self = this this.on('newListener', function (eventName) { if (eventName === 'message') { @@ -101,576 +89,124 @@ Connection.prototype.connect = function (port, host) { options.servername = host } self.stream = tls.connect(options) - self.stream.on('error', reportStreamError) self.attachListeners(self.stream) + self.stream.on('error', reportStreamError) + self.emit('sslconnect') }) } Connection.prototype.attachListeners = function (stream) { - var self = this - stream.on('data', function (buff) { - self._reader.addChunk(buff) - var packet = self._reader.read() - while (packet) { - var msg = self.parseMessage(packet) - var eventName = msg.name === 'error' ? 'errorMessage' : msg.name - if (self._emitMessage) { - self.emit('message', msg) - } - self.emit(eventName, msg) - packet = self._reader.read() - } + stream.on('end', () => { + this.emit('end') }) - stream.on('end', function () { - self.emit('end') + parse(stream, (msg) => { + var eventName = msg.name === 'error' ? 'errorMessage' : msg.name + if (this._emitMessage) { + this.emit('message', msg) + } + this.emit(eventName, msg) }) } Connection.prototype.requestSsl = function () { - var bodyBuffer = this.writer.addInt16(0x04d2).addInt16(0x162f).flush() - - var length = bodyBuffer.length + 4 - - var buffer = new Writer().addInt32(length).add(bodyBuffer).join() - this.stream.write(buffer) + this.stream.write(serialize.requestSsl()) } Connection.prototype.startup = function (config) { - var writer = this.writer.addInt16(3).addInt16(0) - - Object.keys(config).forEach(function (key) { - var val = config[key] - writer.addCString(key).addCString(val) - }) - - writer.addCString('client_encoding').addCString("'utf-8'") - - var bodyBuffer = writer.addCString('').flush() - // this message is sent without a code - - var length = bodyBuffer.length + 4 - - var buffer = new Writer().addInt32(length).add(bodyBuffer).join() - this.stream.write(buffer) + this.stream.write(serialize.startup(config)) } Connection.prototype.cancel = function (processID, secretKey) { - var bodyBuffer = this.writer.addInt16(1234).addInt16(5678).addInt32(processID).addInt32(secretKey).flush() - - var length = bodyBuffer.length + 4 - - var buffer = new Writer().addInt32(length).add(bodyBuffer).join() - this.stream.write(buffer) + this._send(serialize.cancel(processID, secretKey)) } Connection.prototype.password = function (password) { - // 0x70 = 'p' - this._send(0x70, this.writer.addCString(password)) + this._send(serialize.password(password)) } Connection.prototype.sendSASLInitialResponseMessage = function (mechanism, initialResponse) { - // 0x70 = 'p' - this.writer.addCString(mechanism).addInt32(Buffer.byteLength(initialResponse)).addString(initialResponse) - - this._send(0x70) + this._send(serialize.sendSASLInitialResponseMessage(mechanism, initialResponse)) } Connection.prototype.sendSCRAMClientFinalMessage = function (additionalData) { - // 0x70 = 'p' - this.writer.addString(additionalData) - - this._send(0x70) + this._send(serialize.sendSCRAMClientFinalMessage(additionalData)) } -Connection.prototype._send = function (code, more) { +Connection.prototype._send = function (buffer) { if (!this.stream.writable) { return false } - if (more === true) { - this.writer.addHeader(code) - } else { - return this.stream.write(this.writer.flush(code)) - } + return this.stream.write(buffer) } Connection.prototype.query = function (text) { - // 0x51 = Q - this.stream.write(this.writer.addCString(text).flush(0x51)) + this._send(serialize.query(text)) } // send parse message -// "more" === true to buffer the message until flush() is called -Connection.prototype.parse = function (query, more) { - // expect something like this: - // { name: 'queryName', - // text: 'select * from blah', - // types: ['int8', 'bool'] } - - // normalize missing query names to allow for null - query.name = query.name || '' - if (query.name.length > 63) { - /* eslint-disable no-console */ - console.error('Warning! Postgres only supports 63 characters for query names.') - console.error('You supplied %s (%s)', query.name, query.name.length) - console.error('This can cause conflicts and silent errors executing queries') - /* eslint-enable no-console */ - } - // normalize null type array - query.types = query.types || [] - var len = query.types.length - var buffer = this.writer - .addCString(query.name) // name of query - .addCString(query.text) // actual query text - .addInt16(len) - for (var i = 0; i < len; i++) { - buffer.addInt32(query.types[i]) - } - - var code = 0x50 - this._send(code, more) +Connection.prototype.parse = function (query) { + this._send(serialize.parse(query)) } // send bind message // "more" === true to buffer the message until flush() is called -Connection.prototype.bind = function (config, more) { - // normalize config - config = config || {} - config.portal = config.portal || '' - config.statement = config.statement || '' - config.binary = config.binary || false - var values = config.values || [] - var len = values.length - var useBinary = false - for (var j = 0; j < len; j++) { - useBinary |= values[j] instanceof Buffer - } - var buffer = this.writer.addCString(config.portal).addCString(config.statement) - if (!useBinary) { - buffer.addInt16(0) - } else { - buffer.addInt16(len) - for (j = 0; j < len; j++) { - buffer.addInt16(values[j] instanceof Buffer) - } - } - buffer.addInt16(len) - for (var i = 0; i < len; i++) { - var val = values[i] - if (val === null || typeof val === 'undefined') { - buffer.addInt32(-1) - } else if (val instanceof Buffer) { - buffer.addInt32(val.length) - buffer.add(val) - } else { - buffer.addInt32(Buffer.byteLength(val)) - buffer.addString(val) - } - } - - if (config.binary) { - buffer.addInt16(1) // format codes to use binary - buffer.addInt16(1) - } else { - buffer.addInt16(0) // format codes to use text - } - // 0x42 = 'B' - this._send(0x42, more) +Connection.prototype.bind = function (config) { + this._send(serialize.bind(config)) } // send execute message // "more" === true to buffer the message until flush() is called -Connection.prototype.execute = function (config, more) { - config = config || {} - config.portal = config.portal || '' - config.rows = config.rows || '' - this.writer.addCString(config.portal).addInt32(config.rows) - - // 0x45 = 'E' - this._send(0x45, more) +Connection.prototype.execute = function (config) { + this._send(serialize.execute(config)) } -var emptyBuffer = Buffer.alloc(0) - +const flushBuffer = serialize.flush() Connection.prototype.flush = function () { - // 0x48 = 'H' - this.writer.add(emptyBuffer) - this._send(0x48) + if (this.stream.writable) { + this.stream.write(flushBuffer) + } } +const syncBuffer = serialize.sync() Connection.prototype.sync = function () { - // clear out any pending data in the writer - this.writer.flush(0) - - this.writer.add(emptyBuffer) this._ending = true - this._send(0x53) + this._send(syncBuffer) + this._send(flushBuffer) } -const END_BUFFER = Buffer.from([0x58, 0x00, 0x00, 0x00, 0x04]) +const endBuffer = serialize.end() Connection.prototype.end = function () { // 0x58 = 'X' - this.writer.add(emptyBuffer) this._ending = true if (!this._connecting || !this.stream.writable) { this.stream.end() return } - return this.stream.write(END_BUFFER, () => { + return this.stream.write(endBuffer, () => { this.stream.end() }) } -Connection.prototype.close = function (msg, more) { - this.writer.addCString(msg.type + (msg.name || '')) - this._send(0x43, more) +Connection.prototype.close = function (msg) { + this._send(serialize.close(msg)) } -Connection.prototype.describe = function (msg, more) { - this.writer.addCString(msg.type + (msg.name || '')) - this._send(0x44, more) +Connection.prototype.describe = function (msg) { + this._send(serialize.describe(msg)) } Connection.prototype.sendCopyFromChunk = function (chunk) { - this.stream.write(this.writer.add(chunk).flush(0x64)) + this._send(serialize.copyData(chunk)) } Connection.prototype.endCopyFrom = function () { - this.stream.write(this.writer.add(emptyBuffer).flush(0x63)) + this._send(serialize.copyDone()) } Connection.prototype.sendCopyFail = function (msg) { - // this.stream.write(this.writer.add(emptyBuffer).flush(0x66)); - this.writer.addCString(msg) - this._send(0x66) + this._send(serialize.copyFail(msg)) } -var Message = function (name, length) { - this.name = name - this.length = length -} - -Connection.prototype.parseMessage = function (buffer) { - this.offset = 0 - var length = buffer.length + 4 - switch (this._reader.header) { - case 0x52: // R - return this.parseR(buffer, length) - - case 0x53: // S - return this.parseS(buffer, length) - - case 0x4b: // K - return this.parseK(buffer, length) - - case 0x43: // C - return this.parseC(buffer, length) - - case 0x5a: // Z - return this.parseZ(buffer, length) - - case 0x54: // T - return this.parseT(buffer, length) - - case 0x44: // D - return this.parseD(buffer, length) - - case 0x45: // E - return this.parseE(buffer, length) - - case 0x4e: // N - return this.parseN(buffer, length) - - case 0x31: // 1 - return new Message('parseComplete', length) - - case 0x32: // 2 - return new Message('bindComplete', length) - - case 0x33: // 3 - return new Message('closeComplete', length) - - case 0x41: // A - return this.parseA(buffer, length) - - case 0x6e: // n - return new Message('noData', length) - - case 0x49: // I - return new Message('emptyQuery', length) - - case 0x73: // s - return new Message('portalSuspended', length) - - case 0x47: // G - return this.parseG(buffer, length) - - case 0x48: // H - return this.parseH(buffer, length) - - case 0x57: // W - return new Message('replicationStart', length) - - case 0x63: // c - return new Message('copyDone', length) - - case 0x64: // d - return this.parsed(buffer, length) - } -} - -Connection.prototype.parseR = function (buffer, length) { - var code = this.parseInt32(buffer) - - var msg = new Message('authenticationOk', length) - - switch (code) { - case 0: // AuthenticationOk - return msg - case 3: // AuthenticationCleartextPassword - if (msg.length === 8) { - msg.name = 'authenticationCleartextPassword' - return msg - } - break - case 5: // AuthenticationMD5Password - if (msg.length === 12) { - msg.name = 'authenticationMD5Password' - msg.salt = Buffer.alloc(4) - buffer.copy(msg.salt, 0, this.offset, this.offset + 4) - this.offset += 4 - return msg - } - - break - case 10: // AuthenticationSASL - msg.name = 'authenticationSASL' - msg.mechanisms = [] - do { - var mechanism = this.parseCString(buffer) - - if (mechanism) { - msg.mechanisms.push(mechanism) - } - } while (mechanism) - - return msg - case 11: // AuthenticationSASLContinue - msg.name = 'authenticationSASLContinue' - msg.data = this.readString(buffer, length - 4) - - return msg - case 12: // AuthenticationSASLFinal - msg.name = 'authenticationSASLFinal' - msg.data = this.readString(buffer, length - 4) - - return msg - } - - throw new Error('Unknown authenticationOk message type' + util.inspect(msg)) -} - -Connection.prototype.parseS = function (buffer, length) { - var msg = new Message('parameterStatus', length) - msg.parameterName = this.parseCString(buffer) - msg.parameterValue = this.parseCString(buffer) - return msg -} - -Connection.prototype.parseK = function (buffer, length) { - var msg = new Message('backendKeyData', length) - msg.processID = this.parseInt32(buffer) - msg.secretKey = this.parseInt32(buffer) - return msg -} - -Connection.prototype.parseC = function (buffer, length) { - var msg = new Message('commandComplete', length) - msg.text = this.parseCString(buffer) - return msg -} - -Connection.prototype.parseZ = function (buffer, length) { - var msg = new Message('readyForQuery', length) - msg.name = 'readyForQuery' - msg.status = this.readString(buffer, 1) - return msg -} - -var ROW_DESCRIPTION = 'rowDescription' -Connection.prototype.parseT = function (buffer, length) { - var msg = new Message(ROW_DESCRIPTION, length) - msg.fieldCount = this.parseInt16(buffer) - var fields = [] - for (var i = 0; i < msg.fieldCount; i++) { - fields.push(this.parseField(buffer)) - } - msg.fields = fields - return msg -} - -var Field = function () { - this.name = null - this.tableID = null - this.columnID = null - this.dataTypeID = null - this.dataTypeSize = null - this.dataTypeModifier = null - this.format = null -} - -var FORMAT_TEXT = 'text' -var FORMAT_BINARY = 'binary' -Connection.prototype.parseField = function (buffer) { - var field = new Field() - field.name = this.parseCString(buffer) - field.tableID = this.parseInt32(buffer) - field.columnID = this.parseInt16(buffer) - field.dataTypeID = this.parseInt32(buffer) - field.dataTypeSize = this.parseInt16(buffer) - field.dataTypeModifier = this.parseInt32(buffer) - if (this.parseInt16(buffer) === TEXT_MODE) { - this._mode = TEXT_MODE - field.format = FORMAT_TEXT - } else { - this._mode = BINARY_MODE - field.format = FORMAT_BINARY - } - return field -} - -var DATA_ROW = 'dataRow' -var DataRowMessage = function (length, fieldCount) { - this.name = DATA_ROW - this.length = length - this.fieldCount = fieldCount - this.fields = [] -} - -// extremely hot-path code -Connection.prototype.parseD = function (buffer, length) { - var fieldCount = this.parseInt16(buffer) - var msg = new DataRowMessage(length, fieldCount) - for (var i = 0; i < fieldCount; i++) { - msg.fields.push(this._readValue(buffer)) - } - return msg -} - -// extremely hot-path code -Connection.prototype._readValue = function (buffer) { - var length = this.parseInt32(buffer) - if (length === -1) return null - if (this._mode === TEXT_MODE) { - return this.readString(buffer, length) - } - return this.readBytes(buffer, length) -} - -// parses error -Connection.prototype.parseE = function (buffer, length, isNotice) { - var fields = {} - var fieldType = this.readString(buffer, 1) - while (fieldType !== '\0') { - fields[fieldType] = this.parseCString(buffer) - fieldType = this.readString(buffer, 1) - } - - // the msg is an Error instance - var msg = isNotice ? { message: fields.M } : new Error(fields.M) - - // for compatibility with Message - msg.name = isNotice ? 'notice' : 'error' - msg.length = length - - msg.severity = fields.S - msg.code = fields.C - msg.detail = fields.D - msg.hint = fields.H - msg.position = fields.P - msg.internalPosition = fields.p - msg.internalQuery = fields.q - msg.where = fields.W - msg.schema = fields.s - msg.table = fields.t - msg.column = fields.c - msg.dataType = fields.d - msg.constraint = fields.n - msg.file = fields.F - msg.line = fields.L - msg.routine = fields.R - return msg -} - -// same thing, different name -Connection.prototype.parseN = function (buffer, length) { - var msg = this.parseE(buffer, length, true) - msg.name = 'notice' - return msg -} - -Connection.prototype.parseA = function (buffer, length) { - var msg = new Message('notification', length) - msg.processId = this.parseInt32(buffer) - msg.channel = this.parseCString(buffer) - msg.payload = this.parseCString(buffer) - return msg -} - -Connection.prototype.parseG = function (buffer, length) { - var msg = new Message('copyInResponse', length) - return this.parseGH(buffer, msg) -} - -Connection.prototype.parseH = function (buffer, length) { - var msg = new Message('copyOutResponse', length) - return this.parseGH(buffer, msg) -} - -Connection.prototype.parseGH = function (buffer, msg) { - var isBinary = buffer[this.offset] !== 0 - this.offset++ - msg.binary = isBinary - var columnCount = this.parseInt16(buffer) - msg.columnTypes = [] - for (var i = 0; i < columnCount; i++) { - msg.columnTypes.push(this.parseInt16(buffer)) - } - return msg -} - -Connection.prototype.parsed = function (buffer, length) { - var msg = new Message('copyData', length) - msg.chunk = this.readBytes(buffer, msg.length - 4) - return msg -} - -Connection.prototype.parseInt32 = function (buffer) { - var value = buffer.readInt32BE(this.offset) - this.offset += 4 - return value -} - -Connection.prototype.parseInt16 = function (buffer) { - var value = buffer.readInt16BE(this.offset) - this.offset += 2 - return value -} - -Connection.prototype.readString = function (buffer, length) { - return buffer.toString(this.encoding, this.offset, (this.offset += length)) -} - -Connection.prototype.readBytes = function (buffer, length) { - return buffer.slice(this.offset, (this.offset += length)) -} - -Connection.prototype.parseCString = function (buffer) { - var start = this.offset - var end = buffer.indexOf(0, start) - this.offset = end + 1 - return buffer.toString(this.encoding, start, end) -} -// end parsing methods module.exports = Connection diff --git a/packages/pg/test/unit/connection/outbound-sending-tests.js b/packages/pg/test/unit/connection/outbound-sending-tests.js deleted file mode 100644 index 8b21de4c..00000000 --- a/packages/pg/test/unit/connection/outbound-sending-tests.js +++ /dev/null @@ -1,205 +0,0 @@ -'use strict' -require(__dirname + '/test-helper') -var Connection = require(__dirname + '/../../../lib/connection') -var stream = new MemoryStream() -var con = new Connection({ - stream: stream, -}) -con._connecting = true - -assert.received = function (stream, buffer) { - assert.lengthIs(stream.packets, 1) - var packet = stream.packets.pop() - assert.equalBuffers(packet, buffer) -} - -test('sends startup message', function () { - con.startup({ - user: 'brian', - database: 'bang', - }) - assert.received( - stream, - new BufferList() - .addInt16(3) - .addInt16(0) - .addCString('user') - .addCString('brian') - .addCString('database') - .addCString('bang') - .addCString('client_encoding') - .addCString("'utf-8'") - .addCString('') - .join(true) - ) -}) - -test('sends password message', function () { - con.password('!') - assert.received(stream, new BufferList().addCString('!').join(true, 'p')) -}) - -test('sends SASLInitialResponseMessage message', function () { - con.sendSASLInitialResponseMessage('mech', 'data') - assert.received(stream, new BufferList().addCString('mech').addInt32(4).addString('data').join(true, 'p')) -}) - -test('sends SCRAMClientFinalMessage message', function () { - con.sendSCRAMClientFinalMessage('data') - assert.received(stream, new BufferList().addString('data').join(true, 'p')) -}) - -test('sends query message', function () { - var txt = 'select * from boom' - con.query(txt) - assert.received(stream, new BufferList().addCString(txt).join(true, 'Q')) -}) - -test('sends parse message', function () { - con.parse({ text: '!' }) - var expected = new BufferList().addCString('').addCString('!').addInt16(0).join(true, 'P') - assert.received(stream, expected) -}) - -test('sends parse message with named query', function () { - con.parse({ - name: 'boom', - text: 'select * from boom', - types: [], - }) - var expected = new BufferList().addCString('boom').addCString('select * from boom').addInt16(0).join(true, 'P') - assert.received(stream, expected) - - test('with multiple parameters', function () { - con.parse({ - name: 'force', - text: 'select * from bang where name = $1', - types: [1, 2, 3, 4], - }) - var expected = new BufferList() - .addCString('force') - .addCString('select * from bang where name = $1') - .addInt16(4) - .addInt32(1) - .addInt32(2) - .addInt32(3) - .addInt32(4) - .join(true, 'P') - assert.received(stream, expected) - }) -}) - -test('bind messages', function () { - test('with no values', function () { - con.bind() - - var expectedBuffer = new BufferList() - .addCString('') - .addCString('') - .addInt16(0) - .addInt16(0) - .addInt16(0) - .join(true, 'B') - assert.received(stream, expectedBuffer) - }) - - test('with named statement, portal, and values', function () { - con.bind({ - portal: 'bang', - statement: 'woo', - values: ['1', 'hi', null, 'zing'], - }) - var expectedBuffer = new BufferList() - .addCString('bang') // portal name - .addCString('woo') // statement name - .addInt16(0) - .addInt16(4) - .addInt32(1) - .add(Buffer.from('1')) - .addInt32(2) - .add(Buffer.from('hi')) - .addInt32(-1) - .addInt32(4) - .add(Buffer.from('zing')) - .addInt16(0) - .join(true, 'B') - assert.received(stream, expectedBuffer) - }) -}) - -test('with named statement, portal, and buffer value', function () { - con.bind({ - portal: 'bang', - statement: 'woo', - values: ['1', 'hi', null, Buffer.from('zing', 'utf8')], - }) - var expectedBuffer = new BufferList() - .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) - .addInt32(1) - .add(Buffer.from('1')) - .addInt32(2) - .add(Buffer.from('hi')) - .addInt32(-1) - .addInt32(4) - .add(Buffer.from('zing', 'UTF-8')) - .addInt16(0) - .join(true, 'B') - assert.received(stream, expectedBuffer) -}) - -test('sends execute message', function () { - test('for unamed portal with no row limit', function () { - con.execute() - var expectedBuffer = new BufferList().addCString('').addInt32(0).join(true, 'E') - assert.received(stream, expectedBuffer) - }) - - test('for named portal with row limit', function () { - con.execute({ - portal: 'my favorite portal', - rows: 100, - }) - var expectedBuffer = new BufferList().addCString('my favorite portal').addInt32(100).join(true, 'E') - assert.received(stream, expectedBuffer) - }) -}) - -test('sends flush command', function () { - con.flush() - var expected = new BufferList().join(true, 'H') - assert.received(stream, expected) -}) - -test('sends sync command', function () { - con.sync() - var expected = new BufferList().join(true, 'S') - assert.received(stream, expected) -}) - -test('sends end command', function () { - con.end() - var expected = Buffer.from([0x58, 0, 0, 0, 4]) - assert.received(stream, expected) - assert.equal(stream.closed, true) -}) - -test('sends describe command', function () { - test('describe statement', function () { - con.describe({ type: 'S', name: 'bang' }) - var expected = new BufferList().addChar('S').addCString('bang').join(true, 'D') - assert.received(stream, expected) - }) - - test('describe unnamed portal', function () { - con.describe({ type: 'P' }) - var expected = new BufferList().addChar('P').addCString('').join(true, 'D') - assert.received(stream, expected) - }) -}) From 08afb12dccacad265e6fc164ee0421285a5c9369 Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Tue, 12 May 2020 16:32:40 -0500 Subject: [PATCH 54/58] Set noDelay to true --- packages/pg/lib/connection.js | 1 + .../unit/client/stream-and-query-error-interaction-tests.js | 1 + packages/pg/test/unit/test-helper.js | 2 ++ 3 files changed, 4 insertions(+) diff --git a/packages/pg/lib/connection.js b/packages/pg/lib/connection.js index bce18348..98b6b5a5 100644 --- a/packages/pg/lib/connection.js +++ b/packages/pg/lib/connection.js @@ -39,6 +39,7 @@ Connection.prototype.connect = function (port, host) { var self = this this._connecting = true + this.stream.setNoDelay(true) this.stream.connect(port, host) this.stream.once('connect', function () { diff --git a/packages/pg/test/unit/client/stream-and-query-error-interaction-tests.js b/packages/pg/test/unit/client/stream-and-query-error-interaction-tests.js index 041af010..3f84ae4a 100644 --- a/packages/pg/test/unit/client/stream-and-query-error-interaction-tests.js +++ b/packages/pg/test/unit/client/stream-and-query-error-interaction-tests.js @@ -5,6 +5,7 @@ var Client = require(__dirname + '/../../../lib/client') test('emits end when not in query', function () { var stream = new (require('events').EventEmitter)() + stream.setNoDelay = () => {} stream.connect = function () { // NOOP } diff --git a/packages/pg/test/unit/test-helper.js b/packages/pg/test/unit/test-helper.js index 918b1418..407dbf24 100644 --- a/packages/pg/test/unit/test-helper.js +++ b/packages/pg/test/unit/test-helper.js @@ -17,6 +17,8 @@ p.connect = function () { // NOOP } +p.setNoDelay = () => {} + p.write = function (packet, cb) { this.packets.push(packet) if (cb) { From 72b5f6d669d4602319e15a0707464ce5e22fb460 Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Tue, 12 May 2020 17:20:17 -0500 Subject: [PATCH 55/58] Add test & fix packed packet parsing error for SASL authentication messages --- packages/pg-protocol/src/inbound-parser.test.ts | 13 +++++++++++++ packages/pg-protocol/src/parser.ts | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/packages/pg-protocol/src/inbound-parser.test.ts b/packages/pg-protocol/src/inbound-parser.test.ts index 8a8785a5..3fcbe410 100644 --- a/packages/pg-protocol/src/inbound-parser.test.ts +++ b/packages/pg-protocol/src/inbound-parser.test.ts @@ -210,8 +210,21 @@ describe('PgPacketStream', function () { testForMessage(md5PasswordBuffer, expectedMD5PasswordMessage) testForMessage(SASLBuffer, expectedSASLMessage) testForMessage(SASLContinueBuffer, expectedSASLContinueMessage) + + // this exercises a found bug in the parser: + // https://github.com/brianc/node-postgres/pull/2210#issuecomment-627626084 + // and adds a test which is deterministic, rather than relying on network packet chunking + const extendedSASLContinueBuffer = Buffer.concat([SASLContinueBuffer, Buffer.from([1, 2, 3, 4])]) + testForMessage(extendedSASLContinueBuffer, expectedSASLContinueMessage) + testForMessage(SASLFinalBuffer, expectedSASLFinalMessage) + // this exercises a found bug in the parser: + // https://github.com/brianc/node-postgres/pull/2210#issuecomment-627626084 + // and adds a test which is deterministic, rather than relying on network packet chunking + const extendedSASLFinalBuffer = Buffer.concat([SASLFinalBuffer, Buffer.from([1, 2, 4, 5])]) + testForMessage(extendedSASLFinalBuffer, expectedSASLFinalMessage) + testForMessage(paramStatusBuffer, expectedParameterStatusMessage) testForMessage(backendKeyDataBuffer, expectedBackendKeyDataMessage) testForMessage(readyForQueryBuffer, expectedReadyForQueryMessage) diff --git a/packages/pg-protocol/src/parser.ts b/packages/pg-protocol/src/parser.ts index 1531f3c0..4044dae1 100644 --- a/packages/pg-protocol/src/parser.ts +++ b/packages/pg-protocol/src/parser.ts @@ -296,11 +296,11 @@ export class Parser { break case 11: // AuthenticationSASLContinue message.name = MessageName.authenticationSASLContinue - message.data = this.reader.string(length - 4) + message.data = this.reader.string(length - 8) break case 12: // AuthenticationSASLFinal message.name = MessageName.authenticationSASLFinal - message.data = this.reader.string(length - 4) + message.data = this.reader.string(length - 8) break default: throw new Error('Unknown authenticationOk message type ' + code) From 9e55a7073b46da9f2ab274f1dd356087e2a7d982 Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Wed, 13 May 2020 09:10:34 -0500 Subject: [PATCH 56/58] Publish - pg-cursor@2.2.0 - pg-protocol@1.2.3 - pg-query-stream@3.1.0 - pg@8.2.0 --- packages/pg-cursor/package.json | 4 ++-- packages/pg-protocol/package.json | 2 +- packages/pg-query-stream/package.json | 6 +++--- packages/pg/package.json | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/pg-cursor/package.json b/packages/pg-cursor/package.json index 14af348e..4309caf9 100644 --- a/packages/pg-cursor/package.json +++ b/packages/pg-cursor/package.json @@ -1,6 +1,6 @@ { "name": "pg-cursor", - "version": "2.1.11", + "version": "2.2.0", "description": "Query cursor extension for node-postgres", "main": "index.js", "directories": { @@ -17,6 +17,6 @@ "license": "MIT", "devDependencies": { "mocha": "^6.2.2", - "pg": "^8.1.0" + "pg": "^8.2.0" } } diff --git a/packages/pg-protocol/package.json b/packages/pg-protocol/package.json index 60bc2027..f3566438 100644 --- a/packages/pg-protocol/package.json +++ b/packages/pg-protocol/package.json @@ -1,6 +1,6 @@ { "name": "pg-protocol", - "version": "1.2.2", + "version": "1.2.3", "description": "The postgres client/server binary protocol, implemented in TypeScript", "main": "dist/index.js", "types": "dist/index.d.ts", diff --git a/packages/pg-query-stream/package.json b/packages/pg-query-stream/package.json index d6c8e96b..775e65c1 100644 --- a/packages/pg-query-stream/package.json +++ b/packages/pg-query-stream/package.json @@ -1,6 +1,6 @@ { "name": "pg-query-stream", - "version": "3.0.8", + "version": "3.1.0", "description": "Postgres query result returned as readable stream", "main": "index.js", "scripts": { @@ -26,12 +26,12 @@ "concat-stream": "~1.0.1", "eslint-plugin-promise": "^3.5.0", "mocha": "^6.2.2", - "pg": "^8.1.0", + "pg": "^8.2.0", "stream-spec": "~0.3.5", "stream-tester": "0.0.5", "through": "~2.3.4" }, "dependencies": { - "pg-cursor": "^2.1.11" + "pg-cursor": "^2.2.0" } } diff --git a/packages/pg/package.json b/packages/pg/package.json index 1fda0dae..81ef4247 100644 --- a/packages/pg/package.json +++ b/packages/pg/package.json @@ -1,6 +1,6 @@ { "name": "pg", - "version": "8.1.0", + "version": "8.2.0", "description": "PostgreSQL client - pure javascript & libpq with the same API", "keywords": [ "database", @@ -23,7 +23,7 @@ "packet-reader": "1.0.0", "pg-connection-string": "^2.2.2", "pg-pool": "^3.2.0", - "pg-protocol": "^1.2.2", + "pg-protocol": "^1.2.3", "pg-types": "^2.1.0", "pgpass": "1.x", "semver": "4.3.2" From 70c8e5f45175bb7ddedf9a34035c5dafbd6c8d50 Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Wed, 13 May 2020 09:17:08 -0500 Subject: [PATCH 57/58] Update changelog --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e92a7b0..274c7487 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,18 @@ For richer information consult the commit log on github with referenced pull req We do not include break-fix version release in this file. +### pg@8.2.0 + +- Switch internal protocol parser & serializer to [pg-protocol](https://github.com/brianc/node-postgres/tree/master/packages/pg-protocol). The change is backwards compatible but results in a significant performance improvement across the board, with some queries as much as 50% faster. This is the first work to land in an on-going performance improvment initiative I'm working on. Stay tuned as things are set to get much faster still! :rocket: + +### pg-cursor@2.2.0 + +- Switch internal protocol parser & serializer to [pg-protocol](https://github.com/brianc/node-postgres/tree/master/packages/pg-protocol). The change is backwards compatible but results in a significant performance improvement across the board, with some queries as much as 50% faster. + +### pg-query-stream@3.1.0 + +- Switch internal protocol parser & serializer to [pg-protocol](https://github.com/brianc/node-postgres/tree/master/packages/pg-protocol). The change is backwards compatible but results in a significant performance improvement across the board, with some queries as much as 50% faster. + ### pg@8.1.0 - Switch to using [monorepo](https://github.com/brianc/node-postgres/tree/master/packages/pg-connection-string) version of `pg-connection-string`. This includes better support for SSL argument parsing from connection strings and ensures continuity of support. From 84044342794414969005bd9e091875367e77b8ec Mon Sep 17 00:00:00 2001 From: "Brian M. Carlson" Date: Wed, 13 May 2020 11:49:37 -0500 Subject: [PATCH 58/58] Upgrade mocha --- packages/pg-connection-string/package.json | 2 +- packages/pg-cursor/package.json | 2 +- packages/pg-pool/package.json | 2 +- packages/pg-pool/test/mocha.opts | 3 - packages/pg-protocol/package.json | 2 +- packages/pg-query-stream/package.json | 2 +- packages/pg-query-stream/test/mocha.opts | 1 - yarn.lock | 347 +++++++++------------ 8 files changed, 147 insertions(+), 214 deletions(-) delete mode 100644 packages/pg-pool/test/mocha.opts delete mode 100644 packages/pg-query-stream/test/mocha.opts diff --git a/packages/pg-connection-string/package.json b/packages/pg-connection-string/package.json index cdbbf527..a2081e5e 100644 --- a/packages/pg-connection-string/package.json +++ b/packages/pg-connection-string/package.json @@ -29,7 +29,7 @@ "chai": "^4.1.1", "coveralls": "^3.0.4", "istanbul": "^0.4.5", - "mocha": "^3.5.0" + "mocha": "^7.1.2" }, "files": [ "index.js", diff --git a/packages/pg-cursor/package.json b/packages/pg-cursor/package.json index 4309caf9..ac580c30 100644 --- a/packages/pg-cursor/package.json +++ b/packages/pg-cursor/package.json @@ -16,7 +16,7 @@ "author": "Brian M. Carlson", "license": "MIT", "devDependencies": { - "mocha": "^6.2.2", + "mocha": "^7.1.2", "pg": "^8.2.0" } } diff --git a/packages/pg-pool/package.json b/packages/pg-pool/package.json index 176a3e41..0c4c93a8 100644 --- a/packages/pg-pool/package.json +++ b/packages/pg-pool/package.json @@ -30,7 +30,7 @@ "co": "4.6.0", "expect.js": "0.3.1", "lodash": "^4.17.11", - "mocha": "^5.2.0", + "mocha": "^7.1.2", "pg-cursor": "^1.3.0" }, "peerDependencies": { diff --git a/packages/pg-pool/test/mocha.opts b/packages/pg-pool/test/mocha.opts deleted file mode 100644 index eb0ba600..00000000 --- a/packages/pg-pool/test/mocha.opts +++ /dev/null @@ -1,3 +0,0 @@ ---require test/setup.js ---bail ---timeout 10000 diff --git a/packages/pg-protocol/package.json b/packages/pg-protocol/package.json index f3566438..30cfe409 100644 --- a/packages/pg-protocol/package.json +++ b/packages/pg-protocol/package.json @@ -11,7 +11,7 @@ "@types/node": "^12.12.21", "chai": "^4.2.0", "chunky": "^0.0.0", - "mocha": "^6.2.2", + "mocha": "^7.1.2", "ts-node": "^8.5.4", "typescript": "^3.7.3" }, diff --git a/packages/pg-query-stream/package.json b/packages/pg-query-stream/package.json index 775e65c1..0d454b1b 100644 --- a/packages/pg-query-stream/package.json +++ b/packages/pg-query-stream/package.json @@ -25,7 +25,7 @@ "JSONStream": "~0.7.1", "concat-stream": "~1.0.1", "eslint-plugin-promise": "^3.5.0", - "mocha": "^6.2.2", + "mocha": "^7.1.2", "pg": "^8.2.0", "stream-spec": "~0.3.5", "stream-tester": "0.0.5", diff --git a/packages/pg-query-stream/test/mocha.opts b/packages/pg-query-stream/test/mocha.opts deleted file mode 100644 index 8640eeef..00000000 --- a/packages/pg-query-stream/test/mocha.opts +++ /dev/null @@ -1 +0,0 @@ ---bail diff --git a/yarn.lock b/yarn.lock index a1f07fa3..7bfd5878 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1048,6 +1048,14 @@ any-promise@^1.0.0: resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -1241,6 +1249,11 @@ before-after-hook@^2.0.0: resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635" integrity sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A== +binary-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.0.0.tgz#23c0df14f6a88077f5f986c0d167ec03c3d5537c" + integrity sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow== + bluebird@3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.4.1.tgz#b731ddf48e2dd3bedac2e75e1215a11bcb91fa07" @@ -1288,10 +1301,12 @@ braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" -browser-stdout@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" - integrity sha1-81HTKWnTL6XXpVZxVCY9korjvR8= +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" browser-stdout@1.3.1: version "1.3.1" @@ -1442,7 +1457,7 @@ chai@^4.1.1, chai@^4.2.0: pathval "^1.1.0" type-detect "^4.0.5" -chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.2: +chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1461,6 +1476,21 @@ check-error@^1.0.2: resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= +chokidar@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6" + integrity sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.2.0" + optionalDependencies: + fsevents "~2.1.1" + chownr@^1.1.1, chownr@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" @@ -1573,18 +1603,6 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: dependencies: delayed-stream "~1.0.0" -commander@2.15.1: - version "2.15.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" - integrity sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag== - -commander@2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" - integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q= - dependencies: - graceful-readlink ">= 1.0.0" - commander@~2.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -1821,13 +1839,6 @@ dateformat@^3.0.0: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== -debug@2.6.8: - version "2.6.8" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" - integrity sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw= - dependencies: - ms "2.0.0" - debug@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" @@ -1960,11 +1971,6 @@ dezalgo@^1.0.0: asap "^2.0.0" wrappy "1" -diff@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" - integrity sha1-yc45Okt8vQsFinJck98pkCeGj/k= - diff@3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -2436,6 +2442,13 @@ fill-range@^4.0.0: repeat-string "^1.6.1" to-regex-range "^2.1.0" +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + find-up@3.0.0, find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -2561,6 +2574,11 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= +fsevents@~2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -2709,35 +2727,18 @@ glob-parent@^5.0.0: dependencies: is-glob "^4.0.1" +glob-parent@~5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== + dependencies: + is-glob "^4.0.1" + glob-to-regexp@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= -glob@7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" - integrity sha1-gFIR3wT6rxxjo2ADBs31reULLsg= - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.2" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" - integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - glob@7.1.3: version "7.1.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" @@ -2799,21 +2800,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== -"graceful-readlink@>= 1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" - integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= - growl@1.10.5: version "1.10.5" resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== -growl@1.9.2: - version "1.9.2" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" - integrity sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8= - handlebars@^4.0.1: version "4.7.6" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.6.tgz#d4c05c1baf90e9945f77aa68a7a219aa4a7df74e" @@ -2908,11 +2899,6 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" -he@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" - integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0= - he@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" @@ -3129,6 +3115,13 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -3241,7 +3234,7 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" -is-glob@^4.0.0, is-glob@^4.0.1: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== @@ -3255,6 +3248,11 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + is-obj@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-1.0.1.tgz#3e4729ac1f5fde025cd7d83a896dab9f4f67db0f" @@ -3427,11 +3425,6 @@ json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json3@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" - integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE= - jsonfile@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" @@ -3567,34 +3560,6 @@ locate-path@^3.0.0: p-locate "^3.0.0" path-exists "^3.0.0" -lodash._baseassign@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" - integrity sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4= - dependencies: - lodash._basecopy "^3.0.0" - lodash.keys "^3.0.0" - -lodash._basecopy@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" - integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY= - -lodash._basecreate@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" - integrity sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE= - -lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= - -lodash._isiterateecall@^3.0.0: - version "3.0.9" - resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" - integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw= - lodash._reinterpolate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" @@ -3605,44 +3570,16 @@ lodash.clonedeep@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= -lodash.create@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" - integrity sha1-1/KEnw29p+BGgruM1yqwIkYd6+c= - dependencies: - lodash._baseassign "^3.0.0" - lodash._basecreate "^3.0.0" - lodash._isiterateecall "^3.0.0" - lodash.get@^4.4.2: version "4.4.2" resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk= -lodash.isarguments@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" - integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo= - -lodash.isarray@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" - integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U= - lodash.ismatch@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" integrity sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc= -lodash.keys@^3.0.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" - integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo= - dependencies: - lodash._getnative "^3.0.0" - lodash.isarguments "^3.0.0" - lodash.isarray "^3.0.0" - lodash.set@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" @@ -3683,12 +3620,12 @@ log-driver@^1.2.7: resolved "https://registry.yarnpkg.com/log-driver/-/log-driver-1.2.7.tgz#63b95021f0702fedfa2c9bb0a24e7797d71871d8" integrity sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg== -log-symbols@2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" - integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== +log-symbols@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" + integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== dependencies: - chalk "^2.0.1" + chalk "^2.4.2" loud-rejection@^1.0.0: version "1.6.0" @@ -3866,7 +3803,7 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4: +"minimatch@2 || 3", minimatch@3.0.4, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -3947,62 +3884,28 @@ mkdirp-promise@^5.0.1: dependencies: mkdirp "*" -mkdirp@*, mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1: +mkdirp@*, mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" -mkdirp@0.5.x: +mkdirp@0.5.5, mkdirp@0.5.x: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" -mocha@^3.5.0: - version "3.5.3" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.5.3.tgz#1e0480fe36d2da5858d1eb6acc38418b26eaa20d" - integrity sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg== - dependencies: - browser-stdout "1.3.0" - commander "2.9.0" - debug "2.6.8" - diff "3.2.0" - escape-string-regexp "1.0.5" - glob "7.1.1" - growl "1.9.2" - he "1.1.1" - json3 "3.3.2" - lodash.create "3.1.1" - mkdirp "0.5.1" - supports-color "3.1.2" - -mocha@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.2.0.tgz#6d8ae508f59167f940f2b5b3c4a612ae50c90ae6" - integrity sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ== - dependencies: - browser-stdout "1.3.1" - commander "2.15.1" - debug "3.1.0" - diff "3.5.0" - escape-string-regexp "1.0.5" - glob "7.1.2" - growl "1.10.5" - he "1.1.1" - minimatch "3.0.4" - mkdirp "0.5.1" - supports-color "5.4.0" - -mocha@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-6.2.2.tgz#5d8987e28940caf8957a7d7664b910dc5b2fea20" - integrity sha512-FgDS9Re79yU1xz5d+C4rv1G7QagNGHZ+iXF81hO8zY35YZZcLEsJVfFolfsqKFWunATEvNzMK0r/CwWd/szO9A== +mocha@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.1.2.tgz#8e40d198acf91a52ace122cd7599c9ab857b29e6" + integrity sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA== dependencies: ansi-colors "3.2.3" browser-stdout "1.3.1" + chokidar "3.3.0" debug "3.2.6" diff "3.5.0" escape-string-regexp "1.0.5" @@ -4011,18 +3914,18 @@ mocha@^6.2.2: growl "1.10.5" he "1.2.0" js-yaml "3.13.1" - log-symbols "2.2.0" + log-symbols "3.0.0" minimatch "3.0.4" - mkdirp "0.5.1" + mkdirp "0.5.5" ms "2.1.1" - node-environment-flags "1.0.5" + node-environment-flags "1.0.6" object.assign "4.1.0" strip-json-comments "2.0.1" supports-color "6.0.0" which "1.3.1" wide-align "1.1.3" - yargs "13.3.0" - yargs-parser "13.1.1" + yargs "13.3.2" + yargs-parser "13.1.2" yargs-unparser "1.6.0" modify-values@^1.0.0: @@ -4118,10 +4021,10 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -node-environment-flags@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.5.tgz#fa930275f5bf5dae188d6192b24b4c8bbac3d76a" - integrity sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ== +node-environment-flags@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088" + integrity sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw== dependencies: object.getownpropertydescriptors "^2.0.3" semver "^5.7.0" @@ -4182,6 +4085,11 @@ normalize-package-data@^2.0.0, normalize-package-data@^2.3.0, normalize-package- semver "2 || 3 || 4 || 5" validate-npm-package-license "^3.0.1" +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + normalize-url@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" @@ -4629,6 +4537,11 @@ pgpass@1.x: dependencies: split "^1.0.0" +picomatch@^2.0.4: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== + pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -4915,6 +4828,13 @@ readdir-scoped-modules@^1.0.0: graceful-fs "^4.1.2" once "^1.3.0" +readdirp@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.2.0.tgz#c30c33352b12c96dfb4b895421a49fd5a9593839" + integrity sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ== + dependencies: + picomatch "^2.0.4" + redent@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" @@ -5576,20 +5496,6 @@ strong-log-transformer@^2.0.0: minimist "^1.2.0" through "^2.3.4" -supports-color@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" - integrity sha1-cqJiiU2dQIuVbKBf83su2KbiotU= - dependencies: - has-flag "^1.0.0" - -supports-color@5.4.0: - version "5.4.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" - integrity sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w== - dependencies: - has-flag "^3.0.0" - supports-color@6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" @@ -5722,6 +5628,13 @@ to-regex-range@^2.1.0: is-number "^3.0.0" repeat-string "^1.6.1" +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + to-regex@^3.0.1, to-regex@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" @@ -6125,10 +6038,10 @@ yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yargs-parser@13.1.1, yargs-parser@^13.1.1: - version "13.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" - integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== +yargs-parser@13.1.2, yargs-parser@^13.1.2: + version "13.1.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" + integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== dependencies: camelcase "^5.0.0" decamelize "^1.2.0" @@ -6140,6 +6053,14 @@ yargs-parser@^10.0.0: dependencies: camelcase "^4.1.0" +yargs-parser@^13.1.1: + version "13.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" + integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + yargs-parser@^15.0.0: version "15.0.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.0.tgz#cdd7a97490ec836195f59f3f4dbe5ea9e8f75f08" @@ -6157,7 +6078,23 @@ yargs-unparser@1.6.0: lodash "^4.17.15" yargs "^13.3.0" -yargs@13.3.0, yargs@^13.3.0: +yargs@13.3.2: + version "13.3.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" + integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.2" + +yargs@^13.3.0: version "13.3.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==