├── .gitignore ├── .jshintrc ├── .npmignore ├── LICENSE ├── README.md ├── cli.gif ├── index.js ├── package-lock.json ├── package.json ├── templates ├── graphql-from-rest-apollo-rest │ ├── .prettierrc │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── data │ │ │ ├── data-circuits.ts │ │ │ ├── data-drivers.ts │ │ │ ├── data-races.ts │ │ │ ├── data-seasons.ts │ │ │ ├── data-source.ts │ │ │ └── index.ts │ │ ├── lib │ │ │ └── utils.ts │ │ ├── resolvers │ │ │ ├── query.ts │ │ │ ├── resolverMap.ts │ │ │ └── type.ts │ │ ├── schema │ │ │ ├── schema.graphql │ │ │ └── schema.ts │ │ └── server.ts │ ├── tsconfig.json │ └── tslint.json ├── graphql-hello-world-db │ ├── .gitignore │ ├── .prettierrc │ ├── README.md │ ├── package.json │ ├── src │ │ ├── .env │ │ ├── .env_example │ │ ├── config │ │ │ ├── constants.ts │ │ │ ├── database.ts │ │ │ └── environments.ts │ │ ├── lib │ │ │ └── datetime.ts │ │ ├── resolvers │ │ │ ├── mutation.ts │ │ │ ├── query.ts │ │ │ └── resolversMap.ts │ │ ├── schema │ │ │ ├── index.ts │ │ │ └── schema.graphql │ │ └── server.ts │ ├── tsconfig.json │ └── tslint.json ├── graphql-hello-world-with-env │ ├── .gitignore │ ├── .prettierrc │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── .env │ │ ├── .env_example │ │ ├── config │ │ │ └── environments.ts │ │ ├── resolvers │ │ │ ├── mutation.ts │ │ │ ├── query.ts │ │ │ └── resolverMap.ts │ │ ├── schema │ │ │ ├── schema.graphql │ │ │ └── schema.ts │ │ └── server.ts │ ├── tsconfig.json │ └── tslint.json ├── graphql-hello-world │ ├── .gitignore │ ├── .prettierrc │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── src │ │ ├── resolvers │ │ │ ├── mutation.ts │ │ │ ├── query.ts │ │ │ └── resolversMap.ts │ │ ├── schema │ │ │ ├── index.ts │ │ │ └── schema.graphql │ │ └── server.ts │ ├── tsconfig.json │ └── tslint.json └── graphql-jwt-system │ ├── .gitignore │ ├── .prettierrc │ ├── README.md │ ├── package.json │ ├── src │ ├── .env │ ├── .env_example │ ├── config │ │ ├── constants.ts │ │ ├── database.ts │ │ └── environments.ts │ ├── lib │ │ ├── datetime.ts │ │ └── jwt.ts │ ├── resolvers │ │ ├── mutation.ts │ │ ├── query.ts │ │ └── resolversMap.ts │ ├── schema │ │ ├── index.ts │ │ └── schema.graphql │ └── server.ts │ ├── tsconfig.json │ └── tslint.json └── utils └── templates.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | !.envpackage-lock.json 4 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esversion": 6 3 | } 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | ficheros/ 2 | .DS_Store -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Anartz Mugika Ledo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Generador de proyectos GraphQL 2 | 3 | Este generador servirá para crear proyectos de GraphQL con diferentes variantes con el objetivo de agilizar el proceso de crear el proyecto sin tener que hacer todos los pasos iniciales una y otra vez. 4 | 5 | Si algo de lo que habéis visto créeis que os ha sido útil y me queréis apoyar, podéis invitarme a un café: 6 |

7 | 8 | # Requirements 9 | * Node >= 10.15.3 10 | * NPM >= 6.0.0 11 | 12 | # Proyectos 13 | 14 | ## Hola Mundo sin variables de entorno 15 | 16 | Ejemplo en el que tenemos un simple hola mundo en GraphQL con varios tipos de saludo y con la configuración más básica. 17 | ```graphql-hello-world``` 18 | 19 | ## Hola Mundo con configuración de la base de datos MongoDB 20 | 21 | Ejemplo en el que tenemos un simple hola mundo en GraphQL con varios tipos de saludo y con la configuración de la base de datos MongoDB disponible para poder trabajar con bases de datos sin tener que hacer el proceso de configuración paso a paso. Simplemente tenemos que ir al fichero **.env** y en la variable de entorno añadimos la referencia de la base de datos correcta. 22 | ```graphql-hello-world-db``` 23 | 24 | ## Hola Mundo con variables de entorno 25 | 26 | Ejemplo en el que tenemos un simple hola mundo en GraphQL con varios tipos de saludo y con la configuración más básica. Es el mismo ejemplo que el anterior pero en este caso ya tenemos configurado el apartado de las variables de entorno para poder añadirlas en el proyecto con el fichero **.env** 27 | ```graphql-hello-world-with-env``` 28 | 29 | ## Sistema de Login / Registro con JWT 30 | 31 | Ejemplo en el que tenemos un simple servidor GraphQL con la gestión de registro de usuarios, login, visualización de lista de usuarios y autenticación mediante tokens de JWT. Viene configurado el apartado de la base de datos y la configuración de las variables de entorno para que podamos empezar un proyecto con un sistema de autenticación completa como por ejemplo para crear un chat con usuarios. 32 | ```graphql-jwt-system``` 33 | 34 | # Install 35 | ```npm install -g mugan86/graphql-project-cli``` 36 | # Usage 37 | Ejecutamos esta orden 38 | ```graphql-anartz``` 39 | 40 | # Example 41 | ![CLI](./cli.gif) 42 | -------------------------------------------------------------------------------- /cli.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mugan86/graphql-project-cli/7781fe9c93e73bcc2ecc1715e37bc39997673e50/cli.gif -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | // Los imports 4 | const fs = require('fs'); 5 | const path = require('path'); 6 | const inquirer = require('inquirer'); 7 | const shell = require('shelljs'); 8 | const chalk = require('chalk'); 9 | 10 | const render = require('./utils/templates').render; 11 | 12 | // Obtener las opciones de los templates 13 | 14 | const TEMPLATE_OPTIONS = fs.readdirSync(path.join(__dirname, 'templates')); 15 | 16 | // console.log(TEMPLATE_OPTIONS); 17 | 18 | const QUESTIONS = [ 19 | { 20 | name: 'template', 21 | type: 'list', 22 | message: '¿Qué tipo de proyecto quieres generar?', 23 | choices: TEMPLATE_OPTIONS 24 | }, 25 | { 26 | name: 'proyecto', 27 | type: 'input', 28 | message: '¿Cuál es el nombre del proyecto?', 29 | validate: function(input) { 30 | if(/^([a-z@]{1}[a-z\-\.\\\/0-9]{0,213})+$/.test(input)) { 31 | return true; 32 | } 33 | return 'El nombre del proyecto solo puede tener 214 carácteres y tiene que empezar en minúsculas o con una arroba'; 34 | } 35 | }, 36 | { 37 | name: 'github', 38 | type: 'input', 39 | message: 'Usuario Github' 40 | }, 41 | { 42 | name: 'author', 43 | type: 'input', 44 | message: 'Desarrolador - Nombre y Apellidos' 45 | }, 46 | { 47 | name: 'email', 48 | type: 'input', 49 | message: 'Desarrollador - Email' 50 | } 51 | ]; 52 | const DIR_ACTUAL = process.cwd(); 53 | inquirer.prompt(QUESTIONS).then(respuestas => { 54 | const template = respuestas['template']; 55 | const proyecto = respuestas['proyecto']; 56 | const github = respuestas['github']; 57 | const author = respuestas['author']; 58 | const email = respuestas['email']; 59 | 60 | const templatePath = path.join(__dirname, 'templates', template); 61 | const pathTarget = path.join(DIR_ACTUAL, proyecto); 62 | if (!createProject(pathTarget)) return; 63 | 64 | createDirectoriesFilesContent(templatePath, proyecto, github, author, email); 65 | 66 | postProccess(templatePath, pathTarget); 67 | }); 68 | 69 | function createProject(projectPath) { 70 | // Comprobar que no existe el directorio 71 | if(fs.existsSync(projectPath)) { 72 | console.log(chalk.red('No puedes crear el proyecto porque ya existe, intenta con otro')); 73 | return false; 74 | } 75 | fs.mkdirSync(projectPath); 76 | return true; 77 | } 78 | 79 | function createDirectoriesFilesContent(templatePath, projectName, githubUser, authorNameLastname, emailValue, nodeVersion) { 80 | const listFileDirectories = fs.readdirSync(templatePath); 81 | 82 | listFileDirectories.forEach( item => { 83 | const originalPath = path.join(templatePath, item); 84 | 85 | const stats = fs.statSync(originalPath); 86 | 87 | const writePath = path.join(DIR_ACTUAL, projectName, item); 88 | 89 | if (stats.isFile() ) { 90 | let contents = fs.readFileSync(originalPath, 'utf-8'); 91 | contents = render(contents, {projectName, githubUser, authorNameLastname, emailValue, nodeVersion}); 92 | fs.writeFileSync(writePath, contents, 'utf-8'); 93 | // Información adicional 94 | const CREATE = chalk.green('CREATE '); 95 | const size = stats['size']; 96 | console.log(`${CREATE} ${writePath} (${size} bytes)`); 97 | } else if (stats.isDirectory() ) { 98 | fs.mkdirSync(writePath); 99 | createDirectoriesFilesContent(path.join(templatePath, item), path.join(projectName, item)); 100 | } 101 | }) 102 | } 103 | 104 | function postProccess(templatePath, targetPath) { 105 | const isNode = fs.existsSync(path.join(templatePath, 'package.json')); 106 | 107 | if (isNode) { 108 | shell.cd(targetPath); 109 | console.log(chalk.green(`Instalando las dependencias en ${targetPath}`)); 110 | const result = shell.exec('npm install'); 111 | if (result.code != 0) { 112 | return false; 113 | } 114 | } 115 | } -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@mugan86/graphql-projects-cli", 3 | "version": "1.4.0", 4 | "lockfileVersion": 2, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "@mugan86/graphql-projects-cli", 9 | "version": "1.4.0", 10 | "license": "MIT", 11 | "dependencies": { 12 | "chalk": "^2.4.2", 13 | "ejs": "^2.6.1", 14 | "inquirer": "^6.3.1", 15 | "shelljs": "^0.8.3" 16 | }, 17 | "bin": { 18 | "graphql-anartz": "index.js" 19 | } 20 | }, 21 | "node_modules/ansi-escapes": { 22 | "version": "3.2.0", 23 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", 24 | "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", 25 | "engines": { 26 | "node": ">=4" 27 | } 28 | }, 29 | "node_modules/ansi-regex": { 30 | "version": "3.0.0", 31 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 32 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 33 | "engines": { 34 | "node": ">=4" 35 | } 36 | }, 37 | "node_modules/ansi-styles": { 38 | "version": "3.2.1", 39 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 40 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 41 | "dependencies": { 42 | "color-convert": "^1.9.0" 43 | }, 44 | "engines": { 45 | "node": ">=4" 46 | } 47 | }, 48 | "node_modules/balanced-match": { 49 | "version": "1.0.0", 50 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 51 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 52 | }, 53 | "node_modules/brace-expansion": { 54 | "version": "1.1.11", 55 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 56 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 57 | "dependencies": { 58 | "balanced-match": "^1.0.0", 59 | "concat-map": "0.0.1" 60 | } 61 | }, 62 | "node_modules/chalk": { 63 | "version": "2.4.2", 64 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 65 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 66 | "dependencies": { 67 | "ansi-styles": "^3.2.1", 68 | "escape-string-regexp": "^1.0.5", 69 | "supports-color": "^5.3.0" 70 | }, 71 | "engines": { 72 | "node": ">=4" 73 | } 74 | }, 75 | "node_modules/chardet": { 76 | "version": "0.7.0", 77 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", 78 | "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" 79 | }, 80 | "node_modules/cli-cursor": { 81 | "version": "2.1.0", 82 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", 83 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", 84 | "dependencies": { 85 | "restore-cursor": "^2.0.0" 86 | }, 87 | "engines": { 88 | "node": ">=4" 89 | } 90 | }, 91 | "node_modules/cli-width": { 92 | "version": "2.2.0", 93 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 94 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" 95 | }, 96 | "node_modules/color-convert": { 97 | "version": "1.9.3", 98 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 99 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 100 | "dependencies": { 101 | "color-name": "1.1.3" 102 | } 103 | }, 104 | "node_modules/color-name": { 105 | "version": "1.1.3", 106 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 107 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 108 | }, 109 | "node_modules/concat-map": { 110 | "version": "0.0.1", 111 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 112 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 113 | }, 114 | "node_modules/ejs": { 115 | "version": "2.7.4", 116 | "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", 117 | "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", 118 | "engines": { 119 | "node": ">=0.10.0" 120 | } 121 | }, 122 | "node_modules/escape-string-regexp": { 123 | "version": "1.0.5", 124 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 125 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 126 | "engines": { 127 | "node": ">=0.8.0" 128 | } 129 | }, 130 | "node_modules/external-editor": { 131 | "version": "3.1.0", 132 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", 133 | "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", 134 | "dependencies": { 135 | "chardet": "^0.7.0", 136 | "iconv-lite": "^0.4.24", 137 | "tmp": "^0.0.33" 138 | }, 139 | "engines": { 140 | "node": ">=4" 141 | } 142 | }, 143 | "node_modules/figures": { 144 | "version": "2.0.0", 145 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", 146 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", 147 | "dependencies": { 148 | "escape-string-regexp": "^1.0.5" 149 | }, 150 | "engines": { 151 | "node": ">=4" 152 | } 153 | }, 154 | "node_modules/fs.realpath": { 155 | "version": "1.0.0", 156 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 157 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 158 | }, 159 | "node_modules/glob": { 160 | "version": "7.1.6", 161 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 162 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 163 | "dependencies": { 164 | "fs.realpath": "^1.0.0", 165 | "inflight": "^1.0.4", 166 | "inherits": "2", 167 | "minimatch": "^3.0.4", 168 | "once": "^1.3.0", 169 | "path-is-absolute": "^1.0.0" 170 | }, 171 | "engines": { 172 | "node": "*" 173 | } 174 | }, 175 | "node_modules/has-flag": { 176 | "version": "3.0.0", 177 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 178 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 179 | "engines": { 180 | "node": ">=4" 181 | } 182 | }, 183 | "node_modules/iconv-lite": { 184 | "version": "0.4.24", 185 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 186 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 187 | "dependencies": { 188 | "safer-buffer": ">= 2.1.2 < 3" 189 | }, 190 | "engines": { 191 | "node": ">=0.10.0" 192 | } 193 | }, 194 | "node_modules/inflight": { 195 | "version": "1.0.6", 196 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 197 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 198 | "dependencies": { 199 | "once": "^1.3.0", 200 | "wrappy": "1" 201 | } 202 | }, 203 | "node_modules/inherits": { 204 | "version": "2.0.4", 205 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 206 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 207 | }, 208 | "node_modules/inquirer": { 209 | "version": "6.5.2", 210 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", 211 | "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", 212 | "dependencies": { 213 | "ansi-escapes": "^3.2.0", 214 | "chalk": "^2.4.2", 215 | "cli-cursor": "^2.1.0", 216 | "cli-width": "^2.0.0", 217 | "external-editor": "^3.0.3", 218 | "figures": "^2.0.0", 219 | "lodash": "^4.17.12", 220 | "mute-stream": "0.0.7", 221 | "run-async": "^2.2.0", 222 | "rxjs": "^6.4.0", 223 | "string-width": "^2.1.0", 224 | "strip-ansi": "^5.1.0", 225 | "through": "^2.3.6" 226 | }, 227 | "engines": { 228 | "node": ">=6.0.0" 229 | } 230 | }, 231 | "node_modules/interpret": { 232 | "version": "1.2.0", 233 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", 234 | "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", 235 | "engines": { 236 | "node": ">= 0.10" 237 | } 238 | }, 239 | "node_modules/is-fullwidth-code-point": { 240 | "version": "2.0.0", 241 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 242 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 243 | "engines": { 244 | "node": ">=4" 245 | } 246 | }, 247 | "node_modules/is-promise": { 248 | "version": "2.1.0", 249 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 250 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" 251 | }, 252 | "node_modules/lodash": { 253 | "version": "4.17.15", 254 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 255 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" 256 | }, 257 | "node_modules/mimic-fn": { 258 | "version": "1.2.0", 259 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", 260 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", 261 | "engines": { 262 | "node": ">=4" 263 | } 264 | }, 265 | "node_modules/minimatch": { 266 | "version": "3.0.4", 267 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 268 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 269 | "dependencies": { 270 | "brace-expansion": "^1.1.7" 271 | }, 272 | "engines": { 273 | "node": "*" 274 | } 275 | }, 276 | "node_modules/mute-stream": { 277 | "version": "0.0.7", 278 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", 279 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" 280 | }, 281 | "node_modules/once": { 282 | "version": "1.4.0", 283 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 284 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 285 | "dependencies": { 286 | "wrappy": "1" 287 | } 288 | }, 289 | "node_modules/onetime": { 290 | "version": "2.0.1", 291 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", 292 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", 293 | "dependencies": { 294 | "mimic-fn": "^1.0.0" 295 | }, 296 | "engines": { 297 | "node": ">=4" 298 | } 299 | }, 300 | "node_modules/os-tmpdir": { 301 | "version": "1.0.2", 302 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 303 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 304 | "engines": { 305 | "node": ">=0.10.0" 306 | } 307 | }, 308 | "node_modules/path-is-absolute": { 309 | "version": "1.0.1", 310 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 311 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 312 | "engines": { 313 | "node": ">=0.10.0" 314 | } 315 | }, 316 | "node_modules/path-parse": { 317 | "version": "1.0.6", 318 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 319 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" 320 | }, 321 | "node_modules/rechoir": { 322 | "version": "0.6.2", 323 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", 324 | "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", 325 | "dependencies": { 326 | "resolve": "^1.1.6" 327 | }, 328 | "engines": { 329 | "node": ">= 0.10" 330 | } 331 | }, 332 | "node_modules/resolve": { 333 | "version": "1.15.1", 334 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", 335 | "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", 336 | "dependencies": { 337 | "path-parse": "^1.0.6" 338 | } 339 | }, 340 | "node_modules/restore-cursor": { 341 | "version": "2.0.0", 342 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", 343 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", 344 | "dependencies": { 345 | "onetime": "^2.0.0", 346 | "signal-exit": "^3.0.2" 347 | }, 348 | "engines": { 349 | "node": ">=4" 350 | } 351 | }, 352 | "node_modules/run-async": { 353 | "version": "2.4.0", 354 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", 355 | "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", 356 | "dependencies": { 357 | "is-promise": "^2.1.0" 358 | }, 359 | "engines": { 360 | "node": ">=0.12.0" 361 | } 362 | }, 363 | "node_modules/rxjs": { 364 | "version": "6.5.4", 365 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", 366 | "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", 367 | "dependencies": { 368 | "tslib": "^1.9.0" 369 | }, 370 | "engines": { 371 | "npm": ">=2.0.0" 372 | } 373 | }, 374 | "node_modules/safer-buffer": { 375 | "version": "2.1.2", 376 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 377 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 378 | }, 379 | "node_modules/shelljs": { 380 | "version": "0.8.3", 381 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz", 382 | "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==", 383 | "dependencies": { 384 | "glob": "^7.0.0", 385 | "interpret": "^1.0.0", 386 | "rechoir": "^0.6.2" 387 | }, 388 | "bin": { 389 | "shjs": "bin/shjs" 390 | }, 391 | "engines": { 392 | "node": ">=4" 393 | } 394 | }, 395 | "node_modules/signal-exit": { 396 | "version": "3.0.2", 397 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 398 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 399 | }, 400 | "node_modules/string-width": { 401 | "version": "2.1.1", 402 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 403 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 404 | "dependencies": { 405 | "is-fullwidth-code-point": "^2.0.0", 406 | "strip-ansi": "^4.0.0" 407 | }, 408 | "engines": { 409 | "node": ">=4" 410 | } 411 | }, 412 | "node_modules/string-width/node_modules/strip-ansi": { 413 | "version": "4.0.0", 414 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 415 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 416 | "dependencies": { 417 | "ansi-regex": "^3.0.0" 418 | }, 419 | "engines": { 420 | "node": ">=4" 421 | } 422 | }, 423 | "node_modules/strip-ansi": { 424 | "version": "5.2.0", 425 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 426 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 427 | "dependencies": { 428 | "ansi-regex": "^4.1.0" 429 | }, 430 | "engines": { 431 | "node": ">=6" 432 | } 433 | }, 434 | "node_modules/strip-ansi/node_modules/ansi-regex": { 435 | "version": "4.1.0", 436 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 437 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 438 | "engines": { 439 | "node": ">=6" 440 | } 441 | }, 442 | "node_modules/supports-color": { 443 | "version": "5.5.0", 444 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 445 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 446 | "dependencies": { 447 | "has-flag": "^3.0.0" 448 | }, 449 | "engines": { 450 | "node": ">=4" 451 | } 452 | }, 453 | "node_modules/through": { 454 | "version": "2.3.8", 455 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 456 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" 457 | }, 458 | "node_modules/tmp": { 459 | "version": "0.0.33", 460 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 461 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 462 | "dependencies": { 463 | "os-tmpdir": "~1.0.2" 464 | }, 465 | "engines": { 466 | "node": ">=0.6.0" 467 | } 468 | }, 469 | "node_modules/tslib": { 470 | "version": "1.11.1", 471 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", 472 | "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==" 473 | }, 474 | "node_modules/wrappy": { 475 | "version": "1.0.2", 476 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 477 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 478 | } 479 | }, 480 | "dependencies": { 481 | "ansi-escapes": { 482 | "version": "3.2.0", 483 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", 484 | "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==" 485 | }, 486 | "ansi-regex": { 487 | "version": "3.0.0", 488 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 489 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" 490 | }, 491 | "ansi-styles": { 492 | "version": "3.2.1", 493 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 494 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 495 | "requires": { 496 | "color-convert": "^1.9.0" 497 | } 498 | }, 499 | "balanced-match": { 500 | "version": "1.0.0", 501 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 502 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 503 | }, 504 | "brace-expansion": { 505 | "version": "1.1.11", 506 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 507 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 508 | "requires": { 509 | "balanced-match": "^1.0.0", 510 | "concat-map": "0.0.1" 511 | } 512 | }, 513 | "chalk": { 514 | "version": "2.4.2", 515 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 516 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 517 | "requires": { 518 | "ansi-styles": "^3.2.1", 519 | "escape-string-regexp": "^1.0.5", 520 | "supports-color": "^5.3.0" 521 | } 522 | }, 523 | "chardet": { 524 | "version": "0.7.0", 525 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", 526 | "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" 527 | }, 528 | "cli-cursor": { 529 | "version": "2.1.0", 530 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", 531 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", 532 | "requires": { 533 | "restore-cursor": "^2.0.0" 534 | } 535 | }, 536 | "cli-width": { 537 | "version": "2.2.0", 538 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 539 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" 540 | }, 541 | "color-convert": { 542 | "version": "1.9.3", 543 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 544 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 545 | "requires": { 546 | "color-name": "1.1.3" 547 | } 548 | }, 549 | "color-name": { 550 | "version": "1.1.3", 551 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 552 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 553 | }, 554 | "concat-map": { 555 | "version": "0.0.1", 556 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 557 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 558 | }, 559 | "ejs": { 560 | "version": "2.7.4", 561 | "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", 562 | "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==" 563 | }, 564 | "escape-string-regexp": { 565 | "version": "1.0.5", 566 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 567 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 568 | }, 569 | "external-editor": { 570 | "version": "3.1.0", 571 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", 572 | "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", 573 | "requires": { 574 | "chardet": "^0.7.0", 575 | "iconv-lite": "^0.4.24", 576 | "tmp": "^0.0.33" 577 | } 578 | }, 579 | "figures": { 580 | "version": "2.0.0", 581 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", 582 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", 583 | "requires": { 584 | "escape-string-regexp": "^1.0.5" 585 | } 586 | }, 587 | "fs.realpath": { 588 | "version": "1.0.0", 589 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 590 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 591 | }, 592 | "glob": { 593 | "version": "7.1.6", 594 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 595 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 596 | "requires": { 597 | "fs.realpath": "^1.0.0", 598 | "inflight": "^1.0.4", 599 | "inherits": "2", 600 | "minimatch": "^3.0.4", 601 | "once": "^1.3.0", 602 | "path-is-absolute": "^1.0.0" 603 | } 604 | }, 605 | "has-flag": { 606 | "version": "3.0.0", 607 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 608 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" 609 | }, 610 | "iconv-lite": { 611 | "version": "0.4.24", 612 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 613 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 614 | "requires": { 615 | "safer-buffer": ">= 2.1.2 < 3" 616 | } 617 | }, 618 | "inflight": { 619 | "version": "1.0.6", 620 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 621 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 622 | "requires": { 623 | "once": "^1.3.0", 624 | "wrappy": "1" 625 | } 626 | }, 627 | "inherits": { 628 | "version": "2.0.4", 629 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 630 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 631 | }, 632 | "inquirer": { 633 | "version": "6.5.2", 634 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz", 635 | "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==", 636 | "requires": { 637 | "ansi-escapes": "^3.2.0", 638 | "chalk": "^2.4.2", 639 | "cli-cursor": "^2.1.0", 640 | "cli-width": "^2.0.0", 641 | "external-editor": "^3.0.3", 642 | "figures": "^2.0.0", 643 | "lodash": "^4.17.12", 644 | "mute-stream": "0.0.7", 645 | "run-async": "^2.2.0", 646 | "rxjs": "^6.4.0", 647 | "string-width": "^2.1.0", 648 | "strip-ansi": "^5.1.0", 649 | "through": "^2.3.6" 650 | } 651 | }, 652 | "interpret": { 653 | "version": "1.2.0", 654 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", 655 | "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==" 656 | }, 657 | "is-fullwidth-code-point": { 658 | "version": "2.0.0", 659 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 660 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" 661 | }, 662 | "is-promise": { 663 | "version": "2.1.0", 664 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 665 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" 666 | }, 667 | "lodash": { 668 | "version": "4.17.15", 669 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 670 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" 671 | }, 672 | "mimic-fn": { 673 | "version": "1.2.0", 674 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", 675 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" 676 | }, 677 | "minimatch": { 678 | "version": "3.0.4", 679 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 680 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 681 | "requires": { 682 | "brace-expansion": "^1.1.7" 683 | } 684 | }, 685 | "mute-stream": { 686 | "version": "0.0.7", 687 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", 688 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" 689 | }, 690 | "once": { 691 | "version": "1.4.0", 692 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 693 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 694 | "requires": { 695 | "wrappy": "1" 696 | } 697 | }, 698 | "onetime": { 699 | "version": "2.0.1", 700 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", 701 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", 702 | "requires": { 703 | "mimic-fn": "^1.0.0" 704 | } 705 | }, 706 | "os-tmpdir": { 707 | "version": "1.0.2", 708 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 709 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" 710 | }, 711 | "path-is-absolute": { 712 | "version": "1.0.1", 713 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 714 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 715 | }, 716 | "path-parse": { 717 | "version": "1.0.6", 718 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 719 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" 720 | }, 721 | "rechoir": { 722 | "version": "0.6.2", 723 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", 724 | "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", 725 | "requires": { 726 | "resolve": "^1.1.6" 727 | } 728 | }, 729 | "resolve": { 730 | "version": "1.15.1", 731 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", 732 | "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", 733 | "requires": { 734 | "path-parse": "^1.0.6" 735 | } 736 | }, 737 | "restore-cursor": { 738 | "version": "2.0.0", 739 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", 740 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", 741 | "requires": { 742 | "onetime": "^2.0.0", 743 | "signal-exit": "^3.0.2" 744 | } 745 | }, 746 | "run-async": { 747 | "version": "2.4.0", 748 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", 749 | "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", 750 | "requires": { 751 | "is-promise": "^2.1.0" 752 | } 753 | }, 754 | "rxjs": { 755 | "version": "6.5.4", 756 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", 757 | "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", 758 | "requires": { 759 | "tslib": "^1.9.0" 760 | } 761 | }, 762 | "safer-buffer": { 763 | "version": "2.1.2", 764 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 765 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 766 | }, 767 | "shelljs": { 768 | "version": "0.8.3", 769 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz", 770 | "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==", 771 | "requires": { 772 | "glob": "^7.0.0", 773 | "interpret": "^1.0.0", 774 | "rechoir": "^0.6.2" 775 | } 776 | }, 777 | "signal-exit": { 778 | "version": "3.0.2", 779 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 780 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 781 | }, 782 | "string-width": { 783 | "version": "2.1.1", 784 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 785 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 786 | "requires": { 787 | "is-fullwidth-code-point": "^2.0.0", 788 | "strip-ansi": "^4.0.0" 789 | }, 790 | "dependencies": { 791 | "strip-ansi": { 792 | "version": "4.0.0", 793 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 794 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 795 | "requires": { 796 | "ansi-regex": "^3.0.0" 797 | } 798 | } 799 | } 800 | }, 801 | "strip-ansi": { 802 | "version": "5.2.0", 803 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 804 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 805 | "requires": { 806 | "ansi-regex": "^4.1.0" 807 | }, 808 | "dependencies": { 809 | "ansi-regex": { 810 | "version": "4.1.0", 811 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 812 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" 813 | } 814 | } 815 | }, 816 | "supports-color": { 817 | "version": "5.5.0", 818 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 819 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 820 | "requires": { 821 | "has-flag": "^3.0.0" 822 | } 823 | }, 824 | "through": { 825 | "version": "2.3.8", 826 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 827 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" 828 | }, 829 | "tmp": { 830 | "version": "0.0.33", 831 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 832 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 833 | "requires": { 834 | "os-tmpdir": "~1.0.2" 835 | } 836 | }, 837 | "tslib": { 838 | "version": "1.11.1", 839 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", 840 | "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==" 841 | }, 842 | "wrappy": { 843 | "version": "1.0.2", 844 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 845 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 846 | } 847 | } 848 | } 849 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@mugan86/graphql-projects-cli", 3 | "version": "1.4.1", 4 | "description": "Different GraphQL Projects CLI Generator - 2020", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/mugan86/graphql-project-cli.git" 12 | }, 13 | "author": "Anartz Mugika Ledo", 14 | "license": "MIT", 15 | "bugs": { 16 | "url": "https://github.com/mugan86/graphql-project-cli/issues" 17 | }, 18 | "bin": { 19 | "graphql-anartz": "./index.js" 20 | }, 21 | "publishConfig": { 22 | "registry": "https://npm.pkg.github.com/@mugan86" 23 | }, 24 | "homepage": "https://github.com/mugan86/graphql-project-cli#readme", 25 | "dependencies": { 26 | "chalk": "^2.4.2", 27 | "ejs": "^2.6.1", 28 | "inquirer": "^6.3.1", 29 | "shelljs": "^0.8.3" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "vetur.format.defaultFormatterOptions": { 4 | "prettier": { 5 | "singleQuote": true 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 GraphQL Courses 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/README.md: -------------------------------------------------------------------------------- 1 | # <%= projectName %> 2 | 3 | Introduce el contenido de tu README -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= projectName %>", 3 | "version": "1.0.0", 4 | "description": "API GRaphQL F1 desde API Rest mediante RestDataSource", 5 | "main": "build/server.js", 6 | "scripts": { 7 | "start": "node build/server.js", 8 | "build": "tsc -p . && ncp src/schema build/schema", 9 | "start:dev": "npm run build:dev", 10 | "build:dev": "nodemon \"src/server.ts\" --exec \"ts-node\" src-server.ts -e ts,graphql,json" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/mugan86/rest-to-api-graphql.git" 15 | }, 16 | "keywords": [ "ergast", "api-rest-to-graphql", "graphql", "rest-data-source"], 17 | "author": "Anartz Mugika Ledo ", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/mugan86/rest-to-api-graphql/issues" 21 | }, 22 | "homepage": "https://github.com/mugan86/rest-to-api-graphql#readme", 23 | "dependencies": { 24 | "apollo-datasource-rest": "^0.6.0", 25 | "apollo-server": "^2.7.0", 26 | "apollo-server-express": "^2.6.1", 27 | "compression": "^1.7.4", 28 | "cors": "^2.8.5", 29 | "dotenv": "^8.0.0", 30 | "express": "^4.17.1", 31 | "graphql": "^14.3.1", 32 | "graphql-import": "^0.7.1", 33 | "graphql-import-node": "0.0.4", 34 | "graphql-playground-middleware-express": "^1.7.12", 35 | "graphql-tools": "^4.0.4", 36 | "http": "0.0.0", 37 | "ncp": "^2.0.0", 38 | "typescript": "^3.5.1" 39 | }, 40 | "devDependencies": { 41 | "@types/compression": "0.0.36", 42 | "@types/cors": "^2.8.5", 43 | "@types/dotenv": "^6.1.1", 44 | "@types/express": "^4.16.1", 45 | "@types/graphql": "^14.2.0", 46 | "@types/node": "^12.0.4", 47 | "nodemon": "^2.0.7", 48 | "ts-node": "^9.1.1", 49 | "typescript-tslint-plugin": "0.5.5" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/src/data/data-circuits.ts: -------------------------------------------------------------------------------- 1 | import { F1 } from './data-source'; 2 | import { paginationOptions } from '../lib/utils'; 3 | 4 | export class CircuitsData extends F1 { 5 | constructor() { 6 | super(); 7 | } 8 | 9 | async getCircuits(pageElements: number = -1, page: number = 1) { 10 | if (pageElements === -1) { 11 | return await this.get('circuits.json?limit=1000', { 12 | cacheOptions: { ttl: 60 } 13 | }); 14 | } 15 | return await this.get(`circuits.json?${paginationOptions(pageElements, page)}`, { 16 | cacheOptions: { ttl: 60 } 17 | }); 18 | } 19 | async getCircuit(id: string) { 20 | return await this.get(`circuits/${ id }.json`, 21 | { cacheOptions: { ttl: 60} } 22 | ); 23 | } 24 | } -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/src/data/data-drivers.ts: -------------------------------------------------------------------------------- 1 | import { F1 } from './data-source'; 2 | import { checkYear, roundCheck, paginationOptions } from '../lib/utils'; 3 | 4 | export class DriversData extends F1 { 5 | constructor() { 6 | super(); 7 | } 8 | 9 | async getDrivers(pageElements: number = -1, page: number = 1) { 10 | if (pageElements === -1) { 11 | return await this.get('drivers.json?limit=1000', { 12 | cacheOptions: { ttl: 60 } 13 | }); 14 | } 15 | return await this.get(`drivers.json?${ paginationOptions(pageElements, page) }`, { 16 | cacheOptions: { ttl: 60 } 17 | }); 18 | 19 | } 20 | 21 | async getDriversByYear(year: string) { 22 | year = checkYear(year); 23 | return await this.get(String(year).concat('/drivers.json'), 24 | { cacheOptions: { ttl: 60} } 25 | ); 26 | } 27 | 28 | async getDriversByYearAndRound(year: string, round: number) { 29 | year = checkYear(year); 30 | round = roundCheck(round) 31 | return await this.get(String(year).concat(`/${round}`).concat('/drivers.json'), 32 | { cacheOptions: { ttl: 60} } 33 | ); 34 | } 35 | 36 | async getDriver(id: string) { 37 | return await this.get(`drivers/${ id }.json`, 38 | { cacheOptions: { ttl: 60} } 39 | ); 40 | } 41 | 42 | async getSeasonsPilotsRanking(year: string) { 43 | year = checkYear(year); 44 | return await this.get(String(year).concat('/driverStandings.json'), 45 | { cacheOptions: { ttl: 60} } 46 | ); 47 | } 48 | } -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/src/data/data-races.ts: -------------------------------------------------------------------------------- 1 | import { F1 } from './data-source'; 2 | import { checkYear, roundCheck } from '../lib/utils'; 3 | 4 | export class RacesData extends F1 { 5 | constructor() { 6 | super(); 7 | } 8 | 9 | async getYear(year: string) { 10 | year = checkYear(year); 11 | return await this.get(`${ year }.json`, { 12 | cacheOptions: { ttl: 60 } 13 | }); 14 | } 15 | 16 | async getYearRound(year: string, round: number) { 17 | year = checkYear(year); 18 | round = roundCheck(round); 19 | return await this.get(`${ year }/${ round }.json`, { 20 | cacheOptions: { ttl: 60 } 21 | }); 22 | } 23 | } -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/src/data/data-seasons.ts: -------------------------------------------------------------------------------- 1 | import { F1 } from './data-source'; 2 | 3 | export class SeasonsData extends F1 { 4 | constructor() { 5 | super(); 6 | } 7 | 8 | async getSeasons() { 9 | return await this.get('seasons.json?limit=80', { 10 | cacheOptions: { ttl: 60 } 11 | }); 12 | } 13 | } -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/src/data/data-source.ts: -------------------------------------------------------------------------------- 1 | import { RESTDataSource } from 'apollo-datasource-rest'; 2 | 3 | export class F1 extends RESTDataSource { 4 | constructor() { 5 | super(); 6 | this.baseURL = 'https://ergast.com/api/f1/'; 7 | } 8 | } -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/src/data/index.ts: -------------------------------------------------------------------------------- 1 | import { SeasonsData } from './data-seasons'; 2 | import { RacesData } from './data-races'; 3 | import { DriversData } from './data-drivers'; 4 | import { CircuitsData } from './data-circuits'; 5 | export const dataSources = { 6 | SeasonsData, 7 | RacesData, 8 | DriversData, 9 | CircuitsData 10 | } -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | export function getWikipediaMobileUrl(url: string) { 2 | return (url !== undefined) ? url.replace('wikipedia', 'm.wikipedia'): '' 3 | } 4 | 5 | export function checkYear(year: string) { 6 | const currentYear = new Date().getFullYear(); 7 | if (isNaN(+year) || +year < 1950 || +year > currentYear) { 8 | return String(currentYear); 9 | } 10 | return year; 11 | } 12 | 13 | export function roundCheck(round: number) { 14 | if (round >= 100) { 15 | return 1; 16 | } 17 | return round; 18 | } 19 | 20 | export function paginationOptions(pageElements: number, page: number) { 21 | const offset = (page - 1) * pageElements; 22 | const limit = pageElements; 23 | return `limit=${ limit }&offset=${ offset }`; 24 | } -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/src/resolvers/query.ts: -------------------------------------------------------------------------------- 1 | import { IResolvers } from "graphql-tools"; 2 | 3 | // Los resolvers de las operaciones de consulta para devolver información 4 | const resolvers: IResolvers = { 5 | Query: { 6 | async seasonsList(_: void, __: any, { dataSources } ) { 7 | return await dataSources.seasons.getSeasons().then( 8 | (data: any) => data.MRData.SeasonTable.Seasons 9 | ); 10 | }, 11 | async racesByYear(_: void, { year }, { dataSources } ) { 12 | return await dataSources.races.getYear(year).then( 13 | (data: any) => data.MRData.RaceTable.Races 14 | ); 15 | }, 16 | async raceSelect(_: void, { year , round }, { dataSources}) { 17 | return await dataSources.races.getYearRound(year, round).then( 18 | (data: any) => data.MRData.RaceTable.Races[0] 19 | ); 20 | }, 21 | async historyDrivers(_: void, { pageElements, page}, { dataSources }) { 22 | return await dataSources.drivers.getDrivers(pageElements, page).then( 23 | (data: any) => data.MRData.DriverTable.Drivers 24 | ); 25 | }, 26 | async driversYear(_: void, { year }, { dataSources} ) { 27 | return await dataSources.drivers.getDriversByYear(year).then( 28 | (data: any) => data.MRData.DriverTable.Drivers 29 | ); 30 | }, 31 | async driversYearAndRound(_: void, { year, round }, { dataSources} ) { 32 | return await dataSources.drivers.getDriversByYearAndRound(year, round).then( 33 | (data: any) => data.MRData.DriverTable.Drivers 34 | ); 35 | }, 36 | async driverSelect(_: void, { id}, { dataSources}) { 37 | return await dataSources.drivers.getDriver(id).then( 38 | (data: any) => data.MRData.DriverTable.Drivers[0] 39 | ) 40 | }, 41 | async seasonPilotsRanking(_: void, { year }, { dataSources}){ 42 | return await dataSources.drivers.getSeasonsPilotsRanking(year).then( 43 | (data: any) => data.MRData.StandingsTable.StandingsLists[0].DriverStandings 44 | ) 45 | }, 46 | async historyCircuits(_: void, { pageElements, page }, { dataSources}){ 47 | return await dataSources.circuits.getCircuits(pageElements, page).then( 48 | (data: any) => data.MRData.CircuitTable.Circuits 49 | ) 50 | }, 51 | async circuitSelect(_: void, { id }, { dataSources }) { 52 | return await dataSources.circuits.getCircuit(id).then( 53 | (data: any) => data.MRData.CircuitTable.Circuits[0] 54 | ) 55 | } 56 | } 57 | }; 58 | 59 | export default resolvers; -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/src/resolvers/resolverMap.ts: -------------------------------------------------------------------------------- 1 | import { IResolvers } from 'graphql-tools'; 2 | import query from './query'; 3 | import type from './type'; 4 | const resolversMap: IResolvers = { 5 | ...query, 6 | ...type 7 | }; 8 | export default resolversMap; -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/src/resolvers/type.ts: -------------------------------------------------------------------------------- 1 | import { IResolvers } from "graphql-tools"; 2 | import { getWikipediaMobileUrl } from "../lib/utils"; 3 | 4 | // Los resolvers de las operaciones de consulta para devolver información 5 | const type: IResolvers = { 6 | Season: { 7 | year: parent => parent.season, 8 | urlMobile: parent => getWikipediaMobileUrl(parent.url) 9 | }, 10 | Race: { 11 | name: parent => parent.raceName, 12 | circuit: parent => parent.Circuit, 13 | urlMobile: parent => getWikipediaMobileUrl(parent.url) 14 | }, 15 | Circuit: { 16 | id: parent => parent.circuitId, 17 | name: parent => parent.circuitName, 18 | location: parent => parent.Location, 19 | urlMobile: parent => getWikipediaMobileUrl(parent.url) 20 | }, 21 | Location: { 22 | lng: parent => parent.long 23 | }, 24 | Driver: { 25 | id: parent => parent.driverId, 26 | name: parent => parent.givenName.concat(' ').concat(parent.familyName), 27 | urlMobile: parent => getWikipediaMobileUrl(parent.url) 28 | }, 29 | DriverStanding: { 30 | driver: parent => parent.Driver, 31 | constructors: parent => parent.Constructors 32 | }, 33 | Constructor: { 34 | id: parent => parent.constructorId, 35 | urlMobile: parent => getWikipediaMobileUrl(parent.url) 36 | } 37 | }; 38 | 39 | export default type; -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/src/schema/schema.graphql: -------------------------------------------------------------------------------- 1 | type Query { 2 | "Lista de las temporadas de Formula 1. De 1950 a 2019 lo seleccionamos" 3 | seasonsList: [Season!]! 4 | """ 5 | Obtenemos la información de las carreras seleccionadas por año. 6 | Tener en cuenta que solo existen las temporadas desde la 1950 a 2019. 7 | En el caso de que introduzcamos un valor que no corresponde a ese 8 | rango de años, se asignará el año actual. Por ejemplo, si nos encontramos 9 | en el año 2019, el año quese asignará será el 2019 en el caso de que no 10 | añadamos el año correctamente 11 | """ 12 | racesByYear(year: String!): [Race!]! 13 | """ 14 | Carrera seleccionada por año y por número de carrera. 15 | Tener en cuenta que solo existen las temporadas desde la 1950 a 2019. 16 | En el caso de que introduzcamos un valor que no corresponde a ese 17 | rango de años, se asignará el año actual. Por ejemplo, si nos encontramos 18 | en el año 2019, el año quese asignará será el 2019 en el caso de que no 19 | añadamos el año correctamente 20 | """ 21 | raceSelect(year: String!, round: Int!): Race 22 | """ 23 | Lista de los pilotos de la F1 de toda la historia. 24 | Tenemos dos opciones: 25 | Obtener todos los pilotos 26 | Obtener los pilotos haciendo uso de la paginación y podemos limitar el número de resultados 27 | Tener en cuenta que solo existen las temporadas desde la 1950 a 2019. 28 | En el caso de que introduzcamos un valor que no corresponde a ese 29 | rango de años, se asignará el año actual. Por ejemplo, si nos encontramos 30 | en el año 2019, el año quese asignará será el 2019 en el caso de que no 31 | añadamos el año correctamente 32 | """ 33 | historyDrivers(pageElements: Int, page: Int): [Driver!]! 34 | """ 35 | Obtenemos la información de los pilotos seleccionados por año. 36 | Tener en cuenta que solo existen las temporadas desde la 1950 a 2019. 37 | En el caso de que introduzcamos un valor que no corresponde a ese 38 | rango de años, se asignará el año actual. Por ejemplo, si nos encontramos 39 | en el año 2019, el año quese asignará será el 2019 en el caso de que no 40 | añadamos el año correctamente 41 | """ 42 | driversYear(year: String!): [Driver!]! 43 | """ 44 | Obtenemos la información de los pilotos seleccionados por año y número de carrera. 45 | Tener en cuenta que solo existen las temporadas desde la 1950 a 2019. 46 | En el caso de que introduzcamos un valor que no corresponde a ese 47 | rango de años, se asignará el año actual. Por ejemplo, si nos encontramos 48 | en el año 2019, el año quese asignará será el 2019 en el caso de que no 49 | añadamos el año correctamente 50 | """ 51 | driversYearAndRound(year: String!, round: Int!): [Driver!]! 52 | """ 53 | Obtenemos la información del piloto mediante el valor 'id' 54 | Este valor lo obtenemos del tipo de objeto 'Driver' en la propiedad 'id' 55 | donde lo pasamos para obtener los detalles de ese piloto seleccionado. 56 | Si introducimos con el 'id' 'alonso', obtendremos la información del piloto 57 | Fernando Alonso 58 | """ 59 | driverSelect(id: String!): Driver 60 | """ 61 | Clasificación final de los pilotos de una temporada. 62 | Tener en cuenta que solo existen las temporadas desde la 1950 a 2019. 63 | En el caso de que introduzcamos un valor que no corresponde a ese 64 | rango de años, se asignará el año actual. Por ejemplo, si nos encontramos 65 | en el año 2019, el año quese asignará será el 2019 en el caso de que no 66 | añadamos el año correctamente 67 | """ 68 | seasonPilotsRanking(year: String!): [DriverStanding!]! 69 | """ 70 | Lista de los circuitos de la F1 de toda la historia. 71 | Tenemos dos opciones: 72 | Obtener todos los circuitos 73 | Obtener los circuitos haciendo uso de la paginación y podemos limitar el número de resultados 74 | """ 75 | historyCircuits(pageElements: Int, page: Int): [Circuit!]!, 76 | "Circuito seleccionado mediante el id del piloto. Si no encuentra nada, nos devuelve null" 77 | circuitSelect(id: String!): Circuit 78 | } 79 | "Información de la temporada" 80 | type Season { 81 | "Año de la temporada" 82 | year: String! 83 | """ 84 | Información de wikipedia. Obtendremos una URL de este estilo: 85 | https://en.wikipedia.org/wiki/1950_Formula_One_season 86 | """ 87 | url: String! 88 | """ 89 | Información de wikipedia adaptada a los dispositivos móviles. 90 | Obtendremos una URL de este estilo: 91 | https://en.m.wikipedia.org/wiki/1950_Formula_One_season 92 | """ 93 | urlMobile: String! 94 | } 95 | "Información de la carrera" 96 | type Race { 97 | "Temporada de esa carrera" 98 | season: String! 99 | "Número de carrera" 100 | round: String! 101 | """ 102 | Información de wikipedia. Obtendremos una URL de este estilo: 103 | https://en.wikipedia.org/wiki/2012_Australian_Grand_Prix 104 | """ 105 | url: String! 106 | """ 107 | Información de wikipedia adaptada a los dispositivos móviles. 108 | Obtendremos una URL de este estilo: 109 | https://en.m.wikipedia.org/wiki/2012_Australian_Grand_Prix 110 | """ 111 | urlMobile: String! 112 | """ 113 | Nombre del Gran Premio al que corresponde esa carrera. 114 | Por ejemplo: Gran Premio Australiano 115 | """ 116 | name: String! 117 | """ 118 | Información del circuito con sus propiedades 119 | * Nombre 120 | * Url del circuito 121 | * Localización 122 | * ... 123 | """ 124 | circuit: Circuit! 125 | "Fecha en la que se celebra este gran Premio" 126 | date: String! 127 | "Hora en la que se celebra" 128 | time: String 129 | } 130 | "Información correspondiente al circuito" 131 | type Circuit { 132 | """ 133 | Identificador único del circuito que usaremos para cuando queramos obtener la 134 | información de un circuito mediante la API 135 | """ 136 | id: String! 137 | """ 138 | Información de wikipedia. Obtendremos una URL de este estilo: 139 | https://en.wikipedia.org/wiki/1950_Formula_One_season 140 | """ 141 | url: String! 142 | """ 143 | Información de wikipedia adaptada a los dispositivos móviles. 144 | Obtendremos una URL de este estilo: 145 | https://en.m.wikipedia.org/wiki/1950_Formula_One_season 146 | """ 147 | urlMobile: String! 148 | "Nombre del circuito" 149 | name: String! 150 | """ 151 | Localización del circuito con estas propiedades: 152 | * Coordenadas geográficas : latitud / longitud 153 | * Localidad 154 | * País 155 | """ 156 | location: Location! 157 | } 158 | "Localización del circuito" 159 | type Location { 160 | "Coordenada geográfica - latitud" 161 | lat: String! 162 | "Coordenada geográfica - longitud" 163 | lng: String! 164 | "Nombre de la localización" 165 | locality: String! 166 | "País de la localización" 167 | country: String! 168 | } 169 | "Información del piloto que participa en carreras de F1" 170 | type Driver { 171 | """ 172 | Identificador único del piloto que usaremos para cuando queramos obtener la 173 | información de un piloto mediante la API 174 | """ 175 | id: String! 176 | """ 177 | Información de wikipedia. Obtendremos una URL de este estilo: 178 | https://en.wikipedia.org/wiki/1950_Formula_One_season 179 | """ 180 | url: String! 181 | """ 182 | Información de wikipedia adaptada a los dispositivos móviles. 183 | Obtendremos una URL de este estilo: 184 | https://en.m.wikipedia.org/wiki/1950_Formula_One_season 185 | """ 186 | urlMobile: String! 187 | "Nombre y apellidos del piloto" 188 | name: String! 189 | "Fecha de nacimiento del piloto" 190 | dateOfBirth: String! 191 | "Nacionalidad del piloto" 192 | nationality: String! 193 | "Código único del piloto" 194 | code: String 195 | """ 196 | Número permanente del piloto. Normalmente no está 197 | este valor asignado a muchos pilotos 198 | """ 199 | permanentNumber: String 200 | } 201 | 202 | "Estadísticas de los pilotos en las carreras / temporadas" 203 | type DriverStanding { 204 | "Posición que ocupa" 205 | position: String! 206 | "Posición que ocupa" 207 | positionText: String! 208 | "Puntos acumulados en la carrera / temporada" 209 | points: String! 210 | "Victorias conseguidas en carreras" 211 | wins: String! 212 | "Información del piloto" 213 | driver: Driver! 214 | "Equipo al que pertenece el piloto" 215 | constructors: [Constructor!]! 216 | } 217 | 218 | "Información del equipo de Formula 1" 219 | type Constructor { 220 | """ 221 | Identificador único del constructor que usaremos para cuando queramos obtener la 222 | información de un constructor mediante la API 223 | """ 224 | id: String! 225 | """ 226 | Información de wikipedia. Obtendremos una URL de este estilo: 227 | https://en.wikipedia.org/wiki/1950_Formula_One_season 228 | """ 229 | url: String! 230 | """ 231 | Información de wikipedia adaptada a los dispositivos móviles. 232 | Obtendremos una URL de este estilo: 233 | https://en.m.wikipedia.org/wiki/1950_Formula_One_season 234 | """ 235 | urlMobile: String! 236 | "Nombre del equipo" 237 | name: String! 238 | "Nacionalidad del equipo" 239 | nationality: String! 240 | } -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/src/schema/schema.ts: -------------------------------------------------------------------------------- 1 | import 'graphql-import-node'; 2 | import typeDefs from './schema.graphql'; 3 | import { makeExecutableSchema } from 'graphql-tools'; 4 | import { GraphQLSchema } from 'graphql'; 5 | import resolvers from '../resolvers/resolverMap'; 6 | 7 | const schema: GraphQLSchema = makeExecutableSchema({ 8 | typeDefs, 9 | resolvers 10 | }); 11 | 12 | export default schema; -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/src/server.ts: -------------------------------------------------------------------------------- 1 | // Añadir los imports 2 | import express from 'express'; 3 | import compression from 'compression'; 4 | import cors from 'cors'; 5 | import schema from './schema/schema'; 6 | import { ApolloServer } from 'apollo-server-express'; 7 | import { createServer } from 'http'; 8 | import { dataSources } from './data'; 9 | import expressPlayground from 'graphql-playground-middleware-express'; 10 | // Inicializamos la aplicación express 11 | 12 | const app = express(); 13 | 14 | // Añadimos configuración de Cors y compression 15 | app.use('*', cors()); 16 | 17 | app.use(compression()); 18 | 19 | // Inicializamos el servidor de Apollo 20 | const server = new ApolloServer({ 21 | schema: schema, 22 | introspection: true, // Necesario 23 | dataSources: () => ({ 24 | seasons: new dataSources.SeasonsData(), 25 | races: new dataSources.RacesData(), 26 | drivers: new dataSources.DriversData(), 27 | circuits: new dataSources.CircuitsData() 28 | }) 29 | }); 30 | 31 | server.applyMiddleware({ app }); 32 | 33 | app.use('/', expressPlayground ({ 34 | endpoint: '/graphql' 35 | } 36 | )); 37 | const PORT = process.env.PORT || 5000; 38 | 39 | const httpServer = createServer(app); 40 | 41 | httpServer.listen({ port: PORT }, () : void => console.log(`http://localhost:${ PORT }/graphql`)); 42 | -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ 5 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 6 | "lib": ["dom","es6"], /* Specify library files to be included in the compilation. */ 7 | // "allowJs": true, /* Allow javascript files to be compiled. */ 8 | // "checkJs": true, /* Report errors in .js files. */ 9 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 10 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 11 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 12 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 13 | // "outFile": "./", /* Concatenate and emit output to single file. */ 14 | "outDir": "build", /* Redirect output structure to the directory. */ 15 | "rootDir": "src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 16 | // "composite": true, /* Enable project compilation */ 17 | // "incremental": true, /* Enable incremental compilation */ 18 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 19 | "removeComments": true, /* Do not emit comments to output. */ 20 | // "noEmit": true, /* Do not emit outputs. */ 21 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 22 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 23 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 24 | 25 | /* Strict Type-Checking Options */ 26 | "strict": true, /* Enable all strict type-checking options. */ 27 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 28 | // "strictNullChecks": true, /* Enable strict null checks. */ 29 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 30 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 31 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 32 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 33 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 34 | 35 | /* Additional Checks */ 36 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 37 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 38 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 39 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 40 | 41 | /* Module Resolution Options */ 42 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 43 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 44 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 45 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 46 | // "typeRoots": [], /* List of folders to include type definitions from. */ 47 | // "types": [], /* Type declaration files to be included in compilation. */ 48 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 49 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 50 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 51 | 52 | /* Source Map Options */ 53 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 54 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 55 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 56 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 57 | 58 | /* Experimental Options */ 59 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 60 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /templates/graphql-from-rest-apollo-rest/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "quotemark": [true, "single"], 4 | "semicolon": true, 5 | "curly":true, 6 | "no-empty-interface": true 7 | } 8 | } -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | # package-lock.json 64 | 65 | package-lock.json 66 | -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "vetur.format.defaultFormatterOptions": { 4 | "prettier": { 5 | "singleQuote": true 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/README.md: -------------------------------------------------------------------------------- 1 | # <%= projectName %> 2 | 3 | Introduce el contenido de tu README -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= projectName %>", 3 | "version": "1.0.0", 4 | "description": "Hola Mundo con MongoDB en GraphQL", 5 | "main": "build/server.js", 6 | "scripts": { 7 | "start": "node build/server.js", 8 | "build": "tsc -p . && ncp src/schema build/schema", 9 | "start:dev": "npm run build:dev", 10 | "build:dev": "nodemon \"src/server.ts\" --exec \"ts-node\" src/server.ts -e ts,graphql,json" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/<%= githubUser %>/<%= projectName %>.git" 15 | }, 16 | "keywords": [ 17 | "graphql", 18 | "graphql-curso", 19 | "hello-world", 20 | "mongodb" 21 | ], 22 | "author": "<%= authorNameLastname %> <<%= emailValue %>>", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/<%= githubUser %>/<%= projectName %>/issues" 26 | }, 27 | "homepage": "https://github.com/<%= githubUser %>/<%= projectName %>#readme", 28 | "dependencies": { 29 | "apollo-server-express": "^2.6.7", 30 | "chalk": "^2.4.2", 31 | "compression": "^1.7.4", 32 | "cors": "^2.8.5", 33 | "dotenv": "^8.0.0", 34 | "express": "^4.17.1", 35 | "graphql": "^14.3.1", 36 | "graphql-import-node": "0.0.4", 37 | "graphql-playground-middleware-express": "^1.7.12", 38 | "graphql-tools": "^4.0.5", 39 | "http": "0.0.0", 40 | "mongodb": "^3.2.7", 41 | "ncp": "^2.0.0", 42 | "typescript": "^3.5.2" 43 | }, 44 | "devDependencies": { 45 | "@types/compression": "0.0.36", 46 | "@types/cors": "^2.8.5", 47 | "@types/dotenv": "^6.1.1", 48 | "@types/express": "^4.17.0", 49 | "@types/express-graphql": "^0.8.0", 50 | "@types/mongodb": "^3.1.28", 51 | "@types/node": "^12.0.10", 52 | "nodemon":"^2.0.1", 53 | "ts-node": "^8.5.4", 54 | "typescript-tslint-plugin": "0.5.5" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/src/.env: -------------------------------------------------------------------------------- 1 | PORT=5002 2 | DATABASE=mongodb://localhost:27017/ -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/src/.env_example: -------------------------------------------------------------------------------- 1 | PORT=8000 2 | DATABASE="mongodb://localhost:27017/hello-world-db" -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/src/config/constants.ts: -------------------------------------------------------------------------------- 1 | import environments from './environments'; 2 | 3 | if (process.env.NODE_ENV !== 'production') { 4 | const environment = environments; 5 | } 6 | 7 | // Añade tus constantes aquí, si hace falta cogiendo de las variables de entorno -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/src/config/database.ts: -------------------------------------------------------------------------------- 1 | import MongoClient from 'mongodb'; 2 | import chalk from 'chalk'; 3 | class Database { 4 | 5 | async init() { 6 | const MONGODB = String(process.env.DATABASE); 7 | const client = await MongoClient.connect(MONGODB, { useNewUrlParser: true, useUnifiedTopology: true}); 8 | 9 | const db = await client.db(); 10 | 11 | if ( client.isConnected() ) { 12 | console.log('==========DATABASE=========='); 13 | console.log(`STATUS: ${chalk.greenBright('ONLINE')}`); 14 | console.log(`DATABASE: ${chalk.greenBright(db.databaseName)}`); 15 | } 16 | 17 | return db; 18 | } 19 | } 20 | 21 | export default Database; -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/src/config/environments.ts: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv'; 2 | const environments = dotenv.config({ path: './src/.env'}); 3 | if (process.env.NODE_ENV !== 'production') { 4 | if (environments.error) { 5 | throw environments.error; 6 | } 7 | } 8 | export default environments; -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/src/lib/datetime.ts: -------------------------------------------------------------------------------- 1 | export class Datetime { 2 | 3 | getCurrentDateTime(dateSeparateSymbol: string = '-') { 4 | const dateTime = new Date(); 5 | let dateDay: string = this.formatWithTwoDigits(String(dateTime.getDate())); 6 | let month: string = this.formatWithTwoDigits(String(dateTime.getMonth() + 1)); 7 | 8 | let hour : string = this.formatWithTwoDigits(String(dateTime.getHours())); 9 | let minutes : string = this.formatWithTwoDigits(String(dateTime.getMinutes())); 10 | let seconds : string = this.formatWithTwoDigits(String(dateTime.getSeconds())); 11 | 12 | return `${dateTime.getFullYear()}${dateSeparateSymbol}${month}${dateSeparateSymbol}${dateDay} ${hour}:${minutes}:${seconds}`; 13 | } 14 | 15 | private formatWithTwoDigits(value: number | string) { 16 | if (+value < 10) { 17 | return `0${value}`; 18 | } 19 | return String(value); 20 | } 21 | 22 | /** 23 | * Add specific days count to select date or now date 24 | * @param days add days in select date 25 | * @param customDate Specify date if use select date 26 | */ 27 | addDays(days: number, date: string, customDate: string = '', ) { 28 | let date_ = new Date(date); 29 | if (customDate !== '') { 30 | date_ = new Date(customDate); 31 | } 32 | date_.setDate(date_.getDate() + days); 33 | return date; 34 | } 35 | 36 | 37 | } -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/src/resolvers/mutation.ts: -------------------------------------------------------------------------------- 1 | import { IResolvers } from 'graphql-tools'; 2 | 3 | // Los resolvers de las operaciones de modificación de información 4 | const mutation: IResolvers = { 5 | /*Mutation: { 6 | 7 | }*/ 8 | }; 9 | 10 | export default mutation; -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/src/resolvers/query.ts: -------------------------------------------------------------------------------- 1 | import { IResolvers } from 'graphql-tools'; 2 | 3 | const query: IResolvers = { 4 | Query: { 5 | hello(): string { 6 | return 'Hello world!!'; 7 | }, 8 | helloWithName(_: void, args: any): string { 9 | return `Hello ${args.name}!!`; 10 | }, 11 | helloToGraphQLCourse(): string { 12 | return 'Hello to GraphQL Course!!'; 13 | } 14 | } 15 | }; 16 | 17 | export default query; -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/src/resolvers/resolversMap.ts: -------------------------------------------------------------------------------- 1 | import { IResolvers } from 'graphql-tools'; 2 | import mutation from './mutation'; 3 | import query from './query'; 4 | 5 | export const LIST: string [] = [ ]; 6 | const resolvers : IResolvers = { 7 | ...query, 8 | ...mutation 9 | }; 10 | 11 | export default resolvers; -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/src/schema/index.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLSchema } from 'graphql'; 2 | import 'graphql-import-node'; 3 | import typeDefs from './schema.graphql'; 4 | import resolvers from './../resolvers/resolversMap'; 5 | import { makeExecutableSchema } from 'graphql-tools'; 6 | 7 | const schema: GraphQLSchema = makeExecutableSchema({ 8 | typeDefs, 9 | resolvers 10 | }); 11 | 12 | export default schema; -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/src/schema/schema.graphql: -------------------------------------------------------------------------------- 1 | type Query { 2 | hello: String! 3 | helloWithName(name: String!): String! 4 | helloToGraphQLCourse: String! 5 | list: [String] 6 | } -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/src/server.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import compression from 'compression'; 3 | import cors from 'cors'; 4 | import schema from './schema'; 5 | import { ApolloServer } from 'apollo-server-express'; 6 | import { createServer } from 'http'; 7 | import environments from './config/environments'; 8 | import Database from './config/database'; 9 | import expressPlayGround from 'graphql-playground-middleware-express'; 10 | if (process.env.NODE_ENV !== 'production') { 11 | const envs = environments; 12 | console.log(envs); 13 | } 14 | 15 | async function init() { 16 | const app = express(); 17 | 18 | app.use(cors()); 19 | 20 | app.use(compression()); 21 | 22 | const database = new Database(); 23 | const db = await database.init(); 24 | 25 | const context: any = async() => { 26 | return { db }; 27 | }; 28 | 29 | const server = new ApolloServer({ 30 | schema, 31 | context, 32 | introspection: true 33 | }); 34 | 35 | server.applyMiddleware({ app }); 36 | 37 | app.use('/', expressPlayGround({ 38 | endpoint: '/graphql' 39 | })); 40 | 41 | const PORT = process.env.PORT || 5300; 42 | const httpServer = createServer(app); 43 | httpServer.listen( 44 | { port: PORT }, 45 | () => console.log(`Hola Mundo API GraphQL http://localhost:${PORT}/graphql`) 46 | ); 47 | } 48 | 49 | init(); -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "plugins": [{ 5 | "name":"typescript-tslint-plugin" 6 | }], 7 | // "incremental": true, /* Enable incremental compilation */ 8 | "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ 9 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 10 | "lib": ["dom","es6"], /* Specify library files to be included in the compilation. */ 11 | // "allowJs": true, /* Allow javascript files to be compiled. */ 12 | // "checkJs": true, /* Report errors in .js files. */ 13 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 14 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 15 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 16 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 17 | // "outFile": "./", /* Concatenate and emit output to single file. */ 18 | "outDir": "build", /* Redirect output structure to the directory. */ 19 | "rootDir": "src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 20 | // "composite": true, /* Enable project compilation */ 21 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 22 | "removeComments": true, /* Do not emit comments to output. */ 23 | // "noEmit": true, /* Do not emit outputs. */ 24 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 25 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 26 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 27 | 28 | /* Strict Type-Checking Options */ 29 | "strict": true, /* Enable all strict type-checking options. */ 30 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 31 | // "strictNullChecks": true, /* Enable strict null checks. */ 32 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 33 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 34 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 35 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 36 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 37 | 38 | /* Additional Checks */ 39 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 40 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 41 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 42 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 43 | 44 | /* Module Resolution Options */ 45 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 46 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 47 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 48 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 49 | // "typeRoots": [], /* List of folders to include type definitions from. */ 50 | // "types": [], /* Type declaration files to be included in compilation. */ 51 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 52 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 53 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 54 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 55 | 56 | /* Source Map Options */ 57 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 58 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 59 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 60 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 61 | 62 | /* Experimental Options */ 63 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 64 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /templates/graphql-hello-world-db/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "quotemark": [true, "single"], 4 | "semicolon": true, 5 | "curly":true, 6 | "no-empty-interface": true 7 | } 8 | } -------------------------------------------------------------------------------- /templates/graphql-hello-world-with-env/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | !src/.env 3 | logs 4 | *.log 5 | npm-debug.log* 6 | yarn-debug.log* 7 | yarn-error.log* 8 | 9 | # Runtime data 10 | pids 11 | *.pid 12 | *.seed 13 | *.pid.lock 14 | 15 | # Directory for instrumented libs generated by jscoverage/JSCover 16 | lib-cov 17 | 18 | # Coverage directory used by tools like istanbul 19 | coverage 20 | 21 | # nyc test coverage 22 | .nyc_output 23 | 24 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 25 | .grunt 26 | 27 | # Bower dependency directory (https://bower.io/) 28 | bower_components 29 | 30 | # node-waf configuration 31 | .lock-wscript 32 | 33 | # Compiled binary addons (https://nodejs.org/api/addons.html) 34 | build/Release 35 | 36 | # Dependency directories 37 | node_modules/ 38 | jspm_packages/ 39 | 40 | # TypeScript v1 declaration files 41 | typings/ 42 | 43 | # Optional npm cache directory 44 | .npm 45 | 46 | # Optional eslint cache 47 | .eslintcache 48 | 49 | # Optional REPL history 50 | .node_repl_history 51 | 52 | # Output of 'npm pack' 53 | *.tgz 54 | 55 | # Yarn Integrity file 56 | .yarn-integrity 57 | 58 | # dotenv environment variables file 59 | 60 | # next.js build output 61 | .next 62 | 63 | # package-lock.json 64 | 65 | package-lock.json 66 | -------------------------------------------------------------------------------- /templates/graphql-hello-world-with-env/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "vetur.format.defaultFormatterOptions": { 4 | "prettier": { 5 | "singleQuote": true 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /templates/graphql-hello-world-with-env/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 graphql-course 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /templates/graphql-hello-world-with-env/README.md: -------------------------------------------------------------------------------- 1 | # <%= projectName %> 2 | 3 | Introduce el contenido de tu README -------------------------------------------------------------------------------- /templates/graphql-hello-world-with-env/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= projectName %>", 3 | "version": "1.0.0", 4 | "description": "Hello world in GraphQL for first steps", 5 | "main": "build/server.js", 6 | "scripts": { 7 | "start": "node build/server.js", 8 | "build": "tsc -p . && ncp src/schema build/schema", 9 | "start:dev": "npm run build:dev", 10 | "build:dev": "nodemon \"src/server.ts\" --exec \"ts-node\" src/server.ts -e ts,graphql,json" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/<%= githubUser %>/<%= projectName %>.git" 15 | }, 16 | "keywords": [], 17 | "author": "<%= authorNameLastname %> <<%= emailValue %>>", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/<%= githubUser %>/<%= projectName %>/issues" 21 | }, 22 | "homepage": "https://github.com/<%= githubUser %>/<%= projectName %>#readme", 23 | "dependencies": { 24 | "apollo-server-express": "^2.6.1", 25 | "compression": "^1.7.4", 26 | "cors": "^2.8.5", 27 | "dotenv": "^8.0.0", 28 | "express": "^4.17.1", 29 | "graphql": "^14.3.1", 30 | "graphql-import": "^0.7.1", 31 | "graphql-import-node": "0.0.4", 32 | "graphql-playground-middleware-express": "^1.7.12", 33 | "graphql-tools": "^4.0.4", 34 | "http": "0.0.0", 35 | "ncp": "^2.0.0", 36 | "typescript": "^3.5.1" 37 | }, 38 | "devDependencies": { 39 | "@types/compression": "0.0.36", 40 | "@types/cors": "^2.8.5", 41 | "@types/dotenv": "^6.1.1", 42 | "@types/express": "^4.16.1", 43 | "@types/node": "^12.0.4", 44 | "nodemon":"^2.0.1", 45 | "ts-node": "^8.5.4", 46 | "typescript-tslint-plugin": "0.5.5" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /templates/graphql-hello-world-with-env/src/.env: -------------------------------------------------------------------------------- 1 | PORT=5000 -------------------------------------------------------------------------------- /templates/graphql-hello-world-with-env/src/.env_example: -------------------------------------------------------------------------------- 1 | PORT=8000 -------------------------------------------------------------------------------- /templates/graphql-hello-world-with-env/src/config/environments.ts: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv'; 2 | // Configurar las variables de entorno: https://github.com/motdotla/dotenv 3 | 4 | const environments = dotenv.config({ path: './src/.env' }); 5 | 6 | if (process.env.NODE_ENV !== 'production') { 7 | if (environments.error) { 8 | throw environments.error; 9 | } 10 | } 11 | 12 | export default environments; -------------------------------------------------------------------------------- /templates/graphql-hello-world-with-env/src/resolvers/mutation.ts: -------------------------------------------------------------------------------- 1 | import { IResolvers } from 'graphql-tools'; 2 | 3 | // Los resolvers de las operaciones de modificación de información 4 | const mutation: IResolvers = { 5 | /*Mutation: { 6 | 7 | }*/ 8 | }; 9 | 10 | export default mutation; -------------------------------------------------------------------------------- /templates/graphql-hello-world-with-env/src/resolvers/query.ts: -------------------------------------------------------------------------------- 1 | import { IResolvers } from 'graphql-tools'; 2 | 3 | // Los resolvers de las operaciones de consulta para devolver información 4 | const resolvers: IResolvers = { 5 | Query: { 6 | hello(): string { 7 | return 'Hello world!!'; 8 | }, 9 | helloWithName(_: void, args: any): string { 10 | return `Hello ${args.name}!!`; 11 | }, 12 | helloToGraphQLCourse (): string { 13 | return 'Hello to GraphQL Course!!'; 14 | } 15 | } 16 | }; 17 | 18 | export default resolvers; -------------------------------------------------------------------------------- /templates/graphql-hello-world-with-env/src/resolvers/resolverMap.ts: -------------------------------------------------------------------------------- 1 | import { IResolvers } from 'graphql-tools'; 2 | import mutation from './mutation'; 3 | import query from './query'; 4 | 5 | export const LIST: string [] = [ ]; 6 | const resolvers : IResolvers = { 7 | ...query, 8 | ...mutation 9 | }; 10 | 11 | export default resolvers; -------------------------------------------------------------------------------- /templates/graphql-hello-world-with-env/src/schema/schema.graphql: -------------------------------------------------------------------------------- 1 | type Query { 2 | hello: String! 3 | helloWithName(name: String!): String! 4 | helloToGraphQLCourse: String! 5 | } 6 | -------------------------------------------------------------------------------- /templates/graphql-hello-world-with-env/src/schema/schema.ts: -------------------------------------------------------------------------------- 1 | import 'graphql-import-node'; 2 | import typeDefs from './schema.graphql'; 3 | import { makeExecutableSchema } from 'graphql-tools'; 4 | import { GraphQLSchema } from 'graphql'; 5 | import resolvers from '../resolvers/resolverMap'; 6 | 7 | const schema: GraphQLSchema = makeExecutableSchema({ 8 | typeDefs, 9 | resolvers 10 | }); 11 | 12 | export default schema; -------------------------------------------------------------------------------- /templates/graphql-hello-world-with-env/src/server.ts: -------------------------------------------------------------------------------- 1 | // Añadir los imports 2 | import express from 'express'; 3 | import compression from 'compression'; 4 | import cors from 'cors'; 5 | import schema from './schema/schema'; 6 | import { ApolloServer } from 'apollo-server-express'; 7 | import { createServer } from 'http'; 8 | import environments from './config/environments'; 9 | import expressPlayGround from 'graphql-playground-middleware-express'; 10 | 11 | async function init() { 12 | // Inicializar variables de entorno 13 | if (process.env.NODE_ENV !== 'production') { 14 | const envs = environments; 15 | console.log(envs); 16 | } 17 | 18 | // Inicializamos la aplicación express 19 | 20 | const app = express(); 21 | 22 | // Añadimos configuración de Cors y compression 23 | app.use(cors()); 24 | 25 | app.use(compression()); 26 | 27 | // Inicializamos el servidor de Apollo 28 | const server = new ApolloServer({ 29 | schema: schema, 30 | introspection: true // Necesario 31 | }); 32 | 33 | server.applyMiddleware({ app }); 34 | 35 | app.use('/', expressPlayGround({ 36 | endpoint: '/graphql' 37 | })); 38 | 39 | const PORT = process.env.PORT || 5000; 40 | const httpServer = createServer(app); 41 | 42 | httpServer.listen({ port: PORT }, (): void => console.log(`http://localhost:${PORT}/graphql`)); 43 | } 44 | 45 | init(); 46 | -------------------------------------------------------------------------------- /templates/graphql-hello-world-with-env/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "plugins": [{ 5 | "name":"typescript-tslint-plugin" 6 | }], 7 | "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ 8 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 9 | "lib": ["dom","es6"], /* Specify library files to be included in the compilation. */ 10 | // "allowJs": true, /* Allow javascript files to be compiled. */ 11 | // "checkJs": true, /* Report errors in .js files. */ 12 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 13 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 14 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 15 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 16 | // "outFile": "./", /* Concatenate and emit output to single file. */ 17 | "outDir": "build", /* Redirect output structure to the directory. */ 18 | "rootDir": "src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 19 | // "composite": true, /* Enable project compilation */ 20 | // "incremental": true, /* Enable incremental compilation */ 21 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 22 | "removeComments": true, /* Do not emit comments to output. */ 23 | // "noEmit": true, /* Do not emit outputs. */ 24 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 25 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 26 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 27 | 28 | /* Strict Type-Checking Options */ 29 | "strict": true, /* Enable all strict type-checking options. */ 30 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 31 | // "strictNullChecks": true, /* Enable strict null checks. */ 32 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 33 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 34 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 35 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 36 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 37 | 38 | /* Additional Checks */ 39 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 40 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 41 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 42 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 43 | 44 | /* Module Resolution Options */ 45 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 46 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 47 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 48 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 49 | // "typeRoots": [], /* List of folders to include type definitions from. */ 50 | // "types": [], /* Type declaration files to be included in compilation. */ 51 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 52 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 53 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 54 | 55 | /* Source Map Options */ 56 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 57 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 58 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 59 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 60 | 61 | /* Experimental Options */ 62 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 63 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /templates/graphql-hello-world-with-env/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "quotemark": [true, "single"], 4 | "semicolon": true, 5 | "curly":true, 6 | "no-empty-interface": true 7 | } 8 | } -------------------------------------------------------------------------------- /templates/graphql-hello-world/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | 63 | # package-lock.json 64 | 65 | package-lock.json 66 | -------------------------------------------------------------------------------- /templates/graphql-hello-world/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "vetur.format.defaultFormatterOptions": { 4 | "prettier": { 5 | "singleQuote": true 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /templates/graphql-hello-world/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 graphql-course 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /templates/graphql-hello-world/README.md: -------------------------------------------------------------------------------- 1 | # <%= projectName %> 2 | 3 | Introduce el contenido de tu README -------------------------------------------------------------------------------- /templates/graphql-hello-world/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= projectName %>", 3 | "version": "1.0.0", 4 | "description": "Hello world in GraphQL for first steps", 5 | "main": "build/server.js", 6 | "scripts": { 7 | "start": "node build/server.js", 8 | "build": "tsc -p . && ncp src/schema build/schema", 9 | "start:dev": "npm run build:dev", 10 | "build:dev": "nodemon \"src/server.ts\" --exec \"ts-node\" src/server.ts -e ts,graphql,json" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/<%= githubUser %>/<%= projectName %>.git" 15 | }, 16 | "keywords": [], 17 | "author": "<%= authorNameLastname %> <<%= emailValue %>>", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/<%= githubUser %>/<%= projectName %>/issues" 21 | }, 22 | "homepage": "https://github.com/<%= githubUser %>/<%= projectName %>#readme", 23 | "dependencies": { 24 | "apollo-server-express": "^2.6.1", 25 | "compression": "^1.7.4", 26 | "cors": "^2.8.5", 27 | "dotenv": "^8.0.0", 28 | "express": "^4.17.1", 29 | "graphql": "^14.3.1", 30 | "graphql-import": "^0.7.1", 31 | "graphql-import-node": "0.0.4", 32 | "graphql-playground-middleware-express": "^1.7.12", 33 | "graphql-tools": "^4.0.4", 34 | "http": "0.0.0", 35 | "ncp": "^2.0.0", 36 | "typescript": "^3.5.1" 37 | }, 38 | "devDependencies": { 39 | "@types/compression": "0.0.36", 40 | "@types/cors": "^2.8.5", 41 | "@types/dotenv": "^6.1.1", 42 | "@types/express": "^4.16.1", 43 | "@types/node": "^12.0.4", 44 | "nodemon":"^2.0.1", 45 | "ts-node": "^8.5.4", 46 | "typescript-tslint-plugin": "0.5.5" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /templates/graphql-hello-world/src/resolvers/mutation.ts: -------------------------------------------------------------------------------- 1 | import { IResolvers } from 'graphql-tools'; 2 | 3 | // Los resolvers de las operaciones de modificación de información 4 | const mutation: IResolvers = { 5 | /*Mutation: { 6 | 7 | }*/ 8 | }; 9 | 10 | export default mutation; -------------------------------------------------------------------------------- /templates/graphql-hello-world/src/resolvers/query.ts: -------------------------------------------------------------------------------- 1 | import { IResolvers } from 'graphql-tools'; 2 | 3 | const query: IResolvers = { 4 | Query: { 5 | hello(): string { 6 | return 'Hello world!!'; 7 | }, 8 | helloWithName(_: void, args): string { 9 | return `Hello ${args.name}!!`; 10 | }, 11 | helloToGraphQLCourse(): string { 12 | return 'Hello to GraphQL Course!!'; 13 | } 14 | } 15 | }; 16 | 17 | export default query; -------------------------------------------------------------------------------- /templates/graphql-hello-world/src/resolvers/resolversMap.ts: -------------------------------------------------------------------------------- 1 | import { IResolvers } from 'graphql-tools'; 2 | import mutation from './mutation'; 3 | import query from './query'; 4 | 5 | export const LIST: string [] = [ ]; 6 | const resolvers : IResolvers = { 7 | ...query, 8 | ...mutation 9 | }; 10 | 11 | export default resolvers; -------------------------------------------------------------------------------- /templates/graphql-hello-world/src/schema/index.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLSchema } from 'graphql'; 2 | import 'graphql-import-node'; 3 | import typeDefs from './schema.graphql'; 4 | import resolvers from './../resolvers/resolversMap'; 5 | import { makeExecutableSchema } from 'graphql-tools'; 6 | 7 | const schema: GraphQLSchema = makeExecutableSchema({ 8 | typeDefs, 9 | resolvers 10 | }); 11 | 12 | export default schema; -------------------------------------------------------------------------------- /templates/graphql-hello-world/src/schema/schema.graphql: -------------------------------------------------------------------------------- 1 | type Query { 2 | hello: String! 3 | helloWithName(name: String!): String! 4 | helloToGraphQLCourse: String! 5 | list: [String] 6 | } 7 | 8 | type Mutation { 9 | add(value: String!): [String] 10 | } -------------------------------------------------------------------------------- /templates/graphql-hello-world/src/server.ts: -------------------------------------------------------------------------------- 1 | // Añadir los imports 2 | import express from 'express'; 3 | import compression from 'compression'; 4 | import cors from 'cors'; 5 | import schema from './schema'; 6 | import { ApolloServer } from 'apollo-server-express'; 7 | import { createServer } from 'http'; 8 | import expressPlayGround from 'graphql-playground-middleware-express'; 9 | 10 | async function init() { 11 | // Inicializamos la aplicación express 12 | const app = express(); 13 | 14 | // Añadimos configuración de Cors y compression 15 | app.use(cors()); 16 | 17 | app.use(compression()); 18 | 19 | // Inicializamos el servidor de Apollo 20 | const server = new ApolloServer({ 21 | schema, 22 | introspection: true // Necesario 23 | }); 24 | 25 | server.applyMiddleware({ app }); 26 | 27 | app.use('/', expressPlayGround({ 28 | endpoint: '/graphql' 29 | })); 30 | 31 | const PORT = process.env.PORT || 5000; 32 | 33 | const httpServer = createServer(app); 34 | 35 | httpServer.listen({ port: PORT }, (): void => console.log(`http://localhost:${PORT}/graphql`)); 36 | } 37 | 38 | init(); 39 | -------------------------------------------------------------------------------- /templates/graphql-hello-world/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "plugins": [{ 5 | "name":"typescript-tslint-plugin" 6 | }], 7 | "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ 8 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 9 | "lib": ["dom","es6"], /* Specify library files to be included in the compilation. */ 10 | // "allowJs": true, /* Allow javascript files to be compiled. */ 11 | // "checkJs": true, /* Report errors in .js files. */ 12 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 13 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 14 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 15 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 16 | // "outFile": "./", /* Concatenate and emit output to single file. */ 17 | "outDir": "build", /* Redirect output structure to the directory. */ 18 | "rootDir": "src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 19 | // "composite": true, /* Enable project compilation */ 20 | // "incremental": true, /* Enable incremental compilation */ 21 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 22 | "removeComments": true, /* Do not emit comments to output. */ 23 | // "noEmit": true, /* Do not emit outputs. */ 24 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 25 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 26 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 27 | 28 | /* Strict Type-Checking Options */ 29 | "strict": true, /* Enable all strict type-checking options. */ 30 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 31 | // "strictNullChecks": true, /* Enable strict null checks. */ 32 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 33 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 34 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 35 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 36 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 37 | 38 | /* Additional Checks */ 39 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 40 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 41 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 42 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 43 | 44 | /* Module Resolution Options */ 45 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 46 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 47 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 48 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 49 | // "typeRoots": [], /* List of folders to include type definitions from. */ 50 | // "types": [], /* Type declaration files to be included in compilation. */ 51 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 52 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 53 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 54 | 55 | /* Source Map Options */ 56 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 57 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 58 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 59 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 60 | 61 | /* Experimental Options */ 62 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 63 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /templates/graphql-hello-world/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "quotemark": [true, "single"], 4 | "semicolon": true, 5 | "curly":true, 6 | "no-empty-interface": true 7 | } 8 | } -------------------------------------------------------------------------------- /templates/graphql-jwt-system/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | # Logs 3 | logs 4 | *.log 5 | npm-debug.log* 6 | yarn-debug.log* 7 | yarn-error.log* 8 | 9 | # Runtime data 10 | pids 11 | *.pid 12 | *.seed 13 | *.pid.lock 14 | 15 | # Directory for instrumented libs generated by jscoverage/JSCover 16 | lib-cov 17 | 18 | # Coverage directory used by tools like istanbul 19 | coverage 20 | 21 | # nyc test coverage 22 | .nyc_output 23 | 24 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 25 | .grunt 26 | 27 | # Bower dependency directory (https://bower.io/) 28 | bower_components 29 | 30 | # node-waf configuration 31 | .lock-wscript 32 | 33 | # Compiled binary addons (https://nodejs.org/api/addons.html) 34 | build/Release 35 | 36 | # Dependency directories 37 | node_modules/ 38 | jspm_packages/ 39 | 40 | # TypeScript v1 declaration files 41 | typings/ 42 | 43 | # Optional npm cache directory 44 | .npm 45 | 46 | # Optional eslint cache 47 | .eslintcache 48 | 49 | # Optional REPL history 50 | .node_repl_history 51 | 52 | # Output of 'npm pack' 53 | *.tgz 54 | 55 | # Yarn Integrity file 56 | .yarn-integrity 57 | 58 | # dotenv environment variables file 59 | .env 60 | 61 | # next.js build output 62 | .next 63 | 64 | # package-lock.json 65 | 66 | package-lock.json 67 | -------------------------------------------------------------------------------- /templates/graphql-jwt-system/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "singleQuote": true, 3 | "vetur.format.defaultFormatterOptions": { 4 | "prettier": { 5 | "singleQuote": true 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /templates/graphql-jwt-system/README.md: -------------------------------------------------------------------------------- 1 | # <%= projectName %> 2 | 3 | Introduce el contenido de tu README 4 | 5 | ... 6 | En este proyecto vamos a aprender como crear un sistema para registro de usuarios haciendo uso de JWT y con ello vamos a conseguir también el inicio de sesión para obtener el token que nos servirá para autenticarnos en GraphQL. 7 | 8 | ## Requerimientos 9 | 10 | * Node v10.16.0 o más. 11 | * NPM v6.0.0 o más 12 | * MongoDB instalado y en marcha. 13 | 14 | ## Intrucciones de uso 15 | 16 | ### Clonar el repositorio / descargar. 17 | ```git clone https://github.com/graphql-course/3-jwt-login-register-graphql.git``` 18 | 19 | ### Instalar las dependencias de NPM 20 | ```npm install``` 21 | 22 | ### Crear el fichero de variables de entorno 23 | Creamos el fichero .env dentro del directorio "src" 24 | ``` 25 | PORT= 26 | SECRET_KEY= 27 | DATABASE=mongodb://localhost:27017/ 28 | ``` 29 | 30 | ### Iniciar en debug 31 | ```npm run start:dev``` -------------------------------------------------------------------------------- /templates/graphql-jwt-system/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= projectName %>", 3 | "version": "1.0.0", 4 | "description": "Sistema de autenticación JWT con MongoDB en GraphQL", 5 | "main": "build/server.js", 6 | "scripts": { 7 | "start": "node build/server.js", 8 | "build": "tsc -p . && ncp src/schema build/schema", 9 | "start:dev": "npm run build:dev", 10 | "build:dev": "nodemon \"src/server.ts\" --exec \"ts-node\" src/server.ts -e ts,graphql,json" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/<%= githubUser %>/<%= projectName %>.git" 15 | }, 16 | "keywords": [ 17 | "graphql", 18 | "graphql-curso", 19 | "jwt", 20 | "mongodb" 21 | ], 22 | "author": "<%= authorNameLastname %> <<%= emailValue %>>", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/<%= githubUser %>/<%= projectName %>/issues" 26 | }, 27 | "homepage": "https://github.com/<%= githubUser %>/<%= projectName %>#readme", 28 | "dependencies": { 29 | "apollo-server-express": "^2.6.7", 30 | "bcryptjs": "^2.4.3", 31 | "chalk": "^2.4.2", 32 | "compression": "^1.7.4", 33 | "cors": "^2.8.5", 34 | "dotenv": "^8.0.0", 35 | "express": "^4.17.1", 36 | "graphql": "^14.3.1", 37 | "graphql-import-node": "0.0.4", 38 | "graphql-playground-middleware-express": "^1.7.12", 39 | "graphql-tools": "^4.0.5", 40 | "jsonwebtoken": "^8.5.1", 41 | "mongodb": "^3.2.7", 42 | "ncp": "^2.0.0", 43 | "typescript": "^3.5.2" 44 | }, 45 | "devDependencies": { 46 | "@types/bcryptjs": "^2.4.2", 47 | "@types/compression": "0.0.36", 48 | "@types/cors": "^2.8.5", 49 | "@types/dotenv": "^6.1.1", 50 | "@types/express": "^4.17.0", 51 | "@types/express-graphql": "^0.8.0", 52 | "@types/jsonwebtoken": "^8.3.2", 53 | "@types/mongodb": "^3.1.28", 54 | "@types/node": "^12.0.10", 55 | "nodemon":"^2.0.1", 56 | "ts-node": "^8.5.4", 57 | "typescript-tslint-plugin": "0.5.5" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /templates/graphql-jwt-system/src/.env: -------------------------------------------------------------------------------- 1 | PORT=5002 2 | SECRET= 3 | DATABASE=mongodb://localhost:27017/ -------------------------------------------------------------------------------- /templates/graphql-jwt-system/src/.env_example: -------------------------------------------------------------------------------- 1 | PORT=5002 2 | SECRET= 3 | DATABASE=mongodb://localhost:27017/ -------------------------------------------------------------------------------- /templates/graphql-jwt-system/src/config/constants.ts: -------------------------------------------------------------------------------- 1 | import environments from './environments'; 2 | 3 | if (process.env.NODE_ENV !== 'production') { 4 | const environment = environments; 5 | } 6 | 7 | export const SECRET_KEY = process.env.SECRET || 'AnartzMugika'; -------------------------------------------------------------------------------- /templates/graphql-jwt-system/src/config/database.ts: -------------------------------------------------------------------------------- 1 | import MongoClient from 'mongodb'; 2 | import chalk from 'chalk'; 3 | class Database { 4 | 5 | async init() { 6 | const MONGODB = String(process.env.DATABASE); 7 | const client = await MongoClient.connect(MONGODB, { useNewUrlParser: true, useUnifiedTopology: true}); 8 | 9 | const db = await client.db(); 10 | 11 | if ( client.isConnected() ) { 12 | console.log('==========DATABASE=========='); 13 | console.log(`STATUS: ${chalk.greenBright('ONLINE')}`); 14 | console.log(`DATABASE: ${chalk.greenBright(db.databaseName)}`); 15 | } 16 | 17 | return db; 18 | } 19 | } 20 | 21 | export default Database; -------------------------------------------------------------------------------- /templates/graphql-jwt-system/src/config/environments.ts: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv'; 2 | const environments = dotenv.config({ path: './src/.env'}); 3 | if (process.env.NODE_ENV !== 'production') { 4 | if (environments.error) { 5 | throw environments.error; 6 | } 7 | } 8 | export default environments; -------------------------------------------------------------------------------- /templates/graphql-jwt-system/src/lib/datetime.ts: -------------------------------------------------------------------------------- 1 | export class Datetime { 2 | 3 | getCurrentDateTime(dateSeparateSymbol: string = '-') { 4 | const dateTime = new Date(); 5 | let dateDay: string = this.formatWithTwoDigits(String(dateTime.getDate())); 6 | let month: string = this.formatWithTwoDigits(String(dateTime.getMonth() + 1)); 7 | 8 | let hour : string = this.formatWithTwoDigits(String(dateTime.getHours())); 9 | let minutes : string = this.formatWithTwoDigits(String(dateTime.getMinutes())); 10 | let seconds : string = this.formatWithTwoDigits(String(dateTime.getSeconds())); 11 | 12 | return `${dateTime.getFullYear()}${dateSeparateSymbol}${month}${dateSeparateSymbol}${dateDay} ${hour}:${minutes}:${seconds}`; 13 | } 14 | 15 | private formatWithTwoDigits(value: number | string) { 16 | if (+value < 10) { 17 | return `0${value}`; 18 | } 19 | return String(value); 20 | } 21 | 22 | /** 23 | * Add specific days count to select date or now date 24 | * @param days add days in select date 25 | * @param customDate Specify date if use select date 26 | */ 27 | addDays(days: number, date: string, customDate: string = '', ) { 28 | let date_ = new Date(date); 29 | if (customDate !== '') { 30 | date_ = new Date(customDate); 31 | } 32 | date_.setDate(date_.getDate() + days); 33 | return date; 34 | } 35 | 36 | 37 | } -------------------------------------------------------------------------------- /templates/graphql-jwt-system/src/lib/jwt.ts: -------------------------------------------------------------------------------- 1 | import { SECRET_KEY } from '../config/constants'; 2 | import jwt from 'jsonwebtoken'; 3 | class JWT { 4 | private secretKey = SECRET_KEY as string; 5 | 6 | sign(data: any): string { 7 | return jwt.sign({ user: data.user}, this.secretKey, { expiresIn: 24 * 60 * 60}); 8 | } 9 | 10 | verify(token: string): string { 11 | try { 12 | return jwt.verify(token, this.secretKey) as string; 13 | } catch (e) { 14 | return 'La autenticación del token es inválida. Por favor, inicia sesión para obtener un nuevo token'; 15 | } 16 | } 17 | } 18 | 19 | export default JWT; -------------------------------------------------------------------------------- /templates/graphql-jwt-system/src/resolvers/mutation.ts: -------------------------------------------------------------------------------- 1 | import { IResolvers } from 'graphql-tools'; 2 | import { Datetime } from '../lib/datetime'; 3 | import bcryptjs from 'bcryptjs'; 4 | const mutation: IResolvers = { 5 | Mutation: { 6 | async register(_: void, { user }, { db }): Promise { 7 | 8 | const userCheck = await db.collection('users').findOne({ email: user.email }); 9 | 10 | if (userCheck !== null) { 11 | return { 12 | status: false, 13 | message: `Usuario NO registrado porque ya existe el usuario ${user.email}`, 14 | user: null 15 | }; 16 | } 17 | const lastUser = await db.collection('users').find() 18 | .limit(1).sort({ registerDate: -1 }).toArray(); 19 | if (lastUser.length === 0) { 20 | user.id = 1; 21 | } else { 22 | user.id = lastUser[0].id + 1; 23 | } 24 | user.password = bcryptjs.hashSync(user.password, 10); 25 | user.registerDate = new Datetime().getCurrentDateTime(); 26 | return await db.collection('users').insertOne(user) 27 | .then((result: any) => { 28 | return { 29 | status: true, 30 | message: `Usuario ${user.name} ${user.lastname} añadido correctamente`, 31 | user 32 | }; 33 | }) 34 | .catch((err: any) => { 35 | return { 36 | status: false, 37 | message: `Usuario NO añadido correctamente`, 38 | user: null 39 | }; 40 | }); 41 | } 42 | } 43 | }; 44 | 45 | export default mutation; -------------------------------------------------------------------------------- /templates/graphql-jwt-system/src/resolvers/query.ts: -------------------------------------------------------------------------------- 1 | import { IResolvers } from 'graphql-tools'; 2 | import JWT from '../lib/jwt'; 3 | import bcryptjs from 'bcryptjs'; 4 | 5 | const query : IResolvers = { 6 | Query : { 7 | async users (_: void, __: any, { db }): Promise { 8 | return await db.collection('users').find().toArray(); 9 | }, 10 | async login(_: void, { email, password }, { db }): Promise { 11 | const user = await db.collection('users').findOne({email}); 12 | if (user === null) { 13 | return { 14 | status: false, 15 | message: 'Login INCORRECTO. No existe el usuario', 16 | token: null 17 | }; 18 | } 19 | 20 | if (!bcryptjs.compareSync(password, user.password)) { 21 | return { 22 | status: false, 23 | message: 'Login INCORRECTO. Contraseña incorrecta', 24 | token: null 25 | }; 26 | } 27 | delete user.password; 28 | return { 29 | status: true, 30 | message: 'Login Correcto', 31 | token: new JWT().sign({ user }) 32 | }; 33 | }, 34 | me(_: void, __: any, { token }) { 35 | let info: any = new JWT().verify(token); 36 | if (info === 'La autenticación del token es inválida. Por favor, inicia sesión para obtener un nuevo token') { 37 | return { 38 | status: false, 39 | message: info, 40 | user: null 41 | }; 42 | } 43 | return { 44 | status: true, 45 | message: 'Token correcto', 46 | user: info.user 47 | }; 48 | } 49 | } 50 | }; 51 | 52 | export default query; -------------------------------------------------------------------------------- /templates/graphql-jwt-system/src/resolvers/resolversMap.ts: -------------------------------------------------------------------------------- 1 | import { IResolvers } from 'graphql-tools'; 2 | import query from './query'; 3 | import mutation from './mutation'; 4 | 5 | const resolvers : IResolvers = { 6 | ...query, 7 | ...mutation 8 | }; 9 | 10 | export default resolvers; -------------------------------------------------------------------------------- /templates/graphql-jwt-system/src/schema/index.ts: -------------------------------------------------------------------------------- 1 | import { GraphQLSchema } from 'graphql'; 2 | import 'graphql-import-node'; 3 | import typeDefs from './schema.graphql'; 4 | import resolvers from './../resolvers/resolversMap'; 5 | import { makeExecutableSchema } from 'graphql-tools'; 6 | 7 | const schema: GraphQLSchema = makeExecutableSchema({ 8 | typeDefs, 9 | resolvers 10 | }); 11 | 12 | export default schema; -------------------------------------------------------------------------------- /templates/graphql-jwt-system/src/schema/schema.graphql: -------------------------------------------------------------------------------- 1 | type Query { 2 | "Obtenemos las lista de todos los usuarios" 3 | users: [User!]! 4 | "Iniciamos sesión en el sistema" 5 | login(email: String!, password: String!): ResultToken! 6 | "Obtener nuestra información con el token" 7 | me: ResultUser! 8 | } 9 | 10 | type Mutation { 11 | "Registro de los usuarios en el sistema" 12 | register(user: UserInput): ResultUser! 13 | } 14 | 15 | type User { 16 | id: ID! 17 | name: String! 18 | lastname: String! 19 | email: String! 20 | password: String 21 | registerDate: String! 22 | } 23 | 24 | input UserInput { 25 | name: String! 26 | lastname: String! 27 | email: String! 28 | password: String! 29 | } 30 | 31 | type ResultUser { 32 | status: Boolean! 33 | message: String! 34 | user: User 35 | } 36 | 37 | type ResultToken { 38 | status: Boolean! 39 | message: String! 40 | token: String 41 | } -------------------------------------------------------------------------------- /templates/graphql-jwt-system/src/server.ts: -------------------------------------------------------------------------------- 1 | import express from 'express'; 2 | import compression from 'compression'; 3 | import cors from 'cors'; 4 | import schema from './schema'; 5 | import { ApolloServer } from 'apollo-server-express'; 6 | import { createServer } from 'http'; 7 | import environments from './config/environments'; 8 | import Database from './config/database'; 9 | import expressPlayGround from 'graphql-playground-middleware-express'; 10 | if (process.env.NODE_ENV !== 'production') { 11 | const envs = environments; 12 | console.log(envs); 13 | } 14 | 15 | async function init() { 16 | const app = express(); 17 | 18 | app.use(cors()); 19 | 20 | app.use(compression()); 21 | 22 | const database = new Database(); 23 | const db = await database.init(); 24 | 25 | const context: any = async({req,connection}: any) => { 26 | const token = req ? req.headers.authorization : connection.authorization; 27 | return { db, token }; 28 | }; 29 | const server = new ApolloServer({ 30 | schema, 31 | context, 32 | introspection: true 33 | }); 34 | 35 | server.applyMiddleware({ app }); 36 | 37 | app.use('/', expressPlayGround({ 38 | endpoint: '/graphql' 39 | })); 40 | 41 | const PORT = process.env.PORT || 5300; 42 | const httpServer = createServer(app); 43 | httpServer.listen( 44 | { port: PORT }, 45 | () => console.log(`Hola Mundo API GraphQL http://localhost:${PORT}/graphql`) 46 | ); 47 | } 48 | 49 | init(); -------------------------------------------------------------------------------- /templates/graphql-jwt-system/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* Basic Options */ 4 | "plugins": [{ 5 | "name":"typescript-tslint-plugin" 6 | }], 7 | // "incremental": true, /* Enable incremental compilation */ 8 | "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ 9 | "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 10 | "lib": ["dom","es6"], /* Specify library files to be included in the compilation. */ 11 | // "allowJs": true, /* Allow javascript files to be compiled. */ 12 | // "checkJs": true, /* Report errors in .js files. */ 13 | // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ 14 | // "declaration": true, /* Generates corresponding '.d.ts' file. */ 15 | // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ 16 | // "sourceMap": true, /* Generates corresponding '.map' file. */ 17 | // "outFile": "./", /* Concatenate and emit output to single file. */ 18 | "outDir": "build", /* Redirect output structure to the directory. */ 19 | "rootDir": "src", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ 20 | // "composite": true, /* Enable project compilation */ 21 | // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ 22 | "removeComments": true, /* Do not emit comments to output. */ 23 | // "noEmit": true, /* Do not emit outputs. */ 24 | // "importHelpers": true, /* Import emit helpers from 'tslib'. */ 25 | // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ 26 | // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ 27 | 28 | /* Strict Type-Checking Options */ 29 | "strict": true, /* Enable all strict type-checking options. */ 30 | // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ 31 | // "strictNullChecks": true, /* Enable strict null checks. */ 32 | // "strictFunctionTypes": true, /* Enable strict checking of function types. */ 33 | // "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */ 34 | // "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */ 35 | // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ 36 | // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ 37 | 38 | /* Additional Checks */ 39 | // "noUnusedLocals": true, /* Report errors on unused locals. */ 40 | // "noUnusedParameters": true, /* Report errors on unused parameters. */ 41 | // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ 42 | // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ 43 | 44 | /* Module Resolution Options */ 45 | // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ 46 | // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ 47 | // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ 48 | // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ 49 | // "typeRoots": [], /* List of folders to include type definitions from. */ 50 | // "types": [], /* Type declaration files to be included in compilation. */ 51 | // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ 52 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 53 | // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ 54 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 55 | 56 | /* Source Map Options */ 57 | // "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ 58 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 59 | // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ 60 | // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ 61 | 62 | /* Experimental Options */ 63 | // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ 64 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /templates/graphql-jwt-system/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "quotemark": [true, "single"], 4 | "semicolon": true, 5 | "curly":true, 6 | "no-empty-interface": true 7 | } 8 | } -------------------------------------------------------------------------------- /utils/templates.js: -------------------------------------------------------------------------------- 1 | const ejs = require('ejs'); 2 | 3 | module.exports = { 4 | render: function (content, data) { 5 | return ejs.render(content, data); 6 | } 7 | } --------------------------------------------------------------------------------