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==