added bcrypt + user model

This commit is contained in:
Vic 2022-05-20 00:38:28 +02:00
parent 774a37bc58
commit 6359baee5b
8 changed files with 405 additions and 42 deletions

View File

@ -1 +1,2 @@
drop TABLE products
drop TABLE products;
DROP TABLE users;

View File

@ -3,3 +3,12 @@ CREATE TABLE products (
name VARCHAR(250) NOT NULL,
price INTEGER NOT NULL
);
CREATE TABLE users (
id SERIAL PRIMARY KEY,
firstName VARCHAR(250) NOT NULL,
lastName VARCHAR(250) NOT NULL,
username VARCHAR(250) NOT NULL,
password_digest VARCHAR(250) NOT NULL
);

View File

@ -15,14 +15,12 @@
"prettier": "prettier \"src/**/*.ts\" --write",
"tsc": "tsc"
},
"author": "AnisB",
"license": "ISC",
"dependencies": {
"bcrypt": "^5.0.1",
"body-parser": "^1.19.0",
"cross-env": "^7.0.3",
"db-migrate": "^0.11.13",
"db-migrate-pg": "^1.2.2",
"dotenv": "^16.0.0",
"express": "^4.17.1",
"lodash": "^4.17.21",
@ -31,12 +29,15 @@
"typescript": "^4.1.3"
},
"devDependencies": {
"@types/bcrypt": "^5.0.0",
"@types/express": "^4.17.9",
"@types/jasmine": "^3.6.3",
"@types/pg": "^7.14.7",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.10.1",
"@typescript-eslint/parser": "^5.10.1",
"db-migrate": "^0.11.13",
"db-migrate-pg": "^1.2.2",
"eslint": "^7.27.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0",

View File

@ -1,9 +1,9 @@
import express, {request, Request, response, Response} from 'express'
import express, {Request, Response} from 'express'
import { Product, ProductStore } from '../models/product'
const productRoutes = (app: express.Application) => {
app.get('/products', index)
app.get('/products/:id', show)
app.get('/products/:id', read)
app.post('/products/create', create)
app.put('/products/:id', update)
app.delete('/products/:id', destroy)
@ -24,9 +24,9 @@ const index = async (req: Request, res: Response) => {
}
const show = async (req: Request, res: Response) => {
const read = async (req: Request, res: Response) => {
try {
const product = await store.show(parseInt(req.params.id))
const product = await store.read(parseInt(req.params.id))
res.json(product)
} catch (err) {
res.status(400)

View File

@ -1,4 +1,3 @@
import { Client, Connection } from 'pg';
import client from '../database';
export type Product = {
@ -10,27 +9,34 @@ export type Product = {
export class ProductStore {
async index(): Promise<Product[]> {
try {
// @ts-ignore
const conn = await client.connect()
const sql = 'SELECT * FROM products;'
const sql = 'SELECT * FROM products'
const result = await conn.query(sql)
const products = result.rows
conn.release()
return result.rows
return products
} catch (err) {
throw new Error(`Cannot get products ${err}`)
throw new Error(`Cannot get any products ${err}`)
}
}
async show(id: number): Promise<Product> {
async read(id: number): Promise<Product> {
try {
const sql = 'SELECT * FROM products where id=($1);'
// @ts-ignore
const conn = await client.connect()
const sql = 'SELECT * FROM products where id=($1)'
const result = await conn.query(sql, [id])
const product = result.rows[0]
conn.release()
return result.rows[0]
return product
} catch (err) {
throw new Error(`Could not find product ${id}. Error: ${err}`)
@ -40,9 +46,9 @@ export class ProductStore {
async create(p: Product): Promise<Product> {
try {
const sql = 'INSERT INTO products (name, price) VALUES ($1, $2) RETURNING *;'
// @ts-ignore
const conn = await client.connect()
const sql = 'INSERT INTO products (name, price) VALUES ($1, $2) RETURNING *'
const result = await conn.query(sql, [p.name, p.price])
const product = result.rows[0]
@ -50,31 +56,36 @@ export class ProductStore {
conn.release()
return product
} catch (err) {
throw new Error(`Could not add new product ${p.name}. Error: ${err}`)
throw new Error(`Could not add a new product ${p.name}. Error: ${err}`)
}
}
async update(p: Product): Promise<Product> {
try {
const conn = await client.connect();
const result = await conn.query(
'UPDATE products SET name=$1, price=$2 WHERE id=$3 RETURNING *;',
[p.name, p.price, p.id]
);
const sql = 'UPDATE products SET name=$1, price=$2 WHERE id=$3 RETURNING *'
const result = await conn.query(sql, [p.name, p.price, p.id])
const product = result.rows[0]
conn.release()
return result.rows[0]
return product
} catch (err) {
throw new Error(`could not update product ${p.id}. Error: ${err}`)
throw new Error(`Could not update product ${p.id}. Error: ${err}`)
}
}
async delete(id: number): Promise<Product> {
try {
const sql = 'DELETE FROM products WHERE id=($1)'
// @ts-ignore
const conn = await client.connect()
const sql = 'DELETE FROM products WHERE id=($1)'
const result = await conn.query(sql, [id])
const product = result.rows[0]

138
src/models/user.ts Normal file
View File

@ -0,0 +1,138 @@
import client from '../database';
import bcrypt from 'bcrypt';
const { BCRYPT_PASSWORD, SALT_ROUNDS} = process.env
const pepper = BCRYPT_PASSWORD
const saltRounds = SALT_ROUNDS
export type User = {
id?: number;
firstName: string;
lastName: string;
username: string;
password: string;
}
export class UserStore {
async index(): Promise<User> {
try {
const conn = await client.connect()
const sql = 'SELECT * FROM users'
const result = await conn.query(sql)
const user = result.rows[0]
conn.release()
return user
} catch (err) {
throw new Error(`Cannot get any users ${err}`)
}
}
async read(id: number): Promise<User> {
try {
const conn = await client.connect()
const sql = 'SELECT * FROM users WHERE id=($1)'
const result = await conn.query(sql, [id])
const user = result.rows[0]
conn.release()
return user
} catch (err) {
throw new Error(`Could not find user ${id}. Error: ${err}`)
}
}
async create(u: User): Promise<User> {
try {
const conn = await client.connect()
const sql = 'INSERT INTO users (firstName, lastName, username, password) VALUES ($1, $2, 3$, 4$) RETURNING *'
const hash = bcrypt.hashSync(
u.password + pepper,
parseInt(saltRounds as string, 10)
)
const result = await conn.query(sql, [u.firstName, u.lastName, u.username, hash])
const user = result.rows[0]
conn.release()
return user
} catch(err) {
throw new Error(`Could not add a new user ${u.firstName}. Error: ${err}`)
}
}
async update(u: User): Promise<User> {
try {
const conn = await client.connect()
const sql = 'UPDATE users SET fristName=$1, lastName=$2, username=$3, password=$4 WHERE id=$5 RETURNING *'
const result = await conn.query(sql, [u.firstName, u.lastName, u.username, u.password, u.id])
const user = result.rows[0]
conn.release()
return user
} catch (err) {
throw new Error(`Could not update user ${u.firstName}. Error: ${err}`)
}
}
async delete(id: Number): Promise<User> {
try {
const conn = await client.connect()
const sql = 'DELETE FROM users WHERE id=($1)'
const result = await conn.query(sql, [id])
const user = result.rows[0]
conn.release()
return user
} catch (err) {
throw new Error(`Could not delete user ${id}. Error: ${err}`)
}
}
async authenticate(username: string, password: string): Promise<User | null> {
try {
const conn = await client.connect()
const sql = 'SELECT password_digest FROM users WHERE username=($1)'
const result = await conn.query(sql, [username])
console.log("password + pepper :", password + pepper )
if(result.rows.length) {
const user = result.rows[0]
console.log(user)
if (bcrypt.compareSync(password + pepper, user.password_digest)) {
return user
}
}
conn.release()
return null
} catch (err) {
throw new Error(`Could not find user ${username}. Error: ${err}`)
}
}
}

View File

@ -44,7 +44,7 @@ describe("Products store Model", () => {
});
it('show method should return a product', async () => {
const result = await store.show(1);
const result = await store.read(1);
expect(result).toEqual({
id: 1,
name: '1984',

229
yarn.lock
View File

@ -57,6 +57,21 @@
"resolved" "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz"
"version" "1.2.1"
"@mapbox/node-pre-gyp@^1.0.0":
"integrity" "sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw=="
"resolved" "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.9.tgz"
"version" "1.0.9"
dependencies:
"detect-libc" "^2.0.0"
"https-proxy-agent" "^5.0.0"
"make-dir" "^3.1.0"
"node-fetch" "^2.6.7"
"nopt" "^5.0.0"
"npmlog" "^5.0.1"
"rimraf" "^3.0.2"
"semver" "^7.3.5"
"tar" "^6.1.11"
"@nodelib/fs.scandir@2.1.5":
"integrity" "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="
"resolved" "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz"
@ -90,6 +105,13 @@
dependencies:
"defer-to-connect" "^1.0.1"
"@types/bcrypt@^5.0.0":
"integrity" "sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw=="
"resolved" "https://registry.npmjs.org/@types/bcrypt/-/bcrypt-5.0.0.tgz"
"version" "5.0.0"
dependencies:
"@types/node" "*"
"@types/body-parser@*":
"integrity" "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g=="
"resolved" "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz"
@ -294,6 +316,13 @@
"resolved" "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz"
"version" "7.4.1"
"agent-base@6":
"integrity" "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="
"resolved" "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz"
"version" "6.0.2"
dependencies:
"debug" "4"
"ajv@^6.10.0", "ajv@^6.12.4":
"integrity" "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="
"resolved" "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz"
@ -353,6 +382,19 @@
"normalize-path" "^3.0.0"
"picomatch" "^2.0.4"
"aproba@^1.0.3 || ^2.0.0":
"integrity" "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ=="
"resolved" "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz"
"version" "2.0.0"
"are-we-there-yet@^2.0.0":
"integrity" "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw=="
"resolved" "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz"
"version" "2.0.0"
dependencies:
"delegates" "^1.0.0"
"readable-stream" "^3.6.0"
"arg@^4.1.0":
"integrity" "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA=="
"resolved" "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz"
@ -392,12 +434,7 @@
"resolved" "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz"
"version" "2.0.0"
"async@~1.0.0":
"integrity" "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k="
"resolved" "https://registry.npmjs.org/async/-/async-1.0.0.tgz"
"version" "1.0.0"
"async@3.2.3":
"async@^3.2.3", "async@3.2.3":
"integrity" "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g=="
"resolved" "https://registry.npmjs.org/async/-/async-3.2.3.tgz"
"version" "3.2.3"
@ -419,6 +456,14 @@
dependencies:
"tweetnacl" "^0.14.3"
"bcrypt@^5.0.1":
"integrity" "sha512-9BTgmrhZM2t1bNuDtrtIMVSmmxZBrJ71n8Wg+YgdjHuIWYF7SjjmCPZFB+/5i/o/PIeRpwVJR3P+NrpIItUjqw=="
"resolved" "https://registry.npmjs.org/bcrypt/-/bcrypt-5.0.1.tgz"
"version" "5.0.1"
dependencies:
"@mapbox/node-pre-gyp" "^1.0.0"
"node-addon-api" "^3.1.0"
"binary-extensions@^2.0.0":
"integrity" "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
"resolved" "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz"
@ -575,6 +620,11 @@
optionalDependencies:
"fsevents" "~2.3.2"
"chownr@^2.0.0":
"integrity" "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="
"resolved" "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz"
"version" "2.0.0"
"ci-info@^2.0.0":
"integrity" "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="
"resolved" "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz"
@ -634,6 +684,11 @@
"resolved" "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz"
"version" "1.1.3"
"color-support@^1.1.2":
"integrity" "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="
"resolved" "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz"
"version" "1.1.3"
"colors@1.0.x":
"integrity" "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs="
"resolved" "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz"
@ -673,6 +728,11 @@
"write-file-atomic" "^3.0.0"
"xdg-basedir" "^4.0.0"
"console-control-strings@^1.0.0", "console-control-strings@^1.1.0":
"integrity" "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
"resolved" "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz"
"version" "1.1.0"
"content-disposition@0.5.4":
"integrity" "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ=="
"resolved" "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz"
@ -816,6 +876,13 @@
dependencies:
"ms" "2.0.0"
"debug@4":
"integrity" "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="
"resolved" "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz"
"version" "4.3.4"
dependencies:
"ms" "2.1.2"
"decamelize@^1.2.0":
"integrity" "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
"resolved" "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz"
@ -848,6 +915,11 @@
"resolved" "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz"
"version" "1.0.0"
"delegates@^1.0.0":
"integrity" "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
"resolved" "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz"
"version" "1.0.0"
"depd@~1.1.2":
"integrity" "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
"resolved" "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz"
@ -868,6 +940,11 @@
"resolved" "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz"
"version" "1.2.0"
"detect-libc@^2.0.0":
"integrity" "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w=="
"resolved" "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz"
"version" "2.0.1"
"dezalgo@1.0.3":
"integrity" "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY="
"resolved" "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz"
@ -1316,6 +1393,13 @@
"resolved" "https://registry.npmjs.org/from/-/from-0.1.7.tgz"
"version" "0.1.7"
"fs-minipass@^2.0.0":
"integrity" "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="
"resolved" "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz"
"version" "2.1.0"
dependencies:
"minipass" "^3.0.0"
"fs.realpath@^1.0.0":
"integrity" "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
"resolved" "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
@ -1331,6 +1415,21 @@
"resolved" "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz"
"version" "1.0.1"
"gauge@^3.0.0":
"integrity" "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q=="
"resolved" "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz"
"version" "3.0.2"
dependencies:
"aproba" "^1.0.3 || ^2.0.0"
"color-support" "^1.1.2"
"console-control-strings" "^1.0.0"
"has-unicode" "^2.0.1"
"object-assign" "^4.1.1"
"signal-exit" "^3.0.0"
"string-width" "^4.2.3"
"strip-ansi" "^6.0.1"
"wide-align" "^1.1.2"
"get-caller-file@^2.0.1", "get-caller-file@^2.0.5":
"integrity" "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
"resolved" "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz"
@ -1441,6 +1540,11 @@
"resolved" "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz"
"version" "1.0.3"
"has-unicode@^2.0.1":
"integrity" "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
"resolved" "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz"
"version" "2.0.1"
"has-yarn@^2.1.0":
"integrity" "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw=="
"resolved" "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz"
@ -1485,6 +1589,14 @@
"statuses" "2.0.1"
"toidentifier" "1.0.1"
"https-proxy-agent@^5.0.0":
"integrity" "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="
"resolved" "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz"
"version" "5.0.1"
dependencies:
"agent-base" "6"
"debug" "4"
"iconv-lite@0.4.24":
"integrity" "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="
"resolved" "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz"
@ -1775,7 +1887,7 @@
dependencies:
"yallist" "^4.0.0"
"make-dir@^3.0.0":
"make-dir@^3.0.0", "make-dir@^3.1.0":
"integrity" "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw=="
"resolved" "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz"
"version" "3.1.0"
@ -1859,6 +1971,26 @@
"resolved" "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz"
"version" "1.2.6"
"minipass@^3.0.0":
"integrity" "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ=="
"resolved" "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz"
"version" "3.1.6"
dependencies:
"yallist" "^4.0.0"
"minizlib@^2.1.1":
"integrity" "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="
"resolved" "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz"
"version" "2.1.2"
dependencies:
"minipass" "^3.0.0"
"yallist" "^4.0.0"
"mkdirp@^1.0.3":
"integrity" "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
"resolved" "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz"
"version" "1.0.4"
"mkdirp@~0.5.0":
"integrity" "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw=="
"resolved" "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz"
@ -1906,11 +2038,23 @@
"resolved" "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz"
"version" "0.6.3"
"node-addon-api@^3.1.0":
"integrity" "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A=="
"resolved" "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz"
"version" "3.2.1"
"node-cleanup@^2.1.2":
"integrity" "sha1-esGavSl+Caf3KnFUXZUbUX5N3iw="
"resolved" "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz"
"version" "2.1.2"
"node-fetch@^2.6.7":
"integrity" "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ=="
"resolved" "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz"
"version" "2.6.7"
dependencies:
"whatwg-url" "^5.0.0"
"node-fs@~0.1.5":
"integrity" "sha1-MjI8zLRsn78PwRgS1FAhzDHTJbs="
"resolved" "https://registry.npmjs.org/node-fs/-/node-fs-0.1.7.tgz"
@ -1932,6 +2076,13 @@
"undefsafe" "^2.0.5"
"update-notifier" "^5.1.0"
"nopt@^5.0.0":
"integrity" "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ=="
"resolved" "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz"
"version" "5.0.0"
dependencies:
"abbrev" "1"
"nopt@~1.0.10":
"integrity" "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4="
"resolved" "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz"
@ -1949,6 +2100,21 @@
"resolved" "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz"
"version" "4.5.1"
"npmlog@^5.0.1":
"integrity" "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw=="
"resolved" "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz"
"version" "5.0.1"
dependencies:
"are-we-there-yet" "^2.0.0"
"console-control-strings" "^1.1.0"
"gauge" "^3.0.0"
"set-blocking" "^2.0.0"
"object-assign@^4.1.1":
"integrity" "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
"resolved" "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz"
"version" "4.1.1"
"object-inspect@^1.9.0":
"integrity" "sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g=="
"resolved" "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.0.tgz"
@ -2511,7 +2677,7 @@
"get-intrinsic" "^1.0.2"
"object-inspect" "^1.9.0"
"signal-exit@^3.0.2":
"signal-exit@^3.0.0", "signal-exit@^3.0.2":
"integrity" "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
"resolved" "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz"
"version" "3.0.7"
@ -2605,7 +2771,7 @@
"resolved" "https://registry.npmjs.org/string-argv/-/string-argv-0.1.2.tgz"
"version" "0.1.2"
"string-width@^4.0.0", "string-width@^4.1.0", "string-width@^4.2.0", "string-width@^4.2.2", "string-width@^4.2.3":
"string-width@^1.0.2 || 2 || 3 || 4", "string-width@^4.0.0", "string-width@^4.1.0", "string-width@^4.2.0", "string-width@^4.2.2", "string-width@^4.2.3":
"integrity" "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="
"resolved" "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz"
"version" "4.2.3"
@ -2693,6 +2859,18 @@
"string-width" "^4.2.3"
"strip-ansi" "^6.0.1"
"tar@^6.1.11":
"integrity" "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA=="
"resolved" "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz"
"version" "6.1.11"
dependencies:
"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@^0.2.0":
"integrity" "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ="
"resolved" "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz"
@ -2727,6 +2905,11 @@
dependencies:
"nopt" "~1.0.10"
"tr46@~0.0.3":
"integrity" "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o="
"resolved" "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz"
"version" "0.0.3"
"ts-node@^9.1.1", "ts-node@>=3.2.0 <=10":
"integrity" "sha512-hPlt7ZACERQGf03M253ytLY3dHbGNGrAq9qIHWUY9XHYl1z7wYngSr3OQ5xmui8o2AaxsONxIzjafLUiWBo1Fg=="
"resolved" "https://registry.npmjs.org/ts-node/-/ts-node-9.1.1.tgz"
@ -2879,6 +3062,19 @@
"resolved" "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz"
"version" "1.1.2"
"webidl-conversions@^3.0.0":
"integrity" "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE="
"resolved" "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz"
"version" "3.0.1"
"whatwg-url@^5.0.0":
"integrity" "sha1-lmRU6HZUYuN2RNNib2dCzotwll0="
"resolved" "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz"
"version" "5.0.0"
dependencies:
"tr46" "~0.0.3"
"webidl-conversions" "^3.0.0"
"when@~2.0.1":
"integrity" "sha1-jYcv4V5oQkyRtLck6EjggH2rZkI="
"resolved" "https://registry.npmjs.org/when/-/when-2.0.1.tgz"
@ -2896,6 +3092,13 @@
dependencies:
"isexe" "^2.0.0"
"wide-align@^1.1.2":
"integrity" "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg=="
"resolved" "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz"
"version" "1.1.5"
dependencies:
"string-width" "^1.0.2 || 2 || 3 || 4"
"widest-line@^3.1.0":
"integrity" "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg=="
"resolved" "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz"
@ -2904,11 +3107,11 @@
"string-width" "^4.0.0"
"winston@2.x":
"integrity" "sha512-TWoamHt5yYvsMarGlGEQE59SbJHqGsZV8/lwC+iCcGeAe0vUaOh+Lv6SYM17ouzC/a/LB1/hz/7sxFBtlu1l4A=="
"resolved" "https://registry.npmjs.org/winston/-/winston-2.4.5.tgz"
"version" "2.4.5"
"integrity" "sha512-J5Zu4p0tojLde8mIOyDSsmLmcP8I3Z6wtwpTDHx1+hGcdhxcJaAmG4CFtagkb+NiN1M9Ek4b42pzMWqfc9jm8w=="
"resolved" "https://registry.npmjs.org/winston/-/winston-2.4.6.tgz"
"version" "2.4.6"
dependencies:
"async" "~1.0.0"
"async" "^3.2.3"
"colors" "1.0.x"
"cycle" "1.0.x"
"eyes" "0.1.x"