issue #
DTO 공용화
This commit is contained in:
27
.vscode/snippets.code-snippets
vendored
Normal file
27
.vscode/snippets.code-snippets
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"RequestDTO": {
|
||||
"prefix": "ReqDTO",
|
||||
"body": [
|
||||
"import { BaseRequestDTO } from '@BaseRequestDTO';",
|
||||
"",
|
||||
"export class ${1:DtoName}RequestDTO extends BaseRequestDTO {",
|
||||
"$0",
|
||||
"}"
|
||||
]
|
||||
},
|
||||
"RequestField": {
|
||||
"prefix": "ReqField",
|
||||
"body": [
|
||||
"@${1:Decorator}",
|
||||
"${2:field}!: ${3:type};"
|
||||
]
|
||||
},
|
||||
"ResponseDTO": {
|
||||
"prefix": "ResDTO",
|
||||
"body": [
|
||||
"import type { BaseResponseDTO } from '@BaseResponseDTO';",
|
||||
"",
|
||||
"export type ${1:DtoName}ResponseDTO = BaseResponseDTO<${2:data}>;"
|
||||
]
|
||||
}
|
||||
}
|
||||
255
package-lock.json
generated
255
package-lock.json
generated
@@ -9,6 +9,9 @@
|
||||
"version": "1.0.9",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@swc/core": "^1.15.5",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.3",
|
||||
"date-fns": "^4.1.0",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"tsup": "^8.5.1"
|
||||
@@ -755,6 +758,220 @@
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@swc/core": {
|
||||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.5.tgz",
|
||||
"integrity": "sha512-VRy+AEO0zqUkwV9uOgqXtdI5tNj3y3BZI+9u28fHNjNVTtWYVNIq3uYhoGgdBOv7gdzXlqfHKuxH5a9IFAvopQ==",
|
||||
"hasInstallScript": true,
|
||||
"license": "Apache-2.0",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@swc/counter": "^0.1.3",
|
||||
"@swc/types": "^0.1.25"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/swc"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@swc/core-darwin-arm64": "1.15.5",
|
||||
"@swc/core-darwin-x64": "1.15.5",
|
||||
"@swc/core-linux-arm-gnueabihf": "1.15.5",
|
||||
"@swc/core-linux-arm64-gnu": "1.15.5",
|
||||
"@swc/core-linux-arm64-musl": "1.15.5",
|
||||
"@swc/core-linux-x64-gnu": "1.15.5",
|
||||
"@swc/core-linux-x64-musl": "1.15.5",
|
||||
"@swc/core-win32-arm64-msvc": "1.15.5",
|
||||
"@swc/core-win32-ia32-msvc": "1.15.5",
|
||||
"@swc/core-win32-x64-msvc": "1.15.5"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@swc/helpers": ">=0.5.17"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@swc/helpers": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-darwin-arm64": {
|
||||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.5.tgz",
|
||||
"integrity": "sha512-RvdpUcXrIz12yONzOdQrJbEnq23cOc2IHOU1eB8kPxPNNInlm4YTzZEA3zf3PusNpZZLxwArPVLCg0QsFQoTYw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-darwin-x64": {
|
||||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.5.tgz",
|
||||
"integrity": "sha512-ufJnz3UAff/8G5OfqZZc5cTQfGtXyXVLTB8TGT0xjkvEbfFg8jZUMDBnZT/Cn0k214JhMjiLCNl0A8aY/OKsYQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm-gnueabihf": {
|
||||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.5.tgz",
|
||||
"integrity": "sha512-Yqu92wIT0FZKLDWes+69kBykX97hc8KmnyFwNZGXJlbKUGIE0hAIhbuBbcY64FGSwey4aDWsZ7Ojk89KUu9Kzw==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"license": "Apache-2.0",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm64-gnu": {
|
||||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.5.tgz",
|
||||
"integrity": "sha512-3gR3b5V1abe/K1GpD0vVyZgqgV+ykuB5QNecDYzVroX4QuN+amCzQaNSsVM8Aj6DbShQCBTh3hGHd2f3vZ8gCw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-arm64-musl": {
|
||||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.5.tgz",
|
||||
"integrity": "sha512-Of+wmVh5h47tTpN9ghHVjfL0CJrgn99XmaJjmzWFW7agPdVY6gTDgkk6zQ6q4hcDQ7hXb0BGw6YFpuanBzNPow==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-x64-gnu": {
|
||||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.5.tgz",
|
||||
"integrity": "sha512-98kuPS0lZVgjmc/2uTm39r1/OfwKM0PM13ZllOAWi5avJVjRd/j1xA9rKeUzHDWt+ocH9mTCQsAT1jjKSq45bg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-x64-musl": {
|
||||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.5.tgz",
|
||||
"integrity": "sha512-Rk+OtNQP3W/dZExL74LlaakXAQn6/vbrgatmjFqJPO4RZkq+nLo5g7eDUVjyojuERh7R2yhqNvZ/ZZQe8JQqqA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-arm64-msvc": {
|
||||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.5.tgz",
|
||||
"integrity": "sha512-e3RTdJ769+PrN25iCAlxmsljEVu6iIWS7sE21zmlSiipftBQvSAOWuCDv2A8cH9lm5pSbZtwk8AUpIYCNsj2oQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-ia32-msvc": {
|
||||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.5.tgz",
|
||||
"integrity": "sha512-NmOdl6kyAw6zMz36zCdopTgaK2tcLA53NhUsTRopBc/796Fp87XdsslRHglybQ1HyXIGOQOKv2Y14IUbeci4BA==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-x64-msvc": {
|
||||
"version": "1.15.5",
|
||||
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.5.tgz",
|
||||
"integrity": "sha512-EPXJRf0A8eOi8woXf/qgVIWRl9yeSl0oN1ykGZNCGI7oElsfxUobJFmpJFJoVqKFfd1l0c+GPmWsN2xavTFkNw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/counter": {
|
||||
"version": "0.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
|
||||
"integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@swc/types": {
|
||||
"version": "0.1.25",
|
||||
"resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz",
|
||||
"integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@swc/counter": "^0.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
||||
@@ -771,6 +988,12 @@
|
||||
"undici-types": "~7.16.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/validator": {
|
||||
"version": "13.15.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.10.tgz",
|
||||
"integrity": "sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.15.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||
@@ -828,6 +1051,23 @@
|
||||
"url": "https://paulmillr.com/funding/"
|
||||
}
|
||||
},
|
||||
"node_modules/class-transformer": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/class-transformer/-/class-transformer-0.5.1.tgz",
|
||||
"integrity": "sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/class-validator": {
|
||||
"version": "0.14.3",
|
||||
"resolved": "https://registry.npmjs.org/class-validator/-/class-validator-0.14.3.tgz",
|
||||
"integrity": "sha512-rXXekcjofVN1LTOSw+u4u9WXVEUvNBVjORW154q/IdmYWy1nMbOU9aNtZB0t8m+FJQ9q91jlr2f9CwwUFdFMRA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/validator": "^13.15.3",
|
||||
"libphonenumber-js": "^1.11.1",
|
||||
"validator": "^13.15.20"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
|
||||
@@ -972,6 +1212,12 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/libphonenumber-js": {
|
||||
"version": "1.12.31",
|
||||
"resolved": "https://registry.npmjs.org/libphonenumber-js/-/libphonenumber-js-1.12.31.tgz",
|
||||
"integrity": "sha512-Z3IhgVgrqO1S5xPYM3K5XwbkDasU67/Vys4heW+lfSBALcUZjeIIzI8zCLifY+OCzSq+fpDdywMDa7z+4srJPQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lilconfig": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.3.tgz",
|
||||
@@ -1370,6 +1616,15 @@
|
||||
"integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/validator": {
|
||||
"version": "13.15.23",
|
||||
"resolved": "https://registry.npmjs.org/validator/-/validator-13.15.23.tgz",
|
||||
"integrity": "sha512-4yoz1kEWqUjzi5zsPbAS/903QXSYp0UOtHsPpp7p9rHAw/W+dkInskAE386Fat3oKRROwO98d9ZB0G4cObgUyw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
"types": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "tsup src/index.ts --dts --format cjs,esm"
|
||||
"build": "tsup src/index.ts --dts --format cjs,esm",
|
||||
"gen:dto": "node scripts/generate-dto.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -27,6 +28,9 @@
|
||||
"typescript": "^5.9.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@swc/core": "^1.15.5",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.14.3",
|
||||
"date-fns": "^4.1.0",
|
||||
"reflect-metadata": "^0.2.2",
|
||||
"tsup": "^8.5.1"
|
||||
|
||||
39
scripts/generate-dto.js
Normal file
39
scripts/generate-dto.js
Normal file
@@ -0,0 +1,39 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const targetProject = process.argv[2];
|
||||
if (!targetProject) {
|
||||
console.error('targetProject required');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const targetApi = process.argv[3];
|
||||
if (!targetApi) {
|
||||
console.error('targetApi required');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const name = process.argv[4];
|
||||
if (!name) {
|
||||
console.error('name required');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const nameKebab = name
|
||||
.replace(/([a-z0-9])([A-Z])/g, '$1-$2')
|
||||
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1-$2')
|
||||
.toLowerCase();
|
||||
|
||||
const baseDir = path.resolve('src', targetProject, 'http/dto', targetApi, name);
|
||||
|
||||
fs.mkdirSync(baseDir, {recursive: true});
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(baseDir, `${nameKebab}-request.dto.ts`),
|
||||
''
|
||||
);
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(baseDir, `${nameKebab}-response.dto.ts`),
|
||||
''
|
||||
);
|
||||
2
src/common/format/PasswordFormat.ts
Normal file
2
src/common/format/PasswordFormat.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
export const PasswordFormat = /^[a-z](?=.*[0-9])(?=.*[!@#$%^])[a-zA-z0-9!@#$%^]{8,12}$/;
|
||||
export const PasswordFormatString = /^[a-z](?=.*[0-9])(?=.*[!@#$%^])[a-zA-z0-9!@#$%^]{8,12}$/.source;
|
||||
36
src/common/validator/CustomValidators.ts
Normal file
36
src/common/validator/CustomValidators.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import { ValidatorConstraint, type ValidationArguments, type ValidatorConstraintInterface } from "class-validator";
|
||||
|
||||
@ValidatorConstraint({ name: 'accountCheckDuplicationValueValidator', async: false })
|
||||
export class AccountCheckDuplicationValueValidator implements ValidatorConstraintInterface {
|
||||
validate(value: any, args: ValidationArguments) {
|
||||
const { type } = args.object as any;
|
||||
|
||||
if (type === 'email') {
|
||||
return typeof value === 'string' && /\S+@\S+\.\S+/.test(value);
|
||||
}
|
||||
|
||||
if (type === 'accountId') {
|
||||
return typeof value === 'string';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@ValidatorConstraint({ name: 'loginIdValidator', async: false })
|
||||
export class LoginIdValidator implements ValidatorConstraintInterface {
|
||||
validate(value: any, args: ValidationArguments) {
|
||||
const { type } = args.object as any;
|
||||
|
||||
if (type === 'email') {
|
||||
return typeof value === 'string' && /\S+@\S+\.\S+/.test(value);
|
||||
}
|
||||
|
||||
if (type === 'accountId') {
|
||||
return typeof value === 'string';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,4 +9,6 @@ export * from './common/format/DateTimeFormat';
|
||||
|
||||
export * from './scheduler/http/HttpResponseMessage';
|
||||
|
||||
export * from './scheduler/http/HttpApiUrl';
|
||||
export * from './scheduler/http/HttpApiUrl';
|
||||
|
||||
export * as DTO from './scheduler/http/dto';
|
||||
@@ -39,4 +39,4 @@ export const HttpApiUrl = {
|
||||
read: '/read',
|
||||
delete: '/delete'
|
||||
}
|
||||
}
|
||||
} as const;
|
||||
@@ -0,0 +1,11 @@
|
||||
import { IsIn, Validate } from 'class-validator';
|
||||
import { BaseRequestDTO } from '@BaseRequestDTO';
|
||||
import { AccountCheckDuplicationValueValidator } from 'src/common/validator/CustomValidators';
|
||||
|
||||
export class CheckDuplicationRequestDTO extends BaseRequestDTO {
|
||||
@IsIn(['email', 'accountId'])
|
||||
type!: 'email' | 'accountId';
|
||||
|
||||
@Validate(AccountCheckDuplicationValueValidator)
|
||||
value!: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import type { BaseResponseDTO } from '@BaseResponseDTO';
|
||||
|
||||
export type CheckDuplicationResponseDTO = BaseResponseDTO<{ isDuplicated: boolean }>;
|
||||
16
src/scheduler/http/dto/account/login/login-request.dto.ts
Normal file
16
src/scheduler/http/dto/account/login/login-request.dto.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import { IsIn, IsString, Matches, Validate } from "class-validator";
|
||||
import { BaseRequestDTO } from "../../base/base-request.dto";
|
||||
import { LoginIdValidator } from "src/common/validator/CustomValidators";
|
||||
import { PasswordFormat } from "src/common/format/PasswordFormat";
|
||||
|
||||
export class LoginRequestDTO extends BaseRequestDTO {
|
||||
@IsIn(['email', 'accountId'])
|
||||
type!: 'email' | 'accountId';
|
||||
|
||||
@Validate(LoginIdValidator)
|
||||
id!: string;
|
||||
|
||||
@IsString()
|
||||
@Matches(PasswordFormat)
|
||||
password!: string;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { BaseResponseDTO } from '@BaseResponseDTO';
|
||||
|
||||
export type LoginResponseDTO = BaseResponseDTO<
|
||||
{
|
||||
accessToken: string;
|
||||
refreshToken: string;
|
||||
}
|
||||
>;
|
||||
@@ -0,0 +1,8 @@
|
||||
import type { BaseResponseDTO } from '@BaseResponseDTO';
|
||||
|
||||
export type RefreshAccessTokenResponseDTO = BaseResponseDTO<
|
||||
{
|
||||
accessToken: string;
|
||||
refreshToken: string;
|
||||
}
|
||||
>;
|
||||
@@ -0,0 +1,12 @@
|
||||
import { IsEmail, IsString, Matches } from "class-validator";
|
||||
import { BaseRequestDTO } from "../../base/base-request.dto";
|
||||
import { PasswordFormat } from "src/common/format/PasswordFormat";
|
||||
|
||||
export class ResetPasswordRequestDTO extends BaseRequestDTO {
|
||||
@IsEmail()
|
||||
email!: string;
|
||||
|
||||
@IsString()
|
||||
@Matches(PasswordFormat)
|
||||
password!: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import type { BaseResponseDTO } from '@BaseResponseDTO';
|
||||
|
||||
export type ResetPasswordResponseDTO = BaseResponseDTO<{ }>;
|
||||
@@ -0,0 +1,7 @@
|
||||
import { IsEmail } from "class-validator";
|
||||
import { BaseRequestDTO } from "../../base/base-request.dto";
|
||||
|
||||
export class SendEmailVerificationCodeRequestDTO extends BaseRequestDTO {
|
||||
@IsEmail()
|
||||
email!: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import type { BaseResponseDTO } from '@BaseResponseDTO';
|
||||
|
||||
export type SendEmailVerificationCodeResponseDTO = BaseResponseDTO<{ }>;
|
||||
@@ -0,0 +1,7 @@
|
||||
import { IsEmail } from "class-validator";
|
||||
import { BaseRequestDTO } from "../../base/base-request.dto";
|
||||
|
||||
export class SendPasswordResetCodeRequestDTO extends BaseRequestDTO {
|
||||
@IsEmail()
|
||||
email!: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import type { BaseResponseDTO } from '@BaseResponseDTO';
|
||||
|
||||
export type SendPasswordResetCodeResponseDTO = BaseResponseDTO<{ }>;
|
||||
21
src/scheduler/http/dto/account/signup/signup-request.dto.ts
Normal file
21
src/scheduler/http/dto/account/signup/signup-request.dto.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { BaseRequestDTO } from '@BaseRequestDTO';
|
||||
import { IsEmail, IsString, Matches } from 'class-validator';
|
||||
import { PasswordFormat } from 'src/common/format/PasswordFormat';
|
||||
|
||||
export class SignupRequestDTO extends BaseRequestDTO {
|
||||
@IsEmail()
|
||||
email!: string;
|
||||
|
||||
@IsString()
|
||||
name!: string;
|
||||
|
||||
@IsString()
|
||||
nickname!: string;
|
||||
|
||||
@IsString()
|
||||
accoundId!: string;
|
||||
|
||||
@IsString()
|
||||
@Matches(PasswordFormat)
|
||||
password!: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import type { BaseResponseDTO } from '@BaseResponseDTO';
|
||||
|
||||
export type SignupResponseDTO = BaseResponseDTO<{ }>;
|
||||
@@ -0,0 +1,10 @@
|
||||
import { BaseRequestDTO } from '@BaseRequestDTO';
|
||||
import { IsEmail, IsString } from 'class-validator';
|
||||
|
||||
export class VerifyEmailVerificationCodeRequestDTO extends BaseRequestDTO {
|
||||
@IsEmail()
|
||||
email!: string;
|
||||
|
||||
@IsString()
|
||||
code!: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import type { BaseResponseDTO } from '@BaseResponseDTO';
|
||||
|
||||
export type VerifyEmailVerificationCodeResponseDTO = BaseResponseDTO<{ verified: boolean }>;
|
||||
@@ -0,0 +1,10 @@
|
||||
import { BaseRequestDTO } from '@BaseRequestDTO';
|
||||
import { IsEmail, IsString } from 'class-validator';
|
||||
|
||||
export class VerifyPasswordResetCodeRequestDTO extends BaseRequestDTO {
|
||||
@IsEmail()
|
||||
email!: string;
|
||||
|
||||
@IsString()
|
||||
code!: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import type { BaseResponseDTO } from '@BaseResponseDTO';
|
||||
|
||||
export type VerifyPasswordResetCodeResponseDTO = BaseResponseDTO<{ verified: boolean }>;
|
||||
9
src/scheduler/http/dto/base/base-request.dto.ts
Normal file
9
src/scheduler/http/dto/base/base-request.dto.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
import { validate, type ValidationError } from "class-validator";
|
||||
|
||||
export class BaseRequestDTO {
|
||||
async validateObject(): Promise<ValidationError[]> {
|
||||
const errors = await validate(this);
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
19
src/scheduler/http/dto/base/base-response.dto.ts
Normal file
19
src/scheduler/http/dto/base/base-response.dto.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
export type SuccessResponse<T> = {
|
||||
success: true;
|
||||
message: string;
|
||||
data: T;
|
||||
|
||||
error?: never;
|
||||
code?: never;
|
||||
}
|
||||
|
||||
export type ErrorResponse = {
|
||||
success: false;
|
||||
error: string;
|
||||
code: string;
|
||||
|
||||
message?: never;
|
||||
data?: never;
|
||||
}
|
||||
|
||||
export type BaseResponseDTO<T> = SuccessResponse<T> | ErrorResponse;
|
||||
33
src/scheduler/http/dto/index.ts
Normal file
33
src/scheduler/http/dto/index.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
export { CheckDuplicationRequestDTO as CheckDuplicationRequest } from './account/checkDuplication/check-duplication-request.dto';
|
||||
export type { CheckDuplicationResponseDTO as CheckDuplicationResponse } from './account/checkDuplication/check-duplication-response.dto';
|
||||
|
||||
export { LoginRequestDTO as LoginRequest } from './account/login/login-request.dto';
|
||||
export type { LoginResponseDTO as LoginResponse } from './account/login/login-response.dto';
|
||||
|
||||
export type { RefreshAccessTokenResponseDTO as RefreshAccessTokenResponse } from './account/refreshAccessToken/refresh-access-token-response.dto';
|
||||
|
||||
export { ResetPasswordRequestDTO as ResetPasswordRequest } from './account/resetPassword/reset-password-request.dto';
|
||||
export type { ResetPasswordResponseDTO as ResetPasswordResponse } from './account/resetPassword/reset-password-response.dto';
|
||||
|
||||
export { SendEmailVerificationCodeRequestDTO as SendEmailVerificationCodeRequest } from './account/sendEmailVerificationCode/send-email-verification-code-request.dto';
|
||||
export type { SendEmailVerificationCodeResponseDTO as SendEmailVerificationCodeResponse } from './account/sendEmailVerificationCode/sned-email-verification-code-response.dto';
|
||||
|
||||
export { SendPasswordResetCodeRequestDTO as SendPasswordResetCodeRequest } from './account/sendPasswordResetCode/send-password-reset-code-request.dto';
|
||||
export type { SendPasswordResetCodeResponseDTO as SendPasswordResetCodeResponse } from './account/sendPasswordResetCode/send-password-reset-code-response.dto';
|
||||
|
||||
export { SignupRequestDTO as SignupRequest } from './account/signup/signup-request.dto';
|
||||
export type { SignupResponseDTO as SignupResponse } from './account/signup/signup-response.dto';
|
||||
|
||||
export { VerifyEmailVerificationCodeRequestDTO as VerifyEmailVerificationCodeRequest } from './account/verifyEmailVerificationCode/verify-email-verification-code-request.dto';
|
||||
export type { VerifyEmailVerificationCodeResponseDTO as VerifyEmailVerificationCodeResponse } from './account/verifyEmailVerificationCode/verify-email-verification-code-response.dto';
|
||||
|
||||
export { VerifyPasswordResetCodeRequestDTO as VerifyPasswordResetCodeRequest } from './account/verifyPasswordResetCode/verify-password-reset-code-request.dto';
|
||||
export type { VerifyPasswordResetCodeResponseDTO as VerifyPasswordResetCodeResponse } from './account/verifyPasswordResetCode/verify-password-reset-code.response.dto';
|
||||
|
||||
export { ScheduleCreateRequestDTO as ScheduleCreateRequest } from './schedule/create/create-request.dto';
|
||||
export type { ScheduleCreateResponseDTO as ScheduleCreateResponse } from './schedule/create/create-response.dto';
|
||||
|
||||
export { ScheduleListRequestDTO as ScheduleListRequest } from './schedule/list/list-request.dto';
|
||||
export type { ScheduleListResponseDTO as ScheduleListResponse, ScheduleList } from './schedule/list/list-response.dto';
|
||||
|
||||
export type { ScheduleDetailResponseDTO as ScheduleDetailResponse, ScheduleDetail } from './schedule/detail/detail-response.dto';
|
||||
32
src/scheduler/http/dto/schedule/create/create-request.dto.ts
Normal file
32
src/scheduler/http/dto/schedule/create/create-request.dto.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { BaseRequestDTO } from '@BaseRequestDTO';
|
||||
import { IsArray, IsDateString, IsIn, IsString } from 'class-validator';
|
||||
import { ScheduleTypeArray } from 'src/scheduler/type/schedule/ScheduleType';
|
||||
|
||||
export class ScheduleCreateRequestDTO extends BaseRequestDTO {
|
||||
@IsString()
|
||||
name!: string;
|
||||
|
||||
@IsDateString()
|
||||
startDate!: string;
|
||||
|
||||
@IsDateString()
|
||||
endDate!: string;
|
||||
|
||||
@IsIn(ScheduleTypeArray)
|
||||
type!: string;
|
||||
|
||||
@IsString()
|
||||
style!: string;
|
||||
|
||||
@IsString()
|
||||
stratTime!: string;
|
||||
|
||||
@IsString()
|
||||
endTime!: string;
|
||||
|
||||
@IsString()
|
||||
dayList?: string;
|
||||
|
||||
@IsArray()
|
||||
participantList?: string[];
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import type { BaseResponseDTO } from '@BaseResponseDTO';
|
||||
|
||||
export type ScheduleCreateResponseDTO = BaseResponseDTO<{ }>;
|
||||
@@ -0,0 +1,22 @@
|
||||
import type { BaseResponseDTO } from '@BaseResponseDTO';
|
||||
import type { ScheduleType } from 'src/scheduler/type/schedule/ScheduleType';
|
||||
|
||||
export type ScheduleDetail = {
|
||||
id: string;
|
||||
name: string;
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
status: string;
|
||||
content?: string;
|
||||
isDeleted: boolean;
|
||||
type: ScheduleType;
|
||||
createdAt: string;
|
||||
owner: string;
|
||||
style: string;
|
||||
startTime: string;
|
||||
endTime: string;
|
||||
dayList?: string;
|
||||
participantList?: string;
|
||||
}
|
||||
|
||||
export type ScheduleDetailResponseDTO = BaseResponseDTO<ScheduleDetail>;
|
||||
40
src/scheduler/http/dto/schedule/list/list-request.dto.ts
Normal file
40
src/scheduler/http/dto/schedule/list/list-request.dto.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { BaseRequestDTO } from '@BaseRequestDTO';
|
||||
import { IsArray, IsDateString, IsIn, IsNumberString, IsString, ValidateIf } from 'class-validator';
|
||||
import { ScheduleStatusArray } from 'src/scheduler/type/schedule/ScheduleStatus';
|
||||
import { ScheduleTypeArray } from 'src/scheduler/type/schedule/ScheduleType';
|
||||
|
||||
export class ScheduleListRequestDTO extends BaseRequestDTO {
|
||||
@ValidateIf(o => o.date !== undefined)
|
||||
@IsDateString()
|
||||
date?: string;
|
||||
|
||||
@ValidateIf(o => o.startDate !== undefined)
|
||||
@IsDateString()
|
||||
startDate?: string;
|
||||
|
||||
@ValidateIf(o => o.endDate !== undefined)
|
||||
@IsDateString()
|
||||
endDate?: string;
|
||||
|
||||
@ValidateIf(o => o.styleList !== undefined)
|
||||
@IsArray()
|
||||
styleList?: string[];
|
||||
|
||||
@ValidateIf(o => o.typeList !== undefined)
|
||||
@IsArray()
|
||||
@IsIn(ScheduleTypeArray, { each: true})
|
||||
typeList?: string[];
|
||||
|
||||
@ValidateIf(o => o.status !== undefined)
|
||||
@IsString()
|
||||
@IsIn(ScheduleStatusArray)
|
||||
status?: string;
|
||||
|
||||
@ValidateIf(o => o.name !== undefined)
|
||||
@IsString()
|
||||
name?: string;
|
||||
|
||||
@ValidateIf(o => o.dayList !== undefined)
|
||||
@IsNumberString()
|
||||
dayList?: string;
|
||||
}
|
||||
15
src/scheduler/http/dto/schedule/list/list-response.dto.ts
Normal file
15
src/scheduler/http/dto/schedule/list/list-response.dto.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import type { BaseResponseDTO } from '@BaseResponseDTO';
|
||||
import type { ScheduleStatus } from "src/scheduler/type/schedule/ScheduleStatus";
|
||||
import type { ScheduleType } from "src/scheduler/type/schedule/ScheduleType";
|
||||
|
||||
export type ScheduleList = {
|
||||
name: string;
|
||||
id: string;
|
||||
startDate: Date;
|
||||
endDate: Date;
|
||||
type: ScheduleType;
|
||||
style: string;
|
||||
status: ScheduleStatus;
|
||||
}
|
||||
|
||||
export type ScheduleListResponseDTO = BaseResponseDTO<ScheduleList>;
|
||||
13
src/scheduler/type/schedule/ScheduleDay.ts
Normal file
13
src/scheduler/type/schedule/ScheduleDay.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export const ScheduleDay: Record<string, string> = {
|
||||
1: '일',
|
||||
2: '월',
|
||||
3: '화',
|
||||
4: '수',
|
||||
5: '목',
|
||||
6: '금',
|
||||
7: '토'
|
||||
} as const;
|
||||
|
||||
export const ScheduleDayArray = '1234567'.split('');
|
||||
|
||||
export const ScheduleDayLabelArray = '일월화수목금토'.split('');
|
||||
8
src/scheduler/type/schedule/ScheduleStatus.ts
Normal file
8
src/scheduler/type/schedule/ScheduleStatus.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
export type ScheduleStatus = 'yet' | 'completed';
|
||||
|
||||
export const ScheduleStatusLabel: Record<ScheduleStatus, string> = {
|
||||
'yet': '미완료',
|
||||
'completed': '완료'
|
||||
} as const;
|
||||
|
||||
export const ScheduleStatusArray = ['yet', 'completed'] as const;
|
||||
11
src/scheduler/type/schedule/ScheduleType.ts
Normal file
11
src/scheduler/type/schedule/ScheduleType.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export type ScheduleType = 'once' | 'daily' | 'weekly' | 'monthly' | 'annual';
|
||||
|
||||
export const ScheduleTypeLabel: Record<ScheduleType, string> = {
|
||||
'once': '반복없음',
|
||||
'daily': '매일',
|
||||
'weekly': '매주',
|
||||
'monthly': '매달',
|
||||
'annual': '매년'
|
||||
} as const;
|
||||
|
||||
export const ScheduleTypeArray = ['once', 'daily', 'weekly', 'monthly', 'annual'] as const;
|
||||
@@ -44,7 +44,14 @@
|
||||
"moduleDetection": "force",
|
||||
"skipLibCheck": true,
|
||||
"baseUrl": ".",
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"paths": {
|
||||
"@/*": ["src./*"],
|
||||
"@BaseRequestDTO": ["src/scheduler/http/dto/base/base-request.dto.ts"],
|
||||
"@BaseResponseDTO": ["src/scheduler/http/dto/base/base-response.dto.ts"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"include": ["src/**/*", "scripts"],
|
||||
"exclude": ["node-modules", "dist", "**/*.spec.ts"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user