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/.travis.yml b/.travis.yml index 0518579d..7987f761 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,27 +7,25 @@ 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: # 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,28 +34,31 @@ 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: - 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/CHANGELOG.md b/CHANGELOG.md index ab356e0f..274c7487 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,27 @@ 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. +- 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. @@ -12,8 +33,8 @@ We do not include break-fix version release in this file. #### 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. +- 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. @@ -27,16 +48,17 @@ We do not include break-fix version release in this file. ### 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. +- [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. + +- 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 @@ -161,7 +183,7 @@ Promise support & other goodness lives now in [pg-pool](https://github.com/brian - Included support for tcp keep alive. Enable it as follows: ```js -var client = new Client({ keepAlive: true }); +var client = new Client({ keepAlive: true }) ``` This should help with backends incorrectly considering idle clients to be dead and prematurely disconnecting them. @@ -173,12 +195,12 @@ This should help with backends incorrectly considering idle clients to be dead a 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(); -}); +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 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 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 diff --git a/package.json b/package.json index dd32e85b..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": "!([[ -e node_modules/.bin/prettier ]]) || eslint '*/**/*.{js,ts,tsx}'" + "lint": "if [ -x ./node_modules/.bin/prettier ]; then eslint '*/**/*.{js,ts,tsx}'; fi;" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^2.27.0", diff --git a/packages/pg-connection-string/.coveralls.yml b/packages/pg-connection-string/.coveralls.yml new file mode 100644 index 00000000..0709f6e0 --- /dev/null +++ b/packages/pg-connection-string/.coveralls.yml @@ -0,0 +1,2 @@ +service_name: travis-pro +repo_token: 5F6dODinz9L9uFR6HatKmtsYDoV1A5S2N diff --git a/packages/pg-connection-string/.gitignore b/packages/pg-connection-string/.gitignore new file mode 100644 index 00000000..f28f01f7 --- /dev/null +++ b/packages/pg-connection-string/.gitignore @@ -0,0 +1,26 @@ +# 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 +package-lock.json \ No newline at end of file diff --git a/packages/pg-connection-string/.travis.yml b/packages/pg-connection-string/.travis.yml new file mode 100644 index 00000000..daf50ba6 --- /dev/null +++ b/packages/pg-connection-string/.travis.yml @@ -0,0 +1,6 @@ +language: node_js +node_js: + - '0.10' + - '6.9' + - '8' +after_success: 'npm run coveralls' diff --git a/packages/pg-connection-string/LICENSE b/packages/pg-connection-string/LICENSE new file mode 100644 index 00000000..b068a6cb --- /dev/null +++ b/packages/pg-connection-string/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/packages/pg-connection-string/README.md b/packages/pg-connection-string/README.md new file mode 100644 index 00000000..d5b45ab9 --- /dev/null +++ b/packages/pg-connection-string/README.md @@ -0,0 +1,72 @@ +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/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) +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/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. diff --git a/packages/pg-connection-string/index.d.ts b/packages/pg-connection-string/index.d.ts new file mode 100644 index 00000000..b1b7abd9 --- /dev/null +++ b/packages/pg-connection-string/index.d.ts @@ -0,0 +1,14 @@ +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 + + application_name?: string + fallback_application_name?: string +} diff --git a/packages/pg-connection-string/index.js b/packages/pg-connection-string/index.js new file mode 100644 index 00000000..65951c37 --- /dev/null +++ b/packages/pg-connection-string/index.js @@ -0,0 +1,89 @@ +'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) +//MIT License + +//parses a connection string +function parse(str) { + //unix socket + 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 + for (var k in config) { + if (Array.isArray(config[k])) { + config[k] = config[k][config[k].length - 1] + } + } + + 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 + } + if (!config.host) { + // Only set the host if there is no equivalent query param. + 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 && /^%2f/i.test(pathname)) { + 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 + } + config.database = pathname && decodeURI(pathname) + + if (config.ssl === 'true' || config.ssl === '1') { + config.ssl = true + } + + if (config.ssl === '0') { + config.ssl = false + } + + 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 +} + +module.exports = parse + +parse.parse = parse diff --git a/packages/pg-connection-string/package.json b/packages/pg-connection-string/package.json new file mode 100644 index 00000000..a2081e5e --- /dev/null +++ b/packages/pg-connection-string/package.json @@ -0,0 +1,38 @@ +{ + "name": "pg-connection-string", + "version": "2.2.2", + "description": "Functions for dealing with a PostgresSQL connection string", + "main": "./index.js", + "types": "./index.d.ts", + "scripts": { + "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", + "url": "git://github.com/brianc/node-postgres.git" + }, + "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", + "devDependencies": { + "chai": "^4.1.1", + "coveralls": "^3.0.4", + "istanbul": "^0.4.5", + "mocha": "^7.1.2" + }, + "files": [ + "index.js", + "index.d.ts" + ] +} diff --git a/packages/pg-connection-string/test/example.ca b/packages/pg-connection-string/test/example.ca new file mode 100644 index 00000000..0a6dcf40 --- /dev/null +++ b/packages/pg-connection-string/test/example.ca @@ -0,0 +1 @@ +example ca diff --git a/packages/pg-connection-string/test/example.cert b/packages/pg-connection-string/test/example.cert new file mode 100644 index 00000000..7693b3fe --- /dev/null +++ b/packages/pg-connection-string/test/example.cert @@ -0,0 +1 @@ +example cert diff --git a/packages/pg-connection-string/test/example.key b/packages/pg-connection-string/test/example.key new file mode 100644 index 00000000..1aef9935 --- /dev/null +++ b/packages/pg-connection-string/test/example.key @@ -0,0 +1 @@ +example key diff --git a/packages/pg-connection-string/test/parse.js b/packages/pg-connection-string/test/parse.js new file mode 100644 index 00000000..957f0644 --- /dev/null +++ b/packages/pg-connection-string/test/parse.js @@ -0,0 +1,274 @@ +'use strict' + +var chai = require('chai') +var expect = chai.expect +chai.should() + +var parse = require('../').parse + +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('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', + 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 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('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) + 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('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) + }) + + 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') + 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') + }) +}) diff --git a/packages/pg-cursor/package.json b/packages/pg-cursor/package.json index 3ce12975..ac580c30 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.2.0", "description": "Query cursor extension for node-postgres", "main": "index.js", "directories": { @@ -11,12 +11,12 @@ }, "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", "devDependencies": { - "mocha": "^6.2.2", - "pg": "^8.0.2" + "mocha": "^7.1.2", + "pg": "^8.2.0" } } diff --git a/packages/pg-pool/package.json b/packages/pg-pool/package.json index 4eb998ed..0c4c93a8 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.2.0", "description": "Connection pool for node-postgres", "main": "index.js", "directories": { @@ -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", @@ -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 476941dd..30cfe409 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.3", "description": "The postgres client/server binary protocol, implemented in TypeScript", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -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-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/outbound-serializer.test.ts b/packages/pg-protocol/src/outbound-serializer.test.ts index 4d2457e1..06f20cf9 100644 --- a/packages/pg-protocol/src/outbound-serializer.test.ts +++ b/packages/pg-protocol/src/outbound-serializer.test.ts @@ -18,7 +18,7 @@ describe('serializer', () => { .addCString('database') .addCString('bang') .addCString('client_encoding') - .addCString("'utf-8'") + .addCString('UTF8') .addCString('') .join(true) ) 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) diff --git a/packages/pg-query-stream/package.json b/packages/pg-query-stream/package.json index 05a3f970..0d454b1b 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.1.0", "description": "Postgres query result returned as readable stream", "main": "index.js", "scripts": { @@ -25,13 +25,13 @@ "JSONStream": "~0.7.1", "concat-stream": "~1.0.1", "eslint-plugin-promise": "^3.5.0", - "mocha": "^6.2.2", - "pg": "^8.0.2", + "mocha": "^7.1.2", + "pg": "^8.2.0", "stream-spec": "~0.3.5", "stream-tester": "0.0.5", "through": "~2.3.4" }, "dependencies": { - "pg-cursor": "^2.1.9" + "pg-cursor": "^2.2.0" } } 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/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. 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 6344b417..00000000 --- a/packages/pg/lib/connection-fast.js +++ /dev/null @@ -1,216 +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') - -// eslint-disable-next-line -const { parse, serialize } = require('../../pg-protocol/dist') - -// TODO(bmc) support binary mode here -// var BINARY_MODE = 1 -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-parameters.js b/packages/pg/lib/connection-parameters.js index b34e0df5..e1d83892 100644 --- a/packages/pg/lib/connection-parameters.js +++ b/packages/pg/lib/connection-parameters.js @@ -25,7 +25,7 @@ var val = function (key, config, envVar) { return config[key] || envVar || defaults[key] } -var useSsl = function () { +var readSSLConfigFromEnvironment = function () { switch (process.env.PGSSLMODE) { case 'disable': return false @@ -34,6 +34,8 @@ var useSsl = function () { case 'verify-ca': case 'verify-full': return true + case 'no-verify': + return { rejectUnauthorized: false } } return defaults.ssl } @@ -68,7 +70,14 @@ var ConnectionParameters = function (config) { }) this.binary = val('binary', config) - this.ssl = typeof config.ssl === 'undefined' ? useSsl() : 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/lib/connection.js b/packages/pg/lib/connection.js index 76125013..98b6b5a5 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') { @@ -51,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 () { @@ -101,576 +90,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('UTF8') - - 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/package.json b/packages/pg/package.json index 5386ec2e..81ef4247 100644 --- a/packages/pg/package.json +++ b/packages/pg/package.json @@ -1,6 +1,6 @@ { "name": "pg", - "version": "8.0.2", + "version": "8.2.0", "description": "PostgreSQL client - pure javascript & libpq with the same API", "keywords": [ "database", @@ -21,9 +21,9 @@ "dependencies": { "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-connection-string": "^2.2.2", + "pg-pool": "^3.2.0", + "pg-protocol": "^1.2.3", "pg-types": "^2.1.0", "pgpass": "1.x", "semver": "4.3.2" 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') }) -*/ diff --git a/packages/pg/test/unit/client/configuration-tests.js b/packages/pg/test/unit/client/configuration-tests.js index e6cbc0dc..e604513b 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 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/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) { 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 d6b03964..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('UTF8') - .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) - }) -}) 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) { diff --git a/yarn.lock b/yarn.lock index f309fe97..7bfd5878 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" @@ -1038,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" @@ -1098,14 +1116,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 +1133,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" @@ -1182,6 +1184,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" @@ -1242,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" @@ -1289,6 +1301,13 @@ braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" +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" resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" @@ -1426,7 +1445,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== @@ -1438,7 +1457,7 @@ 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== @@ -1457,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" @@ -1569,11 +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.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -1637,11 +1666,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" @@ -1757,6 +1781,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" @@ -1818,7 +1853,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 +1988,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 +2073,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== @@ -2089,6 +2116,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" @@ -2096,35 +2135,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 +2143,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 +2155,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 +2167,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 +2175,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 +2194,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" @@ -2319,6 +2246,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" @@ -2338,6 +2270,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" @@ -2505,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" @@ -2520,7 +2464,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= @@ -2630,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" @@ -2778,23 +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.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" @@ -2807,6 +2751,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" @@ -2850,6 +2805,18 @@ growl@1.10.5: resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== +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" @@ -2866,7 +2833,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== @@ -2874,6 +2841,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" @@ -2927,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" @@ -3148,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" @@ -3260,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== @@ -3274,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" @@ -3351,7 +3330,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= @@ -3383,12 +3362,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== @@ -3477,6 +3476,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" @@ -3519,16 +3523,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" @@ -3621,12 +3615,17 @@ 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-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-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@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" @@ -3804,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@3.0.4, 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== @@ -3829,6 +3828,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" @@ -3880,37 +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" -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== +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: - 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" + minimist "^1.2.5" -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" @@ -3919,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: @@ -4026,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" @@ -4065,6 +4060,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" @@ -4083,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" @@ -4224,22 +4231,12 @@ 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" 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= @@ -4268,7 +4265,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== @@ -4490,13 +4487,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" @@ -4514,11 +4504,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" @@ -4552,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" @@ -4579,13 +4569,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" @@ -4689,6 +4672,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" @@ -4719,7 +4707,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== @@ -4775,14 +4763,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 +4780,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" @@ -4857,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" @@ -4941,6 +4919,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" @@ -4973,7 +4977,12 @@ 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.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" integrity sha512-uviWSi5N67j3t3UKFxej1loCH0VZn5XuqdNxoLShPcYPw6cUZn74K1VRj+9myynRX03bxIBEkwlkob/ujLsJVw== @@ -5228,6 +5237,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" @@ -5480,13 +5496,6 @@ strong-log-transformer@^2.0.0: minimist "^1.2.0" through "^2.3.4" -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" @@ -5494,6 +5503,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" @@ -5612,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" @@ -5635,6 +5658,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" @@ -5894,7 +5925,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== @@ -5920,6 +5951,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" @@ -6002,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" @@ -6017,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" @@ -6034,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==