From 197373c9dfd6f9a4a7eb792f01a60b1155f7c6d2 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 25 Aug 2022 13:39:58 +0200 Subject: [PATCH 1/9] Moved dto to separate package --- dto/.eslintrc.js | 25 +++++++++++++++++++++++++ dto/.prettierrc | 7 +++++++ dto/package.json | 14 ++++++++++++++ dto/requests/auth.ts | 10 ---------- dto/requests/base.ts | 2 -- dto/requests/fs.ts | 12 ------------ dto/responses/base.ts | 12 ------------ dto/{ => src}/index.ts | 0 dto/src/requests/auth.ts | 14 ++++++++++++++ dto/src/requests/base.ts | 1 + dto/src/requests/fs.ts | 19 +++++++++++++++++++ dto/{ => src}/requests/index.ts | 0 dto/{ => src}/responses/auth.ts | 13 +++++++++++-- dto/src/responses/base.ts | 12 ++++++++++++ dto/{ => src}/responses/fs.ts | 27 +++++++++++++++++++++++---- dto/{ => src}/responses/index.ts | 0 dto/tsconfig.json | 17 +++++++++++++++++ dto/yarn.lock | 26 ++++++++++++++++++++++++++ 18 files changed, 169 insertions(+), 42 deletions(-) create mode 100644 dto/.eslintrc.js create mode 100644 dto/.prettierrc create mode 100644 dto/package.json delete mode 100644 dto/requests/auth.ts delete mode 100644 dto/requests/base.ts delete mode 100644 dto/requests/fs.ts delete mode 100644 dto/responses/base.ts rename dto/{ => src}/index.ts (100%) create mode 100644 dto/src/requests/auth.ts create mode 100644 dto/src/requests/base.ts create mode 100644 dto/src/requests/fs.ts rename dto/{ => src}/requests/index.ts (100%) rename dto/{ => src}/responses/auth.ts (64%) create mode 100644 dto/src/responses/base.ts rename dto/{ => src}/responses/fs.ts (53%) rename dto/{ => src}/responses/index.ts (100%) create mode 100644 dto/tsconfig.json create mode 100644 dto/yarn.lock diff --git a/dto/.eslintrc.js b/dto/.eslintrc.js new file mode 100644 index 0000000..2237313 --- /dev/null +++ b/dto/.eslintrc.js @@ -0,0 +1,25 @@ +module.exports = { + parser: '@typescript-eslint/parser', + parserOptions: { + project: 'tsconfig.json', + tsconfigRootDir: __dirname, + sourceType: 'module', + }, + plugins: ['@typescript-eslint/eslint-plugin'], + extends: [ + 'plugin:@typescript-eslint/recommended', + 'plugin:prettier/recommended', + ], + root: true, + env: { + node: true, + jest: true, + }, + ignorePatterns: ['.eslintrc.js'], + rules: { + '@typescript-eslint/interface-name-prefix': 'off', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-explicit-any': 'off', + }, +}; diff --git a/dto/.prettierrc b/dto/.prettierrc new file mode 100644 index 0000000..9145d2d --- /dev/null +++ b/dto/.prettierrc @@ -0,0 +1,7 @@ +{ + "tabWidth": 4, + "useTabs": true, + "singleQuote": true, + "trailingComma": "none", + "endOfLine": "lf" +} diff --git a/dto/package.json b/dto/package.json new file mode 100644 index 0000000..4123b61 --- /dev/null +++ b/dto/package.json @@ -0,0 +1,14 @@ +{ + "name": "dto", + "private": true, + "version": "1.0.0", + "main": "src/index.ts", + "dependencies": { + "class-transformer": "^0.5.1", + "class-validator": "^0.13.2" + }, + "scripts": { + "lint": "eslint \"src/**/*.ts\" && tsc --no-emit", + "lint-fix": "eslint \"src/**/*.ts\" --fix" + } +} diff --git a/dto/requests/auth.ts b/dto/requests/auth.ts deleted file mode 100644 index ea1e6f7..0000000 --- a/dto/requests/auth.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { BaseRequest } from './base'; - -export interface AuthSignUpRequest extends BaseRequest { - username: string; - password: string; -} - -export interface AuthLoginRequest extends AuthSignUpRequest { - otp?: string; -} diff --git a/dto/requests/base.ts b/dto/requests/base.ts deleted file mode 100644 index 9d6341d..0000000 --- a/dto/requests/base.ts +++ /dev/null @@ -1,2 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface BaseRequest {} diff --git a/dto/requests/fs.ts b/dto/requests/fs.ts deleted file mode 100644 index 5cd1d06..0000000 --- a/dto/requests/fs.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { BaseRequest } from './base'; - -export type CreateFileRequest = CreateFolderRequest; - -export interface CreateFolderRequest extends BaseRequest { - parent: number; - name: string; -} - -export interface DeleteRequest extends BaseRequest { - node: number; -} diff --git a/dto/responses/base.ts b/dto/responses/base.ts deleted file mode 100644 index ce059ce..0000000 --- a/dto/responses/base.ts +++ /dev/null @@ -1,12 +0,0 @@ -export interface BaseResponse { - statusCode: number; -} - -export interface SuccessResponse extends BaseResponse { - statusCode: 200; -} - -export interface ErrorResponse extends BaseResponse { - statusCode: 400 | 401 | 403; - message?: string; -} diff --git a/dto/index.ts b/dto/src/index.ts similarity index 100% rename from dto/index.ts rename to dto/src/index.ts diff --git a/dto/src/requests/auth.ts b/dto/src/requests/auth.ts new file mode 100644 index 0000000..9fd1ba4 --- /dev/null +++ b/dto/src/requests/auth.ts @@ -0,0 +1,14 @@ +import { BaseRequest } from './base'; +import { IsEmail, IsNotEmpty } from 'class-validator'; + +export class AuthSignUpRequest extends BaseRequest { + @IsEmail() + username: string; + + @IsNotEmpty() + password: string; +} + +export class AuthLoginRequest extends AuthSignUpRequest { + otp?: string; +} diff --git a/dto/src/requests/base.ts b/dto/src/requests/base.ts new file mode 100644 index 0000000..a74ed1a --- /dev/null +++ b/dto/src/requests/base.ts @@ -0,0 +1 @@ +export class BaseRequest {} diff --git a/dto/src/requests/fs.ts b/dto/src/requests/fs.ts new file mode 100644 index 0000000..63ecabf --- /dev/null +++ b/dto/src/requests/fs.ts @@ -0,0 +1,19 @@ +import { BaseRequest } from './base'; +import { IsInt, IsNotEmpty, Min } from 'class-validator'; + +export type CreateFileRequest = CreateFolderRequest; + +export class CreateFolderRequest extends BaseRequest { + @IsInt() + @Min(1) + parent: number; + + @IsNotEmpty() + name: string; +} + +export class DeleteRequest extends BaseRequest { + @IsInt() + @Min(1) + node: number; +} diff --git a/dto/requests/index.ts b/dto/src/requests/index.ts similarity index 100% rename from dto/requests/index.ts rename to dto/src/requests/index.ts diff --git a/dto/responses/auth.ts b/dto/src/responses/auth.ts similarity index 64% rename from dto/responses/auth.ts rename to dto/src/responses/auth.ts index 545a065..418223d 100644 --- a/dto/responses/auth.ts +++ b/dto/src/responses/auth.ts @@ -1,4 +1,5 @@ import { BaseResponse, SuccessResponse } from './base'; +import { IsBase32, IsJWT, IsNotEmpty } from 'class-validator'; export type TfaRequiredResponse = SuccessResponse; export type RemoveTfaResponse = SuccessResponse; @@ -7,13 +8,21 @@ export type TfaCompletedResponse = SuccessResponse; export type SignupResponse = SuccessResponse; export type RefreshResponse = LoginResponse; -export interface LoginResponse extends BaseResponse { +export class LoginResponse extends BaseResponse { statusCode: 200; + + @IsNotEmpty() + @IsJWT() jwt: string; } -export interface RequestTotpTfaResponse extends BaseResponse { +export class RequestTotpTfaResponse extends BaseResponse { statusCode: 200; + + @IsNotEmpty() qrCode: string; + + @IsNotEmpty() + @IsBase32() secret: string; } diff --git a/dto/src/responses/base.ts b/dto/src/responses/base.ts new file mode 100644 index 0000000..583eed3 --- /dev/null +++ b/dto/src/responses/base.ts @@ -0,0 +1,12 @@ +export class BaseResponse { + statusCode: number; +} + +export class SuccessResponse extends BaseResponse { + statusCode: 200; +} + +export class ErrorResponse extends BaseResponse { + statusCode: 400 | 401 | 403; + message?: string; +} diff --git a/dto/responses/fs.ts b/dto/src/responses/fs.ts similarity index 53% rename from dto/responses/fs.ts rename to dto/src/responses/fs.ts index 8432548..e4cf40f 100644 --- a/dto/responses/fs.ts +++ b/dto/src/responses/fs.ts @@ -1,30 +1,49 @@ import { BaseResponse, SuccessResponse } from './base'; +import { IsBoolean, IsInt, IsNotEmpty, Min } from 'class-validator'; export type UploadFileResponse = SuccessResponse; export type DeleteResponse = SuccessResponse; export type CreateFileResponse = CreateFolderResponse; -export interface GetRootResponse extends BaseResponse { +export class GetRootResponse extends BaseResponse { statusCode: 200; + + @IsInt() + @Min(1) rootId: number; } -export interface GetNodeResponse extends BaseResponse { +export class GetNodeResponse extends BaseResponse { statusCode: 200; + + @IsInt() + @Min(1) id: number; + + @IsNotEmpty() name: string; + + @IsBoolean() isFile: boolean; + parent: number | null; + children?: number[]; + size?: number; } -export interface GetPathResponse extends BaseResponse { +export class GetPathResponse extends BaseResponse { statusCode: 200; + + @IsNotEmpty() path: string; } -export interface CreateFolderResponse extends BaseResponse { +export class CreateFolderResponse extends BaseResponse { statusCode: 200; + + @IsInt() + @Min(1) id: number; } diff --git a/dto/responses/index.ts b/dto/src/responses/index.ts similarity index 100% rename from dto/responses/index.ts rename to dto/src/responses/index.ts diff --git a/dto/tsconfig.json b/dto/tsconfig.json new file mode 100644 index 0000000..7fe4cb9 --- /dev/null +++ b/dto/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "module": "commonjs", + "declaration": false, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "target": "es2017", + "sourceMap": true, + "outDir": "./dist", + "baseUrl": "./src", + "incremental": true, + "skipLibCheck": true + }, + "exclude": ["node_modules", "dist"] +} diff --git a/dto/yarn.lock b/dto/yarn.lock new file mode 100644 index 0000000..0434e37 --- /dev/null +++ b/dto/yarn.lock @@ -0,0 +1,26 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +class-transformer@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/class-transformer/-/class-transformer-0.5.1.tgz#24147d5dffd2a6cea930a3250a677addf96ab336" + integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw== + +class-validator@^0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.13.2.tgz#64b031e9f3f81a1e1dcd04a5d604734608b24143" + integrity sha512-yBUcQy07FPlGzUjoLuUfIOXzgynnQPPruyK1Ge2B74k9ROwnle1E+NxLWnUv5OLU8hA/qL5leAE9XnXq3byaBw== + dependencies: + libphonenumber-js "^1.9.43" + validator "^13.7.0" + +libphonenumber-js@^1.9.43: + version "1.10.13" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.13.tgz#0b5833c7fdbf671140530d83531c6753f7e0ea3c" + integrity sha512-b74iyWmwb4GprAUPjPkJ11GTC7KX4Pd3onpJfKxYyY8y9Rbb4ERY47LvCMEDM09WD3thiLDMXtkfDK/AX+zT7Q== + +validator@^13.7.0: + version "13.7.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857" + integrity sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw== From 032ce687b272150e57f579b0d8cd9a87b1ab503d Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 25 Aug 2022 13:41:29 +0200 Subject: [PATCH 2/9] Use dto package in frontend --- frontend/package.json | 1 + frontend/src/api/base.ts | 4 +--- frontend/src/api/index.ts | 4 +++- frontend/yarn.lock | 29 +++++++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/frontend/package.json b/frontend/package.json index 28acce3..b2f0219 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,6 +10,7 @@ "dependencies": { "axios": "^0.27.2", "core-js": "^3.8.3", + "dto": "../dto", "filesize": "^9.0.11", "jwt-decode": "^3.1.2", "naive-ui": "^2.32.1", diff --git a/frontend/src/api/base.ts b/frontend/src/api/base.ts index 26f786c..406d9bb 100644 --- a/frontend/src/api/base.ts +++ b/frontend/src/api/base.ts @@ -1,7 +1,5 @@ import axios from 'axios'; -import { Requests, Responses } from '../../../dto'; - -export * from '../../../dto'; +import { Requests, Responses } from 'dto'; export const post = (url: string, data: T) => axios diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts index bfd428e..4790bba 100644 --- a/frontend/src/api/index.ts +++ b/frontend/src/api/index.ts @@ -1,4 +1,6 @@ -export { Requests, Responses, isErrorResponse } from './base'; +export { Requests, Responses } from 'dto'; + +export { isErrorResponse } from './base'; export * as Auth from './auth'; export * as FS from './fs'; export * from './util'; diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 00f7a2d..1667a11 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -2393,6 +2393,19 @@ ci-info@^1.5.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" integrity sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A== +class-transformer@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/class-transformer/-/class-transformer-0.5.1.tgz#24147d5dffd2a6cea930a3250a677addf96ab336" + integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw== + +class-validator@^0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.13.2.tgz#64b031e9f3f81a1e1dcd04a5d604734608b24143" + integrity sha512-yBUcQy07FPlGzUjoLuUfIOXzgynnQPPruyK1Ge2B74k9ROwnle1E+NxLWnUv5OLU8hA/qL5leAE9XnXq3byaBw== + dependencies: + libphonenumber-js "^1.9.43" + validator "^13.7.0" + clean-css@^5.2.2: version "5.3.1" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.1.tgz#d0610b0b90d125196a2894d35366f734e5d7aa32" @@ -2985,6 +2998,12 @@ dotenv@^10.0.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== +dto@../dto: + version "1.0.0" + dependencies: + class-transformer "^0.5.1" + class-validator "^0.13.2" + duplexer@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" @@ -4379,6 +4398,11 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +libphonenumber-js@^1.9.43: + version "1.10.13" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.13.tgz#0b5833c7fdbf671140530d83531c6753f7e0ea3c" + integrity sha512-b74iyWmwb4GprAUPjPkJ11GTC7KX4Pd3onpJfKxYyY8y9Rbb4ERY47LvCMEDM09WD3thiLDMXtkfDK/AX+zT7Q== + lilconfig@^2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.6.tgz#32a384558bd58af3d4c6e077dd1ad1d397bc69d4" @@ -6395,6 +6419,11 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +validator@^13.7.0: + version "13.7.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857" + integrity sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw== + vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" From 65464e762a126508ad8669a730669b2d8b98a8d3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 25 Aug 2022 13:43:47 +0200 Subject: [PATCH 3/9] Use dto package in backend --- package.json | 1 + yarn.lock | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/package.json b/package.json index 483496c..558f98f 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "@nestjs/typeorm": "^9.0.0", "argon2": "^0.28.7", "axios": "^0.27.2", + "dto": "./dto", "jsonwebtoken": "^8.5.1", "nodemailer": "^6.7.8", "notp": "^2.0.3", diff --git a/yarn.lock b/yarn.lock index 7ff7215..032b637 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1985,6 +1985,19 @@ cjs-module-lexer@^1.0.0: resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40" integrity sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA== +class-transformer@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/class-transformer/-/class-transformer-0.5.1.tgz#24147d5dffd2a6cea930a3250a677addf96ab336" + integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw== + +class-validator@^0.13.2: + version "0.13.2" + resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.13.2.tgz#64b031e9f3f81a1e1dcd04a5d604734608b24143" + integrity sha512-yBUcQy07FPlGzUjoLuUfIOXzgynnQPPruyK1Ge2B74k9ROwnle1E+NxLWnUv5OLU8hA/qL5leAE9XnXq3byaBw== + dependencies: + libphonenumber-js "^1.9.43" + validator "^13.7.0" + clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" @@ -2330,6 +2343,12 @@ dotenv@^16.0.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.1.tgz#8f8f9d94876c35dac989876a5d3a82a267fdce1d" integrity sha512-1K6hR6wtk2FviQ4kEiSjFiH5rpzEVi8WW0x96aztHVMhEspNpc4DVOUTEHtEva5VThQ8IaBX1Pe4gSzpVVUsKQ== +dto@./dto: + version "1.0.0" + dependencies: + class-transformer "^0.5.1" + class-validator "^0.13.2" + ecdsa-sig-formatter@1.0.11: version "1.0.11" resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" @@ -3901,6 +3920,11 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +libphonenumber-js@^1.9.43: + version "1.10.13" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.13.tgz#0b5833c7fdbf671140530d83531c6753f7e0ea3c" + integrity sha512-b74iyWmwb4GprAUPjPkJ11GTC7KX4Pd3onpJfKxYyY8y9Rbb4ERY47LvCMEDM09WD3thiLDMXtkfDK/AX+zT7Q== + light-my-request@5.4.0: version "5.4.0" resolved "https://registry.yarnpkg.com/light-my-request/-/light-my-request-5.4.0.tgz#bcd483a9157592b16101cb2042275ca89b79aec1" @@ -5669,6 +5693,11 @@ v8-to-istanbul@^9.0.1: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" +validator@^13.7.0: + version "13.7.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857" + integrity sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw== + walker@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" From 23ba777e5aaf72a0352e1fbd336d0d2c3d09c4b8 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 25 Aug 2022 14:16:29 +0200 Subject: [PATCH 4/9] Frontend validation --- dto/src/responses/auth.ts | 10 +++------- dto/src/responses/base.ts | 12 ++++++++++-- dto/src/responses/fs.ts | 20 +++++++------------- dto/tsconfig.json | 3 ++- frontend/src/api/auth.ts | 2 +- frontend/src/api/base.ts | 14 +++++++++++--- frontend/src/views/SetTokenView.vue | 2 +- frontend/tsconfig.json | 3 +++ tsconfig.json | 3 ++- 9 files changed, 40 insertions(+), 29 deletions(-) diff --git a/dto/src/responses/auth.ts b/dto/src/responses/auth.ts index 418223d..46e5257 100644 --- a/dto/src/responses/auth.ts +++ b/dto/src/responses/auth.ts @@ -1,4 +1,4 @@ -import { BaseResponse, SuccessResponse } from './base'; +import { SuccessResponse } from './base'; import { IsBase32, IsJWT, IsNotEmpty } from 'class-validator'; export type TfaRequiredResponse = SuccessResponse; @@ -8,17 +8,13 @@ export type TfaCompletedResponse = SuccessResponse; export type SignupResponse = SuccessResponse; export type RefreshResponse = LoginResponse; -export class LoginResponse extends BaseResponse { - statusCode: 200; - +export class LoginResponse extends SuccessResponse { @IsNotEmpty() @IsJWT() jwt: string; } -export class RequestTotpTfaResponse extends BaseResponse { - statusCode: 200; - +export class RequestTotpTfaResponse extends SuccessResponse { @IsNotEmpty() qrCode: string; diff --git a/dto/src/responses/base.ts b/dto/src/responses/base.ts index 583eed3..48ec026 100644 --- a/dto/src/responses/base.ts +++ b/dto/src/responses/base.ts @@ -1,12 +1,20 @@ export class BaseResponse { + constructor(statusCode: number) { + this.statusCode = statusCode; + } + statusCode: number; } export class SuccessResponse extends BaseResponse { - statusCode: 200; + constructor() { + super(200); + } + + declare statusCode: 200; } export class ErrorResponse extends BaseResponse { - statusCode: 400 | 401 | 403; + declare statusCode: 400 | 401 | 403; message?: string; } diff --git a/dto/src/responses/fs.ts b/dto/src/responses/fs.ts index e4cf40f..cfa7f70 100644 --- a/dto/src/responses/fs.ts +++ b/dto/src/responses/fs.ts @@ -1,21 +1,17 @@ -import { BaseResponse, SuccessResponse } from './base'; +import { SuccessResponse } from './base'; import { IsBoolean, IsInt, IsNotEmpty, Min } from 'class-validator'; export type UploadFileResponse = SuccessResponse; export type DeleteResponse = SuccessResponse; export type CreateFileResponse = CreateFolderResponse; -export class GetRootResponse extends BaseResponse { - statusCode: 200; - +export class GetRootResponse extends SuccessResponse { @IsInt() @Min(1) rootId: number; } -export class GetNodeResponse extends BaseResponse { - statusCode: 200; - +export class GetNodeResponse extends SuccessResponse { @IsInt() @Min(1) id: number; @@ -28,21 +24,19 @@ export class GetNodeResponse extends BaseResponse { parent: number | null; + @IsInt({ each: true }) + @Min(1, { each: true }) children?: number[]; size?: number; } -export class GetPathResponse extends BaseResponse { - statusCode: 200; - +export class GetPathResponse extends SuccessResponse { @IsNotEmpty() path: string; } -export class CreateFolderResponse extends BaseResponse { - statusCode: 200; - +export class CreateFolderResponse extends SuccessResponse { @IsInt() @Min(1) id: number; diff --git a/dto/tsconfig.json b/dto/tsconfig.json index 7fe4cb9..eedea79 100644 --- a/dto/tsconfig.json +++ b/dto/tsconfig.json @@ -11,7 +11,8 @@ "outDir": "./dist", "baseUrl": "./src", "incremental": true, - "skipLibCheck": true + "skipLibCheck": true, + "strictPropertyInitialization": false }, "exclude": ["node_modules", "dist"] } diff --git a/frontend/src/api/auth.ts b/frontend/src/api/auth.ts index 8453e62..aed3adb 100644 --- a/frontend/src/api/auth.ts +++ b/frontend/src/api/auth.ts @@ -27,4 +27,4 @@ export const auth_signup = ( export const refresh_token = ( token: string ): Promise => - post_token('/api/auth/refresh', '', token); + post_token('/api/auth/refresh', {}, token); diff --git a/frontend/src/api/base.ts b/frontend/src/api/base.ts index 406d9bb..180a095 100644 --- a/frontend/src/api/base.ts +++ b/frontend/src/api/base.ts @@ -1,5 +1,7 @@ import axios from 'axios'; import { Requests, Responses } from 'dto'; +export { Requests, Responses }; +import { validateSync } from 'class-validator'; export const post = (url: string, data: T) => axios @@ -9,12 +11,17 @@ export const post = (url: string, data: T) => .then((res) => res.data) .catch((err) => err.response.data); -export const post_token = ( +export function post_token( url: string, data: T, token: string -) => - axios +) { + const errors = validateSync(data); + if (errors.length > 0) { + console.error('Validation failed, errors: ', errors); + throw new Error('Validation failed'); + } + return axios .post(url, data, { headers: { Authorization: 'Bearer ' + token, @@ -23,6 +30,7 @@ export const post_token = ( }) .then((res) => res.data) .catch((err) => err.response.data); +} export const post_token_form = ( url: string, diff --git a/frontend/src/views/SetTokenView.vue b/frontend/src/views/SetTokenView.vue index e737e33..d15660e 100644 --- a/frontend/src/views/SetTokenView.vue +++ b/frontend/src/views/SetTokenView.vue @@ -13,7 +13,7 @@ router.replace({ path: '/' }); diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 9772821..e47981e 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -11,6 +11,9 @@ "forceConsistentCasingInFileNames": true, "useDefineForClassFields": true, "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "strictPropertyInitialization": false, "baseUrl": ".", "types": [ "webpack-env" diff --git a/tsconfig.json b/tsconfig.json index 71e4661..631555b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,7 +12,8 @@ "baseUrl": "./", "incremental": true, "skipLibCheck": true, - "resolveJsonModule": true + "resolveJsonModule": true, + "strictPropertyInitialization": false }, "exclude": ["node_modules", "dist", "test", "**/*spec.ts", "frontend"] } From 9170f8f7aa3f09fcde18672e4058cb2375efa31d Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 25 Aug 2022 15:13:44 +0200 Subject: [PATCH 5/9] Everything is validated now --- .gitlab-ci.yml | 24 ++- dto/.gitignore | 402 +++++++++++++++++++++++++++++++++++ dto/package.json | 11 +- dto/src/index.ts | 1 + dto/src/requests/auth.ts | 28 ++- dto/src/requests/fs.ts | 7 +- dto/src/responses/auth.ts | 28 ++- dto/src/responses/fs.ts | 56 ++++- dto/src/utils.ts | 35 +++ dto/tsconfig.json | 6 +- frontend/src/api/auth.ts | 4 +- frontend/src/api/base.ts | 13 +- src/controller/auth.ts | 65 +++--- src/controller/filesystem.ts | 65 +++--- 14 files changed, 627 insertions(+), 118 deletions(-) create mode 100644 dto/.gitignore create mode 100644 dto/src/utils.ts diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6aab9b6..5d9eafb 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,7 @@ image: node:latest stages: + - setup - test - build - package @@ -23,18 +24,33 @@ before_script: - yarn install --cache-folder .yarn --frozen-lockfile - cd .. -test_backend: +test_build_dto: + stage: setup cache: <<: *global_cache policy: pull-push + before_script: [] + script: + - cd dto + - yarn install --frozen-lockfile + - yarn lint + - yarn build + - cd .. + - yarn install --cache-folder .yarn --frozen-lockfile + - yarn add ./dto + - cd frontend + - yarn install --cache-folder .yarn --frozen-lockfile + - yarn add ../dto + + +test_backend: + needs: ["test_build_dto"] stage: test script: - yarn lint test_frontend: - cache: - <<: *global_cache - policy: pull-push + needs: ["test_build_dto"] stage: test script: - cd frontend diff --git a/dto/.gitignore b/dto/.gitignore new file mode 100644 index 0000000..ab13255 --- /dev/null +++ b/dto/.gitignore @@ -0,0 +1,402 @@ +# Created by .ignore support plugin (hsz.mobi) +### JetBrains template +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff: +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/dictionaries + +# Sensitive or high-churn files: +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.xml +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml + +# Gradle: +.idea/**/gradle.xml +.idea/**/libraries + +# CMake +cmake-build-debug/ + +# Mongo Explorer plugin: +.idea/**/mongoSettings.xml + +## File-based project format: +*.iws + +## Plugin-specific files: + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +### VisualStudio template +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +**/Properties/launchSettings.json + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Typescript v1 declaration files +typings/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# IDE - VSCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ +coverage/ + +### macOS template +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +======= +# Local +.env +dist +lib + +files +sqlite.db \ No newline at end of file diff --git a/dto/package.json b/dto/package.json index 4123b61..328ce5a 100644 --- a/dto/package.json +++ b/dto/package.json @@ -2,13 +2,18 @@ "name": "dto", "private": true, "version": "1.0.0", - "main": "src/index.ts", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "files": [ + "/lib" + ], "dependencies": { "class-transformer": "^0.5.1", "class-validator": "^0.13.2" }, "scripts": { - "lint": "eslint \"src/**/*.ts\" && tsc --no-emit", - "lint-fix": "eslint \"src/**/*.ts\" --fix" + "lint": "eslint \"src/**/*.ts\" && tsc --noEmit", + "lint-fix": "eslint \"src/**/*.ts\" --fix", + "build": "tsc" } } diff --git a/dto/src/index.ts b/dto/src/index.ts index 22f24bf..1c0dbe0 100644 --- a/dto/src/index.ts +++ b/dto/src/index.ts @@ -1,2 +1,3 @@ export * as Requests from './requests'; export * as Responses from './responses'; +export { validateSync, validateAsync, validateAsyncInline } from './utils'; diff --git a/dto/src/requests/auth.ts b/dto/src/requests/auth.ts index 9fd1ba4..5526e9d 100644 --- a/dto/src/requests/auth.ts +++ b/dto/src/requests/auth.ts @@ -1,14 +1,36 @@ import { BaseRequest } from './base'; -import { IsEmail, IsNotEmpty } from 'class-validator'; +import { + IsBoolean, + IsEmail, + IsNotEmpty, + IsOptional, + IsString +} from 'class-validator'; -export class AuthSignUpRequest extends BaseRequest { +export class SignUpRequest extends BaseRequest { @IsEmail() username: string; @IsNotEmpty() + @IsString() password: string; } -export class AuthLoginRequest extends AuthSignUpRequest { +export class LoginRequest extends SignUpRequest { + @IsOptional() + @IsNotEmpty() + @IsString() otp?: string; } + +export class TfaComplete extends BaseRequest { + @IsNotEmpty() + @IsString() + code: string; +} + +export class TfaSetup extends BaseRequest { + @IsNotEmpty() + @IsBoolean() + mail: boolean; +} diff --git a/dto/src/requests/fs.ts b/dto/src/requests/fs.ts index 63ecabf..08ca1ba 100644 --- a/dto/src/requests/fs.ts +++ b/dto/src/requests/fs.ts @@ -1,7 +1,5 @@ import { BaseRequest } from './base'; -import { IsInt, IsNotEmpty, Min } from 'class-validator'; - -export type CreateFileRequest = CreateFolderRequest; +import { IsInt, IsNotEmpty, IsString, Min } from 'class-validator'; export class CreateFolderRequest extends BaseRequest { @IsInt() @@ -9,6 +7,7 @@ export class CreateFolderRequest extends BaseRequest { parent: number; @IsNotEmpty() + @IsString() name: string; } @@ -17,3 +16,5 @@ export class DeleteRequest extends BaseRequest { @Min(1) node: number; } + +export class CreateFileRequest extends CreateFolderRequest {} diff --git a/dto/src/responses/auth.ts b/dto/src/responses/auth.ts index 46e5257..e9177cd 100644 --- a/dto/src/responses/auth.ts +++ b/dto/src/responses/auth.ts @@ -1,20 +1,27 @@ import { SuccessResponse } from './base'; import { IsBase32, IsJWT, IsNotEmpty } from 'class-validator'; +import { ValidateConstructor } from '../utils'; -export type TfaRequiredResponse = SuccessResponse; -export type RemoveTfaResponse = SuccessResponse; -export type RequestEmailTfaResponse = SuccessResponse; -export type TfaCompletedResponse = SuccessResponse; -export type SignupResponse = SuccessResponse; -export type RefreshResponse = LoginResponse; - +@ValidateConstructor export class LoginResponse extends SuccessResponse { + constructor(jwt: string) { + super(); + this.jwt = jwt; + } + @IsNotEmpty() @IsJWT() jwt: string; } +@ValidateConstructor export class RequestTotpTfaResponse extends SuccessResponse { + constructor(qrCode: string, secret: string) { + super(); + this.qrCode = qrCode; + this.secret = secret; + } + @IsNotEmpty() qrCode: string; @@ -22,3 +29,10 @@ export class RequestTotpTfaResponse extends SuccessResponse { @IsBase32() secret: string; } + +export class TfaRequiredResponse extends SuccessResponse {} +export class RemoveTfaResponse extends SuccessResponse {} +export class RequestEmailTfaResponse extends SuccessResponse {} +export class TfaCompletedResponse extends SuccessResponse {} +export class SignupResponse extends SuccessResponse {} +export class RefreshResponse extends LoginResponse {} diff --git a/dto/src/responses/fs.ts b/dto/src/responses/fs.ts index cfa7f70..b4c0ef0 100644 --- a/dto/src/responses/fs.ts +++ b/dto/src/responses/fs.ts @@ -1,17 +1,39 @@ import { SuccessResponse } from './base'; -import { IsBoolean, IsInt, IsNotEmpty, Min } from 'class-validator'; - -export type UploadFileResponse = SuccessResponse; -export type DeleteResponse = SuccessResponse; -export type CreateFileResponse = CreateFolderResponse; +import { + IsBoolean, + IsInt, + IsNotEmpty, + IsOptional, + IsString, + Min +} from 'class-validator'; +import { ValidateConstructor } from '../utils'; +@ValidateConstructor export class GetRootResponse extends SuccessResponse { + constructor(rootId: number) { + super(); + this.rootId = rootId; + } @IsInt() @Min(1) rootId: number; } export class GetNodeResponse extends SuccessResponse { + constructor( + id: number, + name: string, + isFile: boolean, + parent: number | null + ) { + super(); + this.id = id; + this.name = name; + this.isFile = isFile; + this.parent = parent; + } + @IsInt() @Min(1) id: number; @@ -22,22 +44,46 @@ export class GetNodeResponse extends SuccessResponse { @IsBoolean() isFile: boolean; + @IsOptional() + @IsInt() + @Min(1) parent: number | null; + @IsOptional() @IsInt({ each: true }) @Min(1, { each: true }) children?: number[]; + @IsOptional() + @IsInt() + @Min(0) size?: number; } +@ValidateConstructor export class GetPathResponse extends SuccessResponse { + constructor(path: string) { + super(); + this.path = path; + } + @IsNotEmpty() + @IsString() path: string; } +@ValidateConstructor export class CreateFolderResponse extends SuccessResponse { + constructor(id: number) { + super(); + this.id = id; + } + @IsInt() @Min(1) id: number; } + +export class UploadFileResponse extends SuccessResponse {} +export class DeleteResponse extends SuccessResponse {} +export class CreateFileResponse extends CreateFolderResponse {} diff --git a/dto/src/utils.ts b/dto/src/utils.ts new file mode 100644 index 0000000..308f965 --- /dev/null +++ b/dto/src/utils.ts @@ -0,0 +1,35 @@ +import { validate, validateSync as _validateSync } from 'class-validator'; + +export function validateSync(data: T): void { + const errors = _validateSync(data); + if (errors.length > 0) { + console.error('Validation failed, errors: ', errors); + throw new Error('Validation failed'); + } +} + +export async function validateAsync(data: T): Promise { + const errors = await validate(data); + if (errors.length > 0) { + console.error('Validation failed, errors: ', errors); + throw new Error('Validation failed'); + } +} + +export async function validateAsyncInline( + data: T +): Promise { + await validateAsync(data); + return data; +} + +export function ValidateConstructor( + constr: T +) { + return class extends constr { + constructor(...args: any[]) { + super(...args); + validateSync(this); + } + }; +} diff --git a/dto/tsconfig.json b/dto/tsconfig.json index eedea79..a88e7eb 100644 --- a/dto/tsconfig.json +++ b/dto/tsconfig.json @@ -1,18 +1,18 @@ { "compilerOptions": { "module": "commonjs", - "declaration": false, + "declaration": true, "removeComments": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "allowSyntheticDefaultImports": true, "target": "es2017", "sourceMap": true, - "outDir": "./dist", + "outDir": "./lib", "baseUrl": "./src", "incremental": true, "skipLibCheck": true, "strictPropertyInitialization": false }, - "exclude": ["node_modules", "dist"] + "exclude": ["node_modules", "lib"] } diff --git a/frontend/src/api/auth.ts b/frontend/src/api/auth.ts index aed3adb..a2fea85 100644 --- a/frontend/src/api/auth.ts +++ b/frontend/src/api/auth.ts @@ -9,7 +9,7 @@ export const auth_login = ( | Responses.Auth.TfaRequiredResponse | Responses.ErrorResponse > => - post('/api/auth/login', { + post('/api/auth/login', { username: username, password: password, otp: otp @@ -19,7 +19,7 @@ export const auth_signup = ( username: string, password: string ): Promise => - post('/api/auth/signup', { + post('/api/auth/signup', { username: username, password: password }); diff --git a/frontend/src/api/base.ts b/frontend/src/api/base.ts index 180a095..bbc3b4e 100644 --- a/frontend/src/api/base.ts +++ b/frontend/src/api/base.ts @@ -1,7 +1,6 @@ import axios from 'axios'; import { Requests, Responses } from 'dto'; export { Requests, Responses }; -import { validateSync } from 'class-validator'; export const post = (url: string, data: T) => axios @@ -11,17 +10,12 @@ export const post = (url: string, data: T) => .then((res) => res.data) .catch((err) => err.response.data); -export function post_token( +export const post_token = ( url: string, data: T, token: string -) { - const errors = validateSync(data); - if (errors.length > 0) { - console.error('Validation failed, errors: ', errors); - throw new Error('Validation failed'); - } - return axios +) => + axios .post(url, data, { headers: { Authorization: 'Bearer ' + token, @@ -30,7 +24,6 @@ export function post_token( }) .then((res) => res.data) .catch((err) => err.response.data); -} export const post_token_form = ( url: string, diff --git a/src/controller/auth.ts b/src/controller/auth.ts index 30c7be4..756a9a7 100644 --- a/src/controller/auth.ts +++ b/src/controller/auth.ts @@ -4,18 +4,18 @@ import { Controller, Get, HttpCode, - ParseBoolPipe, Post, Query, Redirect, Request, UnauthorizedException, - UseGuards + UseGuards, + ValidationPipe } from '@nestjs/common'; import { AuthService } from '../services/auth'; import { AuthGuard } from '@nestjs/passport'; import { Public } from '../authguards'; -import { Responses } from 'dto'; +import { Responses, Requests } from 'dto'; import { tfaTypes } from '../entities'; import { toDataURL } from 'qrcode'; import * as base32 from 'thirty-two'; @@ -30,25 +30,22 @@ export default class AuthController { @HttpCode(200) async login( @Request() req, - @Body('otp') otp?: string + @Body(new ValidationPipe()) data: Requests.Auth.LoginRequest ): Promise< Responses.Auth.LoginResponse | Responses.Auth.TfaRequiredResponse > { if (this.authService.requiresTfa(req.user)) { - if (!otp) { + if (!data.otp) { if (req.user.tfaType == tfaTypes.EMAIL) await this.authService.sendTfaMail(req.user); - return { - statusCode: 200 - }; + return new Responses.Auth.TfaRequiredResponse(); } - if (!(await this.authService.verifyTfa(req.user, otp))) + if (!(await this.authService.verifyTfa(req.user, data.otp))) throw new UnauthorizedException('Incorrect 2fa'); } - return { - statusCode: 200, - jwt: await this.authService.login(req, req.user) - }; + return new Responses.Auth.LoginResponse( + await this.authService.login(req, req.user) + ); } async tfa( @@ -61,73 +58,61 @@ export default class AuthController { } await this.authService.setTfaType(req.user, type); await this.authService.revokeAll(req.user); - return { - statusCode: 200 - }; + return new Responses.Auth.TfaCompletedResponse(); } @Post('2fa/complete/mail') async tfaMail( @Request() req, - @Body('code') code: string + @Body(new ValidationPipe()) data: Requests.Auth.TfaComplete ): Promise { - return await this.tfa(req, code, tfaTypes.EMAIL); + return await this.tfa(req, data.code, tfaTypes.EMAIL); } @Post('2fa/complete/totp') async tfaTotp( @Request() req, - @Body('code') code: string + @Body(new ValidationPipe()) data: Requests.Auth.TfaComplete ): Promise { - return await this.tfa(req, code, tfaTypes.TOTP); + return await this.tfa(req, data.code, tfaTypes.TOTP); } @Get('2fa/setup') async setupTotp( @Request() req, - @Body('mail', ParseBoolPipe) mail: boolean + @Body(new ValidationPipe()) data: Requests.Auth.TfaSetup ): Promise< | Responses.Auth.RequestTotpTfaResponse | Responses.Auth.RequestEmailTfaResponse > { const secret = await this.authService.setupTfa(req.user); - if (mail) - return { - statusCode: 200 - }; - return { - statusCode: 200, - qrCode: await toDataURL( + if (data.mail) return new Responses.Auth.RequestEmailTfaResponse(); + return new Responses.Auth.RequestTotpTfaResponse( + await toDataURL( `otpauth://totp/MFileserver:${req.user.name}?secret=${base32 .encode(secret) .toString()}&issuer=MFileserver` ), secret - }; + ); } @Public() @Post('signup') async signup( - @Body('username') username, - @Body('password') password + @Body(new ValidationPipe()) data: Requests.Auth.SignUpRequest ): Promise { - if ((await this.authService.findUser(username, false)) != null) + if ((await this.authService.findUser(data.username, false)) != null) throw new BadRequestException('Username already taken'); - await this.authService.signup(username, password); - return { - statusCode: 200 - }; + await this.authService.signup(data.username, data.password); + return new Responses.Auth.SignupResponse(); } @Post('refresh') async refresh(@Request() req): Promise { const token = await this.authService.login(req, req.user); await this.authService.revoke(req.token); - return { - statusCode: 200, - jwt: token - }; + return await new Responses.Auth.RefreshResponse(token); } @Public() diff --git a/src/controller/filesystem.ts b/src/controller/filesystem.ts index 36178fe..2a34145 100644 --- a/src/controller/filesystem.ts +++ b/src/controller/filesystem.ts @@ -6,9 +6,10 @@ import { ParseIntPipe, Post, Request, - StreamableFile + StreamableFile, + ValidationPipe } from '@nestjs/common'; -import { Responses } from 'dto'; +import { Responses, Requests, validateAsyncInline } from 'dto'; import FileSystemService from '../services/filesystem'; import { UserRole } from '../entities'; import { Role } from '../authguards'; @@ -20,10 +21,7 @@ export default class FileSystemController { @Get('root') @Role(UserRole.USER) async getRoot(@Request() req): Promise { - return { - statusCode: 200, - rootId: req.user.rootId - }; + return new Responses.FS.GetRootResponse(req.user.rootId); } @Get('node/:node') @@ -33,19 +31,19 @@ export default class FileSystemController { @Param('node', ParseIntPipe) nodeId ): Promise { const node = await this.fsService.getNodeAndValidate(nodeId, req.user); - const data: Responses.FS.GetNodeResponse = { - id: nodeId, - statusCode: 200, - name: node.name, - parent: node.parentId, - isFile: node.isFile - }; + const data = new Responses.FS.GetNodeResponse( + nodeId, + node.name, + node.isFile, + node.parentId + ); + if (data.isFile) { data.size = node.size; } else { data.children = (await node.children).map((child) => child.id); } - return data; + return validateAsyncInline(data); } @Get('path/:node') @@ -54,62 +52,53 @@ export default class FileSystemController { @Request() req, @Param('node', ParseIntPipe) nodeId ): Promise { - return { - statusCode: 200, - path: await this.fsService.generatePath( + return new Responses.FS.GetPathResponse( + await this.fsService.generatePath( await this.fsService.getNodeAndValidate(nodeId, req.user) ) - }; + ); } @Post('createFolder') @Role(UserRole.USER) async createFolder( @Request() req, - @Body('parent', ParseIntPipe) parent, - @Body('name') name + @Body(new ValidationPipe()) data: Requests.FS.CreateFolderRequest ): Promise { const newChild = await this.fsService.create( - await this.fsService.getNodeAndValidate(parent, req.user), - name, + await this.fsService.getNodeAndValidate(data.parent, req.user), + data.name, req.user, false ); - return { - statusCode: 200, - id: newChild.id - }; + return new Responses.FS.CreateFolderResponse(newChild.id); } @Post('createFile') @Role(UserRole.USER) async createFile( @Request() req, - @Body('parent', ParseIntPipe) parent, - @Body('name') name + @Body(new ValidationPipe()) data: Requests.FS.CreateFileRequest ): Promise { const newChild = await this.fsService.create( - await this.fsService.getNodeAndValidate(parent, req.user), - name, + await this.fsService.getNodeAndValidate(data.parent, req.user), + data.name, req.user, true ); - return { - statusCode: 200, - id: newChild.id - }; + return new Responses.FS.CreateFileResponse(newChild.id); } @Post('delete') @Role(UserRole.USER) async delete( @Request() req, - @Body('node', ParseIntPipe) node_id + @Body(new ValidationPipe()) data: Requests.FS.DeleteRequest ): Promise { await this.fsService.delete( - await this.fsService.getNodeAndValidate(node_id, req.user) + await this.fsService.getNodeAndValidate(data.node, req.user) ); - return { statusCode: 200 }; + return new Responses.FS.DeleteResponse(); } @Post('upload/:node') @@ -119,7 +108,7 @@ export default class FileSystemController { @Param('node', ParseIntPipe) nodeId ): Promise { await this.fsService.uploadFile(await req.file(), nodeId, req.user); - return { statusCode: 200 }; + return new Responses.FS.UploadFileResponse(); } @Post('download') From 5bb00178f0051cffb451d0e23a074fe627c423df Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 25 Aug 2022 15:16:54 +0200 Subject: [PATCH 6/9] Fix dependencies --- dto/package.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dto/package.json b/dto/package.json index 328ce5a..0225315 100644 --- a/dto/package.json +++ b/dto/package.json @@ -11,6 +11,17 @@ "class-transformer": "^0.5.1", "class-validator": "^0.13.2" }, + "devDependencies": { + "@types/node": "^18.6.5", + "@typescript-eslint/eslint-plugin": "^5.33.0", + "@typescript-eslint/parser": "^5.33.0", + "@typescript-eslint/typescript-estree": "^5.33.0", + "eslint": "^8.21.0", + "eslint-config-prettier": "^8.5.0", + "eslint-plugin-prettier": "^4.2.1", + "prettier": "^2.7.1", + "typescript": "^4.7.4" + }, "scripts": { "lint": "eslint \"src/**/*.ts\" && tsc --noEmit", "lint-fix": "eslint \"src/**/*.ts\" --fix", From f6e92abbb81c2a6b26f2db3767eb40cc1f83a170 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 25 Aug 2022 15:18:38 +0200 Subject: [PATCH 7/9] Fix lockfile --- dto/yarn.lock | 914 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 914 insertions(+) diff --git a/dto/yarn.lock b/dto/yarn.lock index 0434e37..e2342f1 100644 --- a/dto/yarn.lock +++ b/dto/yarn.lock @@ -2,6 +2,226 @@ # yarn lockfile v1 +"@eslint/eslintrc@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.3.0.tgz#29f92c30bb3e771e4a2048c95fa6855392dfac4f" + integrity sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.3.2" + globals "^13.15.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@humanwhocodes/config-array@^0.10.4": + version "0.10.4" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.10.4.tgz#01e7366e57d2ad104feea63e72248f22015c520c" + integrity sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.4" + +"@humanwhocodes/gitignore-to-minimatch@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz#316b0a63b91c10e53f242efb4ace5c3b34e8728d" + integrity sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA== + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@types/json-schema@^7.0.9": + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + +"@types/node@^18.6.5": + version "18.7.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.13.tgz#23e6c5168333480d454243378b69e861ab5c011a" + integrity sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw== + +"@typescript-eslint/eslint-plugin@^5.33.0": + version "5.35.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.35.1.tgz#0d822bfea7469904dfc1bb8f13cabd362b967c93" + integrity sha512-RBZZXZlI4XCY4Wzgy64vB+0slT9+yAPQRjj/HSaRwUot33xbDjF1oN9BLwOLTewoOI0jothIltZRe9uJCHf8gg== + dependencies: + "@typescript-eslint/scope-manager" "5.35.1" + "@typescript-eslint/type-utils" "5.35.1" + "@typescript-eslint/utils" "5.35.1" + debug "^4.3.4" + functional-red-black-tree "^1.0.1" + ignore "^5.2.0" + regexpp "^3.2.0" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/parser@^5.33.0": + version "5.35.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.35.1.tgz#bf2ee2ebeaa0a0567213748243fb4eec2857f04f" + integrity sha512-XL2TBTSrh3yWAsMYpKseBYTVpvudNf69rPOWXWVBI08My2JVT5jR66eTt4IgQFHA/giiKJW5dUD4x/ZviCKyGg== + dependencies: + "@typescript-eslint/scope-manager" "5.35.1" + "@typescript-eslint/types" "5.35.1" + "@typescript-eslint/typescript-estree" "5.35.1" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@5.35.1": + version "5.35.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.35.1.tgz#ccb69d54b7fd0f2d0226a11a75a8f311f525ff9e" + integrity sha512-kCYRSAzIW9ByEIzmzGHE50NGAvAP3wFTaZevgWva7GpquDyFPFcmvVkFJGWJJktg/hLwmys/FZwqM9EKr2u24Q== + dependencies: + "@typescript-eslint/types" "5.35.1" + "@typescript-eslint/visitor-keys" "5.35.1" + +"@typescript-eslint/type-utils@5.35.1": + version "5.35.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.35.1.tgz#d50903b56758c5c8fc3be52b3be40569f27f9c4a" + integrity sha512-8xT8ljvo43Mp7BiTn1vxLXkjpw8wS4oAc00hMSB4L1/jIiYbjjnc3Qp2GAUOG/v8zsNCd1qwcqfCQ0BuishHkw== + dependencies: + "@typescript-eslint/utils" "5.35.1" + debug "^4.3.4" + tsutils "^3.21.0" + +"@typescript-eslint/types@5.35.1": + version "5.35.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.35.1.tgz#af355fe52a0cc88301e889bc4ada72f279b63d61" + integrity sha512-FDaujtsH07VHzG0gQ6NDkVVhi1+rhq0qEvzHdJAQjysN+LHDCKDKCBRlZFFE0ec0jKxiv0hN63SNfExy0KrbQQ== + +"@typescript-eslint/typescript-estree@5.35.1", "@typescript-eslint/typescript-estree@^5.33.0": + version "5.35.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.35.1.tgz#db878a39a0dbdc9bb133f11cdad451770bfba211" + integrity sha512-JUqE1+VRTGyoXlDWWjm6MdfpBYVq+hixytrv1oyjYIBEOZhBCwtpp5ZSvBt4wIA1MKWlnaC2UXl2XmYGC3BoQA== + dependencies: + "@typescript-eslint/types" "5.35.1" + "@typescript-eslint/visitor-keys" "5.35.1" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@5.35.1": + version "5.35.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.35.1.tgz#ae1399afbfd6aa7d0ed1b7d941e9758d950250eb" + integrity sha512-v6F8JNXgeBWI4pzZn36hT2HXXzoBBBJuOYvoQiaQaEEjdi5STzux3Yj8v7ODIpx36i/5s8TdzuQ54TPc5AITQQ== + dependencies: + "@types/json-schema" "^7.0.9" + "@typescript-eslint/scope-manager" "5.35.1" + "@typescript-eslint/types" "5.35.1" + "@typescript-eslint/typescript-estree" "5.35.1" + eslint-scope "^5.1.1" + eslint-utils "^3.0.0" + +"@typescript-eslint/visitor-keys@5.35.1": + version "5.35.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.35.1.tgz#285e9e34aed7c876f16ff646a3984010035898e6" + integrity sha512-cEB1DvBVo1bxbW/S5axbGPE6b7FIMAbo3w+AGq6zNDA7+NYJOIkKj/sInfTv4edxd4PxJSgdN4t6/pbvgA+n5g== + dependencies: + "@typescript-eslint/types" "5.35.1" + eslint-visitor-keys "^3.3.0" + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn@^8.8.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + +ajv@^6.10.0, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + class-transformer@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/class-transformer/-/class-transformer-0.5.1.tgz#24147d5dffd2a6cea930a3250a677addf96ab336" @@ -15,12 +235,706 @@ class-validator@^0.13.2: libphonenumber-js "^1.9.43" validator "^13.7.0" +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-prettier@^8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz#5a81680ec934beca02c7b1a61cf8ca34b66feab1" + integrity sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q== + +eslint-plugin-prettier@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" + integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-scope@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.1.1.tgz#fff34894c2f65e5226d3041ac480b4513a163642" + integrity sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + +eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + +eslint-visitor-keys@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" + integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== + +eslint@^8.21.0: + version "8.22.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.22.0.tgz#78fcb044196dfa7eef30a9d65944f6f980402c48" + integrity sha512-ci4t0sz6vSRKdmkOGmprBo6fmI4PrphDFMy5JEq/fNS0gQkJM3rLmrqcp8ipMcdobH3KtUP40KniAE9W19S4wA== + dependencies: + "@eslint/eslintrc" "^1.3.0" + "@humanwhocodes/config-array" "^0.10.4" + "@humanwhocodes/gitignore-to-minimatch" "^1.0.2" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.1.1" + eslint-utils "^3.0.0" + eslint-visitor-keys "^3.3.0" + espree "^9.3.3" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + functional-red-black-tree "^1.0.1" + glob-parent "^6.0.1" + globals "^13.15.0" + globby "^11.1.0" + grapheme-splitter "^1.0.4" + ignore "^5.2.0" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.1" + regexpp "^3.2.0" + strip-ansi "^6.0.1" + strip-json-comments "^3.1.0" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +espree@^9.3.2, espree@^9.3.3: + version "9.3.3" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.3.3.tgz#2dd37c4162bb05f433ad3c1a52ddf8a49dc08e9d" + integrity sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng== + dependencies: + acorn "^8.8.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.3.0" + +esquery@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" + integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + +fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastq@^1.6.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c" + integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw== + dependencies: + reusify "^1.0.4" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.2.7" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== + +glob-parent@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^13.15.0: + version "13.17.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.17.0.tgz#902eb1e680a41da93945adbdcb5a9f361ba69bd4" + integrity sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw== + dependencies: + type-fest "^0.20.2" + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== + +import-fresh@^3.0.0, import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + libphonenumber-js@^1.9.43: version "1.10.13" resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.13.tgz#0b5833c7fdbf671140530d83531c6753f7e0ea3c" integrity sha512-b74iyWmwb4GprAUPjPkJ11GTC7KX4Pd3onpJfKxYyY8y9Rbb4ERY47LvCMEDM09WD3thiLDMXtkfDK/AX+zT7Q== +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +optionator@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" + integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== + dependencies: + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + word-wrap "^1.2.3" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^2.7.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.7.1.tgz#e235806850d057f97bb08368a4f7d899f7760c64" + integrity sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g== + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +regexpp@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +semver@^7.3.7: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +typescript@^4.7.4: + version "4.7.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" + integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +v8-compile-cache@^2.0.3: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + validator@^13.7.0: version "13.7.0" resolved "https://registry.yarnpkg.com/validator/-/validator-13.7.0.tgz#4f9658ba13ba8f3d82ee881d3516489ea85c0857" integrity sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw== + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +word-wrap@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== From 42ddbaea336c894fc4e5cfd3bf7d3b6d1bf92378 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 25 Aug 2022 15:22:14 +0200 Subject: [PATCH 8/9] Fixed validation errors --- dto/src/responses/base.ts | 5 +++++ dto/src/responses/fs.ts | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/dto/src/responses/base.ts b/dto/src/responses/base.ts index 48ec026..7667e40 100644 --- a/dto/src/responses/base.ts +++ b/dto/src/responses/base.ts @@ -1,8 +1,13 @@ +import { IsNumber, Max, Min } from 'class-validator'; + export class BaseResponse { constructor(statusCode: number) { this.statusCode = statusCode; } + @IsNumber() + @Min(100) + @Max(599) statusCode: number; } diff --git a/dto/src/responses/fs.ts b/dto/src/responses/fs.ts index b4c0ef0..2ecb48c 100644 --- a/dto/src/responses/fs.ts +++ b/dto/src/responses/fs.ts @@ -38,7 +38,7 @@ export class GetNodeResponse extends SuccessResponse { @Min(1) id: number; - @IsNotEmpty() + @IsString() name: string; @IsBoolean() From 1f714b5b50fdf3b05c07048c93e74604c6ebfb90 Mon Sep 17 00:00:00 2001 From: Matthias Date: Thu, 25 Aug 2022 15:58:18 +0200 Subject: [PATCH 9/9] Fixed CI --- .gitlab-ci.yml | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5d9eafb..e19f32e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,6 +24,10 @@ before_script: - yarn install --cache-folder .yarn --frozen-lockfile - cd .. +.dto_artifacts_need: &dto_artifacts_need + job: test_build_dto + artifacts: true + test_build_dto: stage: setup cache: @@ -41,16 +45,21 @@ test_build_dto: - cd frontend - yarn install --cache-folder .yarn --frozen-lockfile - yarn add ../dto + artifacts: + paths: + - dto/lib/ test_backend: - needs: ["test_build_dto"] + needs: + - *dto_artifacts_need stage: test script: - yarn lint test_frontend: - needs: ["test_build_dto"] + needs: + - *dto_artifacts_need stage: test script: - cd frontend @@ -59,6 +68,7 @@ test_frontend: build_backend: stage: build needs: + - *dto_artifacts_need - job: test_backend artifacts: false script: @@ -71,6 +81,7 @@ build_backend: build_frontend: stage: build needs: + - *dto_artifacts_need - job: test_frontend artifacts: false script: