From 83a187d0793cbd68aba2b131ff95be60814daa8e Mon Sep 17 00:00:00 2001 From: marco3479 Date: Tue, 1 Aug 2023 14:52:37 -0400 Subject: [PATCH 01/11] Updated `package.json` minimally --- package.json | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 7a397c1..ebd4788 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "node-nuodb", + "name": "nuodb-client", "author": "NuoDB, Inc.", "description": "The official NuoDB driver for Node.js. Provides a high-level SQL API on top of the NuoDB Node.js Addon.", "license": "Apache-2.0", @@ -8,14 +8,19 @@ "keywords": [ "nuodb", "driver", - "official" + "official", + "sql", + "nuosql", + "client" ], + "homepage": "https://github.com/nuodb/node-nuodb", "repository": { "type": "git", "url": "git://github.com/nuodb/node-nuodb.git" }, "bugs": { - "url": "git://github.com/nuodb/node-nuodb/issues" + "url": "git://github.com/nuodb/node-nuodb/issues", + "email": "support@nuodb.zendesk.com" }, "engines": { "node": ">=8" From 9ffae272dd290d53e57ef66a0ffc8d764c3f8f48 Mon Sep 17 00:00:00 2001 From: marco3479 Date: Wed, 2 Aug 2023 00:18:21 -0400 Subject: [PATCH 02/11] Added initial draft for README.md --- README2.md | 288 +++++ doc/README.md | 2 - lib/nuodb_nodejs.log | 0 package-lock.json | 2532 +++++++----------------------------------- 4 files changed, 701 insertions(+), 2121 deletions(-) create mode 100644 README2.md create mode 100644 lib/nuodb_nodejs.log diff --git a/README2.md b/README2.md new file mode 100644 index 0000000..6957725 --- /dev/null +++ b/README2.md @@ -0,0 +1,288 @@ +# **node-nuodb** - Node.js NAN C++ NuoDB Driver + + +The `node-nuodb` add-on for **Node.js** powers high performance **NuoDB** database applications. Use `node-nuodb` to connect **Node.js** to a **NuoDB** database. It supports basic features of the **NuoDB** database and **NuoDB C++** client. + + +## Dependencies + +- Node 16.13.2 + + +## Installation + +If you have NuoDB installed locally, skip to step 4. + +1. Download the nuodb client package. + The client package releases can be found here: https://github.com/nuodb/nuodb-client/releases + +2. Extract the client package. + + `tar -xzf nuodb-client-version.lin64.tar.gz` + +3. Set the `NUODB_CLIENT_PACKAGE` environment variable. + + `export NUODB_CLIENT_PACKAGE=/path/to/nuodb-client-version.lin64` + +4. Install the driver. + + `npm i node-nuodb` + +5. Ensure the driver is working as intended. Note this assumes NuoDB database has `"dba"` user and `"dba"` as password. + + `npm test` + +6. Import the driver into your node.js project. + + `import { Driver } from "node-nuodb";` + + +## Single connection + +The usage of a single connection entails initializing the driver, connecting to a **NuoDB** database using a configuration object with connection properties, executing desired `SQL`, getting the rows from the result set, and finally closing the connection. + +```js +import { Driver } from "node-nuodb"; + +const config = { + database: `test`, + password: "dba", + user: "dba", + port: "48004", + schema: "USER" +}; + +async function run() { + const driver = new Driver(); + const connection = await driver.connect(config); + const results = await connection.execute("SELECT * FROM SYSTEM.NODES;"); + const rows = await results.getRows(); + await connection.close(); + return rows +} + +run() +``` + +### Connect + +To connect to a **NuoDB** database you must provide a configuration object which includes the connection properties. Find the available connection properties in the [NuoDB docs](https://doc.nuodb.com/nuodb/latest/reference-information/connection-properties/#nav-container-toggle). Provide each of the connection property values as a `string`. + +```js +const config = { + database: `test`, + password: "dba", + user: "dba", + port: "48004", + schema: "USER" +}; +``` +With the configuration object defined, you can now `connect()` to the desired **NuoDB** database. + +```js +const driver = new Driver(); +const connection = await driver.connect(config); +``` + +### Execute SQL +With a connection obtained, `execute()` a `SQL` statement against the database. If the default schema was defined in the configuration map, it is not required to specify which schema the statement is intended to target. `getRows()` to obtain the rows from the result set. + +```js +const results = await connection.execute("SELECT * FROM SYSTEM.NODES;"); +const rows = await results.getRows(); +``` + +### Close Connection + +Finally, `close()` the database connection. + +```js +await connection.close(); +``` + +> **NOTE** +> +> Since the methods are `async`, you should `try catch` them, and may use `await` or `then` as desired. + +### Connection Properties + +Key | Value +---|--- +allowSRPFallback=[ true \| false ] | Allows the driver to fall back to SRP if the TLS connection fails (when used in combination with trustStore ). Required (set to true) during rolling upgrade of the security protocol. +ciphers=cipherlist | Enables the client to provide one or more appropriate ciphers for encrypting the network connection to the database. If this property is not specified the default ciphers AES-256-CTR and RC4 are enabled. The server chooses a preferred cipher from this list. If no matching cipher is found, the connection will be refused. The cipherlist is comma-separated and cipher names are case-sensitive and must be provided exactly as shown. The full list of available ciphers are AES-256-CTR, RC4, and None. +clientInfo=info | Arbitrary information about the connecting client. This is available in the CLIENTINFO column of the SYSTEM.CONNECTIONS and SYSTEM.LOCALCONNECTIONS system tables. +clientProcessID=id | The process ID (pid) of the connecting client. The client may set this property only if not already set by the driver. The .NET and Python drivers set this for the client. The client setting of this property does not overrides the driver setting of this property. The clientProcessId is then available in the CLIENTPROCESSID column of the SYSTEM.CONNECTIONS and SYSTEM.LOCALCONNECTIONS system tables. +direct=[ true \| false ] | Connect directly to TE(s) rather than via the AP(s). If not specified, direct defaults to false and connections are made via the AP(s) specified in the connection URL. When direct=true, the client connection is made directly with a TE. The hosts and port numbers in the connection URL are assumed to specify the hosts and port numbers of TE processes. The use of the direct connection property is supported for nuosql and the JDBC, C, C++, and Go drivers. When using nuosql, it supports an equivalent --direct option. Where possible, direct connection should be made using the load-balancing capability of the APs. This connection property is useful when connecting external SQL applications directly to TEs that are running on a different network - such as in the Cloud, on Kubernetes clusters, and in other containerized deployments (such as Docker) or via SSH tunneling. For more details, see Direct TE Connections. Although it is for JDBC, the basic principles apply to all drivers supporting direct. +idle-timeout=number | The maximum time (in seconds) which indicates how long idle connections are left open. Although the IDLE_CONNECTION_TIMEOUT system property is a global setting for timing out idle connections, you can use this connection property to override the system property on a per connection basis. By default, idle-timeout is set to -1, meaning that the global setting is used. If you set a value greater than 0, this property overrides any value set for IDLE_CONNECTION_TIMEOUT. You may also set a value of 0 to specifically disable this property for the connection. Any time a client connection is terminated for being idle for too long, a message will be logged under the net category. For more information on IDLE_CONNECTION_TIMEOUT, see SQL System Properties. +isolation=level | The default transaction isolation level for the connection to use. Isolation levels supported are consistent_read and read_committed. Note that these values are case sensitive. For more information, see CONSISTENT READ and READ COMMITTED. +keepAlive=[ true \| false ] | Allows enabling of TCP KeepAlive on the connection from client to Transaction Engine. If not specified, keepAlive defaults to false. When keepAlive=true, the driver enables TCP KeepAlive on the socket that it opens to the Transaction Engine. +LBPolicy=valueA | From the client application, this property allows selective load balancing across Transaction Engines. For information on using LBPolicy, see Load Balancer Policies. +LBQuery=\(\) | From the client application, this property allows selective load balancing across Transaction Engines. For information on using LBQuery, see Load Balancer Policies. +lock-wait-timeout=sec | Configures lock wait time (in seconds) when establishing a new connection. For more information, see About the NuoDB SQL Configuration File. The default is equal to the system property DEFAULT_LOCK_WAIT_TIMEOUT. For more information, see SQL System Properties. +memory-limit-bytes=size | The memory limit (per connection) in bytes for all blocking SQL engine operations: Hash-grouping, sorting, sorting via priority queue for limit, distinct (via hash-grouping), union, listagg, table functions, and stored procedures returning result set(s) that accumulate data - in main memory. To run statements with a memory limit different from the system-wide limit, start a new connection with this connection property set to the per-connection limit. If you do not define a value for memory-limit-bytes, the value set for the DEFAULT_CONNECTION_MEMORY_LIMIT system property is the default setting used. +password=pwd | The password for the user account used to connect to the database. +PreferInternalAddress=[ true \| false ] | Use internal address and port for TE, as specified by the external-address and external-port process labels. Default is false (disabled). For a detailed explanation, see Controlling Connectivity, a special case of using Load Balancer Policies with labels. +rollbackMode=[ procedure \| transaction \| off ] | Controls the behavior of transactions executed inside a stored procedure. The default is off. See About Implicit and Explicit Transactions. +schema=name | The default schema that the connection should use when objects (such as tables and views) are not fully qualified. +TimeZone=timezone | The default time zone for the connection to use (this is also known as the session time zone). If not specified, the application’s default time zone is used. +user=name | The user name for connecting to the database. +verifyHostname=[ true \| false ] | Verifies the DN name of the SSL server against the name presented on the certificate. The default is true. + +## Connection Pool + +The NuoDB Node.js driver comes with a built in connection pool available. + + +### Usage + +```js +const myPool = new Pool({ + minAvailable: , + connectionConfig: , + maxAge: , + checkTime: , + maxLimit: , + connectionRetryLimit: , + id: , + skipCheckLivelinessOnRelease: false|true, + livelinessCheck: query| +}); +await Pool.init() +const newConnection = await Pool.requestConnection() +await Pool.releaseConnection() +await Pool.closePool() + +``` +```js +const myPool = new Pool({ + minAvailable: , + connectionConfig: , + maxAge: , + checkTime: , + maxLimit: , + connectionRetryLimit: , + id: , + skipCheckLivelinessOnRelease: false|true, + livelinessCheck: query| +}) +``` + +### Methods + +After a pool is created the user must initialize it using the init method: + +```js +await Pool.init() +``` + +This will populate the pool. The pool is unavailable until this completes. + +Once the pool has been successfully initialized it is ready for use. The user calls: + +```js +const newConnection = await Pool.requestConnection() +``` + +to get a connection, this method will return a connection ready for use. + +Once the user has finished using a connection, it can be returned to the pool with: + +```js +await Pool.releaseConnection() +``` + +Connections that have been released back to the connection pool should not be used anymore. +Connections that have failed in any way should be returned to the pool where they will dealt with and replaced. + +A pool should be shutdown by calling: + +```js +await Pool.closePool() +``` + +This will close all of the connections in the pool regardless of whether or not they are in use. + +Users cannot manually close connections provided by the pool, and calling: +`connection.close()` +on a connection provided by the pool will have the same effect as calling: +`Pool.releaseConnection(connection)` + + +### Args + +**connectionConfig:** the configuration that will be used to create the connection in the pool, required argument. + +**minAvailable:** initial size of the pool and the number of connections the pool will aim to maintain, default of 10 is used if no argument is provided. + +**maxAge:** Amount of time from connection creation until it will age out, default of 300000ms (5 minutes) is used if no argument is provided. + +**checkTime:** how often the pool will run an internal liveliness check on free connections, default of 120000ms(2 minutes) is used if no argument is provided. If 0 is provided, the liveliness check will be disabled. + +**maxLimit:** hard cap on the amount of live connection the pool can maintain, default of 200 is used if no argument is provided. If 0, the pool will have no hard cap. + +**connectionRetryLimit:** amount of times a pool will attempt to create a connection, default of 5 is used if no argument is provided. + +**id:** optional argument to give the pool an id. As default the pool will be provided the “new Date().getTime()” at the time of its creation as its id. + +**skipCheckLivelinessOnRelease:** turns off liveliness checks on connections when they are released back to the pool, which is different than the checkTime that is used for aging purposes. The default is false, meaning we will perform a liveliness check when a connection is returned to the pool. + +**livelinessCheck:** indicates the type of liveliness check to be performed. By default, the value is set to "query", which means a query to test the connection. If set to any value (quoted string) other than "query", it will only look to see if the NuoDB API isConnected returns true and we have not trapped a connection related exception previously. + +Arguments should be provided to the pool as an object. Please refer to the Usage section for an example. + +## Related Links + +- [NuoDB Multiplexer][5] +- [NuoDB Node.js Driver Documentation][3] + +## Best Practices + +Any `try` `catch` block in which NuoDB resources are created must be followed by a `finally` block in which NuoDB resources are then cleaned up. Attempting to clean up NuoDB resources in a `try` block can lead to NuoDB resources being created and never cleaned up. + +### Good Example + +```js + let conn + let results + try { + conn = await pool.requestConnection(); + results = await conn.execute(query); + const rows = await results?.getRows(); + rows?.should.be.ok(); + } catch (e) { + console.error(e); + should.not.exist(e); + } finally { + await results?.close(); + await pool.releaseConnection(conn); + } +``` + +### Bad Example + +```js + try { + const conn = await pool.requestConnection(); + const results = await conn.execute(query); // if we get an error here we will never clean up our connection + const rows = await results?.getRows(); + rows?.should.be.ok(); + await results?.close(); + await pool.releaseConnection(conn); + } catch (e) { + console.error(e); + should.not.exist(e); + } +``` + +## Help + +Issues and questions about node-nuodb can be posted on [GitHub][2]. + +## License + +This module is released under the [BSD 3-Clause License][1]. + +[1]: https://opensource.org/licenses/BSD-3-Clause +[2]: https://github.com/nuodb/node-nuodb/issues +[3]: https://nuodb.github.io/node-nuodb/ +[5]: https://github.com/nuodb/node-multiplexer diff --git a/doc/README.md b/doc/README.md index 343d69d..0a86d8f 100644 --- a/doc/README.md +++ b/doc/README.md @@ -3,7 +3,5 @@ ## Table of Contents 1. [Approach and Design][0] -2. [Online API Documentation][1] [0]: APPROACH.md -[1]: https://nuodb.github.io/node-nuodb/ diff --git a/lib/nuodb_nodejs.log b/lib/nuodb_nodejs.log new file mode 100644 index 0000000..e69de29 diff --git a/package-lock.json b/package-lock.json index c675d13..3e1011f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "node-nuodb", + "name": "nuodb-client", "version": "3.5.8", - "lockfileVersion": 2, + "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "node-nuodb", + "name": "nuodb-client", "version": "3.5.8", "license": "Apache-2.0", "dependencies": { @@ -26,76 +26,158 @@ "node": ">=8" } }, + "node_modules/@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz", + "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, "node_modules/@eslint/eslintrc": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", - "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.1.tgz", + "integrity": "sha512-9t7ZA7NGGK8ckelF0PQCfcxIUzs1Md5rrO6U/c+FIQNanea5UZC0wqKXH4vHBccmu4ZJgZ2idtPeW7+Q2npOEA==", "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.2.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", + "espree": "^9.6.0", + "globals": "^13.19.0", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "node_modules/@eslint/js": { + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.46.0.tgz", + "integrity": "sha512-a8TLtmPi8xzPkCbp/OGFUo5yhRkHM2Ko9kOWP4znJr0WAhWyThaw3PnwX4vOTWOAMsV2uRt32PPDcEz63esSaA==", "dev": true, "engines": { - "node": ">= 4" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, "node_modules/@gar/promisify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.2.tgz", - "integrity": "sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw==" + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==" }, "node_modules/@humanwhocodes/config-array": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz", - "integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==", + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz", + "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==", "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, "node_modules/@humanwhocodes/object-schema": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/@npmcli/fs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.0.tgz", - "integrity": "sha512-VhP1qZLXcrXRIaPoqb4YA55JQxLNF3jNR4T55IdOJa3+IFJKNYHtPvtXx8slmeMavj37vCzCfrqQM1vWLsYKLA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", + "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", "dependencies": { "@gar/promisify": "^1.0.1", "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" } }, "node_modules/@npmcli/move-file": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", + "deprecated": "This functionality has been moved to @npmcli/fs", "dependencies": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" @@ -135,9 +217,9 @@ } }, "node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true, "bin": { "acorn": "bin/acorn" @@ -167,12 +249,12 @@ } }, "node_modules/agentkeepalive": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.0.tgz", - "integrity": "sha512-0PhAp58jZNw13UJv7NVdTGb0ZcghHUb3DrZ046JiiJY/BOaTTpbwdHq2VObPCBV8M2GPh7sgrJ3AQ8Ey468LJw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.3.0.tgz", + "integrity": "sha512-7Epl1Blf4Sy37j4v9f9FjICCh4+KAQOyXgHEwlyBiAQLbhKdq/i2QQU3amQalS/wPhdPzDXPL5DMR5bkn+YeWg==", "dependencies": { "debug": "^4.1.0", - "depd": "^1.1.2", + "depd": "^2.0.0", "humanize-ms": "^1.2.1" }, "engines": { @@ -240,9 +322,9 @@ } }, "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", @@ -258,15 +340,15 @@ "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" }, "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", "dependencies": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" }, "engines": { - "node": ">=10" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/argparse": { @@ -276,9 +358,9 @@ "dev": true }, "node_modules/async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", "dev": true }, "node_modules/atomic-sleep": { @@ -540,12 +622,12 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/console-control-strings": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -562,9 +644,9 @@ } }, "node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dependencies": { "ms": "2.1.2" }, @@ -598,14 +680,14 @@ "node_modules/delegates": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" }, "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "engines": { - "node": ">= 0.6" + "node": ">= 0.8" } }, "node_modules/diff": { @@ -678,46 +760,48 @@ } }, "node_modules/eslint": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.7.0.tgz", - "integrity": "sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w==", - "dev": true, - "dependencies": { - "@eslint/eslintrc": "^1.0.5", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", + "version": "8.46.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.46.0.tgz", + "integrity": "sha512-cIO74PvbW0qU8e0mIvk5IV3ToWdCq5FYG6gWPHHkx6gNdjlbAYvtfHmlCMXxjcoVaIdwy/IAt3+mDkZkfvb2Dg==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.1", + "@eslint/js": "^8.46.0", + "@humanwhocodes/config-array": "^0.11.10", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.0", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.2.0", - "espree": "^9.3.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.2", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" + "text-table": "^0.2.0" }, "bin": { "eslint": "bin/eslint.js" @@ -730,9 +814,9 @@ } }, "node_modules/eslint-scope": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", - "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", "dev": true, "dependencies": { "esrecurse": "^4.3.0", @@ -740,62 +824,44 @@ }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" + "url": "https://opencollective.com/eslint" } }, "node_modules/eslint-visitor-keys": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", - "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz", + "integrity": "sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/espree": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", - "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "dependencies": { "estraverse": "^5.1.0" @@ -865,17 +931,26 @@ "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "dev": true }, "node_modules/fast-redact": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.2.0.tgz", - "integrity": "sha512-zaTadChr+NekyzallAMXATXLOR8MNx3zqpZ0MUF2aGf4EathnG0f32VLODNlY8IuGY3HoRO2L6/6fSzNsLaHIw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.3.0.tgz", + "integrity": "sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==", "engines": { "node": ">=6" } }, + "node_modules/fastq": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -944,9 +1019,9 @@ } }, "node_modules/flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", + "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==", "dev": true }, "node_modules/fs-minipass": { @@ -963,31 +1038,38 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } }, "node_modules/gauge": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.0.tgz", - "integrity": "sha512-F8sU45yQpjQjxKkm1UOAhf0U/O0aFt//Fl7hsrNVto+patMHjs7dPI9mFOGUKbhrgKm0S3EjW3scMFuQmWSROw==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", "dependencies": { - "ansi-regex": "^5.0.1", "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", "has-unicode": "^2.0.1", - "signal-exit": "^3.0.0", + "signal-exit": "^3.0.7", "string-width": "^4.2.3", "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" + "wide-align": "^1.1.5" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/get-caller-file": { @@ -1031,9 +1113,9 @@ } }, "node_modules/globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", + "version": "13.20.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", + "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -1046,9 +1128,15 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "dev": true }, "node_modules/growl": { "version": "1.10.5", @@ -1071,7 +1159,7 @@ "node_modules/has-unicode": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" }, "node_modules/he": { "version": "1.2.0", @@ -1083,9 +1171,9 @@ } }, "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" }, "node_modules/http-proxy-agent": { "version": "4.0.1", @@ -1101,9 +1189,9 @@ } }, "node_modules/https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "dependencies": { "agent-base": "6", "debug": "4" @@ -1115,7 +1203,7 @@ "node_modules/humanize-ms": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", "dependencies": { "ms": "^2.0.0" } @@ -1152,9 +1240,9 @@ ] }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, "engines": { "node": ">= 4" @@ -1179,7 +1267,7 @@ "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "engines": { "node": ">=0.8.19" } @@ -1200,7 +1288,7 @@ "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -1212,9 +1300,9 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "node_modules/ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", + "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" }, "node_modules/is-binary-path": { "version": "2.1.0", @@ -1231,7 +1319,7 @@ "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", "dev": true, "engines": { "node": ">=0.10.0" @@ -1260,7 +1348,7 @@ "node_modules/is-lambda": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=" + "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==" }, "node_modules/is-number": { "version": "7.0.0", @@ -1271,6 +1359,15 @@ "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", @@ -1295,7 +1392,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/js-yaml": { "version": "4.1.0", @@ -1318,7 +1415,7 @@ "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, "node_modules/levn": { @@ -1409,9 +1506,9 @@ } }, "node_modules/minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1420,9 +1517,9 @@ } }, "node_modules/minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dependencies": { "yallist": "^4.0.0" }, @@ -1556,6 +1653,29 @@ "url": "https://opencollective.com/mochajs" } }, + "node_modules/mocha/node_modules/debug": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/debug/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, "node_modules/mocha/node_modules/minimatch": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", @@ -1614,7 +1734,7 @@ "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, "node_modules/negotiator": { @@ -1672,23 +1792,23 @@ } }, "node_modules/npmlog": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.0.tgz", - "integrity": "sha512-03ppFRGlsyUaQFbGC2C8QWJN/C/K7PsfyD9aQdhVKAQIH4sQBc8WASqFBP7O+Ut4d2oo5LoeoboB3cGdBZSp6Q==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", "dependencies": { - "are-we-there-yet": "^2.0.0", + "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", - "gauge": "^4.0.0", + "gauge": "^4.0.3", "set-blocking": "^2.0.0" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, "node_modules/okay": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/okay/-/okay-1.0.0.tgz", - "integrity": "sha1-GjhG57eMfhinqTqgiPDKt+zs6D0=", + "integrity": "sha512-5/tIGJkNZgTgraoL2ovrkqSm5onNtpDLPoZfTOEjcaRxWOId5ZXLijvHltXsAaFRS0JMUokFLazo5DvNhVLxUQ==", "dev": true, "dependencies": { "sliced": "0.0.5" @@ -1702,23 +1822,23 @@ "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dependencies": { "wrappy": "1" } }, "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "dependencies": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" }, "engines": { "node": ">= 0.8.0" @@ -1792,7 +1912,7 @@ "node_modules/path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "engines": { "node": ">=0.10.0" } @@ -1819,9 +1939,9 @@ } }, "node_modules/pino": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/pino/-/pino-8.14.1.tgz", - "integrity": "sha512-8LYNv7BKWXSfS+k6oEc6occy5La+q2sPwU3q2ljTX5AZk7v+5kND2o5W794FyRaqha6DJajmkNRsWtPpFyMUdw==", + "version": "8.14.2", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.14.2.tgz", + "integrity": "sha512-zKu9aWeSWTy1JgvxIpZveJKKsAr4+6uNMZ0Vf0KRwzl/UNZA3XjHiIl/0WwqLMkDwuHuDkT5xAgPA2jpKq4whA==", "dependencies": { "atomic-sleep": "^1.0.0", "fast-redact": "^3.1.1", @@ -1849,14 +1969,15 @@ } }, "node_modules/pino-abstract-transport/node_modules/readable-stream": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.0.tgz", - "integrity": "sha512-kDMOq0qLtxV9f/SQv522h8cxZBqNZXuXNyjyezmfAAuribMyVXziljpQ/uQhfE1XLg2/TLTW2DsnoE4VAi/krg==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", + "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", - "process": "^0.11.10" + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1892,7 +2013,7 @@ "node_modules/promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" + "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==" }, "node_modules/promise-retry": { "version": "2.0.1", @@ -1907,14 +2028,34 @@ } }, "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", "dev": true, "engines": { "node": ">=6" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/quick-format-unescaped": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", @@ -1930,9 +2071,9 @@ } }, "node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -1962,22 +2103,10 @@ "node": ">= 12.13.0" } }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "engines": { "node": ">=0.10.0" @@ -1995,11 +2124,21 @@ "node_modules/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "engines": { "node": ">= 4" } }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -2014,6 +2153,29 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -2058,9 +2220,9 @@ } }, "node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -2083,7 +2245,7 @@ "node_modules/set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" }, "node_modules/shebang-command": { "version": "2.0.0", @@ -2131,7 +2293,7 @@ "node_modules/should-format": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", + "integrity": "sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==", "dev": true, "dependencies": { "should-type": "^1.3.0", @@ -2141,7 +2303,7 @@ "node_modules/should-type": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", + "integrity": "sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==", "dev": true }, "node_modules/should-type-adaptors": { @@ -2161,14 +2323,14 @@ "dev": true }, "node_modules/signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" }, "node_modules/sliced": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz", - "integrity": "sha1-XtwETKTrb3gW1Qui/GPiXY/kcH8=", + "integrity": "sha512-9bYT917D6H3+q8GlQBJmLVz3bc4OeVGfZ2BB12wvLnluTGfG6/8UdOUbKJDW1EEx9SZMDbjnatkau5/XcUeyOw==", "dev": true }, "node_modules/smart-buffer": { @@ -2181,12 +2343,12 @@ } }, "node_modules/socks": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", - "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", + "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", "dependencies": { - "ip": "^1.1.5", - "smart-buffer": "^4.1.0" + "ip": "^2.0.0", + "smart-buffer": "^4.2.0" }, "engines": { "node": ">= 10.13.0", @@ -2194,13 +2356,13 @@ } }, "node_modules/socks-proxy-agent": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz", - "integrity": "sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", + "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", "dependencies": { "agent-base": "^6.0.2", - "debug": "^4.3.1", - "socks": "^2.6.1" + "debug": "^4.3.3", + "socks": "^2.6.2" }, "engines": { "node": ">= 10" @@ -2290,25 +2452,33 @@ } }, "node_modules/tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", + "version": "6.1.15", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", + "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", + "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" }, "engines": { - "node": ">= 10" + "node": ">=10" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "engines": { + "node": ">=8" } }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", "dev": true }, "node_modules/thread-stream": { @@ -2383,13 +2553,7 @@ "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, "node_modules/which": { "version": "2.0.2", @@ -2413,15 +2577,6 @@ "string-width": "^1.0.2 || 2 || 3 || 4" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/workerpool": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", @@ -2448,7 +2603,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/y18n": { "version": "5.0.8", @@ -2518,1866 +2673,5 @@ "url": "https://github.com/sponsors/sindresorhus" } } - }, - "dependencies": { - "@eslint/eslintrc": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.0.5.tgz", - "integrity": "sha512-BLxsnmK3KyPunz5wmCCpqy0YelEoxxGmH73Is+Z74oOTMtExcjkr3dDR6quwrjh1YspA8DH9gnX1o069KiS9AQ==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.2.0", - "globals": "^13.9.0", - "ignore": "^4.0.6", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", - "strip-json-comments": "^3.1.1" - }, - "dependencies": { - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true - } - } - }, - "@gar/promisify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.2.tgz", - "integrity": "sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw==" - }, - "@humanwhocodes/config-array": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz", - "integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==", - "dev": true, - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.4" - } - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", - "dev": true - }, - "@npmcli/fs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.0.tgz", - "integrity": "sha512-VhP1qZLXcrXRIaPoqb4YA55JQxLNF3jNR4T55IdOJa3+IFJKNYHtPvtXx8slmeMavj37vCzCfrqQM1vWLsYKLA==", - "requires": { - "@gar/promisify": "^1.0.1", - "semver": "^7.3.5" - } - }, - "@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "requires": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - } - }, - "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" - }, - "@ungap/promise-all-settled": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", - "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" - }, - "abort-controller": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", - "requires": { - "event-target-shim": "^5.0.0" - } - }, - "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", - "dev": true - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "requires": { - "debug": "4" - } - }, - "agentkeepalive": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.0.tgz", - "integrity": "sha512-0PhAp58jZNw13UJv7NVdTGb0ZcghHUb3DrZ046JiiJY/BOaTTpbwdHq2VObPCBV8M2GPh7sgrJ3AQ8Ey468LJw==", - "requires": { - "debug": "^4.1.0", - "depd": "^1.1.2", - "humanize-ms": "^1.2.1" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-colors": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", - "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", - "dev": true - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" - }, - "are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "async": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", - "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", - "dev": true - }, - "atomic-sleep": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", - "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==" - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "requires": { - "fill-range": "^7.0.1" - } - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, - "cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "requires": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true - }, - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "dependencies": { - "glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "requires": { - "is-glob": "^4.0.1" - } - } - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", - "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", - "dev": true - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=" - }, - "diff": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", - "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", - "dev": true - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "optional": true, - "requires": { - "iconv-lite": "^0.6.2" - } - }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" - }, - "err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==" - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true - }, - "eslint": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.7.0.tgz", - "integrity": "sha512-ifHYzkBGrzS2iDU7KjhCAVMGCvF6M3Xfs8X8b37cgrUlDt6bWRTpRh6T/gtSXv1HJ/BUGgmjvNvOEGu85Iif7w==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.0.5", - "@humanwhocodes/config-array": "^0.9.2", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.0", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.2.0", - "espree": "^9.3.0", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^6.0.1", - "globals": "^13.6.0", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" - } - }, - "eslint-scope": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.0.tgz", - "integrity": "sha512-aWwkhnS0qAXqNOgKOK0dJ2nvzEbhEvpy8OlJ9kZ0FeZnA6zpjv1/Vei+puGFFX7zkPCkHHXb7IDX3A+7yPrRWg==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "eslint-visitor-keys": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.2.0.tgz", - "integrity": "sha512-IOzT0X126zn7ALX0dwFiUQEdsfzrm4+ISsQS8nukaJXwEyYKRSnEIIDULYg1mCtGp7UUXgfGl7BIolXREQK+XQ==", - "dev": true - }, - "espree": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.0.tgz", - "integrity": "sha512-d/5nCsb0JcqsSEeQzFZ8DH1RmxPcglRWh24EFTlUEmCKoehXGdpsx0RkHDubqUI8LSAIKMQp4r9SzQ3n+sm4HQ==", - "dev": true, - "requires": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", - "eslint-visitor-keys": "^3.1.0" - } - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "event-target-shim": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==" - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" - }, - "fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fast-redact": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.2.0.tgz", - "integrity": "sha512-zaTadChr+NekyzallAMXATXLOR8MNx3zqpZ0MUF2aGf4EathnG0f32VLODNlY8IuGY3HoRO2L6/6fSzNsLaHIw==" - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" - }, - "fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "requires": { - "to-regex-range": "^5.0.1" - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", - "dev": true - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "requires": { - "minipass": "^3.0.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "gauge": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.0.tgz", - "integrity": "sha512-F8sU45yQpjQjxKkm1UOAhf0U/O0aFt//Fl7hsrNVto+patMHjs7dPI9mFOGUKbhrgKm0S3EjW3scMFuQmWSROw==", - "requires": { - "ansi-regex": "^5.0.1", - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - } - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "requires": { - "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-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "globals": { - "version": "13.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.0.tgz", - "integrity": "sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==", - "dev": true, - "requires": { - "type-fest": "^0.20.2" - } - }, - "graceful-fs": { - "version": "4.2.9", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", - "integrity": "sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==" - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==" - }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "requires": { - "ms": "^2.0.0" - } - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" - }, - "is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=" - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "dev": true - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "requires": { - "argparse": "^2.0.1" - } - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "make-fetch-happen": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", - "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", - "requires": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.2.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^6.0.0", - "minipass": "^3.1.3", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^1.3.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.2", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^6.0.0", - "ssri": "^8.0.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", - "requires": { - "yallist": "^4.0.0" - } - }, - "minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-fetch": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", - "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", - "requires": { - "encoding": "^0.1.12", - "minipass": "^3.1.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.0.0" - } - }, - "minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "requires": { - "minipass": "^3.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" - }, - "mocha": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz", - "integrity": "sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==", - "dev": true, - "requires": { - "@ungap/promise-all-settled": "1.1.2", - "ansi-colors": "4.1.1", - "browser-stdout": "1.3.1", - "chokidar": "3.5.3", - "debug": "4.3.3", - "diff": "5.0.0", - "escape-string-regexp": "4.0.0", - "find-up": "5.0.0", - "glob": "7.2.0", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "4.1.0", - "log-symbols": "4.1.0", - "minimatch": "4.2.1", - "ms": "2.1.3", - "nanoid": "3.3.1", - "serialize-javascript": "6.0.0", - "strip-json-comments": "3.1.1", - "supports-color": "8.1.1", - "which": "2.0.2", - "workerpool": "6.2.0", - "yargs": "16.2.0", - "yargs-parser": "20.2.4", - "yargs-unparser": "2.0.0" - }, - "dependencies": { - "minimatch": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-4.2.1.tgz", - "integrity": "sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==" - }, - "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" - }, - "node-gyp": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", - "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", - "requires": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^9.1.0", - "nopt": "^5.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - } - }, - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "requires": { - "abbrev": "1" - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npmlog": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.0.tgz", - "integrity": "sha512-03ppFRGlsyUaQFbGC2C8QWJN/C/K7PsfyD9aQdhVKAQIH4sQBc8WASqFBP7O+Ut4d2oo5LoeoboB3cGdBZSp6Q==", - "requires": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.0", - "set-blocking": "^2.0.0" - } - }, - "okay": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/okay/-/okay-1.0.0.tgz", - "integrity": "sha1-GjhG57eMfhinqTqgiPDKt+zs6D0=", - "dev": true, - "requires": { - "sliced": "0.0.5" - } - }, - "on-exit-leak-free": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", - "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==" - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "requires": { - "wrappy": "1" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pino": { - "version": "8.14.1", - "resolved": "https://registry.npmjs.org/pino/-/pino-8.14.1.tgz", - "integrity": "sha512-8LYNv7BKWXSfS+k6oEc6occy5La+q2sPwU3q2ljTX5AZk7v+5kND2o5W794FyRaqha6DJajmkNRsWtPpFyMUdw==", - "requires": { - "atomic-sleep": "^1.0.0", - "fast-redact": "^3.1.1", - "on-exit-leak-free": "^2.1.0", - "pino-abstract-transport": "v1.0.0", - "pino-std-serializers": "^6.0.0", - "process-warning": "^2.0.0", - "quick-format-unescaped": "^4.0.3", - "real-require": "^0.2.0", - "safe-stable-stringify": "^2.3.1", - "sonic-boom": "^3.1.0", - "thread-stream": "^2.0.0" - } - }, - "pino-abstract-transport": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz", - "integrity": "sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==", - "requires": { - "readable-stream": "^4.0.0", - "split2": "^4.0.0" - }, - "dependencies": { - "readable-stream": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.0.tgz", - "integrity": "sha512-kDMOq0qLtxV9f/SQv522h8cxZBqNZXuXNyjyezmfAAuribMyVXziljpQ/uQhfE1XLg2/TLTW2DsnoE4VAi/krg==", - "requires": { - "abort-controller": "^3.0.0", - "buffer": "^6.0.3", - "events": "^3.3.0", - "process": "^0.11.10" - } - } - } - }, - "pino-std-serializers": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-6.2.2.tgz", - "integrity": "sha512-cHjPPsE+vhj/tnhCy/wiMh3M3z3h/j15zHQX+S9GkTBgqJuTuJzYJ4gUyACLhDaJ7kk9ba9iRDmbH2tJU03OiA==" - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==" - }, - "process-warning": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", - "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==" - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" - }, - "promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "requires": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "quick-format-unescaped": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", - "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==" - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "real-require": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", - "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==" - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true - }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safe-stable-stringify": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", - "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "optional": true - }, - "segfault-handler": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/segfault-handler/-/segfault-handler-1.3.0.tgz", - "integrity": "sha512-p7kVHo+4uoYkr0jmIiTBthwV5L2qmWtben/KDunDZ834mbos+tY+iO0//HpAJpOFSQZZ+wxKWuRo4DxV02B7Lg==", - "requires": { - "bindings": "^1.2.1", - "nan": "^2.14.0" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" - }, - "shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true - }, - "should": { - "version": "13.2.3", - "resolved": "https://registry.npmjs.org/should/-/should-13.2.3.tgz", - "integrity": "sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==", - "dev": true, - "requires": { - "should-equal": "^2.0.0", - "should-format": "^3.0.3", - "should-type": "^1.4.0", - "should-type-adaptors": "^1.0.1", - "should-util": "^1.0.0" - } - }, - "should-equal": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/should-equal/-/should-equal-2.0.0.tgz", - "integrity": "sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==", - "dev": true, - "requires": { - "should-type": "^1.4.0" - } - }, - "should-format": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/should-format/-/should-format-3.0.3.tgz", - "integrity": "sha1-m/yPdPo5IFxT04w01xcwPidxJPE=", - "dev": true, - "requires": { - "should-type": "^1.3.0", - "should-type-adaptors": "^1.0.1" - } - }, - "should-type": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/should-type/-/should-type-1.4.0.tgz", - "integrity": "sha1-B1bYzoRt/QmEOmlHcZ36DUz/XPM=", - "dev": true - }, - "should-type-adaptors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/should-type-adaptors/-/should-type-adaptors-1.1.0.tgz", - "integrity": "sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==", - "dev": true, - "requires": { - "should-type": "^1.3.0", - "should-util": "^1.0.0" - } - }, - "should-util": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/should-util/-/should-util-1.0.1.tgz", - "integrity": "sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==", - "dev": true - }, - "signal-exit": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.6.tgz", - "integrity": "sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ==" - }, - "sliced": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz", - "integrity": "sha1-XtwETKTrb3gW1Qui/GPiXY/kcH8=", - "dev": true - }, - "smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" - }, - "socks": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.1.tgz", - "integrity": "sha512-kLQ9N5ucj8uIcxrDwjm0Jsqk06xdpBjGNQtpXy4Q8/QY2k+fY7nZH8CARy+hkbG+SGAovmzzuauCpBlb8FrnBA==", - "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.1.0" - } - }, - "socks-proxy-agent": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.1.1.tgz", - "integrity": "sha512-t8J0kG3csjA4g6FTbsMOWws+7R7vuRC8aQ/wy3/1OWmsgwA68zs/+cExQ0koSitUDXqhufF/YJr9wtNMZHw5Ew==", - "requires": { - "agent-base": "^6.0.2", - "debug": "^4.3.1", - "socks": "^2.6.1" - } - }, - "sonic-boom": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz", - "integrity": "sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==", - "requires": { - "atomic-sleep": "^1.0.0" - } - }, - "split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==" - }, - "ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "requires": { - "minipass": "^3.1.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "requires": { - "safe-buffer": "~5.2.0" - } - }, - "string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "thread-stream": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.3.0.tgz", - "integrity": "sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==", - "requires": { - "real-require": "^0.2.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" - }, - "v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { - "isexe": "^2.0.0" - } - }, - "wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "requires": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, - "workerpool": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.0.tgz", - "integrity": "sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==", - "dev": true - }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "yargs-parser": { - "version": "20.2.4", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", - "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", - "dev": true - }, - "yargs-unparser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", - "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", - "dev": true, - "requires": { - "camelcase": "^6.0.0", - "decamelize": "^4.0.0", - "flat": "^5.0.2", - "is-plain-obj": "^2.1.0" - } - }, - "yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true - } } } From e638249926671909882d9959bcdc5bfed8368085 Mon Sep 17 00:00:00 2001 From: marco3479 Date: Mon, 28 Aug 2023 16:00:29 -0400 Subject: [PATCH 03/11] Broke down documentation into sections README2.md is the entry file for documentation - Single Connection - Connection Pool - Best Practices --- BEST_PRACTICES.md | 39 +++++++ CONNECTION_POOL.md | 91 +++++++++++++++ README2.md | 262 ++++--------------------------------------- SINGLE_CONNECTION.md | 177 +++++++++++++++++++++++++++++ 4 files changed, 329 insertions(+), 240 deletions(-) create mode 100644 BEST_PRACTICES.md create mode 100644 CONNECTION_POOL.md create mode 100644 SINGLE_CONNECTION.md diff --git a/BEST_PRACTICES.md b/BEST_PRACTICES.md new file mode 100644 index 0000000..811b4b0 --- /dev/null +++ b/BEST_PRACTICES.md @@ -0,0 +1,39 @@ + +# Best Practices + +Any `try` `catch` block in which NuoDB resources are created must be followed by a `finally` block in which NuoDB resources are then cleaned up. Attempting to clean up NuoDB resources in a `try` block can lead to NuoDB resources being created and never cleaned up. + +### Good Example + +```js + let conn + let results + try { + conn = await pool.requestConnection(); + results = await conn.execute(query); + const rows = await results?.getRows(); + rows?.should.be.ok(); + } catch (e) { + console.error(e); + should.not.exist(e); + } finally { + await results?.close(); + await pool.releaseConnection(conn); + } +``` + +### Bad Example + +```js + try { + const conn = await pool.requestConnection(); + const results = await conn.execute(query); // if we get an error here we will never clean up our connection + const rows = await results?.getRows(); + rows?.should.be.ok(); + await results?.close(); + await pool.releaseConnection(conn); + } catch (e) { + console.error(e); + should.not.exist(e); + } +``` diff --git a/CONNECTION_POOL.md b/CONNECTION_POOL.md new file mode 100644 index 0000000..64f0d6d --- /dev/null +++ b/CONNECTION_POOL.md @@ -0,0 +1,91 @@ + +# Connection Pool + +The **NuoDB Node.js** driver comes with a built-in connection pool. A connection pool serves a critical role in optimizing the interaction between applications and databases. + +Unlike establishing an individual connection for each database interaction, a connection pool efficiently manages a reusable collection of established connections. This approach significantly reduces the overhead associated with repeatedly establishing and closing connections, resulting in improved performance and resource utilization. + +With a connection pool in place, the **NuoDB** driver can intelligently manage the lifecycle of connections, offering seamless access to the **NuoDB** database while effectively mitigating the potential for connection bottlenecks and latency. This allows developers to optimize their application's responsiveness and scalability while ensuring an efficient and streamlined interaction with the database. + + +## Usage + +```js +async function () { + const myPool = new Pool({ + minAvailable: , + connectionConfig: , + maxAge: , + checkTime: , + maxLimit: , + connectionRetryLimit: , + id: , + skipCheckLivelinessOnRelease: false|true, + livelinessCheck: query| + }); + + await Pool.init() + const newConnection = await Pool.requestConnection() + await Pool.releaseConnection() + await Pool.closePool() +} + +``` + +## Methods + +After a pool is created the user must initialize it using the init method: + +```js +await Pool.init() +``` + +This will populate the pool. The pool is unavailable until this completes. + +Once the pool has been successfully initialized it is ready for use. The user calls: + +```js +const newConnection = await Pool.requestConnection() +``` + +to get a connection, this method will return a connection ready for use. + +Once the user has finished using a connection, it can be returned to the pool with: + +```js +await Pool.releaseConnection() +``` + +Connections that have been released back to the connection pool should not be used anymore. +Connections that have failed in any way should be returned to the pool where they will dealt with and replaced. + +A pool should be shutdown by calling: + +```js +await Pool.closePool() +``` + +This will close all of the connections in the pool regardless of whether or not they are in use. + +Users cannot manually close connections provided by the pool, and calling: +`connection.close()` +on a connection provided by the pool will have the same effect as calling: +`Pool.releaseConnection(connection)` + + +## Configuration + +Key | Value +--- | --- +**connectionConfig** | the configuration that will be used to create the connection in the pool, required argument. +**minAvailable** | initial size of the pool and the number of connections the pool will aim to maintain, default of 10 is used if no argument is provided. +**maxAge** | Amount of time from connection creation until it will age out, default of 300000ms (5 minutes) is used if no argument is provided. +**checkTime** | how often the pool will run an internal liveliness check on free connections, default of 120000ms(2 minutes) is used if no argument is provided. If 0 is provided, the liveliness check will be disabled. +**maxLimit** | hard cap on the amount of live connection the pool can maintain, default of 200 is used if no argument is provided. If 0, the pool will have no hard cap. +**connectionRetryLimit** | amount of times a pool will attempt to create a connection, default of 5 is used if no argument is provided. +**id** | optional argument to give the pool an id. As default the pool will be provided the “new Date().getTime()” at the time of its creation as its id. +**skipCheckLivelinessOnRelease** | turns off liveliness checks on connections when they are released back to the pool, which is different than the checkTime that is used for aging purposes. The default is false, meaning we will perform a liveliness check when a connection is returned to the pool. +**livelinessCheck** | indicates the type of liveliness check to be performed. By default, the value is set to "query", which means a query to test the connection. If set to any value (quoted string) other than "query", it will only look to see if the NuoDB API isConnected returns true and we have not trapped a connection related exception previously. + + +Arguments should be provided to the pool as an object. Please refer to the Usage section for an example. diff --git a/README2.md b/README2.md index 6957725..9d5dd7f 100644 --- a/README2.md +++ b/README2.md @@ -1,8 +1,9 @@ # **node-nuodb** - Node.js NAN C++ NuoDB Driver - The `node-nuodb` add-on for **Node.js** powers high performance **NuoDB** database applications. Use `node-nuodb` to connect **Node.js** to a **NuoDB** database. It supports basic features of the **NuoDB** database and **NuoDB C++** client. + Utilizing the **NuoDB** **Node.js** driver, developers can harness NuoDB's distributed architecture and dynamic scaling, while benefiting from **Node.js**' ease. This guide will help you set up, configure, and use the driver to connect seamlessly to a **NuoDB** database, empowering your applications to integrate smoothly with its advanced database technology. + ## Dependencies @@ -11,9 +12,12 @@ The `node-nuodb` add-on for **Node.js** powers high performance **NuoDB** databa ## Installation -If you have NuoDB installed locally, skip to step 4. +**NuoDB** has been designed for gradual adoption from the start, and you can use as little or as much of its capabilities as you need. To connect to a **NuoDB** database, you need to have **NuoDB** installed first. -1. Download the nuodb client package. +> **NOTE** - +> If you have **NuoDB** installed locally, skip to step 4. + +1. Download the **NuoDB** client package. The client package releases can be found here: https://github.com/nuodb/nuodb-client/releases 2. Extract the client package. @@ -28,251 +32,29 @@ If you have NuoDB installed locally, skip to step 4. `npm i node-nuodb` -5. Ensure the driver is working as intended. Note this assumes NuoDB database has `"dba"` user and `"dba"` as password. +5. Ensure the driver is working as intended. Note, this assumes **NuoDB** database has `"dba"` user and `"dba"` as password. `npm test` -6. Import the driver into your node.js project. +6. Import the driver into your **Node.js** project. `import { Driver } from "node-nuodb";` +## Documentation -## Single connection - -The usage of a single connection entails initializing the driver, connecting to a **NuoDB** database using a configuration object with connection properties, executing desired `SQL`, getting the rows from the result set, and finally closing the connection. - -```js -import { Driver } from "node-nuodb"; - -const config = { - database: `test`, - password: "dba", - user: "dba", - port: "48004", - schema: "USER" -}; - -async function run() { - const driver = new Driver(); - const connection = await driver.connect(config); - const results = await connection.execute("SELECT * FROM SYSTEM.NODES;"); - const rows = await results.getRows(); - await connection.close(); - return rows -} - -run() -``` - -### Connect - -To connect to a **NuoDB** database you must provide a configuration object which includes the connection properties. Find the available connection properties in the [NuoDB docs](https://doc.nuodb.com/nuodb/latest/reference-information/connection-properties/#nav-container-toggle). Provide each of the connection property values as a `string`. - -```js -const config = { - database: `test`, - password: "dba", - user: "dba", - port: "48004", - schema: "USER" -}; -``` -With the configuration object defined, you can now `connect()` to the desired **NuoDB** database. - -```js -const driver = new Driver(); -const connection = await driver.connect(config); -``` - -### Execute SQL -With a connection obtained, `execute()` a `SQL` statement against the database. If the default schema was defined in the configuration map, it is not required to specify which schema the statement is intended to target. `getRows()` to obtain the rows from the result set. - -```js -const results = await connection.execute("SELECT * FROM SYSTEM.NODES;"); -const rows = await results.getRows(); -``` - -### Close Connection - -Finally, `close()` the database connection. - -```js -await connection.close(); -``` - -> **NOTE** -> -> Since the methods are `async`, you should `try catch` them, and may use `await` or `then` as desired. - -### Connection Properties - -Key | Value ----|--- -allowSRPFallback=[ true \| false ] | Allows the driver to fall back to SRP if the TLS connection fails (when used in combination with trustStore ). Required (set to true) during rolling upgrade of the security protocol. -ciphers=cipherlist | Enables the client to provide one or more appropriate ciphers for encrypting the network connection to the database. If this property is not specified the default ciphers AES-256-CTR and RC4 are enabled. The server chooses a preferred cipher from this list. If no matching cipher is found, the connection will be refused. The cipherlist is comma-separated and cipher names are case-sensitive and must be provided exactly as shown. The full list of available ciphers are AES-256-CTR, RC4, and None. -clientInfo=info | Arbitrary information about the connecting client. This is available in the CLIENTINFO column of the SYSTEM.CONNECTIONS and SYSTEM.LOCALCONNECTIONS system tables. -clientProcessID=id | The process ID (pid) of the connecting client. The client may set this property only if not already set by the driver. The .NET and Python drivers set this for the client. The client setting of this property does not overrides the driver setting of this property. The clientProcessId is then available in the CLIENTPROCESSID column of the SYSTEM.CONNECTIONS and SYSTEM.LOCALCONNECTIONS system tables. -direct=[ true \| false ] | Connect directly to TE(s) rather than via the AP(s). If not specified, direct defaults to false and connections are made via the AP(s) specified in the connection URL. When direct=true, the client connection is made directly with a TE. The hosts and port numbers in the connection URL are assumed to specify the hosts and port numbers of TE processes. The use of the direct connection property is supported for nuosql and the JDBC, C, C++, and Go drivers. When using nuosql, it supports an equivalent --direct option. Where possible, direct connection should be made using the load-balancing capability of the APs. This connection property is useful when connecting external SQL applications directly to TEs that are running on a different network - such as in the Cloud, on Kubernetes clusters, and in other containerized deployments (such as Docker) or via SSH tunneling. For more details, see Direct TE Connections. Although it is for JDBC, the basic principles apply to all drivers supporting direct. -idle-timeout=number | The maximum time (in seconds) which indicates how long idle connections are left open. Although the IDLE_CONNECTION_TIMEOUT system property is a global setting for timing out idle connections, you can use this connection property to override the system property on a per connection basis. By default, idle-timeout is set to -1, meaning that the global setting is used. If you set a value greater than 0, this property overrides any value set for IDLE_CONNECTION_TIMEOUT. You may also set a value of 0 to specifically disable this property for the connection. Any time a client connection is terminated for being idle for too long, a message will be logged under the net category. For more information on IDLE_CONNECTION_TIMEOUT, see SQL System Properties. -isolation=level | The default transaction isolation level for the connection to use. Isolation levels supported are consistent_read and read_committed. Note that these values are case sensitive. For more information, see CONSISTENT READ and READ COMMITTED. -keepAlive=[ true \| false ] | Allows enabling of TCP KeepAlive on the connection from client to Transaction Engine. If not specified, keepAlive defaults to false. When keepAlive=true, the driver enables TCP KeepAlive on the socket that it opens to the Transaction Engine. -LBPolicy=valueA | From the client application, this property allows selective load balancing across Transaction Engines. For information on using LBPolicy, see Load Balancer Policies. -LBQuery=\(\) | From the client application, this property allows selective load balancing across Transaction Engines. For information on using LBQuery, see Load Balancer Policies. -lock-wait-timeout=sec | Configures lock wait time (in seconds) when establishing a new connection. For more information, see About the NuoDB SQL Configuration File. The default is equal to the system property DEFAULT_LOCK_WAIT_TIMEOUT. For more information, see SQL System Properties. -memory-limit-bytes=size | The memory limit (per connection) in bytes for all blocking SQL engine operations: Hash-grouping, sorting, sorting via priority queue for limit, distinct (via hash-grouping), union, listagg, table functions, and stored procedures returning result set(s) that accumulate data - in main memory. To run statements with a memory limit different from the system-wide limit, start a new connection with this connection property set to the per-connection limit. If you do not define a value for memory-limit-bytes, the value set for the DEFAULT_CONNECTION_MEMORY_LIMIT system property is the default setting used. -password=pwd | The password for the user account used to connect to the database. -PreferInternalAddress=[ true \| false ] | Use internal address and port for TE, as specified by the external-address and external-port process labels. Default is false (disabled). For a detailed explanation, see Controlling Connectivity, a special case of using Load Balancer Policies with labels. -rollbackMode=[ procedure \| transaction \| off ] | Controls the behavior of transactions executed inside a stored procedure. The default is off. See About Implicit and Explicit Transactions. -schema=name | The default schema that the connection should use when objects (such as tables and views) are not fully qualified. -TimeZone=timezone | The default time zone for the connection to use (this is also known as the session time zone). If not specified, the application’s default time zone is used. -user=name | The user name for connecting to the database. -verifyHostname=[ true \| false ] | Verifies the DN name of the SSL server against the name presented on the certificate. The default is true. - -## Connection Pool - -The NuoDB Node.js driver comes with a built in connection pool available. - - -### Usage - -```js -const myPool = new Pool({ - minAvailable: , - connectionConfig: , - maxAge: , - checkTime: , - maxLimit: , - connectionRetryLimit: , - id: , - skipCheckLivelinessOnRelease: false|true, - livelinessCheck: query| -}); -await Pool.init() -const newConnection = await Pool.requestConnection() -await Pool.releaseConnection() -await Pool.closePool() - -``` -```js -const myPool = new Pool({ - minAvailable: , - connectionConfig: , - maxAge: , - checkTime: , - maxLimit: , - connectionRetryLimit: , - id: , - skipCheckLivelinessOnRelease: false|true, - livelinessCheck: query| -}) -``` - -### Methods - -After a pool is created the user must initialize it using the init method: + +`node-nuodb` driver enables the capability of connection to a **NuoDB** database via a single connection or a connection pool. For further details refer to the best practices section. -```js -await Pool.init() -``` +- [Single Connection](SINGLE_CONNECTION.md) +- [Connection Pool](CONNECTION_POOL.md) +- [Best Practices](BEST_PRACTICES.md) -This will populate the pool. The pool is unavailable until this completes. - -Once the pool has been successfully initialized it is ready for use. The user calls: - -```js -const newConnection = await Pool.requestConnection() -``` - -to get a connection, this method will return a connection ready for use. - -Once the user has finished using a connection, it can be returned to the pool with: - -```js -await Pool.releaseConnection() -``` - -Connections that have been released back to the connection pool should not be used anymore. -Connections that have failed in any way should be returned to the pool where they will dealt with and replaced. - -A pool should be shutdown by calling: - -```js -await Pool.closePool() -``` - -This will close all of the connections in the pool regardless of whether or not they are in use. - -Users cannot manually close connections provided by the pool, and calling: -`connection.close()` -on a connection provided by the pool will have the same effect as calling: -`Pool.releaseConnection(connection)` - - -### Args - -**connectionConfig:** the configuration that will be used to create the connection in the pool, required argument. - -**minAvailable:** initial size of the pool and the number of connections the pool will aim to maintain, default of 10 is used if no argument is provided. - -**maxAge:** Amount of time from connection creation until it will age out, default of 300000ms (5 minutes) is used if no argument is provided. - -**checkTime:** how often the pool will run an internal liveliness check on free connections, default of 120000ms(2 minutes) is used if no argument is provided. If 0 is provided, the liveliness check will be disabled. - -**maxLimit:** hard cap on the amount of live connection the pool can maintain, default of 200 is used if no argument is provided. If 0, the pool will have no hard cap. - -**connectionRetryLimit:** amount of times a pool will attempt to create a connection, default of 5 is used if no argument is provided. - -**id:** optional argument to give the pool an id. As default the pool will be provided the “new Date().getTime()” at the time of its creation as its id. - -**skipCheckLivelinessOnRelease:** turns off liveliness checks on connections when they are released back to the pool, which is different than the checkTime that is used for aging purposes. The default is false, meaning we will perform a liveliness check when a connection is returned to the pool. - -**livelinessCheck:** indicates the type of liveliness check to be performed. By default, the value is set to "query", which means a query to test the connection. If set to any value (quoted string) other than "query", it will only look to see if the NuoDB API isConnected returns true and we have not trapped a connection related exception previously. - -Arguments should be provided to the pool as an object. Please refer to the Usage section for an example. +For information on using NuoDB, refer to the [documentation website][1]. ## Related Links -- [NuoDB Multiplexer][5] -- [NuoDB Node.js Driver Documentation][3] - -## Best Practices - -Any `try` `catch` block in which NuoDB resources are created must be followed by a `finally` block in which NuoDB resources are then cleaned up. Attempting to clean up NuoDB resources in a `try` block can lead to NuoDB resources being created and never cleaned up. - -### Good Example - -```js - let conn - let results - try { - conn = await pool.requestConnection(); - results = await conn.execute(query); - const rows = await results?.getRows(); - rows?.should.be.ok(); - } catch (e) { - console.error(e); - should.not.exist(e); - } finally { - await results?.close(); - await pool.releaseConnection(conn); - } -``` - -### Bad Example - -```js - try { - const conn = await pool.requestConnection(); - const results = await conn.execute(query); // if we get an error here we will never clean up our connection - const rows = await results?.getRows(); - rows?.should.be.ok(); - await results?.close(); - await pool.releaseConnection(conn); - } catch (e) { - console.error(e); - should.not.exist(e); - } -``` +- [NuoDB Documentation][1] + ## Help @@ -280,9 +62,9 @@ Issues and questions about node-nuodb can be posted on [GitHub][2]. ## License -This module is released under the [BSD 3-Clause License][1]. +This package is released under the [BSD 3-Clause License][3]. -[1]: https://opensource.org/licenses/BSD-3-Clause +[1]: https://doc.nuodb.com/nuodb/latest/introduction-to-nuodb/ [2]: https://github.com/nuodb/node-nuodb/issues -[3]: https://nuodb.github.io/node-nuodb/ -[5]: https://github.com/nuodb/node-multiplexer + +[3]: https://opensource.org/licenses/BSD-3-Clause diff --git a/SINGLE_CONNECTION.md b/SINGLE_CONNECTION.md new file mode 100644 index 0000000..9a7173d --- /dev/null +++ b/SINGLE_CONNECTION.md @@ -0,0 +1,177 @@ + +# Single connection + +The lifecycle of a single connection of the `node-nuodb` driver to a **NuoDB** database entails: +- Initialization of the `node-nuodb` driver +- Connection to a **NuoDB** database using configuration object +- Execution of desired `SQL` +- Getting the rows from the result set +- Releasing memory +- Closure of the connection + +## Overview + +The `node-nuodb` driver supports `try/catch`, `callback`, and `Promise` semantics. The following is a general example implementing the driver. It exemplifies its safe usage via `try/catch` clauses. + +> **NOTE** +> +> This example assumes `auto commit` is `on` by default. Set `auto commit` through the connection configuration or `SQL` directive. + +```js +import { Driver } from "node-nuodb"; + +const config = { + database: `test`, + password: "dba", + user: "dba", + port: "48004", + schema: "USER" +}; + +async function () { + const driver = new Driver(); + + try { + const connection = await driver.connect(config); + const results = await connection.execute("SELECT * FROM SYSTEM.NODES;"); + const rows = await results.getRows(); + // use rows + + await rows.close(); + + } catch (err) {/* handle error */} + + finally { + await connection.close(); + } +} +``` + +### Connect + +To connect to a **NuoDB** database you must provide a configuration object which includes the connection properties. Find the available connection properties in the [NuoDB documentation](https://doc.nuodb.com/nuodb/latest/reference-information/connection-properties/#nav-container-toggle). Provide each of the connection property values as a `string`. + +```js +const config = { + database: `test`, + password: "dba", + user: "dba", + port: "48004", + schema: "USER" +}; +``` +With the configuration object defined, you can now `connect()` to the desired **NuoDB** database. + +```js +const driver = new Driver(); +const connection = await driver.connect(config); +``` + +### Execute SQL +With a connection obtained, `execute()` a `SQL` statement against the database. If the default schema was defined in the configuration map, it is not required to specify which schema the statement is intended to target. `getRows()` to obtain the rows from the result set. + +```js +const results = await connection.execute("SELECT * FROM SYSTEM.NODES;"); +const rows = await results.getRows(); +``` + +### Cleanup Memory + +Close a results set anytime you are done using any fetch or cursor. This will release memory structures associated with those constructs. +```js +await rows.close(); +``` + +### Close Connection + +Finally, `close()` the database connection. + +```js +await connection.close(); +``` + + +### Using callbacks + +The following is an example of creating a single connection against a **NuoDB** database using `callback` semantics. + +```js +let rows; +const driver = new Driver(); + +driver.connect(config, (err, connection) => { + if (err) {/* handle connection error */} + + connection.execute("SELECT * FROM SYSTEM.NODES;", (err, results) => { + if (err) {/* handle execution error */} + + results.getRows((err, rows) => { + if (err) {/* handle getting rows error */} + + // use rows + }); + }); + + connection.close((err) => { + if (err) {/* handle closure error */} + }); +}); +``` + +### Using Promises + +The following is an example of creating a single connection against a **NuoDB** database using `Promise` semantics. + +```js +let rows; +const driver = new Driver(); + +driver.connect(config) + .then(connection => { + + connection.execute("SELECT * FROM SYSTEM.NODES;") + .then(results => { + + results.getRows() + .then(rows => { /* use rows */ }) + .catch(err => { /* handle getting rows error */ }); + + results.close() + .catch(err => { /* handle results closure error */ }) + }) + .catch(err => { /* handle SQL execution error */ }); + + connection.close() + .catch(err => { /* handle connection closure error */ }) + + }) + .catch(err => { /* handle connection error */ }) +``` + + + +## Connection Properties + +Key | Value +---|--- +allowSRPFallback=[ true \| false ] | Allows the driver to fall back to SRP if the TLS connection fails (when used in combination with trustStore ). Required (set to true) during rolling upgrade of the security protocol. +ciphers=cipherlist | Enables the client to provide one or more appropriate ciphers for encrypting the network connection to the database. If this property is not specified the default ciphers AES-256-CTR and RC4 are enabled. The server chooses a preferred cipher from this list. If no matching cipher is found, the connection will be refused. The cipherlist is comma-separated and cipher names are case-sensitive and must be provided exactly as shown. The full list of available ciphers are AES-256-CTR, RC4, and None. +clientInfo=info | Arbitrary information about the connecting client. This is available in the CLIENTINFO column of the SYSTEM.CONNECTIONS and SYSTEM.LOCALCONNECTIONS system tables. +clientProcessID=id | The process ID (pid) of the connecting client. The client may set this property only if not already set by the driver. The .NET and Python drivers set this for the client. The client setting of this property does not overrides the driver setting of this property. The clientProcessId is then available in the CLIENTPROCESSID column of the SYSTEM.CONNECTIONS and SYSTEM.LOCALCONNECTIONS system tables. +direct=[ true \| false ] | Connect directly to TE(s) rather than via the AP(s). If not specified, direct defaults to false and connections are made via the AP(s) specified in the connection URL. When direct=true, the client connection is made directly with a TE. The hosts and port numbers in the connection URL are assumed to specify the hosts and port numbers of TE processes. The use of the direct connection property is supported for nuosql and the JDBC, C, C++, and Go drivers. When using nuosql, it supports an equivalent --direct option. Where possible, direct connection should be made using the load-balancing capability of the APs. This connection property is useful when connecting external SQL applications directly to TEs that are running on a different network - such as in the Cloud, on Kubernetes clusters, and in other containerized deployments (such as Docker) or via SSH tunneling. For more details, see Direct TE Connections. Although it is for JDBC, the basic principles apply to all drivers supporting direct. +idle-timeout=number | The maximum time (in seconds) which indicates how long idle connections are left open. Although the IDLE_CONNECTION_TIMEOUT system property is a global setting for timing out idle connections, you can use this connection property to override the system property on a per connection basis. By default, idle-timeout is set to -1, meaning that the global setting is used. If you set a value greater than 0, this property overrides any value set for IDLE_CONNECTION_TIMEOUT. You may also set a value of 0 to specifically disable this property for the connection. Any time a client connection is terminated for being idle for too long, a message will be logged under the net category. For more information on IDLE_CONNECTION_TIMEOUT, see SQL System Properties. +isolation=level | The default transaction isolation level for the connection to use. Isolation levels supported are consistent_read and read_committed. Note that these values are case sensitive. For more information, see CONSISTENT READ and READ COMMITTED. +keepAlive=[ true \| false ] | Allows enabling of TCP KeepAlive on the connection from client to Transaction Engine. If not specified, keepAlive defaults to false. When keepAlive=true, the driver enables TCP KeepAlive on the socket that it opens to the Transaction Engine. +LBPolicy=valueA | From the client application, this property allows selective load balancing across Transaction Engines. For information on using LBPolicy, see Load Balancer Policies. +LBQuery=\(\) | From the client application, this property allows selective load balancing across Transaction Engines. For information on using LBQuery, see Load Balancer Policies. +lock-wait-timeout=sec | Configures lock wait time (in seconds) when establishing a new connection. For more information, see About the NuoDB SQL Configuration File. The default is equal to the system property DEFAULT_LOCK_WAIT_TIMEOUT. For more information, see SQL System Properties. +memory-limit-bytes=size | The memory limit (per connection) in bytes for all blocking SQL engine operations: Hash-grouping, sorting, sorting via priority queue for limit, distinct (via hash-grouping), union, listagg, table functions, and stored procedures returning result set(s) that accumulate data - in main memory. To run statements with a memory limit different from the system-wide limit, start a new connection with this connection property set to the per-connection limit. If you do not define a value for memory-limit-bytes, the value set for the DEFAULT_CONNECTION_MEMORY_LIMIT system property is the default setting used. +password=pwd | The password for the user account used to connect to the database. +PreferInternalAddress=[ true \| false ] | Use internal address and port for TE, as specified by the external-address and external-port process labels. Default is false (disabled). For a detailed explanation, see Controlling Connectivity, a special case of using Load Balancer Policies with labels. +rollbackMode=[ procedure \| transaction \| off ] | Controls the behavior of transactions executed inside a stored procedure. The default is off. See About Implicit and Explicit Transactions. +schema=name | The default schema that the connection should use when objects (such as tables and views) are not fully qualified. +TimeZone=timezone | The default time zone for the connection to use (this is also known as the session time zone). If not specified, the application’s default time zone is used. +user=name | The user name for connecting to the database. +verifyHostname=[ true \| false ] | Verifies the DN name of the SSL server against the name presented on the certificate. The default is true. + + From dbf5dc8c543538f9fd65179451a191ff0194881e Mon Sep 17 00:00:00 2001 From: marco3479 Date: Tue, 29 Aug 2023 15:44:00 -0400 Subject: [PATCH 04/11] Improved docs - Added section to best practices page -> Single Connection vs Connection Pool - Cleaned up examples of Connection Pool - Improved descriptions in Single Connection page --- .gitignore | 2 + BEST_PRACTICES.md | 52 ++++++----------- CONNECTION_POOL.md | 134 +++++++++++++++++++++++++++++++------------ README2.md | 4 +- SINGLE_CONNECTION.md | 48 +++++++++++----- lib/driver.js | 3 + 6 files changed, 153 insertions(+), 90 deletions(-) diff --git a/.gitignore b/.gitignore index bb22b4c..f562e1c 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ vol2/ build/ node_modules/ + +test/t.js \ No newline at end of file diff --git a/BEST_PRACTICES.md b/BEST_PRACTICES.md index 811b4b0..9be2dbe 100644 --- a/BEST_PRACTICES.md +++ b/BEST_PRACTICES.md @@ -1,39 +1,21 @@ # Best Practices -Any `try` `catch` block in which NuoDB resources are created must be followed by a `finally` block in which NuoDB resources are then cleaned up. Attempting to clean up NuoDB resources in a `try` block can lead to NuoDB resources being created and never cleaned up. +## Single Connection vs Connection Pool + +While connection pooling offers advantages in managing multiple concurrent connections efficiently, a singular connection might be preferred when dealing with specific use cases that prioritize simplicity, resource optimization, and predictable transactional behavior. + +Maintaining a single connection can reduce the overhead associated with connection establishment and teardown. A singular connection should result in quicker response times and is a more straightforward approach in applications with + +- Low to moderate traffic +- Relatively stable workloads +- Required strict control over transactions +- Required strict control over isolation levels -### Good Example - -```js - let conn - let results - try { - conn = await pool.requestConnection(); - results = await conn.execute(query); - const rows = await results?.getRows(); - rows?.should.be.ok(); - } catch (e) { - console.error(e); - should.not.exist(e); - } finally { - await results?.close(); - await pool.releaseConnection(conn); - } -``` - -### Bad Example - -```js - try { - const conn = await pool.requestConnection(); - const results = await conn.execute(query); // if we get an error here we will never clean up our connection - const rows = await results?.getRows(); - rows?.should.be.ok(); - await results?.close(); - await pool.releaseConnection(conn); - } catch (e) { - console.error(e); - should.not.exist(e); - } -``` +However, it's crucial to acknowledge that this approach might not be suitable for high-traffic applications where connection pooling shines by distributing the load and enhancing scalability. + +The decision between a singular connection and a connection pool should always be context-dependent, carefully considering factors such as expected traffic, workload volatility, and performance requirements. + +## Type Safety + +Any `try` `catch` block in which NuoDB resources are created must be followed by a `finally` block in which NuoDB resources are then cleaned up. Attempting to clean up NuoDB resources in a `try` block can lead to NuoDB resources being created and never cleaned up. diff --git a/CONNECTION_POOL.md b/CONNECTION_POOL.md index 64f0d6d..c4e73ff 100644 --- a/CONNECTION_POOL.md +++ b/CONNECTION_POOL.md @@ -8,72 +8,131 @@ Unlike establishing an individual connection for each database interaction, a co With a connection pool in place, the **NuoDB** driver can intelligently manage the lifecycle of connections, offering seamless access to the **NuoDB** database while effectively mitigating the potential for connection bottlenecks and latency. This allows developers to optimize their application's responsiveness and scalability while ensuring an efficient and streamlined interaction with the database. -## Usage +## Overview + +The lifecycle of a connection pool of the `node-nuodb` driver to a **NuoDB** database entails: + +- Initialization of the connection `Pool` +- Request connections on the `pool` +- Use the connections +- Release each connection +- Close the `pool` + +For simplicity the examples to follow will use `try/catch` semantics, although you `Promise` semantics is also permitted. + +The following is a general example requesting 2 connections on the connection pool. You would in turn manage each connection as a [single connection](./SINGLE_CONNECTION.md#execute-sql). ```js -async function () { - const myPool = new Pool({ - minAvailable: , - connectionConfig: , - maxAge: , - checkTime: , - maxLimit: , - connectionRetryLimit: , - id: , - skipCheckLivelinessOnRelease: false|true, - livelinessCheck: query| - }); - - await Pool.init() - const newConnection = await Pool.requestConnection() - await Pool.releaseConnection() - await Pool.closePool() +const connectionConfig = { + database: `test`, + password: "dba", + user: "dba", + port: "48004", + schema: "USER" +}; + +const poolConfig = { + minAvailable: 10, + connectionConfig, + maxAge: 2000, + checkTime: 10000, + maxLimit: 12, + connectionRetryLimit: 5, +}; + +async function() { + let pool = null; + + try { + pool = new Pool(poolConfig); + const conn1 = await pool.requestConnection(); + const conn2 = await pool.requestConnection(); + // use each connection + + await pool.releaseConnection(conn1); + await pool.releaseConnection(conn2); + + } catch (err) {/* handle error */} + + finally { + try { + if (pool != null) { + await pool.closePool() + } + } catch (err) {/* handle error */} + } } - ``` -## Methods -After a pool is created the user must initialize it using the init method: +## Initialize Connection Pool + +To initialize a connection pool, you must provide a pool configuration. Please review the shape of the [pool configuration](#pool-configuration) to customize for specific needs. Note, you must specify the [connection configuration](./SINGLE_CONNECTION.md#connection-properties) as for a single connection. After a pool is created the user must initialize it using the `init()` method. This will populate the pool. The pool is unavailable until this completes. ```js -await Pool.init() +const poolConfig = { + minAvailable: 10, + connectionConfig, + maxAge: 2000, + checkTime: 10000, + maxLimit: 12, + connectionRetryLimit: 5, +}; + +async function() { + const pool = new Pool(poolConfig); + await pool.init() +} ``` -This will populate the pool. The pool is unavailable until this completes. +## Request Connections -Once the pool has been successfully initialized it is ready for use. The user calls: +Once the pool has been successfully initialized it is ready for use. There are now free connections that can be requested for use. You can see the pool connections via `pool.all_connections` and `pool.free_connections`. ```js -const newConnection = await Pool.requestConnection() +const conn1 = await Pool.requestConnection(); ``` -to get a connection, this method will return a connection ready for use. +You can request multiple connections this way. Each connection can then be used as a [single connection](./SINGLE_CONNECTION.md#execute-sql) would. + +## Release Connections -Once the user has finished using a connection, it can be returned to the pool with: +Once the user has finished using a connection, it can be returned to the pool. You must pass each connection in turn desired to release. Don't forget to manage each single connection's lifecycle properly prior to requesting its release. ```js -await Pool.releaseConnection() +await pool.releaseConnection(conn1) ``` -Connections that have been released back to the connection pool should not be used anymore. -Connections that have failed in any way should be returned to the pool where they will dealt with and replaced. +Connections that have been released back to the connection pool should not be used anymore. Connections that have failed in any way should be returned to the pool where they will dealt with and replaced. + +## Pool Closure -A pool should be shutdown by calling: +Once the pool has been finished being used, it should be shutdown. ```js -await Pool.closePool() +await pool.closePool() ``` This will close all of the connections in the pool regardless of whether or not they are in use. -Users cannot manually close connections provided by the pool, and calling: -`connection.close()` -on a connection provided by the pool will have the same effect as calling: -`Pool.releaseConnection(connection)` +Users cannot manually close connections provided by the pool, and calling `connection.close()` on a connection provided by the pool will have the same effect as calling `Pool.releaseConnection(connection)`. -## Configuration +## Pool Configuration + +```js +{ + minAvailable: number, + connectionConfig: ConnectionConfig, + maxAge: number, + checkTime: number, + maxLimit: number, + connectionRetryLimit: number, + id: number, + skipCheckLivelinessOnRelease: boolean, + livelinessCheck: "query"|string +}; +``` Key | Value --- | --- @@ -88,4 +147,3 @@ Key | Value **livelinessCheck** | indicates the type of liveliness check to be performed. By default, the value is set to "query", which means a query to test the connection. If set to any value (quoted string) other than "query", it will only look to see if the NuoDB API isConnected returns true and we have not trapped a connection related exception previously. -Arguments should be provided to the pool as an object. Please refer to the Usage section for an example. diff --git a/README2.md b/README2.md index 9d5dd7f..bdeb8b6 100644 --- a/README2.md +++ b/README2.md @@ -2,7 +2,7 @@ The `node-nuodb` add-on for **Node.js** powers high performance **NuoDB** database applications. Use `node-nuodb` to connect **Node.js** to a **NuoDB** database. It supports basic features of the **NuoDB** database and **NuoDB C++** client. - Utilizing the **NuoDB** **Node.js** driver, developers can harness NuoDB's distributed architecture and dynamic scaling, while benefiting from **Node.js**' ease. This guide will help you set up, configure, and use the driver to connect seamlessly to a **NuoDB** database, empowering your applications to integrate smoothly with its advanced database technology. +Uilizing the **NuoDB** **Node.js** driver allows developers to harness NuoDB's distributed architecture and dynamic scaling, while benefiting from **Node.js**' ease. This guide will help you set up, configure, and use the driver to connect seamlessly to a **NuoDB** database, empowering your applications to integrate smoothly with its advanced database technology. ## Dependencies @@ -43,7 +43,7 @@ The `node-nuodb` add-on for **Node.js** powers high performance **NuoDB** databa ## Documentation -`node-nuodb` driver enables the capability of connection to a **NuoDB** database via a single connection or a connection pool. For further details refer to the best practices section. +`node-nuodb` driver enables the capability of connection to a **NuoDB** database via a single connection or a connection pool. For further details refer to the [best practices section](./BEST_PRACTICES.md). - [Single Connection](SINGLE_CONNECTION.md) - [Connection Pool](CONNECTION_POOL.md) diff --git a/SINGLE_CONNECTION.md b/SINGLE_CONNECTION.md index 9a7173d..db17299 100644 --- a/SINGLE_CONNECTION.md +++ b/SINGLE_CONNECTION.md @@ -1,16 +1,21 @@ -# Single connection +# Single Connection + +`node-nuodb` exposes `driver.connect()` to directly create a singular connection against a **NuoDB** database. +\ +Be aware of the scenarios where a single connection is preferable over a connection pool - [Single Connection vs Connection Pool](./BEST_PRACTICES.md#single-connection-vs-connection-pool). + +## Overview The lifecycle of a single connection of the `node-nuodb` driver to a **NuoDB** database entails: -- Initialization of the `node-nuodb` driver + +- Initialization of the `Driver` - Connection to a **NuoDB** database using configuration object - Execution of desired `SQL` - Getting the rows from the result set - Releasing memory - Closure of the connection -## Overview - The `node-nuodb` driver supports `try/catch`, `callback`, and `Promise` semantics. The following is a general example implementing the driver. It exemplifies its safe usage via `try/catch` clauses. > **NOTE** @@ -30,24 +35,33 @@ const config = { async function () { const driver = new Driver(); + let connection = null; + let results = null; try { - const connection = await driver.connect(config); - const results = await connection.execute("SELECT * FROM SYSTEM.NODES;"); + connection = await driver.connect(config); + results = await connection.execute("SELECT * FROM SYSTEM.NODES;"); const rows = await results.getRows(); // use rows - await rows.close(); + await results.close(); } catch (err) {/* handle error */} finally { - await connection.close(); + try { + if (connection != null) { + await connection.close(); + } + if (results != null) { + await results.close(); + } + } catch (err) {/* handle error */} } } ``` -### Connect +## Connect To connect to a **NuoDB** database you must provide a configuration object which includes the connection properties. Find the available connection properties in the [NuoDB documentation](https://doc.nuodb.com/nuodb/latest/reference-information/connection-properties/#nav-container-toggle). Provide each of the connection property values as a `string`. @@ -67,7 +81,7 @@ const driver = new Driver(); const connection = await driver.connect(config); ``` -### Execute SQL +## Execute SQL With a connection obtained, `execute()` a `SQL` statement against the database. If the default schema was defined in the configuration map, it is not required to specify which schema the statement is intended to target. `getRows()` to obtain the rows from the result set. ```js @@ -75,14 +89,14 @@ const results = await connection.execute("SELECT * FROM SYSTEM.NODES;"); const rows = await results.getRows(); ``` -### Cleanup Memory +## Cleanup Memory Close a results set anytime you are done using any fetch or cursor. This will release memory structures associated with those constructs. ```js -await rows.close(); +await results.close(); ``` -### Close Connection +## Close Connection Finally, `close()` the database connection. @@ -91,7 +105,7 @@ await connection.close(); ``` -### Using callbacks +## Using callbacks The following is an example of creating a single connection against a **NuoDB** database using `callback` semantics. @@ -110,6 +124,10 @@ driver.connect(config, (err, connection) => { // use rows }); + + results.close(err => { + if (err) {/* handle result set closure error */} + }) }); connection.close((err) => { @@ -118,7 +136,7 @@ driver.connect(config, (err, connection) => { }); ``` -### Using Promises +## Using Promises The following is an example of creating a single connection against a **NuoDB** database using `Promise` semantics. diff --git a/lib/driver.js b/lib/driver.js index 455c301..7f344e5 100644 --- a/lib/driver.js +++ b/lib/driver.js @@ -55,6 +55,9 @@ Driver.prototype._connect = function () { // // Promise-based: [ {}, Function ] // Async-based: [ {}, Function, Function ] +/** + * Create a single connection against a NuoDB database + */ Driver.prototype.connect = util.promisify(Driver.prototype._connect); Driver.prototype.defaults = { From d27d9813244dc8b906ea7ec0e393924ba9823d3c Mon Sep 17 00:00:00 2001 From: marco3479 Date: Wed, 30 Aug 2023 14:33:27 -0400 Subject: [PATCH 05/11] Added Retry Operations sections --- BEST_PRACTICES.md | 42 +++++++++++++++++++++++++++++++++++++++++- README2.md | 18 +++++------------- crash.log | 12 ++++++++++++ 3 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 crash.log diff --git a/BEST_PRACTICES.md b/BEST_PRACTICES.md index 9be2dbe..7938b97 100644 --- a/BEST_PRACTICES.md +++ b/BEST_PRACTICES.md @@ -18,4 +18,44 @@ The decision between a singular connection and a connection pool should always b ## Type Safety -Any `try` `catch` block in which NuoDB resources are created must be followed by a `finally` block in which NuoDB resources are then cleaned up. Attempting to clean up NuoDB resources in a `try` block can lead to NuoDB resources being created and never cleaned up. +The `node-nuodb` driver supports `try/catch`, `callback`, and `Promise` semantics. You should put guard rails that verify the availability of data and catching of any errors that could arise. For tighter type safety, you can deal with error catching at the operation level, rather than catching an errors of any operation within a block. + +Any `try` `catch` block in which **NuoDB** resources are created must be followed by a `finally` block in which NuoDB resources are then cleaned up. Attempting to clean up NuoDB resources in a `try` block can lead to NuoDB resources being created and never cleaned up. + +## Retrying Operations + +Under critical operations, it is recommended to retry operations were they to fail. You could catch the exception, clean-up any operations, and retry the operations. To allow some time margin, increase the time between retries. Here is a retry example: + +```js +async function() { + const driver = new Driver(); + let connection = null; + let results = null; + let tries = 1; + + while (tries < 6) { + + await new Promise(resolve => setTimeout(async () => { + try { + connection = await driver.connect(config); + results = await connection.execute("SELECT * FROM SYSTEM.NODE;"); + const rows = await results.getRows(); + // use rows + + } catch (err) { + console.error(err); + + } finally { + if (results != null) { + results.close().catch(err => { console.error(err) }); + } + if (connection != null) { + connection.close().catch(err => { console.error(err) }); + } + tries++; + resolve(); + } + }, 1000 * tries)); + } +} +``` \ No newline at end of file diff --git a/README2.md b/README2.md index bdeb8b6..ab954f1 100644 --- a/README2.md +++ b/README2.md @@ -43,28 +43,20 @@ Uilizing the **NuoDB** **Node.js** driver allows developers to harness NuoDB's d ## Documentation -`node-nuodb` driver enables the capability of connection to a **NuoDB** database via a single connection or a connection pool. For further details refer to the [best practices section](./BEST_PRACTICES.md). +`node-nuodb` driver enables the capability of connection to a **NuoDB** database via a single connection or a connection pool. For further details refer to the best practices section. - [Single Connection](SINGLE_CONNECTION.md) - [Connection Pool](CONNECTION_POOL.md) - [Best Practices](BEST_PRACTICES.md) -For information on using NuoDB, refer to the [documentation website][1]. - -## Related Links - -- [NuoDB Documentation][1] - +For information on using NuoDB, refer to the [documentation website](https://doc.nuodb.com/nuodb/latest/introduction-to-nuodb/). ## Help -Issues and questions about node-nuodb can be posted on [GitHub][2]. +Issues and questions about node-nuodb can be posted on [GitHub](https://github.com/nuodb/node-nuodb/issues). ## License -This package is released under the [BSD 3-Clause License][3]. +This package is released under the [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause). -[1]: https://doc.nuodb.com/nuodb/latest/introduction-to-nuodb/ -[2]: https://github.com/nuodb/node-nuodb/issues - -[3]: https://opensource.org/licenses/BSD-3-Clause + \ No newline at end of file diff --git a/crash.log b/crash.log new file mode 100644 index 0000000..2c4ab73 --- /dev/null +++ b/crash.log @@ -0,0 +1,12 @@ +PID 3216310 received SIGSEGV for address: 0x10 +/home/users/mmo30/node-nuodb.js/node-nuodb/node_modules/segfault-handler/build/Release/segfault-handler.node(+0x2f56)[0x7f8c6114df56] +/lib64/libpthread.so.0(+0x12cf0)[0x7f8c696b6cf0] +/opt/nuodb/lib64/libNuoRemote.so(+0xa3ab7)[0x7f8c61ba6ab7] +/opt/nuodb/lib64/libNuoRemote.so(+0x95ce4)[0x7f8c61b98ce4] +/opt/nuodb/lib64/libNuoRemote.so(+0x9f5bb)[0x7f8c61ba25bb] +/opt/nuodb/lib64/libNuoRemote.so(+0x86baa)[0x7f8c61b89baa] +/home/users/mmo30/node-nuodb.js/node-nuodb/build/Release/nuodb.node(_ZN5NuoJs10Connection7doCloseEv+0x23)[0x7f8c680c8353] +/home/users/mmo30/node-nuodb.js/node-nuodb/build/Release/nuodb.node(_ZN5NuoJs21ConnectionCloseWorker7ExecuteEv+0x1a)[0x7f8c680cbeda] +node[0x13bbfc4] +/lib64/libpthread.so.0(+0x81ca)[0x7f8c696ac1ca] +/lib64/libc.so.6(clone+0x43)[0x7f8c69318e73] From 7688c1f909997c50af7972b0463cfd2333de5a66 Mon Sep 17 00:00:00 2001 From: marco3479 Date: Wed, 30 Aug 2023 14:34:27 -0400 Subject: [PATCH 06/11] Replaced README with README2 --- README.md | 190 +++++++++-------------------------------------------- README2.md | 62 ----------------- 2 files changed, 32 insertions(+), 220 deletions(-) delete mode 100644 README2.md diff --git a/README.md b/README.md index 05e568b..ab954f1 100644 --- a/README.md +++ b/README.md @@ -1,188 +1,62 @@ -# node-nuodb +# **node-nuodb** - Node.js NAN C++ NuoDB Driver -Node.js NAN C++ NuoDB Driver +The `node-nuodb` add-on for **Node.js** powers high performance **NuoDB** database applications. Use `node-nuodb` to connect **Node.js** to a **NuoDB** database. It supports basic features of the **NuoDB** database and **NuoDB C++** client. -The node-nuodb add-on for Node.js powers high performance NuoDB Database applications. +Uilizing the **NuoDB** **Node.js** driver allows developers to harness NuoDB's distributed architecture and dynamic scaling, while benefiting from **Node.js**' ease. This guide will help you set up, configure, and use the driver to connect seamlessly to a **NuoDB** database, empowering your applications to integrate smoothly with its advanced database technology. -Use node-nuodb to connect Node.js to a NuoDB Database. - -node-nuodb supports basic features of the NuoDB Database and NuoDB C++ client. ## Dependencies -Node 16.13.2 +- Node 16.13.2 + ## Installation -If you have NuoDB installed locally, skip to step 4 +**NuoDB** has been designed for gradual adoption from the start, and you can use as little or as much of its capabilities as you need. To connect to a **NuoDB** database, you need to have **NuoDB** installed first. + +> **NOTE** - +> If you have **NuoDB** installed locally, skip to step 4. -1. Download the nuodb client package. +1. Download the **NuoDB** client package. The client package releases can be found here: https://github.com/nuodb/nuodb-client/releases 2. Extract the client package. - tar -xzf nuodb-client-version.lin64.tar.gz -3. Set the NUODB_CLIENT_PACKAGE environment variable. - export NUODB_CLIENT_PACKAGE=/path/to/nuodb-client-version.lin64 + `tar -xzf nuodb-client-version.lin64.tar.gz` -4. Clone the nuodb node.js driver from the git repo. - git clone https://github.com/nuodb/node-nuodb +3. Set the `NUODB_CLIENT_PACKAGE` environment variable. + + `export NUODB_CLIENT_PACKAGE=/path/to/nuodb-client-version.lin64` -5. Install the driver. - cd node-nuodb && npm i +4. Install the driver. + + `npm i node-nuodb` -6. Ensure the driver is working as intended (requires NuoDB database running named test with user dba and a password dba). - npm test +5. Ensure the driver is working as intended. Note, this assumes **NuoDB** database has `"dba"` user and `"dba"` as password. + + `npm test` -7. Import the driver into your node.js project. - var Driver = require('/path/to/driver/repo/node-nuodb'); +6. Import the driver into your **Node.js** project. + + `import { Driver } from "node-nuodb";` ## Documentation -[**Documentation is Available Online!**][3] - -# Connection Pool - -The NuoDB Node.js driver comes with a built in connection pool available. - -### Arguments - -**connectionConfig:** the configuration that will be used to create the connection in the pool, required argument. - -**minAvailable:** initial size of the pool and the number of connections the pool will aim to maintain, default of 10 is used if no argument is provided. - -**maxAge:** Amount of time from connection creation until it will age out, default of 300000ms (5 minutes) is used if no argument is provided. - -**checkTime:** how often the pool will run an internal liveliness check on free connections, default of 120000ms(2 minutes) is used if no argument is provided. If 0 is provided, the liveliness check will be disabled. - -**maxLimit:** hard cap on the amount of live connection the pool can maintain, default of 200 is used if no argument is provided. If 0, the pool will have no hard cap. - -**connectionRetryLimit:** amount of times a pool will attempt to create a connection, default of 5 is used if no argument is provided. - -**id:** optional argument to give the pool an id. As default the pool will be provided the “new Date().getTime()” at the time of its creation as its id. - -**skipCheckLivelinessOnRelease:** turns off liveliness checks on connections when they are released back to the pool, which is different than the checkTime that is used for aging purposes. The default is false, meaning we will perform a liveliness check when a connection is returned to the pool. - -**livelinessCheck:** indicates the type of liveliness check to be performed. By default, the value is set to 'query', which means a query to test the connection. If set to any value (quoted string) other than 'query', it will only look to see if the NuoDB API isConnected returns true and we have not trapped a connection related exception previously. - -Arguments should be provided to the pool as an object. Please refer to the Usage section for an example. - -### Usage - -``` -const myPool = new Pool({ - minAvailable: , - connectionConfig: , - maxAge: , - checkTime: , - maxLimit: , - connectionRetryLimit: , - id: , - skipCheckLivelinessOnRelease: false|true, - livelinessCheck: query| -}) -``` - -### Methods - -After a pool is created the user must initialize it using the init method: - -``` -await Pool.init() -``` - -This will populate the pool. The pool is unavailable until this completes. - -Once the pool has been successfully initialized it is ready for use. The user calls: - -``` -const newConnection = await Pool.requestConnection() -``` - -to get a connection, this method will return a connection ready for use. - -Once the user has finished using a connection, it can be returned to the pool with: - -``` -await Pool.releaseConnection() -``` - -Connections that have been released back to the connection pool should not be used anymore. -Connections that have failed in any way should be returned to the pool where they will dealt with and replaced. - -A pool should be shutdown by calling: - -``` -await Pool.closePool() -``` - -This will close all of the connections in the pool regardless of whether or not they are in use. - -Users cannot manually close connections provided by the pool, and calling: -`connection.close()` -on a connection provided by the pool will have the same effect as calling: -`Pool.releaseConnection(connection)` - -## Related Links - -- [NuoDB Multiplexer][5] -- [NuoDB Node.js Driver Documentation][3] -- [NuoDB Node.js Driver Docker Sample Express Application][4] - -## Examples (EXPERIMENTAL) - -See branch [examples](https://github.com/nuodb/node-nuodb/tree/examples). - -## Best Practices - -Any `try` `catch` block in which NuoDB resources are created must be followed by a `finally` block in which NuoDB resources are then cleaned up. Attempting to clean up NuoDB resources in a `try` block can lead to NuoDB resources being created and never cleaned up. - -### Good Example - -``` - let conn - let results - try { - conn = await pool.requestConnection(); - results = await conn.execute(query); - const rows = await results?.getRows(); - rows?.should.be.ok(); - } catch (e) { - console.error(e); - should.not.exist(e); - } finally { - await results?.close(); - await pool.releaseConnection(conn); - } -``` + +`node-nuodb` driver enables the capability of connection to a **NuoDB** database via a single connection or a connection pool. For further details refer to the best practices section. -### Bad Example +- [Single Connection](SINGLE_CONNECTION.md) +- [Connection Pool](CONNECTION_POOL.md) +- [Best Practices](BEST_PRACTICES.md) -``` - try { - const conn = await pool.requestConnection(); - const results = await conn.execute(query); // if we get an error here we will never clean up our connection - const rows = await results?.getRows(); - rows?.should.be.ok(); - await results?.close(); - await pool.releaseConnection(conn); - } catch (e) { - console.error(e); - should.not.exist(e); - } -``` +For information on using NuoDB, refer to the [documentation website](https://doc.nuodb.com/nuodb/latest/introduction-to-nuodb/). ## Help -Issues and questions about node-nuodb can be posted on [GitHub][2]. +Issues and questions about node-nuodb can be posted on [GitHub](https://github.com/nuodb/node-nuodb/issues). ## License -This module is released under the [BSD 3-Clause License][1]. +This package is released under the [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause). -[1]: https://opensource.org/licenses/BSD-3-Clause -[2]: https://github.com/nuodb/node-nuodb/issues -[3]: https://nuodb.github.io/node-nuodb/ -[4]: https://github.com/nuodb/node-nuodb-demo -[5]: https://github.com/nuodb/node-multiplexer -[44]: https://github.com/nodejs/abi-stable-node-addon-examples + \ No newline at end of file diff --git a/README2.md b/README2.md deleted file mode 100644 index ab954f1..0000000 --- a/README2.md +++ /dev/null @@ -1,62 +0,0 @@ -# **node-nuodb** - Node.js NAN C++ NuoDB Driver - -The `node-nuodb` add-on for **Node.js** powers high performance **NuoDB** database applications. Use `node-nuodb` to connect **Node.js** to a **NuoDB** database. It supports basic features of the **NuoDB** database and **NuoDB C++** client. - -Uilizing the **NuoDB** **Node.js** driver allows developers to harness NuoDB's distributed architecture and dynamic scaling, while benefiting from **Node.js**' ease. This guide will help you set up, configure, and use the driver to connect seamlessly to a **NuoDB** database, empowering your applications to integrate smoothly with its advanced database technology. - - -## Dependencies - -- Node 16.13.2 - - -## Installation - -**NuoDB** has been designed for gradual adoption from the start, and you can use as little or as much of its capabilities as you need. To connect to a **NuoDB** database, you need to have **NuoDB** installed first. - -> **NOTE** - -> If you have **NuoDB** installed locally, skip to step 4. - -1. Download the **NuoDB** client package. - The client package releases can be found here: https://github.com/nuodb/nuodb-client/releases - -2. Extract the client package. - - `tar -xzf nuodb-client-version.lin64.tar.gz` - -3. Set the `NUODB_CLIENT_PACKAGE` environment variable. - - `export NUODB_CLIENT_PACKAGE=/path/to/nuodb-client-version.lin64` - -4. Install the driver. - - `npm i node-nuodb` - -5. Ensure the driver is working as intended. Note, this assumes **NuoDB** database has `"dba"` user and `"dba"` as password. - - `npm test` - -6. Import the driver into your **Node.js** project. - - `import { Driver } from "node-nuodb";` - -## Documentation - - -`node-nuodb` driver enables the capability of connection to a **NuoDB** database via a single connection or a connection pool. For further details refer to the best practices section. - -- [Single Connection](SINGLE_CONNECTION.md) -- [Connection Pool](CONNECTION_POOL.md) -- [Best Practices](BEST_PRACTICES.md) - -For information on using NuoDB, refer to the [documentation website](https://doc.nuodb.com/nuodb/latest/introduction-to-nuodb/). - -## Help - -Issues and questions about node-nuodb can be posted on [GitHub](https://github.com/nuodb/node-nuodb/issues). - -## License - -This package is released under the [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause). - - \ No newline at end of file From c791edbf2ddab1b8fe69aa5cbd12cd59e162da23 Mon Sep 17 00:00:00 2001 From: Marco Mongalo III <69126746+marco3479@users.noreply.github.com> Date: Wed, 30 Aug 2023 14:36:36 -0400 Subject: [PATCH 07/11] Delete doc/README.md --- doc/README.md | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 doc/README.md diff --git a/doc/README.md b/doc/README.md deleted file mode 100644 index 0a86d8f..0000000 --- a/doc/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Documentation - -## Table of Contents - -1. [Approach and Design][0] - -[0]: APPROACH.md From fdc5f9b7ffc76e3f59388a8850ac91aa6e4d421a Mon Sep 17 00:00:00 2001 From: marco3479 Date: Wed, 30 Aug 2023 14:38:47 -0400 Subject: [PATCH 08/11] Added details --- .gitignore | 3 +- crash.log | 12 ----- doc/APPROACH.md | 122 ------------------------------------------------ package.json | 2 +- 4 files changed, 3 insertions(+), 136 deletions(-) delete mode 100644 crash.log delete mode 100644 doc/APPROACH.md diff --git a/.gitignore b/.gitignore index f562e1c..2c1bc78 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ vol2/ build/ node_modules/ -test/t.js \ No newline at end of file +test/t.js +crash.log diff --git a/crash.log b/crash.log deleted file mode 100644 index 2c4ab73..0000000 --- a/crash.log +++ /dev/null @@ -1,12 +0,0 @@ -PID 3216310 received SIGSEGV for address: 0x10 -/home/users/mmo30/node-nuodb.js/node-nuodb/node_modules/segfault-handler/build/Release/segfault-handler.node(+0x2f56)[0x7f8c6114df56] -/lib64/libpthread.so.0(+0x12cf0)[0x7f8c696b6cf0] -/opt/nuodb/lib64/libNuoRemote.so(+0xa3ab7)[0x7f8c61ba6ab7] -/opt/nuodb/lib64/libNuoRemote.so(+0x95ce4)[0x7f8c61b98ce4] -/opt/nuodb/lib64/libNuoRemote.so(+0x9f5bb)[0x7f8c61ba25bb] -/opt/nuodb/lib64/libNuoRemote.so(+0x86baa)[0x7f8c61b89baa] -/home/users/mmo30/node-nuodb.js/node-nuodb/build/Release/nuodb.node(_ZN5NuoJs10Connection7doCloseEv+0x23)[0x7f8c680c8353] -/home/users/mmo30/node-nuodb.js/node-nuodb/build/Release/nuodb.node(_ZN5NuoJs21ConnectionCloseWorker7ExecuteEv+0x1a)[0x7f8c680cbeda] -node[0x13bbfc4] -/lib64/libpthread.so.0(+0x81ca)[0x7f8c696ac1ca] -/lib64/libc.so.6(clone+0x43)[0x7f8c69318e73] diff --git a/doc/APPROACH.md b/doc/APPROACH.md deleted file mode 100644 index caa2e32..0000000 --- a/doc/APPROACH.md +++ /dev/null @@ -1,122 +0,0 @@ -# Approach: Design & Trade-offs - -## Outcomes - -The outcomes for the project were the following: - -- a driver that is portable between different versions of Node.js -- a driver that provides an API that is natural to the Node.js developer (considers programming idioms) -- a driver that is simply shippable and seamlessly fits into their existing Docker-based SDLC -- simplify maintenance to testing of the driver -- predictable, measurable, quality using existing Node.js tooling, or Linux tooling -- open-source, and deliverable to npmjs.org - -The following are non-requirements: - -- it is not a requirement for customers to compile the driver themselves (though they certainly can do so) -- support for Mac or Windows - -## Features - -The features to accomplish these were: - -- use of Docker-based multi-staged builds to remove driver developer environment dependencies; codify all developer dependencies in Dockerfiles -- use of Mocha.js as the unit testing framework of choice in the Node.js world -- use of Linux Valgrind to detect memory leaks -- deliver a demo application to illustrate best practice, and some coding idioms -- use of GNU make for the top-level driver-developer build system, and a comprehensive, documented, set of targets for each development step, inclusive of starting up, shutting down, and working with, a NuoDB cluster -- integration with the Google V8 engine using the "Native Abstractions for Node.js" (NAN) API, which abstracts away differences between different versions of the v8 Engine. - -## Trade-Off: Google V8 Engine APIs - -The first tier choice and trade-off involved choosing with abstraction layer to use for Node.js, or more specifically, for the v8 Engine which is the ECMAScript engine at its kernel. - -There are multiple ways of working with the v8 engine: - -- use the v8 engine APIs directly, and deal with version incompatibilities yourself (viable option, it's what Electron does, for example), but requires more time investment -- use the NAN API, which is what is most commonly used by integrators, including Oracle, MySQL, Postgres, etc; this option supports a vast range of v8 Engine APIs, from Node.js version 0.10, up until the latest version 10. -- use the Node Addon API (N-API) and its C++ wrappers; which only supports Node.js version 8 and newer. This is actually the Node.js ABI, beta in version 8, and officially released in version 10. - -Originally I tried to use N-API. Given it's the official ABI for Node.js now, the thought was that it would provide the longest term, most stable, approach for implementing a driver. However, a number of issues mounted, which ultimately led to a decision to abandon N-API: - -- 15% process failure rates, asserts being triggered down in the NuoDB Mutex.cpp class -- massive memory leaks -- no purely native way of dealing with Date/Time without dispatch back into the JS engine to eval a Date class constructor (performance implications) -- reference counting issues in the ABI, possible SIGSEGVs - -At the six week mark, given the mounting issues with the ABI, I decided to pivot to using NAN. The entire framework, minus NuoDB-specific code, was swapped out. Net-result: zero failures, zero memory leaks. A decision that paid out. - -## Trade-Off: Language Evolution & Design - -It was desireable to make the user API for the driver natural for the Node.js, and Javascript, user. This meant that basic idioms, intrinsic to Javascript development, must be supported. Of these the following were all paramount, and were chosen to be supported: - -- **callbacks** - Node.js has a single threaded main-event loop, but long running activities can be made asynchronous; ideal for operations such as those involving databases, sockets, IO, ... This is accomplished with the **callback-based** approach commonly seen throughout Javascript code. -- **async/await** - sometimes the callback model becomes a burden, some people call this *callback-hell* - where when you're dealing with heavily nested objects, each of which has its own async APIs, the outcome is heavily nested callback hierarchies that are difficult to read and debug (see examples in the tests). A way to keep asynchronous nature of your code, while being able to code in a way that looks synchronous (where it's easy to reason about), is by declaring a encapsulating function (a scope) to be `async` and then when calling async methods on objects within its scope, perform the call with an `await` keyword present (see online for examples, or the numerous examples herein); behind the scenes the call is scheduled to be performed and the result is returned to the caller as a return value (no need to write a callback which acts as a receiver of the result) -- **promises** - another model for dealing with callback-hell, a promise is an IOU for a result; the benefit of IOUs is that you can schedule as many as you wish, then later redeem that IOU for the actual result. The latter operation is a blocking operation. The power of promises is that you can combine long chains of them through a library called `async` to codify serial, parallel, or other interesting patterns. - -A promise is a linguistic wrapper over the existing callback mechanisms. In effect what promises do is add one extra callback to the tail of all calls. Given a mode where methods have non-callback arguments first, and the callback last, and the callback is always an error-first callback, the promise infrastructure adds one additional callback to the argument list; this callback is used internally within Javascript to handle IOUs, allowing users to redeem the IOUs at a later time for the result. This observation is important as we will detail in a moment. But suffice to say at this point, promise support is added at the Javascript layer using the built-in `promisify` utility, which you see used throughout the `lib` directory of `.js` files. The **trade-off here** was between coding promises in C++ (which you can do) versus integrating them at the Javascript layer. A choice was made to integrate promises at the Javascript layer, hence when you look at the JS code you will see calls to promisify calls. - -The support for async/await is at the language level; so long as your API supports callbacks, you can naturally use the async/await keywords. However, when integrating Promises into the API, care must be exercised so that dispatch of callbacks are performed using the original callbacks, not those introduced by the introduction of promises. When dispatching to the native C++ layer, the C++ code must be careful to NOT treat the last argument of the argument list as the callback to dispatch results back too, for doing so would cause an infinite loop (stack overflow) within the Promise code, instead the C++ code needs to walk through the argument list in-order to find the first Function object, and it's this object that is the callback to return results to. - -## Node.js / v8 Threading Model - -An important point mentioned earlier, Node.js is single-threaded -- well, sort of... It has only a single thread acting within its main event-loop, but does support worker threads. Implications are these... - -- all interaction with JS objects, the runtime, etc MUST be made from the main event loop thread; all methods in the C++ code that are declared as a **NAN_METHOD** are methods that can be dispatched to from JS (provided they are first registered with the runtime (see **NAN_MODULE_INIT**). These methods may interact with V8. -- worker threads can handle async work, and work is scheduled using the AsyncWorker API; doing so will place work onto a `libuv` queue. The `execute` function for `libuv` is the async (database) logic and MUST NOT call any V8 API or NAN wrapper API. The associated `after-execute` method can interact with V8 and is used to dispatch results back to the user through the provided callback (if any). The basic model is as follows: - - the NAN_METHOD parses any inputs, translating them into non V8 objects (pure C++ objects), and creates an AsyncWorker object, and queues the work - - the execute method executes against the database, and sets up return values (pure C++ objects) - - the after-execute method is called automatically, and the results are translated into V8 objects (String, Number, Date, etc), and the given callback is called, passing the results as its second argument - - if an error occurs during the execute call, a different `after-*` method is called, allowing you to raise a Javascript exception with some meaningful error message - -This overall model of main-thread queueing work, the worker doing the work, then the worker dispatching the results back to the main event loop thread, you will see repeated throughout the code base. - -## API Design - -Apart from supporting callbacks, async/await, and promises, the API is built around the following model: - -- **Driver** : has a method to create and return Connection objects -- **Connection** : has a method to execute and return ResultSet objects -- **ResultSet** : method to iterate over rows - -See the `lib` directory to see wrappers for each of these types. - -In addition to creating Connection objects, a Driver (in the JS code) also provides logic to pull configuration, optionally from a hash passed into the `connect` method, which incidentally is supplemented (overridden) with values pulled from the environment; users may provide all connection configuration parameters as environment variables or through a static hash. It is recommended, for security reasons, and ease of integration with the Docker model, to use environment variables instead. - -An additional feature of the API are two configurable means for how results are returned, and specifically, whether each row is returned as an array of values, or as a Javascript Object. If it's the latter, for each column name in the result set, a Javascript Object key-value pair is added to the JS object. With the array-based approach, users are presented with an array of values. - -## Docker-based Builds - -As we said earlier, the entire build and test process is encapsulated behind a Docker veneer. To accomplish this is straight-forward, we use Docker multi-stage builds -- which decisively require a recent version of Docker. In `dockers/centos/Dockerfile` you will see three stages of builds, each building upon another. The net benefit of this is that we can codify all the tooling inside Docker, and also when preparing release images, copy from base build images only those artifacts meant for distribution. A natural outcome of this approach is actually smaller image sizes, as no intermediate (and duplicate) layers are introduced during the **COPY** instruction. So, in theory, the only things needed for local development are as follows: - -- **git** : to checkout the project -- **make** : to build the project -- **docker** : to build and test the driver itself, and build release Docker images - -## Docker Deliverables - -Lastly, there are three Docker deliverables to Docker Hub... - -- **nuodb/node:{8|10}-centos** - there are no CentOS Node.js Dockers in official publication, these are forks of official Docker distros' but built with CentOS for our customers that demand them -- **nuodb/node-nuodb:{8|10|latest}[-centos]** - the Docker that includes the Node.js driver, a Docker image customers may extend with their applications -- nuodb/node-nuodb:{8|10}-onbuild - ONBUILD variants of the driver image. - -More detail is available in the [online documentation][0] on usage of the API and of the Dockers distributed. - -[0]: https://nuodb.github.io/node-nuodb/ - -## Internal Build Process - -We said that we wrap the whole build process using Docker, but what do the Dockers themselves run? - -In the world of Node.js there are two fundamental tools related to packaging, dependency management, and for compilation. The tools are: - -- `node-gyp` : for compiling native code, e.g. C/C++ -- `npm` : for identifying the package, and for declaring dependencies - -For each of these there is a file present in projects: - -- `node-gyp`: `"binding.gyp"` -- `npm`: `"package.json"` - -For the uninitiated, best to look at online documentation, or peek at the files in this project; it's fairly straight-forward though. \ No newline at end of file diff --git a/package.json b/package.json index ebd4788..7255db3 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "nuodb-client", + "name": "node-nuodb", "author": "NuoDB, Inc.", "description": "The official NuoDB driver for Node.js. Provides a high-level SQL API on top of the NuoDB Node.js Addon.", "license": "Apache-2.0", From c5a36ca83f79a8f5c3c8bc66e9291f54e8d35b6f Mon Sep 17 00:00:00 2001 From: marco3479 Date: Thu, 31 Aug 2023 12:14:32 -0400 Subject: [PATCH 09/11] Addressed some PR comments --- BEST_PRACTICES.md | 6 +++--- CONNECTION_POOL.md | 8 ++++---- SINGLE_CONNECTION.md | 14 +++++++------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/BEST_PRACTICES.md b/BEST_PRACTICES.md index 7938b97..5d0fcba 100644 --- a/BEST_PRACTICES.md +++ b/BEST_PRACTICES.md @@ -3,9 +3,9 @@ ## Single Connection vs Connection Pool -While connection pooling offers advantages in managing multiple concurrent connections efficiently, a singular connection might be preferred when dealing with specific use cases that prioritize simplicity, resource optimization, and predictable transactional behavior. +While connection pooling offers advantages in managing multiple concurrent connections efficiently, a single connection might be preferred when dealing with specific use cases that prioritize simplicity, resource optimization, and predictable transactional behavior. -Maintaining a single connection can reduce the overhead associated with connection establishment and teardown. A singular connection should result in quicker response times and is a more straightforward approach in applications with +Maintaining a single connection can reduce the overhead associated with connection establishment and teardown. A single connection should result in quicker response times and is a more straightforward approach in applications with - Low to moderate traffic - Relatively stable workloads @@ -14,7 +14,7 @@ Maintaining a single connection can reduce the overhead associated with connecti However, it's crucial to acknowledge that this approach might not be suitable for high-traffic applications where connection pooling shines by distributing the load and enhancing scalability. -The decision between a singular connection and a connection pool should always be context-dependent, carefully considering factors such as expected traffic, workload volatility, and performance requirements. +The decision between a single connection and a connection pool should always be context-dependent, carefully considering factors such as expected traffic, workload volatility, and performance requirements. ## Type Safety diff --git a/CONNECTION_POOL.md b/CONNECTION_POOL.md index c4e73ff..fe2f982 100644 --- a/CONNECTION_POOL.md +++ b/CONNECTION_POOL.md @@ -13,12 +13,12 @@ With a connection pool in place, the **NuoDB** driver can intelligently manage t The lifecycle of a connection pool of the `node-nuodb` driver to a **NuoDB** database entails: - Initialization of the connection `Pool` -- Request connections on the `pool` +- Request connections from the `pool` - Use the connections - Release each connection - Close the `pool` -For simplicity the examples to follow will use `try/catch` semantics, although you `Promise` semantics is also permitted. +For simplicity the examples to follow will use `try/catch` semantics, although `Promise` semantics is also permitted. The following is a general example requesting 2 connections on the connection pool. You would in turn manage each connection as a [single connection](./SINGLE_CONNECTION.md#execute-sql). @@ -97,7 +97,7 @@ You can request multiple connections this way. Each connection can then be used ## Release Connections -Once the user has finished using a connection, it can be returned to the pool. You must pass each connection in turn desired to release. Don't forget to manage each single connection's lifecycle properly prior to requesting its release. +Once the user has finished using a connection, it can be returned to the pool. You must release a single connection at a time. Don't forget to manage each single connection's lifecycle properly prior to requesting its release. ```js await pool.releaseConnection(conn1) @@ -144,6 +144,6 @@ Key | Value **connectionRetryLimit** | amount of times a pool will attempt to create a connection, default of 5 is used if no argument is provided. **id** | optional argument to give the pool an id. As default the pool will be provided the “new Date().getTime()” at the time of its creation as its id. **skipCheckLivelinessOnRelease** | turns off liveliness checks on connections when they are released back to the pool, which is different than the checkTime that is used for aging purposes. The default is false, meaning we will perform a liveliness check when a connection is returned to the pool. -**livelinessCheck** | indicates the type of liveliness check to be performed. By default, the value is set to "query", which means a query to test the connection. If set to any value (quoted string) other than "query", it will only look to see if the NuoDB API isConnected returns true and we have not trapped a connection related exception previously. +**livelinessCheck** | indicates the type of liveliness check to be performed. By default, the value is set to "query", which means a query is used to test the connection. If set to any value (quoted string) other than "query", it will only look to see if the NuoDB API isConnected returns true and we have not trapped a connection related exception previously. diff --git a/SINGLE_CONNECTION.md b/SINGLE_CONNECTION.md index db17299..b88bdf5 100644 --- a/SINGLE_CONNECTION.md +++ b/SINGLE_CONNECTION.md @@ -1,7 +1,7 @@ # Single Connection -`node-nuodb` exposes `driver.connect()` to directly create a singular connection against a **NuoDB** database. +`node-nuodb` exposes `driver.connect()` to directly create a single connection against a **NuoDB** database. \ Be aware of the scenarios where a single connection is preferable over a connection pool - [Single Connection vs Connection Pool](./BEST_PRACTICES.md#single-connection-vs-connection-pool). @@ -91,7 +91,7 @@ const rows = await results.getRows(); ## Cleanup Memory -Close a results set anytime you are done using any fetch or cursor. This will release memory structures associated with those constructs. +Close a result set anytime you are done using any fetch or cursor. This will release memory structures associated with those constructs. ```js await results.close(); ``` @@ -175,14 +175,14 @@ Key | Value allowSRPFallback=[ true \| false ] | Allows the driver to fall back to SRP if the TLS connection fails (when used in combination with trustStore ). Required (set to true) during rolling upgrade of the security protocol. ciphers=cipherlist | Enables the client to provide one or more appropriate ciphers for encrypting the network connection to the database. If this property is not specified the default ciphers AES-256-CTR and RC4 are enabled. The server chooses a preferred cipher from this list. If no matching cipher is found, the connection will be refused. The cipherlist is comma-separated and cipher names are case-sensitive and must be provided exactly as shown. The full list of available ciphers are AES-256-CTR, RC4, and None. clientInfo=info | Arbitrary information about the connecting client. This is available in the CLIENTINFO column of the SYSTEM.CONNECTIONS and SYSTEM.LOCALCONNECTIONS system tables. -clientProcessID=id | The process ID (pid) of the connecting client. The client may set this property only if not already set by the driver. The .NET and Python drivers set this for the client. The client setting of this property does not overrides the driver setting of this property. The clientProcessId is then available in the CLIENTPROCESSID column of the SYSTEM.CONNECTIONS and SYSTEM.LOCALCONNECTIONS system tables. -direct=[ true \| false ] | Connect directly to TE(s) rather than via the AP(s). If not specified, direct defaults to false and connections are made via the AP(s) specified in the connection URL. When direct=true, the client connection is made directly with a TE. The hosts and port numbers in the connection URL are assumed to specify the hosts and port numbers of TE processes. The use of the direct connection property is supported for nuosql and the JDBC, C, C++, and Go drivers. When using nuosql, it supports an equivalent --direct option. Where possible, direct connection should be made using the load-balancing capability of the APs. This connection property is useful when connecting external SQL applications directly to TEs that are running on a different network - such as in the Cloud, on Kubernetes clusters, and in other containerized deployments (such as Docker) or via SSH tunneling. For more details, see Direct TE Connections. Although it is for JDBC, the basic principles apply to all drivers supporting direct. -idle-timeout=number | The maximum time (in seconds) which indicates how long idle connections are left open. Although the IDLE_CONNECTION_TIMEOUT system property is a global setting for timing out idle connections, you can use this connection property to override the system property on a per connection basis. By default, idle-timeout is set to -1, meaning that the global setting is used. If you set a value greater than 0, this property overrides any value set for IDLE_CONNECTION_TIMEOUT. You may also set a value of 0 to specifically disable this property for the connection. Any time a client connection is terminated for being idle for too long, a message will be logged under the net category. For more information on IDLE_CONNECTION_TIMEOUT, see SQL System Properties. -isolation=level | The default transaction isolation level for the connection to use. Isolation levels supported are consistent_read and read_committed. Note that these values are case sensitive. For more information, see CONSISTENT READ and READ COMMITTED. +clientProcessID=id | The process ID (pid) of the connecting client. The clientProcessId is available in the CLIENTPROCESSID column of the SYSTEM.CONNECTIONS and SYSTEM.LOCALCONNECTIONS system tables. +direct=[ true \| false ] | Connect directly to TE(s) rather than via the AP(s). If not specified, direct defaults to false and connections are made via the AP(s) specified in the connection URL. When direct=true, the client connection is made directly with a TE. The hosts and port numbers in the connection URL are assumed to specify the hosts and port numbers of TE processes. The use of the direct connection property is supported for nuosql and the JDBC, C, C++, and Go drivers. When using nuosql, it supports an equivalent --direct option. Where possible, direct connection should be made using the load-balancing capability of the APs. This connection property is useful when connecting external SQL applications directly to TEs that are running on a different network - such as in the Cloud, on Kubernetes clusters, and in other containerized deployments (such as Docker) or via SSH tunneling. +idle-timeout=number | The maximum time (in seconds) which indicates how long idle connections are left open. Although the IDLE_CONNECTION_TIMEOUT system property is a global setting for timing out idle connections, you can use this connection property to override the system property on a per connection basis. By default, idle-timeout is set to -1, meaning that the global setting is used. If you set a value greater than 0, this property overrides any value set for IDLE_CONNECTION_TIMEOUT. You may also set a value of 0 to specifically disable this property for the connection. Any time a client connection is terminated for being idle for too long, a message will be logged under the net category. +isolation=level | The default transaction isolation level for the connection to use. Isolation levels supported are consistent_read and read_committed. Note that these values are case sensitive. keepAlive=[ true \| false ] | Allows enabling of TCP KeepAlive on the connection from client to Transaction Engine. If not specified, keepAlive defaults to false. When keepAlive=true, the driver enables TCP KeepAlive on the socket that it opens to the Transaction Engine. LBPolicy=valueA | From the client application, this property allows selective load balancing across Transaction Engines. For information on using LBPolicy, see Load Balancer Policies. LBQuery=\(\) | From the client application, this property allows selective load balancing across Transaction Engines. For information on using LBQuery, see Load Balancer Policies. -lock-wait-timeout=sec | Configures lock wait time (in seconds) when establishing a new connection. For more information, see About the NuoDB SQL Configuration File. The default is equal to the system property DEFAULT_LOCK_WAIT_TIMEOUT. For more information, see SQL System Properties. +lock-wait-timeout=sec | Configures lock wait time (in seconds) when establishing a new connection. memory-limit-bytes=size | The memory limit (per connection) in bytes for all blocking SQL engine operations: Hash-grouping, sorting, sorting via priority queue for limit, distinct (via hash-grouping), union, listagg, table functions, and stored procedures returning result set(s) that accumulate data - in main memory. To run statements with a memory limit different from the system-wide limit, start a new connection with this connection property set to the per-connection limit. If you do not define a value for memory-limit-bytes, the value set for the DEFAULT_CONNECTION_MEMORY_LIMIT system property is the default setting used. password=pwd | The password for the user account used to connect to the database. PreferInternalAddress=[ true \| false ] | Use internal address and port for TE, as specified by the external-address and external-port process labels. Default is false (disabled). For a detailed explanation, see Controlling Connectivity, a special case of using Load Balancer Policies with labels. From 53380df4e05c42da1ea5117aff47c7743cad2f97 Mon Sep 17 00:00:00 2001 From: marco3479 Date: Wed, 6 Sep 2023 09:49:23 -0400 Subject: [PATCH 10/11] Resolved review comments --- README.md | 5 ----- SINGLE_CONNECTION.md | 6 +++--- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index ab954f1..9efa950 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,6 @@ The `node-nuodb` add-on for **Node.js** powers high performance **NuoDB** databa Uilizing the **NuoDB** **Node.js** driver allows developers to harness NuoDB's distributed architecture and dynamic scaling, while benefiting from **Node.js**' ease. This guide will help you set up, configure, and use the driver to connect seamlessly to a **NuoDB** database, empowering your applications to integrate smoothly with its advanced database technology. -## Dependencies - -- Node 16.13.2 - - ## Installation **NuoDB** has been designed for gradual adoption from the start, and you can use as little or as much of its capabilities as you need. To connect to a **NuoDB** database, you need to have **NuoDB** installed first. diff --git a/SINGLE_CONNECTION.md b/SINGLE_CONNECTION.md index b88bdf5..26cd885 100644 --- a/SINGLE_CONNECTION.md +++ b/SINGLE_CONNECTION.md @@ -180,12 +180,12 @@ direct=[ true \| false ] | Connect directly to TE(s) rather than via the AP(s). idle-timeout=number | The maximum time (in seconds) which indicates how long idle connections are left open. Although the IDLE_CONNECTION_TIMEOUT system property is a global setting for timing out idle connections, you can use this connection property to override the system property on a per connection basis. By default, idle-timeout is set to -1, meaning that the global setting is used. If you set a value greater than 0, this property overrides any value set for IDLE_CONNECTION_TIMEOUT. You may also set a value of 0 to specifically disable this property for the connection. Any time a client connection is terminated for being idle for too long, a message will be logged under the net category. isolation=level | The default transaction isolation level for the connection to use. Isolation levels supported are consistent_read and read_committed. Note that these values are case sensitive. keepAlive=[ true \| false ] | Allows enabling of TCP KeepAlive on the connection from client to Transaction Engine. If not specified, keepAlive defaults to false. When keepAlive=true, the driver enables TCP KeepAlive on the socket that it opens to the Transaction Engine. -LBPolicy=valueA | From the client application, this property allows selective load balancing across Transaction Engines. For information on using LBPolicy, see Load Balancer Policies. -LBQuery=\(\) | From the client application, this property allows selective load balancing across Transaction Engines. For information on using LBQuery, see Load Balancer Policies. +LBPolicy=valueA | From the client application, this property allows selective load balancing across Transaction Engines. For information on using LBPolicy, see [Load Balancer Policies](https://doc.nuodb.com/nuodb/latest/client-development/load-balancer-policies/). +LBQuery=\(\) | From the client application, this property allows selective load balancing across Transaction Engines. For information on using LBQuery, see [Load Balancer Policies](https://doc.nuodb.com/nuodb/latest/client-development/load-balancer-policies/). lock-wait-timeout=sec | Configures lock wait time (in seconds) when establishing a new connection. memory-limit-bytes=size | The memory limit (per connection) in bytes for all blocking SQL engine operations: Hash-grouping, sorting, sorting via priority queue for limit, distinct (via hash-grouping), union, listagg, table functions, and stored procedures returning result set(s) that accumulate data - in main memory. To run statements with a memory limit different from the system-wide limit, start a new connection with this connection property set to the per-connection limit. If you do not define a value for memory-limit-bytes, the value set for the DEFAULT_CONNECTION_MEMORY_LIMIT system property is the default setting used. password=pwd | The password for the user account used to connect to the database. -PreferInternalAddress=[ true \| false ] | Use internal address and port for TE, as specified by the external-address and external-port process labels. Default is false (disabled). For a detailed explanation, see Controlling Connectivity, a special case of using Load Balancer Policies with labels. +PreferInternalAddress=[ true \| false ] | Use internal address and port for TE, as specified by the external-address and external-port process labels. Default is false (disabled). For a detailed explanation, see [Controlling Connectivity](https://doc.nuodb.com/nuodb/latest/client-development/load-balancer-policies/#controlling-connectivity), a special case of using Load Balancer Policies with labels. rollbackMode=[ procedure \| transaction \| off ] | Controls the behavior of transactions executed inside a stored procedure. The default is off. See About Implicit and Explicit Transactions. schema=name | The default schema that the connection should use when objects (such as tables and views) are not fully qualified. TimeZone=timezone | The default time zone for the connection to use (this is also known as the session time zone). If not specified, the application’s default time zone is used. From 03f96fd4642efc423c8b78eaebaab9198b37478e Mon Sep 17 00:00:00 2001 From: marco3479 Date: Wed, 6 Sep 2023 10:02:44 -0400 Subject: [PATCH 11/11] Minor Best Practices section Edit --- BEST_PRACTICES.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/BEST_PRACTICES.md b/BEST_PRACTICES.md index 5d0fcba..aad8793 100644 --- a/BEST_PRACTICES.md +++ b/BEST_PRACTICES.md @@ -3,9 +3,7 @@ ## Single Connection vs Connection Pool -While connection pooling offers advantages in managing multiple concurrent connections efficiently, a single connection might be preferred when dealing with specific use cases that prioritize simplicity, resource optimization, and predictable transactional behavior. - -Maintaining a single connection can reduce the overhead associated with connection establishment and teardown. A single connection should result in quicker response times and is a more straightforward approach in applications with +While connection pooling offers advantages in managing multiple concurrent connections efficiently, a single connection might be preferred when dealing with specific use cases that prioritize simplicity, resource optimization, and predictable transactional behavior. A single connection should result in quicker response times and is a more straightforward approach in applications with - Low to moderate traffic - Relatively stable workloads