├── .gitignore ├── .npmignore ├── LICENSE ├── README.MD ├── bin └── easygraphql-now.js ├── commands └── createProject.js ├── gif ├── 1.gif ├── 2.gif └── 3.gif ├── logo.png ├── package-lock.json ├── package.json ├── scripts ├── createPackage.sh ├── deployNow.sh └── installNow.sh ├── services ├── addSchema.js ├── createPackage.js ├── createStarterFiles.js ├── deployNow.js ├── installNow.js └── runLocal.js └── templates ├── starterFileGitignore.txt └── starterFileIndex.txt /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | /gif -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ###The MIT License 2 | 3 | Copyright (c) 2018 EasyGraphQL 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 13 | all 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 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 |

2 | EasyGraphQL now 3 |
4 | easygraphql-now 5 |
6 |
7 |

8 | 9 | `easygraphql-now` is a node library used to create servers with mocks of the schema you pass. 10 | 11 | ## Installation 12 | ```bash 13 | $ npm install easygraphql-now -g 14 | ``` 15 | 16 | ## Usage 17 | To get started with the tester, you might need to follow the next steps: 18 | 19 | ### Deploy with Now ▲ 20 | + Visit the directory with the schema to deploy or pass the schema route. 21 | + Be sure you have already setup [`now`](https://zeit.co/now). 22 | + Run `easygraphql-now`. 23 | + Select the file. 24 | + It will create the server and deploy with [`now`](https://zeit.co/now), after that you will get a url with your GraphQL server. 25 | 26 | 27 | 28 | 29 | 30 | ### Try it locally 31 | + Visit the directory with the schema to deploy or pass the schema route. 32 | + Run `easygraphql-now --local -p=8000`. 33 | + Add `-p=8000` with your favorite port, by default is 8000. 34 | + Select the file. 35 | + After that you will get a url with your local GraphQL server. 36 | 37 | 38 | 39 | 40 | ### Other useful packages for GraphQL 41 | 42 | + [easygraphql-mock](https://www.npmjs.com/package/easygraphql-mock) 43 | + [easygraphql-tester](https://www.npmjs.com/package/easygraphql-tester) 44 | + [easygraphql-format-error](https://www.npmjs.com/package/easygraphql-format-error) 45 | 46 | # License 47 | ### The MIT License 48 | 49 | Copyright (c) 2018 EasyGraphQL 50 | 51 | Permission is hereby granted, free of charge, to any person obtaining a copy 52 | of this software and associated documentation files (the "Software"), to deal 53 | in the Software without restriction, including without limitation the rights 54 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 55 | copies of the Software, and to permit persons to whom the Software is 56 | furnished to do so, subject to the following conditions: 57 | 58 | The above copyright notice and this permission notice shall be included in 59 | all copies or substantial portions of the Software. 60 | 61 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 62 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 63 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 64 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 65 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 66 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 67 | THE SOFTWARE. -------------------------------------------------------------------------------- /bin/easygraphql-now.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | 'use strict' 4 | 5 | const createProject = require('../commands/createProject') 6 | 7 | createProject() 8 | -------------------------------------------------------------------------------- /commands/createProject.js: -------------------------------------------------------------------------------- 1 | const inquirer = require('inquirer') 2 | const ora = require('ora') 3 | const fs = require('fs-extra') 4 | const path = require('path') 5 | const argv = require('minimist')(process.argv.slice(2)) 6 | 7 | const spinner = ora('Creating GraphQL server! 🚀') 8 | 9 | const createPackage = require('../services/createPackage') 10 | const createStarterFiles = require('../services/createStarterFiles') 11 | const addGQLSchema = require('../services/addSchema') 12 | const installNow = require('../services/installNow') 13 | const deployNow = require('../services/deployNow') 14 | const runLocal = require('../services/runLocal') 15 | 16 | const questions = [] 17 | 18 | function createProject () { 19 | let fileName 20 | let filePath 21 | 22 | const arg = argv._.length > 0 ? argv._[0] : false 23 | const local = argv.local ? argv.local : false 24 | const port = argv.p && argv.p > 999 ? argv.p : 8000 25 | const displayGraphiQL = argv.graphiql ? argv.graphiql : null 26 | 27 | if (displayGraphiQL === null) { 28 | const options = { 29 | type: 'confirm', 30 | name: 'graphiql', 31 | message: 'Display GraphiQL' 32 | } 33 | questions.unshift(options) 34 | } 35 | 36 | if (arg && (arg.includes('.gql') || arg.includes('.graphql')) && fs.existsSync(arg)) { 37 | fileName = arg 38 | } else if (arg && fs.existsSync(arg)) { 39 | let files = fs.readdirSync(arg) 40 | files = files.filter(file => file.includes('.gql') || file.includes('.graphql')) 41 | const options = { 42 | type: 'list', 43 | name: 'schemaName', 44 | message: 'Schema file name', 45 | choices: files 46 | } 47 | questions.unshift(options) 48 | filePath = arg 49 | } else { 50 | let files = fs.readdirSync(path.resolve()) 51 | files = files.filter(file => file.includes('.gql') || file.includes('.graphql')) 52 | if (files.length === 0) { 53 | console.log('> Error: There are no GraphQL schema in this dir! ❌') 54 | process.exit(1) 55 | } 56 | const options = { 57 | type: 'list', 58 | name: 'schemaName', 59 | message: 'Schema file name', 60 | choices: files 61 | } 62 | questions.unshift(options) 63 | } 64 | 65 | inquirer.prompt(questions).then(answers => handleResponse(answers, fileName, filePath, local, port, displayGraphiQL)) 66 | } 67 | 68 | async function handleResponse (answers, fileName, filePath, local, port, displayGraphiQL) { 69 | let folderPath 70 | try { 71 | fileName = fileName || answers['schemaName'] 72 | spinner.start() 73 | folderPath = await createPackage() 74 | const graphiql = displayGraphiQL ? displayGraphiQL : answers['graphiql'] 75 | await createStarterFiles(folderPath, graphiql, port) 76 | await addGQLSchema(folderPath, fileName, filePath) 77 | if (!local) { 78 | await installNow(folderPath) 79 | deployNow(folderPath) 80 | } else { 81 | runLocal(folderPath, port) 82 | } 83 | spinner.stop() 84 | } catch (err) { 85 | spinner.stop() 86 | console.log('> Error:', err.message) 87 | fs.removeSync(folderPath) 88 | process.exit(1) 89 | } 90 | } 91 | 92 | module.exports = createProject 93 | -------------------------------------------------------------------------------- /gif/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EasyGraphQL/easygraphql-now/ae1d89dd50c54ddb1522c8dccea5093f3039be7a/gif/1.gif -------------------------------------------------------------------------------- /gif/2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EasyGraphQL/easygraphql-now/ae1d89dd50c54ddb1522c8dccea5093f3039be7a/gif/2.gif -------------------------------------------------------------------------------- /gif/3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EasyGraphQL/easygraphql-now/ae1d89dd50c54ddb1522c8dccea5093f3039be7a/gif/3.gif -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EasyGraphQL/easygraphql-now/ae1d89dd50c54ddb1522c8dccea5093f3039be7a/logo.png -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "easygraphql-now", 3 | "version": "0.0.7", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "ansi-escapes": { 8 | "version": "3.1.0", 9 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", 10 | "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==" 11 | }, 12 | "ansi-regex": { 13 | "version": "3.0.0", 14 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 15 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" 16 | }, 17 | "ansi-styles": { 18 | "version": "3.2.1", 19 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 20 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 21 | "requires": { 22 | "color-convert": "1.9.3" 23 | } 24 | }, 25 | "arch": { 26 | "version": "2.1.1", 27 | "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz", 28 | "integrity": "sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==" 29 | }, 30 | "chalk": { 31 | "version": "2.4.1", 32 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", 33 | "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", 34 | "requires": { 35 | "ansi-styles": "3.2.1", 36 | "escape-string-regexp": "1.0.5", 37 | "supports-color": "5.5.0" 38 | } 39 | }, 40 | "chardet": { 41 | "version": "0.4.2", 42 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", 43 | "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=" 44 | }, 45 | "cli-cursor": { 46 | "version": "2.1.0", 47 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", 48 | "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", 49 | "requires": { 50 | "restore-cursor": "2.0.0" 51 | } 52 | }, 53 | "cli-spinners": { 54 | "version": "1.3.1", 55 | "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.3.1.tgz", 56 | "integrity": "sha512-1QL4544moEsDVH9T/l6Cemov/37iv1RtoKf7NJ04A60+4MREXNfx/QvavbH6QoGdsD4N4Mwy49cmaINR/o2mdg==" 57 | }, 58 | "cli-width": { 59 | "version": "2.2.0", 60 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 61 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" 62 | }, 63 | "clipboardy": { 64 | "version": "1.2.3", 65 | "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-1.2.3.tgz", 66 | "integrity": "sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA==", 67 | "requires": { 68 | "arch": "2.1.1", 69 | "execa": "0.8.0" 70 | } 71 | }, 72 | "color-convert": { 73 | "version": "1.9.3", 74 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 75 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 76 | "requires": { 77 | "color-name": "1.1.3" 78 | } 79 | }, 80 | "color-name": { 81 | "version": "1.1.3", 82 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 83 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" 84 | }, 85 | "cross-spawn": { 86 | "version": "5.1.0", 87 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", 88 | "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", 89 | "requires": { 90 | "lru-cache": "4.1.3", 91 | "shebang-command": "1.2.0", 92 | "which": "1.3.1" 93 | } 94 | }, 95 | "escape-string-regexp": { 96 | "version": "1.0.5", 97 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 98 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" 99 | }, 100 | "execa": { 101 | "version": "0.8.0", 102 | "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", 103 | "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", 104 | "requires": { 105 | "cross-spawn": "5.1.0", 106 | "get-stream": "3.0.0", 107 | "is-stream": "1.1.0", 108 | "npm-run-path": "2.0.2", 109 | "p-finally": "1.0.0", 110 | "signal-exit": "3.0.2", 111 | "strip-eof": "1.0.0" 112 | } 113 | }, 114 | "external-editor": { 115 | "version": "2.2.0", 116 | "resolved": "http://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", 117 | "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", 118 | "requires": { 119 | "chardet": "0.4.2", 120 | "iconv-lite": "0.4.24", 121 | "tmp": "0.0.33" 122 | } 123 | }, 124 | "figures": { 125 | "version": "2.0.0", 126 | "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", 127 | "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", 128 | "requires": { 129 | "escape-string-regexp": "1.0.5" 130 | } 131 | }, 132 | "fs-extra": { 133 | "version": "5.0.0", 134 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", 135 | "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", 136 | "requires": { 137 | "graceful-fs": "4.1.11", 138 | "jsonfile": "4.0.0", 139 | "universalify": "0.1.2" 140 | } 141 | }, 142 | "get-stream": { 143 | "version": "3.0.0", 144 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", 145 | "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" 146 | }, 147 | "graceful-fs": { 148 | "version": "4.1.11", 149 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", 150 | "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=" 151 | }, 152 | "graphql": { 153 | "version": "14.0.0", 154 | "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.0.0.tgz", 155 | "integrity": "sha512-HGVcnO6B25YZcSt6ZsH6/N+XkYuPA7yMqJmlJ4JWxWlS4Tr8SHI56R1Ocs8Eor7V7joEZPRXPDH8RRdll1w44Q==", 156 | "requires": { 157 | "iterall": "1.2.2" 158 | } 159 | }, 160 | "has-flag": { 161 | "version": "3.0.0", 162 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 163 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" 164 | }, 165 | "iconv-lite": { 166 | "version": "0.4.24", 167 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 168 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 169 | "requires": { 170 | "safer-buffer": "2.1.2" 171 | } 172 | }, 173 | "inquirer": { 174 | "version": "3.3.0", 175 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", 176 | "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", 177 | "requires": { 178 | "ansi-escapes": "3.1.0", 179 | "chalk": "2.4.1", 180 | "cli-cursor": "2.1.0", 181 | "cli-width": "2.2.0", 182 | "external-editor": "2.2.0", 183 | "figures": "2.0.0", 184 | "lodash": "4.17.10", 185 | "mute-stream": "0.0.7", 186 | "run-async": "2.3.0", 187 | "rx-lite": "4.0.8", 188 | "rx-lite-aggregates": "4.0.8", 189 | "string-width": "2.1.1", 190 | "strip-ansi": "4.0.0", 191 | "through": "2.3.8" 192 | } 193 | }, 194 | "is-fullwidth-code-point": { 195 | "version": "2.0.0", 196 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 197 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" 198 | }, 199 | "is-promise": { 200 | "version": "2.1.0", 201 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 202 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" 203 | }, 204 | "is-stream": { 205 | "version": "1.1.0", 206 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 207 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=" 208 | }, 209 | "isexe": { 210 | "version": "2.0.0", 211 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 212 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" 213 | }, 214 | "iterall": { 215 | "version": "1.2.2", 216 | "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz", 217 | "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA==" 218 | }, 219 | "jsonfile": { 220 | "version": "4.0.0", 221 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 222 | "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", 223 | "requires": { 224 | "graceful-fs": "4.1.11" 225 | } 226 | }, 227 | "lodash": { 228 | "version": "4.17.10", 229 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", 230 | "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" 231 | }, 232 | "log-symbols": { 233 | "version": "2.2.0", 234 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", 235 | "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", 236 | "requires": { 237 | "chalk": "2.4.1" 238 | } 239 | }, 240 | "lru-cache": { 241 | "version": "4.1.3", 242 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", 243 | "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", 244 | "requires": { 245 | "pseudomap": "1.0.2", 246 | "yallist": "2.1.2" 247 | } 248 | }, 249 | "mimic-fn": { 250 | "version": "1.2.0", 251 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", 252 | "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" 253 | }, 254 | "minimist": { 255 | "version": "1.2.0", 256 | "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 257 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" 258 | }, 259 | "mute-stream": { 260 | "version": "0.0.7", 261 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", 262 | "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" 263 | }, 264 | "npm-run-path": { 265 | "version": "2.0.2", 266 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", 267 | "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", 268 | "requires": { 269 | "path-key": "2.0.1" 270 | } 271 | }, 272 | "onetime": { 273 | "version": "2.0.1", 274 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", 275 | "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", 276 | "requires": { 277 | "mimic-fn": "1.2.0" 278 | } 279 | }, 280 | "ora": { 281 | "version": "1.4.0", 282 | "resolved": "https://registry.npmjs.org/ora/-/ora-1.4.0.tgz", 283 | "integrity": "sha512-iMK1DOQxzzh2MBlVsU42G80mnrvUhqsMh74phHtDlrcTZPK0pH6o7l7DRshK+0YsxDyEuaOkziVdvM3T0QTzpw==", 284 | "requires": { 285 | "chalk": "2.4.1", 286 | "cli-cursor": "2.1.0", 287 | "cli-spinners": "1.3.1", 288 | "log-symbols": "2.2.0" 289 | } 290 | }, 291 | "os-tmpdir": { 292 | "version": "1.0.2", 293 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 294 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" 295 | }, 296 | "p-finally": { 297 | "version": "1.0.0", 298 | "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", 299 | "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=" 300 | }, 301 | "path-key": { 302 | "version": "2.0.1", 303 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 304 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=" 305 | }, 306 | "pseudomap": { 307 | "version": "1.0.2", 308 | "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", 309 | "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" 310 | }, 311 | "restore-cursor": { 312 | "version": "2.0.0", 313 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", 314 | "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", 315 | "requires": { 316 | "onetime": "2.0.1", 317 | "signal-exit": "3.0.2" 318 | } 319 | }, 320 | "run-async": { 321 | "version": "2.3.0", 322 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", 323 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", 324 | "requires": { 325 | "is-promise": "2.1.0" 326 | } 327 | }, 328 | "rx-lite": { 329 | "version": "4.0.8", 330 | "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", 331 | "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=" 332 | }, 333 | "rx-lite-aggregates": { 334 | "version": "4.0.8", 335 | "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", 336 | "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", 337 | "requires": { 338 | "rx-lite": "4.0.8" 339 | } 340 | }, 341 | "safer-buffer": { 342 | "version": "2.1.2", 343 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 344 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 345 | }, 346 | "shebang-command": { 347 | "version": "1.2.0", 348 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 349 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 350 | "requires": { 351 | "shebang-regex": "1.0.0" 352 | } 353 | }, 354 | "shebang-regex": { 355 | "version": "1.0.0", 356 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 357 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" 358 | }, 359 | "signal-exit": { 360 | "version": "3.0.2", 361 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 362 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" 363 | }, 364 | "string-width": { 365 | "version": "2.1.1", 366 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 367 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 368 | "requires": { 369 | "is-fullwidth-code-point": "2.0.0", 370 | "strip-ansi": "4.0.0" 371 | } 372 | }, 373 | "strip-ansi": { 374 | "version": "4.0.0", 375 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 376 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 377 | "requires": { 378 | "ansi-regex": "3.0.0" 379 | } 380 | }, 381 | "strip-eof": { 382 | "version": "1.0.0", 383 | "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", 384 | "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=" 385 | }, 386 | "supports-color": { 387 | "version": "5.5.0", 388 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 389 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 390 | "requires": { 391 | "has-flag": "3.0.0" 392 | } 393 | }, 394 | "through": { 395 | "version": "2.3.8", 396 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 397 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" 398 | }, 399 | "tmp": { 400 | "version": "0.0.33", 401 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 402 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 403 | "requires": { 404 | "os-tmpdir": "1.0.2" 405 | } 406 | }, 407 | "universalify": { 408 | "version": "0.1.2", 409 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 410 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" 411 | }, 412 | "which": { 413 | "version": "1.3.1", 414 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 415 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 416 | "requires": { 417 | "isexe": "2.0.0" 418 | } 419 | }, 420 | "yallist": { 421 | "version": "2.1.2", 422 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", 423 | "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" 424 | } 425 | } 426 | } 427 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "easygraphql-now", 3 | "version": "0.0.7", 4 | "description": "Create GraphQL servers with mocked schema on the go", 5 | "bin": { 6 | "easygraphql-now": "./bin/easygraphql-now.js" 7 | }, 8 | "scripts": { 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "homepage": "https://github.com/EasyGraphQL/easygraphql-now", 12 | "author": { 13 | "name": "EasyGraphQL", 14 | "url": "https://github.com/EasyGraphQL" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "https://github.com/EasyGraphQL/easygraphql-now" 19 | }, 20 | "bugs": { 21 | "url": "https://github.com/EasyGraphQL/easygraphql-now/issues" 22 | }, 23 | "license": "MIT", 24 | "dependencies": { 25 | "clipboardy": "^1.2.3", 26 | "fs-extra": "^5.0.0", 27 | "graphql": "^14.0.0", 28 | "inquirer": "^3.3.0", 29 | "minimist": "^1.2.0", 30 | "ora": "^1.3.0" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /scripts/createPackage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | npm init -y 3 | npm install -s express body-parser easygraphql-mock express-graphql graphql cors -------------------------------------------------------------------------------- /scripts/deployNow.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | now --public -------------------------------------------------------------------------------- /scripts/installNow.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | npm install now -D -------------------------------------------------------------------------------- /services/addSchema.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('path') 4 | const fs = require('fs-extra') 5 | const { buildSchema } = require('graphql') 6 | 7 | /** 8 | * return the path of the directory 9 | * @param {String} dirName the name of the project and dirname 10 | */ 11 | async function addGQLSchema (dirPath, schemaName, filePath) { 12 | try { 13 | if (!dirPath) { 14 | throw new Error("The path can't be empty") 15 | } 16 | if (!schemaName) { 17 | throw new Error("The schema file name can't be empty") 18 | } 19 | 20 | let fileType = schemaName.split('.') 21 | fileType = fileType[fileType.length - 1] 22 | 23 | if (fileType !== 'gql' && fileType !== 'graphql') { 24 | throw new Error('The file type is not valid, it mush be .gql or .graphql') 25 | } 26 | 27 | filePath = filePath ? path.join(path.resolve(), filePath, schemaName) : path.join(path.resolve(), schemaName) 28 | validateSchema(filePath) 29 | copySchemaFile(dirPath, filePath) 30 | addSchemaName(dirPath, schemaName) 31 | } catch (err) { 32 | throw err 33 | } 34 | } 35 | 36 | function validateSchema (filePath) { 37 | const schemaCode = fs.readFileSync(filePath, 'utf8') 38 | buildSchema(schemaCode) 39 | } 40 | 41 | function copySchemaFile (dirPath, filePath) { 42 | fs.copySync(filePath, `${dirPath}/schema.gql`) 43 | } 44 | 45 | function addSchemaName (dirPath, schemaName) { 46 | const data = fs.readFileSync(`${dirPath}/index.js`, 'utf8') 47 | const replaceSchemaName = data.replace(/#schemaName/gm, `'${schemaName}'`) 48 | fs.outputFileSync(`${dirPath}/index.js`, replaceSchemaName) 49 | } 50 | 51 | module.exports = addGQLSchema 52 | -------------------------------------------------------------------------------- /services/createPackage.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('path') 4 | const fs = require('fs-extra') 5 | const { spawnSync } = require('child_process') 6 | const os = require('os') 7 | 8 | /** 9 | * return the path of the directory 10 | * @return {String} a path for the directory 11 | */ 12 | async function createFolder () { 13 | try { 14 | const d = new Date() 15 | const name = d.getTime().toString() 16 | const folderPath = path.join(os.tmpdir(), name) 17 | fs.ensureDirSync(folderPath) 18 | await createPackageJson(folderPath) 19 | return folderPath 20 | } catch (err) { 21 | throw err 22 | } 23 | } 24 | 25 | function createPackageJson (folderPath) { 26 | return new Promise(resolve => { 27 | resolve(spawnSync('sh', [`${path.join(__dirname, '..', 'scripts', 'createPackage.sh')}`], { 28 | cwd: folderPath 29 | })) 30 | }) 31 | } 32 | 33 | module.exports = createFolder 34 | -------------------------------------------------------------------------------- /services/createStarterFiles.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('path') 4 | const fs = require('fs-extra') 5 | const templatesPath = path.join(__dirname, '..', 'templates') 6 | 7 | /** 8 | * return the path of the directory 9 | * @param {String} dirName the name of the project and dirname 10 | */ 11 | async function createStarterFiles (dirPath, displayGraphiQL, port) { 12 | try { 13 | if (!dirPath) { 14 | throw new Error('The path cant be empty') 15 | } 16 | 17 | createIndexFile(dirPath) 18 | createGitIgnoreFile(dirPath) 19 | displayGraphiQLOnIndex(dirPath, displayGraphiQL) 20 | addPort(dirPath, port) 21 | editPackageJson(dirPath) 22 | } catch (err) { 23 | throw err 24 | } 25 | } 26 | 27 | function createIndexFile (dirPath) { 28 | fs.copySync(`${templatesPath}/starterFileIndex.txt`, `${dirPath}/index.js`) 29 | } 30 | 31 | function createGitIgnoreFile (dirPath) { 32 | fs.ensureDirSync(dirPath) 33 | fs.copySync(`${templatesPath}/starterFileGitignore.txt`, `${dirPath}/.gitignore`) 34 | } 35 | 36 | function displayGraphiQLOnIndex (dirPath, displayGraphiQL) { 37 | const data = fs.readFileSync(`${dirPath}/index.js`, 'utf8') 38 | const updatedTemplate = data.replace(/#displayGraphiql/gm, displayGraphiQL) 39 | fs.outputFileSync(`${dirPath}/index.js`, updatedTemplate) 40 | } 41 | 42 | function addPort (dirPath, port) { 43 | const data = fs.readFileSync(`${dirPath}/index.js`, 'utf8') 44 | const updatedTemplate = data.replace(/#port/gm, port) 45 | fs.outputFileSync(`${dirPath}/index.js`, updatedTemplate) 46 | } 47 | 48 | function editPackageJson (dirPath) { 49 | const data = fs.readFileSync(`${dirPath}/package.json`, 'utf8').toString().split('\n') 50 | const scriptPosition = data.indexOf(' "scripts": {') 51 | data.splice(scriptPosition + 1, 0, ' "start": "node index.js",') 52 | const text = data.join('\n') 53 | fs.outputFileSync(`${dirPath}/package.json`, text) 54 | } 55 | 56 | module.exports = createStarterFiles 57 | -------------------------------------------------------------------------------- /services/deployNow.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const fs = require('fs-extra') 4 | const { spawn } = require('child_process') 5 | const clipboardy = require('clipboardy') 6 | const ora = require('ora') 7 | 8 | const spinner = ora('▲ Deploying to now!') 9 | /** 10 | * return the path of the directory 11 | * @param {String} dirName the name of the project and dirname 12 | */ 13 | function deployNow (dirPath) { 14 | spinner.start() 15 | if (!dirPath) { 16 | throw new Error('The path cant be empty') 17 | } 18 | runDeployNow(dirPath) 19 | } 20 | 21 | function runDeployNow (dirPath) { 22 | const consoleProcess = spawn('now', [ '-p' ], { 23 | cwd: dirPath 24 | }) 25 | 26 | let nowUrl 27 | consoleProcess.stdout.setEncoding('utf8') 28 | consoleProcess.stderr.setEncoding('utf8') 29 | consoleProcess.stderr.pipe(process.stdout) 30 | 31 | consoleProcess.stdout.on('data', (data) => { 32 | if (data.includes('https://')) { 33 | nowUrl = data 34 | clipboardy.writeSync(data) 35 | } 36 | }) 37 | 38 | consoleProcess.stderr.on('data', (data) => { 39 | console.log(data) 40 | }) 41 | 42 | consoleProcess.on('close', (code) => { 43 | spinner.succeed() 44 | fs.removeSync(dirPath) 45 | console.log('> url copied on clipboard: ', nowUrl) 46 | console.log('> Thanks for using easygraphql 😀') 47 | }) 48 | } 49 | 50 | module.exports = deployNow 51 | -------------------------------------------------------------------------------- /services/installNow.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('path') 4 | const { spawnSync } = require('child_process') 5 | 6 | /** 7 | * return the path of the directory 8 | * @param {String} dirName the name of the project and dirname 9 | */ 10 | async function createDeployWithNow (dirPath) { 11 | try { 12 | if (!dirPath) { 13 | throw new Error('The path cant be empty') 14 | } 15 | await installNow(dirPath) 16 | } catch (err) { 17 | throw err 18 | } 19 | } 20 | 21 | function installNow (dirPath) { 22 | return new Promise(resolve => { 23 | resolve(spawnSync('sh', [`${path.join(__dirname, '..', 'scripts', 'installNow.sh')}`], { 24 | cwd: dirPath 25 | })) 26 | }) 27 | } 28 | 29 | module.exports = createDeployWithNow 30 | -------------------------------------------------------------------------------- /services/runLocal.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const fs = require('fs-extra') 4 | const { spawn } = require('child_process') 5 | const clipboardy = require('clipboardy') 6 | const ora = require('ora') 7 | 8 | const spinner = ora('Starting server locally ⏳') 9 | 10 | /** 11 | * return the path of the directory 12 | * @param {String} dirName the name of the project and dirname 13 | */ 14 | function runLocal (dirPath, port) { 15 | spinner.start() 16 | if (!dirPath) { 17 | throw new Error('The path cant be empty') 18 | } 19 | runDeployLocal(dirPath, port) 20 | } 21 | 22 | function runDeployLocal (dirPath, port) { 23 | spawn('npm', [ 'start' ], { 24 | cwd: dirPath 25 | }) 26 | 27 | spinner.succeed() 28 | const localUrl = `http://localhost:${port}/` 29 | clipboardy.writeSync(localUrl) 30 | console.log('> url copied on clipboard: ', localUrl) 31 | 32 | // process.on('exit', exitHandler.bind(null, { dirPath })); 33 | process.on('SIGINT', exitHandler.bind(null, { dirPath })) 34 | process.on('SIGUSR1', exitHandler.bind(null, { dirPath })) 35 | process.on('SIGUSR2', exitHandler.bind(null, { dirPath })) 36 | process.on('uncaughtException', exitHandler.bind(null, { dirPath })) 37 | } 38 | 39 | function exitHandler (options) { 40 | fs.removeSync(options.dirPath) 41 | console.log('> Thanks for using easygraphql 😀') 42 | } 43 | 44 | module.exports = runLocal 45 | -------------------------------------------------------------------------------- /templates/starterFileGitignore.txt: -------------------------------------------------------------------------------- 1 | # dependencies 2 | /node_modules/ 3 | 4 | # misc 5 | /variables.env -------------------------------------------------------------------------------- /templates/starterFileIndex.txt: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const express = require('express') 4 | const { buildSchema } = require('graphql') 5 | const graphqlHTTP = require('express-graphql') 6 | const bodyParser = require('body-parser') 7 | const fs = require('fs') 8 | const path = require('path') 9 | const mocker = require('easygraphql-mock') 10 | const cors = require('cors') 11 | 12 | const app = express() 13 | 14 | app.set('port', #port) 15 | app.use(bodyParser.json({limit: '10mb'})) 16 | app.use(bodyParser.urlencoded({ extended: true })) 17 | 18 | const schemaCode = fs.readFileSync(path.join(__dirname, 'schema.gql'), 'utf8') 19 | 20 | const schema = buildSchema(schemaCode) 21 | const mock = mocker(schemaCode) 22 | 23 | const resolver = Object.assign({}, mock.Query, mock.Mutation) 24 | 25 | app.use(cors()) 26 | 27 | app.use('/', (req, res) => { 28 | graphqlHTTP({ 29 | schema, 30 | rootValue: resolver, 31 | graphiql: #displayGraphiql, 32 | formatError: (err) => { 33 | console.log(err) 34 | return err 35 | } 36 | })(req, res) 37 | }) 38 | 39 | const server = app.listen(app.get('port'), () => { 40 | console.log(`Server running -> PORT ${server.address().port}`) 41 | }) 42 | 43 | module.exports = app 44 | --------------------------------------------------------------------------------