diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 434ea8ba8..000000000 --- a/.eslintignore +++ /dev/null @@ -1,5 +0,0 @@ -**/build -**/coverage -**/node_modules -**/jest-dotenv.config.js -**/jest.config.ts diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 9151cb5d6..000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,94 +0,0 @@ -module.exports = { - env: { - es6: true, - node: true, - jest: true, - }, - extends: [ - 'eslint:recommended', - 'plugin:@typescript-eslint/recommended', - 'plugin:prettier/recommended', - 'plugin:@typescript-eslint/recommended-requiring-type-checking', - ], - ignorePatterns: [ - '.eslintrc.js', - 'jest.config.js', - 'jest.config.ts', - 'jest-dotenv.config.js', - 'coverage', - 'build', - 'node_modules', - 'scripts/**/*.mjs', - 'commitlint.config.js', - ], - parser: '@typescript-eslint/parser', - parserOptions: { - ecmaVersion: 2022, - sourceType: 'module', - }, - plugins: ['@typescript-eslint', 'simple-import-sort'], - root: true, - rules: { - 'no-console': 'warn', - '@typescript-eslint/no-unused-vars': [ - 'error', - { argsIgnorePattern: '^_', ignoreRestSiblings: true }, - ], - '@typescript-eslint/member-delimiter-style': [ - 'error', - { - multiline: { - delimiter: 'none', - requireLast: true, - }, - singleline: { - delimiter: 'semi', - requireLast: false, - }, - }, - ], - // Rules for auto sort of imports - 'simple-import-sort/imports': [ - 'error', - { - groups: [ - // Side effect imports. - ['^\\u0000'], - // Packages. - // Packages. `react` related packages come first. - // Things that start with a letter (or digit or underscore), or - // `@` followed by a letter. - ['^react', '^@?\\w'], - // Root imports - // Shared imports should be separate from application imports. - ['^(~shared)(/.*|$)'], - ['^(~)(/.*|$)'], - ['^(~typings)(/.*|$)'], - [ - '^(~assets|~theme)(/.*|$)', - '^(~contexts)(/.*|$)', - '^(~constants)(/.*|$)', - '^(~hooks)(/.*|$)', - '^(~utils)(/.*|$)', - '^(~services)(/.*|$)', - '^(~components)(/.*|$)', - '^(~templates)(/.*|$)', - ], - ['^(~pages)(/.*|$)', '^(~features)(/.*|$)'], - // Parent imports. Put `..` last. - ['^\\.\\.(?!/?$)', '^\\.\\./?$'], - // Other relative imports. Put same-folder imports and `.` last. - ['^\\./(?=.*/)(?!/?$)', '^\\.(?!/?$)', '^\\./?$'], - ], - }, - ], - 'simple-import-sort/exports': 'error', - '@typescript-eslint/no-unsafe-assignment': 'warn', - '@typescript-eslint/no-unsafe-member-access': 'warn', - '@typescript-eslint/require-await': 'warn', - '@typescript-eslint/no-unsafe-return': 'warn', - '@typescript-eslint/no-unsafe-call': 'warn', - '@typescript-eslint/no-floating-promises': 'warn', - '@typescript-eslint/no-misused-promises': 'warn', - }, -} diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index 51d2ee696..000000000 --- a/.prettierrc.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - trailingComma: 'all', - tabWidth: 2, - semi: false, - singleQuote: true, -} diff --git a/backend/.eslintrc.js b/backend/.eslintrc.js deleted file mode 100644 index 91db1642d..000000000 --- a/backend/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - extends: ['../.eslintrc.js'], - parserOptions: { - project: ['./tsconfig.json'], - tsconfigRootDir: __dirname, - }, -} diff --git a/backend/jest.config.ts b/backend/jest.config.ts index 795ef4fc4..4b2c798c8 100644 --- a/backend/jest.config.ts +++ b/backend/jest.config.ts @@ -8,8 +8,8 @@ const config: Config.InitialOptions = { collectCoverageFrom: ['/src/**/*.{ts,js}'], coveragePathIgnorePatterns: ['/build', '/node_modules'], moduleNameMapper: { - '~shared/(.*)': '/../shared/src/$1', - }, + '~shared/(.*)': '/../shared/src/$1' + } } export default config diff --git a/backend/package-lock.json b/backend/package-lock.json index df33fc129..99554ba0c 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -49,7 +49,6 @@ "jest": "^28.1.3", "lint-staged": "^13.0.4", "pino-pretty": "^9.1.1", - "prettier": "^2.8.0", "rimraf": "^3.0.2", "supertest": "^6.3.1", "ts-jest": "^28.0.8", @@ -9631,21 +9630,6 @@ "node": ">=0.10.0" } }, - "node_modules/prettier": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.0.tgz", - "integrity": "sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, "node_modules/pretty-format": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", @@ -19419,12 +19403,6 @@ "xtend": "^4.0.0" } }, - "prettier": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.0.tgz", - "integrity": "sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==", - "dev": true - }, "pretty-format": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", diff --git a/backend/package.json b/backend/package.json index 6e7f5397f..2471b013c 100644 --- a/backend/package.json +++ b/backend/package.json @@ -3,8 +3,8 @@ "version": "0.1.0", "private": true, "scripts": { - "lint": "eslint --ext ts,tsx,js,jsx . && prettier -c \"src/**/*.{ts,tsx}\"", - "lint:fix": "eslint --fix --ext ts,tsx,js,jsx . && prettier -c --write \"src/**/*.{ts,tsx}\"", + "lint": "ts-standard", + "lint:fix": "npm run lint -- --fix", "pre-commit": "lint-staged", "prebuild": "rimraf build", "build": "nest build", @@ -73,7 +73,6 @@ "jest": "^28.1.3", "lint-staged": "^13.0.4", "pino-pretty": "^9.1.1", - "prettier": "^2.8.0", "rimraf": "^3.0.2", "supertest": "^6.3.1", "ts-jest": "^28.0.8", @@ -84,7 +83,12 @@ }, "lint-staged": { "**/*.(js|jsx|ts|tsx)": [ - "eslint --fix" + "ts-standard --fix" + ] + }, + "ts-standard": { + "ignore": [ + "build" ] } } diff --git a/backend/scripts/env/loader.mjs b/backend/scripts/env/loader.mjs index 125a72e8c..6476b94f2 100644 --- a/backend/scripts/env/loader.mjs +++ b/backend/scripts/env/loader.mjs @@ -3,17 +3,17 @@ import fs from 'fs' import { exit } from 'process' /** - * This is a helper for local file runs or jest, as specified in package.json - * It emulates the loading of SSM which Lambda will do. + * This is a helper for local file runs or jest, as specified in package.json + * It emulates the loading of SSM which Lambda will do. * This is not meant to be used in a deployment and is .mjs so we can use top-level await */ -async function loadAllParameters() { +async function loadAllParameters () { console.log(`Retrieving parameters for ENV=${process.env.ENV}`) if (process.env.ENV === 'development') { console.log('In develop mode! Not fetching from SSM param store.') console.log( - 'Please reference .env.example to populate .env.development file for development environment', + 'Please reference .env.example to populate .env.development file for development environment' ) exit(0) } @@ -30,8 +30,8 @@ async function loadAllParameters() { Path: prefix, Recursive: true, WithDecryption: true, - ...(nextToken ? { NextToken: nextToken } : {}), - }), + ...(nextToken ? { NextToken: nextToken } : {}) + }) ) for (const parameter of res.Parameters ?? []) { @@ -56,14 +56,14 @@ async function loadAllParameters() { return looksLikeJson ? `${k}=${strippedValue}` : `${k}='${strippedValue}'` }) .join('\n') - .concat(params['NODE_ENV'] ? '' : `\nNODE_ENV=${process.env.ENV}`) + .concat(params.NODE_ENV ? '' : `\nNODE_ENV=${process.env.ENV}`) if (Object.entries(params).length > 0) { console.log(`Writing to file .env.${process.env.ENV}`) await fs.promises.writeFile(`.env.${process.env.ENV}`, envString) } else { console.log( - `No env vars found, not writing to file .env.${process.env.ENV}`, + `No env vars found, not writing to file .env.${process.env.ENV}` ) } } diff --git a/backend/scripts/env/putter.mjs b/backend/scripts/env/putter.mjs index 8f1739444..831815254 100644 --- a/backend/scripts/env/putter.mjs +++ b/backend/scripts/env/putter.mjs @@ -4,11 +4,11 @@ import { exit } from 'process' import dotenv from 'dotenv' /** - * This is a helper for local file runs or jest, as specified in package.json - * It emulates the putting of parameters into SSM which Lambda will do. + * This is a helper for local file runs or jest, as specified in package.json + * It emulates the putting of parameters into SSM which Lambda will do. * This is not meant to be used in a deployment and is .mjs so we can use top-level await */ -async function putAllParameters() { +async function putAllParameters () { console.log(`Retrieving parameters for ENV=${process.env.ENV}`) if (process.env.ENV === 'development') { @@ -29,8 +29,8 @@ async function putAllParameters() { Path: prefix, Recursive: true, WithDecryption: true, - ...(nextToken ? { NextToken: nextToken } : {}), - }), + ...(nextToken ? { NextToken: nextToken } : {}) + }) ) for (const parameter of res.Parameters ?? []) { @@ -53,11 +53,11 @@ async function putAllParameters() { if (Object.keys(params).includes(k) && params[k] !== v) { // different values, set override flag console.log( - `aws ssm put-parameter --overwrite --name /application/${process.env.ENV}/${k} --value ${v} --type String`, + `aws ssm put-parameter --overwrite --name /application/${process.env.ENV}/${k} --value ${v} --type String` ) } else if (!Object.keys(params).includes(k)) { console.log( - `aws ssm put-parameter --name /application/${process.env.ENV}/${k} --value ${v} --type String`, + `aws ssm put-parameter --name /application/${process.env.ENV}/${k} --value ${v} --type String` ) } } diff --git a/backend/src/api.module.ts b/backend/src/api.module.ts index e40bb4a16..400942343 100644 --- a/backend/src/api.module.ts +++ b/backend/src/api.module.ts @@ -12,7 +12,7 @@ const apiModules = [ TerminusModule, HealthModule, OtpModule, - MailerModule, + MailerModule ] @Module({ @@ -21,9 +21,9 @@ const apiModules = [ RouterModule.register([ { path: 'api', - children: apiModules, - }, - ]), - ], + children: apiModules + } + ]) + ] }) export class ApiModule {} diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index e7c167f52..c4e20168f 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -29,7 +29,7 @@ const FRONTEND_PATH = join(__dirname, '..', '..', 'frontend', 'build') customProps: (req) => { const context = { trace_id: req.headers['x-datadog-trace-id'], - xray_id: req.headers['x-amzn-trace-id'], + xray_id: req.headers['x-amzn-trace-id'] } return { context, scope: 'NestApplication' } }, @@ -40,15 +40,15 @@ const FRONTEND_PATH = join(__dirname, '..', '..', 'frontend', 'build') return `${req.method ?? ''} ${req.url ?? ''} ${res.statusCode}: (${ err.name }) ${err.message}` - }, + } }, - renameContext: 'scope', - }), + renameContext: 'scope' + }) }), TypeOrmModule.forRootAsync({ imports: [ConfigModule], inject: [ConfigService], - useClass: DatabaseConfigService, + useClass: DatabaseConfigService }), ServeStaticModule.forRoot({ rootPath: FRONTEND_PATH, @@ -60,13 +60,13 @@ const FRONTEND_PATH = join(__dirname, '..', '..', 'frontend', 'build') if (path === join(FRONTEND_PATH, 'index.html')) { res.setHeader('Cache-control', 'public, max-age=0') } - }, - }, - }), - ], + } + } + }) + ] }) export class AppModule implements NestModule { - configure(consumer: MiddlewareConsumer): void { + configure (consumer: MiddlewareConsumer): void { consumer.apply(HelmetMiddleware, SessionMiddleware).forRoutes('*') } } diff --git a/backend/src/auth/__tests__/auth.controller.spec.ts b/backend/src/auth/__tests__/auth.controller.spec.ts index 3bbf5507f..a9b2468f4 100644 --- a/backend/src/auth/__tests__/auth.controller.spec.ts +++ b/backend/src/auth/__tests__/auth.controller.spec.ts @@ -21,21 +21,21 @@ describe('AuthController', () => { AuthService, { provide: getRepositoryToken(User), - useValue: mockModel, + useValue: mockModel }, { provide: getRepositoryToken(Session), - useValue: mockModel, + useValue: mockModel }, { provide: `${PinoLogger.name}:${AuthController.name}`, - useValue: console, + useValue: console }, { provide: `${PinoLogger.name}:${AuthService.name}`, - useValue: console, - }, - ], + useValue: console + } + ] }).compile() controller = module.get(AuthController) diff --git a/backend/src/auth/__tests__/auth.service.spec.ts b/backend/src/auth/__tests__/auth.service.spec.ts index 276bd9648..2c088c46f 100644 --- a/backend/src/auth/__tests__/auth.service.spec.ts +++ b/backend/src/auth/__tests__/auth.service.spec.ts @@ -21,17 +21,17 @@ describe('AuthService', () => { MailerService, { provide: getRepositoryToken(User), - useValue: mockModel, + useValue: mockModel }, { provide: getRepositoryToken(Session), - useValue: mockModel, + useValue: mockModel }, { provide: `${PinoLogger.name}:${AuthService.name}`, - useValue: console, - }, - ], + useValue: console + } + ] }).compile() service = module.get(AuthService) diff --git a/backend/src/auth/auth.controller.ts b/backend/src/auth/auth.controller.ts index f6fe65b54..fc92a25cc 100644 --- a/backend/src/auth/auth.controller.ts +++ b/backend/src/auth/auth.controller.ts @@ -6,7 +6,7 @@ import { Post, Req, Res, - Session, + Session } from '@nestjs/common' import { Request, Response } from 'express' import { InjectPinoLogger, PinoLogger } from 'nestjs-pino' @@ -20,17 +20,17 @@ import { AuthService } from './auth.service' @Controller('auth') export class AuthController { - constructor( + constructor ( private readonly config: ConfigService, private readonly authService: AuthService, @InjectPinoLogger(AuthController.name) - private readonly logger: PinoLogger, - ) {} + private readonly logger: PinoLogger + ) { } @Post() - async generateOtp( + async generateOtp ( @Res() res: Response, - @Body() generateOtpDto: GenerateOtpDto, + @Body() generateOtpDto: GenerateOtpDto ): Promise { try { await this.authService.generateOtp(generateOtpDto) @@ -44,17 +44,17 @@ export class AuthController { } @Post('verify') - async verifyOtp( + async verifyOtp ( @Req() req: Request, - @Res() res: Response, - @Body() verifyOtpDto: VerifyOtpDto, + @Res() res: Response, + @Body() verifyOtpDto: VerifyOtpDto ): Promise { try { const user = await this.authService.verifyOtp(verifyOtpDto) - if (user) { + if (user !== undefined && user !== null) { req.session.user = user this.logger.info( - `Successfully verified OTP for user ${verifyOtpDto.email}`, + `Successfully verified OTP for user ${verifyOtpDto.email}` ) res.status(HttpStatus.OK).json({ message: 'OTP verified' }) } else { @@ -72,22 +72,22 @@ export class AuthController { } @Post('logout') - async logout( + async logout ( @Req() req: Request, - @Session() session: UserSession, - @Res({ passthrough: true }) res: Response, + @Session() session: UserSession, + @Res({ passthrough: true }) res: Response ): Promise { res.clearCookie(this.config.get('session.name')) session.destroy(() => - res.status(HttpStatus.OK).json({ message: 'Logged out' }), + res.status(HttpStatus.OK).json({ message: 'Logged out' }) ) } @Get('whoami') - async whoami(@Req() req: Request, @Res() res: Response): Promise { + async whoami (@Req() req: Request, @Res() res: Response): Promise { const user = req.session.user res .status(HttpStatus.OK) - .json(user ? { id: user.id, email: user.email } : null) + .json((user !== undefined && user !== null) ? { id: user.id, email: user.email } : null) } } diff --git a/backend/src/auth/auth.module.ts b/backend/src/auth/auth.module.ts index d53f5e4b1..bbb2fc604 100644 --- a/backend/src/auth/auth.module.ts +++ b/backend/src/auth/auth.module.ts @@ -14,9 +14,9 @@ import { AuthService } from './auth.service' ConfigModule, OtpModule, MailerModule, - TypeOrmModule.forFeature([User, Session]), + TypeOrmModule.forFeature([User, Session]) ], controllers: [AuthController], - providers: [AuthService], + providers: [AuthService] }) export class AuthModule {} diff --git a/backend/src/auth/auth.service.ts b/backend/src/auth/auth.service.ts index 3ab413a65..2816af496 100644 --- a/backend/src/auth/auth.service.ts +++ b/backend/src/auth/auth.service.ts @@ -12,19 +12,19 @@ import { OtpService } from '../otp/otp.service' @Injectable() export class AuthService { - constructor( + constructor ( @InjectRepository(User) private readonly usersRepository: Repository, @InjectRepository(Session) private readonly sessionRepository: Repository, - private otpService: OtpService, - private mailerService: MailerService, - private config: ConfigService, + private readonly otpService: OtpService, + private readonly mailerService: MailerService, + private readonly config: ConfigService, @InjectPinoLogger(AuthService.name) - private readonly logger: PinoLogger, + private readonly logger: PinoLogger ) {} - async generateOtp(generateOtpDto: GenerateOtpDto): Promise { + async generateOtp (generateOtpDto: GenerateOtpDto): Promise { const { email } = generateOtpDto const { token, timeLeft } = this.otpService.generateOtp(email) @@ -36,32 +36,32 @@ export class AuthService { const mail = { to: email, from: `${this.config.get('otp.sender_name')} <${this.config.get( - 'otp.email', + 'otp.email' )}>`, subject: 'One-Time Password (OTP) for Starter Kit', - html, + html } this.logger.info(`Sending mail to ${email}`) - return this.mailerService.sendMail(mail) + return await this.mailerService.sendMail(mail) } - async verifyOtp(verifyOtpDto: VerifyOtpDto): Promise { + async verifyOtp (verifyOtpDto: VerifyOtpDto): Promise { const { email, token } = verifyOtpDto const isVerified = this.otpService.verifyOtp(email, token) return isVerified ? await this.findOrCreate( - { where: { email } }, - { - email, - }, - ) + { where: { email } }, + { + email + } + ) : undefined } - async findOrCreate( + async findOrCreate ( query: FindOneOptions>, - create: Partial>, + create: Partial> ): Promise { const user = await this.usersRepository.findOne(query) return user ?? (await this.usersRepository.save(create)) diff --git a/backend/src/config/config.module.ts b/backend/src/config/config.module.ts index 8c44b4280..eb78c36c4 100644 --- a/backend/src/config/config.module.ts +++ b/backend/src/config/config.module.ts @@ -5,6 +5,6 @@ import { ConfigService } from './config.service' @Global() @Module({ providers: [ConfigService], - exports: [ConfigService], + exports: [ConfigService] }) export class ConfigModule {} diff --git a/backend/src/config/config.schema.ts b/backend/src/config/config.schema.ts index 8989fb943..6c99daa98 100644 --- a/backend/src/config/config.schema.ts +++ b/backend/src/config/config.schema.ts @@ -39,17 +39,17 @@ export interface ConfigSchema { host: string port: number } - health: { heapSizeThreshold: number; rssThreshold: number } + health: { heapSizeThreshold: number, rssThreshold: number } } addFormats({ 'required-string': { validate: (val?: string): void => { - if (val == undefined || val === '') { + if (val === undefined || val === null || val === '') { throw new Error('Required value cannot be empty') } - }, - }, + } + } }) export const schema: Schema = { @@ -57,125 +57,125 @@ export const schema: Schema = { doc: 'The port that the service listens on', env: 'PORT', format: 'int', - default: 8080, + default: 8080 }, environment: { doc: 'The environment that Node.js is running in', env: 'NODE_ENV', format: ['development', 'staging', 'production', 'test'], - default: 'development', + default: 'development' }, awsRegion: { doc: 'The AWS region for SES. Optional, logs mail to console if absent', env: 'AWS_REGION', format: '*', - default: '', + default: '' }, database: { username: { env: 'DB_USERNAME', sensitive: true, default: '', - format: 'required-string', + format: 'required-string' }, password: { env: 'DB_PASSWORD', sensitive: true, default: '', - format: 'required-string', + format: 'required-string' }, host: { env: 'DB_HOST', default: 'localhost', - format: 'required-string', + format: 'required-string' }, port: { env: 'DB_PORT', default: 5432, - format: Number, + format: Number }, name: { env: 'DB_NAME', default: '', - format: 'required-string', + format: 'required-string' }, logging: { env: 'DB_LOGGING', - default: false, + default: false }, minPool: { env: 'DB_MIN_POOL_SIZE', - default: 10, + default: 10 }, maxPool: { env: 'DB_MAX_POOL_SIZE', - default: 100, + default: 100 }, ca: { env: 'CA_CERT', default: '', - format: String, - }, + format: String + } }, session: { name: { doc: 'Name of session ID cookie to set in response', env: 'SESSION_NAME', default: 'ts-template.sid', - format: String, + format: String }, secret: { doc: 'A secret string used to generate sessions for users', env: 'SESSION_SECRET', default: 'toomanysecrets', - format: String, + format: String }, cookie: { maxAge: { doc: 'The maximum age for a cookie, expressed in ms', env: 'COOKIE_MAX_AGE', format: 'int', - default: 24 * 60 * 60 * 1000, // 24 hours - }, - }, + default: 24 * 60 * 60 * 1000 // 24 hours + } + } }, otp: { expiry: { doc: 'The number of seconds that an OTP is valid for a user', env: 'OTP_EXPIRY', format: 'int', - default: 300, + default: 300 }, secret: { doc: 'A secret string used to generate TOTPs for users', env: 'OTP_SECRET', format: '*', - default: 'toomanysecrets', + default: 'toomanysecrets' }, numValidPastWindows: { doc: 'The number of past windows for which tokens should be considered valid, where a window is the duration that an OTP is valid for, e.g. OTP expiry time.', env: 'OTP_NUM_VALID_PAST_WINDOWS', format: 'int', - default: 1, + default: 1 }, numValidFutureWindows: { doc: 'The number of future windows for which tokens should be considered valid, where a window is the duration that an OTP is valid for, e.g. OTP expiry time.', env: 'OTP_NUM_VALID_FUTURE_WINDOWS', format: 'int', - default: 0, + default: 0 }, sender_name: { doc: 'Name of email sender', env: 'OTP_SENDER_NAME', format: String, - default: 'Starter Kit', + default: 'Starter Kit' }, email: { doc: 'Email to send OTP emails from', env: 'OTP_EMAIL', format: String, - default: 'donotreply@mail.open.gov.sg', - }, + default: 'donotreply@mail.open.gov.sg' + } }, mailer: { doc: @@ -186,33 +186,33 @@ export const schema: Schema = { type: { doc: 'The type of authentication used. Currently, only "login" is supported', format: ['login'], - default: 'login', + default: 'login' }, user: { doc: 'The user to present to the SMTP service', env: 'MAILER_USER', format: String, - default: 'mailer-user', + default: 'mailer-user' }, pass: { doc: 'The password to present to the SMTP service', env: 'MAILER_PASSWORD', format: String, - default: 'mailer-password', - }, + default: 'mailer-password' + } }, host: { doc: 'The server hosting the SMTP service', env: 'MAILER_HOST', format: String, - default: 'localhost', + default: 'localhost' }, port: { doc: 'The port for the SMTP service', env: 'MAILER_PORT', format: 'port', - default: 1025, - }, + default: 1025 + } }, health: { heapSizeThreshold: { @@ -220,14 +220,14 @@ export const schema: Schema = { env: 'HEAP_SIZE_THRESHOLD', format: 'int', // TODO: Set to a more reasonable value depending on the instance size used. - default: 200 * 1024 * 1024, // 200MB + default: 200 * 1024 * 1024 // 200MB }, rssThreshold: { doc: 'Resident set size threshold before healthcheck fails (in bytes).', env: 'RSS_THRESHOLD', format: 'int', // TODO: Set to a more reasonable value depending on the instance size used. - default: 3000 * 1024 * 1024, // 3000MB - }, - }, + default: 3000 * 1024 * 1024 // 3000MB + } + } } diff --git a/backend/src/config/config.service.ts b/backend/src/config/config.service.ts index 92f002a9d..b47b499b6 100644 --- a/backend/src/config/config.service.ts +++ b/backend/src/config/config.service.ts @@ -7,18 +7,18 @@ import { ConfigSchema, schema } from './config.schema' export class ConfigService { config: Config - constructor() { + constructor () { this.config = convict(schema) this.config.validate() } // We want to implicitly use the return type of convict get method. - // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types + // eslint-disable-next-line get>(key: K) { return this.config.get(key) } - get isDevEnv(): boolean { + get isDevEnv (): boolean { return this.config.get('environment') === 'development' } } diff --git a/backend/src/database/database-config.service.ts b/backend/src/database/database-config.service.ts index 6fcabdba6..afd74b234 100644 --- a/backend/src/database/database-config.service.ts +++ b/backend/src/database/database-config.service.ts @@ -8,32 +8,36 @@ import { base } from './ormconfig' @Injectable() export class DatabaseConfigService implements TypeOrmOptionsFactory { - constructor(private readonly config: ConfigService) {} + constructor (private readonly config: ConfigService) { } - private async createDatabase() { + private async createDatabase (): Promise { const client = new Client({ host: this.config.get('database.host'), port: this.config.get('database.port'), user: this.config.get('database.username'), password: this.config.get('database.password'), database: this.config.get('database.name'), - ...(this.config.get('database.ca') + ...(this.config.get('database.ca') !== undefined && + this.config.get('database.ca') !== null && + this.config.get('database.ca') !== '' ? { ssl: { ca: this.config.get('database.ca') } } - : {}), + : {}) }) await client.connect() const res = await client.query( 'SELECT 1 FROM pg_database WHERE datname = $1;', - [this.config.get('database.name')], + [this.config.get('database.name')] ) + const dbName = this.config.get('database') if (res.rowCount === 0) { - await client.query(`CREATE DATABASE ${this.config.get('database.name')}`) + // eslint-disable-next-line + await client.query(`CREATE DATABASE ${dbName}`) } await client.end() } - async createTypeOrmOptions(): Promise { + async createTypeOrmOptions (): Promise { // Create database, remove in production await this.createDatabase() diff --git a/backend/src/database/datasource-seed.ts b/backend/src/database/datasource-seed.ts index 5bb139dbf..776bbe985 100644 --- a/backend/src/database/datasource-seed.ts +++ b/backend/src/database/datasource-seed.ts @@ -5,7 +5,7 @@ import { base } from './ormconfig' const config: DataSourceOptions = { ...base, - migrations: [join(__dirname, 'seeds', '*{.js,.ts}')], + migrations: [join(__dirname, 'seeds', '*{.js,.ts}')] } export const appDataSource = new DataSource(config) diff --git a/backend/src/database/datasource.ts b/backend/src/database/datasource.ts index eb1a7384b..e06027f36 100644 --- a/backend/src/database/datasource.ts +++ b/backend/src/database/datasource.ts @@ -5,7 +5,7 @@ import { base } from './ormconfig' export const config: DataSourceOptions = { ...base, - migrations: [join(__dirname, 'migrations', '*{.js,.ts}')], + migrations: [join(__dirname, 'migrations', '*{.js,.ts}')] } // For CLI migrations. diff --git a/backend/src/database/entities/session.entity.ts b/backend/src/database/entities/session.entity.ts index 63e3cef96..eeaa160b3 100644 --- a/backend/src/database/entities/session.entity.ts +++ b/backend/src/database/entities/session.entity.ts @@ -4,15 +4,15 @@ import { Column, DeleteDateColumn, Entity, Index, PrimaryColumn } from 'typeorm' @Entity({ name: 'sessions' }) export class Session implements ISession { @PrimaryColumn('varchar', { length: 255 }) - id!: string + id!: string @Index('sessions_expiredAt_idx') @Column('bigint') - expiredAt = Date.now() + expiredAt = Date.now() @Column('text', { default: '' }) - json!: string + json!: string @DeleteDateColumn() - destroyedAt?: Date + destroyedAt?: Date } diff --git a/backend/src/database/entities/user.entity.ts b/backend/src/database/entities/user.entity.ts index 98908e8ea..81ff792ed 100644 --- a/backend/src/database/entities/user.entity.ts +++ b/backend/src/database/entities/user.entity.ts @@ -5,27 +5,27 @@ import { Entity, Index, PrimaryGeneratedColumn, - UpdateDateColumn, + UpdateDateColumn } from 'typeorm' @Entity({ name: 'users' }) export class User { @PrimaryGeneratedColumn() - id: number + id: number @Column('varchar', { length: 255 }) @Index('user_email_idx', { unique: true, - where: '"deletedAt" IS NULL', + where: '"deletedAt" IS NULL' }) - email: string + email: string @CreateDateColumn({ type: 'timestamptz' }) - createdAt: Date + createdAt: Date @UpdateDateColumn({ type: 'timestamptz' }) - updatedAt: Date + updatedAt: Date @DeleteDateColumn({ type: 'timestamptz' }) - deletedAt: Date | null + deletedAt: Date | null } diff --git a/backend/src/database/migrations/1659538032978-initial.ts b/backend/src/database/migrations/1659538032978-initial.ts index cadc5d5af..49d708821 100644 --- a/backend/src/database/migrations/1659538032978-initial.ts +++ b/backend/src/database/migrations/1659538032978-initial.ts @@ -3,25 +3,25 @@ import { MigrationInterface, QueryRunner } from 'typeorm' export class initial1659538032978 implements MigrationInterface { name = 'initial1659538032978' - public async up(queryRunner: QueryRunner): Promise { + public async up (queryRunner: QueryRunner): Promise { await queryRunner.query( - `CREATE TABLE "sessions" ("id" character varying(255) NOT NULL, "expiredAt" bigint NOT NULL, "json" text NOT NULL DEFAULT '', CONSTRAINT "PK_3238ef96f18b355b671619111bc" PRIMARY KEY ("id"))`, + 'CREATE TABLE "sessions" ("id" character varying(255) NOT NULL, "expiredAt" bigint NOT NULL, "json" text NOT NULL DEFAULT \'\', CONSTRAINT "PK_3238ef96f18b355b671619111bc" PRIMARY KEY ("id"))' ) await queryRunner.query( - `CREATE INDEX "sessions_expiredAt_idx" ON "sessions" ("expiredAt") `, + 'CREATE INDEX "sessions_expiredAt_idx" ON "sessions" ("expiredAt") ' ) await queryRunner.query( - `CREATE TABLE "users" ("id" SERIAL NOT NULL, "email" character varying(255) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP WITH TIME ZONE, CONSTRAINT "PK_a3ffb1c0c8416b9fc6f907b7433" PRIMARY KEY ("id"))`, + 'CREATE TABLE "users" ("id" SERIAL NOT NULL, "email" character varying(255) NOT NULL, "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP WITH TIME ZONE, CONSTRAINT "PK_a3ffb1c0c8416b9fc6f907b7433" PRIMARY KEY ("id"))' ) await queryRunner.query( - `CREATE UNIQUE INDEX "user_email_idx" ON "users" ("email") WHERE "deletedAt" IS NULL`, + 'CREATE UNIQUE INDEX "user_email_idx" ON "users" ("email") WHERE "deletedAt" IS NULL' ) } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP INDEX "public"."user_email_idx"`) - await queryRunner.query(`DROP TABLE "users"`) - await queryRunner.query(`DROP INDEX "public"."sessions_expiredAt_idx"`) - await queryRunner.query(`DROP TABLE "sessions"`) + public async down (queryRunner: QueryRunner): Promise { + await queryRunner.query('DROP INDEX "public"."user_email_idx"') + await queryRunner.query('DROP TABLE "users"') + await queryRunner.query('DROP INDEX "public"."sessions_expiredAt_idx"') + await queryRunner.query('DROP TABLE "sessions"') } } diff --git a/backend/src/database/ormconfig.ts b/backend/src/database/ormconfig.ts index 6d7dcc59b..764d81e46 100644 --- a/backend/src/database/ormconfig.ts +++ b/backend/src/database/ormconfig.ts @@ -8,7 +8,7 @@ import { schema } from '../config/config.schema' const config = convict(schema) -export const base = { +export const base: DataSourceOptions = { type: 'postgres', host: config.get('database.host'), port: config.get('database.port'), @@ -21,15 +21,15 @@ export const base = { migrationsRun: false, // js for runtime, ts for typeorm cli entities: [join(__dirname, 'entities', '*.entity{.js,.ts}')], - ...(config.get('database.ca') + ...(![undefined, null, ''].includes(config.get('database.ca')) ? { ssl: { ca: config.get('database.ca') } } : {}), // ref: https://github.com/typeorm/typeorm/issues/3388 to set pool size extra: { min: config.get('database.minPool'), - max: config.get('database.maxPool'), - }, -} as DataSourceOptions + max: config.get('database.maxPool') + } +} const dataSource = new DataSource(base) export default dataSource diff --git a/backend/src/health/__tests__/health.controller.spec.ts b/backend/src/health/__tests__/health.controller.spec.ts index 978fbd2da..4ae76da8b 100644 --- a/backend/src/health/__tests__/health.controller.spec.ts +++ b/backend/src/health/__tests__/health.controller.spec.ts @@ -10,7 +10,7 @@ describe('HealthController', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ imports: [ConfigModule, TerminusModule], - controllers: [HealthController], + controllers: [HealthController] }).compile() controller = module.get(HealthController) diff --git a/backend/src/health/health.controller.ts b/backend/src/health/health.controller.ts index dbbd403c8..c2e07bbf3 100644 --- a/backend/src/health/health.controller.ts +++ b/backend/src/health/health.controller.ts @@ -3,7 +3,7 @@ import { HealthCheck, HealthCheckService, MemoryHealthIndicator, - TypeOrmHealthIndicator, + TypeOrmHealthIndicator } from '@nestjs/terminus' import { HealthDto } from '~shared/types/health.dto' @@ -12,30 +12,30 @@ import { ConfigService } from '../config/config.service' @Controller('health') export class HealthController { - constructor( - private health: HealthCheckService, - private config: ConfigService, + constructor ( + private readonly health: HealthCheckService, + private readonly config: ConfigService, // Refer to https://github.com/nestjs/terminus/blob/master/sample/ for // examples of how to add other services/databases to healthcheck. - private db: TypeOrmHealthIndicator, - private memory: MemoryHealthIndicator, + private readonly db: TypeOrmHealthIndicator, + private readonly memory: MemoryHealthIndicator ) {} @Get() @HealthCheck() - async check(): Promise { - return this.health.check([ - async () => this.db.pingCheck('database'), + async check (): Promise { + return await this.health.check([ + async () => await this.db.pingCheck('database'), async () => - this.memory.checkHeap( + await this.memory.checkHeap( 'memory_heap', - this.config.get('health.heapSizeThreshold'), + this.config.get('health.heapSizeThreshold') ), async () => - this.memory.checkRSS( + await this.memory.checkRSS( 'memory_rss', - this.config.get('health.rssThreshold'), - ), + this.config.get('health.rssThreshold') + ) ]) } } diff --git a/backend/src/health/health.module.ts b/backend/src/health/health.module.ts index 7f7da2220..0d6e43e5e 100644 --- a/backend/src/health/health.module.ts +++ b/backend/src/health/health.module.ts @@ -6,6 +6,6 @@ import { HealthController } from './health.controller' @Module({ imports: [TerminusModule, TypeOrmModule], - controllers: [HealthController], + controllers: [HealthController] }) export class HealthModule {} diff --git a/backend/src/mailer/mailer.module.ts b/backend/src/mailer/mailer.module.ts index e640dd69c..9791d1b00 100644 --- a/backend/src/mailer/mailer.module.ts +++ b/backend/src/mailer/mailer.module.ts @@ -8,6 +8,6 @@ import { MailerService } from './mailer.service' @Module({ imports: [ConfigModule], providers: [MailerService], - exports: [MailerService], + exports: [MailerService] }) export class MailerModule {} diff --git a/backend/src/mailer/mailer.service.ts b/backend/src/mailer/mailer.service.ts index 931a1446c..ed5f9530b 100644 --- a/backend/src/mailer/mailer.service.ts +++ b/backend/src/mailer/mailer.service.ts @@ -3,31 +3,31 @@ import { SES } from 'aws-sdk' import nodemailer, { SendMailOptions, SentMessageInfo, - Transporter, + Transporter } from 'nodemailer' import { ConfigService } from '../config/config.service' @Injectable() export class MailerService { - constructor(private config: ConfigService) {} + constructor (private readonly config: ConfigService) { } - private mailer: Pick = this.config.get('awsRegion') + private readonly mailer: Pick = ![undefined, null, ''].includes(this.config.get('awsRegion')) ? nodemailer.createTransport({ - SES: new SES({ - region: this.config.get('awsRegion'), - httpOptions: { - connectTimeout: 20000, - }, - }), + SES: new SES({ + region: this.config.get('awsRegion'), + httpOptions: { + connectTimeout: 20000 + } }) + }) : nodemailer.createTransport({ - ...this.config.get('mailer'), - secure: !this.config.isDevEnv, - ignoreTLS: this.config.isDevEnv, - }) + ...this.config.get('mailer'), + secure: !this.config.isDevEnv, + ignoreTLS: this.config.isDevEnv + }) sendMail = async (mailOptions: SendMailOptions): Promise => { - return this.mailer.sendMail(mailOptions) + return await this.mailer.sendMail(mailOptions) } } diff --git a/backend/src/main.ts b/backend/src/main.ts index 8aa9326c8..83580ff7d 100644 --- a/backend/src/main.ts +++ b/backend/src/main.ts @@ -5,18 +5,19 @@ import { Logger } from 'nestjs-pino' import { AppModule } from './app.module' -async function bootstrap() { +async function bootstrap (): Promise { const app = await NestFactory.create(AppModule, { - bufferLogs: true, + bufferLogs: true }) app.useLogger(app.get(Logger)) const config = app.get(ConfigService) - if (!config.isDevEnv) { + const isDevEnv: boolean = config.isDevEnv + if (isDevEnv) { app.set('trust proxy', 1) } await app.listen(config.get('port')) } -bootstrap() +void bootstrap() diff --git a/backend/src/middlewares/helmet.middleware.ts b/backend/src/middlewares/helmet.middleware.ts index 773f1fa37..2cb8833ae 100644 --- a/backend/src/middlewares/helmet.middleware.ts +++ b/backend/src/middlewares/helmet.middleware.ts @@ -5,9 +5,9 @@ import helmet from 'helmet' @Injectable() export class HelmetMiddleware implements NestMiddleware { - private middleware: RequestHandler + private readonly middleware: RequestHandler - constructor(private config: ConfigService) { + constructor (private readonly config: ConfigService) { this.middleware = helmet({ contentSecurityPolicy: { directives: { @@ -26,17 +26,17 @@ export class HelmetMiddleware implements NestMiddleware { styleSrc: [ "'self'", "'unsafe-inline'", - 'https://fonts.googleapis.com', + 'https://fonts.googleapis.com' ], scriptSrcAttr: ["'none'"], scriptSrc: ["'self'"], - upgradeInsecureRequests: config.isDevEnv ? null : [], - }, - }, + upgradeInsecureRequests: config.isDevEnv ? null : [] + } + } }) } - use(req: Request, res: Response, next: NextFunction): void { + use (req: Request, res: Response, next: NextFunction): void { this.middleware(req, res, next) } } diff --git a/backend/src/middlewares/session.middleware.ts b/backend/src/middlewares/session.middleware.ts index 78f1b6032..e5dce55b6 100644 --- a/backend/src/middlewares/session.middleware.ts +++ b/backend/src/middlewares/session.middleware.ts @@ -10,12 +10,12 @@ import { Session } from '../database/entities' @Injectable() export class SessionMiddleware implements NestMiddleware { - private middleware: RequestHandler + private readonly middleware: RequestHandler - constructor( - private config: ConfigService, + constructor ( + private readonly config: ConfigService, @InjectDataSource() - private readonly dataSource: DataSource, + private readonly dataSource: DataSource ) { const sessionRepository = dataSource.getRepository(Session) @@ -28,16 +28,16 @@ export class SessionMiddleware implements NestMiddleware { httpOnly: true, sameSite: 'strict', maxAge: this.config.get('session.cookie.maxAge'), - secure: !config.isDevEnv, // disable in local dev env + secure: !config.isDevEnv // disable in local dev env }, store: new TypeormStore({ // for every new session, remove this many expired ones. Defaults to 0 - cleanupLimit: 2, - }).connect(sessionRepository), + cleanupLimit: 2 + }).connect(sessionRepository) }) } - use(req: Request, res: Response, next: NextFunction): void { + use (req: Request, res: Response, next: NextFunction): void { this.middleware(req, res, next) } } diff --git a/backend/src/otp/otp.module.ts b/backend/src/otp/otp.module.ts index 97ee15568..1e102d8fe 100644 --- a/backend/src/otp/otp.module.ts +++ b/backend/src/otp/otp.module.ts @@ -8,6 +8,6 @@ import { OtpService } from './otp.service' @Module({ imports: [ConfigModule], providers: [OtpService], - exports: [OtpService], + exports: [OtpService] }) export class OtpModule {} diff --git a/backend/src/otp/otp.service.ts b/backend/src/otp/otp.service.ts index a2943bfdb..1eb522ed3 100644 --- a/backend/src/otp/otp.service.ts +++ b/backend/src/otp/otp.service.ts @@ -7,32 +7,32 @@ const NUM_MINUTES_IN_AN_HOUR = 60 @Injectable() export class OtpService { - constructor(private config: ConfigService) {} + constructor (private readonly config: ConfigService) { } - private totp = totpFactory.clone({ + private readonly totp = totpFactory.clone({ step: this.config.get('otp.expiry'), window: [ this.config.get('otp.numValidPastWindows'), - this.config.get('otp.numValidFutureWindows'), - ], + this.config.get('otp.numValidFutureWindows') + ] }) - private concatSecretWithEmail(email: string): string { + private concatSecretWithEmail (email: string): string { return this.config.get('otp.secret') + email } - generateOtp(email: string): { token: string; timeLeft: number } { + generateOtp (email: string): { token: string, timeLeft: number } { const token = this.totp.generate(this.concatSecretWithEmail(email)) - const timeLeft = this.totp.options.step + const timeLeft = this.totp.options.step !== undefined ? Math.floor(this.totp.options.step / NUM_MINUTES_IN_AN_HOUR) // Round down to minutes : NaN return { token, timeLeft } } - verifyOtp(email: string, token: string): boolean { + verifyOtp (email: string, token: string): boolean { return this.totp.verify({ secret: this.concatSecretWithEmail(email), - token, + token }) } } diff --git a/backend/src/tracing/__tests__/trace-id.provider.spec.ts b/backend/src/tracing/__tests__/trace-id.provider.spec.ts index 4a05d8381..c27e4fedd 100644 --- a/backend/src/tracing/__tests__/trace-id.provider.spec.ts +++ b/backend/src/tracing/__tests__/trace-id.provider.spec.ts @@ -9,7 +9,7 @@ describe('TraceIdProvider', () => { beforeEach(async () => { const module: TestingModule = await Test.createTestingModule({ - providers: [TraceIdProvider], + providers: [TraceIdProvider] }).compile() traceIdProvider = module.get(TraceIdProvider) @@ -17,7 +17,7 @@ describe('TraceIdProvider', () => { it('generates its own id if no headers available', () => { const req = { - headers: {}, + headers: {} } as unknown as IncomingMessage const id = traceIdProvider.getTraceId(req) expect(id).toBeTruthy() @@ -27,8 +27,8 @@ describe('TraceIdProvider', () => { const requestId = randomUUID() const req = { headers: { - 'x-request-id': requestId, - }, + 'x-request-id': requestId + } } as unknown as IncomingMessage const id = traceIdProvider.getTraceId(req) expect(id).toBe(requestId) @@ -39,8 +39,8 @@ describe('TraceIdProvider', () => { const req = { headers: { 'x-amzn-trace-id': requestId, - 'x-request-id': 'x-request-id', - }, + 'x-request-id': 'x-request-id' + } } as unknown as IncomingMessage const id = traceIdProvider.getTraceId(req) expect(id).toBe(requestId) @@ -52,8 +52,8 @@ describe('TraceIdProvider', () => { headers: { 'x-datadog-trace-id': requestId, 'x-amzn-trace-id': 'x-amzn-trace-id', - 'x-request-id': 'x-request-id', - }, + 'x-request-id': 'x-request-id' + } } as unknown as IncomingMessage const id = traceIdProvider.getTraceId(req) expect(id).toBe(requestId) diff --git a/backend/src/tracing/trace-id.provider.ts b/backend/src/tracing/trace-id.provider.ts index 35642b1e9..12e1cd4db 100644 --- a/backend/src/tracing/trace-id.provider.ts +++ b/backend/src/tracing/trace-id.provider.ts @@ -4,15 +4,16 @@ import { IncomingMessage } from 'http' @Injectable() export class TraceIdProvider { - getTraceId(req: IncomingMessage): string { - const extractHeader = (headerName: string) => { + getTraceId (req: IncomingMessage): string { + const extractHeader = (headerName: string): string | undefined => { const header = req.headers[headerName.toLowerCase()] - return ([] as string[]).concat(header ?? '').join('') + const headerValue = ([] as string[]).concat(header ?? '').join('') + return headerValue === '' ? undefined : headerValue } return ( - extractHeader('x-datadog-trace-id') || - extractHeader('x-amzn-trace-id') || - extractHeader('x-request-id') || + extractHeader('x-datadog-trace-id') ?? + extractHeader('x-amzn-trace-id') ?? + extractHeader('x-request-id') ?? randomUUID() ) } diff --git a/backend/tsconfig.eslint.json b/backend/tsconfig.eslint.json new file mode 100644 index 000000000..00e022e6e --- /dev/null +++ b/backend/tsconfig.eslint.json @@ -0,0 +1,8 @@ +{ + "extends": "./tsconfig.json", + "exclude": [], + "include": [ + "src/**/*", + "jest.config.ts" + ] +} diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js deleted file mode 100644 index 515c93503..000000000 --- a/frontend/.eslintrc.js +++ /dev/null @@ -1,25 +0,0 @@ -module.exports = { - plugins: ['react', 'react-hooks'], - extends: [ - '../.eslintrc.js', - 'plugin:react/recommended', - 'plugin:react-hooks/recommended', - ], - ignorePatterns: ['config-overrides.js'], - parserOptions: { - project: ['./tsconfig.json'], - tsconfigRootDir: __dirname, - }, - env: { - browser: true, - es2021: true, - }, - settings: { - react: { - version: 'detect', - }, - }, - rules: { - 'react/react-in-jsx-scope': 'off', - }, -} diff --git a/frontend/.prettierignore b/frontend/.prettierignore deleted file mode 100644 index de198ac47..000000000 --- a/frontend/.prettierignore +++ /dev/null @@ -1,28 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# production -/build - -# misc -.DS_Store -.env.local -.env.development.local -.env.test.local -.env.production.local - -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -storybook-static -build-storybook.log - -.storybook/preview-head.html diff --git a/frontend/config-overrides.js b/frontend/config-overrides.js index 00a4e1c27..46275d65d 100644 --- a/frontend/config-overrides.js +++ b/frontend/config-overrides.js @@ -5,7 +5,7 @@ const { aliasWebpack, aliasJest, configPaths } = require('react-app-alias-ex') const aliasMap = configPaths('./tsconfig.paths.json') const options = { - alias: aliasMap, + alias: aliasMap } module.exports = aliasWebpack(options) module.exports.jest = aliasJest(options) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 10d93bb41..c7e1776fa 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -42,11 +42,7 @@ "@types/react-router-dom": "^5.3.3", "babel-plugin-named-exports-order": "^0.0.2", "cross-env": "^7.0.3", - "eslint-plugin-react": "^7.31.11", - "eslint-plugin-react-hooks": "^4.4.0", - "eslint-plugin-storybook": "^0.6.7", "lint-staged": "^13.0.4", - "prettier": "^2.8.0", "prop-types": "^15.8.1", "react-app-alias-ex": "^2.1.0", "react-app-rewired": "^2.2.1", @@ -19944,33 +19940,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/eslint-plugin-storybook": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-0.6.7.tgz", - "integrity": "sha512-lcUsB+3PesKWXwwEHGSTCijKWDXuQ4ITVbnsSDMXRCR/cjGtHZIEcy2pp/Eh7nfWA/GZrDPpK97DsTWEzyN6Bw==", - "dev": true, - "dependencies": { - "@storybook/csf": "^0.0.1", - "@typescript-eslint/experimental-utils": "^5.3.0", - "requireindex": "^1.1.0", - "ts-dedent": "^2.2.0" - }, - "engines": { - "node": "12.x || 14.x || >= 16" - }, - "peerDependencies": { - "eslint": ">=6" - } - }, - "node_modules/eslint-plugin-storybook/node_modules/@storybook/csf": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.1.tgz", - "integrity": "sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.15" - } - }, "node_modules/eslint-plugin-testing-library": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.6.0.tgz", @@ -32156,21 +32125,6 @@ "node": ">= 0.8.0" } }, - "node_modules/prettier": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.0.tgz", - "integrity": "sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", @@ -34978,15 +34932,6 @@ "node": ">=0.10.0" } }, - "node_modules/requireindex": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", - "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", - "dev": true, - "engines": { - "node": ">=0.10.5" - } - }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -55556,29 +55501,6 @@ "dev": true, "requires": {} }, - "eslint-plugin-storybook": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/eslint-plugin-storybook/-/eslint-plugin-storybook-0.6.7.tgz", - "integrity": "sha512-lcUsB+3PesKWXwwEHGSTCijKWDXuQ4ITVbnsSDMXRCR/cjGtHZIEcy2pp/Eh7nfWA/GZrDPpK97DsTWEzyN6Bw==", - "dev": true, - "requires": { - "@storybook/csf": "^0.0.1", - "@typescript-eslint/experimental-utils": "^5.3.0", - "requireindex": "^1.1.0", - "ts-dedent": "^2.2.0" - }, - "dependencies": { - "@storybook/csf": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/@storybook/csf/-/csf-0.0.1.tgz", - "integrity": "sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==", - "dev": true, - "requires": { - "lodash": "^4.17.15" - } - } - } - }, "eslint-plugin-testing-library": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.6.0.tgz", @@ -64692,12 +64614,6 @@ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, - "prettier": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.0.tgz", - "integrity": "sha512-9Lmg8hTFZKG0Asr/kW9Bp8tJjRVluO8EJQVfY2T7FMw9T5jy4I/Uvx0Rca/XWf50QQ1/SS48+6IJWnrb+2yemA==", - "dev": true - }, "pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", @@ -66584,12 +66500,6 @@ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, - "requireindex": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", - "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", - "dev": true - }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 6ab56d11a..af4c09b1a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -38,11 +38,7 @@ "@types/react-router-dom": "^5.3.3", "babel-plugin-named-exports-order": "^0.0.2", "cross-env": "^7.0.3", - "eslint-plugin-react": "^7.31.11", - "eslint-plugin-react-hooks": "^4.4.0", - "eslint-plugin-storybook": "^0.6.7", "lint-staged": "^13.0.4", - "prettier": "^2.8.0", "prop-types": "^15.8.1", "react-app-alias-ex": "^2.1.0", "react-app-rewired": "^2.2.1", @@ -68,16 +64,15 @@ "eject": "react-scripts eject", "storybook": "start-storybook -p 6006 -s public", "build-storybook": "build-storybook -s public", - "lint": "eslint ./ --ignore-path .gitignore && prettier . -c", - "lint:fix": "eslint ./ --ignore-path .gitignore --fix && prettier . -c --write", + "lint": "ts-standard", + "lint:fix": "npm run lint -- --fix", "pre-commit": "lint-staged", "snyk-protect": "snyk-protect", "prepare": "npm run snyk-protect" }, "lint-staged": { "**/*.(js|jsx|ts|tsx)": [ - "prettier --write", - "eslint --cache --fix" + "ts-standard --fix" ] }, "browserslist": { @@ -92,5 +87,10 @@ "last 1 safari version" ] }, - "snyk": true + "snyk": true, + "ts-standard": { + "ignore": [ + "build" + ] + } } diff --git a/frontend/src/app/AppRouter.tsx b/frontend/src/app/AppRouter.tsx index 9a870a41d..485f13193 100644 --- a/frontend/src/app/AppRouter.tsx +++ b/frontend/src/app/AppRouter.tsx @@ -9,14 +9,14 @@ import { routes } from '~constants/routes' import { LoginPage } from '~features/auth/LoginPage' -const WorkspacePage = lazy(() => import('~features/dashboard/DashboardPage')) -const HealthPage = lazy(() => import('~features/health/HealthPage')) +const WorkspacePage = lazy(async () => await import('~features/dashboard/DashboardPage')) +const HealthPage = lazy(async () => await import('~features/health/HealthPage')) export const AppRouter = (): JSX.Element => { return ( + } @@ -29,7 +29,7 @@ export const AppRouter = (): JSX.Element => { } - > + /> { } /> - 404} /> + 404} /> ) diff --git a/frontend/src/app/PrivateRoute.tsx b/frontend/src/app/PrivateRoute.tsx index 5018f6ea4..8918fb3ba 100644 --- a/frontend/src/app/PrivateRoute.tsx +++ b/frontend/src/app/PrivateRoute.tsx @@ -4,8 +4,9 @@ import { routes } from '~constants/routes' import { useAuth } from '~features/auth' -export const PrivateRoute = ({ children }: { children: JSX.Element }) => { - const { isAuthenticated } = useAuth() +export const PrivateRoute = ({ children }: { children: JSX.Element }): JSX.Element => { + const authContext = useAuth() + const isAuthenticated: boolean = authContext.isAuthenticated ?? false if (!isAuthenticated) return return children diff --git a/frontend/src/app/PublicRoute.tsx b/frontend/src/app/PublicRoute.tsx index 8ad3f1a01..3b27a2057 100644 --- a/frontend/src/app/PublicRoute.tsx +++ b/frontend/src/app/PublicRoute.tsx @@ -4,8 +4,9 @@ import { routes } from '~constants/routes' import { useAuth } from '~features/auth' -export const PublicRoute = ({ children }: { children: JSX.Element }) => { - const { isAuthenticated } = useAuth() +export const PublicRoute = ({ children }: { children: JSX.Element }): JSX.Element => { + const authContext = useAuth() + const isAuthenticated: boolean = authContext.isAuthenticated ?? false if (isAuthenticated) return return children diff --git a/frontend/src/app/__tests__/App.test.tsx b/frontend/src/app/__tests__/App.test.tsx index 1c17232a4..eed6ebdfa 100644 --- a/frontend/src/app/__tests__/App.test.tsx +++ b/frontend/src/app/__tests__/App.test.tsx @@ -6,6 +6,6 @@ test('renders page', async () => { render() await waitFor(() => - expect(screen.getByText('Get started with Template')).toBeInTheDocument(), + expect(screen.getByText('Get started with Template')).toBeInTheDocument() ) }) diff --git a/frontend/src/constants/routes.ts b/frontend/src/constants/routes.ts index dce066802..84ea73986 100644 --- a/frontend/src/constants/routes.ts +++ b/frontend/src/constants/routes.ts @@ -1,5 +1,5 @@ export const routes = { index: '/', login: '/login', - health: '/health', + health: '/health' } diff --git a/frontend/src/features/auth/AuthContext.tsx b/frontend/src/features/auth/AuthContext.tsx index 2d7c484c3..2e333b345 100644 --- a/frontend/src/features/auth/AuthContext.tsx +++ b/frontend/src/features/auth/AuthContext.tsx @@ -7,12 +7,12 @@ import { LOGGED_IN_KEY, useLocalStorage } from '~features/localStorage' import * as AuthService from './AuthService' -type AuthContextProps = { +interface AuthContextProps { isAuthenticated?: boolean user?: WhoAmIResponseDto isLoading: boolean sendLoginOtp: typeof AuthService.sendLoginOtp - verifyLoginOtp: (params: { token: string; email: string }) => Promise + verifyLoginOtp: (params: { token: string, email: string }) => Promise logout: typeof AuthService.logout } @@ -22,7 +22,7 @@ const AuthContext = createContext(undefined) * Provider component that wraps your app and makes auth object available to any * child component that calls `useAuth()`. */ -export const AuthProvider = ({ children }: { children: ReactNode }) => { +export const AuthProvider = ({ children }: { children: ReactNode }): JSX.Element => { const auth = useProvideAuth() return {children} @@ -33,48 +33,50 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => { */ export const useAuth = (): AuthContextProps => { const context = useContext(AuthContext) - if (!context) { - throw new Error(`useAuth must be used within a AuthProvider component`) + if (context == null) { + throw new Error('useAuth must be used within a AuthProvider component') } return context } // Provider hook that creates auth object and handles state -const useProvideAuth = () => { +const useProvideAuth = (): AuthContextProps => { const [isLoggedIn, setIsLoggedIn] = useLocalStorage(LOGGED_IN_KEY) const queryClient = useQueryClient() const { data: user, isLoading } = useQuery( ['currentUser'], - () => AuthService.fetchUser(), + async () => await AuthService.fetchUser(), // 10 minutes staletime, do not need to retrieve so often. - { staleTime: 600000, enabled: !!isLoggedIn }, + { staleTime: 600000, enabled: isLoggedIn ?? false } ) const verifyLoginOtp = useCallback( - async (params: { token: string; email: string }) => { + async (params: { token: string, email: string }) => { await AuthService.verifyLoginOtp(params) setIsLoggedIn(true) }, - [setIsLoggedIn], + [setIsLoggedIn] ) + const isLoggedInCoercedValue: boolean = isLoggedIn ?? false + const logout = useCallback(async () => { await AuthService.logout() - if (isLoggedIn) { + if (isLoggedInCoercedValue) { // Clear logged in state. setIsLoggedIn(undefined) } queryClient.clear() - }, [isLoggedIn, queryClient, setIsLoggedIn]) + }, [isLoggedInCoercedValue, queryClient, setIsLoggedIn]) // Return the user object and auth methods return { isAuthenticated: isLoggedIn, - user: isLoggedIn ? user : undefined, + user: isLoggedInCoercedValue ? user : undefined, isLoading, sendLoginOtp: AuthService.sendLoginOtp, - verifyLoginOtp: verifyLoginOtp, - logout, + verifyLoginOtp, + logout } } diff --git a/frontend/src/features/auth/AuthService.ts b/frontend/src/features/auth/AuthService.ts index 2e18bebb2..693060aae 100644 --- a/frontend/src/features/auth/AuthService.ts +++ b/frontend/src/features/auth/AuthService.ts @@ -3,7 +3,7 @@ import { SendLoginOtpResponseDto, VerifyOtpRequestDto, VerifyOtpResponseDto, - WhoAmIResponseDto, + WhoAmIResponseDto } from '~shared/types/auth.dto' import { api } from '~/api' @@ -13,19 +13,19 @@ import { api } from '~/api' * * @returns the logged in user if session is valid, will throw 401 error if not. */ -export const fetchUser = async () => { - return api.url('/auth/whoami').get().json() +export const fetchUser = async (): Promise => { + return await api.url('/auth/whoami').get().json() } -export const sendLoginOtp = async (params: SendLoginOtpRequestDto) => { +export const sendLoginOtp = async (params: SendLoginOtpRequestDto): Promise => { params.email = params.email.toLowerCase() - return api.url('/auth').post(params).json() + return await api.url('/auth').post(params).json() } -export const verifyLoginOtp = async (params: VerifyOtpRequestDto) => { - return api.url('/auth/verify').post(params).json() +export const verifyLoginOtp = async (params: VerifyOtpRequestDto): Promise => { + return await api.url('/auth/verify').post(params).json() } export const logout = async (): Promise => { - return api.url('/auth/logout').post().json() + return await api.url('/auth/logout').post().json() } diff --git a/frontend/src/features/auth/LoginPage.tsx b/frontend/src/features/auth/LoginPage.tsx index 531587edc..e4678fca5 100644 --- a/frontend/src/features/auth/LoginPage.tsx +++ b/frontend/src/features/auth/LoginPage.tsx @@ -8,7 +8,7 @@ import { Link, Text, useBreakpointValue, - Wrap, + Wrap } from '@chakra-ui/react' import { ReactComponent as BrandLogoSvg } from '../../assets/svgs/brand-hort-colour.svg' @@ -21,7 +21,7 @@ import { useAuth } from './AuthContext' const LoginImage = chakra(LoginImageSvg) const BrandLogo = chakra(BrandLogoSvg) -export type LoginOtpData = { +export interface LoginOtpData { email: string } @@ -39,149 +39,151 @@ export const LoginPage = (): JSX.Element => { { label: 'Guide', href: '' }, { label: 'Privacy', href: '' }, { label: 'Terms of Use', href: '' }, - { label: 'Report Vulnerability', href: '' }, + { label: 'Report Vulnerability', href: '' } ], - [], + [] ) - const handleSendOtp = async ({ email }: LoginFormInputs) => { + const handleSendOtp = async ({ email }: LoginFormInputs): Promise => { await sendLoginOtp({ email }) return setEmail(email) } - const handleVerifyOtp = ({ otp }: OtpFormInputs) => { + const handleVerifyOtp = async ({ otp }: OtpFormInputs): Promise => { // Should not happen, since OtpForm component is only shown when there is // already an email state set. - if (!email) { + if (email === undefined || email === null || email === '') { throw new Error('Something went wrong') } - return verifyLoginOtp({ token: otp, email }) + return await verifyLoginOtp({ token: otp, email }) } - const handleResendOtp = async () => { + const handleResendOtp = async (): Promise => { // Should not happen, since OtpForm component is only shown when there is // already an email state set. - if (!email) { + if (email === undefined || email === null || email === '') { throw new Error('Something went wrong') } await sendLoginOtp({ email }) } return ( - + - {isTablet && ( + {Boolean(isTablet ?? false) && ( Fuss-free project templates )} - + Get started with Template - {!email ? ( - - ) : ( - - )} + {email === undefined || email === null || email === '' + ? ( + + ) + : ( + + )} - {isDesktop && ( + {Boolean(isDesktop ?? false) && ( <> - + © {currentYear} Open Government Products, GovTech Singapore - + {footerLinks.map(({ label, href }, index) => ( {label} diff --git a/frontend/src/features/auth/components/LoginForm.tsx b/frontend/src/features/auth/components/LoginForm.tsx index cbef76b6d..84a06f421 100644 --- a/frontend/src/features/auth/components/LoginForm.tsx +++ b/frontend/src/features/auth/components/LoginForm.tsx @@ -9,13 +9,13 @@ import { Link, Stack, Text, - useBreakpointValue, + useBreakpointValue } from '@chakra-ui/react' const emailRegex = /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+/ -export type LoginFormInputs = { +export interface LoginFormInputs { email: string } @@ -33,12 +33,12 @@ export const LoginForm = ({ onSubmit }: LoginFormProps): JSX.Element => { return 'Please enter a valid email' } - const isGovDomain = value.split('@').pop()?.includes('gov.sg') + const isGovDomain = value.split('@').pop()?.includes('gov.sg') ?? false return isGovDomain || 'Please sign in with a gov.sg email address.' }, []) - const onSubmitForm = async (inputs: LoginFormInputs) => { - return onSubmit(inputs).catch((e) => { + const onSubmitForm = async (inputs: LoginFormInputs): Promise => { + return await onSubmit(inputs).catch((e) => { setError('email', { type: 'server', message: e.json.message }) }) } @@ -46,40 +46,41 @@ export const LoginForm = ({ onSubmit }: LoginFormProps): JSX.Element => { const isMobile = useBreakpointValue({ base: true, xs: true, lg: false }) return ( + // eslint-disable-next-line
- - Email - + + Email + Only available for use by public officers with a gov.sg email - {formState.errors.email && ( + {(formState.errors.email != null) && ( {formState.errors.email.message} )} diff --git a/frontend/src/features/auth/components/OtpForm.tsx b/frontend/src/features/auth/components/OtpForm.tsx index 718355aac..1a9cf9d13 100644 --- a/frontend/src/features/auth/components/OtpForm.tsx +++ b/frontend/src/features/auth/components/OtpForm.tsx @@ -7,12 +7,12 @@ import { FormLabel, Input, Stack, - useBreakpointValue, + useBreakpointValue } from '@chakra-ui/react' import { ResendOtpButton } from './ResendOtpButton' -export type OtpFormInputs = { +export interface OtpFormInputs { otp: string } @@ -23,7 +23,7 @@ interface OtpFormProps { export const OtpForm = ({ onSubmit, - onResendOtp, + onResendOtp }: OtpFormProps): JSX.Element => { const { handleSubmit, register, formState, setError } = useForm() @@ -32,49 +32,50 @@ export const OtpForm = ({ const validateOtp = useCallback( (value: string) => value.length === 6 || 'Please enter a 6 digit OTP.', - [], + [] ) - const onSubmitForm = async (inputs: OtpFormInputs) => { - return onSubmit(inputs).catch((e) => { + const onSubmitForm = async (inputs: OtpFormInputs): Promise => { + return await onSubmit(inputs).catch((e) => { setError('otp', { type: 'server', message: e.json.message }) }) } return ( + // eslint-disable-next-line - - + + Enter 6 digit OTP sent to your email - {formState.errors.otp && ( + {(formState.errors.otp != null) && ( {formState.errors.otp.message} )} diff --git a/frontend/src/features/auth/components/ResendOtpButton.tsx b/frontend/src/features/auth/components/ResendOtpButton.tsx index 5b0a3f2f9..125f8a73c 100644 --- a/frontend/src/features/auth/components/ResendOtpButton.tsx +++ b/frontend/src/features/auth/components/ResendOtpButton.tsx @@ -9,28 +9,28 @@ export interface ResendOtpButtonProps { } export const ResendOtpButton = ({ - onResendOtp, + onResendOtp }: ResendOtpButtonProps): JSX.Element => { // The counter const [timer, setTimer] = useState(0) const resendOtpMutation = useMutation(onResendOtp, { // On success, restart the timer before this can be called again. - onSuccess: () => setTimer(60), + onSuccess: () => setTimer(60) }) useInterval( () => setTimer(timer - 1), // Stop interval if timer hits 0. - timer <= 0 ? null : 1000, + timer <= 0 ? null : 1000 ) return ( + {/* eslint-enable */} ) @@ -44,9 +46,9 @@ const DashboardPage = (): JSX.Element => { const { user } = useAuth() return ( - + - + Welcome {user?.email}. YOU ARE NOW AUTHENTICATED. Replace this page with the root page of diff --git a/frontend/src/features/health/queries.ts b/frontend/src/features/health/queries.ts index f61304753..46e52525b 100644 --- a/frontend/src/features/health/queries.ts +++ b/frontend/src/features/health/queries.ts @@ -4,13 +4,14 @@ import { HealthDto } from '~shared/types/health.dto' import { api } from '~/api' -export function useHealth() { +export function useHealth (): { data?: HealthDto } { const { data } = useQuery( ['health'], - () => api.url(`/health`).get().json(), + // eslint-disable-next-line + async () => await api.url('/health').get().json(), { - suspense: true, - }, + suspense: true + } ) return { data } } diff --git a/frontend/src/features/localStorage/useLocalStorage.ts b/frontend/src/features/localStorage/useLocalStorage.ts index b2432f2b8..9118d6d1f 100644 --- a/frontend/src/features/localStorage/useLocalStorage.ts +++ b/frontend/src/features/localStorage/useLocalStorage.ts @@ -5,7 +5,7 @@ import { LOCAL_STORAGE_EVENT } from './constants' export const useLocalStorage = ( key: string, - initialValue?: T, + initialValue?: T ): readonly [T | undefined, (value?: T) => void] => { // Get from local storage then // parse stored json or return initialValue @@ -16,7 +16,7 @@ export const useLocalStorage = ( } try { const item = window.localStorage.getItem(key) - return item ? JSON.parse(item) : initialValue + return item !== null ? JSON.parse(item) : initialValue } catch (error) { return initialValue } @@ -26,12 +26,12 @@ export const useLocalStorage = ( const [storedValue, setStoredValue] = useState(readValue) // Return a wrapped version of useState's setter function that ... // ... persists the new value to localStorage. - const setValue = (value?: T) => { + const setValue = (value?: T): void => { try { // Allow value to be a function so we have the same API as useState const newValue = value instanceof Function ? value(storedValue) : value - if (!value) { + if (value !== undefined) { window.localStorage.removeItem(key) } else { // Save to local storage @@ -50,7 +50,7 @@ export const useLocalStorage = ( setStoredValue(readValue()) }, [readValue]) useEffect(() => { - const handleStorageChange = () => { + const handleStorageChange = (): void => { setStoredValue(readValue()) } // this only works for other documents, not the current one diff --git a/frontend/src/hooks/useInterval.ts b/frontend/src/hooks/useInterval.ts index 2230a08b6..6a686fbed 100644 --- a/frontend/src/hooks/useInterval.ts +++ b/frontend/src/hooks/useInterval.ts @@ -2,7 +2,7 @@ import { useEffect, useRef } from 'react' export const useInterval = ( callback: () => void, - delay: number | null, + delay: number | null ): void => { const savedCallback = useRef(callback) diff --git a/frontend/src/index.tsx b/frontend/src/index.tsx index 443a53afa..f390e2bfd 100644 --- a/frontend/src/index.tsx +++ b/frontend/src/index.tsx @@ -8,7 +8,7 @@ const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement) root.render( - , + ) // If you want your app to work offline and load faster, you can change diff --git a/frontend/src/react-app-env.d.ts b/frontend/src/react-app-env.d.ts index 6c82b06eb..0d856dd81 100644 --- a/frontend/src/react-app-env.d.ts +++ b/frontend/src/react-app-env.d.ts @@ -1,4 +1,4 @@ -/// +import 'react-scripts' declare namespace NodeJS { interface ProcessEnv { REACT_APP_ENV: 'development' | 'production' | 'staging' diff --git a/frontend/src/serviceWorker.ts b/frontend/src/serviceWorker.ts index 71df3c740..61a2b27c4 100644 --- a/frontend/src/serviceWorker.ts +++ b/frontend/src/serviceWorker.ts @@ -13,20 +13,20 @@ const isLocalhost = Boolean( window.location.hostname === 'localhost' || - // [::1] is the IPv6 localhost address. - window.location.hostname === '[::1]' || - // 127.0.0.0/8 are considered localhost for IPv4. - window.location.hostname.match( - /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/, - ), + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.0/8 are considered localhost for IPv4. + window.location.hostname.match( + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ + ) ) -type Config = { +interface Config { onSuccess?: (_registration: ServiceWorkerRegistration) => void onUpdate?: (_registration: ServiceWorkerRegistration) => void } -export function register(config?: Config): void { +export function register (config?: Config): void { if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { // The URL constructor is available in all browsers that support SW. const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href) @@ -46,10 +46,10 @@ export function register(config?: Config): void { // Add some additional logging to localhost, pointing developers to the // service worker/PWA documentation. - navigator.serviceWorker.ready.then(() => { + void navigator.serviceWorker.ready.then(() => { console.log( 'This web app is being served cache-first by a service ' + - 'worker. To learn more, visit https://bit.ly/CRA-PWA', + 'worker. To learn more, visit https://bit.ly/CRA-PWA' ) }) } else { @@ -60,7 +60,7 @@ export function register(config?: Config): void { } } -function registerValidSW(swUrl: string, config?: Config) { +function registerValidSW (swUrl: string, config?: Config): void { navigator.serviceWorker .register(swUrl) .then((registration) => { @@ -71,17 +71,17 @@ function registerValidSW(swUrl: string, config?: Config) { } installingWorker.onstatechange = () => { if (installingWorker.state === 'installed') { - if (navigator.serviceWorker.controller) { + if (navigator.serviceWorker.controller != null) { // At this point, the updated precached content has been fetched, // but the previous service worker will still serve the older // content until all client tabs are closed. console.log( 'New content is available and will be used when all ' + - 'tabs for this page are closed. See https://bit.ly/CRA-PWA.', + 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' ) // Execute callback - if (config && config.onUpdate) { + if ((config?.onUpdate != null)) { config.onUpdate(registration) } } else { @@ -91,7 +91,7 @@ function registerValidSW(swUrl: string, config?: Config) { console.log('Content is cached for offline use.') // Execute callback - if (config && config.onSuccess) { + if ((config?.onSuccess != null)) { config.onSuccess(registration) } } @@ -104,21 +104,21 @@ function registerValidSW(swUrl: string, config?: Config) { }) } -function checkValidServiceWorker(swUrl: string, config?: Config) { +function checkValidServiceWorker (swUrl: string, config?: Config): void { // Check if the service worker can be found. If it can't reload the page. fetch(swUrl, { - headers: { 'Service-Worker': 'script' }, + headers: { 'Service-Worker': 'script' } }) .then((response) => { // Ensure service worker exists, and that we really are getting a JS file. const contentType = response.headers.get('content-type') if ( response.status === 404 || - (contentType != null && contentType.indexOf('javascript') === -1) + (contentType != null && !contentType.includes('javascript')) ) { // No service worker found. Probably a different app. Reload the page. - navigator.serviceWorker.ready.then((registration) => { - registration.unregister().then(() => { + void navigator.serviceWorker.ready.then((registration) => { + void registration.unregister().then(() => { window.location.reload() }) }) @@ -129,16 +129,16 @@ function checkValidServiceWorker(swUrl: string, config?: Config) { }) .catch(() => { console.log( - 'No internet connection found. App is running in offline mode.', + 'No internet connection found. App is running in offline mode.' ) }) } -export function unregister(): void { +export function unregister (): void { if ('serviceWorker' in navigator) { navigator.serviceWorker.ready .then((registration) => { - registration.unregister() + void registration.unregister() }) .catch((error) => { console.error(error.message) diff --git a/frontend/src/setupTests.ts b/frontend/src/setupTests.ts index 3fb306834..cf3d5a8c8 100644 --- a/frontend/src/setupTests.ts +++ b/frontend/src/setupTests.ts @@ -6,11 +6,11 @@ import '@testing-library/jest-dom' // Handle TypeError: env.window.matchMedia is not a function window.matchMedia = - window.matchMedia || + window.matchMedia ?? function () { return { matches: false, addListener: () => null, - removeListener: () => null, + removeListener: () => null } } diff --git a/frontend/src/theme/foundations/colours.ts b/frontend/src/theme/foundations/colours.ts index 5f9f6bd68..bcb070152 100644 --- a/frontend/src/theme/foundations/colours.ts +++ b/frontend/src/theme/foundations/colours.ts @@ -18,16 +18,16 @@ export type ThemeColorScheme = * Available color schemes to use for form field colors */ export type FieldColorScheme = Extract< - ThemeColorScheme, - | 'primary' - | 'theme-green' - | 'theme-teal' - | 'theme-purple' - | 'theme-grey' - | 'theme-yellow' - | 'theme-orange' - | 'theme-red' - | 'theme-brown' +ThemeColorScheme, +| 'primary' +| 'theme-green' +| 'theme-teal' +| 'theme-purple' +| 'theme-grey' +| 'theme-yellow' +| 'theme-orange' +| 'theme-red' +| 'theme-brown' > export const colours: { [k in ThemeColorScheme]: Record } = { @@ -40,7 +40,7 @@ export const colours: { [k in ThemeColorScheme]: Record } = { 600: '#3B4E9A', 700: '#2C3A73', 800: '#1E274D', - 900: '#161D3A', + 900: '#161D3A' }, secondary: { 100: '#F5F6F8', @@ -51,7 +51,7 @@ export const colours: { [k in ThemeColorScheme]: Record } = { 600: '#36405B', 700: '#293044', 800: '#1B202E', - 900: '#0E1017', + 900: '#0E1017' }, danger: { 100: '#FFF8F8', @@ -62,7 +62,7 @@ export const colours: { [k in ThemeColorScheme]: Record } = { 600: '#AD4848', 700: '#9A4040', 800: '#733030', - 900: '#602828', + 900: '#602828' }, warning: { 100: '#FFFCF2', @@ -73,7 +73,7 @@ export const colours: { [k in ThemeColorScheme]: Record } = { 600: '#E0C25D', 700: '#AE9748', 800: '#7D6C34', - 900: '#4B411F', + 900: '#4B411F' }, success: { 100: '#E6FCF7', @@ -84,7 +84,7 @@ export const colours: { [k in ThemeColorScheme]: Record } = { 600: '#05B88B', 700: '#038564', 800: '#03664D', - 900: '#023D2E', + 900: '#023D2E' }, neutral: { 100: '#FBFCFD', @@ -95,7 +95,7 @@ export const colours: { [k in ThemeColorScheme]: Record } = { 600: '#999B9F', 700: '#636467', 800: '#48494B', - 900: '#242425', + 900: '#242425' }, 'theme-green': { 100: '#F3F6F6', @@ -104,7 +104,7 @@ export const colours: { [k in ThemeColorScheme]: Record } = { 400: '#81ABA0', 500: '#357867', 600: '#025641', - 700: '#013C2E', + 700: '#013C2E' }, 'theme-teal': { 100: '#F3F6F8', @@ -113,7 +113,7 @@ export const colours: { [k in ThemeColorScheme]: Record } = { 400: '#7AA5B7', 500: '#417E98', 600: '#1B6483', - 700: '#054763', + 700: '#054763' }, 'theme-purple': { 100: '#F4F2F5', @@ -122,7 +122,7 @@ export const colours: { [k in ThemeColorScheme]: Record } = { 400: '#B393C1', 500: '#9265A7', 600: '#583D64', - 700: '#3A2843', + 700: '#3A2843' }, 'theme-grey': { 100: '#F6F6F6', @@ -131,7 +131,7 @@ export const colours: { [k in ThemeColorScheme]: Record } = { 400: '#929DA3', 500: '#495C66', 600: '#2C373D', - 700: '#1D2529', + 700: '#1D2529' }, 'theme-yellow': { 100: '#F5F4EE', @@ -140,7 +140,7 @@ export const colours: { [k in ThemeColorScheme]: Record } = { 400: '#F0DD97', 500: '#F9D651', 600: '#847642', - 700: '#6C5D21', + 700: '#6C5D21' }, 'theme-orange': { 100: '#FAF7F4', @@ -149,7 +149,7 @@ export const colours: { [k in ThemeColorScheme]: Record } = { 400: '#FBB791', 500: '#F66F23', 600: '#BF5200', - 700: '#8C3C00', + 700: '#8C3C00' }, 'theme-red': { 100: '#FAF7F7', @@ -158,7 +158,7 @@ export const colours: { [k in ThemeColorScheme]: Record } = { 400: '#F1AAAA', 500: '#DC2A2A', 600: '#B22222', - 700: '#7C0E0E', + 700: '#7C0E0E' }, 'theme-brown': { 100: '#F6F5F3', @@ -167,6 +167,6 @@ export const colours: { [k in ThemeColorScheme]: Record } = { 400: '#B2A99E', 500: '#7F6F5E', 600: '#635649', - 700: '#473E34', - }, + 700: '#473E34' + } } diff --git a/frontend/src/theme/index.ts b/frontend/src/theme/index.ts index 6a842357f..3494468c4 100644 --- a/frontend/src/theme/index.ts +++ b/frontend/src/theme/index.ts @@ -7,5 +7,5 @@ import { textStyles } from './textStyles' export const theme = extendTheme({ colors: colours, textStyles, - components, + components }) diff --git a/frontend/src/theme/textStyles.ts b/frontend/src/theme/textStyles.ts index 078675479..70a10ff00 100644 --- a/frontend/src/theme/textStyles.ts +++ b/frontend/src/theme/textStyles.ts @@ -4,91 +4,91 @@ export const textStyles = { fontWeight: 700, fontSize: '4rem', lineHeight: '4.5rem', - letterSpacing: '-0.022em', + letterSpacing: '-0.022em' }, 'display-2': { fontStyle: 'normal', fontWeight: 600, fontSize: '2.5rem', lineHeight: '3rem', - letterSpacing: '-0.022em', + letterSpacing: '-0.022em' }, h1: { fontStyle: 'normal', fontWeight: 300, fontSize: '3.375rem', lineHeight: '4rem', - letterSpacing: '-0.022em', + letterSpacing: '-0.022em' }, 'h1-mobile': { fontStyle: 'normal', fontWeight: 300, fontSize: '2rem', lineHeight: '2.5rem', - letterSpacing: '-0.017em', + letterSpacing: '-0.017em' }, h2: { fontStyle: 'normal', fontWeight: 600, fontSize: '1.5rem', lineHeight: '2rem', - letterSpacing: '-0.019em', + letterSpacing: '-0.019em' }, h3: { fontWeight: 600, fontSize: '1.25rem', lineHeight: '2rem', - letterSpacing: '-0.017em', + letterSpacing: '-0.017em' }, h4: { fontWeight: 500, fontSize: '1.125rem', lineHeight: '1.5rem', - letterSpacing: '-0.014em', + letterSpacing: '-0.014em' }, 'subhead-1': { fontWeight: 500, fontSize: '1rem', lineHeight: '1.5rem', - letterSpacing: '-0.011em', + letterSpacing: '-0.011em' }, 'subhead-2': { fontWeight: 500, fontSize: '0.875rem', lineHeight: '1.5rem', - letterSpacing: '-0.006em', + letterSpacing: '-0.006em' }, 'subhead-3': { fontWeight: 600, fontSize: '0.875rem', lineHeight: '1.5rem', letterSpacing: '0.08em', - textTransform: 'uppercase', + textTransform: 'uppercase' }, 'body-1': { fontStyle: 'normal', fontWeight: 400, fontSize: '1rem', lineHeight: '1.5rem', - letterSpacing: '-0.011em', + letterSpacing: '-0.011em' }, 'body-2': { fontStyle: 'normal', fontWeight: 400, fontSize: '0.875rem', lineHeight: '1.5rem', - letterSpacing: '-0.006em', + letterSpacing: '-0.006em' }, 'caption-1': { fontStyle: 'normal', fontWeight: 500, fontSize: '0.75rem', - lineHeight: '1rem', + lineHeight: '1rem' }, legal: { fontStyle: 'normal', fontWeight: 400, fontSize: '0.625rem', - lineHeight: '0.75rem', - }, + lineHeight: '0.75rem' + } } diff --git a/frontend/tsconfig.eslint.json b/frontend/tsconfig.eslint.json new file mode 100644 index 000000000..fc8520e73 --- /dev/null +++ b/frontend/tsconfig.eslint.json @@ -0,0 +1,3 @@ +{ + "extends": "./tsconfig.json" +} diff --git a/package-lock.json b/package-lock.json index 0660ae89d..e86da309f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,11 +19,8 @@ "concurrently": "^7.6.0", "cz-conventional-changelog": "^3.3.0", "env-cmd": "^10.1.0", - "eslint": "^8.28.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-simple-import-sort": "^8.0.0", - "husky": "^8.0.2" + "husky": "^8.0.2", + "ts-standard": "^12.0.1" } }, "node_modules/@babel/code-frame": { @@ -574,6 +571,12 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, "node_modules/@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -928,6 +931,25 @@ "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", "dev": true }, + "node_modules/array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -937,6 +959,55 @@ "node": ">=8" } }, + "node_modules/array.prototype.flat": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", + "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.1.3" + } + }, "node_modules/arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -1038,6 +1109,15 @@ "ieee754": "^1.1.13" } }, + "node_modules/builtins": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", + "dev": true, + "dependencies": { + "semver": "^7.0.0" + } + }, "node_modules/cachedir": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", @@ -1047,6 +1127,19 @@ "node": ">=6" } }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -1577,6 +1670,22 @@ "clone": "^1.0.2" } }, + "node_modules/define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dev": true, + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", @@ -1671,6 +1780,70 @@ "is-arrayish": "^0.2.1" } }, + "node_modules/es-abstract": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", + "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.2", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -1748,177 +1921,464 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "node_modules/eslint-config-standard": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz", + "integrity": "sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==", "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], "peerDependencies": { - "eslint": ">=7.0.0" + "eslint": "^8.0.1", + "eslint-plugin-import": "^2.25.2", + "eslint-plugin-n": "^15.0.0", + "eslint-plugin-promise": "^6.0.0" + } + }, + "node_modules/eslint-config-standard-jsx": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-11.0.0.tgz", + "integrity": "sha512-+1EV/R0JxEK1L0NGolAr8Iktm3Rgotx3BKwgaX+eAuSX8D952LULKtjgZD3F+e6SvibONnhLwoTi9DPxN5LvvQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "peerDependencies": { + "eslint": "^8.8.0", + "eslint-plugin-react": "^7.28.0" } }, - "node_modules/eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "node_modules/eslint-config-standard-with-typescript": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-23.0.0.tgz", + "integrity": "sha512-iaaWifImn37Z1OXbNW1es7KI+S7D408F9ys0bpaQf2temeBWlvb0Nc5qHkOgYaRb5QxTZT32GGeN1gtswASOXA==", "dev": true, "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=12.0.0" + "@typescript-eslint/parser": "^5.0.0", + "eslint-config-standard": "17.0.0" }, "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" - }, - "peerDependenciesMeta": { - "eslint-config-prettier": { - "optional": true - } + "@typescript-eslint/eslint-plugin": "^5.0.0", + "eslint": "^8.0.1", + "eslint-plugin-import": "^2.25.2", + "eslint-plugin-n": "^15.0.0", + "eslint-plugin-promise": "^6.0.0", + "typescript": "*" } }, - "node_modules/eslint-plugin-simple-import-sort": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-8.0.0.tgz", - "integrity": "sha512-bXgJQ+lqhtQBCuWY/FUWdB27j4+lqcvXv5rUARkzbeWLwea+S5eBZEQrhnO+WgX3ZoJHVj0cn943iyXwByHHQw==", + "node_modules/eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", "dev": true, - "peerDependencies": { - "eslint": ">=5.0.0" + "dependencies": { + "debug": "^3.2.7", + "resolve": "^1.20.0" } }, - "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } } }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, "dependencies": { - "eslint-visitor-keys": "^2.0.0" + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-es": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", + "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", + "dev": true, + "dependencies": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + "node": ">=8.10.0" }, "funding": { "url": "https://github.com/sponsors/mysticatea" }, "peerDependencies": { - "eslint": ">=5" + "eslint": ">=4.19.1" } }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "node_modules/eslint-plugin-es/node_modules/eslint-utils": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, "engines": { - "node": ">=10" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "node_modules/eslint-plugin-es/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "dev": true, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=4" } }, - "node_modules/espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "node_modules/eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", "dev": true, "dependencies": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=4" }, - "funding": { - "url": "https://opencollective.com/eslint" + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" + "ms": "2.0.0" } }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "dependencies": { - "estraverse": "^5.2.0" + "esutils": "^2.0.2" }, "engines": { - "node": ">=4.0" + "node": ">=0.10.0" } }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "node_modules/eslint-plugin-n": { + "version": "15.5.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.5.1.tgz", + "integrity": "sha512-kAd+xhZm7brHoFLzKLB7/FGRFJNg/srmv67mqb7tto22rpr4wv/LV6RuXzAfv3jbab7+k1wi42PsIhGviywaaw==", "dev": true, + "dependencies": { + "builtins": "^5.0.1", + "eslint-plugin-es": "^4.1.0", + "eslint-utils": "^3.0.0", + "ignore": "^5.1.1", + "is-core-module": "^2.11.0", + "minimatch": "^3.1.2", + "resolve": "^1.22.1", + "semver": "^7.3.8" + }, "engines": { - "node": ">=0.10.0" + "node": ">=12.22.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=7.0.0" } }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "node_modules/eslint-plugin-n/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" }, "engines": { "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/eslint-plugin-promise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", + "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.31.11", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz", + "integrity": "sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.3", + "semver": "^6.3.0", + "string.prototype.matchall": "^4.0.8" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "dev": true, + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-scope": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", + "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/espree": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", + "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "dev": true, + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, "node_modules/expand-tilde": { @@ -1953,12 +2413,6 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, "node_modules/fast-glob": { "version": "3.2.11", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", @@ -2148,6 +2602,33 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -2157,6 +2638,32 @@ "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -2169,6 +2676,22 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/git-raw-commits": { "version": "2.0.11", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", @@ -2342,6 +2865,15 @@ "node": ">= 0.4.0" } }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -2351,6 +2883,45 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -2531,12 +3102,66 @@ "node": ">=12.0.0" } }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-core-module": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", @@ -2549,6 +3174,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2588,6 +3228,18 @@ "node": ">=8" } }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -2597,6 +3249,21 @@ "node": ">=0.12.0" } }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", @@ -2624,6 +3291,34 @@ "node": ">=0.10.0" } }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", @@ -2636,6 +3331,36 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-text-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", @@ -2666,6 +3391,18 @@ "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", "dev": true }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -2705,6 +3442,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -2723,6 +3466,18 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -2760,6 +3515,19 @@ "node": "*" } }, + "node_modules/jsx-ast-utils": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", + "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.5", + "object.assign": "^4.1.3" + }, + "engines": { + "node": ">=4.0" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -2788,6 +3556,18 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "node_modules/load-json-file": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-7.0.1.tgz", + "integrity": "sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -2900,6 +3680,18 @@ "node": ">=0.10.0" } }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -3048,58 +3840,164 @@ "kind-of": "^6.0.3" }, "engines": { - "node": ">= 6" + "node": ">= 6" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "dev": true + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==", - "dev": true - }, - "node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "node_modules/object.hasown": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", + "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", "dev": true, "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" }, - "engines": { - "node": ">=10" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "node_modules/object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", "dev": true, "dependencies": { - "path-key": "^3.0.0" + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/once": { @@ -3307,41 +4205,131 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true, "engines": { - "node": ">= 0.8.0" + "node": ">=6" } }, - "node_modules/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "node_modules/pkg-conf": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-4.0.0.tgz", + "integrity": "sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==", "dev": true, - "peer": true, - "bin": { - "prettier": "bin-prettier.js" + "dependencies": { + "find-up": "^6.0.0", + "load-json-file": "^7.0.0" }, "engines": { - "node": ">=10.13.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "node_modules/pkg-conf/node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", "dev": true, "dependencies": { - "fast-diff": "^1.1.2" + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" }, "engines": { - "node": ">=6.0.0" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-conf/node_modules/locate-path": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.1.1.tgz", + "integrity": "sha512-vJXaRMJgRVD3+cUZs3Mncj2mxpt5mP0EmNOsxRSZRMlbqjvxzDEOIUWXGmavo0ZC9+tNZCBLQ66reA11nbpHZg==", + "dev": true, + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-conf/node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-conf/node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-conf/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/pkg-conf/node_modules/yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" } }, "node_modules/punycode": { @@ -3392,6 +4380,12 @@ "node": ">=8" } }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, "node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -3548,6 +4542,23 @@ "node": ">=8" } }, + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -3728,6 +4739,20 @@ } ] }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -3776,6 +4801,20 @@ "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", "dev": true }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -3829,13 +4868,163 @@ "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", "dev": true }, - "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/standard-engine": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-15.0.0.tgz", + "integrity": "sha512-4xwUhJNo1g/L2cleysUqUv7/btn7GEbYJvmgKrQ2vd/8pkTmN8cpqAZg+BT8Z1hNeEH787iWUdOpL8fmApLtxA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "get-stdin": "^8.0.0", + "minimist": "^1.2.6", + "pkg-conf": "^3.1.0", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/standard-engine/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/standard-engine/node_modules/load-json-file": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.15", + "parse-json": "^4.0.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0", + "type-fest": "^0.3.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/standard-engine/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/standard-engine/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/standard-engine/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/standard-engine/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/standard-engine/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/standard-engine/node_modules/pkg-conf": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", + "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0", + "load-json-file": "^5.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/standard-engine/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/standard-engine/node_modules/type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", "dev": true, - "dependencies": { - "readable-stream": "^3.0.0" + "engines": { + "node": ">=6" } }, "node_modules/string_decoder": { @@ -3861,6 +5050,53 @@ "node": ">=8" } }, + "node_modules/string.prototype.matchall": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", + "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.3", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -4054,6 +5290,56 @@ } } }, + "node_modules/ts-standard": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/ts-standard/-/ts-standard-12.0.1.tgz", + "integrity": "sha512-Ewk3l0k/SwckuVoMokkKq5W0B6daOlVzk0Yu9Wrcp3m0/CWneVM8NK/EgUZFkx4OHw1F+RpAC7dFyzO2cLNmsw==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "^5.0.0", + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^8.0.1", + "eslint-config-standard-jsx": "^11.0.0", + "eslint-config-standard-with-typescript": "^23.0.0", + "eslint-plugin-import": "^2.25.2", + "eslint-plugin-n": "^15.0.0", + "eslint-plugin-promise": "^6.0.0", + "eslint-plugin-react": "^7.28.0", + "minimist": "^1.2.6", + "pkg-conf": "^4.0.0", + "standard-engine": "^15.0.0" + }, + "bin": { + "ts-standard": "cli.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "typescript": "*" + } + }, + "node_modules/tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/tslib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", @@ -4118,6 +5404,21 @@ "node": ">=4.2.0" } }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -4182,6 +5483,22 @@ "node": ">= 8" } }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -4214,6 +5531,15 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "node_modules/xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", @@ -4730,6 +6056,12 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, "@types/minimist": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", @@ -4957,12 +6289,62 @@ "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", "dev": true }, + "array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" + } + }, "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, + "array.prototype.flat": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz", + "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.tosorted": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", + "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.1.3" + } + }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", @@ -5027,12 +6409,31 @@ "ieee754": "^1.1.13" } }, + "builtins": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-5.0.1.tgz", + "integrity": "sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==", + "dev": true, + "requires": { + "semver": "^7.0.0" + } + }, "cachedir": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", "integrity": "sha512-A+Fezp4zxnit6FanDmv9EqXNAi3vt9DWp51/71UEhXukb7QUuvtv9344h91dyAxuTLoSYJFU299qzR3tzwPAhw==", "dev": true }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -5428,6 +6829,16 @@ "clone": "^1.0.2" } }, + "define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dev": true, + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, "detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", @@ -5498,6 +6909,58 @@ "is-arrayish": "^0.2.1" } }, + "es-abstract": { + "version": "1.20.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz", + "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.2", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + } + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -5557,29 +7020,230 @@ "text-table": "^0.2.0" } }, - "eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "eslint-config-standard": { + "version": "17.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz", + "integrity": "sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg==", + "dev": true, + "requires": {} + }, + "eslint-config-standard-jsx": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-11.0.0.tgz", + "integrity": "sha512-+1EV/R0JxEK1L0NGolAr8Iktm3Rgotx3BKwgaX+eAuSX8D952LULKtjgZD3F+e6SvibONnhLwoTi9DPxN5LvvQ==", "dev": true, "requires": {} }, - "eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "eslint-config-standard-with-typescript": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard-with-typescript/-/eslint-config-standard-with-typescript-23.0.0.tgz", + "integrity": "sha512-iaaWifImn37Z1OXbNW1es7KI+S7D408F9ys0bpaQf2temeBWlvb0Nc5qHkOgYaRb5QxTZT32GGeN1gtswASOXA==", "dev": true, "requires": { - "prettier-linter-helpers": "^1.0.0" + "@typescript-eslint/parser": "^5.0.0", + "eslint-config-standard": "17.0.0" } }, - "eslint-plugin-simple-import-sort": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-8.0.0.tgz", - "integrity": "sha512-bXgJQ+lqhtQBCuWY/FUWdB27j4+lqcvXv5rUARkzbeWLwea+S5eBZEQrhnO+WgX3ZoJHVj0cn943iyXwByHHQw==", + "eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-module-utils": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz", + "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==", + "dev": true, + "requires": { + "debug": "^3.2.7" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-plugin-es": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz", + "integrity": "sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + }, + "dependencies": { + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "dev": true, + "requires": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "eslint-plugin-n": { + "version": "15.5.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.5.1.tgz", + "integrity": "sha512-kAd+xhZm7brHoFLzKLB7/FGRFJNg/srmv67mqb7tto22rpr4wv/LV6RuXzAfv3jbab7+k1wi42PsIhGviywaaw==", + "dev": true, + "requires": { + "builtins": "^5.0.1", + "eslint-plugin-es": "^4.1.0", + "eslint-utils": "^3.0.0", + "ignore": "^5.1.1", + "is-core-module": "^2.11.0", + "minimatch": "^3.1.2", + "resolve": "^1.22.1", + "semver": "^7.3.8" + }, + "dependencies": { + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "eslint-plugin-promise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", + "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", "dev": true, "requires": {} }, + "eslint-plugin-react": { + "version": "7.31.11", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz", + "integrity": "sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==", + "dev": true, + "requires": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.3", + "semver": "^6.3.0", + "string.prototype.matchall": "^4.0.8" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "resolve": { + "version": "2.0.0-next.4", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz", + "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "eslint-scope": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", @@ -5697,12 +7361,6 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "dev": true }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, "fast-glob": { "version": "3.2.11", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", @@ -5860,18 +7518,63 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true + }, "get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, "git-raw-commits": { "version": "2.0.11", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", @@ -6002,12 +7705,42 @@ "function-bind": "^1.1.1" } }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true + }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } + }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, "homedir-polyfill": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", @@ -6134,12 +7867,48 @@ "wrap-ansi": "^7.0.0" } }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", "dev": true }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true + }, "is-core-module": { "version": "2.11.0", "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", @@ -6149,6 +7918,15 @@ "has": "^1.0.3" } }, + "is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -6176,12 +7954,27 @@ "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", "dev": true }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", @@ -6200,12 +7993,49 @@ "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", "dev": true }, + "is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, "is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, "is-text-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", @@ -6227,6 +8057,15 @@ "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==", "dev": true }, + "is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -6260,6 +8099,12 @@ "argparse": "^2.0.1" } }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, "json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", @@ -6278,6 +8123,15 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, "jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -6304,6 +8158,16 @@ "through": ">=2.2.7 <3" } }, + "jsx-ast-utils": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", + "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", + "dev": true, + "requires": { + "array-includes": "^3.1.5", + "object.assign": "^4.1.3" + } + }, "kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -6326,6 +8190,12 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "dev": true }, + "load-json-file": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-7.0.1.tgz", + "integrity": "sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==", + "dev": true + }, "locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -6423,6 +8293,15 @@ "integrity": "sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==", "dev": true }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -6582,6 +8461,79 @@ "path-key": "^3.0.0" } }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true + }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "object.entries": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "object.fromentries": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "object.hasown": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", + "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", + "dev": true, + "requires": { + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -6724,26 +8676,88 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pkg-conf": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-4.0.0.tgz", + "integrity": "sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==", + "dev": true, + "requires": { + "find-up": "^6.0.0", + "load-json-file": "^7.0.0" + }, + "dependencies": { + "find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "requires": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + } + }, + "locate-path": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.1.1.tgz", + "integrity": "sha512-vJXaRMJgRVD3+cUZs3Mncj2mxpt5mP0EmNOsxRSZRMlbqjvxzDEOIUWXGmavo0ZC9+tNZCBLQ66reA11nbpHZg==", + "dev": true, + "requires": { + "p-locate": "^6.0.0" + } + }, + "p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "requires": { + "yocto-queue": "^1.0.0" + } + }, + "p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "requires": { + "p-limit": "^4.0.0" + } + }, + "path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true + }, + "yocto-queue": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", + "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", + "dev": true + } + } + }, "prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", "dev": true }, - "prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true, - "peer": true - }, - "prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "dev": true, "requires": { - "fast-diff": "^1.1.2" + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" } }, "punycode": { @@ -6770,6 +8784,12 @@ "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -6891,6 +8911,17 @@ "strip-indent": "^3.0.0" } }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -7000,6 +9031,17 @@ "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -7036,6 +9078,17 @@ "integrity": "sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==", "dev": true }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } + }, "signal-exit": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", @@ -7095,6 +9148,108 @@ "readable-stream": "^3.0.0" } }, + "standard-engine": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-15.0.0.tgz", + "integrity": "sha512-4xwUhJNo1g/L2cleysUqUv7/btn7GEbYJvmgKrQ2vd/8pkTmN8cpqAZg+BT8Z1hNeEH787iWUdOpL8fmApLtxA==", + "dev": true, + "requires": { + "get-stdin": "^8.0.0", + "minimist": "^1.2.6", + "pkg-conf": "^3.1.0", + "xdg-basedir": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "load-json-file": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", + "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "parse-json": "^4.0.0", + "pify": "^4.0.1", + "strip-bom": "^3.0.0", + "type-fest": "^0.3.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true + }, + "pkg-conf": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", + "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "load-json-file": "^5.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + }, + "type-fest": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", + "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", + "dev": true + } + } + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -7115,6 +9270,44 @@ "strip-ansi": "^6.0.1" } }, + "string.prototype.matchall": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", + "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.3", + "side-channel": "^1.0.4" + } + }, + "string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, "strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -7244,6 +9437,46 @@ "yn": "3.1.1" } }, + "ts-standard": { + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/ts-standard/-/ts-standard-12.0.1.tgz", + "integrity": "sha512-Ewk3l0k/SwckuVoMokkKq5W0B6daOlVzk0Yu9Wrcp3m0/CWneVM8NK/EgUZFkx4OHw1F+RpAC7dFyzO2cLNmsw==", + "dev": true, + "requires": { + "@typescript-eslint/eslint-plugin": "^5.0.0", + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^8.0.1", + "eslint-config-standard-jsx": "^11.0.0", + "eslint-config-standard-with-typescript": "^23.0.0", + "eslint-plugin-import": "^2.25.2", + "eslint-plugin-n": "^15.0.0", + "eslint-plugin-promise": "^6.0.0", + "eslint-plugin-react": "^7.28.0", + "minimist": "^1.2.6", + "pkg-conf": "^4.0.0", + "standard-engine": "^15.0.0" + } + }, + "tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + } + } + }, "tslib": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.0.tgz", @@ -7288,6 +9521,18 @@ "integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==", "dev": true }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, "universalify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", @@ -7343,6 +9588,19 @@ "isexe": "^2.0.0" } }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -7366,6 +9624,12 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, + "xdg-basedir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", + "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", + "dev": true + }, "y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index c7f41146f..7c1a74321 100644 --- a/package.json +++ b/package.json @@ -32,15 +32,12 @@ "concurrently": "^7.6.0", "cz-conventional-changelog": "^3.3.0", "env-cmd": "^10.1.0", - "eslint": "^8.28.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-simple-import-sort": "^8.0.0", - "husky": "^8.0.2" + "husky": "^8.0.2", + "ts-standard": "^12.0.1" }, "lint-staged": { "**/*.(js|jsx|ts|tsx)": [ - "eslint --fix" + "ts-standard --fix" ] }, "config": { @@ -48,4 +45,4 @@ "path": "./node_modules/cz-conventional-changelog" } } -} \ No newline at end of file +} diff --git a/shared/.eslintrc.js b/shared/.eslintrc.js deleted file mode 100644 index 91db1642d..000000000 --- a/shared/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - extends: ['../.eslintrc.js'], - parserOptions: { - project: ['./tsconfig.json'], - tsconfigRootDir: __dirname, - }, -} diff --git a/shared/jest.config.ts b/shared/jest.config.ts index faff05f8d..b4afa8c45 100644 --- a/shared/jest.config.ts +++ b/shared/jest.config.ts @@ -6,7 +6,7 @@ const config: Config.InitialOptions = { roots: ['/src'], testPathIgnorePatterns: ['/build/', '/node_modules/'], collectCoverageFrom: ['/src/**/*.{ts,js}'], - coveragePathIgnorePatterns: ['/build', '/node_modules'], + coveragePathIgnorePatterns: ['/build', '/node_modules'] } export default config diff --git a/shared/package-lock.json b/shared/package-lock.json index 008185bcc..775bff0fb 100644 --- a/shared/package-lock.json +++ b/shared/package-lock.json @@ -12,7 +12,6 @@ "@types/jest": "^28.1.6", "jest": "^28.1.3", "lint-staged": "^13.0.3", - "prettier": "^2.6.2", "ts-jest": "^28.0.7", "tsc-watch": "^5.0.3", "typescript": "^4.6.3" @@ -1983,9 +1982,9 @@ "dev": true }, "node_modules/is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -3431,21 +3430,6 @@ "node": ">=8" } }, - "node_modules/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, "node_modules/pretty-format": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", @@ -5836,9 +5820,9 @@ "dev": true }, "is-core-module": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", - "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "dev": true, "requires": { "has": "^1.0.3" @@ -6905,12 +6889,6 @@ "find-up": "^4.0.0" } }, - "prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", - "dev": true - }, "pretty-format": { "version": "28.1.3", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.3.tgz", diff --git a/shared/package.json b/shared/package.json index c23cb1ceb..2bf25b1c9 100644 --- a/shared/package.json +++ b/shared/package.json @@ -4,8 +4,8 @@ "private": true, "scripts": { "pre-commit": "lint-staged", - "lint": "eslint --ext ts,tsx,js,jsx . && prettier -c \"src/**/*.{ts,tsx}\"", - "lint:fix": "eslint --fix --ext ts,tsx,js,jsx . && prettier -c --write \"src/**/*.{ts,tsx}\"", + "lint": "ts-standard", + "lint:fix": "npm run lint -- --fix", "build": "tsc --build --clean && tsc --build tsconfig.build.json --force", "test": "jest", "test:watch": "jest --watch --runInBand", @@ -17,7 +17,6 @@ "@types/jest": "^28.1.6", "jest": "^28.1.3", "lint-staged": "^13.0.3", - "prettier": "^2.6.2", "ts-jest": "^28.0.7", "tsc-watch": "^5.0.3", "typescript": "^4.6.3" @@ -28,5 +27,9 @@ "eslint --fix" ] }, - "dependencies": {} + "ts-standard": { + "ignore": [ + "build" + ] + } } diff --git a/shared/tsconfig.eslint.json b/shared/tsconfig.eslint.json new file mode 100644 index 000000000..96d25697f --- /dev/null +++ b/shared/tsconfig.eslint.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "include": [ + "src/**/*", + "jest.config.ts" + ] +} diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json new file mode 100644 index 000000000..f7a27aa49 --- /dev/null +++ b/tsconfig.eslint.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "module": "commonjs", + "composite": true, + "declaration": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "strict": true, + "strictPropertyInitialization": false, + "allowSyntheticDefaultImports": true, + "target": "es2017", + "sourceMap": true, + "incremental": true, + "skipLibCheck": true, + "esModuleInterop": true, + "noImplicitAny": false, + "strictBindCallApply": false, + "forceConsistentCasingInFileNames": true + } +}