├── .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 | 
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 | }
--------------------------------------------------------------------------------