typescript-express-starter 10.2.1 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.kr.md +136 -287
- package/README.md +134 -274
- package/bin/ast-utils.js +226 -0
- package/bin/common.js +312 -0
- package/bin/config.js +80 -0
- package/bin/db-map.js +169 -0
- package/bin/errors.js +129 -0
- package/bin/performance.js +203 -0
- package/bin/starter.js +359 -0
- package/bin/validators.js +146 -0
- package/devtools/biome/.biome.json +34 -0
- package/devtools/biome/.biomeignore +29 -0
- package/devtools/docker/.dockerignore +27 -0
- package/devtools/docker/Dockerfile.dev +20 -0
- package/devtools/docker/Dockerfile.prod +35 -0
- package/{lib/default → devtools/docker}/Makefile +3 -0
- package/devtools/docker/nginx.conf +67 -0
- package/devtools/eslint/eslint.config.cjs +23 -0
- package/devtools/husky/.husky/commit-msg +4 -0
- package/devtools/husky/.husky/pre-commit +4 -0
- package/devtools/husky/.husky/pre-push +4 -0
- package/devtools/jest/jest.config.cjs +2 -0
- package/devtools/jest/jest.config.ts +25 -0
- package/devtools/jest/src/test/e2e/auth.e2e.spec.ts +40 -0
- package/devtools/jest/src/test/e2e/users.e2e.spec.ts +63 -0
- package/devtools/jest/src/test/setup.ts +31 -0
- package/devtools/jest/src/test/unit/entities/user.entity.spec.ts +279 -0
- package/devtools/jest/src/test/unit/services/auth.service.spec.ts +75 -0
- package/devtools/jest/src/test/unit/services/users.service.spec.ts +109 -0
- package/devtools/oxlint/.oxlintrc.json +57 -0
- package/devtools/pm2/ecosystem.config.js +59 -0
- package/devtools/swagger/swagger.yaml +124 -0
- package/{lib/prisma → devtools/swc}/.swcrc +2 -1
- package/devtools/tsup/tsup.config.ts +15 -0
- package/devtools/vitest/src/test/e2e/auth.e2e.spec.ts +41 -0
- package/devtools/vitest/src/test/e2e/users.e2e.spec.ts +64 -0
- package/devtools/vitest/src/test/setup.ts +31 -0
- package/devtools/vitest/src/test/unit/services/auth.service.spec.ts +70 -0
- package/devtools/vitest/src/test/unit/services/users.service.spec.ts +90 -0
- package/devtools/vitest/vitest.config.ts +22 -0
- package/package.json +24 -11
- package/templates/default/nodemon.json +7 -0
- package/templates/default/package.json +48 -0
- package/templates/default/src/app.ts +118 -0
- package/templates/default/src/config/env.ts +78 -0
- package/templates/default/src/controllers/auth.controller.ts +40 -0
- package/templates/default/src/controllers/users.controller.ts +46 -0
- package/templates/default/src/dtos/users.dto.ts +42 -0
- package/templates/default/src/entities/user.entity.ts +190 -0
- package/templates/default/src/exceptions/httpException.ts +14 -0
- package/{lib/knex → templates/default}/src/interfaces/auth.interface.ts +3 -3
- package/templates/default/src/interfaces/users.interface.ts +9 -0
- package/templates/default/src/middlewares/auth.middleware.ts +49 -0
- package/templates/default/src/middlewares/error.middleware.ts +89 -0
- package/templates/default/src/middlewares/notFound.middleware.ts +6 -0
- package/templates/default/src/middlewares/validation.middleware.ts +15 -0
- package/templates/default/src/repositories/users.repository.ts +55 -0
- package/templates/default/src/routes/auth.route.ts +31 -0
- package/templates/default/src/routes/users.route.ts +32 -0
- package/templates/default/src/server.ts +35 -0
- package/templates/default/src/services/auth.service.ts +67 -0
- package/templates/default/src/services/users.service.ts +48 -0
- package/templates/default/src/utils/asyncHandler.ts +8 -0
- package/templates/default/src/utils/logger.ts +113 -0
- package/{lib/typeorm → templates/default}/tsconfig.json +23 -22
- package/CONTRIBUTORS.md +0 -69
- package/bin/cli.js +0 -18
- package/lib/default/.dockerignore +0 -18
- package/lib/default/.editorconfig +0 -9
- package/lib/default/.env.development.local +0 -13
- package/lib/default/.env.production.local +0 -13
- package/lib/default/.env.test.local +0 -13
- package/lib/default/.eslintignore +0 -1
- package/lib/default/.eslintrc +0 -18
- package/lib/default/.huskyrc +0 -5
- package/lib/default/.lintstagedrc.json +0 -5
- package/lib/default/.prettierrc +0 -8
- package/lib/default/.swcrc +0 -39
- package/lib/default/.vscode/launch.json +0 -35
- package/lib/default/.vscode/settings.json +0 -6
- package/lib/default/Dockerfile.dev +0 -18
- package/lib/default/Dockerfile.prod +0 -18
- package/lib/default/docker-compose.yml +0 -35
- package/lib/default/ecosystem.config.js +0 -57
- package/lib/default/jest.config.js +0 -12
- package/lib/default/nginx.conf +0 -40
- package/lib/default/nodemon.json +0 -12
- package/lib/default/package.json +0 -76
- package/lib/default/src/app.ts +0 -81
- package/lib/default/src/config/index.ts +0 -5
- package/lib/default/src/controllers/auth.controller.ts +0 -44
- package/lib/default/src/controllers/users.controller.ts +0 -63
- package/lib/default/src/dtos/users.dto.ts +0 -20
- package/lib/default/src/exceptions/HttpException.ts +0 -10
- package/lib/default/src/http/auth.http +0 -27
- package/lib/default/src/http/users.http +0 -34
- package/lib/default/src/interfaces/auth.interface.ts +0 -15
- package/lib/default/src/interfaces/users.interface.ts +0 -5
- package/lib/default/src/middlewares/auth.middleware.ts +0 -38
- package/lib/default/src/middlewares/error.middleware.ts +0 -15
- package/lib/default/src/middlewares/validation.middleware.ts +0 -27
- package/lib/default/src/models/users.model.ts +0 -9
- package/lib/default/src/routes/auth.route.ts +0 -21
- package/lib/default/src/routes/users.route.ts +0 -23
- package/lib/default/src/server.ts +0 -10
- package/lib/default/src/services/auth.service.ts +0 -52
- package/lib/default/src/services/users.service.ts +0 -51
- package/lib/default/src/test/auth.test.ts +0 -52
- package/lib/default/src/test/users.test.ts +0 -62
- package/lib/default/src/utils/logger.ts +0 -65
- package/lib/default/src/utils/validateEnv.ts +0 -8
- package/lib/default/swagger.yaml +0 -123
- package/lib/default/tsconfig.json +0 -39
- package/lib/graphql/.dockerignore +0 -18
- package/lib/graphql/.editorconfig +0 -9
- package/lib/graphql/.env.development.local +0 -20
- package/lib/graphql/.env.production.local +0 -20
- package/lib/graphql/.env.test.local +0 -20
- package/lib/graphql/.eslintignore +0 -1
- package/lib/graphql/.eslintrc +0 -18
- package/lib/graphql/.huskyrc +0 -5
- package/lib/graphql/.lintstagedrc.json +0 -5
- package/lib/graphql/.prettierrc +0 -8
- package/lib/graphql/.swcrc +0 -40
- package/lib/graphql/.vscode/launch.json +0 -35
- package/lib/graphql/.vscode/settings.json +0 -6
- package/lib/graphql/Dockerfile.dev +0 -19
- package/lib/graphql/Dockerfile.prod +0 -19
- package/lib/graphql/Makefile +0 -46
- package/lib/graphql/docker-compose.yml +0 -58
- package/lib/graphql/ecosystem.config.js +0 -59
- package/lib/graphql/jest.config.js +0 -12
- package/lib/graphql/nginx.conf +0 -40
- package/lib/graphql/nodemon.json +0 -12
- package/lib/graphql/package.json +0 -75
- package/lib/graphql/src/app.ts +0 -107
- package/lib/graphql/src/config/index.ts +0 -6
- package/lib/graphql/src/database/index.ts +0 -26
- package/lib/graphql/src/dtos/users.dto.ts +0 -27
- package/lib/graphql/src/entities/users.entity.ts +0 -26
- package/lib/graphql/src/exceptions/HttpException.ts +0 -10
- package/lib/graphql/src/http/auth.http +0 -49
- package/lib/graphql/src/http/users.http +0 -78
- package/lib/graphql/src/interfaces/auth.interface.ts +0 -14
- package/lib/graphql/src/interfaces/users.interface.ts +0 -5
- package/lib/graphql/src/middlewares/auth.middleware.ts +0 -42
- package/lib/graphql/src/middlewares/error.middleware.ts +0 -15
- package/lib/graphql/src/repositories/auth.repository.ts +0 -53
- package/lib/graphql/src/repositories/users.repository.ts +0 -51
- package/lib/graphql/src/resolvers/auth.resolver.ts +0 -32
- package/lib/graphql/src/resolvers/users.resolver.ts +0 -47
- package/lib/graphql/src/server.ts +0 -10
- package/lib/graphql/src/test/auth.test.ts +0 -10
- package/lib/graphql/src/test/users.test.ts +0 -11
- package/lib/graphql/src/typedefs/users.type.ts +0 -13
- package/lib/graphql/src/utils/logger.ts +0 -77
- package/lib/graphql/src/utils/validateEnv.ts +0 -8
- package/lib/graphql/tsconfig.json +0 -40
- package/lib/knex/.dockerignore +0 -18
- package/lib/knex/.editorconfig +0 -9
- package/lib/knex/.env.development.local +0 -20
- package/lib/knex/.env.production.local +0 -20
- package/lib/knex/.env.test.local +0 -20
- package/lib/knex/.eslintignore +0 -1
- package/lib/knex/.eslintrc +0 -18
- package/lib/knex/.huskyrc +0 -5
- package/lib/knex/.lintstagedrc.json +0 -5
- package/lib/knex/.prettierrc +0 -8
- package/lib/knex/.swcrc +0 -40
- package/lib/knex/.vscode/launch.json +0 -35
- package/lib/knex/.vscode/settings.json +0 -6
- package/lib/knex/Dockerfile.dev +0 -19
- package/lib/knex/Dockerfile.prod +0 -19
- package/lib/knex/Makefile +0 -46
- package/lib/knex/docker-compose.yml +0 -55
- package/lib/knex/ecosystem.config.js +0 -57
- package/lib/knex/jest.config.js +0 -12
- package/lib/knex/knexfile.ts +0 -23
- package/lib/knex/nginx.conf +0 -40
- package/lib/knex/nodemon.json +0 -12
- package/lib/knex/package.json +0 -85
- package/lib/knex/src/app.ts +0 -87
- package/lib/knex/src/config/index.ts +0 -6
- package/lib/knex/src/controllers/auth.controller.ts +0 -44
- package/lib/knex/src/controllers/users.controller.ts +0 -63
- package/lib/knex/src/database/index.ts +0 -24
- package/lib/knex/src/database/migrations/.gitkeep +0 -0
- package/lib/knex/src/database/migrations/20210713110926_initial.ts +0 -17
- package/lib/knex/src/database/seeds/.gitkeep +0 -0
- package/lib/knex/src/dtos/users.dto.ts +0 -20
- package/lib/knex/src/exceptions/HttpException.ts +0 -10
- package/lib/knex/src/http/auth.http +0 -27
- package/lib/knex/src/http/users.http +0 -34
- package/lib/knex/src/interfaces/routes.interface.ts +0 -6
- package/lib/knex/src/interfaces/users.interface.ts +0 -5
- package/lib/knex/src/middlewares/auth.middleware.ts +0 -40
- package/lib/knex/src/middlewares/error.middleware.ts +0 -15
- package/lib/knex/src/middlewares/validation.middleware.ts +0 -27
- package/lib/knex/src/models/users.model.ts +0 -13
- package/lib/knex/src/routes/auth.route.ts +0 -22
- package/lib/knex/src/routes/users.route.ts +0 -23
- package/lib/knex/src/server.ts +0 -10
- package/lib/knex/src/services/auth.service.ts +0 -60
- package/lib/knex/src/services/users.service.ts +0 -55
- package/lib/knex/src/test/auth.test.ts +0 -51
- package/lib/knex/src/test/users.test.ts +0 -65
- package/lib/knex/src/utils/logger.ts +0 -65
- package/lib/knex/src/utils/validateEnv.ts +0 -8
- package/lib/knex/swagger.yaml +0 -123
- package/lib/knex/tsconfig.json +0 -40
- package/lib/mikro-orm/.dockerignore +0 -18
- package/lib/mikro-orm/.editorconfig +0 -9
- package/lib/mikro-orm/.env.development.local +0 -18
- package/lib/mikro-orm/.env.production.local +0 -18
- package/lib/mikro-orm/.env.test.local +0 -18
- package/lib/mikro-orm/.eslintignore +0 -1
- package/lib/mikro-orm/.eslintrc +0 -18
- package/lib/mikro-orm/.huskyrc +0 -5
- package/lib/mikro-orm/.lintstagedrc.json +0 -5
- package/lib/mikro-orm/.prettierrc +0 -8
- package/lib/mikro-orm/.swcrc +0 -41
- package/lib/mikro-orm/.vscode/launch.json +0 -35
- package/lib/mikro-orm/.vscode/settings.json +0 -6
- package/lib/mikro-orm/Dockerfile.dev +0 -19
- package/lib/mikro-orm/Dockerfile.prod +0 -19
- package/lib/mikro-orm/Makefile +0 -46
- package/lib/mikro-orm/docker-compose.yml +0 -55
- package/lib/mikro-orm/ecosystem.config.js +0 -57
- package/lib/mikro-orm/jest.config.js +0 -12
- package/lib/mikro-orm/nginx.conf +0 -40
- package/lib/mikro-orm/nodemon.json +0 -12
- package/lib/mikro-orm/package.json +0 -79
- package/lib/mikro-orm/src/app.ts +0 -97
- package/lib/mikro-orm/src/config/index.ts +0 -6
- package/lib/mikro-orm/src/controllers/auth.controller.ts +0 -44
- package/lib/mikro-orm/src/controllers/users.controller.ts +0 -63
- package/lib/mikro-orm/src/database/index.ts +0 -19
- package/lib/mikro-orm/src/dtos/users.dto.ts +0 -20
- package/lib/mikro-orm/src/entities/base.entity.ts +0 -16
- package/lib/mikro-orm/src/entities/users.entity.ts +0 -17
- package/lib/mikro-orm/src/exceptions/HttpException.ts +0 -10
- package/lib/mikro-orm/src/http/auth.http +0 -32
- package/lib/mikro-orm/src/http/users.http +0 -34
- package/lib/mikro-orm/src/interfaces/auth.interface.ts +0 -15
- package/lib/mikro-orm/src/interfaces/routes.interface.ts +0 -6
- package/lib/mikro-orm/src/interfaces/users.interface.ts +0 -5
- package/lib/mikro-orm/src/middlewares/auth.middleware.ts +0 -39
- package/lib/mikro-orm/src/middlewares/error.middleware.ts +0 -15
- package/lib/mikro-orm/src/middlewares/validation.middleware.ts +0 -27
- package/lib/mikro-orm/src/routes/auth.route.ts +0 -22
- package/lib/mikro-orm/src/routes/users.route.ts +0 -23
- package/lib/mikro-orm/src/server.ts +0 -10
- package/lib/mikro-orm/src/services/auth.service.ts +0 -53
- package/lib/mikro-orm/src/services/users.service.ts +0 -60
- package/lib/mikro-orm/src/test/auth.test.ts +0 -65
- package/lib/mikro-orm/src/test/users.test.ts +0 -69
- package/lib/mikro-orm/src/utils/logger.ts +0 -65
- package/lib/mikro-orm/src/utils/validateEnv.ts +0 -8
- package/lib/mikro-orm/swagger.yaml +0 -122
- package/lib/mikro-orm/tsconfig.json +0 -41
- package/lib/mongoose/.dockerignore +0 -18
- package/lib/mongoose/.editorconfig +0 -9
- package/lib/mongoose/.env.development.local +0 -18
- package/lib/mongoose/.env.production.local +0 -18
- package/lib/mongoose/.env.test.local +0 -18
- package/lib/mongoose/.eslintignore +0 -1
- package/lib/mongoose/.eslintrc +0 -18
- package/lib/mongoose/.huskyrc +0 -5
- package/lib/mongoose/.lintstagedrc.json +0 -5
- package/lib/mongoose/.prettierrc +0 -8
- package/lib/mongoose/.swcrc +0 -40
- package/lib/mongoose/.vscode/launch.json +0 -35
- package/lib/mongoose/.vscode/settings.json +0 -6
- package/lib/mongoose/Dockerfile.dev +0 -19
- package/lib/mongoose/Dockerfile.prod +0 -19
- package/lib/mongoose/Makefile +0 -46
- package/lib/mongoose/docker-compose.yml +0 -55
- package/lib/mongoose/ecosystem.config.js +0 -57
- package/lib/mongoose/jest.config.js +0 -12
- package/lib/mongoose/nginx.conf +0 -40
- package/lib/mongoose/nodemon.json +0 -12
- package/lib/mongoose/package.json +0 -78
- package/lib/mongoose/src/app.ts +0 -87
- package/lib/mongoose/src/config/index.ts +0 -6
- package/lib/mongoose/src/controllers/auth.controller.ts +0 -44
- package/lib/mongoose/src/controllers/users.controller.ts +0 -63
- package/lib/mongoose/src/database/index.ts +0 -18
- package/lib/mongoose/src/dtos/users.dto.ts +0 -20
- package/lib/mongoose/src/exceptions/HttpException.ts +0 -10
- package/lib/mongoose/src/http/auth.http +0 -27
- package/lib/mongoose/src/http/users.http +0 -34
- package/lib/mongoose/src/interfaces/auth.interface.ts +0 -15
- package/lib/mongoose/src/interfaces/routes.interface.ts +0 -6
- package/lib/mongoose/src/interfaces/users.interface.ts +0 -5
- package/lib/mongoose/src/middlewares/auth.middleware.ts +0 -39
- package/lib/mongoose/src/middlewares/error.middleware.ts +0 -15
- package/lib/mongoose/src/middlewares/validation.middleware.ts +0 -27
- package/lib/mongoose/src/models/users.model.ts +0 -16
- package/lib/mongoose/src/routes/auth.route.ts +0 -22
- package/lib/mongoose/src/routes/users.route.ts +0 -23
- package/lib/mongoose/src/server.ts +0 -10
- package/lib/mongoose/src/services/auth.service.ts +0 -52
- package/lib/mongoose/src/services/users.service.ts +0 -54
- package/lib/mongoose/src/test/auth.test.ts +0 -83
- package/lib/mongoose/src/test/index.test.ts +0 -18
- package/lib/mongoose/src/test/users.test.ts +0 -133
- package/lib/mongoose/src/utils/logger.ts +0 -65
- package/lib/mongoose/src/utils/validateEnv.ts +0 -8
- package/lib/mongoose/swagger.yaml +0 -120
- package/lib/mongoose/tsconfig.json +0 -40
- package/lib/node-postgres/.dockerignore +0 -18
- package/lib/node-postgres/.editorconfig +0 -9
- package/lib/node-postgres/.env.development.local +0 -20
- package/lib/node-postgres/.env.production.local +0 -20
- package/lib/node-postgres/.env.test.local +0 -20
- package/lib/node-postgres/.eslintignore +0 -1
- package/lib/node-postgres/.eslintrc +0 -18
- package/lib/node-postgres/.huskyrc +0 -5
- package/lib/node-postgres/.lintstagedrc.json +0 -5
- package/lib/node-postgres/.prettierrc +0 -8
- package/lib/node-postgres/.swcrc +0 -38
- package/lib/node-postgres/.vscode/launch.json +0 -35
- package/lib/node-postgres/.vscode/settings.json +0 -6
- package/lib/node-postgres/Dockerfile.dev +0 -17
- package/lib/node-postgres/Dockerfile.prod +0 -17
- package/lib/node-postgres/Makefile +0 -46
- package/lib/node-postgres/docker-compose.yml +0 -61
- package/lib/node-postgres/ecosystem.config.js +0 -57
- package/lib/node-postgres/jest.config.js +0 -12
- package/lib/node-postgres/nginx.conf +0 -40
- package/lib/node-postgres/nodemon.json +0 -12
- package/lib/node-postgres/package.json +0 -78
- package/lib/node-postgres/src/app.ts +0 -81
- package/lib/node-postgres/src/config/index.ts +0 -6
- package/lib/node-postgres/src/controllers/auth.controller.ts +0 -44
- package/lib/node-postgres/src/controllers/users.controller.ts +0 -63
- package/lib/node-postgres/src/database/index.ts +0 -10
- package/lib/node-postgres/src/database/init.sql +0 -13
- package/lib/node-postgres/src/dtos/users.dto.ts +0 -20
- package/lib/node-postgres/src/exceptions/httpException.ts +0 -10
- package/lib/node-postgres/src/http/auth.http +0 -27
- package/lib/node-postgres/src/http/users.http +0 -34
- package/lib/node-postgres/src/interfaces/auth.interface.ts +0 -15
- package/lib/node-postgres/src/interfaces/routes.interface.ts +0 -6
- package/lib/node-postgres/src/interfaces/users.interface.ts +0 -5
- package/lib/node-postgres/src/middlewares/auth.middleware.ts +0 -46
- package/lib/node-postgres/src/middlewares/error.middleware.ts +0 -15
- package/lib/node-postgres/src/middlewares/validation.middleware.ts +0 -27
- package/lib/node-postgres/src/routes/auth.route.ts +0 -21
- package/lib/node-postgres/src/routes/users.route.ts +0 -23
- package/lib/node-postgres/src/server.ts +0 -10
- package/lib/node-postgres/src/services/auth.service.ts +0 -103
- package/lib/node-postgres/src/services/users.service.ts +0 -133
- package/lib/node-postgres/src/test/auth.test.ts +0 -57
- package/lib/node-postgres/src/test/users.test.ts +0 -72
- package/lib/node-postgres/src/utils/logger.ts +0 -65
- package/lib/node-postgres/src/utils/validateEnv.ts +0 -8
- package/lib/node-postgres/swagger.yaml +0 -123
- package/lib/node-postgres/tsconfig.json +0 -39
- package/lib/prisma/.dockerignore +0 -18
- package/lib/prisma/.editorconfig +0 -9
- package/lib/prisma/.env.development.local +0 -16
- package/lib/prisma/.env.production.local +0 -16
- package/lib/prisma/.env.test.local +0 -16
- package/lib/prisma/.eslintignore +0 -1
- package/lib/prisma/.eslintrc +0 -18
- package/lib/prisma/.huskyrc +0 -5
- package/lib/prisma/.lintstagedrc.json +0 -5
- package/lib/prisma/.prettierrc +0 -8
- package/lib/prisma/.vscode/launch.json +0 -35
- package/lib/prisma/.vscode/settings.json +0 -6
- package/lib/prisma/Dockerfile.dev +0 -19
- package/lib/prisma/Dockerfile.prod +0 -19
- package/lib/prisma/Makefile +0 -46
- package/lib/prisma/docker-compose.yml +0 -51
- package/lib/prisma/ecosystem.config.js +0 -57
- package/lib/prisma/jest.config.js +0 -12
- package/lib/prisma/nginx.conf +0 -40
- package/lib/prisma/nodemon.json +0 -12
- package/lib/prisma/package.json +0 -84
- package/lib/prisma/src/app.ts +0 -81
- package/lib/prisma/src/config/index.ts +0 -5
- package/lib/prisma/src/controllers/auth.controller.ts +0 -44
- package/lib/prisma/src/controllers/users.controller.ts +0 -63
- package/lib/prisma/src/dtos/users.dto.ts +0 -20
- package/lib/prisma/src/exceptions/HttpException.ts +0 -10
- package/lib/prisma/src/http/auth.http +0 -27
- package/lib/prisma/src/http/users.http +0 -34
- package/lib/prisma/src/interfaces/auth.interface.ts +0 -15
- package/lib/prisma/src/interfaces/routes.interface.ts +0 -6
- package/lib/prisma/src/interfaces/users.interface.ts +0 -5
- package/lib/prisma/src/middlewares/auth.middleware.ts +0 -39
- package/lib/prisma/src/middlewares/error.middleware.ts +0 -15
- package/lib/prisma/src/middlewares/validation.middleware.ts +0 -27
- package/lib/prisma/src/prisma/migrations/20210314081925_initial/migration.sql +0 -9
- package/lib/prisma/src/prisma/migrations/migration_lock.toml +0 -3
- package/lib/prisma/src/prisma/schema.prisma +0 -17
- package/lib/prisma/src/routes/auth.route.ts +0 -22
- package/lib/prisma/src/routes/users.route.ts +0 -23
- package/lib/prisma/src/server.ts +0 -10
- package/lib/prisma/src/services/auth.service.ts +0 -56
- package/lib/prisma/src/services/users.service.ts +0 -49
- package/lib/prisma/src/test/auth.test.ts +0 -81
- package/lib/prisma/src/test/index.test.ts +0 -18
- package/lib/prisma/src/test/users.test.ts +0 -134
- package/lib/prisma/src/utils/logger.ts +0 -65
- package/lib/prisma/src/utils/validateEnv.ts +0 -8
- package/lib/prisma/swagger.yaml +0 -123
- package/lib/prisma/tsconfig.json +0 -38
- package/lib/routing-controllers/.dockerignore +0 -18
- package/lib/routing-controllers/.editorconfig +0 -9
- package/lib/routing-controllers/.env.development.local +0 -13
- package/lib/routing-controllers/.env.production.local +0 -13
- package/lib/routing-controllers/.env.test.local +0 -13
- package/lib/routing-controllers/.eslintignore +0 -1
- package/lib/routing-controllers/.eslintrc +0 -18
- package/lib/routing-controllers/.huskyrc +0 -5
- package/lib/routing-controllers/.lintstagedrc.json +0 -5
- package/lib/routing-controllers/.prettierrc +0 -8
- package/lib/routing-controllers/.swcrc +0 -38
- package/lib/routing-controllers/.vscode/launch.json +0 -35
- package/lib/routing-controllers/.vscode/settings.json +0 -6
- package/lib/routing-controllers/Dockerfile.dev +0 -19
- package/lib/routing-controllers/Dockerfile.prod +0 -19
- package/lib/routing-controllers/Makefile +0 -42
- package/lib/routing-controllers/docker-compose.yml +0 -35
- package/lib/routing-controllers/ecosystem.config.js +0 -57
- package/lib/routing-controllers/jest.config.js +0 -12
- package/lib/routing-controllers/nginx.conf +0 -40
- package/lib/routing-controllers/nodemon.json +0 -12
- package/lib/routing-controllers/package.json +0 -77
- package/lib/routing-controllers/src/app.ts +0 -101
- package/lib/routing-controllers/src/config/index.ts +0 -5
- package/lib/routing-controllers/src/controllers/auth.controller.ts +0 -41
- package/lib/routing-controllers/src/controllers/users.controller.ts +0 -51
- package/lib/routing-controllers/src/dtos/users.dto.ts +0 -20
- package/lib/routing-controllers/src/exceptions/HttpException.ts +0 -12
- package/lib/routing-controllers/src/http/auth.http +0 -27
- package/lib/routing-controllers/src/http/users.http +0 -34
- package/lib/routing-controllers/src/interfaces/auth.interface.ts +0 -15
- package/lib/routing-controllers/src/interfaces/users.interface.ts +0 -5
- package/lib/routing-controllers/src/middlewares/auth.middleware.ts +0 -38
- package/lib/routing-controllers/src/middlewares/error.middleware.ts +0 -15
- package/lib/routing-controllers/src/middlewares/validation.middleware.ts +0 -27
- package/lib/routing-controllers/src/models/users.model.ts +0 -9
- package/lib/routing-controllers/src/server.ts +0 -9
- package/lib/routing-controllers/src/services/auth.service.ts +0 -53
- package/lib/routing-controllers/src/services/users.service.ts +0 -52
- package/lib/routing-controllers/src/test/auth.test.ts +0 -49
- package/lib/routing-controllers/src/test/users.test.ts +0 -65
- package/lib/routing-controllers/src/utils/logger.ts +0 -65
- package/lib/routing-controllers/src/utils/validateEnv.ts +0 -8
- package/lib/routing-controllers/tsconfig.json +0 -38
- package/lib/sequelize/.dockerignore +0 -18
- package/lib/sequelize/.editorconfig +0 -9
- package/lib/sequelize/.env.development.local +0 -20
- package/lib/sequelize/.env.production.local +0 -20
- package/lib/sequelize/.env.test.local +0 -20
- package/lib/sequelize/.eslintignore +0 -1
- package/lib/sequelize/.eslintrc +0 -18
- package/lib/sequelize/.huskyrc +0 -5
- package/lib/sequelize/.lintstagedrc.json +0 -5
- package/lib/sequelize/.prettierrc +0 -8
- package/lib/sequelize/.sequelizerc +0 -8
- package/lib/sequelize/.swcrc +0 -40
- package/lib/sequelize/.vscode/launch.json +0 -35
- package/lib/sequelize/.vscode/settings.json +0 -6
- package/lib/sequelize/Dockerfile.dev +0 -23
- package/lib/sequelize/Dockerfile.prod +0 -23
- package/lib/sequelize/Makefile +0 -46
- package/lib/sequelize/docker-compose.yml +0 -55
- package/lib/sequelize/docker-entrypoint.sh +0 -5
- package/lib/sequelize/ecosystem.config.js +0 -57
- package/lib/sequelize/jest.config.js +0 -12
- package/lib/sequelize/nginx.conf +0 -40
- package/lib/sequelize/nodemon.json +0 -12
- package/lib/sequelize/package.json +0 -82
- package/lib/sequelize/src/app.ts +0 -87
- package/lib/sequelize/src/config/index.ts +0 -6
- package/lib/sequelize/src/config/sequelize-cli.js +0 -15
- package/lib/sequelize/src/controllers/auth.controller.ts +0 -45
- package/lib/sequelize/src/controllers/users.controller.ts +0 -64
- package/lib/sequelize/src/database/index.ts +0 -34
- package/lib/sequelize/src/database/migrations/.gitkeep +0 -0
- package/lib/sequelize/src/database/seeders/.gitkeep +0 -0
- package/lib/sequelize/src/dtos/users.dto.ts +0 -20
- package/lib/sequelize/src/exceptions/HttpException.ts +0 -10
- package/lib/sequelize/src/http/auth.http +0 -27
- package/lib/sequelize/src/http/users.http +0 -34
- package/lib/sequelize/src/interfaces/auth.interface.ts +0 -15
- package/lib/sequelize/src/interfaces/routes.interface.ts +0 -6
- package/lib/sequelize/src/interfaces/users.interface.ts +0 -5
- package/lib/sequelize/src/middlewares/auth.middleware.ts +0 -38
- package/lib/sequelize/src/middlewares/error.middleware.ts +0 -15
- package/lib/sequelize/src/middlewares/validation.middleware.ts +0 -27
- package/lib/sequelize/src/models/users.model.ts +0 -39
- package/lib/sequelize/src/routes/auth.route.ts +0 -21
- package/lib/sequelize/src/routes/users.route.ts +0 -23
- package/lib/sequelize/src/server.ts +0 -10
- package/lib/sequelize/src/services/auth.service.ts +0 -52
- package/lib/sequelize/src/services/users.service.ts +0 -50
- package/lib/sequelize/src/test/auth.test.ts +0 -71
- package/lib/sequelize/src/test/users.test.ts +0 -131
- package/lib/sequelize/src/utils/logger.ts +0 -65
- package/lib/sequelize/src/utils/validateEnv.ts +0 -8
- package/lib/sequelize/swagger.yaml +0 -123
- package/lib/sequelize/tsconfig.json +0 -40
- package/lib/starter.js +0 -262
- package/lib/typegoose/.dockerignore +0 -18
- package/lib/typegoose/.editorconfig +0 -9
- package/lib/typegoose/.env.development.local +0 -18
- package/lib/typegoose/.env.production.local +0 -18
- package/lib/typegoose/.env.test.local +0 -18
- package/lib/typegoose/.eslintignore +0 -1
- package/lib/typegoose/.eslintrc +0 -18
- package/lib/typegoose/.huskyrc +0 -5
- package/lib/typegoose/.lintstagedrc.json +0 -5
- package/lib/typegoose/.prettierrc +0 -8
- package/lib/typegoose/.swcrc +0 -40
- package/lib/typegoose/.vscode/launch.json +0 -35
- package/lib/typegoose/.vscode/settings.json +0 -6
- package/lib/typegoose/Dockerfile.dev +0 -19
- package/lib/typegoose/Dockerfile.prod +0 -19
- package/lib/typegoose/Makefile +0 -46
- package/lib/typegoose/docker-compose.yml +0 -55
- package/lib/typegoose/ecosystem.config.js +0 -57
- package/lib/typegoose/jest.config.js +0 -12
- package/lib/typegoose/nginx.conf +0 -40
- package/lib/typegoose/nodemon.json +0 -12
- package/lib/typegoose/package.json +0 -79
- package/lib/typegoose/src/app.ts +0 -90
- package/lib/typegoose/src/config/index.ts +0 -6
- package/lib/typegoose/src/controllers/auth.controller.ts +0 -44
- package/lib/typegoose/src/controllers/users.controller.ts +0 -63
- package/lib/typegoose/src/database/index.ts +0 -18
- package/lib/typegoose/src/dtos/users.dto.ts +0 -20
- package/lib/typegoose/src/exceptions/HttpException.ts +0 -10
- package/lib/typegoose/src/http/auth.http +0 -27
- package/lib/typegoose/src/http/users.http +0 -34
- package/lib/typegoose/src/interfaces/auth.interface.ts +0 -15
- package/lib/typegoose/src/interfaces/routes.interface.ts +0 -6
- package/lib/typegoose/src/interfaces/users.interface.ts +0 -5
- package/lib/typegoose/src/middlewares/auth.middleware.ts +0 -38
- package/lib/typegoose/src/middlewares/error.middleware.ts +0 -15
- package/lib/typegoose/src/middlewares/validation.middleware.ts +0 -27
- package/lib/typegoose/src/models/users.model.ts +0 -16
- package/lib/typegoose/src/routes/auth.route.ts +0 -21
- package/lib/typegoose/src/routes/users.route.ts +0 -23
- package/lib/typegoose/src/server.ts +0 -10
- package/lib/typegoose/src/services/auth.service.ts +0 -52
- package/lib/typegoose/src/services/users.service.ts +0 -55
- package/lib/typegoose/src/test/auth.test.ts +0 -83
- package/lib/typegoose/src/test/users.test.ts +0 -133
- package/lib/typegoose/src/utils/logger.ts +0 -65
- package/lib/typegoose/src/utils/validateEnv.ts +0 -8
- package/lib/typegoose/swagger.yaml +0 -120
- package/lib/typegoose/tsconfig.json +0 -40
- package/lib/typeorm/.dockerignore +0 -18
- package/lib/typeorm/.editorconfig +0 -9
- package/lib/typeorm/.env.development.local +0 -20
- package/lib/typeorm/.env.production.local +0 -20
- package/lib/typeorm/.env.test.local +0 -20
- package/lib/typeorm/.eslintignore +0 -1
- package/lib/typeorm/.eslintrc +0 -18
- package/lib/typeorm/.huskyrc +0 -5
- package/lib/typeorm/.lintstagedrc.json +0 -5
- package/lib/typeorm/.prettierrc +0 -8
- package/lib/typeorm/.swcrc +0 -40
- package/lib/typeorm/.vscode/launch.json +0 -35
- package/lib/typeorm/.vscode/settings.json +0 -6
- package/lib/typeorm/Dockerfile.dev +0 -19
- package/lib/typeorm/Dockerfile.prod +0 -19
- package/lib/typeorm/Makefile +0 -46
- package/lib/typeorm/docker-compose.yml +0 -57
- package/lib/typeorm/ecosystem.config.js +0 -57
- package/lib/typeorm/jest.config.js +0 -12
- package/lib/typeorm/nginx.conf +0 -40
- package/lib/typeorm/nodemon.json +0 -12
- package/lib/typeorm/package.json +0 -78
- package/lib/typeorm/src/app.ts +0 -87
- package/lib/typeorm/src/config/index.ts +0 -6
- package/lib/typeorm/src/controllers/auth.controller.ts +0 -44
- package/lib/typeorm/src/controllers/users.controller.ts +0 -63
- package/lib/typeorm/src/database/index.ts +0 -26
- package/lib/typeorm/src/database/migrations/.gitkeep +0 -0
- package/lib/typeorm/src/dtos/users.dto.ts +0 -20
- package/lib/typeorm/src/entities/users.entity.ts +0 -26
- package/lib/typeorm/src/exceptions/HttpException.ts +0 -10
- package/lib/typeorm/src/http/auth.http +0 -27
- package/lib/typeorm/src/http/users.http +0 -34
- package/lib/typeorm/src/interfaces/auth.interface.ts +0 -15
- package/lib/typeorm/src/interfaces/routes.interface.ts +0 -6
- package/lib/typeorm/src/interfaces/users.interface.ts +0 -5
- package/lib/typeorm/src/middlewares/auth.middleware.ts +0 -38
- package/lib/typeorm/src/middlewares/error.middleware.ts +0 -15
- package/lib/typeorm/src/middlewares/validation.middleware.ts +0 -27
- package/lib/typeorm/src/routes/auth.route.ts +0 -21
- package/lib/typeorm/src/routes/users.route.ts +0 -23
- package/lib/typeorm/src/server.ts +0 -10
- package/lib/typeorm/src/services/auth.service.ts +0 -54
- package/lib/typeorm/src/services/users.service.ts +0 -51
- package/lib/typeorm/src/test/auth.test.ts +0 -75
- package/lib/typeorm/src/test/users.test.ts +0 -136
- package/lib/typeorm/src/utils/logger.ts +0 -65
- package/lib/typeorm/src/utils/validateEnv.ts +0 -8
- package/lib/typeorm/swagger.yaml +0 -123
- /package/{lib → templates}/default/src/interfaces/routes.interface.ts +0 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Request, Response, NextFunction } from 'express';
|
|
2
|
+
import { verify, TokenExpiredError, JsonWebTokenError } from 'jsonwebtoken';
|
|
3
|
+
import { container } from 'tsyringe';
|
|
4
|
+
import { SECRET_KEY } from '@config/env';
|
|
5
|
+
import { HttpException } from '@exceptions/httpException';
|
|
6
|
+
import { DataStoredInToken, RequestWithUser } from '@interfaces/auth.interface';
|
|
7
|
+
import { UsersRepository } from '@repositories/users.repository';
|
|
8
|
+
|
|
9
|
+
const getAuthorization = (req: RequestWithUser) => {
|
|
10
|
+
const cookie = req.cookies['Authorization'];
|
|
11
|
+
if (cookie) return cookie;
|
|
12
|
+
|
|
13
|
+
const header = req.header('Authorization');
|
|
14
|
+
if (header && header.startsWith('Bearer ')) {
|
|
15
|
+
return header.replace('Bearer ', '').trim();
|
|
16
|
+
}
|
|
17
|
+
return null;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const AuthMiddleware = async (req: Request, res: Response, next: NextFunction) => {
|
|
21
|
+
try {
|
|
22
|
+
const userReq = req as RequestWithUser;
|
|
23
|
+
const token = getAuthorization(userReq);
|
|
24
|
+
if (!token) return next(new HttpException(401, 'Authentication token missing'));
|
|
25
|
+
|
|
26
|
+
let payload: DataStoredInToken;
|
|
27
|
+
try {
|
|
28
|
+
payload = verify(token, SECRET_KEY as string) as DataStoredInToken;
|
|
29
|
+
} catch (err) {
|
|
30
|
+
if (err instanceof TokenExpiredError) {
|
|
31
|
+
return next(new HttpException(401, 'Authentication token expired'));
|
|
32
|
+
}
|
|
33
|
+
if (err instanceof JsonWebTokenError) {
|
|
34
|
+
return next(new HttpException(401, 'Invalid authentication token'));
|
|
35
|
+
}
|
|
36
|
+
return next(new HttpException(401, 'Authentication failed'));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 타입 일치 유의 (number/string)
|
|
40
|
+
const userRepo = container.resolve(UsersRepository);
|
|
41
|
+
const findUser = await userRepo.findById(String(payload.id));
|
|
42
|
+
if (!findUser) return next(new HttpException(401, 'User not found with this token'));
|
|
43
|
+
|
|
44
|
+
(req as RequestWithUser).user = findUser;
|
|
45
|
+
next();
|
|
46
|
+
} catch {
|
|
47
|
+
next(new HttpException(500, 'Authentication middleware error'));
|
|
48
|
+
}
|
|
49
|
+
};
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { Request, Response, NextFunction } from 'express';
|
|
2
|
+
import { JsonWebTokenError, TokenExpiredError } from 'jsonwebtoken';
|
|
3
|
+
import { ZodError } from 'zod';
|
|
4
|
+
import { NODE_ENV } from '@config/env';
|
|
5
|
+
import { HttpException } from '@exceptions/httpException';
|
|
6
|
+
import { logger } from '@utils/logger';
|
|
7
|
+
|
|
8
|
+
type ValidationIssue = { path: string; message: string };
|
|
9
|
+
type HttpExceptionWithData = HttpException & { data?: unknown };
|
|
10
|
+
type WithStack = { stack?: string };
|
|
11
|
+
|
|
12
|
+
interface ErrorDetails {
|
|
13
|
+
code: number;
|
|
14
|
+
message: string;
|
|
15
|
+
data?: unknown;
|
|
16
|
+
stack?: string;
|
|
17
|
+
}
|
|
18
|
+
interface ErrorResponseBody {
|
|
19
|
+
success: false;
|
|
20
|
+
error: ErrorDetails;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** 타입가드들 */
|
|
24
|
+
const isZodError = (e: unknown): e is ZodError => {
|
|
25
|
+
return e instanceof ZodError;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
/** jsonwebtoken은 런타임에 따라 클래스 경계 이슈가 있을 수 있어 name 기반 가드 권장 */
|
|
29
|
+
const isTokenExpiredError = (e: unknown): e is TokenExpiredError => {
|
|
30
|
+
return e instanceof Error && (e as any).name === 'TokenExpiredError';
|
|
31
|
+
};
|
|
32
|
+
const isJsonWebTokenError = (e: unknown): e is JsonWebTokenError => {
|
|
33
|
+
return e instanceof Error && (e as any).name === 'JsonWebTokenError';
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
const toHttpException = (err: unknown): HttpException => {
|
|
37
|
+
if (err instanceof HttpException) return err;
|
|
38
|
+
|
|
39
|
+
if (isZodError(err)) {
|
|
40
|
+
const data: ValidationIssue[] = err.issues.map((i) => ({
|
|
41
|
+
path: i.path.join('.'),
|
|
42
|
+
message: i.message,
|
|
43
|
+
}));
|
|
44
|
+
return new HttpException(400, 'Validation failed', data);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (isTokenExpiredError(err)) return new HttpException(401, 'Token expired');
|
|
48
|
+
if (isJsonWebTokenError(err)) return new HttpException(401, 'Invalid token');
|
|
49
|
+
|
|
50
|
+
const e = err as Error | undefined;
|
|
51
|
+
return new HttpException(500, e?.message || 'Internal Server Error');
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const extractStack = (err: unknown): string | undefined => {
|
|
55
|
+
if (err && typeof err === 'object' && 'stack' in err) {
|
|
56
|
+
const s = (err as WithStack).stack;
|
|
57
|
+
return typeof s === 'string' ? s : undefined;
|
|
58
|
+
}
|
|
59
|
+
return undefined;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export const ErrorMiddleware = (
|
|
63
|
+
error: unknown,
|
|
64
|
+
req: Request,
|
|
65
|
+
res: Response,
|
|
66
|
+
_next: NextFunction,
|
|
67
|
+
) => {
|
|
68
|
+
const httpErr = toHttpException(error);
|
|
69
|
+
const status = httpErr.status || 500;
|
|
70
|
+
const message = httpErr.message || 'Something went wrong';
|
|
71
|
+
|
|
72
|
+
if (res.headersSent) return _next(httpErr);
|
|
73
|
+
|
|
74
|
+
const stack = extractStack(httpErr);
|
|
75
|
+
logger.error(
|
|
76
|
+
`[${req.method}] ${req.originalUrl} | ${status} | ${message}${stack ? `\n${stack}` : ''}`,
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const body: ErrorResponseBody = {
|
|
80
|
+
success: false,
|
|
81
|
+
error: { code: status, message },
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const maybeData = (httpErr as HttpExceptionWithData).data;
|
|
85
|
+
if (typeof maybeData !== 'undefined') body.error.data = maybeData;
|
|
86
|
+
if (NODE_ENV === 'development' && stack) body.error.stack = stack;
|
|
87
|
+
|
|
88
|
+
res.status(status).json(body);
|
|
89
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { NextFunction, Request, Response } from 'express';
|
|
2
|
+
import type { ZodTypeAny } from 'zod';
|
|
3
|
+
import { HttpException } from '@exceptions/httpException';
|
|
4
|
+
|
|
5
|
+
export function ValidationMiddleware(schema: ZodTypeAny) {
|
|
6
|
+
return (req: Request, res: Response, next: NextFunction) => {
|
|
7
|
+
const result = schema.safeParse(req.body);
|
|
8
|
+
if (!result.success) {
|
|
9
|
+
const message = result.error.issues.map((e) => e.message).join(', ');
|
|
10
|
+
return next(new HttpException(400, message));
|
|
11
|
+
}
|
|
12
|
+
req.body = result.data;
|
|
13
|
+
next();
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { singleton } from 'tsyringe';
|
|
2
|
+
import { User, type UserPersistenceData } from '@entities/user.entity';
|
|
3
|
+
|
|
4
|
+
export interface IUsersRepository {
|
|
5
|
+
findAll(): Promise<User[]>;
|
|
6
|
+
findById(id: string): Promise<User | undefined>;
|
|
7
|
+
findByEmail(email: string): Promise<User | undefined>;
|
|
8
|
+
save(user: User): Promise<User>;
|
|
9
|
+
update(id: string, user: User): Promise<User | undefined>;
|
|
10
|
+
delete(id: string): Promise<boolean>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
@singleton()
|
|
14
|
+
export class UsersRepository implements IUsersRepository {
|
|
15
|
+
private users: UserPersistenceData[] = [];
|
|
16
|
+
|
|
17
|
+
async findAll(): Promise<User[]> {
|
|
18
|
+
return this.users.map((userData) => User.fromPersistence(userData));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async findById(id: string): Promise<User | undefined> {
|
|
22
|
+
const userData = this.users.find((u) => u.id === id);
|
|
23
|
+
return userData ? User.fromPersistence(userData) : undefined;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async findByEmail(email: string): Promise<User | undefined> {
|
|
27
|
+
const userData = this.users.find((u) => u.email === email.toLowerCase());
|
|
28
|
+
return userData ? User.fromPersistence(userData) : undefined;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async save(user: User): Promise<User> {
|
|
32
|
+
const persistenceData = user.toPersistence();
|
|
33
|
+
this.users.push(persistenceData);
|
|
34
|
+
return user;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async update(id: string, user: User): Promise<User | undefined> {
|
|
38
|
+
const idx = this.users.findIndex((u) => u.id === id);
|
|
39
|
+
if (idx === -1) return undefined;
|
|
40
|
+
|
|
41
|
+
this.users[idx] = user.toPersistence();
|
|
42
|
+
return user;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async delete(id: string): Promise<boolean> {
|
|
46
|
+
const idx = this.users.findIndex((u) => u.id === id);
|
|
47
|
+
if (idx === -1) return false;
|
|
48
|
+
this.users.splice(idx, 1);
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
reset() {
|
|
53
|
+
this.users = [];
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { injectable, inject } from 'tsyringe';
|
|
3
|
+
import { AuthController } from '@controllers/auth.controller';
|
|
4
|
+
import { createUserSchema } from '@dtos/users.dto';
|
|
5
|
+
import { Routes } from '@interfaces/routes.interface';
|
|
6
|
+
import { AuthMiddleware } from '@middlewares/auth.middleware';
|
|
7
|
+
import { ValidationMiddleware } from '@middlewares/validation.middleware';
|
|
8
|
+
|
|
9
|
+
@injectable()
|
|
10
|
+
export class AuthRoute implements Routes {
|
|
11
|
+
public router: Router = Router();
|
|
12
|
+
public path = '/auth';
|
|
13
|
+
|
|
14
|
+
constructor(@inject(AuthController) private authController: AuthController) {
|
|
15
|
+
this.initializeRoutes();
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
private initializeRoutes() {
|
|
19
|
+
this.router.post(
|
|
20
|
+
`${this.path}/signup`,
|
|
21
|
+
ValidationMiddleware(createUserSchema),
|
|
22
|
+
this.authController.signUp,
|
|
23
|
+
);
|
|
24
|
+
this.router.post(
|
|
25
|
+
`${this.path}/login`,
|
|
26
|
+
ValidationMiddleware(createUserSchema),
|
|
27
|
+
this.authController.logIn,
|
|
28
|
+
);
|
|
29
|
+
this.router.post(`${this.path}/logout`, AuthMiddleware, this.authController.logOut);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { injectable, inject } from 'tsyringe';
|
|
3
|
+
import { UsersController } from '@controllers/users.controller';
|
|
4
|
+
import { createUserSchema, updateUserSchema } from '@dtos/users.dto';
|
|
5
|
+
import { Routes } from '@interfaces/routes.interface';
|
|
6
|
+
import { ValidationMiddleware } from '@middlewares/validation.middleware';
|
|
7
|
+
|
|
8
|
+
@injectable()
|
|
9
|
+
export class UsersRoute implements Routes {
|
|
10
|
+
public router: Router = Router();
|
|
11
|
+
public path = '/users';
|
|
12
|
+
|
|
13
|
+
constructor(@inject(UsersController) private userController: UsersController) {
|
|
14
|
+
this.initializeRoutes();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
private initializeRoutes() {
|
|
18
|
+
this.router.get(this.path, this.userController.getUsers);
|
|
19
|
+
this.router.get(`${this.path}/:id`, this.userController.getUserById);
|
|
20
|
+
this.router.post(
|
|
21
|
+
this.path,
|
|
22
|
+
ValidationMiddleware(createUserSchema),
|
|
23
|
+
this.userController.createUser,
|
|
24
|
+
);
|
|
25
|
+
this.router.put(
|
|
26
|
+
`${this.path}/:id`,
|
|
27
|
+
ValidationMiddleware(updateUserSchema),
|
|
28
|
+
this.userController.updateUser,
|
|
29
|
+
);
|
|
30
|
+
this.router.delete(`${this.path}/:id`, this.userController.deleteUser);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import 'reflect-metadata';
|
|
2
|
+
import '@config/env';
|
|
3
|
+
import { container } from 'tsyringe';
|
|
4
|
+
import App from '@/app';
|
|
5
|
+
import { UsersRepository } from '@repositories/users.repository';
|
|
6
|
+
import { AuthRoute } from '@routes/auth.route';
|
|
7
|
+
import { UsersRoute } from '@routes/users.route';
|
|
8
|
+
|
|
9
|
+
// DI 등록
|
|
10
|
+
container.registerInstance(UsersRepository, new UsersRepository());
|
|
11
|
+
|
|
12
|
+
// 라우트 모듈을 필요에 따라 동적으로 배열화 가능
|
|
13
|
+
const routes = [container.resolve(UsersRoute), container.resolve(AuthRoute)];
|
|
14
|
+
|
|
15
|
+
// API prefix는 app.ts에서 기본값 세팅, 필요하면 인자로 전달
|
|
16
|
+
const appInstance = new App(routes);
|
|
17
|
+
|
|
18
|
+
// listen()이 서버 객체(http.Server)를 반환하도록 app.ts를 살짝 수정
|
|
19
|
+
const server = appInstance.listen(); // PORT를 쓰려면 이렇게 전달도 가능
|
|
20
|
+
|
|
21
|
+
// Graceful Shutdown: 운영환경에서 필수!
|
|
22
|
+
if (server && typeof server.close === 'function') {
|
|
23
|
+
['SIGINT', 'SIGTERM'].forEach((signal) => {
|
|
24
|
+
process.on(signal, () => {
|
|
25
|
+
console.log(`Received ${signal}, closing server...`);
|
|
26
|
+
server.close(() => {
|
|
27
|
+
console.log('HTTP server closed gracefully');
|
|
28
|
+
// 필요하면 DB/Redis 등 외부 자원 해제 코드 추가
|
|
29
|
+
process.exit(0);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export default server;
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { sign } from 'jsonwebtoken';
|
|
2
|
+
import { injectable, inject } from 'tsyringe';
|
|
3
|
+
import { NODE_ENV, SECRET_KEY } from '@config/env';
|
|
4
|
+
import { HttpException } from '@exceptions/httpException';
|
|
5
|
+
import { DataStoredInToken, TokenData } from '@interfaces/auth.interface';
|
|
6
|
+
import { User, type UserCreateData } from '@entities/user.entity';
|
|
7
|
+
import { UsersRepository } from '@repositories/users.repository';
|
|
8
|
+
import type { IUsersRepository } from '@repositories/users.repository';
|
|
9
|
+
|
|
10
|
+
@injectable()
|
|
11
|
+
export class AuthService {
|
|
12
|
+
constructor(@inject(UsersRepository) private usersRepository: IUsersRepository) {}
|
|
13
|
+
|
|
14
|
+
private createToken(user: User): TokenData {
|
|
15
|
+
if (!SECRET_KEY) throw new Error('SECRET_KEY is not defined');
|
|
16
|
+
|
|
17
|
+
if (user.id === undefined) {
|
|
18
|
+
throw new Error('User id is undefined');
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const dataStoredInToken: DataStoredInToken = { id: user.id };
|
|
22
|
+
const expiresIn = 60 * 60; // 1h
|
|
23
|
+
const token = sign(dataStoredInToken, SECRET_KEY as string, { expiresIn });
|
|
24
|
+
return { expiresIn, token };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
private createCookie(tokenData: TokenData): string {
|
|
28
|
+
return `Authorization=${tokenData.token}; HttpOnly; Max-Age=${
|
|
29
|
+
tokenData.expiresIn
|
|
30
|
+
}; Path=/; SameSite=Lax;${NODE_ENV === 'production' ? ' Secure;' : ''}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public async signup(userData: UserCreateData): Promise<User> {
|
|
34
|
+
const findUser = await this.usersRepository.findByEmail(userData.email);
|
|
35
|
+
if (findUser) throw new HttpException(409, `Email is already in use`);
|
|
36
|
+
|
|
37
|
+
// Entity 클래스의 팩토리 메서드로 생성 (모든 검증이 자동 처리됨)
|
|
38
|
+
const newUser = await User.create(userData);
|
|
39
|
+
await this.usersRepository.save(newUser);
|
|
40
|
+
return newUser;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
public async login(loginData: {
|
|
44
|
+
email: string;
|
|
45
|
+
password: string;
|
|
46
|
+
}): Promise<{ cookie: string; user: User }> {
|
|
47
|
+
const findUser = await this.usersRepository.findByEmail(loginData.email);
|
|
48
|
+
if (!findUser) throw new HttpException(401, `Invalid email or password.`);
|
|
49
|
+
|
|
50
|
+
// Entity의 도메인 메서드로 패스워드 검증
|
|
51
|
+
const isPasswordMatching = await findUser.verifyPassword(loginData.password);
|
|
52
|
+
if (!isPasswordMatching) throw new HttpException(401, 'Password is incorrect');
|
|
53
|
+
|
|
54
|
+
const tokenData = this.createToken(findUser);
|
|
55
|
+
const cookie = this.createCookie(tokenData);
|
|
56
|
+
|
|
57
|
+
return { cookie, user: findUser };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
public async logout(user: User): Promise<void> {
|
|
61
|
+
// 로그아웃은 실제 서비스에서는 서버에서 세션/리프레시토큰을 블랙리스트 처리 등 구현 가능
|
|
62
|
+
// 여기서는 클라이언트의 쿠키를 삭제하면 충분
|
|
63
|
+
console.log(`User with email ${user.email} logged out.`);
|
|
64
|
+
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { injectable, inject } from 'tsyringe';
|
|
2
|
+
import { HttpException } from '@exceptions/httpException';
|
|
3
|
+
import { User, type UserCreateData } from '@entities/user.entity';
|
|
4
|
+
import { UsersRepository } from '@repositories/users.repository';
|
|
5
|
+
import type { IUsersRepository } from '@repositories/users.repository';
|
|
6
|
+
|
|
7
|
+
@injectable()
|
|
8
|
+
export class UsersService {
|
|
9
|
+
constructor(@inject(UsersRepository) private usersRepository: IUsersRepository) {}
|
|
10
|
+
|
|
11
|
+
async getAllUsers(): Promise<User[]> {
|
|
12
|
+
return this.usersRepository.findAll();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async getUserById(id: string): Promise<User> {
|
|
16
|
+
const user = await this.usersRepository.findById(id);
|
|
17
|
+
if (!user) throw new HttpException(404, 'User not found');
|
|
18
|
+
return user;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async createUser(userData: UserCreateData): Promise<User> {
|
|
22
|
+
// Entity에서 이메일 중복 검사를 위해 먼저 확인
|
|
23
|
+
const exists = await this.usersRepository.findByEmail(userData.email);
|
|
24
|
+
if (exists) throw new HttpException(409, 'Email already exists');
|
|
25
|
+
|
|
26
|
+
// Entity 클래스의 팩토리 메서드로 생성 (모든 검증이 자동 처리됨)
|
|
27
|
+
const user = await User.create(userData);
|
|
28
|
+
await this.usersRepository.save(user);
|
|
29
|
+
return user;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async updateUser(id: string, updateData: { email?: string; password?: string }): Promise<User> {
|
|
33
|
+
const existingUser = await this.usersRepository.findById(id);
|
|
34
|
+
if (!existingUser) throw new HttpException(404, 'User not found');
|
|
35
|
+
|
|
36
|
+
// Entity의 도메인 메서드를 사용하여 업데이트
|
|
37
|
+
await existingUser.updateProfile(updateData);
|
|
38
|
+
|
|
39
|
+
const updated = await this.usersRepository.update(id, existingUser);
|
|
40
|
+
if (!updated) throw new HttpException(404, 'User not found');
|
|
41
|
+
return updated;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async deleteUser(id: string): Promise<void> {
|
|
45
|
+
const deleted = await this.usersRepository.delete(id);
|
|
46
|
+
if (!deleted) throw new HttpException(404, 'User not found');
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Request, Response, NextFunction, RequestHandler } from 'express';
|
|
2
|
+
|
|
3
|
+
export type AsyncHandler = (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
4
|
+
|
|
5
|
+
export const asyncHandler =
|
|
6
|
+
(fn: AsyncHandler): RequestHandler =>
|
|
7
|
+
(req, res, next) =>
|
|
8
|
+
Promise.resolve(fn(req, res, next)).catch(next);
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { existsSync, mkdirSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import pino from 'pino';
|
|
4
|
+
import { LOG_DIR, LOG_LEVEL, NODE_ENV } from '@config/env';
|
|
5
|
+
|
|
6
|
+
// 로그 환경 설정
|
|
7
|
+
const isProd = NODE_ENV === 'production';
|
|
8
|
+
const logRoot = LOG_DIR || 'logs';
|
|
9
|
+
const logLevel = LOG_LEVEL || 'info';
|
|
10
|
+
|
|
11
|
+
// 현재 런타임 위치(프로젝트 실행 디렉토리)에 logs 폴더 생성
|
|
12
|
+
const projectRoot = process.cwd(); // 현재 프로세스 실행 디렉토리
|
|
13
|
+
const logDir = join(projectRoot, logRoot);
|
|
14
|
+
|
|
15
|
+
// 로그 디렉토리 생성 (에러 핸들링 포함)
|
|
16
|
+
try {
|
|
17
|
+
if (!existsSync(logDir)) {
|
|
18
|
+
mkdirSync(logDir, { recursive: true });
|
|
19
|
+
console.log(`[Logger Init] Created log directory: ${logDir}`);
|
|
20
|
+
} else {
|
|
21
|
+
console.log(`[Logger Init] Log directory already exists: ${logDir}`);
|
|
22
|
+
}
|
|
23
|
+
} catch (error) {
|
|
24
|
+
console.error(`[Logger Init] Failed to create log directory: ${logDir}`, error);
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// 파일 로깅용 경로
|
|
29
|
+
const prodFile = join(logDir, 'app');
|
|
30
|
+
const devFile = join(logDir, 'app.dev');
|
|
31
|
+
const errorFile = join(logDir, 'error');
|
|
32
|
+
|
|
33
|
+
// Pino 인스턴스
|
|
34
|
+
const transport = pino.transport({
|
|
35
|
+
targets: isProd
|
|
36
|
+
? [
|
|
37
|
+
// prod: 일자/용량 기반 롤링 + 30일 보관 (전체 로그)
|
|
38
|
+
{
|
|
39
|
+
target: 'pino-roll',
|
|
40
|
+
level: logLevel,
|
|
41
|
+
options: {
|
|
42
|
+
file: prodFile, // 최종 파일: app.2025-08-29.log 등
|
|
43
|
+
frequency: 'daily', // 'daily' | 'hourly' | number(ms)
|
|
44
|
+
size: '50m', // 용량 기준 분할
|
|
45
|
+
dateFormat: 'yyyy-MM-dd',
|
|
46
|
+
extension: '.log',
|
|
47
|
+
mkdir: true,
|
|
48
|
+
symlink: true, // current.log 심볼릭 링크 생성
|
|
49
|
+
limit: { count: 30 }, // 30개 보관
|
|
50
|
+
// limit: { count: 30, removeOtherLogFiles: false }, // PM2/클러스터면 주의
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
// prod: 에러 전용 파일 (보관 60일 등 별도 정책 가능)
|
|
54
|
+
{
|
|
55
|
+
target: 'pino-roll',
|
|
56
|
+
level: 'error',
|
|
57
|
+
options: {
|
|
58
|
+
file: errorFile,
|
|
59
|
+
frequency: 'daily',
|
|
60
|
+
size: '50m',
|
|
61
|
+
dateFormat: 'yyyy-MM-dd',
|
|
62
|
+
extension: '.log',
|
|
63
|
+
mkdir: true,
|
|
64
|
+
symlink: true,
|
|
65
|
+
limit: { count: 60 },
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
]
|
|
69
|
+
: [
|
|
70
|
+
// dev: 예쁜 콘솔 출력
|
|
71
|
+
{
|
|
72
|
+
target: 'pino-pretty',
|
|
73
|
+
level: logLevel,
|
|
74
|
+
options: {
|
|
75
|
+
colorize: true,
|
|
76
|
+
translateTime: 'yyyy-mm-dd HH:MM:ss',
|
|
77
|
+
ignore: 'pid,hostname',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
// dev: 파일도 같이 굴리고 싶다면(선택) — 필요 없으면 이 블록을 지워도 됨
|
|
81
|
+
{
|
|
82
|
+
target: 'pino-roll',
|
|
83
|
+
level: logLevel,
|
|
84
|
+
options: {
|
|
85
|
+
file: devFile,
|
|
86
|
+
frequency: 'daily',
|
|
87
|
+
size: '20m',
|
|
88
|
+
dateFormat: 'yyyy-MM-dd',
|
|
89
|
+
extension: '.log',
|
|
90
|
+
mkdir: true,
|
|
91
|
+
symlink: true,
|
|
92
|
+
limit: { count: 7 },
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
// ── Logger 인스턴스
|
|
99
|
+
export const logger = pino(
|
|
100
|
+
{
|
|
101
|
+
level: logLevel,
|
|
102
|
+
base: undefined,
|
|
103
|
+
timestamp: pino.stdTimeFunctions.isoTime,
|
|
104
|
+
redact: {
|
|
105
|
+
paths: ['req.headers.authorization', 'password', 'token'],
|
|
106
|
+
censor: '[REDACTED]',
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
transport,
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
// morgan stream
|
|
113
|
+
export const stream = { write: (msg: string) => logger.info(msg.trim()) };
|
|
@@ -1,40 +1,41 @@
|
|
|
1
1
|
{
|
|
2
|
-
"compileOnSave": false,
|
|
3
2
|
"compilerOptions": {
|
|
4
|
-
"target": "
|
|
5
|
-
"lib": ["es2017", "esnext.asynciterable"],
|
|
6
|
-
"typeRoots": ["node_modules/@types"],
|
|
7
|
-
"allowSyntheticDefaultImports": true,
|
|
8
|
-
"experimentalDecorators": true,
|
|
9
|
-
"emitDecoratorMetadata": true,
|
|
10
|
-
"forceConsistentCasingInFileNames": true,
|
|
11
|
-
"moduleResolution": "node",
|
|
3
|
+
"target": "es2020",
|
|
12
4
|
"module": "commonjs",
|
|
13
|
-
"
|
|
14
|
-
"sourceMap": true,
|
|
15
|
-
"declaration": true,
|
|
5
|
+
"moduleResolution": "node",
|
|
16
6
|
"outDir": "dist",
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
|
|
7
|
+
"declaration": true,
|
|
8
|
+
"sourceMap": true,
|
|
9
|
+
"strict": true,
|
|
10
|
+
"lib": ["es2020", "esnext.asynciterable"],
|
|
11
|
+
|
|
22
12
|
"baseUrl": "src",
|
|
23
13
|
"paths": {
|
|
24
14
|
"@/*": ["*"],
|
|
25
|
-
"@config": ["config"],
|
|
15
|
+
"@config/*": ["config/*"],
|
|
26
16
|
"@controllers/*": ["controllers/*"],
|
|
27
|
-
"@database": ["database"],
|
|
28
17
|
"@dtos/*": ["dtos/*"],
|
|
29
18
|
"@entities/*": ["entities/*"],
|
|
30
19
|
"@exceptions/*": ["exceptions/*"],
|
|
31
20
|
"@interfaces/*": ["interfaces/*"],
|
|
32
21
|
"@middlewares/*": ["middlewares/*"],
|
|
22
|
+
"@repositories/*": ["repositories/*"],
|
|
33
23
|
"@routes/*": ["routes/*"],
|
|
34
24
|
"@services/*": ["services/*"],
|
|
35
25
|
"@utils/*": ["utils/*"]
|
|
36
|
-
}
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
"esModuleInterop": true,
|
|
29
|
+
"allowSyntheticDefaultImports": true,
|
|
30
|
+
"resolveJsonModule": true,
|
|
31
|
+
"importHelpers": true,
|
|
32
|
+
"forceConsistentCasingInFileNames": true,
|
|
33
|
+
"experimentalDecorators": true,
|
|
34
|
+
"emitDecoratorMetadata": true,
|
|
35
|
+
"pretty": true,
|
|
36
|
+
"allowJs": false,
|
|
37
|
+
"noEmit": false
|
|
37
38
|
},
|
|
38
|
-
"include": ["src/**/*.ts", "src/**/*.json"
|
|
39
|
-
"exclude": ["node_modules", "
|
|
39
|
+
"include": ["src/**/*.ts", "src/**/*.json"],
|
|
40
|
+
"exclude": ["node_modules", "dist", "coverage", "logs", "src/http"]
|
|
40
41
|
}
|