Finally have prettier and linting maybe working
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2023-05-02 10:54:45 -04:00
parent 34acea15a2
commit 7f5765aaaa
19 changed files with 528 additions and 322 deletions

View File

@@ -1,5 +1,13 @@
/* eslint-env node */
module.exports = { module.exports = {
extends: [ extends: [
'semistandard' 'eslint:recommended',
] 'plugin:@typescript-eslint/recommended',
'plugin:import/errors',
'plugin:prettier/recommended',
'prettier',
],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
root: true,
}; };

7
.prettierrc.js Normal file
View File

@@ -0,0 +1,7 @@
module.exports = {
parser: 'typescript',
printWidth: 120,
trailingComma: 'all',
tabWidth: 4,
singleQuote: true,
};

View File

@@ -1,8 +1,8 @@
import Koa from 'koa'; import koa from 'koa';
import bodyParser from 'koa-bodyparser'; import koaBodyparser from 'koa-bodyparser';
import cookie from 'koa-cookie'; import koaCookie from 'koa-cookie';
import passport from 'koa-passport'; import koaPassport from 'koa-passport';
import session from 'koa-session'; import koaSession from 'koa-session';
import { performanceLogger, perfromanceTimer } from './middleware/performance'; import { performanceLogger, perfromanceTimer } from './middleware/performance';
import { errorHandler } from './middleware/errorHandler'; import { errorHandler } from './middleware/errorHandler';

View File

@@ -1,4 +1,4 @@
import passport from 'koa-passport'; import koaPassport from 'koa-passport';
// import Users from 'grow-db/lib/models/users'; // import Users from 'grow-db/lib/models/users';
// import { User } from 'grow-db/lib/schemas/user'; // import { User } from 'grow-db/lib/schemas/user';

View File

@@ -1,7 +1,7 @@
export enum STRATEGIES { export enum STRATEGIES {
LOCAL, LOCAL,
APPLE, APPLE,
FACEBOOK, FACEBOOK,
FIDO2, FIDO2,
GOOGLE, GOOGLE,
} }

View File

@@ -6,6 +6,4 @@ const DB_HOST = process.env.DB_HOST || 'mongodb';
const DB_PORT = process.env.DB_PORT || 27017; const DB_PORT = process.env.DB_PORT || 27017;
const DB_NAME = process.env.DB_NAME || 'auth'; const DB_NAME = process.env.DB_NAME || 'auth';
export const connection = mongoose.connect( export const connection = mongoose.connect(`${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}`);
`${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}`
);

View File

@@ -2,13 +2,12 @@ import { StatusCodes } from 'http-status-codes';
import { Context, Next } from 'koa'; import { Context, Next } from 'koa';
export const errorHandler = async (ctx: Context, next: Next) => { export const errorHandler = async (ctx: Context, next: Next) => {
try { try {
await next(); await next();
} catch (error: any) { } catch (error: any) {
ctx.status = ctx.status = error.statusCode || error.status || StatusCodes.INTERNAL_SERVER_ERROR;
error.statusCode || error.status || StatusCodes.INTERNAL_SERVER_ERROR; error.status = ctx.status;
error.status = ctx.status; ctx.body = { error };
ctx.body = { error }; ctx.app.emit('error', error, ctx);
ctx.app.emit('error', error, ctx); }
}
}; };

View File

@@ -2,14 +2,14 @@ import { Next } from 'koa';
import { KoaContext } from '../types/KoaContext'; import { KoaContext } from '../types/KoaContext';
export const performanceLogger = async (ctx: KoaContext, next: Next) => { export const performanceLogger = async (ctx: KoaContext, next: Next) => {
await next(); await next();
const rt = ctx.response.get('X-Response-Time'); const rt = ctx.response.get('X-Response-Time');
console.log(`${ctx.method} ${ctx.url} - ${rt}`); console.log(`${ctx.method} ${ctx.url} - ${rt}`);
}; };
export const perfromanceTimer = async (ctx: KoaContext, next: Next) => { export const perfromanceTimer = async (ctx: KoaContext, next: Next) => {
const start = Date.now(); const start = Date.now();
await next(); await next();
const ms = Date.now() - start; const ms = Date.now() - start;
ctx.set('X-Response-Time', `${ms}ms`); ctx.set('X-Response-Time', `${ms}ms`);
}; };

View File

@@ -1,11 +1,5 @@
import { JwtPayload } from 'jsonwebtoken'; import { JwtPayload } from 'jsonwebtoken';
import { import { InferSchemaType, Model, Schema, StringSchemaDefinition, Types } from 'mongoose';
InferSchemaType,
Model,
Schema,
StringSchemaDefinition,
Types,
} from 'mongoose';
import { Strategy } from './strategy'; import { Strategy } from './strategy';
import { STRATEGIES } from '../constants/strategies'; import { STRATEGIES } from '../constants/strategies';
@@ -14,139 +8,132 @@ import { encrypt, verify as verifyPassword } from '../utils/password';
import { generateResetToken } from '../utils/tokens'; import { generateResetToken } from '../utils/tokens';
export type Auth = { export type Auth = {
is2FA?: boolean; is2FA?: boolean;
record: StringSchemaDefinition; record: StringSchemaDefinition;
username: string; username: string;
}; };
export type AuthPrivate = Auth & { export type AuthPrivate = Auth & {
strategies: Types.ArraySubdocument<Strategy>; strategies: Types.ArraySubdocument<Strategy>;
}; };
export interface AuthMethods { export interface AuthMethods {
authenticate(password: string): boolean; authenticate(password: string): boolean;
getAuthStrategy(method?: STRATEGIES): Strategy | false; getAuthStrategy(method?: STRATEGIES): Strategy | false;
getResetLink(route: string): Promise<string | undefined>; getResetLink(route: string): Promise<string | undefined>;
getResetToken(): Promise<string | undefined>; getResetToken(): Promise<string | undefined>;
getToken(props?: Omit<TokenProps, 'sub'>): string; getToken(props?: Omit<TokenProps, 'sub'>): string;
setPassword(password: string): Promise<boolean>; setPassword(password: string): Promise<boolean>;
} }
export interface AuthModel extends Model<AuthPrivate, {}, AuthMethods> { export interface AuthModel extends Model<AuthPrivate, {}, AuthMethods> {
authenticate(password: any): boolean; authenticate(password: any): boolean;
findByUsername(username: string): Promise<AuthModel & AuthPrivate>; findByUsername(username: string): Promise<AuthModel & AuthPrivate>;
isUsernameAvailable(username: string): Promise<boolean>; isUsernameAvailable(username: string): Promise<boolean>;
findUserForReset( findUserForReset(strategy: STRATEGIES, token: string): Promise<Strategy | undefined>;
strategy: STRATEGIES, resetPassword(token: string, password: string): Promise<boolean>;
token: string
): Promise<Strategy | undefined>;
resetPassword(token: string, password: string): Promise<boolean>;
} }
export const AuthSchema = new Schema<AuthPrivate, AuthModel, AuthMethods>( export const AuthSchema = new Schema<AuthPrivate, AuthModel, AuthMethods>(
{ {
is2FA: { type: Boolean, default: false }, is2FA: { type: Boolean, default: false },
record: { type: Types.ObjectId }, record: { type: Types.ObjectId },
strategies: { type: Types.ArraySubdocument<Strategy>, required: true }, strategies: { type: Types.ArraySubdocument<Strategy>, required: true },
username: { type: String, required: true, unique: true }, username: { type: String, required: true, unique: true },
}, },
{ {
minimize: true, minimize: true,
timestamps: true, timestamps: true,
} },
); );
AuthSchema.methods = { AuthSchema.methods = {
authenticate: function (password: string) { authenticate(password: string) {
const strategy = this.getAuthStrategy(STRATEGIES.LOCAL); const strategy = this.getAuthStrategy(STRATEGIES.LOCAL);
return !!strategy && verifyPassword(password, strategy.key); return !!strategy && verifyPassword(password, strategy.key);
}, },
getAuthStrategy: function (method = STRATEGIES.LOCAL) { getAuthStrategy(method = STRATEGIES.LOCAL) {
return ( return this.strategies.filter((strategy: Strategy) => strategy.method === method).pop() || false;
this.strategies },
.filter((strategy: Strategy) => strategy.method === method)
.pop() || false
);
},
getToken: function (props = {}) { getToken(props = {}) {
return sign({ return sign({
sub: this._id, sub: this._id,
...props, ...props,
}); });
}, },
getResetLink: async function (route) { async getResetLink(route) {
const resetToken = await this.getResetToken(); const resetToken = await this.getResetToken();
if (resetToken) { if (resetToken) {
let resetRoute = route; let resetRoute = route;
resetRoute = resetRoute.replace(':user_id', this._id); resetRoute = resetRoute.replace(':user_id', this._id);
resetRoute = resetRoute.replace(':reset_token?', resetToken); resetRoute = resetRoute.replace(':reset_token?', resetToken);
const resetUrl = `${process.env.URL}${resetRoute}`; const resetUrl = `${process.env.URL}${resetRoute}`;
console.log('[sendPasswordReset] resetUrl:', resetUrl); console.log('[sendPasswordReset] resetUrl:', resetUrl);
return resetUrl; return resetUrl;
} }
}, },
getResetToken: async function () { async getResetToken() {
const { key, token } = generateResetToken(this._id); const { key, token } = generateResetToken(this._id);
this.resetCheckBit = key; this.resetCheckBit = key;
await this.save().catch(() => undefined); await this.save().catch(() => undefined);
return token; return token;
}, },
setPassword: async function (password) { async setPassword(password) {
const key = encrypt(password); const key = encrypt(password);
const hasLocalStrategy = !!this.getAuthStrategy(STRATEGIES.LOCAL); const hasLocalStrategy = !!this.getAuthStrategy(STRATEGIES.LOCAL);
const strategy = { const strategy = {
key, key,
method: STRATEGIES.LOCAL, method: STRATEGIES.LOCAL,
resetToken: undefined, resetToken: undefined,
}; };
if (hasLocalStrategy) { if (hasLocalStrategy) {
await this.model('User') await this.model('User')
.findOneAndUpdate( .findOneAndUpdate(
{ _id: this._id, 'strategies.method': STRATEGIES.LOCAL }, { _id: this._id, 'strategies.method': STRATEGIES.LOCAL },
{ $set: { 'strategies.$': strategy } }, { $set: { 'strategies.$': strategy } },
{ upsert: true }, { upsert: true },
) )
.catch(); .catch();
return true; return true;
} }
this.credentials.push(strategy); this.credentials.push(strategy);
await this.save().catch(() => false); await this.save().catch(() => false);
return true; return true;
} },
}; };
AuthSchema.statics = { AuthSchema.statics = {
// authenticateAndGetRecordLocator: async function (username, password) { // authenticateAndGetRecordLocator: async function (username, password) {
// const auth = await this.findByUserName(username); // const auth = await this.findByUserName(username);
// if (auth && auth.authenticate(password)) { // if (auth && auth.authenticate(password)) {
// return auth?.record; // return auth?.record;
// } // }
// return false; // return false;
// }, // },
findByUsername: async function (username) { async findByUsername(username) {
return this.findOne({ username }); return this.findOne({ username });
}, },
isUsernameAvailable: async function (username) { async isUsernameAvailable(username) {
return !this.findByUsername(username); return !this.findByUsername(username);
}, },
resetPassword: async function (token, password) { async resetPassword(token, password) {
const decoded = verifyJwt(token); const decoded = verifyJwt(token);
const { sub, key } = decoded as JwtPayload; const { sub, key } = decoded as JwtPayload;
const auth = await this.findOne({ const auth = await this.findOne({
_id: sub, _id: sub,
'strategies.resetToken': key, 'strategies.resetToken': key,
}).catch(); }).catch();
return !!auth && auth.setPassword(password); return !!auth && auth.setPassword(password);
} },
}; };
export type AuthSchema = InferSchemaType<typeof AuthSchema>; export type AuthSchema = InferSchemaType<typeof AuthSchema>;

View File

@@ -2,24 +2,24 @@ import { InferSchemaType, Schema, Types } from 'mongoose';
import { STRATEGIES } from '../constants/strategies'; import { STRATEGIES } from '../constants/strategies';
export const Strategy = new Schema( export const Strategy = new Schema(
{ {
method: { method: {
type: Number, type: Number,
enum: Object.values(STRATEGIES), enum: Object.values(STRATEGIES),
index: true, index: true,
required: true, required: true,
unique: 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<typeof Strategy>; export type Strategy = InferSchemaType<typeof Strategy>;

View File

@@ -2,11 +2,12 @@ import dotenv from 'dotenv';
import app from './app'; import app from './app';
import { connection } from './database/database.connection'; import { connection } from './database/database.connection';
dotenv.config(); dotenv.config();
const PORT: number = Number(process.env.PORT) || 9000; const PORT: number = Number(process.env.PORT) || 9000;
connection.then( connection.then(
() => app.listen(PORT), () => app.listen(PORT),
(err) => console.error('ERROR!', err), (err) => console.error('ERROR!', err),
); );

View File

@@ -1,19 +1,19 @@
import passport from 'koa-passport'; import koaPassport from 'koa-passport';
import { Strategy } from 'passport-local'; import { Strategy } from 'passport-local';
import Auth from '../model/auth'; import Auth from '../model/auth';
export const localStrategy = passport.use( export const localStrategy = passport.use(
new Strategy(async (username, password, done) => { new Strategy(async (username, password, done) => {
const user = await Auth.findOne({ const user = await Auth.findOne({
where: { where: {
username, username,
} },
}).catch(); }).catch();
if (user && user.authenticate(password)) { if (user && user.authenticate(password)) {
done(null, user); done(null, user);
} else { } else {
done(null, false); done(null, false);
} }
}) }),
); );

View File

@@ -1,17 +1,14 @@
import Auth from '../model/auth'; import auth from '../model/auth';
import { AuthModel, AuthPrivate } from '../schema/auth'; import { AuthModel, AuthPrivate } from '../schema/auth';
import { sign } from './jwt'; import { sign } from './jwt';
export const getAuthenticationBundle = async ( export const getAuthenticationBundle = async (username: string, password: string) => {
username: string, const auth = await Auth.findByUsername(username).catch();
password: string, const isAuthenticated = !!auth && (auth as AuthModel).authenticate(password);
) => { const record = isAuthenticated ? (auth as AuthPrivate).record : null;
const auth = await Auth.findByUsername(username).catch(); const token = isAuthenticated ? (auth as AuthModel).getToken() : sign();
const isAuthenticated = !!auth && (auth as AuthModel).authenticate(password); return {
const record = isAuthenticated ? (auth as AuthPrivate).record : null; record,
const token = isAuthenticated ? (auth as AuthModel).getToken() : sign(); token,
return { };
record,
token,
};
}; };

View File

@@ -1,40 +1,35 @@
import jwt, { JwtPayload } from 'jsonwebtoken'; import jsonwebtoken, { JwtPayload } from 'jsonwebtoken';
export interface TokenProps { export interface TokenProps {
aud?: string; aud?: string;
exp?: number | Date; exp?: number | Date;
iss?: string; iss?: string;
sub: string | null; sub: string | null;
[key: string]: any; [key: string]: any;
} }
export type SignProps = string | TokenProps | void; export type SignProps = string | TokenProps | void;
export const sign = (props: SignProps) => { export const sign = (props: SignProps) => {
const today = new Date(); const today = new Date();
const { sub = null, ...rest }: TokenProps = const { sub = null, ...rest }: TokenProps =
typeof props === 'string' || typeof props === 'undefined' typeof props === 'string' || typeof props === 'undefined' ? { sub: props || null } : props;
? { sub: props || null } let { exp } = rest;
: props; if (!exp) {
let exp = rest.exp; exp = new Date(today);
if (!exp) { exp.setDate(today.getDate() + parseInt(process.env.JWT_DAYS_VALID as string));
exp = new Date(today); exp = exp.getTime() / 1000;
exp.setDate( }
today.getDate() + parseInt(process.env.JWT_DAYS_VALID as string), 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) => export const verify = (token: string) => jwt.verify(token, process.env.JWT_SECRET || 'secret');
jwt.verify(token, process.env.JWT_SECRET || 'secret');

View File

@@ -1,12 +1,12 @@
import { pbkdf2Sync, randomBytes } from 'crypto'; import { pbkdf2Sync, randomBytes } from 'crypto';
export const encrypt = (password: string) => { export const encrypt = (password: string) => {
const salt = randomBytes(16).toString('hex'); const salt = randomBytes(16).toString('hex');
const hash = pbkdf2Sync(password, salt, 10000, 512, 'sha512').toString('hex'); const hash = pbkdf2Sync(password, salt, 10000, 512, 'sha512').toString('hex');
return `${salt}:${hash}`; return `${salt}:${hash}`;
}; };
export const verify = (test: string, secret: string) => { export const verify = (test: string, secret: string) => {
const [salt, hash] = secret.split(':'); const [salt, hash] = secret.split(':');
return pbkdf2Sync(test, salt, 10000, 512, 'sha512').toString('hex') === hash; return pbkdf2Sync(test, salt, 10000, 512, 'sha512').toString('hex') === hash;
}; };

View File

@@ -3,11 +3,11 @@ import crypto from 'crypto';
import { sign } from './jwt'; import { sign } from './jwt';
export const generateResetToken = (sub: string) => { export const generateResetToken = (sub: string) => {
const key = crypto.randomBytes(16).toString('hex'); const key = crypto.randomBytes(16).toString('hex');
const token = sign({ const token = sign({
sub, sub,
key, key,
exp: Date.now() + 24 * 60 * 60 * 1000, exp: Date.now() + 24 * 60 * 60 * 1000,
}); });
return { key, token }; return { key, token };
}; };

View File

@@ -5,8 +5,9 @@
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
"lint": "tslint --project tsconfig.json --format stylish", "format": "prettier:fix && lint:fix",
"prettier:fix": "prettier-eslint --write '**/*.ts'", "lint": "eslint . --ext .js",
"prettier:fix": "prettier --write 'lib/**/*.ts'",
"serve": "ts-node src/server.ts", "serve": "ts-node src/server.ts",
"start": "nodemon" "start": "nodemon"
}, },
@@ -30,11 +31,13 @@
"@types/passport-google-oauth": "^1.0.42", "@types/passport-google-oauth": "^1.0.42",
"@types/passport-jwt": "^3.0.8", "@types/passport-jwt": "^3.0.8",
"@types/passport-local": "^1.0.35", "@types/passport-local": "^1.0.35",
"eslint": "^8.13.0", "@typescript-eslint/eslint-plugin": "^5.59.2",
"eslint-config-semistandard": "latest", "@typescript-eslint/parser": "^5.59.2",
"eslint-config-standard": "^17.0.0", "eslint": "^8.39.0",
"eslint-plugin-import": "^2.26.0", "eslint-config-prettier": "^8.8.0",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-n": "^15.0.0", "eslint-plugin-n": "^15.0.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-promise": "^6.0.0", "eslint-plugin-promise": "^6.0.0",
"jest": "^29.4.2", "jest": "^29.4.2",
"nodemon": "^2.0.20", "nodemon": "^2.0.20",
@@ -45,6 +48,8 @@
"ts-node": "^10.9.1", "ts-node": "^10.9.1",
"tslint": "^6.1.3", "tslint": "^6.1.3",
"tslint-config-airbnb": "^5.11.2", "tslint-config-airbnb": "^5.11.2",
"tslint-config-prettier": "^1.18.0",
"tslint-plugin-prettier": "^2.3.0",
"typescript": "^4.9.5" "typescript": "^4.9.5"
}, },
"dependencies": { "dependencies": {

View File

@@ -1,6 +0,0 @@
{
"extends": "tslint-config-airbnb",
"rules": {
"import-name": false
}
}

369
yarn.lock
View File

@@ -1827,12 +1827,14 @@ __metadata:
"@types/passport-google-oauth": ^1.0.42 "@types/passport-google-oauth": ^1.0.42
"@types/passport-jwt": ^3.0.8 "@types/passport-jwt": ^3.0.8
"@types/passport-local": ^1.0.35 "@types/passport-local": ^1.0.35
"@typescript-eslint/eslint-plugin": ^5.59.2
"@typescript-eslint/parser": ^5.59.2
dotenv: ^16.0.3 dotenv: ^16.0.3
eslint: ^8.13.0 eslint: ^8.39.0
eslint-config-semistandard: latest eslint-config-prettier: ^8.8.0
eslint-config-standard: ^17.0.0 eslint-plugin-import: ^2.27.5
eslint-plugin-import: ^2.26.0
eslint-plugin-n: ^15.0.0 eslint-plugin-n: ^15.0.0
eslint-plugin-prettier: ^4.2.1
eslint-plugin-promise: ^6.0.0 eslint-plugin-promise: ^6.0.0
http-status-codes: ^2.2.0 http-status-codes: ^2.2.0
jest: ^29.4.2 jest: ^29.4.2
@@ -1859,6 +1861,8 @@ __metadata:
ts-node: ^10.9.1 ts-node: ^10.9.1
tslint: ^6.1.3 tslint: ^6.1.3
tslint-config-airbnb: ^5.11.2 tslint-config-airbnb: ^5.11.2
tslint-config-prettier: ^1.18.0
tslint-plugin-prettier: ^2.3.0
typescript: ^4.9.5 typescript: ^4.9.5
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@@ -2292,7 +2296,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/json-schema@npm:*": "@types/json-schema@npm:*, @types/json-schema@npm:^7.0.9":
version: 7.0.11 version: 7.0.11
resolution: "@types/json-schema@npm:7.0.11" resolution: "@types/json-schema@npm:7.0.11"
checksum: 527bddfe62db9012fccd7627794bd4c71beb77601861055d87e3ee464f2217c85fca7a4b56ae677478367bbd248dbde13553312b7d4dbc702a2f2bbf60c4018d checksum: 527bddfe62db9012fccd7627794bd4c71beb77601861055d87e3ee464f2217c85fca7a4b56ae677478367bbd248dbde13553312b7d4dbc702a2f2bbf60c4018d
@@ -2523,6 +2527,13 @@ __metadata:
languageName: node languageName: node
linkType: hard 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:*": "@types/serve-static@npm:*":
version: 1.15.1 version: 1.15.1
resolution: "@types/serve-static@npm:1.15.1" resolution: "@types/serve-static@npm:1.15.1"
@@ -2573,6 +2584,30 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "@typescript-eslint/parser@npm:^5.10.0":
version: 5.59.0 version: 5.59.0
resolution: "@typescript-eslint/parser@npm:5.59.0" resolution: "@typescript-eslint/parser@npm:5.59.0"
@@ -2590,6 +2625,23 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "@typescript-eslint/scope-manager@npm:5.59.0":
version: 5.59.0 version: 5.59.0
resolution: "@typescript-eslint/scope-manager@npm:5.59.0" resolution: "@typescript-eslint/scope-manager@npm:5.59.0"
@@ -2600,6 +2652,33 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "@typescript-eslint/types@npm:5.59.0":
version: 5.59.0 version: 5.59.0
resolution: "@typescript-eslint/types@npm:5.59.0" resolution: "@typescript-eslint/types@npm:5.59.0"
@@ -2607,6 +2686,13 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "@typescript-eslint/typescript-estree@npm:5.59.0":
version: 5.59.0 version: 5.59.0
resolution: "@typescript-eslint/typescript-estree@npm:5.59.0" resolution: "@typescript-eslint/typescript-estree@npm:5.59.0"
@@ -2625,6 +2711,42 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "@typescript-eslint/visitor-keys@npm:5.59.0":
version: 5.59.0 version: 5.59.0
resolution: "@typescript-eslint/visitor-keys@npm:5.59.0" resolution: "@typescript-eslint/visitor-keys@npm:5.59.0"
@@ -2635,6 +2757,16 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "abbrev@npm:1, abbrev@npm:^1.0.0":
version: 1.1.1 version: 1.1.1
resolution: "abbrev@npm:1.1.1" resolution: "abbrev@npm:1.1.1"
@@ -4041,28 +4173,14 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"eslint-config-semistandard@npm:latest": "eslint-config-prettier@npm:^8.8.0":
version: 17.0.0 version: 8.8.0
resolution: "eslint-config-semistandard@npm:17.0.0" resolution: "eslint-config-prettier@npm:8.8.0"
peerDependencies: peerDependencies:
eslint: ^8.13.0 eslint: ">=7.0.0"
eslint-config-standard: ^17.0.0 bin:
eslint-plugin-import: ^2.26.0 eslint-config-prettier: bin/cli.js
eslint-plugin-n: ^15.0.0 checksum: 1e94c3882c4d5e41e1dcfa2c368dbccbfe3134f6ac7d40101644d3bfbe3eb2f2ffac757f3145910b5eacf20c0e85e02b91293d3126d770cbf3dc390b3564681c
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
languageName: node languageName: node
linkType: hard linkType: hard
@@ -4101,7 +4219,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"eslint-plugin-import@npm:^2.26.0": "eslint-plugin-import@npm:^2.27.5":
version: 2.27.5 version: 2.27.5
resolution: "eslint-plugin-import@npm:2.27.5" resolution: "eslint-plugin-import@npm:2.27.5"
dependencies: dependencies:
@@ -4144,6 +4262,33 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "eslint-plugin-promise@npm:^6.0.0":
version: 6.1.1 version: 6.1.1
resolution: "eslint-plugin-promise@npm:6.1.1" resolution: "eslint-plugin-promise@npm:6.1.1"
@@ -4153,6 +4298,16 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "eslint-scope@npm:^7.0.0, eslint-scope@npm:^7.1.1, eslint-scope@npm:^7.2.0":
version: 7.2.0 version: 7.2.0
resolution: "eslint-scope@npm:7.2.0" resolution: "eslint-scope@npm:7.2.0"
@@ -4204,56 +4359,6 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "eslint@npm:^8.21.0, eslint@npm:^8.7.0":
version: 8.38.0 version: 8.38.0
resolution: "eslint@npm:8.38.0" resolution: "eslint@npm:8.38.0"
@@ -4304,6 +4409,56 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "espree@npm:^9.0.0, espree@npm:^9.5.1":
version: 9.5.1 version: 9.5.1
resolution: "espree@npm:9.5.1" resolution: "espree@npm:9.5.1"
@@ -4343,6 +4498,13 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "estraverse@npm:^5.1.0, estraverse@npm:^5.2.0":
version: 5.3.0 version: 5.3.0
resolution: "estraverse@npm:5.3.0" resolution: "estraverse@npm:5.3.0"
@@ -4408,6 +4570,13 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "fast-glob@npm:^3.2.9":
version: 3.2.12 version: 3.2.12
resolution: "fast-glob@npm:3.2.12" resolution: "fast-glob@npm:3.2.12"
@@ -5541,6 +5710,13 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "jest-docblock@npm:^29.4.3":
version: 29.4.3 version: 29.4.3
resolution: "jest-docblock@npm:29.4.3" resolution: "jest-docblock@npm:29.4.3"
@@ -6669,6 +6845,13 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "natural-compare@npm:^1.4.0":
version: 1.4.0 version: 1.4.0
resolution: "natural-compare@npm:1.4.0" resolution: "natural-compare@npm:1.4.0"
@@ -7246,6 +7429,15 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "prettier@npm:^2.5.1, prettier@npm:^2.8.4":
version: 2.8.7 version: 2.8.7
resolution: "prettier@npm:2.8.7" resolution: "prettier@npm:2.8.7"
@@ -8147,6 +8339,15 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "tslint-consistent-codestyle@npm:^1.14.1":
version: 1.16.0 version: 1.16.0
resolution: "tslint-consistent-codestyle@npm:1.16.0" resolution: "tslint-consistent-codestyle@npm:1.16.0"
@@ -8187,6 +8388,20 @@ __metadata:
languageName: node languageName: node
linkType: hard 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": "tslint@npm:^6.1.3":
version: 6.1.3 version: 6.1.3
resolution: "tslint@npm:6.1.3" resolution: "tslint@npm:6.1.3"