├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── index.js ├── package-lock.json ├── package.json ├── templates └── base-tamplate │ ├── .eslintignore │ ├── .eslintrc.json │ ├── __test__ │ └── integration │ │ ├── api │ │ └── user.test.ts │ │ └── database.test.ts │ ├── commitlint.config.js │ ├── dinamic-package │ ├── gitignorefile │ ├── jest.config.js │ ├── jsdoc.json │ ├── jsdoc │ ├── docs │ │ ├── Database.html │ │ ├── ExampleDTO.ExampleDTO.html │ │ ├── ExampleDTO.html │ │ ├── ExampleRouter.html │ │ ├── HttpException.HttpException.html │ │ ├── HttpException.html │ │ ├── ICrud.html │ │ ├── IResourceExample.html │ │ ├── IRoute.html │ │ ├── IUser.html │ │ ├── ResourceExampleController.html │ │ ├── ResourceRepository.html │ │ ├── ResourceService.html │ │ ├── Server.Server.html │ │ ├── Server.html │ │ ├── UserController.html │ │ ├── UserDTO.UserDTO.html │ │ ├── UserDTO.html │ │ ├── UserRepository.html │ │ ├── UserRouter.html │ │ ├── UserService.html │ │ ├── config_database.ts.html │ │ ├── controller_ResourceExampleController.ts.html │ │ ├── controller_UserController.ts.html │ │ ├── dtos_ExampleDTO.ts.html │ │ ├── dtos_UserDTO.ts.html │ │ ├── exceptions_errorHandler.ts.html │ │ ├── exceptions_httpException.ts.html │ │ ├── global.html │ │ ├── index.html │ │ ├── interfaces_ICrud.ts.html │ │ ├── interfaces_IResourceExample.ts.html │ │ ├── interfaces_IRoute.ts.html │ │ ├── interfaces_IUser.ts.html │ │ ├── logo.png │ │ ├── middlewares_isDefinedParamMiddleware.ts.html │ │ ├── middlewares_isRequiredParamMiddleware.ts.html │ │ ├── middlewares_validationMiddleware.ts.html │ │ ├── repository_ResourceExampleRepository.ts.html │ │ ├── repository_UserRepository.ts.html │ │ ├── routes_example.route.ts.html │ │ ├── routes_user.route.ts.html │ │ ├── scripts │ │ │ ├── app.min.js │ │ │ ├── linenumber.js │ │ │ └── search.js │ │ ├── server_Server.ts.html │ │ ├── services_ResourceService.ts.html │ │ ├── services_UserService.ts.html │ │ ├── style.css │ │ └── styles │ │ │ ├── app.min.css │ │ │ ├── iframe.css │ │ │ ├── prettify-jsdoc.css │ │ │ ├── prettify-tomorrow.css │ │ │ └── reset.css │ ├── readme.md │ └── statics │ │ ├── logo.png │ │ └── style.css │ ├── package-lock.json │ ├── src │ ├── app.ts │ ├── config │ │ ├── database.ts │ │ ├── dotenv.ts │ │ └── index.ts │ ├── controller │ │ ├── UserController.ts │ │ └── index.ts │ ├── dtos │ │ ├── UserDTO.ts │ │ └── index.ts │ ├── exceptions │ │ ├── errorHandler.ts │ │ ├── httpException.ts │ │ └── index.ts │ ├── interfaces │ │ ├── ICrud.ts │ │ ├── IRoute.ts │ │ ├── IUser.ts │ │ └── index.ts │ ├── middlewares │ │ ├── index.ts │ │ ├── isRequiredParamMiddleware.ts │ │ └── validationMiddleware.ts │ ├── models │ │ ├── User.ts │ │ └── index.ts │ ├── repository │ │ ├── UserRepository.ts │ │ └── index.ts │ ├── routes │ │ ├── index.ts │ │ └── user.route.ts │ ├── server │ │ └── Server.ts │ ├── services │ │ ├── UserService.ts │ │ └── index.ts │ ├── setupTests.ts │ └── utils │ │ ├── index.ts │ │ └── logger.ts │ └── tsconfig.json └── util ├── createDirectoryContents.js ├── createGitignore.js ├── createProjectDirectory.js ├── ignoreFeature.js ├── questions.js └── template.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .env 3 | .env.dev 4 | templates/base-template/.env.dev 5 | templates/base-template/.env 6 | templates/base-template/dist 7 | templates/base-template/node_modules -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 express-typescript-template-generator 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

Welcome to Express with typescript and good practices template 👋

2 |

3 | 4 | License: MIT 5 | 6 | 7 | Build 8 | 9 | 10 | Downloads 11 | 12 | 13 |

14 | 15 | Base express.js template with TypeScript and best practices ready for start to coding. 16 | 17 | ## Feactures 18 | - Selector of features to use 19 | - Typescript 20 | - Dodumentation with jsdoc (available in jsdoc/docs/index.html) 21 | - Commits convections 22 | - Eslint 23 | - Repository pattern 24 | - DTO pattern 25 | - Validation request data with middlewares 26 | - Global error handler 27 | - Mogoose config 28 | - Dotenv config 29 | - Testing with jest 30 | - Pretty logs with winston 31 | - Pretty routes pattern 32 | 33 | ## Project structure 34 | ``` 35 | 📦src # Main folder of code 36 | ┣ 📂config # Folder for app config, here there is files like dotenv config ig 37 | ┣ 📂controller # Folder for handlers functions called from routes 38 | ┣ 📂dtos # DTO pattern for handle data of models 39 | ┣ 📂exceptions # Global handle error and custom exceptions 40 | ┣ 📂interfaces # Interfaces for greater abstraction 41 | ┣ 📂middlewares # Folder for express middlewares 42 | ┣ 📂models # Schemas of mongodb for handle data 43 | ┣ 📂repository # Pattern repository for disengage database engine 44 | ┣ 📂routes # Express routes for slices 45 | ┣ 📂server # Express server instance 46 | ┣ 📂services # Services for write core code bussiness 47 | ┣ 📂utils # Utils for usage in the application like logger utils 48 | ┣ 📜app.ts # Main file of project 49 | ┗ 📜setupTests.ts # Config for testing with jest 50 | ``` 51 | 52 | ## Installation 53 | ```sh 54 | $ npm i -g express-typescript-template-generator 55 | ``` 56 | 57 | ## Use 58 | ```sh 59 | $ express-typescript-template-generator 60 | ``` 61 | ```sh 62 | $ cd 63 | ``` 64 | > Configure your .env file with the necessary environment variables. 65 | > Create the .env and .env.dev files at the root of the project with: 66 | > - DB_URI=your database uri 67 | 68 | ## Development usage 69 | 70 | ```sh 71 | $ npm run tsc 72 | $ npm run dev 73 | ``` 74 | > Open the browser in: http://localhost:3000/api/user. 75 | 76 | ## Production usage 77 | 78 | ```sh 79 | $ npm start 80 | ``` 81 | 82 | ## Run tests 83 | 84 | ```sh 85 | $ npm run test 86 | ``` 87 | 88 | ## Create documentation 89 | 90 | ```sh 91 | $ npm run jsdoc 92 | ``` 93 | 94 | ## Eslint 95 | 96 | ```sh 97 | $ npm run lint 98 | $ npm run lint:fix 99 | ``` 100 | 101 | ## Author 102 | 103 | 👤 **Deiver Carrascal** 104 | 105 | * Website: https://ingdeiver.github.io/portafolio/ 106 | * Github: [@IngDeiver](https://github.com/IngDeiver) 107 | 108 | ## Show your support 109 | 110 | Give a ⭐️ if this project helped you!. 111 | Can make pull request to contribute!. 112 | 113 | *** 114 | _This README was generated with ❤️ by [readme-md-generator](https://github.com/kefranabg/readme-md-generator)_ -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // dinamic package.json properties 3 | var author = ""; 4 | var projectDescription = ""; 5 | var license = ""; 6 | var jsdoc = true; 7 | 8 | const inquirer = require("inquirer"); 9 | const path = require("path"); 10 | const fs = require("fs"); 11 | const chalk = require("chalk"); 12 | const { exec } = require("child_process"); 13 | 14 | const CURRENT_DIR = process.cwd(); 15 | const QUESTIONS = require("./util/questions"); 16 | const createProjectDirectory = require("./util/createProjectDirectory"); 17 | const createDirectoryContents = require("./util/createDirectoryContents"); 18 | const createGitignore = require('./util/createGitignore') 19 | 20 | console.log(` 21 | ______________________________ 22 | / / \\ 23 | | Express | ========== 🔥 24 | \\____________________________\\_/ 25 | ______________________________ 26 | / / \\ 27 | | TypeScript | ========== 🔥 28 | \\____________________________\\_/ 29 | ______________________________ 30 | / / \\ 31 | | Template | ========== 🔥 32 | \\____________________________\\_/ 33 | ______________________________ 34 | / / \\ 35 | | Generator | ========== 🔥 36 | \\____________________________\\_/ 37 | 38 | `); 39 | 40 | inquirer 41 | .prompt(QUESTIONS) 42 | .then((answers) => { 43 | const templateChoice = answers["template-choice"]; 44 | 45 | // package.json dproperties 46 | const projectName = answers["project-name"].trim(); 47 | author = answers["project-author"]; 48 | projectDescription = answers["project-description"]; 49 | license = answers["project-license"]; 50 | jsdoc = answers["features"][0]; 51 | 52 | const PACKGE_JSON_PROPERTIES_VALUES = { 53 | projectName, 54 | author, 55 | projectDescription, 56 | license, 57 | jsdoc, 58 | }; 59 | 60 | const templatePath = path.join(__dirname, "templates", templateChoice); 61 | const targetPath = path.join(CURRENT_DIR, projectName); 62 | 63 | if (!createProjectDirectory(targetPath)) { 64 | return; 65 | } 66 | 67 | createDirectoryContents( 68 | templatePath, 69 | projectName, // first directory (root) to write content 70 | PACKGE_JSON_PROPERTIES_VALUES, 71 | CURRENT_DIR, 72 | ); 73 | 74 | // create .gitignore file 75 | createGitignore(CURRENT_DIR, projectName, templatePath) 76 | 77 | console.log("Instalalling dependencies..."); 78 | 79 | exec( 80 | `cd ${targetPath} && git init && npm install`, 81 | (error, stdout, stderr) => { 82 | if (error) { 83 | console.log(chalk.red(`😭 error: ${error}`)); 84 | } 85 | console.log(chalk.bold.green(`🚀 Project created in: ${targetPath}`)); 86 | console.log(chalk.bold.green(`If it was helpful, leave a star ⭐️`)); 87 | console.log(""); 88 | 89 | console.log( 90 | chalk.yellow( 91 | "/--------------------------------------------------------------------/" 92 | ) 93 | ); 94 | console.log( 95 | chalk.yellow( 96 | "/ Follow the steps below to start development /" 97 | ) 98 | ); 99 | console.log( 100 | chalk.yellow( 101 | "/ /" 102 | ) 103 | ); 104 | console.log(chalk.yellow(`/ cd ${projectName}`)); 105 | console.log( 106 | chalk.yellow( 107 | "/ configure your .env file with the necessary environment variables. /" 108 | ) 109 | ); 110 | console.log( 111 | chalk.yellow( 112 | "/ npm run tsc: for execute ts compiler in mode watch. /" 113 | ) 114 | ); 115 | console.log( 116 | chalk.yellow( 117 | "/ npm run dev: for start the development server. /" 118 | ) 119 | ); 120 | console.log( 121 | chalk.yellow( 122 | "/ npm run test: for test the project. /" 123 | ) 124 | ); 125 | console.log( 126 | chalk.yellow( 127 | "/ Open the browser in: http://localhost:3000/api/example /" 128 | ) 129 | ); 130 | console.log( 131 | chalk.yellow( 132 | "/--------------------------------------------------------------------/" 133 | ) 134 | ); 135 | } 136 | ); 137 | }) 138 | .catch((error) => { 139 | if (error.isTtyError) { 140 | console.log( 141 | chalk.red( 142 | "😭 Prompt could do not be rendered in the current environment" 143 | ) 144 | ); 145 | } else { 146 | console.log(chalk.red(`😭 ${error}`)); 147 | } 148 | }); 149 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "express-typescript-template-generator", 3 | "version": "2.2.5", 4 | "description": "Base express.js template with TypeScript and best practices ready for start to coding ", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "bin": { 8 | "express-typescript-template-generator": "index.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "https://github.com/IngDeiver/express-typescript-template-generator" 13 | }, 14 | "keywords": [ 15 | "express", 16 | "template", 17 | "typescript" 18 | ], 19 | "author": "Deiver Carrascal", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/IngDeiver/express-typescript-template-generator/issues" 23 | }, 24 | "homepage": "https://github.com/IngDeiver/express-typescript-template-generator#readme", 25 | "dependencies": { 26 | "chalk": "^4.1.0", 27 | "ejs": "^3.1.5", 28 | "inquirer": "^7.3.3" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /templates/base-tamplate/.eslintignore: -------------------------------------------------------------------------------- 1 | dist 2 | jsdoc 3 | node_modules -------------------------------------------------------------------------------- /templates/base-tamplate/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "es2021": true, 4 | "node": true 5 | }, 6 | "extends": [ 7 | "eslint:recommended", 8 | "airbnb-base", 9 | "plugin:jest/recommended", 10 | "plugin:jest/style" 11 | ], 12 | "parser": "@typescript-eslint/parser", 13 | "parserOptions": { 14 | "ecmaVersion": 12, 15 | "sourceType": "module" 16 | }, 17 | "plugins": [ 18 | "@typescript-eslint", 19 | "jest" 20 | ], 21 | "rules": { 22 | "jest/no-disabled-tests": "warn", 23 | "jest/no-focused-tests": "error", 24 | "jest/no-identical-title": "error", 25 | "jest/prefer-to-have-length": "warn", 26 | "jest/valid-expect": "error", 27 | "import/no-extraneous-dependencies": ["error", {"devDependencies": true}], 28 | "import/extensions": [0], 29 | "no-use-before-define": [0], 30 | "import/no-unresolved":[0], 31 | "radix":"off", 32 | "consistent-return":"off" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /templates/base-tamplate/__test__/integration/api/user.test.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-underscore-dangle */ 2 | /* eslint-disable jest/valid-expect-in-promise */ 3 | /* eslint-disable jest/expect-expect */ 4 | import supertest from 'supertest'; 5 | import expres from 'express'; 6 | import server from '../../../src/app'; 7 | 8 | let app: expres.Application; 9 | let request: supertest.SuperTest; 10 | const baseUri = '/api/user'; 11 | 12 | 13 | beforeAll(() => { 14 | app = server.app; 15 | request = supertest(app); 16 | }); 17 | 18 | // list 19 | it('should get list users', async () => { 20 | const response = await request.get(baseUri) 21 | expect(response.status).toBe(200); 22 | expect(response.body).toBeInstanceOf(Array); 23 | }); 24 | 25 | 26 | // get by id 27 | describe('should get user by id', () => { 28 | it('should response with 200 status', async () => { 29 | const id = '60228ef97b60c097608374da'; // verify that this id exist in your database 30 | const response = await request.get(`${baseUri}/${id}`) 31 | 32 | expect(response.status).toBe(200); 33 | }); 34 | 35 | it('should response with 404 status', async () => { 36 | const id = '5fe0287346956c638f701222'; 37 | const response = await request.get(`${baseUri}/${id}`) 38 | 39 | expect(response.status).toBe(404); 40 | expect(response.body.username).toBeUndefined(); 41 | }); 42 | }); 43 | 44 | // save 45 | describe('should save user', () => { 46 | it('should save with 200 status', async () => { 47 | const user = { 48 | username: 'user update with test', 49 | email: `test@${Math.random().toString(5)}.com`, 50 | password: "password" 51 | }; 52 | 53 | const response = await request.post(baseUri) 54 | .send(user) 55 | .set('Accept', 'application/json'); 56 | expect(response.status).toBe(200); 57 | expect(response.body.username).toBeDefined(); 58 | expect(response.body.username).toEqual(user.username); 59 | 60 | // remove a user saved 61 | const responseRemove = await request.delete(`${baseUri}/${response.body._id}`); 62 | expect(responseRemove.status).toBe(200); 63 | expect(responseRemove.body.username).toBeDefined(); 64 | }); 65 | 66 | it('should fail save without body with 400 status', async () => { 67 | const response = await request.post(baseUri) 68 | .set('Accept', 'application/json'); 69 | expect(response.status).toBe(400); 70 | expect(response.body.username).toBeUndefined(); 71 | }); 72 | }); 73 | 74 | 75 | // update 76 | describe('should update a user', () => { 77 | it('should update with 200 status', async () => { 78 | const id: string = '60228ef97b60c097608374da'; // verify that this id exist in your database 79 | const user = { 80 | username: 'user update with test', 81 | email: `test@${Math.random().toString(5)}.com`, 82 | password: "password" 83 | }; 84 | 85 | const response = await request.put(`${baseUri}/${id}`) 86 | .send(user); 87 | expect(response.status).toBe(200); 88 | expect(response.body.username).toEqual(user.username); 89 | }); 90 | 91 | it('should fail with 404 status', async () => { 92 | const id = '5fe0287346956c638f701bd2'; 93 | const response = await request.put(`${baseUri}/${id}`) 94 | .send({ username: 'user update with test', 95 | email: `test@${Math.random().toString(5)}.com`, 96 | password: "password"}); 97 | expect(response.status).toBe(404); 98 | expect(response.body.username).toBeUndefined(); 99 | }); 100 | }); 101 | 102 | // remove 103 | describe('should remove a user', () => { 104 | it('should fail with 404 status', async () => { 105 | const id = '5fe0287346956c638f701bd2'; 106 | const response = await request.delete(`${baseUri}/${id}`) 107 | 108 | expect(response.status).toBe(404); 109 | expect(response.body.username).toBeUndefined(); 110 | }); 111 | }); 112 | -------------------------------------------------------------------------------- /templates/base-tamplate/__test__/integration/database.test.ts: -------------------------------------------------------------------------------- 1 | import { Connection } from 'mongoose'; 2 | import { Database } from '../../src/config'; 3 | 4 | let db: Connection; 5 | beforeAll(async () => { 6 | db = await Database.connect(); 7 | }); 8 | 9 | afterAll(() => { 10 | db.close(); 11 | }); 12 | 13 | describe('Database', () => { 14 | it('should is connected', () => { 15 | expect(db.readyState).toEqual(1); 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /templates/base-tamplate/commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = {extends: ['@commitlint/config-conventional']}; 2 | -------------------------------------------------------------------------------- /templates/base-tamplate/dinamic-package: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= projectName %>", 3 | "version": "1.0.0", 4 | "description": "<%= projectDescription %>", 5 | "main": "src/app.js", 6 | "scripts": { 7 | "test": "jest --watchAll --detectOpenHandles", 8 | "tsc": "tsc --watch", 9 | "dev": "cross-env NODE_ENV=development nodemon dist/src/app.js", 10 | "build": "tsc", 11 | "start": "npm run build && cross-env NODE_ENV=production node dist/src/app.js", 12 | <% if (jsdoc) { %>"jsdoc": "jsdoc -c jsdoc.json",<% } %> 13 | "lint": "eslint --ext .ts", 14 | "lint:fix": "eslint --fix --ext .ts" 15 | }, 16 | "keywords": [], 17 | "author": "<%= author %>", 18 | "license": "<%= license %>", 19 | "devDependencies": { 20 | "@commitlint/cli": "^11.0.0", 21 | "@commitlint/config-conventional": "^11.0.0", 22 | "@types/cors": "^2.8.9", 23 | "@types/express": "^4.17.9", 24 | "@types/jest": "^26.0.19", 25 | "@types/morgan": "^1.9.2", 26 | "@types/supertest": "^2.0.10", 27 | "@typescript-eslint/eslint-plugin": "^4.10.0", 28 | "@typescript-eslint/parser": "^4.10.0", 29 | "better-docs": "^2.3.2", 30 | "cross-env": "^7.0.3", 31 | "eslint": "^7.15.0", 32 | "eslint-config-airbnb-base": "^14.2.1", 33 | "eslint-plugin-import": "^2.22.1", 34 | "eslint-plugin-jest": "^24.1.3", 35 | "husky": "^4.3.6", 36 | <% if (jsdoc) { %>"jsdoc": "^3.6.6",<% } %> 37 | "nodemon": "^2.0.6", 38 | "supertest": "^6.0.1", 39 | "typescript": "^4.1.3" 40 | }, 41 | "dependencies": { 42 | "@types/bcrypt": "^3.0.0", 43 | "@types/mongoose": "^5.10.3", 44 | "@types/winston": "^2.4.4", 45 | "bcrypt": "^5.0.0", 46 | "class-transformer": "^0.3.1", 47 | "class-validator": "^0.12.2", 48 | "cors": "^2.8.5", 49 | "dotenv": "^8.2.0", 50 | "express": "^4.17.1", 51 | "jest": "^26.6.3", 52 | "mongoose": "^5.11.8", 53 | "morgan": "^1.10.0", 54 | "path": "^0.12.7", 55 | "ts-jest": "^26.4.4", 56 | "winston": "^3.3.3", 57 | "winston-daily-rotate-file": "^4.5.0" 58 | }, 59 | "husky": { 60 | "hooks": { 61 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /templates/base-tamplate/gitignorefile: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | .env 4 | .env.dev 5 | 6 | # docs 7 | jsdoc/docs -------------------------------------------------------------------------------- /templates/base-tamplate/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'ts-jest', 3 | coverageDirectory: 'coverage', 4 | coveragePathIgnorePatterns: [ 5 | 'node_modules/**', 6 | ], 7 | coverageProvider: 'v8', 8 | moduleFileExtensions: [ 9 | 'js', 10 | 'ts', 11 | ], 12 | setupFiles: ['/src/setupTests.ts'], 13 | moduleDirectories: [ 14 | 'node_modules' 15 | ], 16 | testEnvironment: 'node', 17 | testMatch: [ 18 | '**/__tests__/**/*.[jt]s?(x)', 19 | '**/?(*.)+(spec|test).[tj]s?(x)', 20 | ], 21 | testPathIgnorePatterns: [ 22 | 'node_modules', 23 | 'dist', 24 | 'jsdoc', 25 | ], 26 | }; 27 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": { 3 | "allowUnknownTags": ["category","subcategory"] 4 | }, 5 | "source": { 6 | "exclude":["reportWebVitals.ts"], 7 | "include": ["./src"], 8 | "includePattern": "\\.(jsx|js|ts|tsx)$", 9 | "excludePattern": "(node_modules/|jsdoc/docs|public|reportWebVitals)" 10 | }, 11 | "plugins": [ 12 | "node_modules/better-docs/category", 13 | "node_modules/better-docs/typescript" 14 | ], 15 | "opts": { 16 | "encoding": "utf8", 17 | "destination": "jsdoc/docs/", 18 | "recurse": true, 19 | "verbose": true, 20 | "template": "node_modules/better-docs", 21 | "readme": "jsdoc/readme.md" 22 | }, 23 | "templates": { 24 | "cleverLinks": false, 25 | "monospaceLinks": false, 26 | "search": true, 27 | "default": { 28 | "staticFiles": { 29 | "include": [ 30 | "./jsdoc/statics" 31 | ] 32 | } 33 | }, 34 | "better-docs": { 35 | "logo": "logo.png", 36 | "title": "Documentation", 37 | "css": "style.css", 38 | "trackingCode": "tracking-code-which-will-go-to-the-HEAD", 39 | "hideGenerator": false, 40 | "navLinks": [ 41 | { 42 | "label": "Github", 43 | "href": "https://github.com/IngDeiver" 44 | } 45 | ] 46 | } 47 | }, 48 | "typescript": { 49 | "moduleRoot": "src" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/ExampleRouter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | tracking-code-which-will-go-to-the-HEAD 6 | 7 | 8 | Documentation ExampleRouter 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 |
36 | 41 | 49 | 72 |
73 |
74 |
75 | 90 |
91 |
92 |
93 |

Class

94 |

ExampleRouter

95 |
96 | 97 | 98 | 99 | 100 | 101 |
102 | 103 |
104 | 105 |

ExampleRouter()

106 | 107 | 108 |
109 | 110 |
111 |
112 | 113 | 114 |
115 |
116 |
117 |
118 | Constructor 119 |
120 | 121 | 122 | 123 | 124 |

125 | # 126 | 127 | 128 | 129 | new ExampleRouter() 130 | 131 | 132 |

133 | 134 | 135 | 136 | 137 |
138 | Managament the routes of resource 139 |
140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 |
155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 |
Implements:
168 |
    169 | 170 |
  • IRoute
  • 171 | 172 |
173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 |

194 | View Source 195 | 196 | routes/example.route.ts, line 6 197 | 198 |

199 | 200 |
201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 |
224 |
225 |
226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 |
250 | 251 |
252 | 253 | 254 | 255 | 256 |
257 | 258 | 267 | 268 |
269 |
270 |
271 |
272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/IResourceExample.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | tracking-code-which-will-go-to-the-HEAD 6 | 7 | 8 | Documentation IResourceExample 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 |
36 | 41 | 49 | 72 |
73 |
74 |
75 | 90 |
91 |
92 |
93 |

Interface

94 |

IResourceExample

95 |
96 | 97 | 98 | 99 | 100 | 101 |
102 | 103 |
104 | 105 |

IResourceExample

106 | 107 | 108 |
109 | 110 |
111 |
112 | 113 | 114 |
Define a interface of resource to managament with mongoose
115 | 116 | 117 | 118 | 119 | 120 |
121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 |

153 | View Source 154 | 155 | interfaces/IResourceExample.ts, line 4 156 | 157 |

158 | 159 |
160 | 161 | 162 | 163 | 164 |
165 | 166 | 167 |

Extends

168 | 169 | 170 | 171 | 172 |
    173 |
  • Document
  • 174 |
175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 |
197 | 198 |
199 | 200 | 201 | 202 | 203 |
204 | 205 | 214 | 215 |
216 |
217 |
218 |
219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/IRoute.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | tracking-code-which-will-go-to-the-HEAD 6 | 7 | 8 | Documentation IRoute 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 |
36 | 41 | 49 | 72 |
73 |
74 |
75 | 90 |
91 |
92 |
93 |

Interface

94 |

IRoute

95 |
96 | 97 | 98 | 99 | 100 | 101 |
102 | 103 |
104 | 105 |

IRoute

106 | 107 | 108 |
109 | 110 |
111 |
112 | 113 | 114 |
Define the atributes of routes
115 | 116 | 117 | 118 | 119 | 120 |
121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 |

153 | View Source 154 | 155 | interfaces/IRoute.ts, line 4 156 | 157 |

158 | 159 |
160 | 161 | 162 | 163 | 164 |
165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 |
186 | 187 |
188 | 189 | 190 | 191 | 192 |
193 | 194 | 203 | 204 |
205 |
206 |
207 |
208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/IUser.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | tracking-code-which-will-go-to-the-HEAD 6 | 7 | 8 | Documentation IUser 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 |
36 | 41 | 49 | 72 |
73 |
74 |
75 | 90 |
91 |
92 |
93 |

Interface

94 |

IUser

95 |
96 | 97 | 98 | 99 | 100 | 101 |
102 | 103 |
104 | 105 |

IUser

106 | 107 | 108 |
109 | 110 |
111 |
112 | 113 | 114 |
Define a user interface to managament with mongoose
115 | 116 | 117 | 118 | 119 | 120 |
121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 |

153 | View Source 154 | 155 | interfaces/IUser.ts, line 4 156 | 157 |

158 | 159 |
160 | 161 | 162 | 163 | 164 |
165 | 166 | 167 |

Extends

168 | 169 | 170 | 171 | 172 |
    173 |
  • Document
  • 174 |
175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 |
197 | 198 |
199 | 200 | 201 | 202 | 203 |
204 | 205 | 214 | 215 |
216 |
217 |
218 |
219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/UserRouter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | tracking-code-which-will-go-to-the-HEAD 6 | 7 | 8 | Documentation UserRouter 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 |
36 | 41 | 49 | 72 |
73 |
74 |
75 | 90 |
91 |
92 |
93 |

Class

94 |

UserRouter

95 |
96 | 97 | 98 | 99 | 100 | 101 |
102 | 103 |
104 | 105 |

UserRouter()

106 | 107 | 108 |
109 | 110 |
111 |
112 | 113 | 114 |
115 |
116 |
117 |
118 | Constructor 119 |
120 | 121 | 122 | 123 | 124 |

125 | # 126 | 127 | 128 | 129 | new UserRouter() 130 | 131 | 132 |

133 | 134 | 135 | 136 | 137 |
138 | Managament the routes of user 139 |
140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 |
155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 |
Implements:
168 |
    169 | 170 |
  • IRoute
  • 171 | 172 |
173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 |

194 | View Source 195 | 196 | routes/user.route.ts, line 6 197 | 198 |

199 | 200 |
201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 |
224 |
225 |
226 | 227 | 228 |
229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 |
250 | 251 |
252 | 253 | 254 | 255 | 256 |
257 | 258 | 267 | 268 |
269 |
270 |
271 |
272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/config_database.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | tracking-code-which-will-go-to-the-HEAD 8 | 9 | 10 | Documentation config/database.ts 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 | 43 | 51 | 74 |
75 |
76 |
77 | 92 |
93 |
94 |
95 |

Source

96 |

config/database.ts

97 |
98 | 99 | 100 | 101 | 102 | 103 |
104 |
105 |
/* eslint-disable no-console */
106 | // getting-started.js
107 | import mongoose, { Connection } from 'mongoose';
108 | import { logger } from '../utils';
109 | 
110 | /**
111 |  *
112 |  * The clas for database managament
113 |  * @class Database
114 |  *
115 |  */
116 | class Database {
117 |  static db: Connection;
118 | 
119 |  /**
120 |   *
121 |   * Make a conecttion with database configured
122 |   * @static
123 |   * @return Connection  return a new connection
124 |   * @memberof Database
125 |   */
126 |  static connect(): Connection {
127 |    mongoose.connect(process.env.DB_URI || '', { useNewUrlParser: true, useUnifiedTopology: true })
128 |      .then(() => logger.info('🟢 The database is connected.'))
129 |      .catch((error) => logger.error(`🔴 Unable to connect to the database: ${error}.`));
130 |    this.db = mongoose.connection;
131 |    return this.db;
132 |  }
133 | 
134 |  /**
135 |   *
136 |   * CLose the current connection
137 |   * @static
138 |   * @memberof Database
139 |   */
140 |  static close(): void {
141 |    this.db.close();
142 |  }
143 | }
144 | export default Database;
145 | 
146 |
147 |
148 | 149 | 150 | 151 | 152 |
153 | 154 | 163 | 164 |
165 |
166 |
167 |
168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/dtos_ExampleDTO.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | tracking-code-which-will-go-to-the-HEAD 8 | 9 | 10 | Documentation dtos/ExampleDTO.ts 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 | 43 | 51 | 74 |
75 |
76 |
77 | 92 |
93 |
94 |
95 |

Source

96 |

dtos/ExampleDTO.ts

97 |
98 | 99 | 100 | 101 | 102 | 103 |
104 |
105 |
/* eslint-disable no-empty-function */
106 | /* eslint-disable no-unused-vars */
107 | /* eslint-disable no-useless-constructor */
108 | 
109 | import { IsString, IsNotEmpty } from 'class-validator';
110 | 
111 | /**
112 |  *
113 |  * DTO for resource example
114 |  * @category DTOs
115 |  * @class ExampleDTO
116 |  * @param {string}propery - A property example
117 |  */
118 | class ExampleDTO {
119 |     @IsNotEmpty()
120 |     @IsString()
121 |     public property: string;
122 | 
123 |     /**
124 |    * Creates an instance of ExampleDTO.
125 |    * @param {string} property - the tile of resource
126 |    * @memberof ExampleDTO
127 |    */
128 |     constructor(property: string) {
129 |       this.property = property;
130 |     }
131 | }
132 | 
133 | export default ExampleDTO;
134 | 
135 |
136 |
137 | 138 | 139 | 140 | 141 |
142 | 143 | 152 | 153 |
154 |
155 |
156 |
157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/dtos_UserDTO.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | tracking-code-which-will-go-to-the-HEAD 8 | 9 | 10 | Documentation dtos/UserDTO.ts 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 | 43 | 51 | 74 |
75 |
76 |
77 | 92 |
93 |
94 |
95 |

Source

96 |

dtos/UserDTO.ts

97 |
98 | 99 | 100 | 101 | 102 | 103 |
104 |
105 |
/* eslint-disable no-empty-function */
106 | /* eslint-disable no-unused-vars */
107 | /* eslint-disable no-useless-constructor */
108 | 
109 | import { IsString, IsNotEmpty, IsEmail } from 'class-validator';
110 | 
111 | /**
112 |  *
113 |  * DTO for user 
114 |  * @category DTOs
115 |  * @class UserDTO
116 |  * @param {string} username - A username 
117 |  */
118 | class UserDTO {
119 |     @IsNotEmpty()
120 |     @IsString()
121 |     public username: string;
122 | 
123 |     @IsNotEmpty()
124 |     @IsEmail()
125 |     public email: string
126 | 
127 |     @IsNotEmpty()
128 |     @IsString()
129 |     public password: string
130 | 
131 |     /**
132 |    * Creates an instance of UserDTO.
133 |    * @param {string} username - the name user
134 |    * @param {string} email - the email user
135 |    * @param {string} password - the password user
136 |    * @memberof UserDTO
137 |    */
138 |     constructor(username: string, email: string, password: string) {
139 |       this.username = username;
140 |       this.email = email;
141 |       this.password = password;
142 |     }
143 | }
144 | 
145 | export default UserDTO;
146 | 
147 |
148 |
149 | 150 | 151 | 152 | 153 |
154 | 155 | 164 | 165 |
166 |
167 |
168 |
169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/exceptions_errorHandler.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | tracking-code-which-will-go-to-the-HEAD 8 | 9 | 10 | Documentation exceptions/errorHandler.ts 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 | 43 | 51 | 74 |
75 |
76 |
77 | 92 |
93 |
94 |
95 |

Source

96 |

exceptions/errorHandler.ts

97 |
98 | 99 | 100 | 101 | 102 | 103 |
104 |
105 |
import { Request, Response, NextFunction } from 'express';
106 | import HttpException from './httpException';
107 | 
108 | /**
109 |  *
110 |  * The middleware for catch they erros into application
111 |  * @category Exceptions
112 |  * @param {HttpException} err - The error (if exist)
113 |  * @param {Request} req - The request
114 |  * @param {Response} res - The response
115 |  * @param {NextFunction} cb - The next function (if pass)
116 |  * @return {void}  void
117 |  */
118 | const errorHandler = (err: HttpException, req: Request, res: Response, cb: NextFunction): void => {
119 |   if (res.headersSent) {
120 |     return cb(err);
121 |   }
122 | 
123 |   res.status(err.status || 500).json({
124 |     error: {
125 |       message: err.message,
126 |       status: err.status,
127 |     },
128 |   });
129 | };
130 | 
131 | export default errorHandler;
132 | 
133 |
134 |
135 | 136 | 137 | 138 | 139 |
140 | 141 | 150 | 151 |
152 |
153 |
154 |
155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/exceptions_httpException.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | tracking-code-which-will-go-to-the-HEAD 8 | 9 | 10 | Documentation exceptions/httpException.ts 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 | 43 | 51 | 74 |
75 |
76 |
77 | 92 |
93 |
94 |
95 |

Source

96 |

exceptions/httpException.ts

97 |
98 | 99 | 100 | 101 | 102 | 103 |
104 |
105 |
/**
106 |  *
107 |  *
108 |  * Is a custom exception for implmented with the error handler
109 |  * @category Exceptions
110 |  * @class HttpException
111 |  *  @param {number} status - THe status of error
112 |  *  @param {string} message -The message of error
113 |  * @extends {Error}
114 |  */
115 | class HttpException extends Error {
116 |   /**
117 |    *
118 |    *
119 |    * @type {number} - The status of error
120 |    * @memberof HttpException
121 |    */
122 |   public status: number
123 | 
124 |   /**
125 |    *
126 |    *
127 |    * @type {string} - The messages of error
128 |    * @memberof HttpException
129 |    */
130 |   public message: string
131 | 
132 |   /**
133 |    * Creates an instance of HttpException.
134 |    * @param {number} status - The status of error
135 |    * @param {string} message - he message  of error
136 |    * @memberof HttpException
137 |    */
138 |   constructor(status: number, message: string) {
139 |     super(message);
140 |     this.status = status;
141 |     this.message = message;
142 |   }
143 | }
144 | 
145 | export default HttpException;
146 | 
147 |
148 |
149 | 150 | 151 | 152 | 153 |
154 | 155 | 164 | 165 |
166 |
167 |
168 |
169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | tracking-code-which-will-go-to-the-HEAD 6 | 7 | 8 | Documentation Home 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 |
36 | 41 | 49 | 72 |
73 |
74 |
75 | 90 |
91 |
92 |
93 |

94 |

Home

95 |
96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 |

104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 |
120 |

JsDoc Home

121 |
122 | 123 | 124 | 125 | 126 | 127 | 128 |
129 | 130 | 139 | 140 |
141 |
142 |
143 |
144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/interfaces_ICrud.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | tracking-code-which-will-go-to-the-HEAD 8 | 9 | 10 | Documentation interfaces/ICrud.ts 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 | 43 | 51 | 74 |
75 |
76 |
77 | 92 |
93 |
94 |
95 |

Source

96 |

interfaces/ICrud.ts

97 |
98 | 99 | 100 | 101 | 102 | 103 |
104 |
105 |
/* eslint-disable no-unused-vars */
106 | /**
107 |  *
108 |  * The interface for managament generics ICrud
109 |  * @category Interfaces
110 |  * @interface ICrud
111 |  * @template T - The type of resource
112 |  * @template U - The type of ID the resource
113 |  */
114 | interface ICrud<T, U> {
115 |      /**
116 |       *
117 |       * Create a new resource
118 |       * @param {T} object - Object to create
119 |       * @return {T} - Return a resource
120 |       * @memberof ICrud
121 |       */
122 |      create(object: T): Promise<T | null>;
123 |      /**
124 |       *
125 |       * List all resources of type T
126 |       * @return {Array<T>} - Return an Array<T> resources
127 |       * @memberof ICrud
128 |       */
129 |      list(): Promise<Array<T>>;
130 |      /**
131 |       *
132 |       * Get a resource by id
133 |       * @param {U} id - id of resource to find
134 |       * @return {T} - Return a resource
135 |       * @memberof ICrud
136 |       */
137 |      getById(id: U): Promise<T | null>;
138 |      /**
139 |       *
140 |       * Remove a resource
141 |       * @param {T} object - Object to remove
142 |       * @return {T} - Return a resource removed
143 |       * @memberof ICrud
144 |       */
145 |      remove(object: T): Promise<T | null>;
146 |      /**
147 |       *
148 |       *  Remove a resource by id
149 |       * @param {U} id - id of resource to find
150 |       * @return {T} - Return a resource
151 |       * @memberof ICrud
152 |       */
153 |      removeById(id: U): Promise<T | null>;
154 |      /**
155 |       *
156 |       * Update a resource
157 |       * @param {T} object - Object to update
158 |       * @return {T} - Return a resource updated
159 |       * @memberof ICrud
160 |       */
161 |      update(object: T): Promise<T | null>;
162 |      /**
163 |       *
164 |       * Update a resource by id
165 |       * @param {U} id - id of resource to find
166 |       * @param {T} id - Resource
167 |       * @return {T} - Return a resource updated
168 |       * @memberof ICrud
169 |       */
170 |      updateById(id: U, body: Object): Promise<T | null>;
171 | }
172 | 
173 | export default ICrud;
174 | 
175 |
176 |
177 | 178 | 179 | 180 | 181 |
182 | 183 | 192 | 193 |
194 |
195 |
196 |
197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/interfaces_IResourceExample.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | tracking-code-which-will-go-to-the-HEAD 8 | 9 | 10 | Documentation interfaces/IResourceExample.ts 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 | 43 | 51 | 74 |
75 |
76 |
77 | 92 |
93 |
94 |
95 |

Source

96 |

interfaces/IResourceExample.ts

97 |
98 | 99 | 100 | 101 | 102 | 103 |
104 |
105 |
import { Document } from 'mongoose';
106 | 
107 | /**
108 |  * Define a interface of resource to managament with mongoose
109 |  * @category Interfaces
110 |  * @interface IResourceExample
111 |  * @extends {Document}
112 |  */
113 | interface IResourceExample extends Document{
114 |     property: { type: String, required: true }
115 | }
116 | export default IResourceExample;
117 | 
118 |
119 |
120 | 121 | 122 | 123 | 124 |
125 | 126 | 135 | 136 |
137 |
138 |
139 |
140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/interfaces_IRoute.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | tracking-code-which-will-go-to-the-HEAD 8 | 9 | 10 | Documentation interfaces/IRoute.ts 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 | 43 | 51 | 74 |
75 |
76 |
77 | 92 |
93 |
94 |
95 |

Source

96 |

interfaces/IRoute.ts

97 |
98 | 99 | 100 | 101 | 102 | 103 |
104 |
105 |
import { Router } from 'express';
106 | /**
107 |  *
108 |  * Define the atributes of routes
109 |  * @category Interfaces
110 |  * @interface IRoute
111 |  */
112 | interface IRoute {
113 |     router: Router,
114 |     pathIdParam?: string
115 | }
116 | 
117 | export default IRoute;
118 | 
119 |
120 |
121 | 122 | 123 | 124 | 125 |
126 | 127 | 136 | 137 |
138 |
139 |
140 |
141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/interfaces_IUser.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | tracking-code-which-will-go-to-the-HEAD 8 | 9 | 10 | Documentation interfaces/IUser.ts 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 | 43 | 51 | 74 |
75 |
76 |
77 | 92 |
93 |
94 |
95 |

Source

96 |

interfaces/IUser.ts

97 |
98 | 99 | 100 | 101 | 102 | 103 |
104 |
105 |
import { Document } from 'mongoose';
106 | 
107 | /**
108 |  * Define a user interface to managament with mongoose
109 |  * @category Interfaces
110 |  * @interface   IUser
111 |  * @extends {Document}
112 |  */
113 | interface   IUser extends Document{
114 |     username: String,
115 |     email: String,
116 |     password: String,
117 |     verifyPassword: Function
118 | }
119 | export default  IUser;
120 | 
121 |
122 |
123 | 124 | 125 | 126 | 127 |
128 | 129 | 138 | 139 |
140 |
141 |
142 |
143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IngDeiver/express-typescript-template-generator/a6e1bb8dda9c8c7125bfaca850f41a1a0357d5d7/templates/base-tamplate/jsdoc/docs/logo.png -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/middlewares_isDefinedParamMiddleware.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | tracking-code-which-will-go-to-the-HEAD 8 | 9 | 10 | Documentation middlewares/isDefinedParamMiddleware.ts 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 | 43 | 51 | 74 |
75 |
76 |
77 | 92 |
93 |
94 |
95 |

Source

96 |

middlewares/isDefinedParamMiddleware.ts

97 |
98 | 99 | 100 | 101 | 102 | 103 |
104 |
105 |
import { isNotEmpty } from 'class-validator';
106 | import {
107 |   NextFunction, RequestHandler, Request, Response,
108 | } from 'express';
109 | import { HttpException } from '../exceptions';
110 | 
111 | const { ObjectId } = require('mongoose').Types;
112 | 
113 | /**
114 |  *
115 |  * Valid a value if is defined (is required), default valid id from url and valid _id of mongodb
116 |  * @category Middlewares
117 |  * @param {any} value - the value to validate
118 |  * @return {RequestHandler}  {RequestHandler}
119 |  */
120 | const isDefinedParam = (
121 |   value: 'params' | 'body' = 'params',
122 |   param: string = 'id',
123 |   validateMongoId: boolean = true,
124 | ): RequestHandler => (req: Request, res: Response, next: NextFunction) => {
125 |   const paramValue = req[value][param];
126 |   const exist: boolean = isNotEmpty(req[value][param]);
127 |   let isMongoId: boolean = false;
128 | 
129 |   if (validateMongoId) {
130 |     isMongoId = ObjectId.isValid(paramValue);
131 |     if (!exist || !isMongoId) {
132 |       return next(
133 |         new HttpException(400, `${value} is required and shoul be ObjectId`),
134 |       );
135 |     }
136 |   } else if (!exist) return next(new HttpException(400, `${value} is required`));
137 |   next();
138 | };
139 | export default isDefinedParam;
140 | 
141 |
142 |
143 | 144 | 145 | 146 | 147 |
148 | 149 | 158 | 159 |
160 |
161 |
162 |
163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/middlewares_isRequiredParamMiddleware.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | tracking-code-which-will-go-to-the-HEAD 8 | 9 | 10 | Documentation middlewares/isRequiredParamMiddleware.ts 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 | 43 | 51 | 74 |
75 |
76 |
77 | 92 |
93 |
94 |
95 |

Source

96 |

middlewares/isRequiredParamMiddleware.ts

97 |
98 | 99 | 100 | 101 | 102 | 103 |
104 |
105 |
import { isNotEmpty } from 'class-validator';
106 | import {
107 |   NextFunction, RequestHandler, Request, Response,
108 | } from 'express';
109 | import { HttpException } from '../exceptions';
110 | 
111 | const { ObjectId } = require('mongoose').Types;
112 | 
113 | /**
114 |  *
115 |  * Valid a value if is defined into req (body or params), default valid id from url and valid _id of mongodb
116 |  * @category Middlewares
117 |  * @param {any} value - the value to validate
118 |  * @return {RequestHandler}  {RequestHandler}
119 |  */
120 | const isDefinedParam = (
121 |   value: 'params' | 'body' = 'params',
122 |   param: string = 'id',
123 |   validateMongoId: boolean = true,
124 | ): RequestHandler => (req: Request, res: Response, next: NextFunction) => {
125 |   const paramValue = req[value][param];
126 |   const exist: boolean = isNotEmpty(paramValue);
127 |   let isMongoId: boolean = false;
128 | 
129 |   if (validateMongoId) {
130 |     isMongoId = ObjectId.isValid(paramValue);
131 |     if (!exist || !isMongoId) {
132 |       return next(
133 |         new HttpException(400, `${param} is required and shoul be ObjectId`),
134 |       );
135 |     }
136 |   } else if (!exist) return next(new HttpException(400, `${param} is required`));
137 |   next();
138 | };
139 | export default isDefinedParam;
140 | 
141 |
142 |
143 | 144 | 145 | 146 | 147 |
148 | 149 | 158 | 159 |
160 |
161 |
162 |
163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/middlewares_validationMiddleware.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | tracking-code-which-will-go-to-the-HEAD 8 | 9 | 10 | Documentation middlewares/validationMiddleware.ts 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 | 43 | 51 | 74 |
75 |
76 |
77 | 92 |
93 |
94 |
95 |

Source

96 |

middlewares/validationMiddleware.ts

97 |
98 | 99 | 100 | 101 | 102 | 103 |
104 |
105 |
import { validate, ValidationError } from 'class-validator';
106 | import { plainToClass } from 'class-transformer';
107 | import {
108 |   NextFunction, RequestHandler, Response, Request,
109 | } from 'express';
110 | import { HttpException } from '../exceptions';
111 | 
112 | /**
113 |  *
114 |  * Valid the body of DTO
115 |  * @category Middlewares
116 |  * @param {*} dto - the dto to validate
117 |  * @param {('body' | 'query' | 'params')} value - the prperty to get from the request
118 |  * @param {boolean} [skipMissingProperties=false] - true if should accept propertys unknow
119 |  * @return {*}  {RequestHandler}
120 |  */
121 | const validationMiddleware = (
122 |   dto: any,
123 |   skipMissingProperties = false, // true when need update
124 |   value: 'body' | 'query' | 'params' = 'body',
125 | ): RequestHandler => (req: Request, res: Response, next: NextFunction) => {
126 |   // plainToClass is a mapping
127 |   validate(plainToClass(dto, req[value]), {
128 |     validationError: { target: false },
129 |     skipMissingProperties,
130 |     whitelist: true,
131 |     forbidUnknownValues: true,
132 |   }).then((errors: ValidationError[]) => {
133 |     if (errors.length > 0) {
134 |       const message = errors
135 |         .map((error: ValidationError) => {
136 |           if (error.constraints) {
137 |              return Object.values(error.constraints)
138 |           };
139 |           return `${error.property}: validation error`;
140 |         })
141 |         .join(', ');
142 |       next(new HttpException(400, message));
143 |     } else {
144 |       next();
145 |     }
146 |   });
147 | };
148 | 
149 | export default validationMiddleware;
150 | 
151 |
152 |
153 | 154 | 155 | 156 | 157 |
158 | 159 | 168 | 169 |
170 |
171 |
172 |
173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/routes_example.route.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | tracking-code-which-will-go-to-the-HEAD 8 | 9 | 10 | Documentation routes/example.route.ts 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 | 43 | 51 | 74 |
75 |
76 |
77 | 92 |
93 |
94 |
95 |

Source

96 |

routes/example.route.ts

97 |
98 | 99 | 100 | 101 | 102 | 103 |
104 |
105 |
import {
106 |   NextFunction, Request, Response, Router,
107 | } from 'express';
108 | import { IRoute } from '../interfaces';
109 | import { ResourceExampleControler } from '../controller';
110 | import { isDefinedParamMiddleware, validationMiddleware } from '../middlewares';
111 | import { ExampleDTO } from '../dtos';
112 | 
113 | /**
114 |  *
115 |  * Managament the routes of resource
116 |  * @category Routes
117 |  * @class ExampleRouter
118 |  * @implements {IRoute}
119 |  */
120 | class ExampleRouter implements IRoute {
121 |   public router = Router();
122 | 
123 |   public pathIdParam = '/:id';
124 | 
125 |   constructor() {
126 |     this.createRoutes();
127 |   }
128 | 
129 |   createRoutes(): void {
130 |     this.router.get(
131 |       this.pathIdParam,
132 |       isDefinedParamMiddleware(),
133 |       (req: Request, res: Response, next: NextFunction) => ResourceExampleControler
134 |         .getById(req, res, next),
135 |     );
136 |     this.router.get('/', (req: Request, res: Response, next: NextFunction) => ResourceExampleControler
137 |       .list(req, res, next));
138 |     this.router.post(
139 |       '/',
140 |       validationMiddleware(ExampleDTO),
141 |       (req: Request, res: Response, next: NextFunction) => ResourceExampleControler
142 |         .create(req, res, next),
143 |     );
144 |     this.router.put(
145 |       this.pathIdParam,
146 |       isDefinedParamMiddleware(),
147 |       validationMiddleware(ExampleDTO, true),
148 |       (req: Request, res: Response, next: NextFunction) => ResourceExampleControler
149 |         .updateById(req, res, next),
150 |     );
151 |     this.router.delete(
152 |       this.pathIdParam,
153 |       isDefinedParamMiddleware(),
154 |       (req: Request, res: Response, next: NextFunction) => ResourceExampleControler
155 |         .removeById(req, res, next),
156 |     );
157 |   }
158 | }
159 | export default new ExampleRouter().router;
160 | 
161 |
162 |
163 | 164 | 165 | 166 | 167 |
168 | 169 | 178 | 179 |
180 |
181 |
182 |
183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/routes_user.route.ts.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | tracking-code-which-will-go-to-the-HEAD 8 | 9 | 10 | Documentation routes/user.route.ts 11 | 12 | 13 | 14 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
37 |
38 | 43 | 51 | 74 |
75 |
76 |
77 | 92 |
93 |
94 |
95 |

Source

96 |

routes/user.route.ts

97 |
98 | 99 | 100 | 101 | 102 | 103 |
104 |
105 |
import {
106 |   NextFunction, Request, Response, Router,
107 | } from 'express';
108 | import { IRoute } from '../interfaces';
109 | import { UserControler } from '../controller';
110 | import { isRequiredParamMiddleware, validationMiddleware } from '../middlewares';
111 | import { UserDTO } from '../dtos';
112 | 
113 | 
114 | /**
115 |  *
116 |  * Managament the routes of user
117 |  * @category Routes
118 |  * @class UserRouter
119 |  * @implements {IRoute}
120 |  */
121 | class UserRouter implements IRoute {
122 |   public router = Router();
123 | 
124 |   public pathIdParam = '/:id';
125 | 
126 |   constructor() {
127 |     this.createRoutes();
128 |   }
129 | 
130 |   createRoutes(): void {
131 | 
132 |     // get user by Id
133 |     this.router.get(
134 |       this.pathIdParam,
135 |       isRequiredParamMiddleware(),
136 |       (req: Request, res: Response, next: NextFunction) => UserControler
137 |         .getById(req, res, next),
138 |     );
139 | 
140 |     // list users
141 |     this.router.get('/', (req: Request, res: Response, next: NextFunction) => UserControler
142 |       .list(req, res, next));
143 | 
144 |     // Save user
145 |     this.router.post('/',
146 |       validationMiddleware(UserDTO),
147 |       (req: Request, res: Response, next: NextFunction) => UserControler
148 |         .create(req, res, next),
149 |     );
150 | 
151 |     // Update user
152 |     this.router.put(
153 |       this.pathIdParam,
154 |       isRequiredParamMiddleware(),
155 |       validationMiddleware(UserDTO, true),
156 |       (req: Request, res: Response, next: NextFunction) => UserControler
157 |         .updateById(req, res, next),
158 |     );
159 | 
160 |     // Remove user
161 |     this.router.delete(
162 |       this.pathIdParam,
163 |       isRequiredParamMiddleware(),
164 |       (req: Request, res: Response, next: NextFunction) => UserControler
165 |         .removeById(req, res, next),
166 |     );
167 |   }
168 | }
169 | export default new UserRouter().router;
170 | 
171 |
172 |
173 | 174 | 175 | 176 | 177 |
178 | 179 | 188 | 189 |
190 |
191 |
192 |
193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/scripts/app.min.js: -------------------------------------------------------------------------------- 1 | "use strict";$().ready(function(){});var sidebarIsVisible=!1,toggleSidebar=function(e){var a=!(0 h1").text();if(t){o.append($("

").text(t));var s=$("
    ");i.find(".members h4.name").each(function(e,a){var i=$(a),t=i.find(".code-name").clone().children().remove().end().text(),n=i.find("a").attr("href"),r=$('')).text(t);s.append($("
  • ").append(r)),c.push({link:r,offset:i.offset().top})}),o.append(s)}else i.find(".members h4.name").each(function(e,a){var i=$(a),t=i.find(".code-name").clone().children().remove().end().text(),n=i.find("a").attr("href"),r=$('
    ')).text(t);o.append(r),c.push({link:r,offset:i.offset().top})})}),!$.trim(o.text()))return o.hide();function e(){for(var e=n.scrollTop(),a=!1,i=c.length-1;0<=i;i--){var t=c[i];t.link.removeClass("is-active"),e+OFFSET>=t.offset?a?t.link.addClass("is-past"):(t.link.addClass("is-active"),a=!0):t.link.removeClass("is-past")}}var n=$("#main-content-wrapper");n.on("scroll",e),e(),c.forEach(function(e){e.link.click(function(){n.animate({scrollTop:e.offset-OFFSET+1},500)})})}),$().ready(function(){$("#sidebarNav a").each(function(e,a){var i=$(a).attr("href");window.location.pathname.match("/"+i)&&($(a).addClass("active"),$("#sidebarNav").scrollTop($(a).offset().top-150))})}); -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/scripts/linenumber.js: -------------------------------------------------------------------------------- 1 | /*global document */ 2 | 3 | (function() { 4 | var source = document.getElementsByClassName('prettyprint source linenums'); 5 | var i = 0; 6 | var lineNumber = 0; 7 | var lineId; 8 | var lines; 9 | var totalLines; 10 | var anchorHash; 11 | 12 | if (source && source[0]) { 13 | anchorHash = document.location.hash.substring(1); 14 | lines = source[0].getElementsByTagName('li'); 15 | totalLines = lines.length; 16 | 17 | for (; i < totalLines; i++) { 18 | lineNumber++; 19 | lineId = 'line' + lineNumber; 20 | lines[i].id = lineId; 21 | if (lineId === anchorHash) { 22 | lines[i].className += ' selected'; 23 | } 24 | } 25 | } 26 | })(); 27 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/scripts/search.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | const input = document.querySelector('#search') 3 | const targets = [ ...document.querySelectorAll('#sidebarNav li')] 4 | input.addEventListener('keyup', () => { 5 | // loop over each targets and hide the not corresponding ones 6 | targets.forEach(target => { 7 | if (!target.innerText.toLowerCase().includes(input.value.toLowerCase())) { 8 | target.style.display = 'none' 9 | 10 | /** 11 | * Detects an empty list 12 | * Remove the list and the list's title if the list is not displayed 13 | */ 14 | const list = [...target.parentNode.childNodes].filter( elem => elem.style.display !== 'none') 15 | 16 | if (!list.length) { 17 | target.parentNode.style.display = 'none' 18 | target.parentNode.previousSibling.style.display = 'none' 19 | } 20 | 21 | /** 22 | * Detects empty category 23 | * Remove the entire category if no item is displayed 24 | */ 25 | const category = [...target.parentNode.parentNode.childNodes] 26 | .filter( elem => elem.tagName !== 'H2' && elem.style.display !== 'none') 27 | 28 | if (!category.length) { 29 | target.parentNode.parentNode.style.display = 'none' 30 | } 31 | } else { 32 | target.parentNode.style.display = 'block' 33 | target.parentNode.previousSibling.style.display = 'block' 34 | target.parentNode.parentNode.style.display = 'block' 35 | target.style.display = 'block' 36 | } 37 | }) 38 | }) 39 | })() -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/style.css: -------------------------------------------------------------------------------- 1 | img[src="logo.png"]{ 2 | width: 70px; 3 | height: 50px; 4 | } -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/styles/iframe.css: -------------------------------------------------------------------------------- 1 | .bd__button { 2 | padding: 10px 0; 3 | text-align: right; 4 | } 5 | .bd__button > a{ 6 | font-weight: 100; 7 | text-decoration: none; 8 | color: #BDC3CB; 9 | font-family: sans-serif; 10 | } 11 | .bd__button > a:hover { 12 | color: #798897; 13 | } -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/styles/prettify-jsdoc.css: -------------------------------------------------------------------------------- 1 | /* JSDoc prettify.js theme */ 2 | 3 | /* plain text */ 4 | .pln { 5 | color: #000000; 6 | font-weight: normal; 7 | font-style: normal; 8 | } 9 | 10 | /* string content */ 11 | .str { 12 | color: #006400; 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | 17 | /* a keyword */ 18 | .kwd { 19 | color: #000000; 20 | font-weight: bold; 21 | font-style: normal; 22 | } 23 | 24 | /* a comment */ 25 | .com { 26 | font-weight: normal; 27 | font-style: italic; 28 | } 29 | 30 | /* a type name */ 31 | .typ { 32 | color: #000000; 33 | font-weight: normal; 34 | font-style: normal; 35 | } 36 | 37 | /* a literal value */ 38 | .lit { 39 | color: #006400; 40 | font-weight: normal; 41 | font-style: normal; 42 | } 43 | 44 | /* punctuation */ 45 | .pun { 46 | color: #000000; 47 | font-weight: bold; 48 | font-style: normal; 49 | } 50 | 51 | /* lisp open bracket */ 52 | .opn { 53 | color: #000000; 54 | font-weight: bold; 55 | font-style: normal; 56 | } 57 | 58 | /* lisp close bracket */ 59 | .clo { 60 | color: #000000; 61 | font-weight: bold; 62 | font-style: normal; 63 | } 64 | 65 | /* a markup tag name */ 66 | .tag { 67 | color: #006400; 68 | font-weight: normal; 69 | font-style: normal; 70 | } 71 | 72 | /* a markup attribute name */ 73 | .atn { 74 | color: #006400; 75 | font-weight: normal; 76 | font-style: normal; 77 | } 78 | 79 | /* a markup attribute value */ 80 | .atv { 81 | color: #006400; 82 | font-weight: normal; 83 | font-style: normal; 84 | } 85 | 86 | /* a declaration */ 87 | .dec { 88 | color: #000000; 89 | font-weight: bold; 90 | font-style: normal; 91 | } 92 | 93 | /* a variable name */ 94 | .var { 95 | color: #000000; 96 | font-weight: normal; 97 | font-style: normal; 98 | } 99 | 100 | /* a function name */ 101 | .fun { 102 | color: #000000; 103 | font-weight: bold; 104 | font-style: normal; 105 | } 106 | 107 | /* Specify class=linenums on a pre to get line numbering */ 108 | ol.linenums { 109 | margin-top: 0; 110 | margin-bottom: 0; 111 | } 112 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/styles/prettify-tomorrow.css: -------------------------------------------------------------------------------- 1 | /* Tomorrow Theme */ 2 | /* Original theme - https://github.com/chriskempson/tomorrow-theme */ 3 | /* Pretty printing styles. Used with prettify.js. */ 4 | /* SPAN elements with the classes below are added by prettyprint. */ 5 | /* plain text */ 6 | .pln { 7 | color: #4d4d4c; } 8 | 9 | @media screen { 10 | /* string content */ 11 | .str { 12 | color: #718c00; } 13 | 14 | /* a keyword */ 15 | .kwd { 16 | color: #8959a8; } 17 | 18 | /* a comment */ 19 | .com { 20 | color: #8e908c; } 21 | 22 | /* a type name */ 23 | .typ { 24 | color: #4271ae; } 25 | 26 | /* a literal value */ 27 | .lit { 28 | color: #f5871f; } 29 | 30 | /* punctuation */ 31 | .pun { 32 | color: #4d4d4c; } 33 | 34 | /* lisp open bracket */ 35 | .opn { 36 | color: #4d4d4c; } 37 | 38 | /* lisp close bracket */ 39 | .clo { 40 | color: #4d4d4c; } 41 | 42 | /* a markup tag name */ 43 | .tag { 44 | color: #c82829; } 45 | 46 | /* a markup attribute name */ 47 | .atn { 48 | color: #f5871f; } 49 | 50 | /* a markup attribute value */ 51 | .atv { 52 | color: #3e999f; } 53 | 54 | /* a declaration */ 55 | .dec { 56 | color: #f5871f; } 57 | 58 | /* a variable name */ 59 | .var { 60 | color: #c82829; } 61 | 62 | /* a function name */ 63 | .fun { 64 | color: #4271ae; } } 65 | /* Use higher contrast and text-weight for printable form. */ 66 | @media print, projection { 67 | .str { 68 | color: #060; } 69 | 70 | .kwd { 71 | color: #006; 72 | font-weight: bold; } 73 | 74 | .com { 75 | color: #600; 76 | font-style: italic; } 77 | 78 | .typ { 79 | color: #404; 80 | font-weight: bold; } 81 | 82 | .lit { 83 | color: #044; } 84 | 85 | .pun, .opn, .clo { 86 | color: #440; } 87 | 88 | .tag { 89 | color: #006; 90 | font-weight: bold; } 91 | 92 | .atn { 93 | color: #404; } 94 | 95 | .atv { 96 | color: #060; } } 97 | /* Style */ 98 | /* 99 | pre.prettyprint { 100 | background: white; 101 | font-family: Consolas, Monaco, 'Andale Mono', monospace; 102 | font-size: 12px; 103 | line-height: 1.5; 104 | border: 1px solid #ccc; 105 | padding: 10px; } 106 | */ 107 | 108 | /* Specify class=linenums on a pre to get line numbering */ 109 | ol.linenums { 110 | margin-top: 0; 111 | margin-bottom: 0; } 112 | 113 | /* IE indents via margin-left */ 114 | li.L0, 115 | li.L1, 116 | li.L2, 117 | li.L3, 118 | li.L4, 119 | li.L5, 120 | li.L6, 121 | li.L7, 122 | li.L8, 123 | li.L9 { 124 | /* */ } 125 | 126 | /* Alternate shading for lines */ 127 | li.L1, 128 | li.L3, 129 | li.L5, 130 | li.L7, 131 | li.L9 { 132 | /* */ } 133 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/docs/styles/reset.css: -------------------------------------------------------------------------------- 1 | /* reset css */ 2 | html, body, div, span, applet, object, iframe, 3 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 4 | a, abbr, acronym, address, big, cite, code, 5 | del, dfn, em, img, ins, kbd, q, s, samp, 6 | small, strike, strong, sub, sup, tt, var, 7 | b, u, i, center, 8 | dl, dt, dd, ol, ul, li, 9 | fieldset, form, label, legend, 10 | table, caption, tbody, tfoot, thead, tr, th, td, 11 | article, aside, canvas, details, embed, 12 | figure, figcaption, footer, header, hgroup, 13 | menu, nav, output, ruby, section, summary, 14 | time, mark, audio, video { 15 | margin: 0; 16 | padding: 0; 17 | border: 0; 18 | font-size: 100%; 19 | font: inherit; 20 | vertical-align: baseline; 21 | } 22 | /* HTML5 display-role reset for older browsers */ 23 | article, aside, details, figcaption, figure, 24 | footer, header, hgroup, menu, nav, section { 25 | display: block; 26 | } 27 | body { 28 | line-height: 1; 29 | } 30 | ol, ul { 31 | list-style: none; 32 | } 33 | blockquote, q { 34 | quotes: none; 35 | } 36 | blockquote:before, blockquote:after, 37 | q:before, q:after { 38 | content: ''; 39 | content: none; 40 | } 41 | table { 42 | border-collapse: collapse; 43 | border-spacing: 0; 44 | } 45 | -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/readme.md: -------------------------------------------------------------------------------- 1 | JsDoc Home -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/statics/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IngDeiver/express-typescript-template-generator/a6e1bb8dda9c8c7125bfaca850f41a1a0357d5d7/templates/base-tamplate/jsdoc/statics/logo.png -------------------------------------------------------------------------------- /templates/base-tamplate/jsdoc/statics/style.css: -------------------------------------------------------------------------------- 1 | img[src="logo.png"]{ 2 | width: 70px; 3 | height: 50px; 4 | } -------------------------------------------------------------------------------- /templates/base-tamplate/src/app.ts: -------------------------------------------------------------------------------- 1 | import Server from './server/Server'; 2 | import Database from './config/database'; 3 | import './config/dotenv'; 4 | import { logger } from './utils'; 5 | 6 | const PORT: number = process.env.PORT ? parseInt(process.env.PORT) : 3000; 7 | const server: Server = Server.init(PORT); 8 | 9 | // database 10 | Database.connect(); 11 | 12 | // START 13 | // eslint-disable-next-line no-console 14 | if (process.env.NODE_ENV !== 'test') { 15 | server.listen(() => logger.info(`🚀 App listening on the port ${PORT}`)); 16 | } 17 | export default server; 18 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/config/database.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-console */ 2 | // getting-started.js 3 | import mongoose, { Connection } from 'mongoose'; 4 | import { logger } from '../utils'; 5 | 6 | /** 7 | * 8 | * The clas for database managament 9 | * @class Database 10 | * 11 | */ 12 | class Database { 13 | static db: Connection; 14 | 15 | /** 16 | * 17 | * Make a conecttion with database configured 18 | * @static 19 | * @return Connection return a new connection 20 | * @memberof Database 21 | */ 22 | static connect(): Connection { 23 | mongoose.connect(process.env.DB_URI || '', { useNewUrlParser: true, useUnifiedTopology: true }) 24 | .then(() => logger.info('🟢 The database is connected.')) 25 | .catch((error) => logger.error(`🔴 Unable to connect to the database: ${error}.`)); 26 | this.db = mongoose.connection; 27 | return this.db; 28 | } 29 | 30 | /** 31 | * 32 | * CLose the current connection 33 | * @static 34 | * @memberof Database 35 | */ 36 | static close(): void { 37 | this.db.close(); 38 | } 39 | } 40 | export default Database; 41 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/config/dotenv.ts: -------------------------------------------------------------------------------- 1 | import * as dotenv from 'dotenv'; 2 | import path from 'path'; 3 | 4 | const environment = process.env.NODE_ENV; 5 | 6 | if (environment === 'production') { 7 | dotenv.config(); 8 | } else { 9 | dotenv.config({ path: path.resolve(process.cwd(), '.env.dev') }); 10 | } 11 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/config/index.ts: -------------------------------------------------------------------------------- 1 | import Database from './database'; 2 | 3 | export { 4 | // eslint-disable-next-line import/prefer-default-export 5 | Database, 6 | }; 7 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/controller/UserController.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | /* eslint-disable class-methods-use-this */ 3 | import { NextFunction, Response, Request } from 'express'; 4 | import { IUser } from '../interfaces'; 5 | import { User } from '../models'; 6 | import { HttpException } from '../exceptions'; 7 | import { UserService } from '../services'; 8 | import bcrypt from 'bcrypt' 9 | /** 10 | * 11 | * The user controller 12 | * @category Controllers 13 | * @class UserController 14 | */ 15 | class UserController { 16 | /** 17 | * 18 | * List all users 19 | * @static 20 | * @param {Request} req - The request 21 | * @param {Response} res - The response 22 | * @param {NextFunction} next - The next middleware in queue 23 | * @return {JSON} - A list of users 24 | * @memberof UserController 25 | */ 26 | public static async list(req: Request, res: Response, next: NextFunction) { 27 | try { 28 | const users: Array = await UserService.list(); 29 | res.json(users); 30 | } catch (error) { 31 | return next(new HttpException(error.status || 500, error.message)); 32 | } 33 | } 34 | 35 | /** 36 | * 37 | * create a new user 38 | * @static 39 | * @param {Request} req - The request 40 | * @param {Response} res - The response 41 | * @param {NextFunction} next - The next middleware in queue 42 | * @return {JSON} - A user creted 43 | * @memberof UserController 44 | */ 45 | public static async create(req: Request, res: Response, next: NextFunction) { 46 | try { 47 | let { username, email, password } = req.body; 48 | 49 | // Encrypt password 50 | password = bcrypt.hashSync(password, 10) 51 | 52 | const user:IUser = new User({ username, email, password }); 53 | const userSaved: IUser = await UserService.create(user); 54 | res.json(userSaved); 55 | } catch (error) { 56 | return next(new HttpException(error.status || 500, error.message)); 57 | } 58 | } 59 | 60 | /** 61 | * 62 | * Get user by id 63 | * @static 64 | * @param {Request} req - The request 65 | * @param {Response} res - The response 66 | * @param {NextFunction} next - The next middleware in queue 67 | * @return {JSON} - A list of users 68 | * @memberof UserController 69 | */ 70 | public static async getById(req: Request, res: Response, next: NextFunction) { 71 | try { 72 | const { id } = req.params; 73 | const user: IUser | null = await UserService.getById(id); 74 | if (!user) throw new HttpException(404, 'User not found'); 75 | res.json(user); 76 | } catch (error) { 77 | return next(new HttpException(error.status || 500, error.message)); 78 | } 79 | } 80 | 81 | /** 82 | * 83 | * Remove user by id 84 | * @static 85 | * @param {Request} req - The request 86 | * @param {Response} res - The response 87 | * @param {NextFunction} next - The next middleware in queue 88 | * @return {JSON} - A list of userS 89 | * @memberof UserController 90 | */ 91 | public static async removeById(req: Request, res: Response, next: NextFunction) { 92 | try { 93 | const { id } = req.params; 94 | const user: IUser | null = await UserService 95 | .removeById(id); 96 | if (!user) throw new HttpException(404, 'User not found'); 97 | res.json(user); 98 | } catch (error) { 99 | return next(new HttpException(error.status || 500, error.message)); 100 | } 101 | } 102 | 103 | /** 104 | * 105 | * Update user by id 106 | * @static 107 | * @param {Request} req - The request 108 | * @param {Response} res - The response 109 | * @param {NextFunction} next - The next middleware in queue 110 | * @return {JSON} - A list of userS 111 | * @memberof UserController 112 | */ 113 | public static async updateById(req: Request, res: Response, next: NextFunction) { 114 | try { 115 | const { id } = req.params; 116 | const { username, email, password } = req.body; 117 | const userUpdated: IUser | null = await UserService 118 | .updateById(id, { username, email, password}); 119 | if (!userUpdated) throw new HttpException(404, 'User not found'); 120 | res.json(userUpdated); 121 | } catch (error) { 122 | return next(new HttpException(error.status || 500, error.message)); 123 | } 124 | } 125 | 126 | } 127 | export default UserController; 128 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/controller/index.ts: -------------------------------------------------------------------------------- 1 | import UserControler from './UserController'; 2 | 3 | export { 4 | // eslint-disable-next-line import/prefer-default-export 5 | UserControler, 6 | }; 7 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/dtos/UserDTO.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-empty-function */ 2 | /* eslint-disable no-unused-vars */ 3 | /* eslint-disable no-useless-constructor */ 4 | 5 | import { IsString, IsNotEmpty, IsEmail } from 'class-validator'; 6 | 7 | /** 8 | * 9 | * DTO for user 10 | * @category DTOs 11 | * @class UserDTO 12 | * @param {string} username - A username 13 | */ 14 | class UserDTO { 15 | @IsNotEmpty() 16 | @IsString() 17 | public username: string; 18 | 19 | @IsNotEmpty() 20 | @IsEmail() 21 | public email: string 22 | 23 | @IsNotEmpty() 24 | @IsString() 25 | public password: string 26 | 27 | /** 28 | * Creates an instance of UserDTO. 29 | * @param {string} username - the name user 30 | * @param {string} email - the email user 31 | * @param {string} password - the password user 32 | * @memberof UserDTO 33 | */ 34 | constructor(username: string, email: string, password: string) { 35 | this.username = username; 36 | this.email = email; 37 | this.password = password; 38 | } 39 | } 40 | 41 | export default UserDTO; 42 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/dtos/index.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/prefer-default-export */ 2 | import UserDTO from './UserDTO'; 3 | 4 | export { 5 | UserDTO, 6 | }; 7 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/exceptions/errorHandler.ts: -------------------------------------------------------------------------------- 1 | import { Request, Response, NextFunction } from 'express'; 2 | import HttpException from './httpException'; 3 | 4 | /** 5 | * 6 | * The middleware for catch they erros into application 7 | * @category Exceptions 8 | * @param {HttpException} err - The error (if exist) 9 | * @param {Request} req - The request 10 | * @param {Response} res - The response 11 | * @param {NextFunction} cb - The next function (if pass) 12 | * @return {void} void 13 | */ 14 | const errorHandler = (err: HttpException, req: Request, res: Response, cb: NextFunction): void => { 15 | if (res.headersSent) { 16 | return cb(err); 17 | } 18 | 19 | res.status(err.status || 500).json({ 20 | error: { 21 | message: err.message, 22 | status: err.status, 23 | }, 24 | }); 25 | }; 26 | 27 | export default errorHandler; 28 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/exceptions/httpException.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * 4 | * Is a custom exception for implmented with the error handler 5 | * @category Exceptions 6 | * @class HttpException 7 | * @param {number} status - THe status of error 8 | * @param {string} message -The message of error 9 | * @extends {Error} 10 | */ 11 | class HttpException extends Error { 12 | /** 13 | * 14 | * 15 | * @type {number} - The status of error 16 | * @memberof HttpException 17 | */ 18 | public status: number 19 | 20 | /** 21 | * 22 | * 23 | * @type {string} - The messages of error 24 | * @memberof HttpException 25 | */ 26 | public message: string 27 | 28 | /** 29 | * Creates an instance of HttpException. 30 | * @param {number} status - The status of error 31 | * @param {string} message - he message of error 32 | * @memberof HttpException 33 | */ 34 | constructor(status: number, message: string) { 35 | super(message); 36 | this.status = status; 37 | this.message = message; 38 | } 39 | } 40 | 41 | export default HttpException; 42 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/exceptions/index.ts: -------------------------------------------------------------------------------- 1 | import HttpException from './httpException'; 2 | import ErrorHandler from './errorHandler'; 3 | 4 | export { 5 | HttpException, 6 | ErrorHandler, 7 | }; 8 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/interfaces/ICrud.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-unused-vars */ 2 | /** 3 | * 4 | * The interface for managament generics ICrud 5 | * @category Interfaces 6 | * @interface ICrud 7 | * @template T - The type of resource 8 | * @template U - The type of ID the resource 9 | */ 10 | interface ICrud { 11 | /** 12 | * 13 | * Create a new resource 14 | * @param {T} object - Object to create 15 | * @return {T} - Return a resource 16 | * @memberof ICrud 17 | */ 18 | create(object: T): Promise; 19 | /** 20 | * 21 | * List all resources of type T 22 | * @return {Array} - Return an Array resources 23 | * @memberof ICrud 24 | */ 25 | list(): Promise>; 26 | /** 27 | * 28 | * Get a resource by id 29 | * @param {U} id - id of resource to find 30 | * @return {T} - Return a resource 31 | * @memberof ICrud 32 | */ 33 | getById(id: U): Promise; 34 | /** 35 | * 36 | * Remove a resource 37 | * @param {T} object - Object to remove 38 | * @return {T} - Return a resource removed 39 | * @memberof ICrud 40 | */ 41 | remove(object: T): Promise; 42 | /** 43 | * 44 | * Remove a resource by id 45 | * @param {U} id - id of resource to find 46 | * @return {T} - Return a resource 47 | * @memberof ICrud 48 | */ 49 | removeById(id: U): Promise; 50 | /** 51 | * 52 | * Update a resource 53 | * @param {T} object - Object to update 54 | * @return {T} - Return a resource updated 55 | * @memberof ICrud 56 | */ 57 | update(object: T): Promise; 58 | /** 59 | * 60 | * Update a resource by id 61 | * @param {U} id - id of resource to find 62 | * @param {T} id - Resource 63 | * @return {T} - Return a resource updated 64 | * @memberof ICrud 65 | */ 66 | updateById(id: U, body: Object): Promise; 67 | } 68 | 69 | export default ICrud; 70 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/interfaces/IRoute.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | /** 3 | * 4 | * Define the atributes of routes 5 | * @category Interfaces 6 | * @interface IRoute 7 | */ 8 | interface IRoute { 9 | router: Router, 10 | pathIdParam?: string 11 | } 12 | 13 | export default IRoute; 14 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/interfaces/IUser.ts: -------------------------------------------------------------------------------- 1 | import { Document } from 'mongoose'; 2 | 3 | /** 4 | * Define a user interface to managament with mongoose 5 | * @category Interfaces 6 | * @interface IUser 7 | * @extends {Document} 8 | */ 9 | interface IUser extends Document{ 10 | username: String, 11 | email: String, 12 | password: String, 13 | verifyPassword: Function 14 | } 15 | export default IUser; 16 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/interfaces/index.ts: -------------------------------------------------------------------------------- 1 | import ICrud from './ICrud'; 2 | import IUser from './IUser'; 3 | import IRoute from './IRoute'; 4 | 5 | export { 6 | // eslint-disable-next-line import/prefer-default-export 7 | ICrud, 8 | IUser, 9 | IRoute, 10 | }; 11 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/middlewares/index.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable import/prefer-default-export */ 2 | import validationMiddleware from './validationMiddleware'; 3 | import isRequiredParamMiddleware from './isRequiredParamMiddleware'; 4 | 5 | export { 6 | validationMiddleware, 7 | isRequiredParamMiddleware, 8 | }; 9 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/middlewares/isRequiredParamMiddleware.ts: -------------------------------------------------------------------------------- 1 | import { isNotEmpty } from 'class-validator'; 2 | import { 3 | NextFunction, RequestHandler, Request, Response, 4 | } from 'express'; 5 | import { HttpException } from '../exceptions'; 6 | 7 | const { ObjectId } = require('mongoose').Types; 8 | 9 | /** 10 | * 11 | * Valid a value if is defined into req (body or params), default valid id from url and valid _id of mongodb 12 | * @category Middlewares 13 | * @param {any} value - the value to validate 14 | * @return {RequestHandler} {RequestHandler} 15 | */ 16 | const isDefinedParam = ( 17 | value: 'params' | 'body' = 'params', 18 | param: string = 'id', 19 | validateMongoId: boolean = true, 20 | ): RequestHandler => (req: Request, res: Response, next: NextFunction) => { 21 | const paramValue = req[value][param]; 22 | const exist: boolean = isNotEmpty(paramValue); 23 | let isMongoId: boolean = false; 24 | 25 | if (validateMongoId) { 26 | isMongoId = ObjectId.isValid(paramValue); 27 | if (!exist || !isMongoId) { 28 | return next( 29 | new HttpException(400, `${param} is required and shoul be ObjectId`), 30 | ); 31 | } 32 | } else if (!exist) return next(new HttpException(400, `${param} is required`)); 33 | next(); 34 | }; 35 | export default isDefinedParam; 36 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/middlewares/validationMiddleware.ts: -------------------------------------------------------------------------------- 1 | import { validate, ValidationError } from 'class-validator'; 2 | import { plainToClass } from 'class-transformer'; 3 | import { 4 | NextFunction, RequestHandler, Response, Request, 5 | } from 'express'; 6 | import { HttpException } from '../exceptions'; 7 | 8 | /** 9 | * 10 | * Valid the body of DTO 11 | * @category Middlewares 12 | * @param {*} dto - the dto to validate 13 | * @param {('body' | 'query' | 'params')} value - the prperty to get from the request 14 | * @param {boolean} [skipMissingProperties=false] - true if should accept propertys unknow 15 | * @return {*} {RequestHandler} 16 | */ 17 | const validationMiddleware = ( 18 | dto: any, 19 | skipMissingProperties = false, // true when need update 20 | value: 'body' | 'query' | 'params' = 'body', 21 | ): RequestHandler => (req: Request, res: Response, next: NextFunction) => { 22 | // plainToClass is a mapping 23 | validate(plainToClass(dto, req[value]), { 24 | validationError: { target: false }, 25 | skipMissingProperties, 26 | whitelist: true, 27 | forbidUnknownValues: true, 28 | }).then((errors: ValidationError[]) => { 29 | if (errors.length > 0) { 30 | const message = errors 31 | .map((error: ValidationError) => { 32 | if (error.constraints) { 33 | return Object.values(error.constraints) 34 | }; 35 | return `${error.property}: validation error`; 36 | }) 37 | .join(', '); 38 | next(new HttpException(400, message)); 39 | } else { 40 | next(); 41 | } 42 | }); 43 | }; 44 | 45 | export default validationMiddleware; 46 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/models/User.ts: -------------------------------------------------------------------------------- 1 | import mongoose, { Model, Schema } from 'mongoose'; 2 | import { IUser } from '../interfaces'; 3 | import bcrypt from 'bcrypt' 4 | 5 | const UserSchema: Schema = new Schema({ 6 | username: { type: String, required: true }, 7 | email: { type: String, required: true, unique: true}, 8 | password: {type: String, required: true} 9 | }); 10 | 11 | // Verify the password 12 | UserSchema.methods.verifyPassword = function (password: string) { 13 | return bcrypt.compare(password, this.password) 14 | } 15 | 16 | const User: Model = mongoose.model('User', UserSchema); 17 | export default User; 18 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/models/index.ts: -------------------------------------------------------------------------------- 1 | import User from './User'; 2 | 3 | export { 4 | // eslint-disable-next-line import/prefer-default-export 5 | User, 6 | }; 7 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/repository/UserRepository.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-underscore-dangle */ 2 | /* eslint-disable no-unused-vars */ 3 | /* eslint-disable class-methods-use-this */ 4 | import { UserDTO } from 'dtos'; 5 | import { ICrud, IUser } from '../interfaces'; 6 | import { User } from '../models'; 7 | 8 | /** 9 | * 10 | * The user repository 11 | * @category Repositorys 12 | * @class UserRepository 13 | * @implements {ICrud} 14 | */ 15 | class UserRepository implements ICrud { 16 | /** 17 | * 18 | * 19 | * @param {IUser} user - The user to create 20 | * @return {Promise} A user created 21 | * @memberof UserRepository 22 | */ 23 | create(user: IUser): Promise { 24 | return new Promise((resolve, reject) => { 25 | user.save() 26 | .then((user: IUser) => resolve(user)) 27 | .catch(err => reject(err)) 28 | }) 29 | } 30 | 31 | /** 32 | * 33 | * 34 | * @return {Promise>} A list of users 35 | * @memberof UserRepository 36 | */ 37 | list(): Promise> { 38 | return new Promise>((resolve, reject) => { 39 | User.find({}) 40 | .then((user: Array) => resolve(user)) 41 | .catch(err => reject(err)) 42 | }) 43 | } 44 | 45 | /** 46 | * 47 | * 48 | * @param {string} id - The id to find 49 | * @return {Promise} A User 50 | * @memberof UserRepository 51 | */ 52 | getById(id: string): Promise { 53 | return new Promise((resolve, reject) => { 54 | User.findById(id) 55 | .then((user: IUser | null) => resolve(user)) 56 | .catch(err => reject(err)) 57 | }) 58 | } 59 | 60 | /** 61 | * 62 | * 63 | * @param {IUser} user - The user to remove 64 | * @return {Promise} A user removed 65 | * @memberof UserRepository 66 | */ 67 | remove(user: IUser): Promise { 68 | return new Promise(async (resolve, reject) => { 69 | try { 70 | if (user._id) await user.remove(); 71 | resolve(user) 72 | } catch (error) { 73 | reject(error) 74 | } 75 | }) 76 | } 77 | 78 | /** 79 | * 80 | * 81 | * @param {string} id - The id to find 82 | * @return {Promise} A user removed 83 | * @memberof UserRepository 84 | */ 85 | removeById(id: string): Promise { 86 | return new Promise(async (resolve, reject) => { 87 | try { 88 | const userToDelete: IUser | null = await User.findByIdAndRemove(id) 89 | if (userToDelete) await userToDelete.remove(); 90 | resolve(userToDelete) 91 | } catch (error) { 92 | reject(error) 93 | } 94 | }) 95 | } 96 | 97 | /** 98 | * 99 | * 100 | * @param {IUser} user - The user to updated 101 | * @return {Promise} A user updated 102 | * @memberof UserRepository 103 | */ 104 | async update(user: IUser): Promise { 105 | return new Promise(async (resolve, reject) => { 106 | try { 107 | if (user._id) await user.update(); 108 | resolve(user) 109 | } catch (error) { 110 | reject(error) 111 | } 112 | }); 113 | } 114 | 115 | /** 116 | * 117 | * 118 | * @param {string} id - The id to find 119 | * @param {IUser} user - The user to updated 120 | * @return {Promise} A user updated 121 | * @memberof UserRepository 122 | */ 123 | async updateById(id: string, user: UserDTO): 124 | Promise { 125 | return new Promise(async (resolve, reject) => { 126 | try { 127 | const userToUpdate = await User.findByIdAndUpdate(id, user, { new: true}) 128 | resolve(userToUpdate) 129 | } catch (error) { 130 | reject(error) 131 | } 132 | }) 133 | } 134 | } 135 | export default new UserRepository(); 136 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/repository/index.ts: -------------------------------------------------------------------------------- 1 | import UserRepository from './UserRepository'; 2 | 3 | export { 4 | // eslint-disable-next-line import/prefer-default-export 5 | UserRepository, 6 | }; 7 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/routes/index.ts: -------------------------------------------------------------------------------- 1 | import { Router } from 'express'; 2 | import UserRouter from './user.route'; 3 | 4 | const router = Router(); 5 | const prefix: string = '/api'; 6 | 7 | router.use(`${prefix}/user`, UserRouter); 8 | 9 | export default router; 10 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/routes/user.route.ts: -------------------------------------------------------------------------------- 1 | import { 2 | NextFunction, Request, Response, Router, 3 | } from 'express'; 4 | import { IRoute } from '../interfaces'; 5 | import { UserControler } from '../controller'; 6 | import { isRequiredParamMiddleware, validationMiddleware } from '../middlewares'; 7 | import { UserDTO } from '../dtos'; 8 | 9 | 10 | /** 11 | * 12 | * Managament the routes of user 13 | * @category Routes 14 | * @class UserRouter 15 | * @implements {IRoute} 16 | */ 17 | class UserRouter implements IRoute { 18 | public router = Router(); 19 | 20 | public pathIdParam = '/:id'; 21 | 22 | constructor() { 23 | this.createRoutes(); 24 | } 25 | 26 | createRoutes(): void { 27 | 28 | // get user by Id 29 | this.router.get( 30 | this.pathIdParam, 31 | isRequiredParamMiddleware(), 32 | (req: Request, res: Response, next: NextFunction) => UserControler 33 | .getById(req, res, next), 34 | ); 35 | 36 | // list users 37 | this.router.get('/', (req: Request, res: Response, next: NextFunction) => UserControler 38 | .list(req, res, next)); 39 | 40 | // Save user 41 | this.router.post('/', 42 | validationMiddleware(UserDTO), 43 | (req: Request, res: Response, next: NextFunction) => UserControler 44 | .create(req, res, next), 45 | ); 46 | 47 | // Update user 48 | this.router.put( 49 | this.pathIdParam, 50 | isRequiredParamMiddleware(), 51 | validationMiddleware(UserDTO, true), 52 | (req: Request, res: Response, next: NextFunction) => UserControler 53 | .updateById(req, res, next), 54 | ); 55 | 56 | // Remove user 57 | this.router.delete( 58 | this.pathIdParam, 59 | isRequiredParamMiddleware(), 60 | (req: Request, res: Response, next: NextFunction) => UserControler 61 | .removeById(req, res, next), 62 | ); 63 | } 64 | } 65 | export default new UserRouter().router; 66 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/server/Server.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import cors from 'cors'; 3 | import morgan from 'morgan'; 4 | import router from '../routes'; 5 | import errorHandler from '../exceptions/errorHandler'; 6 | import { stream } from '../utils'; 7 | 8 | /** 9 | * 10 | * 11 | * The class of managament application 12 | * @class Server 13 | */ 14 | class Server { 15 | /** 16 | * 17 | * 18 | * @type {express.Application} - the instance of application 19 | * @memberof Server 20 | */ 21 | public app: express.Application; 22 | 23 | /** 24 | * 25 | * 26 | * @type {string} - the current environment 27 | * @memberof Server 28 | */ 29 | public env: string; 30 | 31 | /** 32 | * Creates an instance of Server. 33 | * @param {number} port - The por of app listen 34 | * @memberof Server 35 | */ 36 | // eslint-disable-next-line no-unused-vars 37 | constructor(private port: number) { 38 | this.app = express(); 39 | this.env = process.env.NODE_ENV || 'development'; 40 | this.initializeMiddlewares(); 41 | this.initializeRoutes(); 42 | this.initializeErrorHandling(); 43 | } 44 | 45 | /** 46 | * 47 | * Initialize the application 48 | * @static 49 | * @param {number} port - the port 50 | * @return Server 51 | * @memberof Server 52 | */ 53 | static init(port: number): Server { 54 | return new Server(port); 55 | } 56 | 57 | /** 58 | * 59 | * Start listen the server 60 | * @param {Function} callback 61 | * @memberof Server 62 | */ 63 | listen(callback: Function): void { 64 | this.app.listen(this.port, callback()); 65 | } 66 | 67 | /** 68 | * 69 | * Initialize the middlewares of the application 70 | * @private 71 | * @memberof Server 72 | */ 73 | private initializeMiddlewares() { 74 | if (this.env === 'production') { 75 | this.app.use(morgan('combined', { stream })); 76 | this.app.use(cors({ origin: 'your.domain.com', credentials: true })); 77 | } else if (this.env === 'development') { 78 | this.app.use(morgan('dev', { stream })); 79 | this.app.use(cors({ origin: true, credentials: true })); 80 | } 81 | 82 | this.app.use(express.json()); 83 | this.app.use(router); 84 | } 85 | 86 | /** 87 | * 88 | * Initialize the routes of application 89 | * @private 90 | * @memberof Server 91 | */ 92 | private initializeRoutes(): void { 93 | this.app.use(router); 94 | } 95 | 96 | /** 97 | * 98 | * Initialize the error handler of the applicacion 99 | * @private 100 | * @memberof Server 101 | */ 102 | private initializeErrorHandling() { 103 | this.app.use(errorHandler); 104 | } 105 | } 106 | 107 | export default Server; 108 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/services/UserService.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable class-methods-use-this */ 2 | import { ICrud, IUser} from '../interfaces'; 3 | import { UserRepository } from '../repository'; 4 | import { User} from '../models'; 5 | import { UserDTO } from 'dtos'; 6 | 7 | /** 8 | * 9 | * The user service,layer of repository pattern 10 | * @category Services 11 | * @class UserService 12 | * @implements {ICrud} 13 | */ 14 | class UserService implements ICrud { 15 | /** 16 | * 17 | * Create a user 18 | * @param {IUser} user - The user to create 19 | * @return {Promise} A user created 20 | * @memberof UserService 21 | */ 22 | async create(user: IUser): Promise { 23 | return new Promise((resolve, reject) => { 24 | UserRepository.create(user) 25 | .then((user: IUser) => resolve(user)) 26 | .catch(err => reject(err)) 27 | }) 28 | } 29 | 30 | /** 31 | * 32 | * List all users 33 | * @return {Promise>} A list of tasks 34 | * @memberof UserService 35 | */ 36 | async list(): Promise> { 37 | return new Promise>((resolve, reject) => { 38 | UserRepository.list() 39 | .then((user: Array) => resolve(user)) 40 | .catch(err => reject(err)) 41 | }) 42 | } 43 | 44 | /** 45 | * 46 | * Find by id a user 47 | * @param {string} id - The id to find 48 | * @return {Promise} A user 49 | * @memberof UserService 50 | */ 51 | async getById(id: string): Promise { 52 | return new Promise((resolve, reject) => { 53 | UserRepository.getById(id) 54 | .then((user: IUser | null) => resolve(user)) 55 | .catch(err => reject(err)) 56 | }) 57 | } 58 | 59 | /** 60 | * 61 | * Remove a user 62 | * @param {IUser} user - The user to remove 63 | * @return {Promise} A user removed 64 | * @memberof UserService 65 | */ 66 | async remove(user: IUser): Promise { 67 | return new Promise(async (resolve, reject) => { 68 | try { 69 | if (user._id) await UserRepository.remove(user); 70 | resolve(user) 71 | } catch (error) { 72 | reject(error) 73 | } 74 | }) 75 | } 76 | 77 | /** 78 | * 79 | * Remove by id a user 80 | * @param {string} id - The id to find 81 | * @return {Promise} A user removed 82 | * @memberof UserService 83 | */ 84 | async removeById(id: string): Promise { 85 | return new Promise(async (resolve, reject) => { 86 | try { 87 | const userToDelete: IUser | null = await UserRepository.removeById(id) 88 | if (userToDelete) await userToDelete.remove(); 89 | resolve(userToDelete) 90 | } catch (error) { 91 | reject(error) 92 | } 93 | }) 94 | } 95 | 96 | /** 97 | * 98 | * Update a user 99 | * @param {IUser} user - The user to updated 100 | * @return {Promise} A user updated 101 | * @memberof UserService 102 | */ 103 | async update(user: IUser): Promise { 104 | return new Promise(async (resolve, reject) => { 105 | try { 106 | if (user._id) await UserRepository.update(user) 107 | resolve(user) 108 | } catch (error) { 109 | reject(error) 110 | } 111 | }); 112 | } 113 | 114 | /** 115 | * 116 | * Update by id a user 117 | * @param {string} id - The id to find 118 | * @param {IUser} user - The user to updated 119 | * @return {Promise} A user updated 120 | * @memberof UserService 121 | */ 122 | async updateById(id: string, user: UserDTO): Promise { 123 | // eslint-disable-next-line no-unused-vars 124 | return new Promise(async (resolve, reject) => { 125 | try { 126 | const userToUpdate = await UserRepository.updateById(id, user) 127 | resolve(userToUpdate) 128 | } catch (error) { 129 | reject(error) 130 | } 131 | }) 132 | } 133 | } 134 | 135 | export default new UserService(); 136 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/services/index.ts: -------------------------------------------------------------------------------- 1 | import UserService from './UserService'; 2 | 3 | export { 4 | // eslint-disable-next-line import/prefer-default-export 5 | UserService, 6 | }; 7 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/setupTests.ts: -------------------------------------------------------------------------------- 1 | import './config/dotenv'; 2 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | import { logger, stream } from './logger'; 2 | 3 | export { 4 | // eslint-disable-next-line import/prefer-default-export 5 | logger, 6 | stream, 7 | }; 8 | -------------------------------------------------------------------------------- /templates/base-tamplate/src/utils/logger.ts: -------------------------------------------------------------------------------- 1 | import winston from 'winston'; 2 | 3 | // winston format 4 | const { printf } = winston.format; 5 | 6 | // Define log format 7 | // eslint-disable-next-line no-shadow 8 | const logFormat = printf(({ level, message }) => `${level}: ${message}`); 9 | 10 | // simple log console with winston 11 | const logger = winston.createLogger({ 12 | format: logFormat, 13 | transports: [ 14 | new winston.transports.Console({ 15 | format: winston.format.combine(winston.format.splat(), winston.format.colorize(), 16 | winston.format.simple()), 17 | }), 18 | ], 19 | }); 20 | 21 | const stream = { 22 | write: (message: string) => { 23 | logger.info(message.substring(0, message.lastIndexOf('\n'))); 24 | }, 25 | }; 26 | 27 | export { logger, stream }; 28 | -------------------------------------------------------------------------------- /templates/base-tamplate/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "outDir": "./dist", 5 | "rootDir": "./", 6 | "strict": true, 7 | "esModuleInterop": true, 8 | "skipLibCheck": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "baseUrl": "src", 11 | "paths": { 12 | "test-utils": ["./utils/test-utils"] 13 | }, 14 | "experimentalDecorators": true 15 | } 16 | } -------------------------------------------------------------------------------- /util/createDirectoryContents.js: -------------------------------------------------------------------------------- 1 | const fs = require("fs"); 2 | const path = require("path"); 3 | const template = require("./template"); 4 | const ignoreFeature = require('./ignoreFeature') 5 | 6 | 7 | module.exports = function createDirectoryContents( 8 | templatePath, 9 | pathDirectoryTocreateContent, 10 | PACKGE_JSON_PROPERTIES_VALUES, 11 | CURRENT_DIR 12 | ) { 13 | const filesToCreate = fs.readdirSync(templatePath); 14 | const basePatch = path.join(CURRENT_DIR, pathDirectoryTocreateContent); 15 | 16 | filesToCreate.forEach((file) => { 17 | const origFilePath = path.join(templatePath, file); 18 | let writePath = `${basePatch}/${file}`; 19 | const SKIP_FILES = [ 20 | "node_modules", 21 | ".env", 22 | ".env.dev", 23 | "README.md", 24 | ".git", 25 | "gitignorefile" 26 | ]; 27 | 28 | // get stats about the current file 29 | const stats = fs.statSync(origFilePath); 30 | 31 | //ignore files 32 | if (SKIP_FILES.indexOf(file) > -1) return; 33 | 34 | // ignore features 35 | if(!PACKGE_JSON_PROPERTIES_VALUES.jsdoc){ 36 | if(ignoreFeature(file, "jsdoc")) return; 37 | }; 38 | 39 | 40 | if (stats.isFile()) { // copy files into directory 41 | // read file content and transform it using template engine 42 | let contents = fs.readFileSync(origFilePath, "utf8"); 43 | // If the file is package.json apply the dinamyc properties 44 | if (file.includes("dinamic-package")) { 45 | contents = template.render(contents.toString(), { 46 | projectName: PACKGE_JSON_PROPERTIES_VALUES.projectName, 47 | author: PACKGE_JSON_PROPERTIES_VALUES.author, 48 | projectDescription: PACKGE_JSON_PROPERTIES_VALUES.projectDescription, 49 | license: PACKGE_JSON_PROPERTIES_VALUES.license, 50 | jsdoc: PACKGE_JSON_PROPERTIES_VALUES.jsdoc, 51 | }); 52 | packeJsonFileName = "package.json"; 53 | writePath = `${basePatch}/${packeJsonFileName}`; 54 | } 55 | fs.writeFileSync(writePath, contents, "utf8"); 56 | 57 | } else if (stats.isDirectory()) { // create directory 58 | fs.mkdirSync(`${writePath}`); 59 | // recursive call 60 | createDirectoryContents(`${origFilePath}`, `${pathDirectoryTocreateContent}/${file}`, PACKGE_JSON_PROPERTIES_VALUES, CURRENT_DIR); 61 | } 62 | }); 63 | 64 | console.log(`Writing files into: ${basePatch}`); 65 | }; 66 | -------------------------------------------------------------------------------- /util/createGitignore.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const gitIgnoreFileName = 'gitignorefile' 3 | const path = require('path') 4 | 5 | module.exports = function (CURRENT_DIR, projectName, templatePath) { 6 | const projectPath = path.join(CURRENT_DIR, projectName); 7 | const writeGitIgnorePath = `${projectPath}/.gitignore`; 8 | 9 | const gitIgnoreFilePath = path.join(templatePath, gitIgnoreFileName); 10 | let gitignoreContent = fs.readFileSync(gitIgnoreFilePath, "utf8"); 11 | 12 | fs.writeFileSync(writeGitIgnorePath, gitignoreContent.toString(), "utf8"); 13 | }; 14 | -------------------------------------------------------------------------------- /util/createProjectDirectory.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | 3 | module.exports = function createProjectDirectory(projectPath) { 4 | if (fs.existsSync(projectPath)) { 5 | console.log( 6 | chalk.red(`😭 Folder ${projectPath} exists. Delete or use another name.`) 7 | ); 8 | return false; 9 | } 10 | 11 | fs.mkdirSync(projectPath); 12 | return true; 13 | } -------------------------------------------------------------------------------- /util/ignoreFeature.js: -------------------------------------------------------------------------------- 1 | module.exports = function (fileOrDirectory, feature) { 2 | return fileOrDirectory.toLowerCase().includes(feature.toLowerCase()) 3 | } -------------------------------------------------------------------------------- /util/questions.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | const CHOICES = fs.readdirSync(path.join(__dirname, "../templates")); 4 | 5 | module.exports = [{ 6 | name: "template-choice", 7 | type: "list", 8 | message: "What template would you like to generate?", 9 | choices: CHOICES, 10 | }, 11 | { 12 | name: "project-name", 13 | type: "input", 14 | default: "express-project", 15 | message: "Write a project name:", 16 | validate: function (input) { 17 | if (/^([A-Za-z\-\_\d])+$/.test(input)) return true; 18 | else 19 | return "Project name may only include letters, numbers, underscores and hashes."; 20 | }, 21 | }, 22 | { 23 | name: "project-author", 24 | type: "input", 25 | default: "Without author", 26 | message: "Author", 27 | validate: function (input) { 28 | if (/^([A-Za-z\-\_\ \d])+$/.test(input)) return true; 29 | else 30 | return "Author name may only include letters, numbers, underscores and hashes."; 31 | }, 32 | }, 33 | { 34 | name: "project-description", 35 | type: "input", 36 | default: "Without description", 37 | message: "Write a description" 38 | }, 39 | { 40 | name: "project-license", 41 | type: "input", 42 | default: "ISC", 43 | message: "Write a license name:", 44 | }, 45 | { 46 | name: "features", 47 | type: "checkbox", 48 | message: "Select features to use", 49 | choices: [{ name: "Jsdoc", checked: true, value: true }], 50 | }, 51 | ]; -------------------------------------------------------------------------------- /util/template.js: -------------------------------------------------------------------------------- 1 | const ejs = require("ejs") 2 | 3 | function render(content, data) { 4 | return ejs.render(content, data); 5 | } 6 | 7 | module.exports = { 8 | render 9 | } --------------------------------------------------------------------------------