From 92fd173e116578af2790c14f2ed5ad94c6a26002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?javier=20ram=C3=ADrez?= Date: Thu, 25 Jul 2024 18:02:25 +0200 Subject: [PATCH] [docs] Changed code examples and bumped dev dependency (#35) * changed code examples * changing examples to use at with a date. Bumped dependency for audit * Update README.md consistent quotes Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> * Update README.md consistent quotes Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> * Update README.md consistent quotes Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> * Update README.md consistent quotes Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> * Update README.md consistent quotes Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> * Update README.md consistent quotes Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> * Update README.md consistent quotes Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> * Update README.md consistent quotes Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> * Update examples/workers.js consistent quotes Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> * Update examples/workers.js consistent quotes Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> * Update README.md consistent quotes Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> * Update README.md consistent quotes Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> * Update README.md consistent quotes Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> * Update README.md consistent quotes Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> * Update README.md consistent quotes Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> * Update README.md consistent quotes Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> --------- Co-authored-by: Andrei Pechkurov <37772591+puzpuzpuz@users.noreply.github.com> --- README.md | 135 ++++++++++++++++++++++-------------------- examples/auth.js | 44 +++++++------- examples/auth_tls.js | 46 +++++++------- examples/basic.js | 39 +++++------- examples/from_conf.js | 38 +++++------- examples/workers.js | 102 ++++++++++++++++--------------- package-lock.json | 32 +++++----- 7 files changed, 218 insertions(+), 218 deletions(-) diff --git a/README.md b/README.md index b1f1e2d..29f42c0 100644 --- a/README.md +++ b/README.md @@ -22,77 +22,80 @@ For more details, please, check the Sender's documenta ### Basic API usage ```javascript -const { Sender } = require('@questdb/nodejs-client'); +const { Sender } = require("@questdb/nodejs-client") async function run() { - // create a sender using HTTP protocol - const sender = Sender.fromConfig('http::addr=localhost:9000'); - - // add rows to the buffer of the sender - await sender.table('prices').symbol('instrument', 'EURUSD') - .floatColumn('bid', 1.0195).floatColumn('ask', 1.0221) - .at(Date.now(), 'ms'); - await sender.table('prices').symbol('instrument', 'GBPUSD') - .floatColumn('bid', 1.2076).floatColumn('ask', 1.2082) - .at(Date.now(), 'ms'); - - // flush the buffer of the sender, sending the data to QuestDB - // the buffer is cleared after the data is sent, and the sender is ready to accept new data - await sender.flush(); - - // add rows to the buffer again, and send it to the server - await sender.table('prices').symbol('instrument', 'EURUSD') - .floatColumn('bid', 1.0197).floatColumn('ask', 1.0224) - .at(Date.now(), 'ms'); - await sender.flush(); - - // close the connection after all rows ingested - await sender.close(); + // create a sender using HTTP protocol + const sender = Sender.fromConfig("http::addr=127.0.0.1:9000") + + // add rows to the buffer of the sender + await sender + .table("trades") + .symbol("symbol", "ETH-USD") + .symbol("side", "sell") + .floatColumn("price", 2615.54) + .floatColumn("amount", 0.00044) + .at(Date.now(), "ms") + + // flush the buffer of the sender, sending the data to QuestDB + // the buffer is cleared after the data is sent, and the sender is ready to accept new data + await sender.flush() + + // close the connection after all rows ingested + // unflushed data will be lost + await sender.close() } -run() - .then(console.log) - .catch(console.error); +run().then(console.log).catch(console.error) ``` ### Authentication and secure connection ```javascript -const { Sender } = require('@questdb/nodejs-client'); +const { Sender } = require("@questdb/nodejs-client") async function run() { // create a sender using HTTPS protocol with username and password authentication - const sender = Sender.fromConfig('https::addr=localhost:9000;username=user1;password=pwd'); + const sender = Sender.fromConfig("https::addr=127.0.0.1:9000;username=admin;password=quest;") // send the data over the authenticated and secure connection - await sender.table('prices').symbol('instrument', 'EURUSD') - .floatColumn('bid', 1.0197).floatColumn('ask', 1.0224) - .at(Date.now(), 'ms'); - await sender.flush(); + await sender + .table("trades") + .symbol("symbol", "ETH-USD") + .symbol("side", "sell") + .floatColumn("price", 2615.54) + .floatColumn("amount", 0.00044) + .at(Date.now(), "ms") + await sender.flush() // close the connection after all rows ingested - await sender.close(); + await sender.close() } -run().catch(console.error); +run().catch(console.error) ``` ### TypeScript example ```typescript -import { Sender } from '@questdb/nodejs-client'; +import { Sender } from "@questdb/nodejs-client" -async function run(): Promise { +async function run(): Promise { // create a sender using HTTPS protocol with bearer token authentication - const sender: Sender = Sender.fromConfig('https::addr=localhost:9000;token=Xyvd3er6GF87ysaHk'); + const sender: Sender = Sender.fromConfig("https::addr=127.0.0.1:9000;token=Xyvd3er6GF87ysaHk;") // send the data over the authenticated and secure connection - sender.table('prices').symbol('instrument', 'EURUSD') - .floatColumn('bid', 1.0197).floatColumn('ask', 1.0224).at(Date.now(), 'ms'); - await sender.flush(); + await sender + .table("trades") + .symbol("symbol", "ETH-USD") + .symbol("side", "sell") + .floatColumn("price", 2615.54) + .floatColumn("amount", 0.00044) + .at(Date.now(), "ms") + await sender.flush() // close the connection after all rows ingested - await sender.close(); + await sender.close() } run().catch(console.error); @@ -101,77 +104,79 @@ run().catch(console.error); ### Worker threads example ```javascript -const { Sender } = require('@questdb/nodejs-client'); -const { Worker, isMainThread, parentPort, workerData } = require('worker_threads'); +const { Sender } = require("@questdb/nodejs-client") +const { Worker, isMainThread, parentPort, workerData } = require("worker_threads") // fake venue -// generates random prices for a ticker for max 5 seconds, then the feed closes +// generates random prices and amounts for a ticker for max 5 seconds, then the feed closes function* venue(ticker) { - let end = false; - setTimeout(() => { end = true; }, rndInt(5000)); + let end = false + setTimeout(() => { end = true; }, rndInt(5000)) while (!end) { - yield {'ticker': ticker, 'price': Math.random()}; + yield {ticker, price: Math.random(), amount: Math.random()} } } // market data feed simulator -// uses the fake venue to deliver price updates to the feed handler (onTick() callback) +// uses the fake venue to deliver price and amount updates to the feed handler (onTick() callback) async function subscribe(ticker, onTick) { - const feed = venue(workerData.ticker); + const feed = venue(workerData.ticker) let tick; while (tick = feed.next().value) { - await onTick(tick); - await sleep(rndInt(30)); + await onTick(tick) + await sleep(rndInt(30)) } } async function run() { if (isMainThread) { - const tickers = ['t1', 't2', 't3', 't4']; + const tickers = ["ETH-USD", "BTC-USD", "SOL-USD", "DOGE-USD"] // main thread to start a worker thread for each ticker - for (let ticker in tickers) { + for (let ticker of tickers) { const worker = new Worker(__filename, { workerData: { ticker: ticker } }) .on('error', (err) => { throw err; }) .on('exit', () => { console.log(`${ticker} thread exiting...`); }) .on('message', (msg) => { - console.log(`Ingested ${msg.count} prices for ticker ${msg.ticker}`); + console.log(`Ingested ${msg.count} prices for ticker ${msg.ticker}`) }); } } else { // it is important that each worker has a dedicated sender object // threads cannot share the sender because they would write into the same buffer - const sender = Sender.fromConfig('http::addr=localhost:9000'); + const sender = Sender.fromConfig("http::addr=127.0.0.1:9000"); // subscribe for the market data of the ticker assigned to the worker // ingest each price update into the database using the sender let count = 0; await subscribe(workerData.ticker, async (tick) => { await sender - .table('prices') - .symbol('ticker', tick.ticker) - .floatColumn('price', tick.price) - .at(Date.now(), 'ms'); + .table("trades") + .symbol("symbol", tick.ticker) + .symbol("side", "sell") + .floatColumn("price", tick.price) + .floatColumn("amount", tick.amount) + .at(Date.now(), "ms") await sender.flush(); count++; }); // let the main thread know how many prices were ingested - parentPort.postMessage({'ticker': workerData.ticker, 'count': count}); + parentPort.postMessage({ticker: workerData.ticker, count}) // close the connection to the database - await sender.close(); + await sender.close() } } function sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); + return new Promise(resolve => setTimeout(resolve, ms)) } function rndInt(limit) { - return Math.floor((Math.random() * limit) + 1); + return Math.floor((Math.random() * limit) + 1) } run() .then(console.log) - .catch(console.error); + .catch(console.error) ``` diff --git a/examples/auth.js b/examples/auth.js index 7437a31..59faebd 100644 --- a/examples/auth.js +++ b/examples/auth.js @@ -2,40 +2,40 @@ const { Sender } = require('@questdb/nodejs-client'); async function run() { // authentication details - const CLIENT_ID = 'testapp'; - const PRIVATE_KEY = '9b9x5WhJywDEuo1KGQWSPNxtX-6X6R2BRCKhYMMY6n8'; + const CLIENT_ID = 'admin' + const PRIVATE_KEY = 'ZRxmCOQBpZoj2fZ-lEtqzVDkCre_ouF3ePpaQNDwoQk' const AUTH = { keyId: CLIENT_ID, token: PRIVATE_KEY - }; + } // pass the authentication details to the sender - const sender = new Sender({ protocol: 'tcp', host: 'localhost', port: 9009, bufferSize: 4096, auth: AUTH }); - await sender.connect(); + const sender = new Sender({ protocol: 'tcp', host: '127.0.0.1', port: 9009, bufferSize: 4096, auth: AUTH }) + await sender.connect() // send the data over the authenticated connection - let bday = Date.parse('1856-07-10'); await sender - .table('inventors_nodejs') - .symbol('born', 'Austrian Empire') - .timestampColumn('birthday', bday, 'ms') // epoch in millis - .intColumn('id', 0) - .stringColumn('name', 'Nicola Tesla') - .at(Date.now(), 'ms'); // epoch in millis - bday = Date.parse('1847-02-11'); + .table("trades") + .symbol("symbol", "ETH-USD") + .symbol("side", "sell") + .floatColumn("price", 2615.54) + .floatColumn("amount", 0.00044) + .at(Date.now(), 'ms') + + // add rows to the buffer of the sender await sender - .table('inventors_nodejs') - .symbol('born', 'USA') - .timestampColumn('birthday', bday, 'ms') - .intColumn('id', 1) - .stringColumn('name', 'Thomas Alva Edison') - .at(Date.now(), 'ms'); + .table("trades") + .symbol("symbol", "BTC-USD") + .symbol("side", "sell") + .floatColumn("price", 39269.98) + .floatColumn("amount", 0.001) + .at(Date.now(), 'ms') // flush the buffer of the sender, sending the data to QuestDB - await sender.flush(); + await sender.flush() // close the connection after all rows ingested - await sender.close(); + await sender.close() } -run().catch(console.error); +run().catch(console.error) diff --git a/examples/auth_tls.js b/examples/auth_tls.js index 52e5400..3bb5b28 100644 --- a/examples/auth_tls.js +++ b/examples/auth_tls.js @@ -2,40 +2,40 @@ const { Sender } = require('@questdb/nodejs-client'); async function run() { // authentication details - const CLIENT_ID = 'testapp'; - const PRIVATE_KEY = '9b9x5WhJywDEuo1KGQWSPNxtX-6X6R2BRCKhYMMY6n8'; + const CLIENT_ID = 'admin' + const PRIVATE_KEY = 'ZRxmCOQBpZoj2fZ-lEtqzVDkCre_ouF3ePpaQNDwoQk' const AUTH = { keyId: CLIENT_ID, token: PRIVATE_KEY - }; + } // pass the authentication details to the sender - const sender = new Sender({ protocol: 'tcps', host: 'localhost', port: 9009, bufferSize: 4096, auth: AUTH }); - await sender.connect(); + const sender = new Sender({ protocol: 'tcps', host: '127.0.0.1', port: 9009, bufferSize: 4096, auth: AUTH }) + await sender.connect() - // send the data over the authenticated and secure connection - let bday = Date.parse('1856-07-10'); + // send the data over the authenticated connection await sender - .table('inventors_nodejs') - .symbol('born', 'Austrian Empire') - .timestampColumn('birthday', bday, 'ms') // epoch in millis - .intColumn('id', 0) - .stringColumn('name', 'Nicola Tesla') - .at(Date.now(), 'ms'); // epoch in millis - bday = Date.parse('1847-02-11'); + .table("trades") + .symbol("symbol", "ETH-USD") + .symbol("side", "sell") + .floatColumn("price", 2615.54) + .floatColumn("amount", 0.00044) + .at(Date.now(), 'ms') + + // add rows to the buffer of the sender await sender - .table('inventors_nodejs') - .symbol('born', 'USA') - .timestampColumn('birthday', bday, 'ms') - .intColumn('id', 1) - .stringColumn('name', 'Thomas Alva Edison') - .at(Date.now(), 'ms'); + .table("trades") + .symbol("symbol", "BTC-USD") + .symbol("side", "sell") + .floatColumn("price", 39269.98) + .floatColumn("amount", 0.001) + .at(Date.now(), 'ms') // flush the buffer of the sender, sending the data to QuestDB - await sender.flush(); + await sender.flush() // close the connection after all rows ingested - await sender.close(); + await sender.close() } -run().catch(console.error); +run().catch(console.error) diff --git a/examples/basic.js b/examples/basic.js index 22d7dab..fa65423 100644 --- a/examples/basic.js +++ b/examples/basic.js @@ -1,34 +1,27 @@ -const { Sender } = require('@questdb/nodejs-client'); +const { Sender } = require('@questdb/nodejs-client') async function run() { // create a sender with a 4KB buffer - const sender = new Sender({ protocol: 'tcp', host: 'localhost', port: 9009, bufferSize: 4096 }); - await sender.connect(); + const sender = new Sender({ protocol: 'tcp', host: '127.0.0.1', port: 9009, bufferSize: 4096 }) + await sender.connect() + // add rows to the buffer of the sender - let bday = Date.parse('1856-07-10'); - await sender - .table('inventors_nodejs') - .symbol('born', 'Austrian Empire') - .timestampColumn('birthday', bday, 'ms') // epoch in millis - .intColumn('id', 0) - .stringColumn('name', 'Nicola Tesla') - .at(Date.now(), 'ms'); // epoch in millis - bday = Date.parse('1847-02-11'); await sender - .table('inventors_nodejs') - .symbol('born', 'USA') - .timestampColumn('birthday', bday, 'ms') - .intColumn('id', 1) - .stringColumn('name', 'Thomas Alva Edison') - .at(Date.now(), 'ms'); + .table("trades") + .symbol("symbol", "ETH-USD") + .symbol("side", "sell") + .floatColumn("price", 2615.54) + .floatColumn("amount", 0.00044) + .at(Date.now(), 'ms') // flush the buffer of the sender, sending the data to QuestDB - // the buffer is cleared after the data is sent and the sender is ready to accept new data - await sender.flush(); + // the buffer is cleared after the data is sent, and the sender is ready to accept new data + await sender.flush() - // close the connection after all rows were sent - await sender.close(); + // close the connection after all rows ingested + // unflushed data will be lost + await sender.close() } -run().catch(console.error); +run().then(console.log).catch(console.error) diff --git a/examples/from_conf.js b/examples/from_conf.js index 0bb1b2d..8a82563 100644 --- a/examples/from_conf.js +++ b/examples/from_conf.js @@ -1,33 +1,25 @@ -const { Sender } = require('@questdb/nodejs-client'); +const { Sender } = require("@questdb/nodejs-client") async function run() { - // configure the sender - const sender = Sender.fromConfig('http::addr=localhost:9000'); + // create a sender using HTTP protocol + const sender = Sender.fromConfig("http::addr=127.0.0.1:9000") // add rows to the buffer of the sender - let bday = Date.parse('1856-07-10'); await sender - .table('inventors_nodejs') - .symbol('born', 'Austrian Empire') - .timestampColumn('birthday', bday, 'ms') // epoch in millis - .intColumn('id', 0) - .stringColumn('name', 'Nicola Tesla') - .at(Date.now(), 'ms'); // epoch in millis - bday = Date.parse('1847-02-11'); - await sender - .table('inventors_nodejs') - .symbol('born', 'USA') - .timestampColumn('birthday', bday, 'ms') - .intColumn('id', 1) - .stringColumn('name', 'Thomas Alva Edison') - .at(Date.now(), 'ms'); + .table("trades") + .symbol("symbol", "ETH-USD") + .symbol("side", "sell") + .floatColumn("price", 2615.54) + .floatColumn("amount", 0.00044) + .at(Date.now(), 'ms') // flush the buffer of the sender, sending the data to QuestDB - // the buffer is cleared after the data is sent and the sender is ready to accept new data - await sender.flush(); + // the buffer is cleared after the data is sent, and the sender is ready to accept new data + await sender.flush() - // close the connection after all rows were sent - await sender.close(); + // close the connection after all rows ingested + // unflushed data will be lost + await sender.close() } -run().catch(console.error); +run().then(console.log).catch(console.error) diff --git a/examples/workers.js b/examples/workers.js index 579fc6f..9f90480 100644 --- a/examples/workers.js +++ b/examples/workers.js @@ -1,69 +1,75 @@ -const { Sender } = require('@questdb/nodejs-client'); -const { Worker, isMainThread, parentPort, workerData } = require('worker_threads'); +const { Sender } = require('@questdb/nodejs-client') +const { Worker, isMainThread, parentPort, workerData } = require('worker_threads') // fake venue -// generates random prices for a ticker for max 5 seconds, then the feed closes +// generates random prices and amounts for a ticker for max 5 seconds, then the feed closes function* venue(ticker) { - let end = false; - setTimeout(() => { end = true; }, rndInt(5000)); - while (!end) { - yield {'ticker': ticker, 'price': Math.random()}; - } + let end = false + setTimeout(() => { end = true; }, rndInt(5000)) + while (!end) { + yield {ticker, price: Math.random(), amount: Math.random()} + } } // market data feed simulator -// uses the fake venue to deliver price updates to the feed handler (onTick() callback) +// uses the fake venue to deliver price and amount updates to the feed handler (onTick() callback) async function subscribe(ticker, onTick) { - const feed = venue(workerData.ticker); - let tick; - while (tick = feed.next().value) { - await onTick(tick); - await sleep(rndInt(30)); - } + const feed = venue(workerData.ticker) + let tick; + while (tick = feed.next().value) { + await onTick(tick); + await sleep(rndInt(30)) + } } async function run() { - if (isMainThread) { - const tickers = ['t1', 't2', 't3', 't4']; - // main thread to start a worker thread for each ticker - for (let ticker in tickers) { - const worker = new Worker(__filename, { workerData: { ticker: ticker } }) - .on('error', (err) => { throw err; }) - .on('exit', () => { console.log(`${ticker} thread exiting...`); }) - .on('message', (msg) => { console.log('Ingested ' + msg.count + ' prices for ticker ' + msg.ticker); }); - } - } else { - // it is important that each worker has a dedicated sender object - // threads cannot share the sender because they would write into the same buffer - const sender = Sender.fromConfig('http::addr=localhost:9000'); + if (isMainThread) { + const tickers = ['ETH-USD', 'BTC-USD', 'SOL-USD', 'DOGE-USD'] + // main thread to start a worker thread for each ticker + for (let ticker of tickers) { + const worker = new Worker(__filename, { workerData: { ticker: ticker } }) + .on('error', (err) => { throw err; }) + .on('exit', () => { console.log(`${ticker} thread exiting...`); }) + .on('message', (msg) => { + console.log(`Ingested ${msg.count} prices for ticker ${msg.ticker}`) + }); + } + } else { + // it is important that each worker has a dedicated sender object + // threads cannot share the sender because they would write into the same buffer + const sender = Sender.fromConfig('http::addr=127.0.0.1:9000') - // subscribe for the market data of the ticker assigned to the worker - // ingest each price update into the database using the sender - let count = 0; - await subscribe(workerData.ticker, async (tick) => { - await sender - .table('prices_nodejs') - .symbol('ticker', tick.ticker) - .floatColumn('price', tick.price) - .atNow(); - await sender.flush(); - count++; - }); + // subscribe for the market data of the ticker assigned to the worker + // ingest each price update into the database using the sender + let count = 0; + await subscribe(workerData.ticker, async (tick) => { + await sender + .table("trades") + .symbol("symbol", tick.ticker) + .symbol("side", "sell") + .floatColumn("price", tick.price) + .floatColumn("amount", tick.amount) + .at(Date.now(), 'ms') + await sender.flush() + count++; + }); - // let the main thread know how many prices were ingested - parentPort.postMessage({'ticker': workerData.ticker, 'count': count}); + // let the main thread know how many prices were ingested + parentPort.postMessage({ticker: workerData.ticker, count}) - // close the connection to the database - await sender.close(); - } + // close the connection to the database + await sender.close(); + } } function sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); + return new Promise(resolve => setTimeout(resolve, ms)); } function rndInt(limit) { - return Math.floor((Math.random() * limit) + 1); + return Math.floor((Math.random() * limit) + 1) } -run().catch(console.error); +run() + .then(console.log) + .catch(console.error) diff --git a/package-lock.json b/package-lock.json index 6b2fc83..0763b4c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1675,12 +1675,13 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -2535,10 +2536,11 @@ } }, "node_modules/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==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -2898,6 +2900,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } @@ -4919,6 +4922,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, + "license": "MIT", "dependencies": { "is-number": "^7.0.0" }, @@ -6497,12 +6501,12 @@ } }, "braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" } }, "browserslist": { @@ -7109,9 +7113,9 @@ } }, "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==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dev": true, "requires": { "to-regex-range": "^5.0.1"