├── .gitignore ├── LICENSE ├── README.md ├── index.js ├── lib └── tracer.js ├── package-lock.json ├── package.json └── result.gif /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ###The MIT License 2 | 3 | Copyright (c) 2019 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-tracing 3 |
4 | easygraphql-tracing 5 |
6 |
7 |

8 | 9 | `easygraphql-tracing` is a node libreary used with [`express-graphql`](https://github.com/graphql/express-graphql) to get the time 10 | to resolve a field. 11 | 12 | ## Requirements 13 | 14 | + GraphQL: `"^14.0.0"` 15 | + express-graphql: `"^0.7.0"` 16 | 17 | ## Installation 18 | 19 | To install the package on your project just run on the root of your project 20 | 21 | ```shell 22 | $ npm install easygraphql-tracing --save-dev 23 | ``` 24 | 25 | ## How to use it 26 | 27 | + Import `{ tracing, fieldResolver }` from `easygraphql-tracing` package 28 | + Create a new express middleware with `tracing` 29 | + On your `graphqlHTTP` function, set the option `fieldResolver` 30 | 31 | 32 | ## Example: 33 | 34 | ```js 35 | const express = require('express'); 36 | const graphqlHTTP = require('express-graphql'); 37 | const { tracing, fieldResolver } = require('easygraphql-tracing'); 38 | 39 | const app = express(); 40 | 41 | app.use(tracing) 42 | 43 | app.use('/graphql', graphqlHTTP({ 44 | schema: MyGraphQLSchema, 45 | graphiql: true, 46 | fieldResolver 47 | })); 48 | 49 | app.listen(4000); 50 | ``` 51 | 52 | ## Result 53 | It'll create a table on the console 54 | ``` 55 | ┌─────────────┬─────────────┬─────────────┬─────────────────────────────────┬───────────────┬───────────────┐ 56 | │ Field name │ Parent Type │ Return Type │ Path │ Duration (ns) │ Duration (ms) │ 57 | ├─────────────┼─────────────┼─────────────┼─────────────────────────────────┼───────────────┼───────────────┤ 58 | │ uuid │ Activity │ ID! │ getActivityByUuid - uuid │ 3645 │ 0.003645 │ 59 | ├─────────────┼─────────────┼─────────────┼─────────────────────────────────┼───────────────┼───────────────┤ 60 | │ name │ Activity │ String! │ getActivityByUuid - name │ 1768 │ 0.001768 │ 61 | ├─────────────┼─────────────┼─────────────┼─────────────────────────────────┼───────────────┼───────────────┤ 62 | │ description │ Activity │ String │ getActivityByUuid - description │ 751 │ 0.000751 │ 63 | ├─────────────┼─────────────┼─────────────┼─────────────────────────────────┼───────────────┼───────────────┤ 64 | │ rating │ Activity │ Float! │ getActivityByUuid - rating │ 913 │ 0.000913 │ 65 | └─────────────┴─────────────┴─────────────┴─────────────────────────────────┴───────────────┴───────────────┘ 66 | ``` 67 | 68 | result 69 | 70 | 71 | ## License 72 | ### The MIT License 73 | 74 | Copyright (c) 2019 EasyGraphQL 75 | 76 | Permission is hereby granted, free of charge, to any person obtaining a copy 77 | of this software and associated documentation files (the "Software"), to deal 78 | in the Software without restriction, including without limitation the rights 79 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 80 | copies of the Software, and to permit persons to whom the Software is 81 | furnished to do so, subject to the following conditions: 82 | 83 | The above copyright notice and this permission notice shall be included in 84 | all copies or substantial portions of the Software. 85 | 86 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 87 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 88 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 89 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 90 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 91 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 92 | THE SOFTWARE. 93 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | module.exports = require('./lib/tracer') 4 | -------------------------------------------------------------------------------- /lib/tracer.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const { responsePathAsArray, defaultFieldResolver } = require("graphql"); 4 | const Table = require("cli-table"); 5 | 6 | class Tracer { 7 | constructor() { 8 | this.table = new Table({ 9 | head: [ 10 | "Field name", 11 | "Parent Type", 12 | "Return Type", 13 | "Path", 14 | "Duration (ns)", 15 | "Duration (ms)" 16 | ] 17 | }); 18 | this.tracingResolvers = []; 19 | } 20 | 21 | fieldResolver() { 22 | const self = this; 23 | return function(value, args, ctx, info) { 24 | const tracerResult = {}; 25 | 26 | tracerResult.fieldName = info.fieldName; 27 | tracerResult.path = [...responsePathAsArray(info.path)]; 28 | tracerResult.parentType = info.parentType; 29 | tracerResult.returnType = info.returnType; 30 | tracerResult.startTime = duration(process.hrtime()); 31 | 32 | self.tracingResolvers.push(tracerResult); 33 | 34 | const result = defaultFieldResolver(value, args, ctx, info); 35 | 36 | tracerResult.endTime = duration(process.hrtime()); 37 | 38 | return result; 39 | }; 40 | } 41 | 42 | tracing() { 43 | const self = this; 44 | return function(req, res, next) { 45 | res.once("finish", function() { 46 | self.tracingResolvers = self.tracingResolvers.map(tracingResolver => { 47 | const duration = tracingResolver.endTime - tracingResolver.startTime; 48 | self.table.push([ 49 | tracingResolver.fieldName, 50 | tracingResolver.parentType, 51 | tracingResolver.returnType, 52 | tracingResolver.path.join(" - "), 53 | duration, 54 | duration / 1e6 55 | ]); 56 | 57 | return { ...tracingResolver, duration }; 58 | }); 59 | 60 | if (self.tracingResolvers.length) { 61 | console.log(self.table.toString()); 62 | } 63 | }); 64 | 65 | self.table = new Table({ 66 | head: [ 67 | "Field name", 68 | "Parent Type", 69 | "Return Type", 70 | "Path", 71 | "Duration (ns)", 72 | "Duration (ms)" 73 | ] 74 | }); 75 | self.tracingResolvers = []; 76 | 77 | next(); 78 | }; 79 | } 80 | } 81 | 82 | function duration(hrtime) { 83 | return hrtime[0] * 1e9 + hrtime[1]; 84 | } 85 | 86 | const tracer = new Tracer(); 87 | 88 | module.exports = { 89 | tracing: tracer.tracing(), 90 | fieldResolver: tracer.fieldResolver() 91 | }; 92 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "easygraphql-tracing", 3 | "version": "0.0.3", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "argparse": { 8 | "version": "1.0.10", 9 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 10 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 11 | "dev": true, 12 | "requires": { 13 | "sprintf-js": "~1.0.2" 14 | } 15 | }, 16 | "caller-callsite": { 17 | "version": "2.0.0", 18 | "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", 19 | "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", 20 | "dev": true, 21 | "requires": { 22 | "callsites": "^2.0.0" 23 | } 24 | }, 25 | "caller-path": { 26 | "version": "2.0.0", 27 | "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", 28 | "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", 29 | "dev": true, 30 | "requires": { 31 | "caller-callsite": "^2.0.0" 32 | } 33 | }, 34 | "callsites": { 35 | "version": "2.0.0", 36 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", 37 | "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", 38 | "dev": true 39 | }, 40 | "ci-info": { 41 | "version": "2.0.0", 42 | "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", 43 | "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", 44 | "dev": true 45 | }, 46 | "cli-table": { 47 | "version": "0.3.1", 48 | "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", 49 | "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", 50 | "requires": { 51 | "colors": "1.0.3" 52 | } 53 | }, 54 | "colors": { 55 | "version": "1.0.3", 56 | "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", 57 | "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=" 58 | }, 59 | "cosmiconfig": { 60 | "version": "5.1.0", 61 | "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.1.0.tgz", 62 | "integrity": "sha512-kCNPvthka8gvLtzAxQXvWo4FxqRB+ftRZyPZNuab5ngvM9Y7yw7hbEysglptLgpkGX9nAOKTBVkHUAe8xtYR6Q==", 63 | "dev": true, 64 | "requires": { 65 | "import-fresh": "^2.0.0", 66 | "is-directory": "^0.3.1", 67 | "js-yaml": "^3.9.0", 68 | "lodash.get": "^4.4.2", 69 | "parse-json": "^4.0.0" 70 | } 71 | }, 72 | "cross-spawn": { 73 | "version": "6.0.5", 74 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 75 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 76 | "dev": true, 77 | "requires": { 78 | "nice-try": "^1.0.4", 79 | "path-key": "^2.0.1", 80 | "semver": "^5.5.0", 81 | "shebang-command": "^1.2.0", 82 | "which": "^1.2.9" 83 | } 84 | }, 85 | "end-of-stream": { 86 | "version": "1.4.1", 87 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", 88 | "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", 89 | "dev": true, 90 | "requires": { 91 | "once": "^1.4.0" 92 | } 93 | }, 94 | "error-ex": { 95 | "version": "1.3.2", 96 | "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", 97 | "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", 98 | "dev": true, 99 | "requires": { 100 | "is-arrayish": "^0.2.1" 101 | } 102 | }, 103 | "esprima": { 104 | "version": "4.0.1", 105 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 106 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 107 | "dev": true 108 | }, 109 | "execa": { 110 | "version": "1.0.0", 111 | "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", 112 | "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", 113 | "dev": true, 114 | "requires": { 115 | "cross-spawn": "^6.0.0", 116 | "get-stream": "^4.0.0", 117 | "is-stream": "^1.1.0", 118 | "npm-run-path": "^2.0.0", 119 | "p-finally": "^1.0.0", 120 | "signal-exit": "^3.0.0", 121 | "strip-eof": "^1.0.0" 122 | } 123 | }, 124 | "find-up": { 125 | "version": "3.0.0", 126 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", 127 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", 128 | "dev": true, 129 | "requires": { 130 | "locate-path": "^3.0.0" 131 | } 132 | }, 133 | "get-stdin": { 134 | "version": "6.0.0", 135 | "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", 136 | "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", 137 | "dev": true 138 | }, 139 | "get-stream": { 140 | "version": "4.1.0", 141 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", 142 | "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", 143 | "dev": true, 144 | "requires": { 145 | "pump": "^3.0.0" 146 | } 147 | }, 148 | "graphql": { 149 | "version": "14.1.1", 150 | "resolved": "https://registry.npmjs.org/graphql/-/graphql-14.1.1.tgz", 151 | "integrity": "sha512-C5zDzLqvfPAgTtP8AUPIt9keDabrdRAqSWjj2OPRKrKxI9Fb65I36s1uCs1UUBFnSWTdO7hyHi7z1ZbwKMKF6Q==", 152 | "requires": { 153 | "iterall": "^1.2.2" 154 | } 155 | }, 156 | "hosted-git-info": { 157 | "version": "2.7.1", 158 | "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", 159 | "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", 160 | "dev": true 161 | }, 162 | "husky": { 163 | "version": "1.3.1", 164 | "resolved": "https://registry.npmjs.org/husky/-/husky-1.3.1.tgz", 165 | "integrity": "sha512-86U6sVVVf4b5NYSZ0yvv88dRgBSSXXmHaiq5pP4KDj5JVzdwKgBjEtUPOm8hcoytezFwbU+7gotXNhpHdystlg==", 166 | "dev": true, 167 | "requires": { 168 | "cosmiconfig": "^5.0.7", 169 | "execa": "^1.0.0", 170 | "find-up": "^3.0.0", 171 | "get-stdin": "^6.0.0", 172 | "is-ci": "^2.0.0", 173 | "pkg-dir": "^3.0.0", 174 | "please-upgrade-node": "^3.1.1", 175 | "read-pkg": "^4.0.1", 176 | "run-node": "^1.0.0", 177 | "slash": "^2.0.0" 178 | } 179 | }, 180 | "import-fresh": { 181 | "version": "2.0.0", 182 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", 183 | "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", 184 | "dev": true, 185 | "requires": { 186 | "caller-path": "^2.0.0", 187 | "resolve-from": "^3.0.0" 188 | } 189 | }, 190 | "is-arrayish": { 191 | "version": "0.2.1", 192 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", 193 | "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", 194 | "dev": true 195 | }, 196 | "is-ci": { 197 | "version": "2.0.0", 198 | "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", 199 | "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", 200 | "dev": true, 201 | "requires": { 202 | "ci-info": "^2.0.0" 203 | } 204 | }, 205 | "is-directory": { 206 | "version": "0.3.1", 207 | "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", 208 | "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", 209 | "dev": true 210 | }, 211 | "is-stream": { 212 | "version": "1.1.0", 213 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", 214 | "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", 215 | "dev": true 216 | }, 217 | "isexe": { 218 | "version": "2.0.0", 219 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 220 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 221 | "dev": true 222 | }, 223 | "iterall": { 224 | "version": "1.2.2", 225 | "resolved": "https://registry.npmjs.org/iterall/-/iterall-1.2.2.tgz", 226 | "integrity": "sha512-yynBb1g+RFUPY64fTrFv7nsjRrENBQJaX2UL+2Szc9REFrSNm1rpSXHGzhmAy7a9uv3vlvgBlXnf9RqmPH1/DA==" 227 | }, 228 | "js-yaml": { 229 | "version": "3.12.1", 230 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", 231 | "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", 232 | "dev": true, 233 | "requires": { 234 | "argparse": "^1.0.7", 235 | "esprima": "^4.0.0" 236 | } 237 | }, 238 | "json-parse-better-errors": { 239 | "version": "1.0.2", 240 | "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", 241 | "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", 242 | "dev": true 243 | }, 244 | "locate-path": { 245 | "version": "3.0.0", 246 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", 247 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", 248 | "dev": true, 249 | "requires": { 250 | "p-locate": "^3.0.0", 251 | "path-exists": "^3.0.0" 252 | } 253 | }, 254 | "lodash.get": { 255 | "version": "4.4.2", 256 | "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", 257 | "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", 258 | "dev": true 259 | }, 260 | "nice-try": { 261 | "version": "1.0.5", 262 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 263 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", 264 | "dev": true 265 | }, 266 | "normalize-package-data": { 267 | "version": "2.5.0", 268 | "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", 269 | "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", 270 | "dev": true, 271 | "requires": { 272 | "hosted-git-info": "^2.1.4", 273 | "resolve": "^1.10.0", 274 | "semver": "2 || 3 || 4 || 5", 275 | "validate-npm-package-license": "^3.0.1" 276 | } 277 | }, 278 | "npm-run-path": { 279 | "version": "2.0.2", 280 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", 281 | "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", 282 | "dev": true, 283 | "requires": { 284 | "path-key": "^2.0.0" 285 | } 286 | }, 287 | "once": { 288 | "version": "1.4.0", 289 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 290 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 291 | "dev": true, 292 | "requires": { 293 | "wrappy": "1" 294 | } 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 | "dev": true 301 | }, 302 | "p-limit": { 303 | "version": "2.1.0", 304 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", 305 | "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", 306 | "dev": true, 307 | "requires": { 308 | "p-try": "^2.0.0" 309 | } 310 | }, 311 | "p-locate": { 312 | "version": "3.0.0", 313 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", 314 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", 315 | "dev": true, 316 | "requires": { 317 | "p-limit": "^2.0.0" 318 | } 319 | }, 320 | "p-try": { 321 | "version": "2.0.0", 322 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", 323 | "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", 324 | "dev": true 325 | }, 326 | "parse-json": { 327 | "version": "4.0.0", 328 | "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", 329 | "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", 330 | "dev": true, 331 | "requires": { 332 | "error-ex": "^1.3.1", 333 | "json-parse-better-errors": "^1.0.1" 334 | } 335 | }, 336 | "path-exists": { 337 | "version": "3.0.0", 338 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 339 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 340 | "dev": true 341 | }, 342 | "path-key": { 343 | "version": "2.0.1", 344 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 345 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", 346 | "dev": true 347 | }, 348 | "path-parse": { 349 | "version": "1.0.6", 350 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 351 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", 352 | "dev": true 353 | }, 354 | "pify": { 355 | "version": "3.0.0", 356 | "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", 357 | "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", 358 | "dev": true 359 | }, 360 | "pkg-dir": { 361 | "version": "3.0.0", 362 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", 363 | "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", 364 | "dev": true, 365 | "requires": { 366 | "find-up": "^3.0.0" 367 | } 368 | }, 369 | "please-upgrade-node": { 370 | "version": "3.1.1", 371 | "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz", 372 | "integrity": "sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ==", 373 | "dev": true, 374 | "requires": { 375 | "semver-compare": "^1.0.0" 376 | } 377 | }, 378 | "prettier": { 379 | "version": "1.18.2", 380 | "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz", 381 | "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==", 382 | "dev": true 383 | }, 384 | "pump": { 385 | "version": "3.0.0", 386 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", 387 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", 388 | "dev": true, 389 | "requires": { 390 | "end-of-stream": "^1.1.0", 391 | "once": "^1.3.1" 392 | } 393 | }, 394 | "read-pkg": { 395 | "version": "4.0.1", 396 | "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", 397 | "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", 398 | "dev": true, 399 | "requires": { 400 | "normalize-package-data": "^2.3.2", 401 | "parse-json": "^4.0.0", 402 | "pify": "^3.0.0" 403 | } 404 | }, 405 | "resolve": { 406 | "version": "1.10.0", 407 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", 408 | "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", 409 | "dev": true, 410 | "requires": { 411 | "path-parse": "^1.0.6" 412 | } 413 | }, 414 | "resolve-from": { 415 | "version": "3.0.0", 416 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", 417 | "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", 418 | "dev": true 419 | }, 420 | "run-node": { 421 | "version": "1.0.0", 422 | "resolved": "https://registry.npmjs.org/run-node/-/run-node-1.0.0.tgz", 423 | "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==", 424 | "dev": true 425 | }, 426 | "semver": { 427 | "version": "5.6.0", 428 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", 429 | "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", 430 | "dev": true 431 | }, 432 | "semver-compare": { 433 | "version": "1.0.0", 434 | "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", 435 | "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", 436 | "dev": true 437 | }, 438 | "shebang-command": { 439 | "version": "1.2.0", 440 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 441 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 442 | "dev": true, 443 | "requires": { 444 | "shebang-regex": "^1.0.0" 445 | } 446 | }, 447 | "shebang-regex": { 448 | "version": "1.0.0", 449 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 450 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 451 | "dev": true 452 | }, 453 | "signal-exit": { 454 | "version": "3.0.2", 455 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 456 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 457 | "dev": true 458 | }, 459 | "slash": { 460 | "version": "2.0.0", 461 | "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", 462 | "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", 463 | "dev": true 464 | }, 465 | "spdx-correct": { 466 | "version": "3.1.0", 467 | "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", 468 | "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", 469 | "dev": true, 470 | "requires": { 471 | "spdx-expression-parse": "^3.0.0", 472 | "spdx-license-ids": "^3.0.0" 473 | } 474 | }, 475 | "spdx-exceptions": { 476 | "version": "2.2.0", 477 | "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", 478 | "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", 479 | "dev": true 480 | }, 481 | "spdx-expression-parse": { 482 | "version": "3.0.0", 483 | "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", 484 | "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", 485 | "dev": true, 486 | "requires": { 487 | "spdx-exceptions": "^2.1.0", 488 | "spdx-license-ids": "^3.0.0" 489 | } 490 | }, 491 | "spdx-license-ids": { 492 | "version": "3.0.3", 493 | "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", 494 | "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", 495 | "dev": true 496 | }, 497 | "sprintf-js": { 498 | "version": "1.0.3", 499 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 500 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 501 | "dev": true 502 | }, 503 | "strip-eof": { 504 | "version": "1.0.0", 505 | "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", 506 | "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", 507 | "dev": true 508 | }, 509 | "validate-npm-package-license": { 510 | "version": "3.0.4", 511 | "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", 512 | "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", 513 | "dev": true, 514 | "requires": { 515 | "spdx-correct": "^3.0.0", 516 | "spdx-expression-parse": "^3.0.0" 517 | } 518 | }, 519 | "which": { 520 | "version": "1.3.1", 521 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 522 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 523 | "dev": true, 524 | "requires": { 525 | "isexe": "^2.0.0" 526 | } 527 | }, 528 | "wrappy": { 529 | "version": "1.0.2", 530 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 531 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 532 | "dev": true 533 | } 534 | } 535 | } 536 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "easygraphql-tracing", 3 | "version": "0.0.3", 4 | "description": "Get a tracing of your GraphQL resolvers", 5 | "main": "index.js", 6 | "scripts": { 7 | "prettier:check": "prettier --write './{lib,test,utils}/**/*.{js,graphql}'", 8 | "prettier:format": "prettier --write './{lib,test,utils}/**/*.{js,graphql}'", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "husky": { 12 | "hooks": { 13 | "pre-commit": "npm run prettier:format && git add ." 14 | } 15 | }, 16 | "keywords": [], 17 | "homepage": "https://github.com/EasyGraphQL/easygraphql-tracing", 18 | "author": { 19 | "name": "EasyGraphQL", 20 | "url": "https://github.com/EasyGraphQL" 21 | }, 22 | "repository": { 23 | "type": "git", 24 | "url": "https://github.com/EasyGraphQL/easygraphql-tracing" 25 | }, 26 | "bugs": { 27 | "url": "https://github.com/EasyGraphQL/easygraphql-tracing" 28 | }, 29 | "license": "MIT", 30 | "peerDependencies": { 31 | "graphql": "^14.0.0" 32 | }, 33 | "dependencies": { 34 | "graphql": "^14.0.2", 35 | "cli-table": "^0.3.1" 36 | }, 37 | "devDependencies": { 38 | "husky": "^1.2.1", 39 | "prettier": "^1.18.2" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /result.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EasyGraphQL/easygraphql-tracing/d0e820ea0e8eaaa7ca89d3894209c600e2a15a93/result.gif --------------------------------------------------------------------------------