├── .github ├── ISSUE_TEMPLATE │ ├── bug-report---.md │ ├── feature-request---.md │ └── question---.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── publish.yml ├── .gitignore ├── .npmignore ├── CONTRIBUTORS.md ├── LICENSE ├── README.kr.md ├── README.md ├── bin └── cli.js ├── lib ├── default │ ├── .dockerignore │ ├── .editorconfig │ ├── .env.development.local │ ├── .env.production.local │ ├── .env.test.local │ ├── .eslintignore │ ├── .eslintrc │ ├── .huskyrc │ ├── .lintstagedrc.json │ ├── .prettierrc │ ├── .swcrc │ ├── .vscode │ │ ├── launch.json │ │ └── settings.json │ ├── Dockerfile.dev │ ├── Dockerfile.prod │ ├── Makefile │ ├── docker-compose.yml │ ├── ecosystem.config.js │ ├── jest.config.js │ ├── nginx.conf │ ├── nodemon.json │ ├── package.json │ ├── src │ │ ├── app.ts │ │ ├── config │ │ │ └── index.ts │ │ ├── controllers │ │ │ ├── auth.controller.ts │ │ │ └── users.controller.ts │ │ ├── dtos │ │ │ └── users.dto.ts │ │ ├── exceptions │ │ │ └── HttpException.ts │ │ ├── http │ │ │ ├── auth.http │ │ │ └── users.http │ │ ├── interfaces │ │ │ ├── auth.interface.ts │ │ │ ├── routes.interface.ts │ │ │ └── users.interface.ts │ │ ├── middlewares │ │ │ ├── auth.middleware.ts │ │ │ ├── error.middleware.ts │ │ │ └── validation.middleware.ts │ │ ├── models │ │ │ └── users.model.ts │ │ ├── routes │ │ │ ├── auth.route.ts │ │ │ └── users.route.ts │ │ ├── server.ts │ │ ├── services │ │ │ ├── auth.service.ts │ │ │ └── users.service.ts │ │ ├── test │ │ │ ├── auth.test.ts │ │ │ └── users.test.ts │ │ └── utils │ │ │ ├── logger.ts │ │ │ └── validateEnv.ts │ ├── swagger.yaml │ └── tsconfig.json ├── graphql │ ├── .dockerignore │ ├── .editorconfig │ ├── .env.development.local │ ├── .env.production.local │ ├── .env.test.local │ ├── .eslintignore │ ├── .eslintrc │ ├── .huskyrc │ ├── .lintstagedrc.json │ ├── .prettierrc │ ├── .swcrc │ ├── .vscode │ │ ├── launch.json │ │ └── settings.json │ ├── Dockerfile.dev │ ├── Dockerfile.prod │ ├── Makefile │ ├── docker-compose.yml │ ├── ecosystem.config.js │ ├── jest.config.js │ ├── nginx.conf │ ├── nodemon.json │ ├── package.json │ ├── src │ │ ├── app.ts │ │ ├── config │ │ │ └── index.ts │ │ ├── database │ │ │ └── index.ts │ │ ├── dtos │ │ │ └── users.dto.ts │ │ ├── entities │ │ │ └── users.entity.ts │ │ ├── exceptions │ │ │ └── HttpException.ts │ │ ├── http │ │ │ ├── auth.http │ │ │ └── users.http │ │ ├── interfaces │ │ │ ├── auth.interface.ts │ │ │ └── users.interface.ts │ │ ├── middlewares │ │ │ ├── auth.middleware.ts │ │ │ └── error.middleware.ts │ │ ├── repositories │ │ │ ├── auth.repository.ts │ │ │ └── users.repository.ts │ │ ├── resolvers │ │ │ ├── auth.resolver.ts │ │ │ └── users.resolver.ts │ │ ├── server.ts │ │ ├── test │ │ │ ├── auth.test.ts │ │ │ └── users.test.ts │ │ ├── typedefs │ │ │ └── users.type.ts │ │ └── utils │ │ │ ├── logger.ts │ │ │ └── validateEnv.ts │ └── tsconfig.json ├── knex │ ├── .dockerignore │ ├── .editorconfig │ ├── .env.development.local │ ├── .env.production.local │ ├── .env.test.local │ ├── .eslintignore │ ├── .eslintrc │ ├── .huskyrc │ ├── .lintstagedrc.json │ ├── .prettierrc │ ├── .swcrc │ ├── .vscode │ │ ├── launch.json │ │ └── settings.json │ ├── Dockerfile.dev │ ├── Dockerfile.prod │ ├── Makefile │ ├── docker-compose.yml │ ├── ecosystem.config.js │ ├── jest.config.js │ ├── knexfile.ts │ ├── nginx.conf │ ├── nodemon.json │ ├── package.json │ ├── src │ │ ├── app.ts │ │ ├── config │ │ │ └── index.ts │ │ ├── controllers │ │ │ ├── auth.controller.ts │ │ │ └── users.controller.ts │ │ ├── database │ │ │ ├── index.ts │ │ │ ├── migrations │ │ │ │ ├── .gitkeep │ │ │ │ └── 20210713110926_initial.ts │ │ │ └── seeds │ │ │ │ └── .gitkeep │ │ ├── dtos │ │ │ └── users.dto.ts │ │ ├── exceptions │ │ │ └── HttpException.ts │ │ ├── http │ │ │ ├── auth.http │ │ │ └── users.http │ │ ├── interfaces │ │ │ ├── auth.interface.ts │ │ │ ├── routes.interface.ts │ │ │ └── users.interface.ts │ │ ├── middlewares │ │ │ ├── auth.middleware.ts │ │ │ ├── error.middleware.ts │ │ │ └── validation.middleware.ts │ │ ├── models │ │ │ └── users.model.ts │ │ ├── routes │ │ │ ├── auth.route.ts │ │ │ └── users.route.ts │ │ ├── server.ts │ │ ├── services │ │ │ ├── auth.service.ts │ │ │ └── users.service.ts │ │ ├── test │ │ │ ├── auth.test.ts │ │ │ └── users.test.ts │ │ └── utils │ │ │ ├── logger.ts │ │ │ └── validateEnv.ts │ ├── swagger.yaml │ └── tsconfig.json ├── mikro-orm │ ├── .dockerignore │ ├── .editorconfig │ ├── .env.development.local │ ├── .env.production.local │ ├── .env.test.local │ ├── .eslintignore │ ├── .eslintrc │ ├── .huskyrc │ ├── .lintstagedrc.json │ ├── .prettierrc │ ├── .swcrc │ ├── .vscode │ │ ├── launch.json │ │ └── settings.json │ ├── Dockerfile.dev │ ├── Dockerfile.prod │ ├── Makefile │ ├── docker-compose.yml │ ├── ecosystem.config.js │ ├── jest.config.js │ ├── nginx.conf │ ├── nodemon.json │ ├── package.json │ ├── src │ │ ├── app.ts │ │ ├── config │ │ │ └── index.ts │ │ ├── controllers │ │ │ ├── auth.controller.ts │ │ │ └── users.controller.ts │ │ ├── database │ │ │ └── index.ts │ │ ├── dtos │ │ │ └── users.dto.ts │ │ ├── entities │ │ │ ├── base.entity.ts │ │ │ └── users.entity.ts │ │ ├── exceptions │ │ │ └── HttpException.ts │ │ ├── http │ │ │ ├── auth.http │ │ │ └── users.http │ │ ├── interfaces │ │ │ ├── auth.interface.ts │ │ │ ├── routes.interface.ts │ │ │ └── users.interface.ts │ │ ├── middlewares │ │ │ ├── auth.middleware.ts │ │ │ ├── error.middleware.ts │ │ │ └── validation.middleware.ts │ │ ├── routes │ │ │ ├── auth.route.ts │ │ │ └── users.route.ts │ │ ├── server.ts │ │ ├── services │ │ │ ├── auth.service.ts │ │ │ └── users.service.ts │ │ ├── test │ │ │ ├── auth.test.ts │ │ │ └── users.test.ts │ │ └── utils │ │ │ ├── logger.ts │ │ │ └── validateEnv.ts │ ├── swagger.yaml │ └── tsconfig.json ├── mongoose │ ├── .dockerignore │ ├── .editorconfig │ ├── .env.development.local │ ├── .env.production.local │ ├── .env.test.local │ ├── .eslintignore │ ├── .eslintrc │ ├── .huskyrc │ ├── .lintstagedrc.json │ ├── .prettierrc │ ├── .swcrc │ ├── .vscode │ │ ├── launch.json │ │ └── settings.json │ ├── Dockerfile.dev │ ├── Dockerfile.prod │ ├── Makefile │ ├── docker-compose.yml │ ├── ecosystem.config.js │ ├── jest.config.js │ ├── nginx.conf │ ├── nodemon.json │ ├── package.json │ ├── src │ │ ├── app.ts │ │ ├── config │ │ │ └── index.ts │ │ ├── controllers │ │ │ ├── auth.controller.ts │ │ │ └── users.controller.ts │ │ ├── database │ │ │ └── index.ts │ │ ├── dtos │ │ │ └── users.dto.ts │ │ ├── exceptions │ │ │ └── HttpException.ts │ │ ├── http │ │ │ ├── auth.http │ │ │ └── users.http │ │ ├── interfaces │ │ │ ├── auth.interface.ts │ │ │ ├── routes.interface.ts │ │ │ └── users.interface.ts │ │ ├── middlewares │ │ │ ├── auth.middleware.ts │ │ │ ├── error.middleware.ts │ │ │ └── validation.middleware.ts │ │ ├── models │ │ │ └── users.model.ts │ │ ├── routes │ │ │ ├── auth.route.ts │ │ │ └── users.route.ts │ │ ├── server.ts │ │ ├── services │ │ │ ├── auth.service.ts │ │ │ └── users.service.ts │ │ ├── test │ │ │ ├── auth.test.ts │ │ │ ├── index.test.ts │ │ │ └── users.test.ts │ │ └── utils │ │ │ ├── logger.ts │ │ │ └── validateEnv.ts │ ├── swagger.yaml │ └── tsconfig.json ├── node-postgres │ ├── .dockerignore │ ├── .editorconfig │ ├── .env.development.local │ ├── .env.production.local │ ├── .env.test.local │ ├── .eslintignore │ ├── .eslintrc │ ├── .huskyrc │ ├── .lintstagedrc.json │ ├── .prettierrc │ ├── .swcrc │ ├── .vscode │ │ ├── launch.json │ │ └── settings.json │ ├── Dockerfile.dev │ ├── Dockerfile.prod │ ├── Makefile │ ├── docker-compose.yml │ ├── ecosystem.config.js │ ├── jest.config.js │ ├── nginx.conf │ ├── nodemon.json │ ├── package.json │ ├── src │ │ ├── app.ts │ │ ├── config │ │ │ └── index.ts │ │ ├── controllers │ │ │ ├── auth.controller.ts │ │ │ └── users.controller.ts │ │ ├── database │ │ │ ├── index.ts │ │ │ └── init.sql │ │ ├── dtos │ │ │ └── users.dto.ts │ │ ├── exceptions │ │ │ └── httpException.ts │ │ ├── http │ │ │ ├── auth.http │ │ │ └── users.http │ │ ├── interfaces │ │ │ ├── auth.interface.ts │ │ │ ├── routes.interface.ts │ │ │ └── users.interface.ts │ │ ├── middlewares │ │ │ ├── auth.middleware.ts │ │ │ ├── error.middleware.ts │ │ │ └── validation.middleware.ts │ │ ├── routes │ │ │ ├── auth.route.ts │ │ │ └── users.route.ts │ │ ├── server.ts │ │ ├── services │ │ │ ├── auth.service.ts │ │ │ └── users.service.ts │ │ ├── test │ │ │ ├── auth.test.ts │ │ │ └── users.test.ts │ │ └── utils │ │ │ ├── logger.ts │ │ │ └── validateEnv.ts │ ├── swagger.yaml │ └── tsconfig.json ├── prisma │ ├── .dockerignore │ ├── .editorconfig │ ├── .env.development.local │ ├── .env.production.local │ ├── .env.test.local │ ├── .eslintignore │ ├── .eslintrc │ ├── .huskyrc │ ├── .lintstagedrc.json │ ├── .prettierrc │ ├── .swcrc │ ├── .vscode │ │ ├── launch.json │ │ └── settings.json │ ├── Dockerfile.dev │ ├── Dockerfile.prod │ ├── Makefile │ ├── docker-compose.yml │ ├── ecosystem.config.js │ ├── jest.config.js │ ├── nginx.conf │ ├── nodemon.json │ ├── package.json │ ├── src │ │ ├── app.ts │ │ ├── config │ │ │ └── index.ts │ │ ├── controllers │ │ │ ├── auth.controller.ts │ │ │ └── users.controller.ts │ │ ├── dtos │ │ │ └── users.dto.ts │ │ ├── exceptions │ │ │ └── HttpException.ts │ │ ├── http │ │ │ ├── auth.http │ │ │ └── users.http │ │ ├── interfaces │ │ │ ├── auth.interface.ts │ │ │ ├── routes.interface.ts │ │ │ └── users.interface.ts │ │ ├── middlewares │ │ │ ├── auth.middleware.ts │ │ │ ├── error.middleware.ts │ │ │ └── validation.middleware.ts │ │ ├── prisma │ │ │ ├── migrations │ │ │ │ ├── 20210314081925_initial │ │ │ │ │ └── migration.sql │ │ │ │ └── migration_lock.toml │ │ │ └── schema.prisma │ │ ├── routes │ │ │ ├── auth.route.ts │ │ │ └── users.route.ts │ │ ├── server.ts │ │ ├── services │ │ │ ├── auth.service.ts │ │ │ └── users.service.ts │ │ ├── test │ │ │ ├── auth.test.ts │ │ │ ├── index.test.ts │ │ │ └── users.test.ts │ │ └── utils │ │ │ ├── logger.ts │ │ │ └── validateEnv.ts │ ├── swagger.yaml │ └── tsconfig.json ├── routing-controllers │ ├── .dockerignore │ ├── .editorconfig │ ├── .env.development.local │ ├── .env.production.local │ ├── .env.test.local │ ├── .eslintignore │ ├── .eslintrc │ ├── .huskyrc │ ├── .lintstagedrc.json │ ├── .prettierrc │ ├── .swcrc │ ├── .vscode │ │ ├── launch.json │ │ └── settings.json │ ├── Dockerfile.dev │ ├── Dockerfile.prod │ ├── Makefile │ ├── docker-compose.yml │ ├── ecosystem.config.js │ ├── jest.config.js │ ├── nginx.conf │ ├── nodemon.json │ ├── package.json │ ├── src │ │ ├── app.ts │ │ ├── config │ │ │ └── index.ts │ │ ├── controllers │ │ │ ├── auth.controller.ts │ │ │ └── users.controller.ts │ │ ├── dtos │ │ │ └── users.dto.ts │ │ ├── exceptions │ │ │ └── HttpException.ts │ │ ├── http │ │ │ ├── auth.http │ │ │ └── users.http │ │ ├── interfaces │ │ │ ├── auth.interface.ts │ │ │ └── users.interface.ts │ │ ├── middlewares │ │ │ ├── auth.middleware.ts │ │ │ ├── error.middleware.ts │ │ │ └── validation.middleware.ts │ │ ├── models │ │ │ └── users.model.ts │ │ ├── server.ts │ │ ├── services │ │ │ ├── auth.service.ts │ │ │ └── users.service.ts │ │ ├── test │ │ │ ├── auth.test.ts │ │ │ └── users.test.ts │ │ └── utils │ │ │ ├── logger.ts │ │ │ └── validateEnv.ts │ └── tsconfig.json ├── sequelize │ ├── .dockerignore │ ├── .editorconfig │ ├── .env.development.local │ ├── .env.production.local │ ├── .env.test.local │ ├── .eslintignore │ ├── .eslintrc │ ├── .huskyrc │ ├── .lintstagedrc.json │ ├── .prettierrc │ ├── .sequelizerc │ ├── .swcrc │ ├── .vscode │ │ ├── launch.json │ │ └── settings.json │ ├── Dockerfile.dev │ ├── Dockerfile.prod │ ├── Makefile │ ├── docker-compose.yml │ ├── docker-entrypoint.sh │ ├── ecosystem.config.js │ ├── jest.config.js │ ├── nginx.conf │ ├── nodemon.json │ ├── package.json │ ├── src │ │ ├── app.ts │ │ ├── config │ │ │ ├── index.ts │ │ │ └── sequelize-cli.js │ │ ├── controllers │ │ │ ├── auth.controller.ts │ │ │ └── users.controller.ts │ │ ├── database │ │ │ ├── index.ts │ │ │ ├── migrations │ │ │ │ └── .gitkeep │ │ │ └── seeders │ │ │ │ └── .gitkeep │ │ ├── dtos │ │ │ └── users.dto.ts │ │ ├── exceptions │ │ │ └── HttpException.ts │ │ ├── http │ │ │ ├── auth.http │ │ │ └── users.http │ │ ├── interfaces │ │ │ ├── auth.interface.ts │ │ │ ├── routes.interface.ts │ │ │ └── users.interface.ts │ │ ├── middlewares │ │ │ ├── auth.middleware.ts │ │ │ ├── error.middleware.ts │ │ │ └── validation.middleware.ts │ │ ├── models │ │ │ └── users.model.ts │ │ ├── routes │ │ │ ├── auth.route.ts │ │ │ └── users.route.ts │ │ ├── server.ts │ │ ├── services │ │ │ ├── auth.service.ts │ │ │ └── users.service.ts │ │ ├── test │ │ │ ├── auth.test.ts │ │ │ └── users.test.ts │ │ └── utils │ │ │ ├── logger.ts │ │ │ └── validateEnv.ts │ ├── swagger.yaml │ └── tsconfig.json ├── starter.js ├── typegoose │ ├── .dockerignore │ ├── .editorconfig │ ├── .env.development.local │ ├── .env.production.local │ ├── .env.test.local │ ├── .eslintignore │ ├── .eslintrc │ ├── .huskyrc │ ├── .lintstagedrc.json │ ├── .prettierrc │ ├── .swcrc │ ├── .vscode │ │ ├── launch.json │ │ └── settings.json │ ├── Dockerfile.dev │ ├── Dockerfile.prod │ ├── Makefile │ ├── docker-compose.yml │ ├── ecosystem.config.js │ ├── jest.config.js │ ├── nginx.conf │ ├── nodemon.json │ ├── package.json │ ├── src │ │ ├── app.ts │ │ ├── config │ │ │ └── index.ts │ │ ├── controllers │ │ │ ├── auth.controller.ts │ │ │ └── users.controller.ts │ │ ├── database │ │ │ └── index.ts │ │ ├── dtos │ │ │ └── users.dto.ts │ │ ├── exceptions │ │ │ └── HttpException.ts │ │ ├── http │ │ │ ├── auth.http │ │ │ └── users.http │ │ ├── interfaces │ │ │ ├── auth.interface.ts │ │ │ ├── routes.interface.ts │ │ │ └── users.interface.ts │ │ ├── middlewares │ │ │ ├── auth.middleware.ts │ │ │ ├── error.middleware.ts │ │ │ └── validation.middleware.ts │ │ ├── models │ │ │ └── users.model.ts │ │ ├── routes │ │ │ ├── auth.route.ts │ │ │ └── users.route.ts │ │ ├── server.ts │ │ ├── services │ │ │ ├── auth.service.ts │ │ │ └── users.service.ts │ │ ├── test │ │ │ ├── auth.test.ts │ │ │ └── users.test.ts │ │ └── utils │ │ │ ├── logger.ts │ │ │ └── validateEnv.ts │ ├── swagger.yaml │ └── tsconfig.json └── typeorm │ ├── .dockerignore │ ├── .editorconfig │ ├── .env.development.local │ ├── .env.production.local │ ├── .env.test.local │ ├── .eslintignore │ ├── .eslintrc │ ├── .huskyrc │ ├── .lintstagedrc.json │ ├── .prettierrc │ ├── .swcrc │ ├── .vscode │ ├── launch.json │ └── settings.json │ ├── Dockerfile.dev │ ├── Dockerfile.prod │ ├── Makefile │ ├── docker-compose.yml │ ├── ecosystem.config.js │ ├── jest.config.js │ ├── nginx.conf │ ├── nodemon.json │ ├── package.json │ ├── src │ ├── app.ts │ ├── config │ │ └── index.ts │ ├── controllers │ │ ├── auth.controller.ts │ │ └── users.controller.ts │ ├── database │ │ ├── index.ts │ │ └── migrations │ │ │ └── .gitkeep │ ├── dtos │ │ └── users.dto.ts │ ├── entities │ │ └── users.entity.ts │ ├── exceptions │ │ └── HttpException.ts │ ├── http │ │ ├── auth.http │ │ └── users.http │ ├── interfaces │ │ ├── auth.interface.ts │ │ ├── routes.interface.ts │ │ └── users.interface.ts │ ├── middlewares │ │ ├── auth.middleware.ts │ │ ├── error.middleware.ts │ │ └── validation.middleware.ts │ ├── routes │ │ ├── auth.route.ts │ │ └── users.route.ts │ ├── server.ts │ ├── services │ │ ├── auth.service.ts │ │ └── users.service.ts │ ├── test │ │ ├── auth.test.ts │ │ └── users.test.ts │ └── utils │ │ ├── logger.ts │ │ └── validateEnv.ts │ ├── swagger.yaml │ └── tsconfig.json └── package.json /.github/ISSUE_TEMPLATE/feature-request---.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Feature Request(기능 요청서) \U0001F4A1" 3 | about: "Suggest an idea for this project" 4 | title: "" 5 | labels: "\U000026A1 Feature" 6 | assignees: "ljlm0402" 7 | --- 8 | 9 | ### Motivation (새로운 기능 설명) 10 | 11 | 12 | 13 | ### Proposed Solution (기능을 통해 얻고자 하는 솔루션) 14 | 15 | 16 | 17 | ### Alternatives (제안 된 솔루션이 더 나은 이유) 18 | 19 | 20 | 21 | ### Additional Context (추가 사항) 22 | 23 | 24 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question---.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Question(문의) \U00002753" 3 | about: "Ask a question about this project" 4 | title: "" 5 | labels: "\U00002754 Question" 6 | assignees: "ljlm0402" 7 | --- 8 | 9 | ### Summary (요약) 10 | 11 | 12 | 13 | ### Additional Details (추가적인 세부 사항) 14 | 15 | 16 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Content (작업 내용) 📝 2 | 3 | 4 | 5 | 6 | ### Screenshot for work content (작업 내용 스크린샷) 📸 7 | 8 | 9 | 10 | 11 | ## Links (링크) 🔗 12 | 13 | - Issue Links (이슈 링크) 14 | 15 | - API Links (API 스팩 문서) 16 | 17 | - Development Links (개발 문서) 18 | 19 | - Document Links (기획 문서) 20 | 21 | - Design Links (디자인 문서) 22 | 23 | ## Etc (기타 사항) 🔖 24 | 25 | 26 | 27 | 28 | ## Check List (체크 사항) ✅ 29 | 30 | 31 | 32 | 33 | - [ ] Issue (이슈) 34 | - [ ] Tests (테스트) 35 | - [ ] Ready to be merged (병합 준비 완료) 36 | - [ ] Added myself to contributors table (기여자 추가) 37 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: npm publish 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - master 7 | paths: 8 | - package.json 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: ⬇️ Checkout source code 15 | uses: actions/checkout@v2 16 | 17 | - name: ⎔ Setup nodejs 18 | uses: actions/setup-node@v1 19 | with: 20 | node-version: 16 21 | registry-url: https://registry.npmjs.org/ 22 | 23 | - name: 🏗 Publish npm 24 | run: npm publish --access public 25 | env: 26 | NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} 27 | 28 | - name: 📤 Send Notification to Slack 29 | uses: 8398a7/action-slack@v2.6.0 30 | with: 31 | status: ${{ job.status }} 32 | author_name: Github Actions 33 | env: 34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 35 | SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} 36 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .github 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 아구몬 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /bin/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /***************************************************************** 4 | * TypeScript Express Starter 5 | * 2019.12.18 ~ 🎮 6 | * Made By AGUMON 🦖 7 | * https://github.com/ljlm0402/typescript-express-starter 8 | *****************************************************************/ 9 | 10 | const path = require("path"); 11 | const starter = require("../lib/starter"); 12 | const destination = getDest(process.argv[2]); 13 | 14 | function getDest(destFolder = "typescript-express-starter") { 15 | return path.join(process.cwd(), destFolder); 16 | } 17 | 18 | starter(destination); 19 | -------------------------------------------------------------------------------- /lib/default/.dockerignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | .vscode 3 | /node_modules 4 | 5 | # code formatter 6 | .eslintrc 7 | .eslintignore 8 | .editorconfig 9 | .huskyrc 10 | .lintstagedrc.json 11 | .prettierrc 12 | 13 | # test 14 | jest.config.js 15 | 16 | # docker 17 | Dockerfile 18 | docker-compose.yml 19 | -------------------------------------------------------------------------------- /lib/default/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /lib/default/.env.development.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # TOKEN 5 | SECRET_KEY = secretKey 6 | 7 | # LOG 8 | LOG_FORMAT = dev 9 | LOG_DIR = ../logs 10 | 11 | # CORS 12 | ORIGIN = * 13 | CREDENTIALS = true 14 | -------------------------------------------------------------------------------- /lib/default/.env.production.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # TOKEN 5 | SECRET_KEY = secretKey 6 | 7 | # LOG 8 | LOG_FORMAT = combined 9 | LOG_DIR = ../logs 10 | 11 | # CORS 12 | ORIGIN = your.domain.com 13 | CREDENTIALS = true 14 | -------------------------------------------------------------------------------- /lib/default/.env.test.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # TOKEN 5 | SECRET_KEY = secretKey 6 | 7 | # LOG 8 | LOG_FORMAT = dev 9 | LOG_DIR = ../logs 10 | 11 | # CORS 12 | ORIGIN = * 13 | CREDENTIALS = true 14 | -------------------------------------------------------------------------------- /lib/default/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist -------------------------------------------------------------------------------- /lib/default/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": ["prettier", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"], 4 | "parserOptions": { 5 | "ecmaVersion": 2018, 6 | "sourceType": "module" 7 | }, 8 | "rules": { 9 | "@typescript-eslint/explicit-member-accessibility": 0, 10 | "@typescript-eslint/explicit-function-return-type": 0, 11 | "@typescript-eslint/no-parameter-properties": 0, 12 | "@typescript-eslint/interface-name-prefix": 0, 13 | "@typescript-eslint/explicit-module-boundary-types": 0, 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/ban-types": "off", 16 | "@typescript-eslint/no-var-requires": "off" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/default/.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "lint-staged" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/default/.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "*.ts": [ 3 | "npm run lint" 4 | ] 5 | } -------------------------------------------------------------------------------- /lib/default/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 150, 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "trailingComma": "all", 6 | "semi": true, 7 | "arrowParens": "avoid" 8 | } -------------------------------------------------------------------------------- /lib/default/.swcrc: -------------------------------------------------------------------------------- 1 | { 2 | "jsc": { 3 | "parser": { 4 | "syntax": "typescript", 5 | "tsx": false, 6 | "dynamicImport": true, 7 | "decorators": true 8 | }, 9 | "transform": { 10 | "legacyDecorator": true, 11 | "decoratorMetadata": true 12 | }, 13 | "target": "es2017", 14 | "externalHelpers": false, 15 | "keepClassNames": true, 16 | "loose": false, 17 | "minify": { 18 | "compress": false, 19 | "mangle": false 20 | }, 21 | "baseUrl": "src", 22 | "paths": { 23 | "@/*": ["*"], 24 | "@config": ["config"], 25 | "@controllers/*": ["controllers/*"], 26 | "@dtos/*": ["dtos/*"], 27 | "@exceptions/*": ["exceptions/*"], 28 | "@interfaces/*": ["interfaces/*"], 29 | "@middlewares/*": ["middlewares/*"], 30 | "@models/*": ["models/*"], 31 | "@routes/*": ["routes/*"], 32 | "@services/*": ["services/*"], 33 | "@utils/*": ["utils/*"] 34 | } 35 | }, 36 | "module": { 37 | "type": "commonjs" 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /lib/default/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "node-terminal", 6 | "request": "launch", 7 | "name": "Dev typescript-express-starter", 8 | "command": "npm run dev" 9 | }, 10 | { 11 | "type": "node-terminal", 12 | "request": "launch", 13 | "name": "Start typescript-express-starter", 14 | "command": "npm run start" 15 | }, 16 | { 17 | "type": "node-terminal", 18 | "request": "launch", 19 | "name": "Test typescript-express-starter", 20 | "command": "npm run test" 21 | }, 22 | { 23 | "type": "node-terminal", 24 | "request": "launch", 25 | "name": "Lint typescript-express-starter", 26 | "command": "npm run lint" 27 | }, 28 | { 29 | "type": "node-terminal", 30 | "request": "launch", 31 | "name": "Lint:Fix typescript-express-starter", 32 | "command": "npm run lint:fix" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /lib/default/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true 4 | }, 5 | "editor.formatOnSave": false 6 | } 7 | -------------------------------------------------------------------------------- /lib/default/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV development 15 | EXPOSE 3000 16 | 17 | # Cmd script 18 | CMD ["npm", "run", "dev"] 19 | -------------------------------------------------------------------------------- /lib/default/Dockerfile.prod: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV production 15 | EXPOSE 3000 16 | 17 | # Cmd script 18 | CMD ["npm", "run", "start"] 19 | -------------------------------------------------------------------------------- /lib/default/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.9" 2 | 3 | services: 4 | proxy: 5 | container_name: proxy 6 | image: nginx:alpine 7 | ports: 8 | - "80:80" 9 | volumes: 10 | - ./nginx.conf:/etc/nginx/nginx.conf 11 | restart: "unless-stopped" 12 | networks: 13 | - backend 14 | 15 | server: 16 | container_name: server 17 | build: 18 | context: ./ 19 | dockerfile: Dockerfile.dev 20 | ports: 21 | - "3000:3000" 22 | volumes: 23 | - ./:/app 24 | - /app/node_modules 25 | restart: 'unless-stopped' 26 | networks: 27 | - backend 28 | 29 | networks: 30 | backend: 31 | driver: bridge 32 | 33 | volumes: 34 | data: 35 | driver: local 36 | -------------------------------------------------------------------------------- /lib/default/jest.config.js: -------------------------------------------------------------------------------- 1 | const { pathsToModuleNameMapper } = require('ts-jest'); 2 | const { compilerOptions } = require('./tsconfig.json'); 3 | 4 | module.exports = { 5 | preset: 'ts-jest', 6 | testEnvironment: 'node', 7 | roots: ['/src'], 8 | transform: { 9 | '^.+\\.tsx?$': 'ts-jest', 10 | }, 11 | moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '/src' }), 12 | }; 13 | -------------------------------------------------------------------------------- /lib/default/nginx.conf: -------------------------------------------------------------------------------- 1 | user nginx; 2 | worker_processes 1; 3 | 4 | error_log /var/log/nginx/error.log warn; 5 | pid /var/run/nginx.pid; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | http { 12 | include /etc/nginx/mime.types; 13 | default_type application/octet-stream; 14 | 15 | upstream api-server { 16 | server server:3000; 17 | keepalive 100; 18 | } 19 | 20 | server { 21 | listen 80; 22 | server_name localhost; 23 | 24 | location / { 25 | proxy_http_version 1.1; 26 | proxy_pass http://api-server; 27 | } 28 | 29 | } 30 | 31 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 32 | '$status $body_bytes_sent "$http_referer" ' 33 | '"$http_user_agent" "$http_x_forwarded_for"'; 34 | 35 | access_log /var/log/nginx/access.log main; 36 | 37 | sendfile on; 38 | keepalive_timeout 65; 39 | include /etc/nginx/conf.d/*.conf; 40 | } 41 | -------------------------------------------------------------------------------- /lib/default/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": [ 3 | "src", 4 | ".env" 5 | ], 6 | "ext": "js,ts,json", 7 | "ignore": [ 8 | "src/logs/*", 9 | "src/**/*.{spec,test}.ts" 10 | ], 11 | "exec": "ts-node -r tsconfig-paths/register --transpile-only src/server.ts" 12 | } -------------------------------------------------------------------------------- /lib/default/src/config/index.ts: -------------------------------------------------------------------------------- 1 | import { config } from 'dotenv'; 2 | config({ path: `.env.${process.env.NODE_ENV || 'development'}.local` }); 3 | 4 | export const CREDENTIALS = process.env.CREDENTIALS === 'true'; 5 | export const { NODE_ENV, PORT, SECRET_KEY, LOG_FORMAT, LOG_DIR, ORIGIN } = process.env; 6 | -------------------------------------------------------------------------------- /lib/default/src/dtos/users.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsEmail, IsString, IsNotEmpty, MinLength, MaxLength } from 'class-validator'; 2 | 3 | export class CreateUserDto { 4 | @IsEmail() 5 | public email: string; 6 | 7 | @IsString() 8 | @IsNotEmpty() 9 | @MinLength(9) 10 | @MaxLength(32) 11 | public password: string; 12 | } 13 | 14 | export class UpdateUserDto { 15 | @IsString() 16 | @IsNotEmpty() 17 | @MinLength(9) 18 | @MaxLength(32) 19 | public password: string; 20 | } 21 | -------------------------------------------------------------------------------- /lib/default/src/exceptions/HttpException.ts: -------------------------------------------------------------------------------- 1 | export class HttpException extends Error { 2 | public status: number; 3 | public message: string; 4 | 5 | constructor(status: number, message: string) { 6 | super(message); 7 | this.status = status; 8 | this.message = message; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/default/src/http/auth.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # User Signup 6 | POST {{ baseURL }}/signup 7 | Content-Type: application/json 8 | 9 | { 10 | "email": "example@email.com", 11 | "password": "password" 12 | } 13 | 14 | ### 15 | # User Login 16 | POST {{ baseURL }}/login 17 | Content-Type: application/json 18 | 19 | { 20 | "email": "example@email.com", 21 | "password": "password" 22 | } 23 | 24 | ### 25 | # User Logout 26 | POST {{ baseURL }}/logout 27 | Content-Type: application/json 28 | -------------------------------------------------------------------------------- /lib/default/src/http/users.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # Find All Users 6 | GET {{ baseURL }}/users 7 | 8 | ### 9 | # Find User By Id 10 | GET {{ baseURL }}/users/1 11 | 12 | ### 13 | # Create User 14 | POST {{ baseURL }}/users 15 | Content-Type: application/json 16 | 17 | { 18 | "email": "example@email.com", 19 | "password": "password" 20 | } 21 | 22 | ### 23 | # Modify User By Id 24 | PUT {{ baseURL }}/users/1 25 | Content-Type: application/json 26 | 27 | { 28 | "email": "example@email.com", 29 | "password": "password" 30 | } 31 | 32 | ### 33 | # Delete User By Id 34 | DELETE {{ baseURL }}/users/1 35 | -------------------------------------------------------------------------------- /lib/default/src/interfaces/auth.interface.ts: -------------------------------------------------------------------------------- 1 | import { Request } from 'express'; 2 | import { User } from '@interfaces/users.interface'; 3 | 4 | export interface DataStoredInToken { 5 | id: number; 6 | } 7 | 8 | export interface TokenData { 9 | token: string; 10 | expiresIn: number; 11 | } 12 | 13 | export interface RequestWithUser extends Request { 14 | user: User; 15 | } 16 | -------------------------------------------------------------------------------- /lib/default/src/interfaces/routes.interface.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | 3 | export interface Routes { 4 | path?: string; 5 | router: Router; 6 | } 7 | -------------------------------------------------------------------------------- /lib/default/src/interfaces/users.interface.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | id?: number; 3 | email?: string; 4 | password: string; 5 | } 6 | -------------------------------------------------------------------------------- /lib/default/src/middlewares/error.middleware.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from 'express'; 2 | import { HttpException } from '@exceptions/httpException'; 3 | import { logger } from '@utils/logger'; 4 | 5 | export const ErrorMiddleware = (error: HttpException, req: Request, res: Response, next: NextFunction) => { 6 | try { 7 | const status: number = error.status || 500; 8 | const message: string = error.message || 'Something went wrong'; 9 | 10 | logger.error(`[${req.method}] ${req.path} >> StatusCode:: ${status}, Message:: ${message}`); 11 | res.status(status).json({ message }); 12 | } catch (error) { 13 | next(error); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /lib/default/src/models/users.model.ts: -------------------------------------------------------------------------------- 1 | import { User } from '@interfaces/users.interface'; 2 | 3 | // password: password123456789 4 | export const UserModel: User[] = [ 5 | { id: 1, email: 'example1@email.com', password: '$2b$10$2YC2ht8x06Yto5VAr08kben8.oxjTPrMn0yJhv8xxSVVltH3bOs4u' }, 6 | { id: 2, email: 'example2@email.com', password: '$2b$10$2YC2ht8x06Yto5VAr08kben8.oxjTPrMn0yJhv8xxSVVltH3bOs4u' }, 7 | { id: 3, email: 'example3@email.com', password: '$2b$10$2YC2ht8x06Yto5VAr08kben8.oxjTPrMn0yJhv8xxSVVltH3bOs4u' }, 8 | { id: 4, email: 'example4@email.com', password: '$2b$10$2YC2ht8x06Yto5VAr08kben8.oxjTPrMn0yJhv8xxSVVltH3bOs4u' }, 9 | ]; 10 | -------------------------------------------------------------------------------- /lib/default/src/routes/auth.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { AuthController } from '@controllers/auth.controller'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { AuthMiddleware } from '@middlewares/auth.middleware'; 6 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 7 | 8 | export class AuthRoute implements Routes { 9 | public router = Router(); 10 | public auth = new AuthController(); 11 | 12 | constructor() { 13 | this.initializeRoutes(); 14 | } 15 | 16 | private initializeRoutes() { 17 | this.router.post('/signup', ValidationMiddleware(CreateUserDto), this.auth.signUp); 18 | this.router.post('/login', ValidationMiddleware(CreateUserDto), this.auth.logIn); 19 | this.router.post('/logout', AuthMiddleware, this.auth.logOut); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/default/src/routes/users.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { UserController } from '@controllers/users.controller'; 3 | import { CreateUserDto, UpdateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 6 | 7 | export class UserRoute implements Routes { 8 | public path = '/users'; 9 | public router = Router(); 10 | public user = new UserController(); 11 | 12 | constructor() { 13 | this.initializeRoutes(); 14 | } 15 | 16 | private initializeRoutes() { 17 | this.router.get(`${this.path}`, this.user.getUsers); 18 | this.router.get(`${this.path}/:id(\\d+)`, this.user.getUserById); 19 | this.router.post(`${this.path}`, ValidationMiddleware(CreateUserDto), this.user.createUser); 20 | this.router.put(`${this.path}/:id(\\d+)`, ValidationMiddleware(UpdateUserDto), this.user.updateUser); 21 | this.router.delete(`${this.path}/:id(\\d+)`, this.user.deleteUser); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/default/src/server.ts: -------------------------------------------------------------------------------- 1 | import { App } from '@/app'; 2 | import { AuthRoute } from '@routes/auth.route'; 3 | import { UserRoute } from '@routes/users.route'; 4 | import { ValidateEnv } from '@utils/validateEnv'; 5 | 6 | ValidateEnv(); 7 | 8 | const app = new App([new UserRoute(), new AuthRoute()]); 9 | 10 | app.listen(); 11 | -------------------------------------------------------------------------------- /lib/default/src/utils/validateEnv.ts: -------------------------------------------------------------------------------- 1 | import { cleanEnv, port, str } from 'envalid'; 2 | 3 | export const ValidateEnv = () => { 4 | cleanEnv(process.env, { 5 | NODE_ENV: str(), 6 | PORT: port(), 7 | }); 8 | }; 9 | -------------------------------------------------------------------------------- /lib/graphql/.dockerignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | .vscode 3 | /node_modules 4 | 5 | # code formatter 6 | .eslintrc 7 | .eslintignore 8 | .editorconfig 9 | .huskyrc 10 | .lintstagedrc.json 11 | .prettierrc 12 | 13 | # test 14 | jest.config.js 15 | 16 | # docker 17 | Dockerfile 18 | docker-compose.yml 19 | -------------------------------------------------------------------------------- /lib/graphql/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /lib/graphql/.env.development.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | POSTGRES_USER = root 6 | POSTGRES_PASSWORD = password 7 | POSTGRES_HOST = localhost 8 | POSTGRES_PORT = 5432 9 | POSTGRES_DB = dev 10 | 11 | # TOKEN 12 | SECRET_KEY = secretKey 13 | 14 | # LOG 15 | LOG_FORMAT = dev 16 | LOG_DIR = ../logs 17 | 18 | # CORS 19 | ORIGIN = * 20 | CREDENTIALS = true 21 | -------------------------------------------------------------------------------- /lib/graphql/.env.production.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | POSTGRES_USER = root 6 | POSTGRES_PASSWORD = password 7 | POSTGRES_HOST = localhost 8 | POSTGRES_PORT = 5432 9 | POSTGRES_DB = dev 10 | 11 | # TOKEN 12 | SECRET_KEY = secretKey 13 | 14 | # LOG 15 | LOG_FORMAT = combined 16 | LOG_DIR = ../logs 17 | 18 | # CORS 19 | ORIGIN = your.domain.com 20 | CREDENTIALS = true 21 | -------------------------------------------------------------------------------- /lib/graphql/.env.test.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | POSTGRES_USER = root 6 | POSTGRES_PASSWORD = password 7 | POSTGRES_HOST = localhost 8 | POSTGRES_PORT = 5432 9 | POSTGRES_DB = dev 10 | 11 | # TOKEN 12 | SECRET_KEY = secretKey 13 | 14 | # LOG 15 | LOG_FORMAT = dev 16 | LOG_DIR = ../logs 17 | 18 | # CORS 19 | ORIGIN = * 20 | CREDENTIALS = true 21 | -------------------------------------------------------------------------------- /lib/graphql/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist -------------------------------------------------------------------------------- /lib/graphql/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": ["prettier", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"], 4 | "parserOptions": { 5 | "ecmaVersion": 2018, 6 | "sourceType": "module" 7 | }, 8 | "rules": { 9 | "@typescript-eslint/explicit-member-accessibility": 0, 10 | "@typescript-eslint/explicit-function-return-type": 0, 11 | "@typescript-eslint/no-parameter-properties": 0, 12 | "@typescript-eslint/interface-name-prefix": 0, 13 | "@typescript-eslint/explicit-module-boundary-types": 0, 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/ban-types": "off", 16 | "@typescript-eslint/no-var-requires": "off" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/graphql/.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "lint-staged" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/graphql/.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "*.ts": [ 3 | "npm run lint" 4 | ] 5 | } -------------------------------------------------------------------------------- /lib/graphql/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 150, 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "trailingComma": "all", 6 | "semi": true, 7 | "arrowParens": "avoid" 8 | } -------------------------------------------------------------------------------- /lib/graphql/.swcrc: -------------------------------------------------------------------------------- 1 | { 2 | "jsc": { 3 | "parser": { 4 | "syntax": "typescript", 5 | "tsx": false, 6 | "dynamicImport": true, 7 | "decorators": true 8 | }, 9 | "transform": { 10 | "legacyDecorator": true, 11 | "decoratorMetadata": true 12 | }, 13 | "target": "es2017", 14 | "externalHelpers": false, 15 | "keepClassNames": true, 16 | "loose": false, 17 | "minify": { 18 | "compress": false, 19 | "mangle": false 20 | }, 21 | "baseUrl": "src", 22 | "paths": { 23 | "@/*": ["*"], 24 | "@config": ["config"], 25 | "@database": ["database"], 26 | "@dtos/*": ["dtos/*"], 27 | "@entities/*": ["entities/*"], 28 | "@exceptions/*": ["exceptions/*"], 29 | "@interfaces/*": ["interfaces/*"], 30 | "@middlewares/*": ["middlewares/*"], 31 | "@repositories/*": ["repositories/*"], 32 | "@resolvers/*": ["resolvers/*"], 33 | "@typedefs/*": ["typedefs/*"], 34 | "@utils/*": ["utils/*"] 35 | } 36 | }, 37 | "module": { 38 | "type": "commonjs" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/graphql/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "node-terminal", 6 | "request": "launch", 7 | "name": "Dev typescript-express-starter", 8 | "command": "npm run dev" 9 | }, 10 | { 11 | "type": "node-terminal", 12 | "request": "launch", 13 | "name": "Start typescript-express-starter", 14 | "command": "npm run start" 15 | }, 16 | { 17 | "type": "node-terminal", 18 | "request": "launch", 19 | "name": "Test typescript-express-starter", 20 | "command": "npm run test" 21 | }, 22 | { 23 | "type": "node-terminal", 24 | "request": "launch", 25 | "name": "Lint typescript-express-starter", 26 | "command": "npm run lint" 27 | }, 28 | { 29 | "type": "node-terminal", 30 | "request": "launch", 31 | "name": "Lint:Fix typescript-express-starter", 32 | "command": "npm run lint:fix" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /lib/graphql/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true 4 | }, 5 | "editor.formatOnSave": false 6 | } 7 | -------------------------------------------------------------------------------- /lib/graphql/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV development 15 | 16 | EXPOSE 3000 17 | 18 | # Cmd script 19 | CMD ["npm", "run", "dev"] 20 | -------------------------------------------------------------------------------- /lib/graphql/Dockerfile.prod: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV production 15 | 16 | EXPOSE 3000 17 | 18 | # Cmd script 19 | CMD ["npm", "run", "start"] 20 | -------------------------------------------------------------------------------- /lib/graphql/jest.config.js: -------------------------------------------------------------------------------- 1 | const { pathsToModuleNameMapper } = require('ts-jest'); 2 | const { compilerOptions } = require('./tsconfig.json'); 3 | 4 | module.exports = { 5 | preset: 'ts-jest', 6 | testEnvironment: 'node', 7 | roots: ['/src'], 8 | transform: { 9 | '^.+\\.tsx?$': 'ts-jest', 10 | }, 11 | moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '/src' }), 12 | }; 13 | -------------------------------------------------------------------------------- /lib/graphql/nginx.conf: -------------------------------------------------------------------------------- 1 | user nginx; 2 | worker_processes 1; 3 | 4 | error_log /var/log/nginx/error.log warn; 5 | pid /var/run/nginx.pid; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | http { 12 | include /etc/nginx/mime.types; 13 | default_type application/octet-stream; 14 | 15 | upstream api-server { 16 | server server:3000; 17 | keepalive 100; 18 | } 19 | 20 | server { 21 | listen 80; 22 | server_name localhost; 23 | 24 | location / { 25 | proxy_http_version 1.1; 26 | proxy_pass http://api-server; 27 | } 28 | 29 | } 30 | 31 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 32 | '$status $body_bytes_sent "$http_referer" ' 33 | '"$http_user_agent" "$http_x_forwarded_for"'; 34 | 35 | access_log /var/log/nginx/access.log main; 36 | 37 | sendfile on; 38 | keepalive_timeout 65; 39 | include /etc/nginx/conf.d/*.conf; 40 | } 41 | -------------------------------------------------------------------------------- /lib/graphql/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": [ 3 | "src", 4 | ".env" 5 | ], 6 | "ext": "js,ts,json", 7 | "ignore": [ 8 | "src/logs/*", 9 | "src/**/*.{spec,test}.ts" 10 | ], 11 | "exec": "ts-node -r tsconfig-paths/register --transpile-only src/server.ts" 12 | } -------------------------------------------------------------------------------- /lib/graphql/src/config/index.ts: -------------------------------------------------------------------------------- 1 | import { config } from 'dotenv'; 2 | config({ path: `.env.${process.env.NODE_ENV || 'development'}.local` }); 3 | 4 | export const CREDENTIALS = process.env.CREDENTIALS === 'true'; 5 | export const { NODE_ENV, PORT, SECRET_KEY, LOG_FORMAT, LOG_DIR, ORIGIN } = process.env; 6 | export const { POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DB } = process.env; 7 | -------------------------------------------------------------------------------- /lib/graphql/src/database/index.ts: -------------------------------------------------------------------------------- 1 | import { join } from 'path'; 2 | import { createConnection, ConnectionOptions } from 'typeorm'; 3 | import { POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DB } from '@config'; 4 | 5 | export const dbConnection = async () => { 6 | const dbConfig: ConnectionOptions = { 7 | type: 'postgres', 8 | username: POSTGRES_USER, 9 | password: POSTGRES_PASSWORD, 10 | host: POSTGRES_HOST, 11 | port: Number(POSTGRES_PORT), 12 | database: POSTGRES_DB, 13 | synchronize: true, 14 | logging: false, 15 | entities: [join(__dirname, '../**/*.entity{.ts,.js}')], 16 | migrations: [join(__dirname, '../**/*.migration{.ts,.js}')], 17 | subscribers: [join(__dirname, '../**/*.subscriber{.ts,.js}')], 18 | cli: { 19 | entitiesDir: 'src/entities', 20 | migrationsDir: 'src/migration', 21 | subscribersDir: 'src/subscriber', 22 | }, 23 | }; 24 | 25 | await createConnection(dbConfig); 26 | } 27 | -------------------------------------------------------------------------------- /lib/graphql/src/dtos/users.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsEmail, IsString, IsNotEmpty, MinLength, MaxLength } from 'class-validator'; 2 | import { InputType, Field } from 'type-graphql'; 3 | import { User } from '@typedefs/users.type'; 4 | 5 | @InputType() 6 | export class CreateUserDto implements Partial { 7 | @Field() 8 | @IsEmail() 9 | email: string; 10 | 11 | @Field() 12 | @IsString() 13 | @IsNotEmpty() 14 | @MinLength(9) 15 | @MaxLength(32) 16 | password: string; 17 | } 18 | 19 | @InputType() 20 | export class UpdateUserDto implements Partial { 21 | @Field() 22 | @IsString() 23 | @IsNotEmpty() 24 | @MinLength(9) 25 | @MaxLength(32) 26 | password: string; 27 | } 28 | -------------------------------------------------------------------------------- /lib/graphql/src/entities/users.entity.ts: -------------------------------------------------------------------------------- 1 | import { IsNotEmpty } from 'class-validator'; 2 | import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, Unique, CreateDateColumn, UpdateDateColumn } from 'typeorm'; 3 | import { User } from '@interfaces/users.interface'; 4 | 5 | @Entity() 6 | export class UserEntity extends BaseEntity implements User { 7 | @PrimaryGeneratedColumn() 8 | id: number; 9 | 10 | @Column() 11 | @IsNotEmpty() 12 | @Unique(['email']) 13 | email: string; 14 | 15 | @Column() 16 | @IsNotEmpty() 17 | password: string; 18 | 19 | @Column() 20 | @CreateDateColumn() 21 | createdAt: Date; 22 | 23 | @Column() 24 | @UpdateDateColumn() 25 | updatedAt: Date; 26 | } 27 | -------------------------------------------------------------------------------- /lib/graphql/src/exceptions/HttpException.ts: -------------------------------------------------------------------------------- 1 | export class HttpException extends Error { 2 | public status: number; 3 | public message: string; 4 | 5 | constructor(status: number, message: string) { 6 | super(message); 7 | this.status = status; 8 | this.message = message; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/graphql/src/http/auth.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000/graphql 3 | 4 | ### 5 | # User Signup 6 | POST {{ baseURL }} 7 | Content-Type: application/json 8 | X-REQUEST-TYPE: GraphQL 9 | 10 | mutation { 11 | signup (userData: { 12 | email: "example@email.com", 13 | password: "password" 14 | }) { 15 | id, 16 | email, 17 | password 18 | } 19 | } 20 | 21 | ### 22 | # User Login 23 | POST {{ baseURL }} 24 | Content-Type: application/json 25 | X-REQUEST-TYPE: GraphQL 26 | 27 | mutation { 28 | login (userData: { 29 | email: "example@email.com", 30 | password: "password" 31 | }) { 32 | email, 33 | password 34 | } 35 | } 36 | 37 | ### 38 | # User Logout 39 | POST {{ baseURL }} 40 | Content-Type: application/json 41 | X-REQUEST-TYPE: GraphQL 42 | Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MiwiaWF0IjoxNjM5MDQ3MjM3LCJleHAiOjE2MzkwNTA4Mzd9.HD0AvZl1s-mycKxo0IJ1QT-oSKhjeArXrlNBffZUanY; 43 | 44 | mutation { 45 | logout { 46 | email, 47 | password 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/graphql/src/interfaces/auth.interface.ts: -------------------------------------------------------------------------------- 1 | import { User } from '@interfaces/users.interface'; 2 | 3 | export interface DataStoredInToken { 4 | id: number; 5 | } 6 | 7 | export interface TokenData { 8 | token: string; 9 | expiresIn: number; 10 | } 11 | 12 | export interface RequestWithUser { 13 | user: User; 14 | } 15 | -------------------------------------------------------------------------------- /lib/graphql/src/interfaces/users.interface.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | id?: number; 3 | email?: string; 4 | password: string; 5 | } 6 | -------------------------------------------------------------------------------- /lib/graphql/src/middlewares/error.middleware.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from 'express'; 2 | import { HttpException } from '@exceptions/httpException'; 3 | import { logger } from '@utils/logger'; 4 | 5 | export const ErrorMiddleware = (error: HttpException, req: Request, res: Response, next: NextFunction) => { 6 | try { 7 | const status: number = error.status || 500; 8 | const message: string = error.message || 'Something went wrong'; 9 | 10 | logger.error(`[${req.method}] ${req.path} >> StatusCode:: ${status}, Message:: ${message}`); 11 | res.status(status).json({ message }); 12 | } catch (error) { 13 | next(error); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /lib/graphql/src/resolvers/auth.resolver.ts: -------------------------------------------------------------------------------- 1 | import { Authorized, Arg, Ctx, Mutation, Resolver } from 'type-graphql'; 2 | import { CreateUserDto } from '@dtos/users.dto'; 3 | import { AuthRepository } from '@repositories/auth.repository'; 4 | import { User } from '@typedefs/users.type'; 5 | 6 | @Resolver() 7 | export class AuthResolver extends AuthRepository { 8 | @Mutation(() => User, { 9 | description: 'User signup', 10 | }) 11 | async signup(@Arg('userData') userData: CreateUserDto): Promise { 12 | const user: User = await this.userSignUp(userData); 13 | return user; 14 | } 15 | 16 | @Mutation(() => User, { 17 | description: 'User login', 18 | }) 19 | async login(@Arg('userData') userData: CreateUserDto): Promise { 20 | const { findUser } = await this.userLogIn(userData); 21 | return findUser; 22 | } 23 | 24 | @Authorized() 25 | @Mutation(() => User, { 26 | description: 'User logout', 27 | }) 28 | async logout(@Ctx('user') userData: any): Promise { 29 | const user = await this.userLogOut(userData); 30 | return user; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/graphql/src/server.ts: -------------------------------------------------------------------------------- 1 | import { App } from '@/app'; 2 | import { AuthResolver } from '@resolvers/auth.resolver'; 3 | import { UserResolver } from '@resolvers/users.resolver'; 4 | import { ValidateEnv } from '@utils/validateEnv'; 5 | 6 | ValidateEnv(); 7 | 8 | const app = new App([AuthResolver, UserResolver]); 9 | 10 | app.listen(); 11 | -------------------------------------------------------------------------------- /lib/graphql/src/test/auth.test.ts: -------------------------------------------------------------------------------- 1 | import request from 'supertest'; 2 | import { App } from '@/app'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | 5 | afterAll(async () => { 6 | await new Promise(resolve => setTimeout(() => resolve(), 500)); 7 | }); 8 | 9 | describe('Testing Auth', () => { 10 | }); 11 | -------------------------------------------------------------------------------- /lib/graphql/src/test/users.test.ts: -------------------------------------------------------------------------------- 1 | import request from 'supertest'; 2 | import { App } from '@app'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { User } from '@interfaces/users.interface'; 5 | 6 | afterAll(async () => { 7 | await new Promise(resolve => setTimeout(() => resolve(), 500)); 8 | }); 9 | 10 | describe('Testing Users', () => { 11 | }); 12 | -------------------------------------------------------------------------------- /lib/graphql/src/typedefs/users.type.ts: -------------------------------------------------------------------------------- 1 | import { Field, ObjectType } from 'type-graphql'; 2 | 3 | @ObjectType() 4 | export class User { 5 | @Field() 6 | id?: number; 7 | 8 | @Field() 9 | email?: string; 10 | 11 | @Field() 12 | password: string; 13 | } 14 | -------------------------------------------------------------------------------- /lib/graphql/src/utils/validateEnv.ts: -------------------------------------------------------------------------------- 1 | import { cleanEnv, port, str } from 'envalid'; 2 | 3 | export const ValidateEnv = () => { 4 | cleanEnv(process.env, { 5 | NODE_ENV: str(), 6 | PORT: port(), 7 | }); 8 | }; 9 | -------------------------------------------------------------------------------- /lib/knex/.dockerignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | .vscode 3 | /node_modules 4 | 5 | # code formatter 6 | .eslintrc 7 | .eslintignore 8 | .editorconfig 9 | .huskyrc 10 | .lintstagedrc.json 11 | .prettierrc 12 | 13 | # test 14 | jest.config.js 15 | 16 | # docker 17 | Dockerfile 18 | docker-compose.yml 19 | -------------------------------------------------------------------------------- /lib/knex/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /lib/knex/.env.development.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DB_USER = root 6 | DB_PASSWORD = password 7 | DB_HOST = localhost 8 | DB_PORT = 3306 9 | DB_DATABASE = dev 10 | 11 | # TOKEN 12 | SECRET_KEY = secretKey 13 | 14 | # LOG 15 | LOG_FORMAT = dev 16 | LOG_DIR = ../logs 17 | 18 | # CORS 19 | ORIGIN = * 20 | CREDENTIALS = true 21 | -------------------------------------------------------------------------------- /lib/knex/.env.production.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DB_USER = root 6 | DB_PASSWORD = password 7 | DB_HOST = localhost 8 | DB_PORT = 3306 9 | DB_DATABASE = dev 10 | 11 | # TOKEN 12 | SECRET_KEY = secretKey 13 | 14 | # LOG 15 | LOG_FORMAT = combined 16 | LOG_DIR = ../logs 17 | 18 | # CORS 19 | ORIGIN = your.domain.com 20 | CREDENTIALS = true 21 | -------------------------------------------------------------------------------- /lib/knex/.env.test.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DB_USER = root 6 | DB_PASSWORD = password 7 | DB_HOST = localhost 8 | DB_PORT = 3306 9 | DB_DATABASE = dev 10 | 11 | # TOKEN 12 | SECRET_KEY = secretKey 13 | 14 | # LOG 15 | LOG_FORMAT = dev 16 | LOG_DIR = ../logs 17 | 18 | # CORS 19 | ORIGIN = * 20 | CREDENTIALS = true 21 | -------------------------------------------------------------------------------- /lib/knex/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist -------------------------------------------------------------------------------- /lib/knex/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": ["prettier", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"], 4 | "parserOptions": { 5 | "ecmaVersion": 2018, 6 | "sourceType": "module" 7 | }, 8 | "rules": { 9 | "@typescript-eslint/explicit-member-accessibility": 0, 10 | "@typescript-eslint/explicit-function-return-type": 0, 11 | "@typescript-eslint/no-parameter-properties": 0, 12 | "@typescript-eslint/interface-name-prefix": 0, 13 | "@typescript-eslint/explicit-module-boundary-types": 0, 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/ban-types": "off", 16 | "@typescript-eslint/no-var-requires": "off" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/knex/.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "lint-staged" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/knex/.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "*.ts": [ 3 | "npm run lint" 4 | ] 5 | } -------------------------------------------------------------------------------- /lib/knex/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 150, 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "trailingComma": "all", 6 | "semi": true, 7 | "arrowParens": "avoid" 8 | } -------------------------------------------------------------------------------- /lib/knex/.swcrc: -------------------------------------------------------------------------------- 1 | { 2 | "jsc": { 3 | "parser": { 4 | "syntax": "typescript", 5 | "tsx": false, 6 | "dynamicImport": true, 7 | "decorators": true 8 | }, 9 | "transform": { 10 | "legacyDecorator": true, 11 | "decoratorMetadata": true 12 | }, 13 | "target": "es2017", 14 | "externalHelpers": false, 15 | "keepClassNames": true, 16 | "loose": false, 17 | "minify": { 18 | "compress": false, 19 | "mangle": false 20 | }, 21 | "baseUrl": "src", 22 | "paths": { 23 | "@/*": ["*"], 24 | "@config": ["config"], 25 | "@controllers/*": ["controllers/*"], 26 | "@database": ["database"], 27 | "@dtos/*": ["dtos/*"], 28 | "@exceptions/*": ["exceptions/*"], 29 | "@interfaces/*": ["interfaces/*"], 30 | "@middlewares/*": ["middlewares/*"], 31 | "@models/*": ["models/*"], 32 | "@routes/*": ["routes/*"], 33 | "@services/*": ["services/*"], 34 | "@utils/*": ["utils/*"] 35 | } 36 | }, 37 | "module": { 38 | "type": "commonjs" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/knex/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "node-terminal", 6 | "request": "launch", 7 | "name": "Dev typescript-express-starter", 8 | "command": "npm run dev" 9 | }, 10 | { 11 | "type": "node-terminal", 12 | "request": "launch", 13 | "name": "Start typescript-express-starter", 14 | "command": "npm run start" 15 | }, 16 | { 17 | "type": "node-terminal", 18 | "request": "launch", 19 | "name": "Test typescript-express-starter", 20 | "command": "npm run test" 21 | }, 22 | { 23 | "type": "node-terminal", 24 | "request": "launch", 25 | "name": "Lint typescript-express-starter", 26 | "command": "npm run lint" 27 | }, 28 | { 29 | "type": "node-terminal", 30 | "request": "launch", 31 | "name": "Lint:Fix typescript-express-starter", 32 | "command": "npm run lint:fix" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /lib/knex/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true 4 | }, 5 | "editor.formatOnSave": false 6 | } 7 | -------------------------------------------------------------------------------- /lib/knex/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV development 15 | 16 | EXPOSE 3000 17 | 18 | # Cmd script 19 | CMD ["npm", "run", "dev"] 20 | -------------------------------------------------------------------------------- /lib/knex/Dockerfile.prod: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV production 15 | 16 | EXPOSE 3000 17 | 18 | # Cmd script 19 | CMD ["npm", "run", "start"] 20 | -------------------------------------------------------------------------------- /lib/knex/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.9" 2 | 3 | services: 4 | proxy: 5 | container_name: proxy 6 | image: nginx:alpine 7 | ports: 8 | - "80:80" 9 | volumes: 10 | - ./nginx.conf:/etc/nginx/nginx.conf 11 | restart: "unless-stopped" 12 | networks: 13 | - backend 14 | 15 | server: 16 | container_name: server 17 | build: 18 | context: ./ 19 | dockerfile: Dockerfile.dev 20 | ports: 21 | - "3000:3000" 22 | environment: 23 | DB_USER: root 24 | DB_PASSWORD: password 25 | DB_DATABASE: dev 26 | volumes: 27 | - ./:/app 28 | - /app/node_modules 29 | restart: "unless-stopped" 30 | networks: 31 | - backend 32 | links: 33 | - mysql 34 | depends_on: 35 | - mysql 36 | 37 | mysql: 38 | container_name: mysql 39 | image: mysql:5.7 40 | environment: 41 | DB_USER: root 42 | DB_PASSWORD: password 43 | DB_DATABASE: dev 44 | ports: 45 | - "3306:3306" 46 | networks: 47 | - backend 48 | 49 | networks: 50 | backend: 51 | driver: bridge 52 | 53 | volumes: 54 | data: 55 | driver: local 56 | -------------------------------------------------------------------------------- /lib/knex/jest.config.js: -------------------------------------------------------------------------------- 1 | const { pathsToModuleNameMapper } = require('ts-jest'); 2 | const { compilerOptions } = require('./tsconfig.json'); 3 | 4 | module.exports = { 5 | preset: 'ts-jest', 6 | testEnvironment: 'node', 7 | roots: ['/src'], 8 | transform: { 9 | '^.+\\.tsx?$': 'ts-jest', 10 | }, 11 | moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '/src' }), 12 | }; 13 | -------------------------------------------------------------------------------- /lib/knex/knexfile.ts: -------------------------------------------------------------------------------- 1 | import { DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_DATABASE } from './src/config'; 2 | 3 | export const dbConfig = { 4 | client: 'mysql', 5 | connection: { 6 | charset: 'utf8', 7 | timezone: 'UTC', 8 | user: DB_USER, 9 | password: DB_PASSWORD, 10 | host: DB_HOST, 11 | port: DB_PORT, 12 | database: DB_DATABASE, 13 | }, 14 | migrations: { 15 | directory: 'src/database/migrations', 16 | tableName: 'migrations', 17 | // stub: 'src/database/stubs', 18 | }, 19 | seeds: { 20 | directory: 'src/database/seeds', 21 | // stub: 'src/database/stubs', 22 | }, 23 | }; 24 | -------------------------------------------------------------------------------- /lib/knex/nginx.conf: -------------------------------------------------------------------------------- 1 | user nginx; 2 | worker_processes 1; 3 | 4 | error_log /var/log/nginx/error.log warn; 5 | pid /var/run/nginx.pid; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | http { 12 | include /etc/nginx/mime.types; 13 | default_type application/octet-stream; 14 | 15 | upstream api-server { 16 | server server:3000; 17 | keepalive 100; 18 | } 19 | 20 | server { 21 | listen 80; 22 | server_name localhost; 23 | 24 | location / { 25 | proxy_http_version 1.1; 26 | proxy_pass http://api-server; 27 | } 28 | 29 | } 30 | 31 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 32 | '$status $body_bytes_sent "$http_referer" ' 33 | '"$http_user_agent" "$http_x_forwarded_for"'; 34 | 35 | access_log /var/log/nginx/access.log main; 36 | 37 | sendfile on; 38 | keepalive_timeout 65; 39 | include /etc/nginx/conf.d/*.conf; 40 | } 41 | -------------------------------------------------------------------------------- /lib/knex/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": [ 3 | "src", 4 | ".env" 5 | ], 6 | "ext": "js,ts,json", 7 | "ignore": [ 8 | "src/logs/*", 9 | "src/**/*.{spec,test}.ts" 10 | ], 11 | "exec": "ts-node -r tsconfig-paths/register --transpile-only src/server.ts" 12 | } -------------------------------------------------------------------------------- /lib/knex/src/config/index.ts: -------------------------------------------------------------------------------- 1 | import { config } from 'dotenv'; 2 | config({ path: `.env.${process.env.NODE_ENV || 'development'}.local` }); 3 | 4 | export const CREDENTIALS = process.env.CREDENTIALS === 'true'; 5 | export const { NODE_ENV, PORT, SECRET_KEY, LOG_FORMAT, LOG_DIR, ORIGIN } = process.env; 6 | export const { DB_USER, DB_PASSWORD, DB_HOST, DB_PORT, DB_DATABASE } = process.env; 7 | -------------------------------------------------------------------------------- /lib/knex/src/database/index.ts: -------------------------------------------------------------------------------- 1 | import { Model } from 'objection'; 2 | import Knex from 'knex'; 3 | import { DB_USER, DB_PASSWORD, DB_HOST, DB_PORT, DB_DATABASE } from '@config'; 4 | 5 | export const dbConnection = async () => { 6 | const dbConfig = { 7 | client: 'mysql', 8 | connection: { 9 | charset: 'utf8', 10 | timezone: 'UTC', 11 | user: DB_USER, 12 | password: DB_PASSWORD, 13 | host: DB_HOST, 14 | port: DB_PORT, 15 | database: DB_DATABASE, 16 | }, 17 | pool: { 18 | min: 2, 19 | max: 10, 20 | }, 21 | }; 22 | 23 | await Model.knex(Knex(dbConfig)); 24 | }; 25 | -------------------------------------------------------------------------------- /lib/knex/src/database/migrations/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljlm0402/typescript-express-starter/572dfd9bfdfc3b3f3e9e55b834be73445b1acf9a/lib/knex/src/database/migrations/.gitkeep -------------------------------------------------------------------------------- /lib/knex/src/database/migrations/20210713110926_initial.ts: -------------------------------------------------------------------------------- 1 | import { Knex } from 'knex'; 2 | 3 | const up = (knex: Knex): Promise => { 4 | return knex.schema.createTable('users', table => { 5 | table.bigIncrements('id').unsigned().primary(); 6 | table.string('email', 45).notNullable(); 7 | table.string('password', 255).notNullable(); 8 | table.timestamp('createdAt').defaultTo(knex.fn.now()); 9 | table.timestamp('updatedAt').defaultTo(knex.fn.now()); 10 | }); 11 | }; 12 | 13 | const down = (knex: Knex): Promise => { 14 | return knex.schema.dropTable('users'); 15 | }; 16 | 17 | export default { up, down }; 18 | -------------------------------------------------------------------------------- /lib/knex/src/database/seeds/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljlm0402/typescript-express-starter/572dfd9bfdfc3b3f3e9e55b834be73445b1acf9a/lib/knex/src/database/seeds/.gitkeep -------------------------------------------------------------------------------- /lib/knex/src/dtos/users.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsEmail, IsString, IsNotEmpty, MinLength, MaxLength } from 'class-validator'; 2 | 3 | export class CreateUserDto { 4 | @IsEmail() 5 | public email: string; 6 | 7 | @IsString() 8 | @IsNotEmpty() 9 | @MinLength(9) 10 | @MaxLength(32) 11 | public password: string; 12 | } 13 | 14 | export class UpdateUserDto { 15 | @IsString() 16 | @IsNotEmpty() 17 | @MinLength(9) 18 | @MaxLength(32) 19 | public password: string; 20 | } 21 | -------------------------------------------------------------------------------- /lib/knex/src/exceptions/HttpException.ts: -------------------------------------------------------------------------------- 1 | export class HttpException extends Error { 2 | public status: number; 3 | public message: string; 4 | 5 | constructor(status: number, message: string) { 6 | super(message); 7 | this.status = status; 8 | this.message = message; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/knex/src/http/auth.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # User Signup 6 | POST {{ baseURL }}/signup 7 | Content-Type: application/json 8 | 9 | { 10 | "email": "example@email.com", 11 | "password": "password" 12 | } 13 | 14 | ### 15 | # User Login 16 | POST {{ baseURL }}/login 17 | Content-Type: application/json 18 | 19 | { 20 | "email": "example@email.com", 21 | "password": "password" 22 | } 23 | 24 | ### 25 | # User Logout 26 | POST {{ baseURL }}/logout 27 | Content-Type: application/json 28 | -------------------------------------------------------------------------------- /lib/knex/src/http/users.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # Find All Users 6 | GET {{ baseURL }}/users 7 | 8 | ### 9 | # Find User By Id 10 | GET {{ baseURL }}/users/1 11 | 12 | ### 13 | # Create User 14 | POST {{ baseURL }}/users 15 | Content-Type: application/json 16 | 17 | { 18 | "email": "example@email.com", 19 | "password": "password" 20 | } 21 | 22 | ### 23 | # Modify User By Id 24 | PUT {{ baseURL }}/users/1 25 | Content-Type: application/json 26 | 27 | { 28 | "email": "example@email.com", 29 | "password": "password" 30 | } 31 | 32 | ### 33 | # Delete User By Id 34 | DELETE {{ baseURL }}/users/1 35 | -------------------------------------------------------------------------------- /lib/knex/src/interfaces/auth.interface.ts: -------------------------------------------------------------------------------- 1 | import { Request } from 'express'; 2 | import { User } from '@interfaces/users.interface'; 3 | 4 | export interface DataStoredInToken { 5 | id: number; 6 | } 7 | 8 | export interface TokenData { 9 | token: string; 10 | expiresIn: number; 11 | } 12 | 13 | export interface RequestWithUser extends Request { 14 | user: User; 15 | } 16 | -------------------------------------------------------------------------------- /lib/knex/src/interfaces/routes.interface.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | 3 | export interface Routes { 4 | path?: string; 5 | router: Router; 6 | } 7 | -------------------------------------------------------------------------------- /lib/knex/src/interfaces/users.interface.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | id?: number; 3 | email?: string; 4 | password: string; 5 | } 6 | -------------------------------------------------------------------------------- /lib/knex/src/middlewares/error.middleware.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from 'express'; 2 | import { HttpException } from '@exceptions/httpException'; 3 | import { logger } from '@utils/logger'; 4 | 5 | export const ErrorMiddleware = (error: HttpException, req: Request, res: Response, next: NextFunction) => { 6 | try { 7 | const status: number = error.status || 500; 8 | const message: string = error.message || 'Something went wrong'; 9 | 10 | logger.error(`[${req.method}] ${req.path} >> StatusCode:: ${status}, Message:: ${message}`); 11 | res.status(status).json({ message }); 12 | } catch (error) { 13 | next(error); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /lib/knex/src/models/users.model.ts: -------------------------------------------------------------------------------- 1 | import { Model, ModelObject } from 'objection'; 2 | import { User } from '@interfaces/users.interface'; 3 | 4 | export class UserModel extends Model implements User { 5 | id!: number; 6 | email!: string; 7 | password!: string; 8 | 9 | static tableName = 'users'; // database table name 10 | static idColumn = 'id'; // id column name 11 | } 12 | 13 | export type UserShape = ModelObject; 14 | -------------------------------------------------------------------------------- /lib/knex/src/routes/auth.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { AuthController } from '@/controllers/auth.controller'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { AuthMiddleware } from '@middlewares/auth.middleware'; 6 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 7 | 8 | export class AuthRoute implements Routes { 9 | public path = '/'; 10 | public router = Router(); 11 | public auth = new AuthController(); 12 | 13 | constructor() { 14 | this.initializeRoutes(); 15 | } 16 | 17 | private initializeRoutes() { 18 | this.router.post(`${this.path}signup`, ValidationMiddleware(CreateUserDto), this.auth.signUp); 19 | this.router.post(`${this.path}login`, ValidationMiddleware(CreateUserDto), this.auth.logIn); 20 | this.router.post(`${this.path}logout`, AuthMiddleware, this.auth.logOut); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/knex/src/routes/users.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { UserController } from '@/controllers/users.controller'; 3 | import { CreateUserDto, UpdateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 6 | 7 | export class UserRoute implements Routes { 8 | public path = '/users'; 9 | public router = Router(); 10 | public user = new UserController(); 11 | 12 | constructor() { 13 | this.initializeRoutes(); 14 | } 15 | 16 | private initializeRoutes() { 17 | this.router.get(`${this.path}`, this.user.getUsers); 18 | this.router.get(`${this.path}/:id(\\d+)`, this.user.getUserById); 19 | this.router.post(`${this.path}`, ValidationMiddleware(CreateUserDto), this.user.createUser); 20 | this.router.put(`${this.path}/:id(\\d+)`, ValidationMiddleware(UpdateUserDto), this.user.updateUser); 21 | this.router.delete(`${this.path}/:id(\\d+)`, this.user.deleteUser); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/knex/src/server.ts: -------------------------------------------------------------------------------- 1 | import { App } from '@/app'; 2 | import { AuthRoute } from '@routes/auth.route'; 3 | import { UserRoute } from '@routes/users.route'; 4 | import { ValidateEnv } from '@utils/validateEnv'; 5 | 6 | ValidateEnv(); 7 | 8 | const app = new App([new UserRoute(), new AuthRoute()]); 9 | 10 | app.listen(); 11 | -------------------------------------------------------------------------------- /lib/knex/src/utils/validateEnv.ts: -------------------------------------------------------------------------------- 1 | import { cleanEnv, port, str } from 'envalid'; 2 | 3 | export const ValidateEnv = () => { 4 | cleanEnv(process.env, { 5 | NODE_ENV: str(), 6 | PORT: port(), 7 | }); 8 | }; 9 | -------------------------------------------------------------------------------- /lib/mikro-orm/.dockerignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | .vscode 3 | /node_modules 4 | 5 | # code formatter 6 | .eslintrc 7 | .eslintignore 8 | .editorconfig 9 | .huskyrc 10 | .lintstagedrc.json 11 | .prettierrc 12 | 13 | # test 14 | jest.config.js 15 | 16 | # docker 17 | Dockerfile 18 | docker-compose.yml 19 | -------------------------------------------------------------------------------- /lib/mikro-orm/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /lib/mikro-orm/.env.development.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DB_HOST = localhost 6 | DB_PORT = 27017 7 | DB_DATABASE = dev 8 | 9 | # TOKEN 10 | SECRET_KEY = secretKey 11 | 12 | # LOG 13 | LOG_FORMAT = dev 14 | LOG_DIR = ../logs 15 | 16 | # CORS 17 | ORIGIN = * 18 | CREDENTIALS = true 19 | -------------------------------------------------------------------------------- /lib/mikro-orm/.env.production.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DB_HOST = localhost 6 | DB_PORT = 27017 7 | DB_DATABASE = dev 8 | 9 | # TOKEN 10 | SECRET_KEY = secretKey 11 | 12 | # LOG 13 | LOG_FORMAT = combined 14 | LOG_DIR = ../logs 15 | 16 | # CORS 17 | ORIGIN = your.domain.com 18 | CREDENTIALS = true 19 | -------------------------------------------------------------------------------- /lib/mikro-orm/.env.test.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DB_HOST = localhost 6 | DB_PORT = 27017 7 | DB_DATABASE = dev 8 | 9 | # TOKEN 10 | SECRET_KEY = secretKey 11 | 12 | # LOG 13 | LOG_FORMAT = dev 14 | LOG_DIR = ../logs 15 | 16 | # CORS 17 | ORIGIN = * 18 | CREDENTIALS = true 19 | -------------------------------------------------------------------------------- /lib/mikro-orm/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist -------------------------------------------------------------------------------- /lib/mikro-orm/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": ["prettier", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"], 4 | "parserOptions": { 5 | "ecmaVersion": 2018, 6 | "sourceType": "module" 7 | }, 8 | "rules": { 9 | "@typescript-eslint/explicit-member-accessibility": 0, 10 | "@typescript-eslint/explicit-function-return-type": 0, 11 | "@typescript-eslint/no-parameter-properties": 0, 12 | "@typescript-eslint/interface-name-prefix": 0, 13 | "@typescript-eslint/explicit-module-boundary-types": 0, 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/ban-types": "off", 16 | "@typescript-eslint/no-var-requires": "off" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/mikro-orm/.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "lint-staged" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/mikro-orm/.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "*.ts": [ 3 | "npm run lint" 4 | ] 5 | } -------------------------------------------------------------------------------- /lib/mikro-orm/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 150, 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "trailingComma": "all", 6 | "semi": true, 7 | "arrowParens": "avoid" 8 | } -------------------------------------------------------------------------------- /lib/mikro-orm/.swcrc: -------------------------------------------------------------------------------- 1 | { 2 | "jsc": { 3 | "parser": { 4 | "syntax": "typescript", 5 | "tsx": false, 6 | "dynamicImport": true, 7 | "decorators": true 8 | }, 9 | "transform": { 10 | "legacyDecorator": true, 11 | "decoratorMetadata": true 12 | }, 13 | "target": "es2017", 14 | "externalHelpers": false, 15 | "keepClassNames": true, 16 | "loose": false, 17 | "minify": { 18 | "compress": false, 19 | "mangle": false 20 | }, 21 | "baseUrl": "src", 22 | "paths": { 23 | "@/*": ["*"], 24 | "@config": ["config"], 25 | "@controllers/*": ["controllers/*"], 26 | "@database": ["database"], 27 | "@dtos/*": ["dtos/*"], 28 | "@entities/*": ["entities/*"], 29 | "@exceptions/*": ["exceptions/*"], 30 | "@interfaces/*": ["interfaces/*"], 31 | "@middlewares/*": ["middlewares/*"], 32 | "@models/*": ["models/*"], 33 | "@routes/*": ["routes/*"], 34 | "@services/*": ["services/*"], 35 | "@utils/*": ["utils/*"] 36 | } 37 | }, 38 | "module": { 39 | "type": "commonjs" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/mikro-orm/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "node-terminal", 6 | "request": "launch", 7 | "name": "Dev typescript-express-starter", 8 | "command": "npm run dev" 9 | }, 10 | { 11 | "type": "node-terminal", 12 | "request": "launch", 13 | "name": "Start typescript-express-starter", 14 | "command": "npm run start" 15 | }, 16 | { 17 | "type": "node-terminal", 18 | "request": "launch", 19 | "name": "Test typescript-express-starter", 20 | "command": "npm run test" 21 | }, 22 | { 23 | "type": "node-terminal", 24 | "request": "launch", 25 | "name": "Lint typescript-express-starter", 26 | "command": "npm run lint" 27 | }, 28 | { 29 | "type": "node-terminal", 30 | "request": "launch", 31 | "name": "Lint:Fix typescript-express-starter", 32 | "command": "npm run lint:fix" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /lib/mikro-orm/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true 4 | }, 5 | "editor.formatOnSave": false 6 | } 7 | -------------------------------------------------------------------------------- /lib/mikro-orm/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV development 15 | 16 | EXPOSE 3000 17 | 18 | # Cmd script 19 | CMD ["npm", "run", "dev"] 20 | -------------------------------------------------------------------------------- /lib/mikro-orm/Dockerfile.prod: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV production 15 | 16 | EXPOSE 3000 17 | 18 | # Cmd script 19 | CMD ["npm", "run", "start"] 20 | -------------------------------------------------------------------------------- /lib/mikro-orm/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.9" 2 | 3 | services: 4 | proxy: 5 | container_name: proxy 6 | image: nginx:alpine 7 | ports: 8 | - "80:80" 9 | volumes: 10 | - ./nginx.conf:/etc/nginx/nginx.conf 11 | restart: "unless-stopped" 12 | networks: 13 | - backend 14 | 15 | server: 16 | container_name: server 17 | build: 18 | context: ./ 19 | dockerfile: Dockerfile.dev 20 | ports: 21 | - "3000:3000" 22 | environment: 23 | DB_HOST: localhost 24 | DB_PORT: 27017 25 | DB_DATABASE: dev 26 | volumes: 27 | - ./:/app 28 | - /app/node_modules 29 | restart: "unless-stopped" 30 | networks: 31 | - backend 32 | links: 33 | - mongo 34 | depends_on: 35 | - mongo 36 | 37 | mongo: 38 | container_name: mongo 39 | image: mongo 40 | ports: 41 | - "27017:27017" 42 | environment: 43 | DB_HOST: localhost 44 | DB_PORT: 27017 45 | DB_DATABASE: dev 46 | networks: 47 | - backend 48 | 49 | networks: 50 | backend: 51 | driver: bridge 52 | 53 | volumes: 54 | data: 55 | driver: local 56 | -------------------------------------------------------------------------------- /lib/mikro-orm/jest.config.js: -------------------------------------------------------------------------------- 1 | const { pathsToModuleNameMapper } = require('ts-jest'); 2 | const { compilerOptions } = require('./tsconfig.json'); 3 | 4 | module.exports = { 5 | preset: 'ts-jest', 6 | testEnvironment: 'node', 7 | roots: ['/src'], 8 | transform: { 9 | '^.+\\.tsx?$': 'ts-jest', 10 | }, 11 | moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '/src' }), 12 | }; 13 | -------------------------------------------------------------------------------- /lib/mikro-orm/nginx.conf: -------------------------------------------------------------------------------- 1 | user nginx; 2 | worker_processes 1; 3 | 4 | error_log /var/log/nginx/error.log warn; 5 | pid /var/run/nginx.pid; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | http { 12 | include /etc/nginx/mime.types; 13 | default_type application/octet-stream; 14 | 15 | upstream api-server { 16 | server server:3000; 17 | keepalive 100; 18 | } 19 | 20 | server { 21 | listen 80; 22 | server_name localhost; 23 | 24 | location / { 25 | proxy_http_version 1.1; 26 | proxy_pass http://api-server; 27 | } 28 | 29 | } 30 | 31 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 32 | '$status $body_bytes_sent "$http_referer" ' 33 | '"$http_user_agent" "$http_x_forwarded_for"'; 34 | 35 | access_log /var/log/nginx/access.log main; 36 | 37 | sendfile on; 38 | keepalive_timeout 65; 39 | include /etc/nginx/conf.d/*.conf; 40 | } 41 | -------------------------------------------------------------------------------- /lib/mikro-orm/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": [ 3 | "src", 4 | ".env" 5 | ], 6 | "ext": "js,ts,json", 7 | "ignore": [ 8 | "src/logs/*", 9 | "src/**/*.{spec,test}.ts" 10 | ], 11 | "exec": "ts-node -r tsconfig-paths/register --transpile-only src/server.ts" 12 | } -------------------------------------------------------------------------------- /lib/mikro-orm/src/config/index.ts: -------------------------------------------------------------------------------- 1 | import { config } from 'dotenv'; 2 | config({ path: `.env.${process.env.NODE_ENV || 'development'}.local` }); 3 | 4 | export const CREDENTIALS = process.env.CREDENTIALS === 'true'; 5 | export const { NODE_ENV, PORT, SECRET_KEY, LOG_FORMAT, LOG_DIR, ORIGIN } = process.env; 6 | export const { DB_HOST, DB_PORT, DB_DATABASE } = process.env; 7 | -------------------------------------------------------------------------------- /lib/mikro-orm/src/database/index.ts: -------------------------------------------------------------------------------- 1 | import { EntityManager, EntityRepository, MikroORM, Options } from '@mikro-orm/core'; 2 | import { MongoHighlighter } from '@mikro-orm/mongo-highlighter'; 3 | import { NODE_ENV, DB_HOST, DB_PORT, DB_DATABASE } from '@config'; 4 | import { BaseEntity } from '@entities/base.entity'; 5 | import { UserEntity } from '@entities/users.entity'; 6 | 7 | export const dbOptions: Options = { 8 | type: 'mongo', 9 | clientUrl: `mongodb://${DB_HOST}:${DB_PORT}/${DB_DATABASE}`, 10 | entities: [BaseEntity, UserEntity], 11 | highlighter: new MongoHighlighter(), 12 | debug: NODE_ENV === 'development' ? true : false, 13 | }; 14 | 15 | export const DI = {} as { 16 | orm: MikroORM; 17 | em: EntityManager; 18 | userRepository: EntityRepository; 19 | }; 20 | -------------------------------------------------------------------------------- /lib/mikro-orm/src/dtos/users.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsEmail, IsString, IsNotEmpty, MinLength, MaxLength } from 'class-validator'; 2 | 3 | export class CreateUserDto { 4 | @IsEmail() 5 | public email: string; 6 | 7 | @IsString() 8 | @IsNotEmpty() 9 | @MinLength(9) 10 | @MaxLength(32) 11 | public password: string; 12 | } 13 | 14 | export class UpdateUserDto { 15 | @IsString() 16 | @IsNotEmpty() 17 | @MinLength(9) 18 | @MaxLength(32) 19 | public password: string; 20 | } 21 | -------------------------------------------------------------------------------- /lib/mikro-orm/src/entities/base.entity.ts: -------------------------------------------------------------------------------- 1 | import { PrimaryKey, Property, SerializedPrimaryKey } from '@mikro-orm/core'; 2 | import { ObjectId } from '@mikro-orm/mongodb'; 3 | 4 | export abstract class BaseEntity { 5 | @PrimaryKey() 6 | _id!: ObjectId; 7 | 8 | @SerializedPrimaryKey({ type: 'text' }) 9 | id!: string; 10 | 11 | @Property({ type: 'date' }) 12 | createdAt = new Date(); 13 | 14 | @Property({ type: 'date', onUpdate: () => new Date() }) 15 | updatedAt = new Date(); 16 | } 17 | -------------------------------------------------------------------------------- /lib/mikro-orm/src/entities/users.entity.ts: -------------------------------------------------------------------------------- 1 | import { Entity, Property } from '@mikro-orm/core'; 2 | import { BaseEntity } from '@entities/base.entity'; 3 | 4 | @Entity() 5 | export class UserEntity extends BaseEntity { 6 | constructor(email: string, password: string) { 7 | super(); 8 | this.email = email; 9 | this.password = password; 10 | } 11 | 12 | @Property({ type: 'text' }) 13 | email!: string; 14 | 15 | @Property({ type: 'text' }) 16 | password!: string; 17 | } 18 | -------------------------------------------------------------------------------- /lib/mikro-orm/src/exceptions/HttpException.ts: -------------------------------------------------------------------------------- 1 | export class HttpException extends Error { 2 | public status: number; 3 | public message: string; 4 | 5 | constructor(status: number, message: string) { 6 | super(message); 7 | this.status = status; 8 | this.message = message; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/mikro-orm/src/http/auth.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # User Signup 6 | POST {{ baseURL }}/signup 7 | Content-Type: application/json 8 | 9 | { 10 | "email": "example@email.com", 11 | "password": "password" 12 | } 13 | 14 | ### 15 | # User Login 16 | POST {{ baseURL }}/login 17 | Content-Type: application/json 18 | 19 | { 20 | "email": "example@email.com", 21 | "password": "password" 22 | } 23 | 24 | ### 25 | # User Logout 26 | POST {{ baseURL }}/logout 27 | Content-Type: application/json 28 | 29 | { 30 | "email": "example@email.com", 31 | "password": "password" 32 | } 33 | -------------------------------------------------------------------------------- /lib/mikro-orm/src/http/users.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # Find All Users 6 | GET {{ baseURL }}/users 7 | 8 | ### 9 | # Find User By Id 10 | GET {{ baseURL }}/users/6257233cbfa5c2b8e249dbe7 11 | 12 | ### 13 | # Create User 14 | POST {{ baseURL }}/users 15 | Content-Type: application/json 16 | 17 | { 18 | "email": "example@email.com", 19 | "password": "password" 20 | } 21 | 22 | ### 23 | # Modify User By Id 24 | PUT {{ baseURL }}/users/6257233cbfa5c2b8e249dbe7 25 | Content-Type: application/json 26 | 27 | { 28 | "email": "example@email.com", 29 | "password": "password" 30 | } 31 | 32 | ### 33 | # Delete User By Id 34 | DELETE {{ baseURL }}/users/6257233cbfa5c2b8e249dbe7 35 | -------------------------------------------------------------------------------- /lib/mikro-orm/src/interfaces/auth.interface.ts: -------------------------------------------------------------------------------- 1 | import { Request } from 'express'; 2 | import { User } from '@interfaces/users.interface'; 3 | 4 | export interface DataStoredInToken { 5 | _id: string; 6 | } 7 | 8 | export interface TokenData { 9 | token: string; 10 | expiresIn: number; 11 | } 12 | 13 | export interface RequestWithUser extends Request { 14 | user: User; 15 | } 16 | -------------------------------------------------------------------------------- /lib/mikro-orm/src/interfaces/routes.interface.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | 3 | export interface Routes { 4 | path?: string; 5 | router: Router; 6 | } 7 | -------------------------------------------------------------------------------- /lib/mikro-orm/src/interfaces/users.interface.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | id?: string; 3 | email: string; 4 | password: string; 5 | } 6 | -------------------------------------------------------------------------------- /lib/mikro-orm/src/middlewares/error.middleware.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from 'express'; 2 | import { HttpException } from '@exceptions/httpException'; 3 | import { logger } from '@utils/logger'; 4 | 5 | export const ErrorMiddleware = (error: HttpException, req: Request, res: Response, next: NextFunction) => { 6 | try { 7 | const status: number = error.status || 500; 8 | const message: string = error.message || 'Something went wrong'; 9 | 10 | logger.error(`[${req.method}] ${req.path} >> StatusCode:: ${status}, Message:: ${message}`); 11 | res.status(status).json({ message }); 12 | } catch (error) { 13 | next(error); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /lib/mikro-orm/src/routes/auth.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { AuthController } from '@controllers/auth.controller'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { AuthMiddleware } from '@middlewares/auth.middleware'; 6 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 7 | 8 | export class AuthRoute implements Routes { 9 | public path = '/'; 10 | public router = Router(); 11 | public auth = new AuthController(); 12 | 13 | constructor() { 14 | this.initializeRoutes(); 15 | } 16 | 17 | private initializeRoutes() { 18 | this.router.post(`${this.path}signup`, ValidationMiddleware(CreateUserDto), this.auth.signUp); 19 | this.router.post(`${this.path}login`, ValidationMiddleware(CreateUserDto), this.auth.logIn); 20 | this.router.post(`${this.path}logout`, AuthMiddleware, this.auth.logOut); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/mikro-orm/src/routes/users.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { UserController } from '@controllers/users.controller'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 6 | 7 | export class UserRoute implements Routes { 8 | public path = '/users'; 9 | public router = Router(); 10 | public user = new UserController(); 11 | 12 | constructor() { 13 | this.initializeRoutes(); 14 | } 15 | 16 | private initializeRoutes() { 17 | this.router.get(`${this.path}`, this.user.getUsers); 18 | this.router.get(`${this.path}/:id`, this.user.getUserById); 19 | this.router.post(`${this.path}`, ValidationMiddleware(CreateUserDto), this.user.createUser); 20 | this.router.put(`${this.path}/:id`, ValidationMiddleware(CreateUserDto, true), this.user.updateUser); 21 | this.router.delete(`${this.path}/:id`, this.user.deleteUser); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/mikro-orm/src/server.ts: -------------------------------------------------------------------------------- 1 | import { App } from '@/app'; 2 | import { AuthRoute } from '@routes/auth.route'; 3 | import { UserRoute } from '@routes/users.route'; 4 | import { ValidateEnv } from '@utils/validateEnv'; 5 | 6 | ValidateEnv(); 7 | 8 | const app = new App([new UserRoute(), new AuthRoute()]); 9 | 10 | app.listen(); 11 | -------------------------------------------------------------------------------- /lib/mikro-orm/src/utils/validateEnv.ts: -------------------------------------------------------------------------------- 1 | import { cleanEnv, port, str } from 'envalid'; 2 | 3 | export const ValidateEnv = () => { 4 | cleanEnv(process.env, { 5 | NODE_ENV: str(), 6 | PORT: port(), 7 | }); 8 | }; 9 | -------------------------------------------------------------------------------- /lib/mongoose/.dockerignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | .vscode 3 | /node_modules 4 | 5 | # code formatter 6 | .eslintrc 7 | .eslintignore 8 | .editorconfig 9 | .huskyrc 10 | .lintstagedrc.json 11 | .prettierrc 12 | 13 | # test 14 | jest.config.js 15 | 16 | # docker 17 | Dockerfile 18 | docker-compose.yml 19 | -------------------------------------------------------------------------------- /lib/mongoose/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /lib/mongoose/.env.development.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DB_HOST = localhost 6 | DB_PORT = 27017 7 | DB_DATABASE = dev 8 | 9 | # TOKEN 10 | SECRET_KEY = secretKey 11 | 12 | # LOG 13 | LOG_FORMAT = dev 14 | LOG_DIR = ../logs 15 | 16 | # CORS 17 | ORIGIN = * 18 | CREDENTIALS = true 19 | -------------------------------------------------------------------------------- /lib/mongoose/.env.production.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DB_HOST = localhost 6 | DB_PORT = 27017 7 | DB_DATABASE = dev 8 | 9 | # TOKEN 10 | SECRET_KEY = secretKey 11 | 12 | # LOG 13 | LOG_FORMAT = combined 14 | LOG_DIR = ../logs 15 | 16 | # CORS 17 | ORIGIN = your.domain.com 18 | CREDENTIALS = true 19 | -------------------------------------------------------------------------------- /lib/mongoose/.env.test.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DB_HOST = localhost 6 | DB_PORT = 27017 7 | DB_DATABASE = dev 8 | 9 | # TOKEN 10 | SECRET_KEY = secretKey 11 | 12 | # LOG 13 | LOG_FORMAT = dev 14 | LOG_DIR = ../logs 15 | 16 | # CORS 17 | ORIGIN = * 18 | CREDENTIALS = true 19 | -------------------------------------------------------------------------------- /lib/mongoose/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist -------------------------------------------------------------------------------- /lib/mongoose/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": ["prettier", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"], 4 | "parserOptions": { 5 | "ecmaVersion": 2018, 6 | "sourceType": "module" 7 | }, 8 | "rules": { 9 | "@typescript-eslint/explicit-member-accessibility": 0, 10 | "@typescript-eslint/explicit-function-return-type": 0, 11 | "@typescript-eslint/no-parameter-properties": 0, 12 | "@typescript-eslint/interface-name-prefix": 0, 13 | "@typescript-eslint/explicit-module-boundary-types": 0, 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/ban-types": "off", 16 | "@typescript-eslint/no-var-requires": "off" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/mongoose/.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "lint-staged" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/mongoose/.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "*.ts": [ 3 | "npm run lint" 4 | ] 5 | } -------------------------------------------------------------------------------- /lib/mongoose/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 150, 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "trailingComma": "all", 6 | "semi": true, 7 | "arrowParens": "avoid" 8 | } -------------------------------------------------------------------------------- /lib/mongoose/.swcrc: -------------------------------------------------------------------------------- 1 | { 2 | "jsc": { 3 | "parser": { 4 | "syntax": "typescript", 5 | "tsx": false, 6 | "dynamicImport": true, 7 | "decorators": true 8 | }, 9 | "transform": { 10 | "legacyDecorator": true, 11 | "decoratorMetadata": true 12 | }, 13 | "target": "es2017", 14 | "externalHelpers": false, 15 | "keepClassNames": true, 16 | "loose": false, 17 | "minify": { 18 | "compress": false, 19 | "mangle": false 20 | }, 21 | "baseUrl": "src", 22 | "paths": { 23 | "@/*": ["*"], 24 | "@config": ["config"], 25 | "@controllers/*": ["controllers/*"], 26 | "@database": ["database"], 27 | "@dtos/*": ["dtos/*"], 28 | "@exceptions/*": ["exceptions/*"], 29 | "@interfaces/*": ["interfaces/*"], 30 | "@middlewares/*": ["middlewares/*"], 31 | "@models/*": ["models/*"], 32 | "@routes/*": ["routes/*"], 33 | "@services/*": ["services/*"], 34 | "@utils/*": ["utils/*"] 35 | } 36 | }, 37 | "module": { 38 | "type": "commonjs" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/mongoose/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "node-terminal", 6 | "request": "launch", 7 | "name": "Dev typescript-express-starter", 8 | "command": "npm run dev" 9 | }, 10 | { 11 | "type": "node-terminal", 12 | "request": "launch", 13 | "name": "Start typescript-express-starter", 14 | "command": "npm run start" 15 | }, 16 | { 17 | "type": "node-terminal", 18 | "request": "launch", 19 | "name": "Test typescript-express-starter", 20 | "command": "npm run test" 21 | }, 22 | { 23 | "type": "node-terminal", 24 | "request": "launch", 25 | "name": "Lint typescript-express-starter", 26 | "command": "npm run lint" 27 | }, 28 | { 29 | "type": "node-terminal", 30 | "request": "launch", 31 | "name": "Lint:Fix typescript-express-starter", 32 | "command": "npm run lint:fix" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /lib/mongoose/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true 4 | }, 5 | "editor.formatOnSave": false 6 | } 7 | -------------------------------------------------------------------------------- /lib/mongoose/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV development 15 | 16 | EXPOSE 3000 17 | 18 | # Cmd script 19 | CMD ["npm", "run", "dev"] 20 | -------------------------------------------------------------------------------- /lib/mongoose/Dockerfile.prod: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV production 15 | 16 | EXPOSE 3000 17 | 18 | # Cmd script 19 | CMD ["npm", "run", "start"] 20 | -------------------------------------------------------------------------------- /lib/mongoose/jest.config.js: -------------------------------------------------------------------------------- 1 | const { pathsToModuleNameMapper } = require('ts-jest'); 2 | const { compilerOptions } = require('./tsconfig.json'); 3 | 4 | module.exports = { 5 | preset: 'ts-jest', 6 | testEnvironment: 'node', 7 | roots: ['/src'], 8 | transform: { 9 | '^.+\\.tsx?$': 'ts-jest', 10 | }, 11 | moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '/src' }), 12 | }; 13 | -------------------------------------------------------------------------------- /lib/mongoose/nginx.conf: -------------------------------------------------------------------------------- 1 | user nginx; 2 | worker_processes 1; 3 | 4 | error_log /var/log/nginx/error.log warn; 5 | pid /var/run/nginx.pid; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | http { 12 | include /etc/nginx/mime.types; 13 | default_type application/octet-stream; 14 | 15 | upstream api-server { 16 | server server:3000; 17 | keepalive 100; 18 | } 19 | 20 | server { 21 | listen 80; 22 | server_name localhost; 23 | 24 | location / { 25 | proxy_http_version 1.1; 26 | proxy_pass http://api-server; 27 | } 28 | 29 | } 30 | 31 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 32 | '$status $body_bytes_sent "$http_referer" ' 33 | '"$http_user_agent" "$http_x_forwarded_for"'; 34 | 35 | access_log /var/log/nginx/access.log main; 36 | 37 | sendfile on; 38 | keepalive_timeout 65; 39 | include /etc/nginx/conf.d/*.conf; 40 | } 41 | -------------------------------------------------------------------------------- /lib/mongoose/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": [ 3 | "src", 4 | ".env" 5 | ], 6 | "ext": "js,ts,json", 7 | "ignore": [ 8 | "src/logs/*", 9 | "src/**/*.{spec,test}.ts" 10 | ], 11 | "exec": "ts-node -r tsconfig-paths/register --transpile-only src/server.ts" 12 | } -------------------------------------------------------------------------------- /lib/mongoose/src/config/index.ts: -------------------------------------------------------------------------------- 1 | import { config } from 'dotenv'; 2 | config({ path: `.env.${process.env.NODE_ENV || 'development'}.local` }); 3 | 4 | export const CREDENTIALS = process.env.CREDENTIALS === 'true'; 5 | export const { NODE_ENV, PORT, SECRET_KEY, LOG_FORMAT, LOG_DIR, ORIGIN } = process.env; 6 | export const { DB_HOST, DB_PORT, DB_DATABASE } = process.env; 7 | -------------------------------------------------------------------------------- /lib/mongoose/src/database/index.ts: -------------------------------------------------------------------------------- 1 | import { connect, set } from 'mongoose'; 2 | import { NODE_ENV, DB_HOST, DB_PORT, DB_DATABASE } from '@config'; 3 | 4 | export const dbConnection = async () => { 5 | const dbConfig = { 6 | url: `mongodb://${DB_HOST}:${DB_PORT}/${DB_DATABASE}`, 7 | options: { 8 | useNewUrlParser: true, 9 | useUnifiedTopology: true 10 | }, 11 | }; 12 | 13 | if (NODE_ENV !== 'production') { 14 | set('debug', true); 15 | } 16 | 17 | await connect(dbConfig.url, dbConfig.options); 18 | } 19 | -------------------------------------------------------------------------------- /lib/mongoose/src/dtos/users.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsEmail, IsString, IsNotEmpty, MinLength, MaxLength } from 'class-validator'; 2 | 3 | export class CreateUserDto { 4 | @IsEmail() 5 | public email: string; 6 | 7 | @IsString() 8 | @IsNotEmpty() 9 | @MinLength(9) 10 | @MaxLength(32) 11 | public password: string; 12 | } 13 | 14 | export class UpdateUserDto { 15 | @IsString() 16 | @IsNotEmpty() 17 | @MinLength(9) 18 | @MaxLength(32) 19 | public password: string; 20 | } -------------------------------------------------------------------------------- /lib/mongoose/src/exceptions/HttpException.ts: -------------------------------------------------------------------------------- 1 | export class HttpException extends Error { 2 | public status: number; 3 | public message: string; 4 | 5 | constructor(status: number, message: string) { 6 | super(message); 7 | this.status = status; 8 | this.message = message; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/mongoose/src/http/auth.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # User Signup 6 | POST {{ baseURL }}/signup 7 | Content-Type: application/json 8 | 9 | { 10 | "email": "example@email.com", 11 | "password": "password" 12 | } 13 | 14 | ### 15 | # User Login 16 | POST {{ baseURL }}/login 17 | Content-Type: application/json 18 | 19 | { 20 | "email": "example@email.com", 21 | "password": "password" 22 | } 23 | 24 | ### 25 | # User Logout 26 | POST {{ baseURL }}/logout 27 | Content-Type: application/json 28 | -------------------------------------------------------------------------------- /lib/mongoose/src/http/users.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # Find All Users 6 | GET {{ baseURL }}/users 7 | 8 | ### 9 | # Find User By Id 10 | GET {{ baseURL }}/users/1 11 | 12 | ### 13 | # Create User 14 | POST {{ baseURL }}/users 15 | Content-Type: application/json 16 | 17 | { 18 | "email": "example@email.com", 19 | "password": "password" 20 | } 21 | 22 | ### 23 | # Modify User By Id 24 | PUT {{ baseURL }}/users/1 25 | Content-Type: application/json 26 | 27 | { 28 | "email": "example@email.com", 29 | "password": "password" 30 | } 31 | 32 | ### 33 | # Delete User By Id 34 | DELETE {{ baseURL }}/users/1 35 | -------------------------------------------------------------------------------- /lib/mongoose/src/interfaces/auth.interface.ts: -------------------------------------------------------------------------------- 1 | import { Request } from 'express'; 2 | import { User } from '@interfaces/users.interface'; 3 | 4 | export interface DataStoredInToken { 5 | _id: string; 6 | } 7 | 8 | export interface TokenData { 9 | token: string; 10 | expiresIn: number; 11 | } 12 | 13 | export interface RequestWithUser extends Request { 14 | user: User; 15 | } 16 | -------------------------------------------------------------------------------- /lib/mongoose/src/interfaces/routes.interface.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | 3 | export interface Routes { 4 | path?: string; 5 | router: Router; 6 | } 7 | -------------------------------------------------------------------------------- /lib/mongoose/src/interfaces/users.interface.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | _id?: string; 3 | email: string; 4 | password: string; 5 | } 6 | -------------------------------------------------------------------------------- /lib/mongoose/src/middlewares/error.middleware.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from 'express'; 2 | import { HttpException } from '@exceptions/httpException'; 3 | import { logger } from '@utils/logger'; 4 | 5 | export const ErrorMiddleware = (error: HttpException, req: Request, res: Response, next: NextFunction) => { 6 | try { 7 | const status: number = error.status || 500; 8 | const message: string = error.message || 'Something went wrong'; 9 | 10 | logger.error(`[${req.method}] ${req.path} >> StatusCode:: ${status}, Message:: ${message}`); 11 | res.status(status).json({ message }); 12 | } catch (error) { 13 | next(error); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /lib/mongoose/src/models/users.model.ts: -------------------------------------------------------------------------------- 1 | import { model, Schema, Document } from 'mongoose'; 2 | import { User } from '@interfaces/users.interface'; 3 | 4 | const UserSchema: Schema = new Schema({ 5 | email: { 6 | type: String, 7 | required: true, 8 | unique: true, 9 | }, 10 | password: { 11 | type: String, 12 | required: true, 13 | }, 14 | }); 15 | 16 | export const UserModel = model('User', UserSchema); 17 | -------------------------------------------------------------------------------- /lib/mongoose/src/routes/auth.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { AuthController } from '@controllers/auth.controller'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { AuthMiddleware } from '@middlewares/auth.middleware'; 6 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 7 | 8 | export class AuthRoute implements Routes { 9 | public path = '/'; 10 | public router = Router(); 11 | public auth = new AuthController(); 12 | 13 | constructor() { 14 | this.initializeRoutes(); 15 | } 16 | 17 | private initializeRoutes() { 18 | this.router.post(`${this.path}signup`, ValidationMiddleware(CreateUserDto), this.auth.signUp); 19 | this.router.post(`${this.path}login`, ValidationMiddleware(CreateUserDto), this.auth.logIn); 20 | this.router.post(`${this.path}logout`, AuthMiddleware, this.auth.logOut); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/mongoose/src/routes/users.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { UserController } from '@controllers/users.controller'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 6 | 7 | export class UserRoute implements Routes { 8 | public path = '/users'; 9 | public router = Router(); 10 | public user = new UserController(); 11 | 12 | constructor() { 13 | this.initializeRoutes(); 14 | } 15 | 16 | private initializeRoutes() { 17 | this.router.get(`${this.path}`, this.user.getUsers); 18 | this.router.get(`${this.path}/:id`, this.user.getUserById); 19 | this.router.post(`${this.path}`, ValidationMiddleware(CreateUserDto), this.user.createUser); 20 | this.router.put(`${this.path}/:id`, ValidationMiddleware(CreateUserDto, true), this.user.updateUser); 21 | this.router.delete(`${this.path}/:id`, this.user.deleteUser); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/mongoose/src/server.ts: -------------------------------------------------------------------------------- 1 | import { App } from '@/app'; 2 | import { AuthRoute } from '@routes/auth.route'; 3 | import { UserRoute } from '@routes/users.route'; 4 | import { ValidateEnv } from '@utils/validateEnv'; 5 | 6 | ValidateEnv(); 7 | 8 | const app = new App([new UserRoute(), new AuthRoute()]); 9 | 10 | app.listen(); 11 | -------------------------------------------------------------------------------- /lib/mongoose/src/test/index.test.ts: -------------------------------------------------------------------------------- 1 | import request from 'supertest'; 2 | import App from '@/app'; 3 | import IndexRoute from '@routes/index.route'; 4 | 5 | afterAll(async () => { 6 | await new Promise(resolve => setTimeout(() => resolve(), 500)); 7 | }); 8 | 9 | describe('Testing Index', () => { 10 | describe('[GET] /', () => { 11 | it('response statusCode 200', () => { 12 | const indexRoute = new IndexRoute(); 13 | const app = new App([indexRoute]); 14 | 15 | return request(app.getServer()).get(`${indexRoute.path}`).expect(200); 16 | }); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /lib/mongoose/src/utils/validateEnv.ts: -------------------------------------------------------------------------------- 1 | import { cleanEnv, port, str } from 'envalid'; 2 | 3 | export const ValidateEnv = () => { 4 | cleanEnv(process.env, { 5 | NODE_ENV: str(), 6 | PORT: port(), 7 | }); 8 | }; 9 | -------------------------------------------------------------------------------- /lib/node-postgres/.dockerignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | .vscode 3 | /node_modules 4 | 5 | # code formatter 6 | .eslintrc 7 | .eslintignore 8 | .editorconfig 9 | .huskyrc 10 | .lintstagedrc.json 11 | .prettierrc 12 | 13 | # test 14 | jest.config.js 15 | 16 | # docker 17 | Dockerfile 18 | docker-compose.yml 19 | -------------------------------------------------------------------------------- /lib/node-postgres/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /lib/node-postgres/.env.development.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # TOKEN 5 | SECRET_KEY = secretKey 6 | 7 | # LOG 8 | LOG_FORMAT = dev 9 | LOG_DIR = ../logs 10 | 11 | # CORS 12 | ORIGIN = * 13 | CREDENTIALS = true 14 | 15 | # DATABASE 16 | POSTGRES_USER = root 17 | POSTGRES_PASSWORD = password 18 | POSTGRES_HOST = localhost 19 | POSTGRES_PORT = 5432 20 | POSTGRES_DB = dev 21 | -------------------------------------------------------------------------------- /lib/node-postgres/.env.production.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # TOKEN 5 | SECRET_KEY = secretKey 6 | 7 | # LOG 8 | LOG_FORMAT = combined 9 | LOG_DIR = ../logs 10 | 11 | # CORS 12 | ORIGIN = your.domain.com 13 | CREDENTIALS = true 14 | 15 | # DATABASE 16 | POSTGRES_USER = root 17 | POSTGRES_PASSWORD = password 18 | POSTGRES_HOST = pg 19 | POSTGRES_PORT = 5432 20 | POSTGRES_DB = dev 21 | -------------------------------------------------------------------------------- /lib/node-postgres/.env.test.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # TOKEN 5 | SECRET_KEY = secretKey 6 | 7 | # LOG 8 | LOG_FORMAT = dev 9 | LOG_DIR = ../logs 10 | 11 | # CORS 12 | ORIGIN = * 13 | CREDENTIALS = true 14 | 15 | # DATABASE 16 | POSTGRES_USER = root 17 | POSTGRES_PASSWORD = password 18 | POSTGRES_HOST = pg 19 | POSTGRES_PORT = 5432 20 | POSTGRES_DB = dev 21 | -------------------------------------------------------------------------------- /lib/node-postgres/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist -------------------------------------------------------------------------------- /lib/node-postgres/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": ["prettier", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"], 4 | "parserOptions": { 5 | "ecmaVersion": 2018, 6 | "sourceType": "module" 7 | }, 8 | "rules": { 9 | "@typescript-eslint/explicit-member-accessibility": 0, 10 | "@typescript-eslint/explicit-function-return-type": 0, 11 | "@typescript-eslint/no-parameter-properties": 0, 12 | "@typescript-eslint/interface-name-prefix": 0, 13 | "@typescript-eslint/explicit-module-boundary-types": 0, 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/ban-types": "off", 16 | "@typescript-eslint/no-var-requires": "off" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/node-postgres/.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "lint-staged" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/node-postgres/.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "*.ts": [ 3 | "npm run lint" 4 | ] 5 | } -------------------------------------------------------------------------------- /lib/node-postgres/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 150, 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "trailingComma": "all", 6 | "semi": true, 7 | "arrowParens": "avoid" 8 | } -------------------------------------------------------------------------------- /lib/node-postgres/.swcrc: -------------------------------------------------------------------------------- 1 | { 2 | "jsc": { 3 | "parser": { 4 | "syntax": "typescript", 5 | "tsx": false, 6 | "dynamicImport": true, 7 | "decorators": true 8 | }, 9 | "transform": { 10 | "legacyDecorator": true, 11 | "decoratorMetadata": true 12 | }, 13 | "target": "es2017", 14 | "externalHelpers": false, 15 | "keepClassNames": true, 16 | "loose": false, 17 | "minify": { 18 | "compress": false, 19 | "mangle": false 20 | }, 21 | "baseUrl": "src", 22 | "paths": { 23 | "@/*": ["*"], 24 | "@config": ["config"], 25 | "@controllers/*": ["controllers/*"], 26 | "@dtos/*": ["dtos/*"], 27 | "@database": ["database"], 28 | "@exceptions/*": ["exceptions/*"], 29 | "@interfaces/*": ["interfaces/*"], 30 | "@middlewares/*": ["middlewares/*"], 31 | "@services/*": ["services/*"], 32 | "@utils/*": ["utils/*"] 33 | } 34 | }, 35 | "module": { 36 | "type": "commonjs" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/node-postgres/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "node-terminal", 6 | "request": "launch", 7 | "name": "Dev typescript-express-starter", 8 | "command": "npm run dev" 9 | }, 10 | { 11 | "type": "node-terminal", 12 | "request": "launch", 13 | "name": "Start typescript-express-starter", 14 | "command": "npm run start" 15 | }, 16 | { 17 | "type": "node-terminal", 18 | "request": "launch", 19 | "name": "Test typescript-express-starter", 20 | "command": "npm run test" 21 | }, 22 | { 23 | "type": "node-terminal", 24 | "request": "launch", 25 | "name": "Lint typescript-express-starter", 26 | "command": "npm run lint" 27 | }, 28 | { 29 | "type": "node-terminal", 30 | "request": "launch", 31 | "name": "Lint:Fix typescript-express-starter", 32 | "command": "npm run lint:fix" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /lib/node-postgres/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true 4 | }, 5 | "editor.formatOnSave": false 6 | } 7 | -------------------------------------------------------------------------------- /lib/node-postgres/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV development 15 | 16 | # Cmd script 17 | CMD ["npm", "run", "dev"] 18 | -------------------------------------------------------------------------------- /lib/node-postgres/Dockerfile.prod: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV production 15 | 16 | # Cmd script 17 | CMD ["npm", "run", "start"] 18 | -------------------------------------------------------------------------------- /lib/node-postgres/jest.config.js: -------------------------------------------------------------------------------- 1 | const { pathsToModuleNameMapper } = require('ts-jest'); 2 | const { compilerOptions } = require('./tsconfig.json'); 3 | 4 | module.exports = { 5 | preset: 'ts-jest', 6 | testEnvironment: 'node', 7 | roots: ['/src'], 8 | transform: { 9 | '^.+\\.tsx?$': 'ts-jest', 10 | }, 11 | moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '/src' }), 12 | }; 13 | -------------------------------------------------------------------------------- /lib/node-postgres/nginx.conf: -------------------------------------------------------------------------------- 1 | user nginx; 2 | worker_processes 1; 3 | 4 | error_log /var/log/nginx/error.log warn; 5 | pid /var/run/nginx.pid; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | http { 12 | include /etc/nginx/mime.types; 13 | default_type application/octet-stream; 14 | 15 | upstream api-server { 16 | server server:3000; 17 | keepalive 100; 18 | } 19 | 20 | server { 21 | listen 80; 22 | server_name localhost; 23 | 24 | location / { 25 | proxy_http_version 1.1; 26 | proxy_pass http://api-server; 27 | } 28 | 29 | } 30 | 31 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 32 | '$status $body_bytes_sent "$http_referer" ' 33 | '"$http_user_agent" "$http_x_forwarded_for"'; 34 | 35 | access_log /var/log/nginx/access.log main; 36 | 37 | sendfile on; 38 | keepalive_timeout 65; 39 | include /etc/nginx/conf.d/*.conf; 40 | } 41 | -------------------------------------------------------------------------------- /lib/node-postgres/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": [ 3 | "src", 4 | ".env" 5 | ], 6 | "ext": "js,ts,json", 7 | "ignore": [ 8 | "src/logs/*", 9 | "src/**/*.{spec,test}.ts" 10 | ], 11 | "exec": "ts-node -r tsconfig-paths/register --transpile-only src/server.ts" 12 | } -------------------------------------------------------------------------------- /lib/node-postgres/src/config/index.ts: -------------------------------------------------------------------------------- 1 | import { config } from 'dotenv'; 2 | config({ path: `.env.${process.env.NODE_ENV || 'development'}.local` }); 3 | 4 | export const CREDENTIALS = process.env.CREDENTIALS === 'true'; 5 | export const { NODE_ENV, PORT, SECRET_KEY, LOG_FORMAT, LOG_DIR, ORIGIN } = process.env; 6 | export const { POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DB } = process.env; 7 | -------------------------------------------------------------------------------- /lib/node-postgres/src/database/index.ts: -------------------------------------------------------------------------------- 1 | import { Client } from 'pg'; 2 | import { POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DB } from '@config'; 3 | 4 | export const client = new Client({ 5 | connectionString: `postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${POSTGRES_HOST}:${POSTGRES_PORT}/${POSTGRES_DB}`, 6 | }); 7 | 8 | client.connect(); 9 | 10 | export default client; 11 | -------------------------------------------------------------------------------- /lib/node-postgres/src/database/init.sql: -------------------------------------------------------------------------------- 1 | -- If Exists Table Drop 2 | DROP TABLE IF EXISTS users cascade; 3 | -- ================ 4 | -- TABLE [users] 5 | -- ================ 6 | -- create users table 7 | CREATE TABLE users( 8 | "id" SERIAL PRIMARY KEY, 9 | "email" VARCHAR(32) UNIQUE NOT NULL, 10 | "password" VARCHAR(48) NOT NULL, 11 | "createdAt" TIMESTAMP WITHOUT TIME ZONE DEFAULT(NOW() AT TIME ZONE 'utc'), 12 | "updatedAt" TIMESTAMP WITHOUT TIME ZONE 13 | ); -------------------------------------------------------------------------------- /lib/node-postgres/src/dtos/users.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsEmail, IsString, IsNotEmpty, MinLength, MaxLength } from 'class-validator'; 2 | 3 | export class CreateUserDto { 4 | @IsEmail() 5 | public email: string; 6 | 7 | @IsString() 8 | @IsNotEmpty() 9 | @MinLength(9) 10 | @MaxLength(32) 11 | public password: string; 12 | } 13 | 14 | export class UpdateUserDto { 15 | @IsString() 16 | @IsNotEmpty() 17 | @MinLength(9) 18 | @MaxLength(32) 19 | public password: string; 20 | } -------------------------------------------------------------------------------- /lib/node-postgres/src/exceptions/httpException.ts: -------------------------------------------------------------------------------- 1 | export class HttpException extends Error { 2 | public status: number; 3 | public message: string; 4 | 5 | constructor(status: number, message: string) { 6 | super(message); 7 | this.status = status; 8 | this.message = message; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/node-postgres/src/http/auth.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # User Signup 6 | POST {{ baseURL }}/signup 7 | Content-Type: application/json 8 | 9 | { 10 | "email": "example@email.com", 11 | "password": "password" 12 | } 13 | 14 | ### 15 | # User Login 16 | POST {{ baseURL }}/login 17 | Content-Type: application/json 18 | 19 | { 20 | "email": "example@email.com", 21 | "password": "password" 22 | } 23 | 24 | ### 25 | # User Logout 26 | POST {{ baseURL }}/logout 27 | Content-Type: application/json 28 | -------------------------------------------------------------------------------- /lib/node-postgres/src/http/users.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # Find All Users 6 | GET {{ baseURL }}/users 7 | 8 | ### 9 | # Find User By Id 10 | GET {{ baseURL }}/users/1 11 | 12 | ### 13 | # Create User 14 | POST {{ baseURL }}/users 15 | Content-Type: application/json 16 | 17 | { 18 | "email": "example@email.com", 19 | "password": "password" 20 | } 21 | 22 | ### 23 | # Modify User By Id 24 | PUT {{ baseURL }}/users/1 25 | Content-Type: application/json 26 | 27 | { 28 | "email": "example@email.com", 29 | "password": "password" 30 | } 31 | 32 | ### 33 | # Delete User By Id 34 | DELETE {{ baseURL }}/users/1 35 | -------------------------------------------------------------------------------- /lib/node-postgres/src/interfaces/auth.interface.ts: -------------------------------------------------------------------------------- 1 | import { Request } from 'express'; 2 | import { User } from '@interfaces/users.interface'; 3 | 4 | export interface DataStoredInToken { 5 | id: number; 6 | } 7 | 8 | export interface TokenData { 9 | token: string; 10 | expiresIn: number; 11 | } 12 | 13 | export interface RequestWithUser extends Request { 14 | user: User; 15 | } 16 | -------------------------------------------------------------------------------- /lib/node-postgres/src/interfaces/routes.interface.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | 3 | export interface Routes { 4 | path?: string; 5 | router: Router; 6 | } 7 | -------------------------------------------------------------------------------- /lib/node-postgres/src/interfaces/users.interface.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | id?: number; 3 | email: string; 4 | password: string; 5 | } 6 | -------------------------------------------------------------------------------- /lib/node-postgres/src/middlewares/error.middleware.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from 'express'; 2 | import { HttpException } from '@exceptions/httpException'; 3 | import { logger } from '@utils/logger'; 4 | 5 | export const ErrorMiddleware = (error: HttpException, req: Request, res: Response, next: NextFunction) => { 6 | try { 7 | const status: number = error.status || 500; 8 | const message: string = error.message || 'Something went wrong'; 9 | 10 | logger.error(`[${req.method}] ${req.path} >> StatusCode:: ${status}, Message:: ${message}`); 11 | res.status(status).json({ message }); 12 | } catch (error) { 13 | next(error); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /lib/node-postgres/src/routes/auth.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { AuthController } from '@controllers/auth.controller'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { AuthMiddleware } from '@middlewares/auth.middleware'; 6 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 7 | 8 | export class AuthRoute implements Routes { 9 | public router = Router(); 10 | public auth = new AuthController(); 11 | 12 | constructor() { 13 | this.initializeRoutes(); 14 | } 15 | 16 | private initializeRoutes() { 17 | this.router.post('/signup', ValidationMiddleware(CreateUserDto), this.auth.signUp); 18 | this.router.post('/login', ValidationMiddleware(CreateUserDto), this.auth.logIn); 19 | this.router.post('/logout', AuthMiddleware, this.auth.logOut); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/node-postgres/src/routes/users.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { UserController } from '@controllers/users.controller'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 6 | 7 | export class UserRoute implements Routes { 8 | public path = '/users'; 9 | public router = Router(); 10 | public user = new UserController(); 11 | 12 | constructor() { 13 | this.initializeRoutes(); 14 | } 15 | 16 | private initializeRoutes() { 17 | this.router.get(`${this.path}`, this.user.getUsers); 18 | this.router.get(`${this.path}/:id(\\d+)`, this.user.getUserById); 19 | this.router.post(`${this.path}`, ValidationMiddleware(CreateUserDto), this.user.createUser); 20 | this.router.put(`${this.path}/:id(\\d+)`, ValidationMiddleware(CreateUserDto, true), this.user.updateUser); 21 | this.router.delete(`${this.path}/:id(\\d+)`, this.user.deleteUser); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/node-postgres/src/server.ts: -------------------------------------------------------------------------------- 1 | import { App } from '@/app'; 2 | import { AuthRoute } from '@routes/auth.route'; 3 | import { UserRoute } from '@routes/users.route'; 4 | import { ValidateEnv } from '@utils/validateEnv'; 5 | 6 | ValidateEnv(); 7 | 8 | const app = new App([new AuthRoute(), new UserRoute()]); 9 | 10 | app.listen(); 11 | -------------------------------------------------------------------------------- /lib/node-postgres/src/utils/validateEnv.ts: -------------------------------------------------------------------------------- 1 | import { cleanEnv, port, str } from 'envalid'; 2 | 3 | export const ValidateEnv = () => { 4 | cleanEnv(process.env, { 5 | NODE_ENV: str(), 6 | PORT: port(), 7 | }); 8 | }; 9 | -------------------------------------------------------------------------------- /lib/prisma/.dockerignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | .vscode 3 | /node_modules 4 | 5 | # code formatter 6 | .eslintrc 7 | .eslintignore 8 | .editorconfig 9 | .huskyrc 10 | .lintstagedrc.json 11 | .prettierrc 12 | 13 | # test 14 | jest.config.js 15 | 16 | # docker 17 | Dockerfile 18 | docker-compose.yml 19 | -------------------------------------------------------------------------------- /lib/prisma/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /lib/prisma/.env.development.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DATABASE_URL= mysql://root:password@localhost:3306/dev 6 | 7 | # TOKEN 8 | SECRET_KEY = secretKey 9 | 10 | # LOG 11 | LOG_FORMAT = dev 12 | LOG_DIR = ../logs 13 | 14 | # CORS 15 | ORIGIN = * 16 | CREDENTIALS = true 17 | -------------------------------------------------------------------------------- /lib/prisma/.env.production.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DATABASE_URL= mysql://root:password@localhost:3306/dev 6 | 7 | # TOKEN 8 | SECRET_KEY = secretKey 9 | 10 | # LOG 11 | LOG_FORMAT = combined 12 | LOG_DIR = ../logs 13 | 14 | # CORS 15 | ORIGIN = your.domain.com 16 | CREDENTIALS = true 17 | -------------------------------------------------------------------------------- /lib/prisma/.env.test.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DATABASE_URL= mysql://root:password@localhost:3306/dev 6 | 7 | # TOKEN 8 | SECRET_KEY = secretKey 9 | 10 | # LOG 11 | LOG_FORMAT = dev 12 | LOG_DIR = ../logs 13 | 14 | # CORS 15 | ORIGIN = * 16 | CREDENTIALS = true 17 | -------------------------------------------------------------------------------- /lib/prisma/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist -------------------------------------------------------------------------------- /lib/prisma/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": ["prettier", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"], 4 | "parserOptions": { 5 | "ecmaVersion": 2018, 6 | "sourceType": "module" 7 | }, 8 | "rules": { 9 | "@typescript-eslint/explicit-member-accessibility": 0, 10 | "@typescript-eslint/explicit-function-return-type": 0, 11 | "@typescript-eslint/no-parameter-properties": 0, 12 | "@typescript-eslint/interface-name-prefix": 0, 13 | "@typescript-eslint/explicit-module-boundary-types": 0, 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/ban-types": "off", 16 | "@typescript-eslint/no-var-requires": "off" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/prisma/.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "lint-staged" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/prisma/.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "*.ts": [ 3 | "npm run lint" 4 | ] 5 | } -------------------------------------------------------------------------------- /lib/prisma/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 150, 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "trailingComma": "all", 6 | "semi": true, 7 | "arrowParens": "avoid" 8 | } -------------------------------------------------------------------------------- /lib/prisma/.swcrc: -------------------------------------------------------------------------------- 1 | { 2 | "jsc": { 3 | "parser": { 4 | "syntax": "typescript", 5 | "tsx": false, 6 | "dynamicImport": true, 7 | "decorators": true 8 | }, 9 | "transform": { 10 | "legacyDecorator": true, 11 | "decoratorMetadata": true 12 | }, 13 | "target": "es2017", 14 | "externalHelpers": false, 15 | "keepClassNames": true, 16 | "loose": false, 17 | "minify": { 18 | "compress": false, 19 | "mangle": false 20 | }, 21 | "baseUrl": "src", 22 | "paths": { 23 | "@/*": ["*"], 24 | "@config": ["config"], 25 | "@controllers/*": ["controllers/*"], 26 | "@dtos/*": ["dtos/*"], 27 | "@exceptions/*": ["exceptions/*"], 28 | "@interfaces/*": ["interfaces/*"], 29 | "@middlewares/*": ["middlewares/*"], 30 | "@routes/*": ["routes/*"], 31 | "@services/*": ["services/*"], 32 | "@utils/*": ["utils/*"] 33 | } 34 | }, 35 | "module": { 36 | "type": "commonjs" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/prisma/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "node-terminal", 6 | "request": "launch", 7 | "name": "Dev typescript-express-starter", 8 | "command": "npm run dev" 9 | }, 10 | { 11 | "type": "node-terminal", 12 | "request": "launch", 13 | "name": "Start typescript-express-starter", 14 | "command": "npm run start" 15 | }, 16 | { 17 | "type": "node-terminal", 18 | "request": "launch", 19 | "name": "Test typescript-express-starter", 20 | "command": "npm run test" 21 | }, 22 | { 23 | "type": "node-terminal", 24 | "request": "launch", 25 | "name": "Lint typescript-express-starter", 26 | "command": "npm run lint" 27 | }, 28 | { 29 | "type": "node-terminal", 30 | "request": "launch", 31 | "name": "Lint:Fix typescript-express-starter", 32 | "command": "npm run lint:fix" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /lib/prisma/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true 4 | }, 5 | "editor.formatOnSave": false 6 | } 7 | -------------------------------------------------------------------------------- /lib/prisma/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV development 15 | 16 | EXPOSE 3000 17 | 18 | # Cmd script 19 | CMD ["npm", "run", "dev"] 20 | -------------------------------------------------------------------------------- /lib/prisma/Dockerfile.prod: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV production 15 | 16 | EXPOSE 3000 17 | 18 | # Cmd script 19 | CMD ["npm", "run", "start"] 20 | -------------------------------------------------------------------------------- /lib/prisma/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.9" 2 | 3 | services: 4 | proxy: 5 | container_name: proxy 6 | image: nginx:alpine 7 | ports: 8 | - "80:80" 9 | volumes: 10 | - ./nginx.conf:/etc/nginx/nginx.conf 11 | restart: "unless-stopped" 12 | networks: 13 | - backend 14 | 15 | server: 16 | container_name: server 17 | build: 18 | context: ./ 19 | dockerfile: Dockerfile.dev 20 | ports: 21 | - "3000:3000" 22 | environment: 23 | DATABASE_URL: mysql://root:password@localhost:3306/dev 24 | volumes: 25 | - ./:/app 26 | - /app/node_modules 27 | restart: "unless-stopped" 28 | networks: 29 | - backend 30 | links: 31 | - mysql 32 | depends_on: 33 | - mysql 34 | 35 | mysql: 36 | container_name: mysql 37 | image: mysql:5.7 38 | environment: 39 | DATABASE_URL: mysql://root:password@localhost:3306/dev 40 | ports: 41 | - "3306:3306" 42 | networks: 43 | - backend 44 | 45 | networks: 46 | backend: 47 | driver: bridge 48 | 49 | volumes: 50 | data: 51 | driver: local 52 | -------------------------------------------------------------------------------- /lib/prisma/jest.config.js: -------------------------------------------------------------------------------- 1 | const { pathsToModuleNameMapper } = require('ts-jest'); 2 | const { compilerOptions } = require('./tsconfig.json'); 3 | 4 | module.exports = { 5 | preset: 'ts-jest', 6 | testEnvironment: 'node', 7 | roots: ['/src'], 8 | transform: { 9 | '^.+\\.tsx?$': 'ts-jest', 10 | }, 11 | moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '/src' }), 12 | }; 13 | -------------------------------------------------------------------------------- /lib/prisma/nginx.conf: -------------------------------------------------------------------------------- 1 | user nginx; 2 | worker_processes 1; 3 | 4 | error_log /var/log/nginx/error.log warn; 5 | pid /var/run/nginx.pid; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | http { 12 | include /etc/nginx/mime.types; 13 | default_type application/octet-stream; 14 | 15 | upstream api-server { 16 | server server:3000; 17 | keepalive 100; 18 | } 19 | 20 | server { 21 | listen 80; 22 | server_name localhost; 23 | 24 | location / { 25 | proxy_http_version 1.1; 26 | proxy_pass http://api-server; 27 | } 28 | 29 | } 30 | 31 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 32 | '$status $body_bytes_sent "$http_referer" ' 33 | '"$http_user_agent" "$http_x_forwarded_for"'; 34 | 35 | access_log /var/log/nginx/access.log main; 36 | 37 | sendfile on; 38 | keepalive_timeout 65; 39 | include /etc/nginx/conf.d/*.conf; 40 | } 41 | -------------------------------------------------------------------------------- /lib/prisma/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": [ 3 | "src", 4 | ".env" 5 | ], 6 | "ext": "js,ts,json", 7 | "ignore": [ 8 | "src/logs/*", 9 | "src/**/*.{spec,test}.ts" 10 | ], 11 | "exec": "ts-node -r tsconfig-paths/register --transpile-only src/server.ts" 12 | } -------------------------------------------------------------------------------- /lib/prisma/src/config/index.ts: -------------------------------------------------------------------------------- 1 | import { config } from 'dotenv'; 2 | config({ path: `.env.${process.env.NODE_ENV || 'development'}.local` }); 3 | 4 | export const CREDENTIALS = process.env.CREDENTIALS === 'true'; 5 | export const { NODE_ENV, PORT, SECRET_KEY, LOG_FORMAT, LOG_DIR, ORIGIN } = process.env; 6 | -------------------------------------------------------------------------------- /lib/prisma/src/dtos/users.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsEmail, IsString, IsNotEmpty, MinLength, MaxLength } from 'class-validator'; 2 | 3 | export class CreateUserDto { 4 | @IsEmail() 5 | public email: string; 6 | 7 | @IsString() 8 | @IsNotEmpty() 9 | @MinLength(9) 10 | @MaxLength(32) 11 | public password: string; 12 | } 13 | 14 | export class UpdateUserDto { 15 | @IsString() 16 | @IsNotEmpty() 17 | @MinLength(9) 18 | @MaxLength(32) 19 | public password: string; 20 | } 21 | -------------------------------------------------------------------------------- /lib/prisma/src/exceptions/HttpException.ts: -------------------------------------------------------------------------------- 1 | export class HttpException extends Error { 2 | public status: number; 3 | public message: string; 4 | 5 | constructor(status: number, message: string) { 6 | super(message); 7 | this.status = status; 8 | this.message = message; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/prisma/src/http/auth.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # User Signup 6 | POST {{ baseURL }}/signup 7 | Content-Type: application/json 8 | 9 | { 10 | "email": "example@email.com", 11 | "password": "password" 12 | } 13 | 14 | ### 15 | # User Login 16 | POST {{ baseURL }}/login 17 | Content-Type: application/json 18 | 19 | { 20 | "email": "example@email.com", 21 | "password": "password" 22 | } 23 | 24 | ### 25 | # User Logout 26 | POST {{ baseURL }}/logout 27 | Content-Type: application/json 28 | -------------------------------------------------------------------------------- /lib/prisma/src/http/users.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # Find All Users 6 | GET {{ baseURL }}/users 7 | 8 | ### 9 | # Find User By Id 10 | GET {{ baseURL }}/users/1 11 | 12 | ### 13 | # Create User 14 | POST {{ baseURL }}/users 15 | Content-Type: application/json 16 | 17 | { 18 | "email": "example@email.com", 19 | "password": "password" 20 | } 21 | 22 | ### 23 | # Modify User By Id 24 | PUT {{ baseURL }}/users/1 25 | Content-Type: application/json 26 | 27 | { 28 | "email": "example@email.com", 29 | "password": "password" 30 | } 31 | 32 | ### 33 | # Delete User By Id 34 | DELETE {{ baseURL }}/users/1 35 | -------------------------------------------------------------------------------- /lib/prisma/src/interfaces/auth.interface.ts: -------------------------------------------------------------------------------- 1 | import { Request } from 'express'; 2 | import { User } from '@interfaces/users.interface'; 3 | 4 | export interface DataStoredInToken { 5 | id: number; 6 | } 7 | 8 | export interface TokenData { 9 | token: string; 10 | expiresIn: number; 11 | } 12 | 13 | export interface RequestWithUser extends Request { 14 | user: User; 15 | } 16 | -------------------------------------------------------------------------------- /lib/prisma/src/interfaces/routes.interface.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | 3 | export interface Routes { 4 | path?: string; 5 | router: Router; 6 | } 7 | -------------------------------------------------------------------------------- /lib/prisma/src/interfaces/users.interface.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | id?: number; 3 | email: string; 4 | password: string; 5 | } 6 | -------------------------------------------------------------------------------- /lib/prisma/src/middlewares/error.middleware.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from 'express'; 2 | import { HttpException } from '@exceptions/httpException'; 3 | import { logger } from '@utils/logger'; 4 | 5 | export const ErrorMiddleware = (error: HttpException, req: Request, res: Response, next: NextFunction) => { 6 | try { 7 | const status: number = error.status || 500; 8 | const message: string = error.message || 'Something went wrong'; 9 | 10 | logger.error(`[${req.method}] ${req.path} >> StatusCode:: ${status}, Message:: ${message}`); 11 | res.status(status).json({ message }); 12 | } catch (error) { 13 | next(error); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /lib/prisma/src/prisma/migrations/20210314081925_initial/migration.sql: -------------------------------------------------------------------------------- 1 | -- CreateTable 2 | CREATE TABLE `User` ( 3 | `id` INTEGER NOT NULL AUTO_INCREMENT, 4 | `email` VARCHAR(191) NOT NULL, 5 | `password` VARCHAR(191) NOT NULL, 6 | UNIQUE INDEX `User.email_unique`(`email`), 7 | 8 | PRIMARY KEY (`id`) 9 | ) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; 10 | -------------------------------------------------------------------------------- /lib/prisma/src/prisma/migrations/migration_lock.toml: -------------------------------------------------------------------------------- 1 | # Please do not edit this file manually 2 | # It should be added in your version-control system (i.e. Git) 3 | provider = "mysql" -------------------------------------------------------------------------------- /lib/prisma/src/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | // This is your Prisma schema file, 2 | // learn more about it in the docs: https://pris.ly/d/prisma-schema 3 | 4 | datasource db { 5 | provider = "mysql" 6 | url = env("DATABASE_URL") 7 | } 8 | 9 | generator client { 10 | provider = "prisma-client-js" 11 | } 12 | 13 | model User { 14 | id Int @id @default(autoincrement()) 15 | email String @unique 16 | password String 17 | } 18 | -------------------------------------------------------------------------------- /lib/prisma/src/routes/auth.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { AuthController } from '@controllers/auth.controller'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { AuthMiddleware } from '@middlewares/auth.middleware'; 6 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 7 | 8 | export class AuthRoute implements Routes { 9 | public path = '/'; 10 | public router = Router(); 11 | public auth = new AuthController(); 12 | 13 | constructor() { 14 | this.initializeRoutes(); 15 | } 16 | 17 | private initializeRoutes() { 18 | this.router.post(`${this.path}signup`, ValidationMiddleware(CreateUserDto), this.auth.signUp); 19 | this.router.post(`${this.path}login`, ValidationMiddleware(CreateUserDto), this.auth.logIn); 20 | this.router.post(`${this.path}logout`, AuthMiddleware, this.auth.logOut); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/prisma/src/routes/users.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { UserController } from '@controllers/users.controller'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 6 | 7 | export class UserRoute implements Routes { 8 | public path = '/users'; 9 | public router = Router(); 10 | public user = new UserController(); 11 | 12 | constructor() { 13 | this.initializeRoutes(); 14 | } 15 | 16 | private initializeRoutes() { 17 | this.router.get(`${this.path}`, this.user.getUsers); 18 | this.router.get(`${this.path}/:id(\\d+)`, this.user.getUserById); 19 | this.router.post(`${this.path}`, ValidationMiddleware(CreateUserDto), this.user.createUser); 20 | this.router.put(`${this.path}/:id(\\d+)`, ValidationMiddleware(CreateUserDto, true), this.user.updateUser); 21 | this.router.delete(`${this.path}/:id(\\d+)`, this.user.deleteUser); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/prisma/src/server.ts: -------------------------------------------------------------------------------- 1 | import { App } from '@/app'; 2 | import { AuthRoute } from '@routes/auth.route'; 3 | import { UserRoute } from '@routes/users.route'; 4 | import { ValidateEnv } from '@utils/validateEnv'; 5 | 6 | ValidateEnv(); 7 | 8 | const app = new App([new UserRoute(), new AuthRoute()]); 9 | 10 | app.listen(); 11 | -------------------------------------------------------------------------------- /lib/prisma/src/test/index.test.ts: -------------------------------------------------------------------------------- 1 | import request from 'supertest'; 2 | import App from '@/app'; 3 | import IndexRoute from '@routes/index.route'; 4 | 5 | afterAll(async () => { 6 | await new Promise(resolve => setTimeout(() => resolve(), 500)); 7 | }); 8 | 9 | describe('Testing Index', () => { 10 | describe('[GET] /', () => { 11 | it('response statusCode 200', () => { 12 | const indexRoute = new IndexRoute(); 13 | const app = new App([indexRoute]); 14 | 15 | return request(app.getServer()).get(`${indexRoute.path}`).expect(200); 16 | }); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /lib/prisma/src/utils/validateEnv.ts: -------------------------------------------------------------------------------- 1 | import { cleanEnv, port, str } from 'envalid'; 2 | 3 | export const ValidateEnv = () => { 4 | cleanEnv(process.env, { 5 | NODE_ENV: str(), 6 | PORT: port(), 7 | }); 8 | }; 9 | -------------------------------------------------------------------------------- /lib/routing-controllers/.dockerignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | .vscode 3 | /node_modules 4 | 5 | # code formatter 6 | .eslintrc 7 | .eslintignore 8 | .editorconfig 9 | .huskyrc 10 | .lintstagedrc.json 11 | .prettierrc 12 | 13 | # test 14 | jest.config.js 15 | 16 | # docker 17 | Dockerfile 18 | docker-compose.yml 19 | -------------------------------------------------------------------------------- /lib/routing-controllers/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /lib/routing-controllers/.env.development.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # TOKEN 5 | SECRET_KEY = secretKey 6 | 7 | # LOG 8 | LOG_FORMAT = dev 9 | LOG_DIR = ../logs 10 | 11 | # CORS 12 | ORIGIN = * 13 | CREDENTIALS = true 14 | -------------------------------------------------------------------------------- /lib/routing-controllers/.env.production.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # TOKEN 5 | SECRET_KEY = secretKey 6 | 7 | # LOG 8 | LOG_FORMAT = combined 9 | LOG_DIR = ../logs 10 | 11 | # CORS 12 | ORIGIN = your.domain.com 13 | CREDENTIALS = true 14 | -------------------------------------------------------------------------------- /lib/routing-controllers/.env.test.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # TOKEN 5 | SECRET_KEY = secretKey 6 | 7 | # LOG 8 | LOG_FORMAT = dev 9 | LOG_DIR = ../logs 10 | 11 | # CORS 12 | ORIGIN = * 13 | CREDENTIALS = true 14 | -------------------------------------------------------------------------------- /lib/routing-controllers/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist -------------------------------------------------------------------------------- /lib/routing-controllers/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": ["prettier", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"], 4 | "parserOptions": { 5 | "ecmaVersion": 2018, 6 | "sourceType": "module" 7 | }, 8 | "rules": { 9 | "@typescript-eslint/explicit-member-accessibility": 0, 10 | "@typescript-eslint/explicit-function-return-type": 0, 11 | "@typescript-eslint/no-parameter-properties": 0, 12 | "@typescript-eslint/interface-name-prefix": 0, 13 | "@typescript-eslint/explicit-module-boundary-types": 0, 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/ban-types": "off", 16 | "@typescript-eslint/no-var-requires": "off" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/routing-controllers/.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "lint-staged" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/routing-controllers/.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "*.ts": [ 3 | "npm run lint" 4 | ] 5 | } -------------------------------------------------------------------------------- /lib/routing-controllers/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 150, 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "trailingComma": "all", 6 | "semi": true, 7 | "arrowParens": "avoid" 8 | } -------------------------------------------------------------------------------- /lib/routing-controllers/.swcrc: -------------------------------------------------------------------------------- 1 | { 2 | "jsc": { 3 | "parser": { 4 | "syntax": "typescript", 5 | "tsx": false, 6 | "dynamicImport": true, 7 | "decorators": true 8 | }, 9 | "transform": { 10 | "legacyDecorator": true, 11 | "decoratorMetadata": true 12 | }, 13 | "target": "es2017", 14 | "externalHelpers": false, 15 | "keepClassNames": true, 16 | "loose": false, 17 | "minify": { 18 | "compress": false, 19 | "mangle": false 20 | }, 21 | "baseUrl": "src", 22 | "paths": { 23 | "@/*": ["*"], 24 | "@config": ["config"], 25 | "@controllers/*": ["controllers/*"], 26 | "@dtos/*": ["dtos/*"], 27 | "@exceptions/*": ["exceptions/*"], 28 | "@interfaces/*": ["interfaces/*"], 29 | "@middlewares/*": ["middlewares/*"], 30 | "@models/*": ["models/*"], 31 | "@services/*": ["services/*"], 32 | "@utils/*": ["utils/*"] 33 | } 34 | }, 35 | "module": { 36 | "type": "commonjs" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/routing-controllers/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true 4 | }, 5 | "editor.formatOnSave": false 6 | } 7 | -------------------------------------------------------------------------------- /lib/routing-controllers/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV development 15 | 16 | EXPOSE 3000 17 | 18 | # Cmd script 19 | CMD ["npm", "run", "dev"] 20 | -------------------------------------------------------------------------------- /lib/routing-controllers/Dockerfile.prod: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV production 15 | 16 | EXPOSE 3000 17 | 18 | # Cmd script 19 | CMD ["npm", "run", "start"] 20 | -------------------------------------------------------------------------------- /lib/routing-controllers/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.9" 2 | 3 | services: 4 | proxy: 5 | container_name: proxy 6 | image: nginx:alpine 7 | ports: 8 | - "80:80" 9 | volumes: 10 | - ./nginx.conf:/etc/nginx/nginx.conf 11 | restart: "unless-stopped" 12 | networks: 13 | - backend 14 | 15 | server: 16 | container_name: server 17 | build: 18 | context: ./ 19 | dockerfile: Dockerfile.dev 20 | ports: 21 | - "3000:3000" 22 | volumes: 23 | - ./:/app 24 | - /app/node_modules 25 | restart: "unless-stopped" 26 | networks: 27 | - backend 28 | 29 | networks: 30 | backend: 31 | driver: bridge 32 | 33 | volumes: 34 | data: 35 | driver: local 36 | -------------------------------------------------------------------------------- /lib/routing-controllers/jest.config.js: -------------------------------------------------------------------------------- 1 | const { pathsToModuleNameMapper } = require('ts-jest'); 2 | const { compilerOptions } = require('./tsconfig.json'); 3 | 4 | module.exports = { 5 | preset: 'ts-jest', 6 | testEnvironment: 'node', 7 | roots: ['/src'], 8 | transform: { 9 | '^.+\\.tsx?$': 'ts-jest', 10 | }, 11 | moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '/src' }), 12 | }; 13 | -------------------------------------------------------------------------------- /lib/routing-controllers/nginx.conf: -------------------------------------------------------------------------------- 1 | user nginx; 2 | worker_processes 1; 3 | 4 | error_log /var/log/nginx/error.log warn; 5 | pid /var/run/nginx.pid; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | http { 12 | include /etc/nginx/mime.types; 13 | default_type application/octet-stream; 14 | 15 | upstream api-server { 16 | server server:3000; 17 | keepalive 100; 18 | } 19 | 20 | server { 21 | listen 80; 22 | server_name localhost; 23 | 24 | location / { 25 | proxy_http_version 1.1; 26 | proxy_pass http://api-server; 27 | } 28 | 29 | } 30 | 31 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 32 | '$status $body_bytes_sent "$http_referer" ' 33 | '"$http_user_agent" "$http_x_forwarded_for"'; 34 | 35 | access_log /var/log/nginx/access.log main; 36 | 37 | sendfile on; 38 | keepalive_timeout 65; 39 | include /etc/nginx/conf.d/*.conf; 40 | } 41 | -------------------------------------------------------------------------------- /lib/routing-controllers/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": [ 3 | "src", 4 | ".env" 5 | ], 6 | "ext": "js,ts,json", 7 | "ignore": [ 8 | "src/logs/*", 9 | "src/**/*.{spec,test}.ts" 10 | ], 11 | "exec": "ts-node -r tsconfig-paths/register --transpile-only src/server.ts" 12 | } -------------------------------------------------------------------------------- /lib/routing-controllers/src/config/index.ts: -------------------------------------------------------------------------------- 1 | import { config } from 'dotenv'; 2 | config({ path: `.env.${process.env.NODE_ENV || 'development'}.local` }); 3 | 4 | export const CREDENTIALS = process.env.CREDENTIALS === 'true'; 5 | export const { NODE_ENV, PORT, SECRET_KEY, LOG_FORMAT, LOG_DIR, ORIGIN } = process.env; 6 | -------------------------------------------------------------------------------- /lib/routing-controllers/src/dtos/users.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsEmail, IsString, IsNotEmpty, MinLength, MaxLength } from 'class-validator'; 2 | 3 | export class CreateUserDto { 4 | @IsEmail() 5 | public email: string; 6 | 7 | @IsString() 8 | @IsNotEmpty() 9 | @MinLength(9) 10 | @MaxLength(32) 11 | public password: string; 12 | } 13 | 14 | export class UpdateUserDto { 15 | @IsString() 16 | @IsNotEmpty() 17 | @MinLength(9) 18 | @MaxLength(32) 19 | public password: string; 20 | } 21 | -------------------------------------------------------------------------------- /lib/routing-controllers/src/exceptions/HttpException.ts: -------------------------------------------------------------------------------- 1 | import { HttpError } from 'routing-controllers'; 2 | 3 | export class HttpException extends HttpError { 4 | public status: number; 5 | public message: string; 6 | 7 | constructor(status: number, message: string) { 8 | super(status, message); 9 | this.status = status; 10 | this.message = message; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /lib/routing-controllers/src/http/auth.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # User Signup 6 | POST {{ baseURL }}/signup 7 | Content-Type: application/json 8 | 9 | { 10 | "email": "example@email.com", 11 | "password": "password" 12 | } 13 | 14 | ### 15 | # User Login 16 | POST {{ baseURL }}/login 17 | Content-Type: application/json 18 | 19 | { 20 | "email": "example@email.com", 21 | "password": "password" 22 | } 23 | 24 | ### 25 | # User Logout 26 | POST {{ baseURL }}/logout 27 | Content-Type: application/json 28 | -------------------------------------------------------------------------------- /lib/routing-controllers/src/http/users.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # Find All Users 6 | GET {{ baseURL }}/users 7 | 8 | ### 9 | # Find User By Id 10 | GET {{ baseURL }}/users/1 11 | 12 | ### 13 | # Create User 14 | POST {{ baseURL }}/users 15 | Content-Type: application/json 16 | 17 | { 18 | "email": "example@email.com", 19 | "password": "password" 20 | } 21 | 22 | ### 23 | # Modify User By Id 24 | PUT {{ baseURL }}/users/1 25 | Content-Type: application/json 26 | 27 | { 28 | "email": "example@email.com", 29 | "password": "password" 30 | } 31 | 32 | ### 33 | # Delete User By Id 34 | DELETE {{ baseURL }}/users/1 35 | -------------------------------------------------------------------------------- /lib/routing-controllers/src/interfaces/auth.interface.ts: -------------------------------------------------------------------------------- 1 | import { Request } from 'express'; 2 | import { User } from '@interfaces/users.interface'; 3 | 4 | export interface DataStoredInToken { 5 | id: number; 6 | } 7 | 8 | export interface TokenData { 9 | token: string; 10 | expiresIn: number; 11 | } 12 | 13 | export interface RequestWithUser extends Request { 14 | user: User; 15 | } 16 | -------------------------------------------------------------------------------- /lib/routing-controllers/src/interfaces/users.interface.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | id?: number; 3 | email: string; 4 | password: string; 5 | } 6 | -------------------------------------------------------------------------------- /lib/routing-controllers/src/middlewares/error.middleware.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from 'express'; 2 | import { HttpException } from '@exceptions/httpException'; 3 | import { logger } from '@utils/logger'; 4 | 5 | export const ErrorMiddleware = (error: HttpException, req: Request, res: Response, next: NextFunction) => { 6 | try { 7 | const status: number = error.status || 500; 8 | const message: string = error.message || 'Something went wrong'; 9 | 10 | logger.error(`[${req.method}] ${req.path} >> StatusCode:: ${status}, Message:: ${message}`); 11 | res.status(status).json({ message }); 12 | } catch (error) { 13 | next(error); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /lib/routing-controllers/src/models/users.model.ts: -------------------------------------------------------------------------------- 1 | import { User } from '@interfaces/users.interface'; 2 | 3 | // password: password 4 | export const UserModel: User[] = [ 5 | { id: 1, email: 'example1@email.com', password: '$2b$10$TBEfaCe1oo.2jfkBDWcj/usBj4oECsW2wOoDXpCa2IH9xqCpEK/hC' }, 6 | { id: 2, email: 'example2@email.com', password: '$2b$10$TBEfaCe1oo.2jfkBDWcj/usBj4oECsW2wOoDXpCa2IH9xqCpEK/hC' }, 7 | { id: 3, email: 'example3@email.com', password: '$2b$10$TBEfaCe1oo.2jfkBDWcj/usBj4oECsW2wOoDXpCa2IH9xqCpEK/hC' }, 8 | { id: 4, email: 'example4@email.com', password: '$2b$10$TBEfaCe1oo.2jfkBDWcj/usBj4oECsW2wOoDXpCa2IH9xqCpEK/hC' }, 9 | ]; 10 | -------------------------------------------------------------------------------- /lib/routing-controllers/src/server.ts: -------------------------------------------------------------------------------- 1 | import { App } from '@/app'; 2 | import { AuthController } from '@controllers/auth.controller'; 3 | import { UserController } from '@controllers/users.controller'; 4 | import { ValidateEnv } from '@utils/validateEnv'; 5 | 6 | ValidateEnv(); 7 | 8 | const app = new App([AuthController, UserController]); 9 | app.listen(); 10 | -------------------------------------------------------------------------------- /lib/routing-controllers/src/utils/validateEnv.ts: -------------------------------------------------------------------------------- 1 | import { cleanEnv, port, str } from 'envalid'; 2 | 3 | export const ValidateEnv = () => { 4 | cleanEnv(process.env, { 5 | NODE_ENV: str(), 6 | PORT: port(), 7 | }); 8 | }; 9 | -------------------------------------------------------------------------------- /lib/sequelize/.dockerignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | .vscode 3 | /node_modules 4 | 5 | # code formatter 6 | .eslintrc 7 | .eslintignore 8 | .editorconfig 9 | .huskyrc 10 | .lintstagedrc.json 11 | .prettierrc 12 | 13 | # test 14 | jest.config.js 15 | 16 | # docker 17 | Dockerfile 18 | docker-compose.yml 19 | -------------------------------------------------------------------------------- /lib/sequelize/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /lib/sequelize/.env.development.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DB_USER = root 6 | DB_PASSWORD = password 7 | DB_HOST = localhost 8 | DB_PORT = 3306 9 | DB_DATABASE = dev 10 | 11 | # TOKEN 12 | SECRET_KEY = secretKey 13 | 14 | # LOG 15 | LOG_FORMAT = dev 16 | LOG_DIR = ../logs 17 | 18 | # CORS 19 | ORIGIN = * 20 | CREDENTIALS = true 21 | -------------------------------------------------------------------------------- /lib/sequelize/.env.production.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DB_USER = root 6 | DB_PASSWORD = password 7 | DB_HOST = localhost 8 | DB_PORT = 3306 9 | DB_DATABASE = dev 10 | 11 | # TOKEN 12 | SECRET_KEY = secretKey 13 | 14 | # LOG 15 | LOG_FORMAT = combined 16 | LOG_DIR = ../logs 17 | 18 | # CORS 19 | ORIGIN = your.domain.com 20 | CREDENTIALS = true 21 | -------------------------------------------------------------------------------- /lib/sequelize/.env.test.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DB_USER = root 6 | DB_PASSWORD = password 7 | DB_HOST = localhost 8 | DB_PORT = 3306 9 | DB_DATABASE = dev 10 | 11 | # TOKEN 12 | SECRET_KEY = secretKey 13 | 14 | # LOG 15 | LOG_FORMAT = dev 16 | LOG_DIR = ../logs 17 | 18 | # CORS 19 | ORIGIN = * 20 | CREDENTIALS = true 21 | -------------------------------------------------------------------------------- /lib/sequelize/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist -------------------------------------------------------------------------------- /lib/sequelize/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": ["prettier", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"], 4 | "parserOptions": { 5 | "ecmaVersion": 2018, 6 | "sourceType": "module" 7 | }, 8 | "rules": { 9 | "@typescript-eslint/explicit-member-accessibility": 0, 10 | "@typescript-eslint/explicit-function-return-type": 0, 11 | "@typescript-eslint/no-parameter-properties": 0, 12 | "@typescript-eslint/interface-name-prefix": 0, 13 | "@typescript-eslint/explicit-module-boundary-types": 0, 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/ban-types": "off", 16 | "@typescript-eslint/no-var-requires": "off" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/sequelize/.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "lint-staged" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/sequelize/.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "*.ts": [ 3 | "npm run lint" 4 | ] 5 | } -------------------------------------------------------------------------------- /lib/sequelize/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 150, 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "trailingComma": "all", 6 | "semi": true, 7 | "arrowParens": "avoid" 8 | } -------------------------------------------------------------------------------- /lib/sequelize/.sequelizerc: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | config: path.resolve('src', 'config', 'sequelize-cli.js'), 5 | 'models-path': path.resolve('src', 'models'), 6 | 'seeders-path': path.resolve('src', 'database', 'seeders'), 7 | 'migrations-path': path.resolve('src', 'database', 'migrations'), 8 | }; 9 | -------------------------------------------------------------------------------- /lib/sequelize/.swcrc: -------------------------------------------------------------------------------- 1 | { 2 | "jsc": { 3 | "parser": { 4 | "syntax": "typescript", 5 | "tsx": false, 6 | "dynamicImport": true, 7 | "decorators": true 8 | }, 9 | "transform": { 10 | "legacyDecorator": true, 11 | "decoratorMetadata": true 12 | }, 13 | "target": "es2017", 14 | "externalHelpers": false, 15 | "keepClassNames": true, 16 | "loose": false, 17 | "minify": { 18 | "compress": false, 19 | "mangle": false 20 | }, 21 | "baseUrl": "src", 22 | "paths": { 23 | "@/*": ["*"], 24 | "@config": ["config"], 25 | "@controllers/*": ["controllers/*"], 26 | "@database": ["database"], 27 | "@dtos/*": ["dtos/*"], 28 | "@exceptions/*": ["exceptions/*"], 29 | "@interfaces/*": ["interfaces/*"], 30 | "@middlewares/*": ["middlewares/*"], 31 | "@models/*": ["models/*"], 32 | "@routes/*": ["routes/*"], 33 | "@services/*": ["services/*"], 34 | "@utils/*": ["utils/*"] 35 | } 36 | }, 37 | "module": { 38 | "type": "commonjs" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/sequelize/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "node-terminal", 6 | "request": "launch", 7 | "name": "Dev typescript-express-starter", 8 | "command": "npm run dev" 9 | }, 10 | { 11 | "type": "node-terminal", 12 | "request": "launch", 13 | "name": "Start typescript-express-starter", 14 | "command": "npm run start" 15 | }, 16 | { 17 | "type": "node-terminal", 18 | "request": "launch", 19 | "name": "Test typescript-express-starter", 20 | "command": "npm run test" 21 | }, 22 | { 23 | "type": "node-terminal", 24 | "request": "launch", 25 | "name": "Lint typescript-express-starter", 26 | "command": "npm run lint" 27 | }, 28 | { 29 | "type": "node-terminal", 30 | "request": "launch", 31 | "name": "Lint:Fix typescript-express-starter", 32 | "command": "npm run lint:fix" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /lib/sequelize/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true 4 | }, 5 | "editor.formatOnSave": false 6 | } 7 | -------------------------------------------------------------------------------- /lib/sequelize/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | RUN chmod +x /app/docker-entrypoint.sh 14 | 15 | ENTRYPOINT [ "docker-entrypoint.sh" ] 16 | 17 | # Set Env 18 | ENV NODE_ENV development 19 | 20 | EXPOSE 3000 21 | 22 | # Cmd script 23 | CMD ["npm", "run", "dev"] 24 | -------------------------------------------------------------------------------- /lib/sequelize/Dockerfile.prod: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | RUN chmod +x /app/docker-entrypoint.sh 14 | 15 | ENTRYPOINT [ "docker-entrypoint.sh" ] 16 | 17 | # Set Env 18 | ENV NODE_ENV production 19 | 20 | EXPOSE 3000 21 | 22 | # Cmd script 23 | CMD ["npm", "run", "start"] 24 | -------------------------------------------------------------------------------- /lib/sequelize/docker-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | dockerize -wait tcp://mysql:3306 -timeout 20s 4 | 5 | echo "Start Wait Mysql" 6 | -------------------------------------------------------------------------------- /lib/sequelize/jest.config.js: -------------------------------------------------------------------------------- 1 | const { pathsToModuleNameMapper } = require('ts-jest'); 2 | const { compilerOptions } = require('./tsconfig.json'); 3 | 4 | module.exports = { 5 | preset: 'ts-jest', 6 | testEnvironment: 'node', 7 | roots: ['/src'], 8 | transform: { 9 | '^.+\\.tsx?$': 'ts-jest', 10 | }, 11 | moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '/src' }), 12 | }; 13 | -------------------------------------------------------------------------------- /lib/sequelize/nginx.conf: -------------------------------------------------------------------------------- 1 | user nginx; 2 | worker_processes 1; 3 | 4 | error_log /var/log/nginx/error.log warn; 5 | pid /var/run/nginx.pid; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | http { 12 | include /etc/nginx/mime.types; 13 | default_type application/octet-stream; 14 | 15 | upstream api-server { 16 | server server:3000; 17 | keepalive 100; 18 | } 19 | 20 | server { 21 | listen 80; 22 | server_name localhost; 23 | 24 | location / { 25 | proxy_http_version 1.1; 26 | proxy_pass http://api-server; 27 | } 28 | 29 | } 30 | 31 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 32 | '$status $body_bytes_sent "$http_referer" ' 33 | '"$http_user_agent" "$http_x_forwarded_for"'; 34 | 35 | access_log /var/log/nginx/access.log main; 36 | 37 | sendfile on; 38 | keepalive_timeout 65; 39 | include /etc/nginx/conf.d/*.conf; 40 | } 41 | -------------------------------------------------------------------------------- /lib/sequelize/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": [ 3 | "src", 4 | ".env" 5 | ], 6 | "ext": "js,ts,json", 7 | "ignore": [ 8 | "src/logs/*", 9 | "src/**/*.{spec,test}.ts" 10 | ], 11 | "exec": "ts-node -r tsconfig-paths/register --transpile-only src/server.ts" 12 | } -------------------------------------------------------------------------------- /lib/sequelize/src/config/index.ts: -------------------------------------------------------------------------------- 1 | import { config } from 'dotenv'; 2 | config({ path: `.env.${process.env.NODE_ENV || 'development'}.local` }); 3 | 4 | export const CREDENTIALS = process.env.CREDENTIALS === 'true'; 5 | export const { NODE_ENV, PORT, SECRET_KEY, LOG_FORMAT, LOG_DIR, ORIGIN } = process.env; 6 | export const { DB_USER, DB_PASSWORD, DB_HOST, DB_PORT, DB_DATABASE } = process.env; 7 | -------------------------------------------------------------------------------- /lib/sequelize/src/config/sequelize-cli.js: -------------------------------------------------------------------------------- 1 | const { config } = require("dotenv"); 2 | config({ path: `.env.${process.env.NODE_ENV || "development"}.local` }); 3 | 4 | const { DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_DATABASE } = process.env; 5 | 6 | module.exports = { 7 | username: DB_USER, 8 | password: DB_PASSWORD, 9 | database: DB_DATABASE, 10 | port: DB_PORT, 11 | host: DB_HOST, 12 | dialect: "mysql", 13 | migrationStorageTableName: "sequelize_migrations", 14 | seederStorageTableName: "sequelize_seeds", 15 | }; 16 | -------------------------------------------------------------------------------- /lib/sequelize/src/database/index.ts: -------------------------------------------------------------------------------- 1 | import Sequelize from 'sequelize'; 2 | import { NODE_ENV, DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_DATABASE } from '@config'; 3 | import UserModel from '@models/users.model'; 4 | import { logger } from '@utils/logger'; 5 | 6 | const sequelize = new Sequelize.Sequelize(DB_DATABASE, DB_USER, DB_PASSWORD, { 7 | dialect: 'mysql', 8 | host: DB_HOST, 9 | port: DB_PORT, 10 | timezone: '+09:00', 11 | define: { 12 | charset: 'utf8mb4', 13 | collate: 'utf8mb4_general_ci', 14 | underscored: true, 15 | freezeTableName: true, 16 | }, 17 | pool: { 18 | min: 0, 19 | max: 5, 20 | }, 21 | logQueryParameters: NODE_ENV === 'development', 22 | logging: (query, time) => { 23 | logger.info(time + 'ms' + ' ' + query); 24 | }, 25 | benchmark: true, 26 | }); 27 | 28 | sequelize.authenticate(); 29 | 30 | export const DB = { 31 | Users: UserModel(sequelize), 32 | sequelize, // connection instance (RAW queries) 33 | Sequelize, // library 34 | }; 35 | -------------------------------------------------------------------------------- /lib/sequelize/src/database/migrations/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljlm0402/typescript-express-starter/572dfd9bfdfc3b3f3e9e55b834be73445b1acf9a/lib/sequelize/src/database/migrations/.gitkeep -------------------------------------------------------------------------------- /lib/sequelize/src/database/seeders/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljlm0402/typescript-express-starter/572dfd9bfdfc3b3f3e9e55b834be73445b1acf9a/lib/sequelize/src/database/seeders/.gitkeep -------------------------------------------------------------------------------- /lib/sequelize/src/dtos/users.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsString, IsEmail, IsNotEmpty, MinLength, MaxLength } from 'class-validator'; 2 | 3 | export class CreateUserDto { 4 | @IsEmail() 5 | public email: string; 6 | 7 | @IsString() 8 | @IsNotEmpty() 9 | @MinLength(9) 10 | @MaxLength(32) 11 | public password: string; 12 | } 13 | 14 | export class UpdateUserDto { 15 | @IsString() 16 | @IsNotEmpty() 17 | @MinLength(9) 18 | @MaxLength(32) 19 | public password: string; 20 | } 21 | -------------------------------------------------------------------------------- /lib/sequelize/src/exceptions/HttpException.ts: -------------------------------------------------------------------------------- 1 | export class HttpException extends Error { 2 | public status: number; 3 | public message: string; 4 | 5 | constructor(status: number, message: string) { 6 | super(message); 7 | this.status = status; 8 | this.message = message; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/sequelize/src/http/auth.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # User Signup 6 | POST {{ baseURL }}/signup 7 | Content-Type: application/json 8 | 9 | { 10 | "email": "example@email.com", 11 | "password": "password" 12 | } 13 | 14 | ### 15 | # User Login 16 | POST {{ baseURL }}/login 17 | Content-Type: application/json 18 | 19 | { 20 | "email": "example@email.com", 21 | "password": "password" 22 | } 23 | 24 | ### 25 | # User Logout 26 | POST {{ baseURL }}/logout 27 | Content-Type: application/json 28 | -------------------------------------------------------------------------------- /lib/sequelize/src/http/users.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # Find All Users 6 | GET {{ baseURL }}/users 7 | 8 | ### 9 | # Find User By Id 10 | GET {{ baseURL }}/users/1 11 | 12 | ### 13 | # Create User 14 | POST {{ baseURL }}/users 15 | Content-Type: application/json 16 | 17 | { 18 | "email": "example@email.com", 19 | "password": "password" 20 | } 21 | 22 | ### 23 | # Modify User By Id 24 | PUT {{ baseURL }}/users/1 25 | Content-Type: application/json 26 | 27 | { 28 | "email": "example@email.com", 29 | "password": "password" 30 | } 31 | 32 | ### 33 | # Delete User By Id 34 | DELETE {{ baseURL }}/users/1 35 | -------------------------------------------------------------------------------- /lib/sequelize/src/interfaces/auth.interface.ts: -------------------------------------------------------------------------------- 1 | import { Request } from 'express'; 2 | import { User } from '@interfaces/users.interface'; 3 | 4 | export interface DataStoredInToken { 5 | id: number; 6 | } 7 | 8 | export interface TokenData { 9 | token: string; 10 | expiresIn: number; 11 | } 12 | 13 | export interface RequestWithUser extends Request { 14 | user: User; 15 | } 16 | -------------------------------------------------------------------------------- /lib/sequelize/src/interfaces/routes.interface.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | 3 | export interface Routes { 4 | path?: string; 5 | router: Router; 6 | } 7 | -------------------------------------------------------------------------------- /lib/sequelize/src/interfaces/users.interface.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | id?: number; 3 | email: string; 4 | password: string; 5 | } 6 | -------------------------------------------------------------------------------- /lib/sequelize/src/middlewares/error.middleware.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from 'express'; 2 | import { HttpException } from '@/exceptions/httpException'; 3 | import { logger } from '@utils/logger'; 4 | 5 | export const ErrorMiddleware = (error: HttpException, req: Request, res: Response, next: NextFunction) => { 6 | try { 7 | const status: number = error.status || 500; 8 | const message: string = error.message || 'Something went wrong'; 9 | 10 | logger.error(`[${req.method}] ${req.path} >> StatusCode:: ${status}, Message:: ${message}`); 11 | res.status(status).json({ message }); 12 | } catch (error) { 13 | next(error); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /lib/sequelize/src/models/users.model.ts: -------------------------------------------------------------------------------- 1 | import { Sequelize, DataTypes, Model, Optional } from 'sequelize'; 2 | import { User } from '@interfaces/users.interface'; 3 | 4 | export type UserCreationAttributes = Optional; 5 | 6 | export class UserModel extends Model implements User { 7 | public id: number; 8 | public email: string; 9 | public password: string; 10 | 11 | public readonly createdAt!: Date; 12 | public readonly updatedAt!: Date; 13 | } 14 | 15 | export default function (sequelize: Sequelize): typeof UserModel { 16 | UserModel.init( 17 | { 18 | id: { 19 | autoIncrement: true, 20 | primaryKey: true, 21 | type: DataTypes.INTEGER, 22 | }, 23 | email: { 24 | allowNull: false, 25 | type: DataTypes.STRING(45), 26 | }, 27 | password: { 28 | allowNull: false, 29 | type: DataTypes.STRING(255), 30 | }, 31 | }, 32 | { 33 | tableName: 'users', 34 | sequelize, 35 | }, 36 | ); 37 | 38 | return UserModel; 39 | } 40 | -------------------------------------------------------------------------------- /lib/sequelize/src/routes/auth.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { AuthController } from '@controllers/auth.controller'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { AuthMiddleware } from '@middlewares/auth.middleware'; 6 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 7 | 8 | export class AuthRoute implements Routes { 9 | public router = Router(); 10 | public auth = new AuthController(); 11 | 12 | constructor() { 13 | this.initializeRoutes(); 14 | } 15 | 16 | private initializeRoutes() { 17 | this.router.post('/signup', ValidationMiddleware(CreateUserDto), this.auth.signUp); 18 | this.router.post('/login', ValidationMiddleware(CreateUserDto), this.auth.logIn); 19 | this.router.post('/logout', AuthMiddleware, this.auth.logOut); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/sequelize/src/routes/users.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { UserController } from '@controllers/users.controller'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 6 | 7 | export class UserRoute implements Routes { 8 | public path = '/users'; 9 | public router = Router(); 10 | public user = new UserController(); 11 | 12 | constructor() { 13 | this.initializeRoutes(); 14 | } 15 | 16 | private initializeRoutes() { 17 | this.router.get(`${this.path}`, this.user.getUsers); 18 | this.router.get(`${this.path}/:id(\\d+)`, this.user.getUserById); 19 | this.router.post(`${this.path}`, ValidationMiddleware(CreateUserDto), this.user.createUser); 20 | this.router.put(`${this.path}/:id(\\d+)`, ValidationMiddleware(CreateUserDto, true), this.user.updateUser); 21 | this.router.delete(`${this.path}/:id(\\d+)`, this.user.deleteUser); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/sequelize/src/server.ts: -------------------------------------------------------------------------------- 1 | import { App } from '@/app'; 2 | import { AuthRoute } from '@routes/auth.route'; 3 | import { UserRoute } from '@routes/users.route'; 4 | import { ValidateEnv } from '@utils/validateEnv'; 5 | 6 | ValidateEnv(); 7 | 8 | const app = new App([new AuthRoute(), new UserRoute()]); 9 | 10 | app.listen(); 11 | -------------------------------------------------------------------------------- /lib/sequelize/src/utils/validateEnv.ts: -------------------------------------------------------------------------------- 1 | import { cleanEnv, port, str } from 'envalid'; 2 | 3 | export function ValidateEnv() { 4 | cleanEnv(process.env, { 5 | NODE_ENV: str(), 6 | PORT: port(), 7 | }); 8 | } 9 | -------------------------------------------------------------------------------- /lib/typegoose/.dockerignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | .vscode 3 | /node_modules 4 | 5 | # code formatter 6 | .eslintrc 7 | .eslintignore 8 | .editorconfig 9 | .huskyrc 10 | .lintstagedrc.json 11 | .prettierrc 12 | 13 | # test 14 | jest.config.js 15 | 16 | # docker 17 | Dockerfile 18 | docker-compose.yml 19 | -------------------------------------------------------------------------------- /lib/typegoose/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /lib/typegoose/.env.development.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DB_HOST = localhost 6 | DB_PORT = 27017 7 | DB_DATABASE = dev 8 | 9 | # TOKEN 10 | SECRET_KEY = secretKey 11 | 12 | # LOG 13 | LOG_FORMAT = dev 14 | LOG_DIR = ../logs 15 | 16 | # CORS 17 | ORIGIN = * 18 | CREDENTIALS = true 19 | -------------------------------------------------------------------------------- /lib/typegoose/.env.production.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DB_HOST = localhost 6 | DB_PORT = 27017 7 | DB_DATABASE = dev 8 | 9 | # TOKEN 10 | SECRET_KEY = secretKey 11 | 12 | # LOG 13 | LOG_FORMAT = combined 14 | LOG_DIR = ../logs 15 | 16 | # CORS 17 | ORIGIN = your.domain.com 18 | CREDENTIALS = true 19 | -------------------------------------------------------------------------------- /lib/typegoose/.env.test.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | DB_HOST = localhost 6 | DB_PORT = 27017 7 | DB_DATABASE = dev 8 | 9 | # TOKEN 10 | SECRET_KEY = secretKey 11 | 12 | # LOG 13 | LOG_FORMAT = dev 14 | LOG_DIR = ../logs 15 | 16 | # CORS 17 | ORIGIN = * 18 | CREDENTIALS = true 19 | -------------------------------------------------------------------------------- /lib/typegoose/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist -------------------------------------------------------------------------------- /lib/typegoose/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": ["prettier", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"], 4 | "parserOptions": { 5 | "ecmaVersion": 2018, 6 | "sourceType": "module" 7 | }, 8 | "rules": { 9 | "@typescript-eslint/explicit-member-accessibility": 0, 10 | "@typescript-eslint/explicit-function-return-type": 0, 11 | "@typescript-eslint/no-parameter-properties": 0, 12 | "@typescript-eslint/interface-name-prefix": 0, 13 | "@typescript-eslint/explicit-module-boundary-types": 0, 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/ban-types": "off", 16 | "@typescript-eslint/no-var-requires": "off" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/typegoose/.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "lint-staged" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/typegoose/.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "*.ts": [ 3 | "npm run lint" 4 | ] 5 | } -------------------------------------------------------------------------------- /lib/typegoose/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 150, 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "trailingComma": "all", 6 | "semi": true, 7 | "arrowParens": "avoid" 8 | } -------------------------------------------------------------------------------- /lib/typegoose/.swcrc: -------------------------------------------------------------------------------- 1 | { 2 | "jsc": { 3 | "parser": { 4 | "syntax": "typescript", 5 | "tsx": false, 6 | "dynamicImport": true, 7 | "decorators": true 8 | }, 9 | "transform": { 10 | "legacyDecorator": true, 11 | "decoratorMetadata": true 12 | }, 13 | "target": "es2017", 14 | "externalHelpers": false, 15 | "keepClassNames": true, 16 | "loose": false, 17 | "minify": { 18 | "compress": false, 19 | "mangle": false 20 | }, 21 | "baseUrl": "src", 22 | "paths": { 23 | "@/*": ["*"], 24 | "@config": ["config"], 25 | "@controllers/*": ["controllers/*"], 26 | "@database": ["database"], 27 | "@dtos/*": ["dtos/*"], 28 | "@exceptions/*": ["exceptions/*"], 29 | "@interfaces/*": ["interfaces/*"], 30 | "@middlewares/*": ["middlewares/*"], 31 | "@models/*": ["models/*"], 32 | "@routes/*": ["routes/*"], 33 | "@services/*": ["services/*"], 34 | "@utils/*": ["utils/*"] 35 | } 36 | }, 37 | "module": { 38 | "type": "commonjs" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/typegoose/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "node-terminal", 6 | "request": "launch", 7 | "name": "Dev typescript-express-starter", 8 | "command": "npm run dev" 9 | }, 10 | { 11 | "type": "node-terminal", 12 | "request": "launch", 13 | "name": "Start typescript-express-starter", 14 | "command": "npm run start" 15 | }, 16 | { 17 | "type": "node-terminal", 18 | "request": "launch", 19 | "name": "Test typescript-express-starter", 20 | "command": "npm run test" 21 | }, 22 | { 23 | "type": "node-terminal", 24 | "request": "launch", 25 | "name": "Lint typescript-express-starter", 26 | "command": "npm run lint" 27 | }, 28 | { 29 | "type": "node-terminal", 30 | "request": "launch", 31 | "name": "Lint:Fix typescript-express-starter", 32 | "command": "npm run lint:fix" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /lib/typegoose/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true 4 | }, 5 | "editor.formatOnSave": false 6 | } 7 | -------------------------------------------------------------------------------- /lib/typegoose/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV development 15 | 16 | EXPOSE 3000 17 | 18 | # Cmd script 19 | CMD ["npm", "run", "dev"] 20 | -------------------------------------------------------------------------------- /lib/typegoose/Dockerfile.prod: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV production 15 | 16 | EXPOSE 3000 17 | 18 | # Cmd script 19 | CMD ["npm", "run", "start"] 20 | -------------------------------------------------------------------------------- /lib/typegoose/jest.config.js: -------------------------------------------------------------------------------- 1 | const { pathsToModuleNameMapper } = require('ts-jest'); 2 | const { compilerOptions } = require('./tsconfig.json'); 3 | 4 | module.exports = { 5 | preset: 'ts-jest', 6 | testEnvironment: 'node', 7 | roots: ['/src'], 8 | transform: { 9 | '^.+\\.tsx?$': 'ts-jest', 10 | }, 11 | moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '/src' }), 12 | }; 13 | -------------------------------------------------------------------------------- /lib/typegoose/nginx.conf: -------------------------------------------------------------------------------- 1 | user nginx; 2 | worker_processes 1; 3 | 4 | error_log /var/log/nginx/error.log warn; 5 | pid /var/run/nginx.pid; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | http { 12 | include /etc/nginx/mime.types; 13 | default_type application/octet-stream; 14 | 15 | upstream api-server { 16 | server server:3000; 17 | keepalive 100; 18 | } 19 | 20 | server { 21 | listen 80; 22 | server_name localhost; 23 | 24 | location / { 25 | proxy_http_version 1.1; 26 | proxy_pass http://api-server; 27 | } 28 | 29 | } 30 | 31 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 32 | '$status $body_bytes_sent "$http_referer" ' 33 | '"$http_user_agent" "$http_x_forwarded_for"'; 34 | 35 | access_log /var/log/nginx/access.log main; 36 | 37 | sendfile on; 38 | keepalive_timeout 65; 39 | include /etc/nginx/conf.d/*.conf; 40 | } 41 | -------------------------------------------------------------------------------- /lib/typegoose/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": [ 3 | "src", 4 | ".env" 5 | ], 6 | "ext": "js,ts,json", 7 | "ignore": [ 8 | "src/logs/*", 9 | "src/**/*.{spec,test}.ts" 10 | ], 11 | "exec": "ts-node -r tsconfig-paths/register --transpile-only src/server.ts" 12 | } -------------------------------------------------------------------------------- /lib/typegoose/src/config/index.ts: -------------------------------------------------------------------------------- 1 | import { config } from 'dotenv'; 2 | config({ path: `.env.${process.env.NODE_ENV || 'development'}.local` }); 3 | 4 | export const CREDENTIALS = process.env.CREDENTIALS === 'true'; 5 | export const { NODE_ENV, PORT, SECRET_KEY, LOG_FORMAT, LOG_DIR, ORIGIN } = process.env; 6 | export const { DB_HOST, DB_PORT, DB_DATABASE } = process.env; 7 | -------------------------------------------------------------------------------- /lib/typegoose/src/database/index.ts: -------------------------------------------------------------------------------- 1 | import { connect, set } from 'mongoose'; 2 | import { NODE_ENV, DB_HOST, DB_PORT, DB_DATABASE } from '@config'; 3 | 4 | export const dbConnection = async () => { 5 | const dbConfig = { 6 | url: `mongodb://${DB_HOST}:${DB_PORT}/${DB_DATABASE}`, 7 | options: { 8 | useNewUrlParser: true, 9 | useUnifiedTopology: true 10 | }, 11 | }; 12 | 13 | if (NODE_ENV !== 'production') { 14 | set('debug', true); 15 | } 16 | 17 | await connect(dbConfig); 18 | }; 19 | -------------------------------------------------------------------------------- /lib/typegoose/src/dtos/users.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsEmail, IsString, IsNotEmpty, MinLength, MaxLength } from 'class-validator'; 2 | 3 | export class CreateUserDto { 4 | @IsEmail() 5 | public email: string; 6 | 7 | @IsString() 8 | @IsNotEmpty() 9 | @MinLength(9) 10 | @MaxLength(32) 11 | public password: string; 12 | } 13 | 14 | export class UpdateUserDto { 15 | @IsString() 16 | @IsNotEmpty() 17 | @MinLength(9) 18 | @MaxLength(32) 19 | public password: string; 20 | } 21 | -------------------------------------------------------------------------------- /lib/typegoose/src/exceptions/HttpException.ts: -------------------------------------------------------------------------------- 1 | export class HttpException extends Error { 2 | public status: number; 3 | public message: string; 4 | 5 | constructor(status: number, message: string) { 6 | super(message); 7 | this.status = status; 8 | this.message = message; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/typegoose/src/http/auth.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # User Signup 6 | POST {{ baseURL }}/signup 7 | Content-Type: application/json 8 | 9 | { 10 | "email": "example@email.com", 11 | "password": "password" 12 | } 13 | 14 | ### 15 | # User Login 16 | POST {{ baseURL }}/login 17 | Content-Type: application/json 18 | 19 | { 20 | "email": "example@email.com", 21 | "password": "password" 22 | } 23 | 24 | ### 25 | # User Logout 26 | POST {{ baseURL }}/logout 27 | Content-Type: application/json 28 | -------------------------------------------------------------------------------- /lib/typegoose/src/http/users.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # Find All Users 6 | GET {{ baseURL }}/users 7 | 8 | ### 9 | # Find User By Id 10 | GET {{ baseURL }}/users/1 11 | 12 | ### 13 | # Create User 14 | POST {{ baseURL }}/users 15 | Content-Type: application/json 16 | 17 | { 18 | "email": "example@email.com", 19 | "password": "password" 20 | } 21 | 22 | ### 23 | # Modify User By Id 24 | PUT {{ baseURL }}/users/1 25 | Content-Type: application/json 26 | 27 | { 28 | "email": "example@email.com", 29 | "password": "password" 30 | } 31 | 32 | ### 33 | # Delete User By Id 34 | DELETE {{ baseURL }}/users/1 35 | -------------------------------------------------------------------------------- /lib/typegoose/src/interfaces/auth.interface.ts: -------------------------------------------------------------------------------- 1 | import { Request } from 'express'; 2 | import { User } from '@interfaces/users.interface'; 3 | 4 | export interface DataStoredInToken { 5 | _id: string; 6 | } 7 | 8 | export interface TokenData { 9 | token: string; 10 | expiresIn: number; 11 | } 12 | 13 | export interface RequestWithUser extends Request { 14 | user: User; 15 | } 16 | -------------------------------------------------------------------------------- /lib/typegoose/src/interfaces/routes.interface.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | 3 | export interface Routes { 4 | path?: string; 5 | router: Router; 6 | } 7 | -------------------------------------------------------------------------------- /lib/typegoose/src/interfaces/users.interface.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | _id?: string; 3 | email: string; 4 | password: string; 5 | } 6 | -------------------------------------------------------------------------------- /lib/typegoose/src/middlewares/error.middleware.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from 'express'; 2 | import { HttpException } from '@/exceptions/httpException'; 3 | import { logger } from '@utils/logger'; 4 | 5 | export const ErrorMiddleware = (error: HttpException, req: Request, res: Response, next: NextFunction) => { 6 | try { 7 | const status: number = error.status || 500; 8 | const message: string = error.message || 'Something went wrong'; 9 | 10 | logger.error(`[${req.method}] ${req.path} >> StatusCode:: ${status}, Message:: ${message}`); 11 | res.status(status).json({ message }); 12 | } catch (error) { 13 | next(error); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /lib/typegoose/src/models/users.model.ts: -------------------------------------------------------------------------------- 1 | import { prop, getModelForClass, modelOptions } from '@typegoose/typegoose'; 2 | 3 | @modelOptions({ schemaOptions: { collection: 'users', timestamps: true } }) 4 | class User { 5 | @prop({ type: String, required: true, unique: true }) 6 | public email: string; 7 | 8 | @prop({ type: String, required: true }) 9 | public password: string; 10 | 11 | public createdAt?: Date; 12 | 13 | public updatedAt?: Date; 14 | } 15 | 16 | export const UserModel = getModelForClass(User); 17 | -------------------------------------------------------------------------------- /lib/typegoose/src/routes/auth.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { AuthController } from '@controllers/auth.controller'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { AuthMiddleware } from '@middlewares/auth.middleware'; 6 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 7 | 8 | export class AuthRoute implements Routes { 9 | public router = Router(); 10 | public auth = new AuthController(); 11 | 12 | constructor() { 13 | this.initializeRoutes(); 14 | } 15 | 16 | private initializeRoutes() { 17 | this.router.post('/signup', ValidationMiddleware(CreateUserDto), this.auth.signUp); 18 | this.router.post('/login', ValidationMiddleware(CreateUserDto), this.auth.logIn); 19 | this.router.post('/logout', AuthMiddleware, this.auth.logOut); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/typegoose/src/routes/users.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { UserController } from '@controllers/users.controller'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 6 | 7 | export class UserRoute implements Routes { 8 | public path = '/users'; 9 | public router = Router(); 10 | public user = new UserController(); 11 | 12 | constructor() { 13 | this.initializeRoutes(); 14 | } 15 | 16 | private initializeRoutes() { 17 | this.router.get(`${this.path}`, this.user.getUsers); 18 | this.router.get(`${this.path}/:id`, this.user.getUserById); 19 | this.router.post(`${this.path}`, ValidationMiddleware(CreateUserDto), this.user.createUser); 20 | this.router.put(`${this.path}/:id`, ValidationMiddleware(CreateUserDto, true), this.user.updateUser); 21 | this.router.delete(`${this.path}/:id`, this.user.deleteUser); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/typegoose/src/server.ts: -------------------------------------------------------------------------------- 1 | import App from '@/app'; 2 | import { AuthRoute } from '@routes/auth.route'; 3 | import { UserRoute } from '@routes/users.route'; 4 | import { ValidateEnv } from '@utils/validateEnv'; 5 | 6 | ValidateEnv(); 7 | 8 | const app = new App([new AuthRoute(), new UserRoute()]); 9 | 10 | app.listen(); 11 | -------------------------------------------------------------------------------- /lib/typegoose/src/utils/validateEnv.ts: -------------------------------------------------------------------------------- 1 | import { cleanEnv, port, str } from 'envalid'; 2 | 3 | export const ValidateEnv = () => { 4 | cleanEnv(process.env, { 5 | NODE_ENV: str(), 6 | PORT: port(), 7 | }); 8 | }; 9 | -------------------------------------------------------------------------------- /lib/typeorm/.dockerignore: -------------------------------------------------------------------------------- 1 | # compiled output 2 | .vscode 3 | /node_modules 4 | 5 | # code formatter 6 | .eslintrc 7 | .eslintignore 8 | .editorconfig 9 | .huskyrc 10 | .lintstagedrc.json 11 | .prettierrc 12 | 13 | # test 14 | jest.config.js 15 | 16 | # docker 17 | Dockerfile 18 | docker-compose.yml 19 | -------------------------------------------------------------------------------- /lib/typeorm/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | -------------------------------------------------------------------------------- /lib/typeorm/.env.development.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | POSTGRES_USER = root 6 | POSTGRES_PASSWORD = password 7 | POSTGRES_HOST = localhost 8 | POSTGRES_PORT = 5432 9 | POSTGRES_DATABASE = dev 10 | 11 | # TOKEN 12 | SECRET_KEY = secretKey 13 | 14 | # LOG 15 | LOG_FORMAT = dev 16 | LOG_DIR = ../logs 17 | 18 | # CORS 19 | ORIGIN = * 20 | CREDENTIALS = true 21 | -------------------------------------------------------------------------------- /lib/typeorm/.env.production.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | POSTGRES_USER = root 6 | POSTGRES_PASSWORD = password 7 | POSTGRES_HOST = localhost 8 | POSTGRES_PORT = 5432 9 | POSTGRES_DATABASE = dev 10 | 11 | # TOKEN 12 | SECRET_KEY = secretKey 13 | 14 | # LOG 15 | LOG_FORMAT = combined 16 | LOG_DIR = ../logs 17 | 18 | # CORS 19 | ORIGIN = your.domain.com 20 | CREDENTIALS = true 21 | -------------------------------------------------------------------------------- /lib/typeorm/.env.test.local: -------------------------------------------------------------------------------- 1 | # PORT 2 | PORT = 3000 3 | 4 | # DATABASE 5 | POSTGRES_USER = root 6 | POSTGRES_PASSWORD = password 7 | POSTGRES_HOST = localhost 8 | POSTGRES_PORT = 5432 9 | POSTGRES_DATABASE = dev 10 | 11 | # TOKEN 12 | SECRET_KEY = secretKey 13 | 14 | # LOG 15 | LOG_FORMAT = dev 16 | LOG_DIR = ../logs 17 | 18 | # CORS 19 | ORIGIN = * 20 | CREDENTIALS = true 21 | -------------------------------------------------------------------------------- /lib/typeorm/.eslintignore: -------------------------------------------------------------------------------- 1 | /dist -------------------------------------------------------------------------------- /lib/typeorm/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@typescript-eslint/parser", 3 | "extends": ["prettier", "plugin:@typescript-eslint/recommended", "plugin:prettier/recommended"], 4 | "parserOptions": { 5 | "ecmaVersion": 2018, 6 | "sourceType": "module" 7 | }, 8 | "rules": { 9 | "@typescript-eslint/explicit-member-accessibility": 0, 10 | "@typescript-eslint/explicit-function-return-type": 0, 11 | "@typescript-eslint/no-parameter-properties": 0, 12 | "@typescript-eslint/interface-name-prefix": 0, 13 | "@typescript-eslint/explicit-module-boundary-types": 0, 14 | "@typescript-eslint/no-explicit-any": "off", 15 | "@typescript-eslint/ban-types": "off", 16 | "@typescript-eslint/no-var-requires": "off" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lib/typeorm/.huskyrc: -------------------------------------------------------------------------------- 1 | { 2 | "hooks": { 3 | "pre-commit": "lint-staged" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /lib/typeorm/.lintstagedrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "*.ts": [ 3 | "npm run lint" 4 | ] 5 | } -------------------------------------------------------------------------------- /lib/typeorm/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 150, 3 | "tabWidth": 2, 4 | "singleQuote": true, 5 | "trailingComma": "all", 6 | "semi": true, 7 | "arrowParens": "avoid" 8 | } -------------------------------------------------------------------------------- /lib/typeorm/.swcrc: -------------------------------------------------------------------------------- 1 | { 2 | "jsc": { 3 | "parser": { 4 | "syntax": "typescript", 5 | "tsx": false, 6 | "dynamicImport": true, 7 | "decorators": true 8 | }, 9 | "transform": { 10 | "legacyDecorator": true, 11 | "decoratorMetadata": true 12 | }, 13 | "target": "es2017", 14 | "externalHelpers": false, 15 | "keepClassNames": true, 16 | "loose": false, 17 | "minify": { 18 | "compress": false, 19 | "mangle": false 20 | }, 21 | "baseUrl": "src", 22 | "paths": { 23 | "@/*": ["*"], 24 | "@config": ["config"], 25 | "@controllers/*": ["controllers/*"], 26 | "@database": ["database"], 27 | "@dtos/*": ["dtos/*"], 28 | "@entities/*": ["entities/*"], 29 | "@exceptions/*": ["exceptions/*"], 30 | "@interfaces/*": ["interfaces/*"], 31 | "@middlewares/*": ["middlewares/*"], 32 | "@routes/*": ["routes/*"], 33 | "@services/*": ["services/*"], 34 | "@utils/*": ["utils/*"] 35 | } 36 | }, 37 | "module": { 38 | "type": "commonjs" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/typeorm/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "node-terminal", 6 | "request": "launch", 7 | "name": "Dev typescript-express-starter", 8 | "command": "npm run dev" 9 | }, 10 | { 11 | "type": "node-terminal", 12 | "request": "launch", 13 | "name": "Start typescript-express-starter", 14 | "command": "npm run start" 15 | }, 16 | { 17 | "type": "node-terminal", 18 | "request": "launch", 19 | "name": "Test typescript-express-starter", 20 | "command": "npm run test" 21 | }, 22 | { 23 | "type": "node-terminal", 24 | "request": "launch", 25 | "name": "Lint typescript-express-starter", 26 | "command": "npm run lint" 27 | }, 28 | { 29 | "type": "node-terminal", 30 | "request": "launch", 31 | "name": "Lint:Fix typescript-express-starter", 32 | "command": "npm run lint:fix" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /lib/typeorm/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.codeActionsOnSave": { 3 | "source.fixAll.eslint": true 4 | }, 5 | "editor.formatOnSave": false 6 | } 7 | -------------------------------------------------------------------------------- /lib/typeorm/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV development 15 | 16 | EXPOSE 3000 17 | 18 | # Cmd script 19 | CMD ["npm", "run", "dev"] 20 | -------------------------------------------------------------------------------- /lib/typeorm/Dockerfile.prod: -------------------------------------------------------------------------------- 1 | # NodeJS Version 16 2 | FROM node:16.18-buster-slim 3 | 4 | # Copy Dir 5 | COPY . ./app 6 | 7 | # Work to Dir 8 | WORKDIR /app 9 | 10 | # Install Node Package 11 | RUN npm install --legacy-peer-deps 12 | 13 | # Set Env 14 | ENV NODE_ENV production 15 | 16 | EXPOSE 3000 17 | 18 | # Cmd script 19 | CMD ["npm", "run", "start"] 20 | -------------------------------------------------------------------------------- /lib/typeorm/jest.config.js: -------------------------------------------------------------------------------- 1 | const { pathsToModuleNameMapper } = require('ts-jest'); 2 | const { compilerOptions } = require('./tsconfig.json'); 3 | 4 | module.exports = { 5 | preset: 'ts-jest', 6 | testEnvironment: 'node', 7 | roots: ['/src'], 8 | transform: { 9 | '^.+\\.tsx?$': 'ts-jest', 10 | }, 11 | moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, { prefix: '/src' }), 12 | }; 13 | -------------------------------------------------------------------------------- /lib/typeorm/nginx.conf: -------------------------------------------------------------------------------- 1 | user nginx; 2 | worker_processes 1; 3 | 4 | error_log /var/log/nginx/error.log warn; 5 | pid /var/run/nginx.pid; 6 | 7 | events { 8 | worker_connections 1024; 9 | } 10 | 11 | http { 12 | include /etc/nginx/mime.types; 13 | default_type application/octet-stream; 14 | 15 | upstream api-server { 16 | server server:3000; 17 | keepalive 100; 18 | } 19 | 20 | server { 21 | listen 80; 22 | server_name localhost; 23 | 24 | location / { 25 | proxy_http_version 1.1; 26 | proxy_pass http://api-server; 27 | } 28 | 29 | } 30 | 31 | log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 32 | '$status $body_bytes_sent "$http_referer" ' 33 | '"$http_user_agent" "$http_x_forwarded_for"'; 34 | 35 | access_log /var/log/nginx/access.log main; 36 | 37 | sendfile on; 38 | keepalive_timeout 65; 39 | include /etc/nginx/conf.d/*.conf; 40 | } 41 | -------------------------------------------------------------------------------- /lib/typeorm/nodemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "watch": [ 3 | "src", 4 | ".env" 5 | ], 6 | "ext": "js,ts,json", 7 | "ignore": [ 8 | "src/logs/*", 9 | "src/**/*.{spec,test}.ts" 10 | ], 11 | "exec": "ts-node -r tsconfig-paths/register --transpile-only src/server.ts" 12 | } -------------------------------------------------------------------------------- /lib/typeorm/src/config/index.ts: -------------------------------------------------------------------------------- 1 | import { config } from 'dotenv'; 2 | config({ path: `.env.${process.env.NODE_ENV || 'development'}.local` }); 3 | 4 | export const CREDENTIALS = process.env.CREDENTIALS === 'true'; 5 | export const { NODE_ENV, PORT, SECRET_KEY, LOG_FORMAT, LOG_DIR, ORIGIN } = process.env; 6 | export const { POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DATABASE } = process.env; 7 | -------------------------------------------------------------------------------- /lib/typeorm/src/database/index.ts: -------------------------------------------------------------------------------- 1 | import { join } from 'path'; 2 | import { createConnection, ConnectionOptions } from 'typeorm'; 3 | import { POSTGRES_USER, POSTGRES_PASSWORD, POSTGRES_HOST, POSTGRES_PORT, POSTGRES_DATABASE } from '@config'; 4 | 5 | export const dbConnection = async () => { 6 | const dbConfig: ConnectionOptions = { 7 | type: 'postgres', 8 | username: POSTGRES_USER, 9 | password: POSTGRES_PASSWORD, 10 | host: POSTGRES_HOST, 11 | port: +POSTGRES_PORT, 12 | database: POSTGRES_DATABASE, 13 | synchronize: true, 14 | logging: false, 15 | entities: [join(__dirname, '../**/*.entity{.ts,.js}')], 16 | migrations: [join(__dirname, '../**/*.migration{.ts,.js}')], 17 | subscribers: [join(__dirname, '../**/*.subscriber{.ts,.js}')], 18 | cli: { 19 | entitiesDir: 'src/entities', 20 | migrationsDir: 'src/migration', 21 | subscribersDir: 'src/subscriber', 22 | }, 23 | }; 24 | 25 | await createConnection(dbConfig); 26 | }; 27 | -------------------------------------------------------------------------------- /lib/typeorm/src/database/migrations/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ljlm0402/typescript-express-starter/572dfd9bfdfc3b3f3e9e55b834be73445b1acf9a/lib/typeorm/src/database/migrations/.gitkeep -------------------------------------------------------------------------------- /lib/typeorm/src/dtos/users.dto.ts: -------------------------------------------------------------------------------- 1 | import { IsEmail, IsString, IsNotEmpty, MinLength, MaxLength } from 'class-validator'; 2 | 3 | export class CreateUserDto { 4 | @IsEmail() 5 | public email: string; 6 | 7 | @IsString() 8 | @IsNotEmpty() 9 | @MinLength(9) 10 | @MaxLength(32) 11 | public password: string; 12 | } 13 | 14 | export class UpdateUserDto { 15 | @IsString() 16 | @IsNotEmpty() 17 | @MinLength(9) 18 | @MaxLength(32) 19 | public password: string; 20 | } 21 | -------------------------------------------------------------------------------- /lib/typeorm/src/entities/users.entity.ts: -------------------------------------------------------------------------------- 1 | import { IsNotEmpty } from 'class-validator'; 2 | import { BaseEntity, Entity, PrimaryGeneratedColumn, Column, Unique, CreateDateColumn, UpdateDateColumn } from 'typeorm'; 3 | import { User } from '@interfaces/users.interface'; 4 | 5 | @Entity() 6 | export class UserEntity extends BaseEntity implements User { 7 | @PrimaryGeneratedColumn() 8 | id: number; 9 | 10 | @Column() 11 | @IsNotEmpty() 12 | @Unique(['email']) 13 | email: string; 14 | 15 | @Column() 16 | @IsNotEmpty() 17 | password: string; 18 | 19 | @Column() 20 | @CreateDateColumn() 21 | createdAt: Date; 22 | 23 | @Column() 24 | @UpdateDateColumn() 25 | updatedAt: Date; 26 | } 27 | -------------------------------------------------------------------------------- /lib/typeorm/src/exceptions/HttpException.ts: -------------------------------------------------------------------------------- 1 | export class HttpException extends Error { 2 | public status: number; 3 | public message: string; 4 | 5 | constructor(status: number, message: string) { 6 | super(message); 7 | this.status = status; 8 | this.message = message; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /lib/typeorm/src/http/auth.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # User Signup 6 | POST {{ baseURL }}/signup 7 | Content-Type: application/json 8 | 9 | { 10 | "email": "example@email.com", 11 | "password": "password" 12 | } 13 | 14 | ### 15 | # User Login 16 | POST {{ baseURL }}/login 17 | Content-Type: application/json 18 | 19 | { 20 | "email": "example@email.com", 21 | "password": "password" 22 | } 23 | 24 | ### 25 | # User Logout 26 | POST {{ baseURL }}/logout 27 | Content-Type: application/json 28 | -------------------------------------------------------------------------------- /lib/typeorm/src/http/users.http: -------------------------------------------------------------------------------- 1 | # baseURL 2 | @baseURL = http://localhost:3000 3 | 4 | ### 5 | # Find All Users 6 | GET {{ baseURL }}/users 7 | 8 | ### 9 | # Find User By Id 10 | GET {{ baseURL }}/users/1 11 | 12 | ### 13 | # Create User 14 | POST {{ baseURL }}/users 15 | Content-Type: application/json 16 | 17 | { 18 | "email": "example@email.com", 19 | "password": "password" 20 | } 21 | 22 | ### 23 | # Modify User By Id 24 | PUT {{ baseURL }}/users/1 25 | Content-Type: application/json 26 | 27 | { 28 | "email": "example@email.com", 29 | "password": "password" 30 | } 31 | 32 | ### 33 | # Delete User By Id 34 | DELETE {{ baseURL }}/users/1 35 | -------------------------------------------------------------------------------- /lib/typeorm/src/interfaces/auth.interface.ts: -------------------------------------------------------------------------------- 1 | import { Request } from 'express'; 2 | import { User } from '@interfaces/users.interface'; 3 | 4 | export interface DataStoredInToken { 5 | id: number; 6 | } 7 | 8 | export interface TokenData { 9 | token: string; 10 | expiresIn: number; 11 | } 12 | 13 | export interface RequestWithUser extends Request { 14 | user: User; 15 | } 16 | -------------------------------------------------------------------------------- /lib/typeorm/src/interfaces/routes.interface.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | 3 | export interface Routes { 4 | path?: string; 5 | router: Router; 6 | } 7 | -------------------------------------------------------------------------------- /lib/typeorm/src/interfaces/users.interface.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | id?: number; 3 | email: string; 4 | password: string; 5 | } 6 | -------------------------------------------------------------------------------- /lib/typeorm/src/middlewares/error.middleware.ts: -------------------------------------------------------------------------------- 1 | import { NextFunction, Request, Response } from 'express'; 2 | import { HttpException } from '@/exceptions/httpException'; 3 | import { logger } from '@utils/logger'; 4 | 5 | export const ErrorMiddleware = (error: HttpException, req: Request, res: Response, next: NextFunction) => { 6 | try { 7 | const status: number = error.status || 500; 8 | const message: string = error.message || 'Something went wrong'; 9 | 10 | logger.error(`[${req.method}] ${req.path} >> StatusCode:: ${status}, Message:: ${message}`); 11 | res.status(status).json({ message }); 12 | } catch (error) { 13 | next(error); 14 | } 15 | }; 16 | -------------------------------------------------------------------------------- /lib/typeorm/src/routes/auth.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { AuthController } from '@controllers/auth.controller'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { AuthMiddleware } from '@middlewares/auth.middleware'; 6 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 7 | 8 | export class AuthRoute implements Routes { 9 | public router = Router(); 10 | public auth = new AuthController(); 11 | 12 | constructor() { 13 | this.initializeRoutes(); 14 | } 15 | 16 | private initializeRoutes() { 17 | this.router.post('/signup', ValidationMiddleware(CreateUserDto), this.auth.signUp); 18 | this.router.post('/login', ValidationMiddleware(CreateUserDto), this.auth.logIn); 19 | this.router.post('/logout', AuthMiddleware, this.auth.logOut); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /lib/typeorm/src/routes/users.route.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import { UserController } from '@controllers/users.controller'; 3 | import { CreateUserDto } from '@dtos/users.dto'; 4 | import { Routes } from '@interfaces/routes.interface'; 5 | import { ValidationMiddleware } from '@middlewares/validation.middleware'; 6 | 7 | export class UserRoute implements Routes { 8 | public path = '/users'; 9 | public router = Router(); 10 | public user = new UserController(); 11 | 12 | constructor() { 13 | this.initializeRoutes(); 14 | } 15 | 16 | private initializeRoutes() { 17 | this.router.get(`${this.path}`, this.user.getUsers); 18 | this.router.get(`${this.path}/:id(\\d+)`, this.user.getUserById); 19 | this.router.post(`${this.path}`, ValidationMiddleware(CreateUserDto), this.user.createUser); 20 | this.router.put(`${this.path}/:id(\\d+)`, ValidationMiddleware(CreateUserDto, true), this.user.updateUser); 21 | this.router.delete(`${this.path}/:id(\\d+)`, this.user.deleteUser); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/typeorm/src/server.ts: -------------------------------------------------------------------------------- 1 | import { App } from '@/app'; 2 | import { AuthRoute } from '@routes/auth.route'; 3 | import { UserRoute } from '@routes/users.route'; 4 | import { ValidateEnv } from '@utils/validateEnv'; 5 | 6 | ValidateEnv(); 7 | 8 | const app = new App([new AuthRoute(), new UserRoute()]); 9 | 10 | app.listen(); 11 | -------------------------------------------------------------------------------- /lib/typeorm/src/utils/validateEnv.ts: -------------------------------------------------------------------------------- 1 | import { cleanEnv, port, str } from 'envalid'; 2 | 3 | export const ValidateEnv = () => { 4 | cleanEnv(process.env, { 5 | NODE_ENV: str(), 6 | PORT: port(), 7 | }); 8 | }; 9 | --------------------------------------------------------------------------------