diff --git a/.eslintrc.js b/.eslintrc.js index 59f25f9..1371207 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,5 +1,13 @@ +/* eslint-env node */ module.exports = { - extends: [ - 'semistandard' - ] + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:import/errors', + 'plugin:prettier/recommended', + 'prettier', + ], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint'], + root: true, }; diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 0000000..f0c3079 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,7 @@ +module.exports = { + parser: 'typescript', + printWidth: 120, + trailingComma: 'all', + tabWidth: 4, + singleQuote: true, +}; diff --git a/lib/app.ts b/lib/app.ts index b34a7c5..1ede131 100644 --- a/lib/app.ts +++ b/lib/app.ts @@ -1,8 +1,8 @@ -import Koa from 'koa'; -import bodyParser from 'koa-bodyparser'; -import cookie from 'koa-cookie'; -import passport from 'koa-passport'; -import session from 'koa-session'; +import koa from 'koa'; +import koaBodyparser from 'koa-bodyparser'; +import koaCookie from 'koa-cookie'; +import koaPassport from 'koa-passport'; +import koaSession from 'koa-session'; import { performanceLogger, perfromanceTimer } from './middleware/performance'; import { errorHandler } from './middleware/errorHandler'; diff --git a/lib/auth.ts b/lib/auth.ts index c5dd9a1..609f4f0 100644 --- a/lib/auth.ts +++ b/lib/auth.ts @@ -1,4 +1,4 @@ -import passport from 'koa-passport'; +import koaPassport from 'koa-passport'; // import Users from 'grow-db/lib/models/users'; // import { User } from 'grow-db/lib/schemas/user'; diff --git a/lib/constants/strategies.ts b/lib/constants/strategies.ts index 2b56a03..ea91c22 100644 --- a/lib/constants/strategies.ts +++ b/lib/constants/strategies.ts @@ -1,7 +1,7 @@ export enum STRATEGIES { - LOCAL, - APPLE, - FACEBOOK, - FIDO2, - GOOGLE, + LOCAL, + APPLE, + FACEBOOK, + FIDO2, + GOOGLE, } diff --git a/lib/database/database.connection.ts b/lib/database/database.connection.ts index 7d275f5..4d1e780 100644 --- a/lib/database/database.connection.ts +++ b/lib/database/database.connection.ts @@ -6,6 +6,4 @@ const DB_HOST = process.env.DB_HOST || 'mongodb'; const DB_PORT = process.env.DB_PORT || 27017; const DB_NAME = process.env.DB_NAME || 'auth'; -export const connection = mongoose.connect( - `${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}` -); +export const connection = mongoose.connect(`${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}`); diff --git a/lib/middleware/errorHandler.ts b/lib/middleware/errorHandler.ts index 2f6579b..b91aa2f 100644 --- a/lib/middleware/errorHandler.ts +++ b/lib/middleware/errorHandler.ts @@ -2,13 +2,12 @@ import { StatusCodes } from 'http-status-codes'; import { Context, Next } from 'koa'; export const errorHandler = async (ctx: Context, next: Next) => { - try { - await next(); - } catch (error: any) { - ctx.status = - error.statusCode || error.status || StatusCodes.INTERNAL_SERVER_ERROR; - error.status = ctx.status; - ctx.body = { error }; - ctx.app.emit('error', error, ctx); - } + try { + await next(); + } catch (error: any) { + ctx.status = error.statusCode || error.status || StatusCodes.INTERNAL_SERVER_ERROR; + error.status = ctx.status; + ctx.body = { error }; + ctx.app.emit('error', error, ctx); + } }; diff --git a/lib/middleware/performance.ts b/lib/middleware/performance.ts index 524aa09..54d4c66 100644 --- a/lib/middleware/performance.ts +++ b/lib/middleware/performance.ts @@ -2,14 +2,14 @@ import { Next } from 'koa'; import { KoaContext } from '../types/KoaContext'; export const performanceLogger = async (ctx: KoaContext, next: Next) => { - await next(); - const rt = ctx.response.get('X-Response-Time'); - console.log(`${ctx.method} ${ctx.url} - ${rt}`); + await next(); + const rt = ctx.response.get('X-Response-Time'); + console.log(`${ctx.method} ${ctx.url} - ${rt}`); }; export const perfromanceTimer = async (ctx: KoaContext, next: Next) => { - const start = Date.now(); - await next(); - const ms = Date.now() - start; - ctx.set('X-Response-Time', `${ms}ms`); + const start = Date.now(); + await next(); + const ms = Date.now() - start; + ctx.set('X-Response-Time', `${ms}ms`); }; diff --git a/lib/schema/auth.ts b/lib/schema/auth.ts index 00d8594..4eacd6c 100644 --- a/lib/schema/auth.ts +++ b/lib/schema/auth.ts @@ -1,11 +1,5 @@ import { JwtPayload } from 'jsonwebtoken'; -import { - InferSchemaType, - Model, - Schema, - StringSchemaDefinition, - Types, -} from 'mongoose'; +import { InferSchemaType, Model, Schema, StringSchemaDefinition, Types } from 'mongoose'; import { Strategy } from './strategy'; import { STRATEGIES } from '../constants/strategies'; @@ -14,139 +8,132 @@ import { encrypt, verify as verifyPassword } from '../utils/password'; import { generateResetToken } from '../utils/tokens'; export type Auth = { - is2FA?: boolean; - record: StringSchemaDefinition; - username: string; + is2FA?: boolean; + record: StringSchemaDefinition; + username: string; }; export type AuthPrivate = Auth & { - strategies: Types.ArraySubdocument; + strategies: Types.ArraySubdocument; }; export interface AuthMethods { - authenticate(password: string): boolean; - getAuthStrategy(method?: STRATEGIES): Strategy | false; - getResetLink(route: string): Promise; - getResetToken(): Promise; - getToken(props?: Omit): string; - setPassword(password: string): Promise; + authenticate(password: string): boolean; + getAuthStrategy(method?: STRATEGIES): Strategy | false; + getResetLink(route: string): Promise; + getResetToken(): Promise; + getToken(props?: Omit): string; + setPassword(password: string): Promise; } export interface AuthModel extends Model { - authenticate(password: any): boolean; - findByUsername(username: string): Promise; - isUsernameAvailable(username: string): Promise; - findUserForReset( - strategy: STRATEGIES, - token: string - ): Promise; - resetPassword(token: string, password: string): Promise; + authenticate(password: any): boolean; + findByUsername(username: string): Promise; + isUsernameAvailable(username: string): Promise; + findUserForReset(strategy: STRATEGIES, token: string): Promise; + resetPassword(token: string, password: string): Promise; } export const AuthSchema = new Schema( - { - is2FA: { type: Boolean, default: false }, - record: { type: Types.ObjectId }, - strategies: { type: Types.ArraySubdocument, required: true }, - username: { type: String, required: true, unique: true }, - }, - { - minimize: true, - timestamps: true, - } + { + is2FA: { type: Boolean, default: false }, + record: { type: Types.ObjectId }, + strategies: { type: Types.ArraySubdocument, required: true }, + username: { type: String, required: true, unique: true }, + }, + { + minimize: true, + timestamps: true, + }, ); AuthSchema.methods = { - authenticate: function (password: string) { - const strategy = this.getAuthStrategy(STRATEGIES.LOCAL); - return !!strategy && verifyPassword(password, strategy.key); - }, + authenticate(password: string) { + const strategy = this.getAuthStrategy(STRATEGIES.LOCAL); + return !!strategy && verifyPassword(password, strategy.key); + }, - getAuthStrategy: function (method = STRATEGIES.LOCAL) { - return ( - this.strategies - .filter((strategy: Strategy) => strategy.method === method) - .pop() || false - ); - }, + getAuthStrategy(method = STRATEGIES.LOCAL) { + return this.strategies.filter((strategy: Strategy) => strategy.method === method).pop() || false; + }, - getToken: function (props = {}) { - return sign({ - sub: this._id, - ...props, - }); - }, + getToken(props = {}) { + return sign({ + sub: this._id, + ...props, + }); + }, - getResetLink: async function (route) { - const resetToken = await this.getResetToken(); - if (resetToken) { - let resetRoute = route; - resetRoute = resetRoute.replace(':user_id', this._id); - resetRoute = resetRoute.replace(':reset_token?', resetToken); - const resetUrl = `${process.env.URL}${resetRoute}`; - console.log('[sendPasswordReset] resetUrl:', resetUrl); - return resetUrl; - } - }, + async getResetLink(route) { + const resetToken = await this.getResetToken(); + if (resetToken) { + let resetRoute = route; + resetRoute = resetRoute.replace(':user_id', this._id); + resetRoute = resetRoute.replace(':reset_token?', resetToken); + const resetUrl = `${process.env.URL}${resetRoute}`; + console.log('[sendPasswordReset] resetUrl:', resetUrl); + return resetUrl; + } + }, - getResetToken: async function () { - const { key, token } = generateResetToken(this._id); - this.resetCheckBit = key; - await this.save().catch(() => undefined); - return token; - }, + async getResetToken() { + const { key, token } = generateResetToken(this._id); + this.resetCheckBit = key; + await this.save().catch(() => undefined); + return token; + }, - setPassword: async function (password) { - const key = encrypt(password); - const hasLocalStrategy = !!this.getAuthStrategy(STRATEGIES.LOCAL); - const strategy = { - key, - method: STRATEGIES.LOCAL, - resetToken: undefined, - }; + async setPassword(password) { + const key = encrypt(password); + const hasLocalStrategy = !!this.getAuthStrategy(STRATEGIES.LOCAL); + const strategy = { + key, + method: STRATEGIES.LOCAL, + resetToken: undefined, + }; - if (hasLocalStrategy) { - await this.model('User') - .findOneAndUpdate( - { _id: this._id, 'strategies.method': STRATEGIES.LOCAL }, - { $set: { 'strategies.$': strategy } }, - { upsert: true }, - ) - .catch(); - return true; - } - this.credentials.push(strategy); - await this.save().catch(() => false); - return true; - } + if (hasLocalStrategy) { + await this.model('User') + .findOneAndUpdate( + { _id: this._id, 'strategies.method': STRATEGIES.LOCAL }, + { $set: { 'strategies.$': strategy } }, + { upsert: true }, + ) + .catch(); + return true; + } + this.credentials.push(strategy); + await this.save().catch(() => false); + return true; + }, }; AuthSchema.statics = { - // authenticateAndGetRecordLocator: async function (username, password) { - // const auth = await this.findByUserName(username); - // if (auth && auth.authenticate(password)) { - // return auth?.record; - // } - // return false; - // }, + // authenticateAndGetRecordLocator: async function (username, password) { + // const auth = await this.findByUserName(username); + // if (auth && auth.authenticate(password)) { + // return auth?.record; + // } + // return false; + // }, - findByUsername: async function (username) { - return this.findOne({ username }); - }, + async findByUsername(username) { + return this.findOne({ username }); + }, - isUsernameAvailable: async function (username) { - return !this.findByUsername(username); - }, + async isUsernameAvailable(username) { + return !this.findByUsername(username); + }, - resetPassword: async function (token, password) { - const decoded = verifyJwt(token); - const { sub, key } = decoded as JwtPayload; - const auth = await this.findOne({ - _id: sub, - 'strategies.resetToken': key, - }).catch(); - return !!auth && auth.setPassword(password); - } + async resetPassword(token, password) { + const decoded = verifyJwt(token); + const { sub, key } = decoded as JwtPayload; + const auth = await this.findOne({ + _id: sub, + 'strategies.resetToken': key, + }).catch(); + return !!auth && auth.setPassword(password); + }, }; export type AuthSchema = InferSchemaType; diff --git a/lib/schema/strategy.ts b/lib/schema/strategy.ts index a97551c..5a04818 100644 --- a/lib/schema/strategy.ts +++ b/lib/schema/strategy.ts @@ -2,24 +2,24 @@ import { InferSchemaType, Schema, Types } from 'mongoose'; import { STRATEGIES } from '../constants/strategies'; export const Strategy = new Schema( - { - method: { - type: Number, - enum: Object.values(STRATEGIES), - index: true, - required: true, - unique: true + { + method: { + type: Number, + enum: Object.values(STRATEGIES), + index: true, + required: true, + unique: true, + }, + externalId: { type: String, index: true }, + key: { type: String, required: true, trim: true }, + profile: {}, + resetToken: { type: String }, + forceReset: { type: Boolean }, + }, + { + minimize: true, + timestamps: true, }, - externalId: { type: String, index: true }, - key: { type: String, required: true, trim: true }, - profile: {}, - resetToken: { type: String }, - forceReset: { type: Boolean } - }, - { - minimize: true, - timestamps: true - } ); export type Strategy = InferSchemaType; diff --git a/lib/server.ts b/lib/server.ts index 9a8f2b8..d0bb5f3 100644 --- a/lib/server.ts +++ b/lib/server.ts @@ -2,11 +2,12 @@ import dotenv from 'dotenv'; import app from './app'; import { connection } from './database/database.connection'; + dotenv.config(); const PORT: number = Number(process.env.PORT) || 9000; connection.then( - () => app.listen(PORT), - (err) => console.error('ERROR!', err), + () => app.listen(PORT), + (err) => console.error('ERROR!', err), ); diff --git a/lib/strategies/local.ts b/lib/strategies/local.ts index 8e85cca..f24ea57 100644 --- a/lib/strategies/local.ts +++ b/lib/strategies/local.ts @@ -1,19 +1,19 @@ -import passport from 'koa-passport'; +import koaPassport from 'koa-passport'; import { Strategy } from 'passport-local'; import Auth from '../model/auth'; export const localStrategy = passport.use( - new Strategy(async (username, password, done) => { - const user = await Auth.findOne({ - where: { - username, - } - }).catch(); - if (user && user.authenticate(password)) { - done(null, user); - } else { - done(null, false); - } - }) + new Strategy(async (username, password, done) => { + const user = await Auth.findOne({ + where: { + username, + }, + }).catch(); + if (user && user.authenticate(password)) { + done(null, user); + } else { + done(null, false); + } + }), ); diff --git a/lib/utils/auth.ts b/lib/utils/auth.ts index 1daf80b..9d18cad 100644 --- a/lib/utils/auth.ts +++ b/lib/utils/auth.ts @@ -1,17 +1,14 @@ -import Auth from '../model/auth'; +import auth from '../model/auth'; import { AuthModel, AuthPrivate } from '../schema/auth'; import { sign } from './jwt'; -export const getAuthenticationBundle = async ( - username: string, - password: string, -) => { - const auth = await Auth.findByUsername(username).catch(); - const isAuthenticated = !!auth && (auth as AuthModel).authenticate(password); - const record = isAuthenticated ? (auth as AuthPrivate).record : null; - const token = isAuthenticated ? (auth as AuthModel).getToken() : sign(); - return { - record, - token, - }; +export const getAuthenticationBundle = async (username: string, password: string) => { + const auth = await Auth.findByUsername(username).catch(); + const isAuthenticated = !!auth && (auth as AuthModel).authenticate(password); + const record = isAuthenticated ? (auth as AuthPrivate).record : null; + const token = isAuthenticated ? (auth as AuthModel).getToken() : sign(); + return { + record, + token, + }; }; diff --git a/lib/utils/jwt.ts b/lib/utils/jwt.ts index 5c55a3a..6d4922a 100644 --- a/lib/utils/jwt.ts +++ b/lib/utils/jwt.ts @@ -1,40 +1,35 @@ -import jwt, { JwtPayload } from 'jsonwebtoken'; +import jsonwebtoken, { JwtPayload } from 'jsonwebtoken'; export interface TokenProps { - aud?: string; - exp?: number | Date; - iss?: string; - sub: string | null; - [key: string]: any; + aud?: string; + exp?: number | Date; + iss?: string; + sub: string | null; + [key: string]: any; } export type SignProps = string | TokenProps | void; export const sign = (props: SignProps) => { - const today = new Date(); - const { sub = null, ...rest }: TokenProps = - typeof props === 'string' || typeof props === 'undefined' - ? { sub: props || null } - : props; - let exp = rest.exp; - if (!exp) { - exp = new Date(today); - exp.setDate( - today.getDate() + parseInt(process.env.JWT_DAYS_VALID as string), + const today = new Date(); + const { sub = null, ...rest }: TokenProps = + typeof props === 'string' || typeof props === 'undefined' ? { sub: props || null } : props; + let { exp } = rest; + if (!exp) { + exp = new Date(today); + exp.setDate(today.getDate() + parseInt(process.env.JWT_DAYS_VALID as string)); + exp = exp.getTime() / 1000; + } + return jwt.sign( + { + exp, + sub, + aud: rest.aud || process.env.JWT_AUDIENCE, + iat: today.getTime(), + iss: rest.iss || process.env.JWT_ISSUER, + }, + process.env.JWT_SECRET || 'secret', ); - exp = exp.getTime() / 1000; - } - return jwt.sign( - { - exp, - sub, - aud: rest.aud || process.env.JWT_AUDIENCE, - iat: today.getTime(), - iss: rest.iss || process.env.JWT_ISSUER, - }, - process.env.JWT_SECRET || 'secret', - ); }; -export const verify = (token: string) => - jwt.verify(token, process.env.JWT_SECRET || 'secret'); +export const verify = (token: string) => jwt.verify(token, process.env.JWT_SECRET || 'secret'); diff --git a/lib/utils/password.ts b/lib/utils/password.ts index 24908a8..922f138 100644 --- a/lib/utils/password.ts +++ b/lib/utils/password.ts @@ -1,12 +1,12 @@ import { pbkdf2Sync, randomBytes } from 'crypto'; export const encrypt = (password: string) => { - const salt = randomBytes(16).toString('hex'); - const hash = pbkdf2Sync(password, salt, 10000, 512, 'sha512').toString('hex'); - return `${salt}:${hash}`; + const salt = randomBytes(16).toString('hex'); + const hash = pbkdf2Sync(password, salt, 10000, 512, 'sha512').toString('hex'); + return `${salt}:${hash}`; }; export const verify = (test: string, secret: string) => { - const [salt, hash] = secret.split(':'); - return pbkdf2Sync(test, salt, 10000, 512, 'sha512').toString('hex') === hash; + const [salt, hash] = secret.split(':'); + return pbkdf2Sync(test, salt, 10000, 512, 'sha512').toString('hex') === hash; }; diff --git a/lib/utils/tokens.ts b/lib/utils/tokens.ts index fcc8f75..2163efb 100644 --- a/lib/utils/tokens.ts +++ b/lib/utils/tokens.ts @@ -3,11 +3,11 @@ import crypto from 'crypto'; import { sign } from './jwt'; export const generateResetToken = (sub: string) => { - const key = crypto.randomBytes(16).toString('hex'); - const token = sign({ - sub, - key, - exp: Date.now() + 24 * 60 * 60 * 1000, - }); - return { key, token }; + const key = crypto.randomBytes(16).toString('hex'); + const token = sign({ + sub, + key, + exp: Date.now() + 24 * 60 * 60 * 1000, + }); + return { key, token }; }; diff --git a/package.json b/package.json index 80e6273..4c2901d 100644 --- a/package.json +++ b/package.json @@ -5,8 +5,9 @@ "license": "MIT", "scripts": { "build": "tsc", - "lint": "tslint --project tsconfig.json --format stylish", - "prettier:fix": "prettier-eslint --write '**/*.ts'", + "format": "prettier:fix && lint:fix", + "lint": "eslint . --ext .js", + "prettier:fix": "prettier --write 'lib/**/*.ts'", "serve": "ts-node src/server.ts", "start": "nodemon" }, @@ -30,11 +31,13 @@ "@types/passport-google-oauth": "^1.0.42", "@types/passport-jwt": "^3.0.8", "@types/passport-local": "^1.0.35", - "eslint": "^8.13.0", - "eslint-config-semistandard": "latest", - "eslint-config-standard": "^17.0.0", - "eslint-plugin-import": "^2.26.0", + "@typescript-eslint/eslint-plugin": "^5.59.2", + "@typescript-eslint/parser": "^5.59.2", + "eslint": "^8.39.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-import": "^2.27.5", "eslint-plugin-n": "^15.0.0", + "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-promise": "^6.0.0", "jest": "^29.4.2", "nodemon": "^2.0.20", @@ -45,6 +48,8 @@ "ts-node": "^10.9.1", "tslint": "^6.1.3", "tslint-config-airbnb": "^5.11.2", + "tslint-config-prettier": "^1.18.0", + "tslint-plugin-prettier": "^2.3.0", "typescript": "^4.9.5" }, "dependencies": { diff --git a/tslint.json b/tslint.json deleted file mode 100644 index 5bfb3b7..0000000 --- a/tslint.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "extends": "tslint-config-airbnb", - "rules": { - "import-name": false - } -} diff --git a/yarn.lock b/yarn.lock index dcd2191..706388f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1827,12 +1827,14 @@ __metadata: "@types/passport-google-oauth": ^1.0.42 "@types/passport-jwt": ^3.0.8 "@types/passport-local": ^1.0.35 + "@typescript-eslint/eslint-plugin": ^5.59.2 + "@typescript-eslint/parser": ^5.59.2 dotenv: ^16.0.3 - eslint: ^8.13.0 - eslint-config-semistandard: latest - eslint-config-standard: ^17.0.0 - eslint-plugin-import: ^2.26.0 + eslint: ^8.39.0 + eslint-config-prettier: ^8.8.0 + eslint-plugin-import: ^2.27.5 eslint-plugin-n: ^15.0.0 + eslint-plugin-prettier: ^4.2.1 eslint-plugin-promise: ^6.0.0 http-status-codes: ^2.2.0 jest: ^29.4.2 @@ -1859,6 +1861,8 @@ __metadata: ts-node: ^10.9.1 tslint: ^6.1.3 tslint-config-airbnb: ^5.11.2 + tslint-config-prettier: ^1.18.0 + tslint-plugin-prettier: ^2.3.0 typescript: ^4.9.5 languageName: unknown linkType: soft @@ -2292,7 +2296,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:*": +"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.9": version: 7.0.11 resolution: "@types/json-schema@npm:7.0.11" checksum: 527bddfe62db9012fccd7627794bd4c71beb77601861055d87e3ee464f2217c85fca7a4b56ae677478367bbd248dbde13553312b7d4dbc702a2f2bbf60c4018d @@ -2523,6 +2527,13 @@ __metadata: languageName: node linkType: hard +"@types/semver@npm:^7.3.12": + version: 7.3.13 + resolution: "@types/semver@npm:7.3.13" + checksum: 00c0724d54757c2f4bc60b5032fe91cda6410e48689633d5f35ece8a0a66445e3e57fa1d6e07eb780f792e82ac542948ec4d0b76eb3484297b79bd18b8cf1cb0 + languageName: node + linkType: hard + "@types/serve-static@npm:*": version: 1.15.1 resolution: "@types/serve-static@npm:1.15.1" @@ -2573,6 +2584,30 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/eslint-plugin@npm:^5.59.2": + version: 5.59.2 + resolution: "@typescript-eslint/eslint-plugin@npm:5.59.2" + dependencies: + "@eslint-community/regexpp": ^4.4.0 + "@typescript-eslint/scope-manager": 5.59.2 + "@typescript-eslint/type-utils": 5.59.2 + "@typescript-eslint/utils": 5.59.2 + debug: ^4.3.4 + grapheme-splitter: ^1.0.4 + ignore: ^5.2.0 + natural-compare-lite: ^1.4.0 + semver: ^7.3.7 + tsutils: ^3.21.0 + peerDependencies: + "@typescript-eslint/parser": ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 1045883173a36a069b56e906ed7e5b4106e1efc2ed0969a1718683aef58fd39e5dfa17774b8782c3ced0529a4edd6dedfcb54348a14525f191a6816e6f3b90dc + languageName: node + linkType: hard + "@typescript-eslint/parser@npm:^5.10.0": version: 5.59.0 resolution: "@typescript-eslint/parser@npm:5.59.0" @@ -2590,6 +2625,23 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/parser@npm:^5.59.2": + version: 5.59.2 + resolution: "@typescript-eslint/parser@npm:5.59.2" + dependencies: + "@typescript-eslint/scope-manager": 5.59.2 + "@typescript-eslint/types": 5.59.2 + "@typescript-eslint/typescript-estree": 5.59.2 + debug: ^4.3.4 + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 0d3f992c49e062ff509606fb72846abaa66602d93ca15bc6498c345c55effa28c8d523b829cd180d901eaf04bca3d93a165d56a387ce109333d60d67b09b5638 + languageName: node + linkType: hard + "@typescript-eslint/scope-manager@npm:5.59.0": version: 5.59.0 resolution: "@typescript-eslint/scope-manager@npm:5.59.0" @@ -2600,6 +2652,33 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/scope-manager@npm:5.59.2": + version: 5.59.2 + resolution: "@typescript-eslint/scope-manager@npm:5.59.2" + dependencies: + "@typescript-eslint/types": 5.59.2 + "@typescript-eslint/visitor-keys": 5.59.2 + checksum: e7adce27890ebaadd0fb36a35639c9a97d2965973643aef4b4b0dcfabb03181c82235d7171e718b002dd398e52fefd67816eb34912ddbc2bb738b47755bd502a + languageName: node + linkType: hard + +"@typescript-eslint/type-utils@npm:5.59.2": + version: 5.59.2 + resolution: "@typescript-eslint/type-utils@npm:5.59.2" + dependencies: + "@typescript-eslint/typescript-estree": 5.59.2 + "@typescript-eslint/utils": 5.59.2 + debug: ^4.3.4 + tsutils: ^3.21.0 + peerDependencies: + eslint: "*" + peerDependenciesMeta: + typescript: + optional: true + checksum: d9dc037509a97b11a3c7f758f0f6e985cf5b4909fab860018a75b1550711ce9ff07bf5b67d4197ba7a0a831fec7255851b1e6a773a69030fc8ea7ec649859f52 + languageName: node + linkType: hard + "@typescript-eslint/types@npm:5.59.0": version: 5.59.0 resolution: "@typescript-eslint/types@npm:5.59.0" @@ -2607,6 +2686,13 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/types@npm:5.59.2": + version: 5.59.2 + resolution: "@typescript-eslint/types@npm:5.59.2" + checksum: 5a91cfbcaa8c7e92ad91f67abd0ce43ae562fdbdd8c32aa968731bf7c200d13a0415e87fc032bd48f7e5b7d3ed1447cb14449ef2592c269ca311974b15ce0af2 + languageName: node + linkType: hard + "@typescript-eslint/typescript-estree@npm:5.59.0": version: 5.59.0 resolution: "@typescript-eslint/typescript-estree@npm:5.59.0" @@ -2625,6 +2711,42 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/typescript-estree@npm:5.59.2": + version: 5.59.2 + resolution: "@typescript-eslint/typescript-estree@npm:5.59.2" + dependencies: + "@typescript-eslint/types": 5.59.2 + "@typescript-eslint/visitor-keys": 5.59.2 + debug: ^4.3.4 + globby: ^11.1.0 + is-glob: ^4.0.3 + semver: ^7.3.7 + tsutils: ^3.21.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: e8bb8817fe53f826f54e4ca584e48a6700dae25e0cc20ab7db38e7e5308987c5759408b39a4e494d4d6dcd7b4bca9f9c507fae987213380dc1c98607cb0a60b1 + languageName: node + linkType: hard + +"@typescript-eslint/utils@npm:5.59.2": + version: 5.59.2 + resolution: "@typescript-eslint/utils@npm:5.59.2" + dependencies: + "@eslint-community/eslint-utils": ^4.2.0 + "@types/json-schema": ^7.0.9 + "@types/semver": ^7.3.12 + "@typescript-eslint/scope-manager": 5.59.2 + "@typescript-eslint/types": 5.59.2 + "@typescript-eslint/typescript-estree": 5.59.2 + eslint-scope: ^5.1.1 + semver: ^7.3.7 + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + checksum: 483c35a592a36a5973204ce4cd11d52935c097b414d7edac2ecd15dba460b8c540b793ffc232c0f8580fef0624eb7704156ce33c66bd09a76769ed019bddd1d1 + languageName: node + linkType: hard + "@typescript-eslint/visitor-keys@npm:5.59.0": version: 5.59.0 resolution: "@typescript-eslint/visitor-keys@npm:5.59.0" @@ -2635,6 +2757,16 @@ __metadata: languageName: node linkType: hard +"@typescript-eslint/visitor-keys@npm:5.59.2": + version: 5.59.2 + resolution: "@typescript-eslint/visitor-keys@npm:5.59.2" + dependencies: + "@typescript-eslint/types": 5.59.2 + eslint-visitor-keys: ^3.3.0 + checksum: 3057a017bca03b4ec3bee442044f2bc2f77a4af0d83ea9bf7c6cb2a12811126d93d9d300d89ef8078d981e478c6cc38693c51a2ae4b10a717796bba880eff924 + languageName: node + linkType: hard + "abbrev@npm:1, abbrev@npm:^1.0.0": version: 1.1.1 resolution: "abbrev@npm:1.1.1" @@ -4041,28 +4173,14 @@ __metadata: languageName: node linkType: hard -"eslint-config-semistandard@npm:latest": - version: 17.0.0 - resolution: "eslint-config-semistandard@npm:17.0.0" +"eslint-config-prettier@npm:^8.8.0": + version: 8.8.0 + resolution: "eslint-config-prettier@npm:8.8.0" peerDependencies: - eslint: ^8.13.0 - eslint-config-standard: ^17.0.0 - eslint-plugin-import: ^2.26.0 - eslint-plugin-n: ^15.0.0 - eslint-plugin-promise: ^6.0.0 - checksum: 89ac11b2eb3aa95b3dcdf6e1d45c2b23707f7ec21dd8ee58850b73ce014895710e5ff3824d38f40f7dfbf105a89363b38d7f6e585d9a5cccfe62cdfd04279b2f - languageName: node - linkType: hard - -"eslint-config-standard@npm:^17.0.0": - version: 17.0.0 - resolution: "eslint-config-standard@npm:17.0.0" - peerDependencies: - eslint: ^8.0.1 - eslint-plugin-import: ^2.25.2 - eslint-plugin-n: ^15.0.0 - eslint-plugin-promise: ^6.0.0 - checksum: dc0ed51e186fd963ff2c0819d33ef580afce11b11036cbcf5e74427e26e514c2b1be96b8ffe74fd2fd00263554a0d49cc873fcf76f17c3dfdba614b45d7fd7da + eslint: ">=7.0.0" + bin: + eslint-config-prettier: bin/cli.js + checksum: 1e94c3882c4d5e41e1dcfa2c368dbccbfe3134f6ac7d40101644d3bfbe3eb2f2ffac757f3145910b5eacf20c0e85e02b91293d3126d770cbf3dc390b3564681c languageName: node linkType: hard @@ -4101,7 +4219,7 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-import@npm:^2.26.0": +"eslint-plugin-import@npm:^2.27.5": version: 2.27.5 resolution: "eslint-plugin-import@npm:2.27.5" dependencies: @@ -4144,6 +4262,33 @@ __metadata: languageName: node linkType: hard +"eslint-plugin-prettier@npm:^2.2.0": + version: 2.7.0 + resolution: "eslint-plugin-prettier@npm:2.7.0" + dependencies: + fast-diff: ^1.1.1 + jest-docblock: ^21.0.0 + peerDependencies: + prettier: ">= 0.11.0" + checksum: 6cb6440d0cac858e65c3bb9c82cc3e257118d1631eaa69b5caa10b39e70af39053dc696a2f431d40e1f8912b98311c8154fc1dbfde9f1b85fe82f6d6533e9f30 + languageName: node + linkType: hard + +"eslint-plugin-prettier@npm:^4.2.1": + version: 4.2.1 + resolution: "eslint-plugin-prettier@npm:4.2.1" + dependencies: + prettier-linter-helpers: ^1.0.0 + peerDependencies: + eslint: ">=7.28.0" + prettier: ">=2.0.0" + peerDependenciesMeta: + eslint-config-prettier: + optional: true + checksum: b9e839d2334ad8ec7a5589c5cb0f219bded260839a857d7a486997f9870e95106aa59b8756ff3f37202085ebab658de382b0267cae44c3a7f0eb0bcc03a4f6d6 + languageName: node + linkType: hard + "eslint-plugin-promise@npm:^6.0.0": version: 6.1.1 resolution: "eslint-plugin-promise@npm:6.1.1" @@ -4153,6 +4298,16 @@ __metadata: languageName: node linkType: hard +"eslint-scope@npm:^5.1.1": + version: 5.1.1 + resolution: "eslint-scope@npm:5.1.1" + dependencies: + esrecurse: ^4.3.0 + estraverse: ^4.1.1 + checksum: 47e4b6a3f0cc29c7feedee6c67b225a2da7e155802c6ea13bbef4ac6b9e10c66cd2dcb987867ef176292bf4e64eccc680a49e35e9e9c669f4a02bac17e86abdb + languageName: node + linkType: hard + "eslint-scope@npm:^7.0.0, eslint-scope@npm:^7.1.1, eslint-scope@npm:^7.2.0": version: 7.2.0 resolution: "eslint-scope@npm:7.2.0" @@ -4204,56 +4359,6 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^8.13.0": - version: 8.39.0 - resolution: "eslint@npm:8.39.0" - dependencies: - "@eslint-community/eslint-utils": ^4.2.0 - "@eslint-community/regexpp": ^4.4.0 - "@eslint/eslintrc": ^2.0.2 - "@eslint/js": 8.39.0 - "@humanwhocodes/config-array": ^0.11.8 - "@humanwhocodes/module-importer": ^1.0.1 - "@nodelib/fs.walk": ^1.2.8 - 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.2.0 - eslint-visitor-keys: ^3.4.0 - espree: ^9.5.1 - esquery: ^1.4.2 - esutils: ^2.0.2 - fast-deep-equal: ^3.1.3 - file-entry-cache: ^6.0.1 - find-up: ^5.0.0 - glob-parent: ^6.0.2 - globals: ^13.19.0 - grapheme-splitter: ^1.0.4 - 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-sdsl: ^4.1.4 - js-yaml: ^4.1.0 - json-stable-stringify-without-jsonify: ^1.0.1 - levn: ^0.4.1 - lodash.merge: ^4.6.2 - minimatch: ^3.1.2 - natural-compare: ^1.4.0 - optionator: ^0.9.1 - strip-ansi: ^6.0.1 - strip-json-comments: ^3.1.0 - text-table: ^0.2.0 - bin: - eslint: bin/eslint.js - checksum: d7a074ff326e7ea482500dc0427a7d4b0260460f0f812d19b46b1cca681806b67309f23da9d17cd3de8eb74dd3c14cb549c4d58b05b140564d14cc1a391122a0 - languageName: node - linkType: hard - "eslint@npm:^8.21.0, eslint@npm:^8.7.0": version: 8.38.0 resolution: "eslint@npm:8.38.0" @@ -4304,6 +4409,56 @@ __metadata: languageName: node linkType: hard +"eslint@npm:^8.39.0": + version: 8.39.0 + resolution: "eslint@npm:8.39.0" + dependencies: + "@eslint-community/eslint-utils": ^4.2.0 + "@eslint-community/regexpp": ^4.4.0 + "@eslint/eslintrc": ^2.0.2 + "@eslint/js": 8.39.0 + "@humanwhocodes/config-array": ^0.11.8 + "@humanwhocodes/module-importer": ^1.0.1 + "@nodelib/fs.walk": ^1.2.8 + 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.2.0 + eslint-visitor-keys: ^3.4.0 + espree: ^9.5.1 + esquery: ^1.4.2 + esutils: ^2.0.2 + fast-deep-equal: ^3.1.3 + file-entry-cache: ^6.0.1 + find-up: ^5.0.0 + glob-parent: ^6.0.2 + globals: ^13.19.0 + grapheme-splitter: ^1.0.4 + 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-sdsl: ^4.1.4 + js-yaml: ^4.1.0 + json-stable-stringify-without-jsonify: ^1.0.1 + levn: ^0.4.1 + lodash.merge: ^4.6.2 + minimatch: ^3.1.2 + natural-compare: ^1.4.0 + optionator: ^0.9.1 + strip-ansi: ^6.0.1 + strip-json-comments: ^3.1.0 + text-table: ^0.2.0 + bin: + eslint: bin/eslint.js + checksum: d7a074ff326e7ea482500dc0427a7d4b0260460f0f812d19b46b1cca681806b67309f23da9d17cd3de8eb74dd3c14cb549c4d58b05b140564d14cc1a391122a0 + languageName: node + linkType: hard + "espree@npm:^9.0.0, espree@npm:^9.5.1": version: 9.5.1 resolution: "espree@npm:9.5.1" @@ -4343,6 +4498,13 @@ __metadata: languageName: node linkType: hard +"estraverse@npm:^4.1.1": + version: 4.3.0 + resolution: "estraverse@npm:4.3.0" + checksum: a6299491f9940bb246124a8d44b7b7a413a8336f5436f9837aaa9330209bd9ee8af7e91a654a3545aee9c54b3308e78ee360cef1d777d37cfef77d2fa33b5827 + languageName: node + linkType: hard + "estraverse@npm:^5.1.0, estraverse@npm:^5.2.0": version: 5.3.0 resolution: "estraverse@npm:5.3.0" @@ -4408,6 +4570,13 @@ __metadata: languageName: node linkType: hard +"fast-diff@npm:^1.1.1, fast-diff@npm:^1.1.2": + version: 1.2.0 + resolution: "fast-diff@npm:1.2.0" + checksum: 1b5306eaa9e826564d9e5ffcd6ebd881eb5f770b3f977fcbf38f05c824e42172b53c79920e8429c54eb742ce15a0caf268b0fdd5b38f6de52234c4a8368131ae + languageName: node + linkType: hard + "fast-glob@npm:^3.2.9": version: 3.2.12 resolution: "fast-glob@npm:3.2.12" @@ -5541,6 +5710,13 @@ __metadata: languageName: node linkType: hard +"jest-docblock@npm:^21.0.0": + version: 21.2.0 + resolution: "jest-docblock@npm:21.2.0" + checksum: 62530c4cefdd0d79863557b519b97e075f1231cd835809e08d7bd2346222a4772f33fd3c6010ad4fdbd64084b32c2f528dccf43998c2bebe7afa9b19eab9f84e + languageName: node + linkType: hard + "jest-docblock@npm:^29.4.3": version: 29.4.3 resolution: "jest-docblock@npm:29.4.3" @@ -6669,6 +6845,13 @@ __metadata: languageName: node linkType: hard +"natural-compare-lite@npm:^1.4.0": + version: 1.4.0 + resolution: "natural-compare-lite@npm:1.4.0" + checksum: 5222ac3986a2b78dd6069ac62cbb52a7bf8ffc90d972ab76dfe7b01892485d229530ed20d0c62e79a6b363a663b273db3bde195a1358ce9e5f779d4453887225 + languageName: node + linkType: hard + "natural-compare@npm:^1.4.0": version: 1.4.0 resolution: "natural-compare@npm:1.4.0" @@ -7246,6 +7429,15 @@ __metadata: languageName: node linkType: hard +"prettier-linter-helpers@npm:^1.0.0": + version: 1.0.0 + resolution: "prettier-linter-helpers@npm:1.0.0" + dependencies: + fast-diff: ^1.1.2 + checksum: 00ce8011cf6430158d27f9c92cfea0a7699405633f7f1d4a45f07e21bf78e99895911cbcdc3853db3a824201a7c745bd49bfea8abd5fb9883e765a90f74f8392 + languageName: node + linkType: hard + "prettier@npm:^2.5.1, prettier@npm:^2.8.4": version: 2.8.7 resolution: "prettier@npm:2.8.7" @@ -8147,6 +8339,15 @@ __metadata: languageName: node linkType: hard +"tslint-config-prettier@npm:^1.18.0": + version: 1.18.0 + resolution: "tslint-config-prettier@npm:1.18.0" + bin: + tslint-config-prettier-check: bin/check.js + checksum: f0c548a7a520f9247f8e4ddba1136f300d1b2ec48a8255b030c05e35866cc22c105d9120540dd5ee82e2a04a769d82f5d098b7eaf6928820f6dba1badad6704c + languageName: node + linkType: hard + "tslint-consistent-codestyle@npm:^1.14.1": version: 1.16.0 resolution: "tslint-consistent-codestyle@npm:1.16.0" @@ -8187,6 +8388,20 @@ __metadata: languageName: node linkType: hard +"tslint-plugin-prettier@npm:^2.3.0": + version: 2.3.0 + resolution: "tslint-plugin-prettier@npm:2.3.0" + dependencies: + eslint-plugin-prettier: ^2.2.0 + lines-and-columns: ^1.1.6 + tslib: ^1.7.1 + peerDependencies: + prettier: ^1.9.0 || ^2.0.0 + tslint: ^5.0.0 || ^6.0.0 + checksum: 6edab4251a454b421d1408b2e758d09bbcf2831607a11da7213a72c8a8fdc1c7dbd0465f662c5859c92c15db8590267e860277a7deee104e81841a61fe202a0f + languageName: node + linkType: hard + "tslint@npm:^6.1.3": version: 6.1.3 resolution: "tslint@npm:6.1.3"