From 7aa9a6b4f7548f989c747bdb9da386f1cb7b1f3c Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Thu, 1 Nov 2018 22:05:04 +0000 Subject: [PATCH] feat: upgraded apollo-server-express, logging extension (#2058) --- package-lock.json | 424 +++++++++++++++--- package.json | 3 +- src/core/server/graph/common/context.ts | 14 +- .../common/middleware/extensions/logger.ts | 42 ++ .../server/graph/common/middleware/index.ts | 46 +- src/core/server/graph/management/context.ts | 2 +- src/core/server/graph/tenant/context.ts | 16 +- 7 files changed, 465 insertions(+), 82 deletions(-) create mode 100644 src/core/server/graph/common/middleware/extensions/logger.ts diff --git a/package-lock.json b/package-lock.json index 22605c63f..5973c0a88 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,21 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@apollographql/apollo-upload-server": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/@apollographql/apollo-upload-server/-/apollo-upload-server-5.0.3.tgz", + "integrity": "sha512-tGAp3ULNyoA8b5o9LsU2Lq6SwgVPUOKAqKywu2liEtTvrFSGPrObwanhYwArq3GPeOqp2bi+JknSJCIU3oQN1Q==", + "requires": { + "@babel/runtime-corejs2": "^7.0.0-rc.1", + "busboy": "^0.2.14", + "object-path": "^0.11.4" + } + }, + "@apollographql/graphql-playground-html": { + "version": "1.6.4", + "resolved": "https://registry.npmjs.org/@apollographql/graphql-playground-html/-/graphql-playground-html-1.6.4.tgz", + "integrity": "sha512-gwvaQO6/Hv4DEwhDLmmu2tzCU9oPjC5Xl9Kk8Yd0IxyKhYLlLalmkMMjsZLzU5H3fGaalLD96OYfxHL0ClVUDQ==" + }, "@babel/code-frame": { "version": "7.0.0-beta.49", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.49.tgz", @@ -1281,6 +1296,22 @@ } } }, + "@babel/runtime-corejs2": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.1.2.tgz", + "integrity": "sha512-drxaPByExlcRDKW4ZLubUO4ZkI8/8ax9k9wve1aEthdLKFzjB7XRkOQ0xoTIWGxqdDnWDElkjYq77bt7yrcYJQ==", + "requires": { + "core-js": "^2.5.7", + "regenerator-runtime": "^0.12.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", + "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==" + } + } + }, "@babel/template": { "version": "7.0.0-beta.49", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.49.tgz", @@ -1563,6 +1594,60 @@ "integrity": "sha512-LAQ1d4OPfSJ/BMbI2DuizmYrrkD9JMaTdi2hQTlI53lQ4kRQPyZQRS4CYQ7O66bnBBnP/oYdRxbk++X0xuFU6A==", "dev": true }, + "@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha1-m4sMxmPWaafY9vXQiToU00jzD78=" + }, + "@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + }, + "@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + }, + "@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha1-NVy8mLr61ZePntCV85diHx0Ga3A=" + }, + "@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU=", + "requires": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E=" + }, + "@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik=" + }, + "@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha1-bMKyDFya1q0NzP0hynZz2Nf79o0=" + }, + "@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q=" + }, + "@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA=" + }, "@samverschueren/stream-to-observable": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", @@ -1634,6 +1719,14 @@ "integrity": "sha512-D7VxhADdZbDJ0HjUTMnSQ5xIGb4H2yWpg8k9Sf1T08zfFiQYlaxM8LZydpR4FQ2E6LZJX8IlabNZ5io4vdChwg==", "dev": true }, + "@types/accepts": { + "version": "1.3.5", + "resolved": "http://registry.npmjs.org/@types/accepts/-/accepts-1.3.5.tgz", + "integrity": "sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ==", + "requires": { + "@types/node": "*" + } + }, "@types/bcryptjs": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/@types/bcryptjs/-/bcryptjs-2.4.1.tgz", @@ -1776,7 +1869,6 @@ "version": "2.8.4", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.4.tgz", "integrity": "sha512-ipZjBVsm2tF/n8qFGOuGBkUij9X9ZswVi9G3bx/6dz7POpVa6gVHcj1wsX/LVEn9MMF41fxK/PnZPPoTD1UFPw==", - "dev": true, "requires": { "@types/express": "*" } @@ -1995,6 +2087,11 @@ "integrity": "sha512-jDD7sendv3V7iwyRXSlECOR8HCtMN2faVA9ngLdHHihSVIwY7nbfsKl2kA6fimUDU1i5l/zgpG3aevwWnN3zCQ==", "dev": true }, + "@types/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", + "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==" + }, "@types/luxon": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-0.5.3.tgz", @@ -2349,7 +2446,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-5.1.2.tgz", "integrity": "sha512-NkTXUKTYdXdnPE2aUUbGOXE1XfMK527SCvU/9bj86kyFF6kZ9ZnOQ3mK5jADn98Y2vEUD/7wKDgZa7Qst2wYOg==", - "dev": true, "requires": { "@types/events": "*", "@types/node": "*" @@ -2963,11 +3059,41 @@ } }, "apollo-cache-control": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.1.1.tgz", - "integrity": "sha512-XJQs167e9u+e5ybSi51nGYr70NPBbswdvTEHtbtXbwkZ+n9t0SLPvUcoqceayOSwjK1XYOdU/EKPawNdb3rLQA==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/apollo-cache-control/-/apollo-cache-control-0.2.5.tgz", + "integrity": "sha512-xEDrUvo3U2mQKSzA8NzQmgeqK4ytwFnTGl2YKGKPfG0+r8fZdswKp6CDBue29KLO8KkSuqW/hntveWrAdK51FQ==", "requires": { - "graphql-extensions": "^0.0.x" + "apollo-server-env": "^2.0.3", + "graphql-extensions": "^0.2.1" + } + }, + "apollo-datasource": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/apollo-datasource/-/apollo-datasource-0.1.3.tgz", + "integrity": "sha512-yEGEe5Cjzqqu5ml1VV3O8+C+thzdknZri9Ny0P3daTGNO+45J3vBOMcmaANeeI2+OOeWxdqUNa5aPOx/35kniw==", + "requires": { + "apollo-server-caching": "0.1.2", + "apollo-server-env": "2.0.3" + } + }, + "apollo-engine-reporting": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/apollo-engine-reporting/-/apollo-engine-reporting-0.0.6.tgz", + "integrity": "sha512-JmfNJ9v3QEJQ8ZhLfCKEDiww53n5kj5HarP85p8LreoYNojbvcWN8Qm6RgvSG5N/ZJrAYHeTRQbSxm1vWwGubw==", + "requires": { + "apollo-engine-reporting-protobuf": "^0.0.1", + "apollo-server-env": "^2.0.3", + "async-retry": "^1.2.1", + "graphql-extensions": "^0.2.1", + "lodash": "^4.17.10" + } + }, + "apollo-engine-reporting-protobuf": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/apollo-engine-reporting-protobuf/-/apollo-engine-reporting-protobuf-0.0.1.tgz", + "integrity": "sha512-AySoDgog2p1Nph44FyyqaU4AfRZOXx8XZxRsVHvYY4dHlrMmDDhhjfF3Jswa7Wr8X/ivvx3xA0jimRn6rsG8Ew==", + "requires": { + "protobufjs": "^6.8.6" } }, "apollo-link": { @@ -2987,36 +3113,122 @@ } } }, - "apollo-server-core": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-1.3.6.tgz", - "integrity": "sha1-CGNiQ8LeVvqMJn1o3WAssfvTI+M=", + "apollo-server-caching": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/apollo-server-caching/-/apollo-server-caching-0.1.2.tgz", + "integrity": "sha512-jBRnsTgXN0m8yVpumoelaUq9mXR7YpJ3EE+y/alI7zgXY+0qFDqksRApU8dEfg3q6qUnO7rFxRhdG5eyc0+1ig==", "requires": { - "apollo-cache-control": "^0.1.0", - "apollo-tracing": "^0.1.0", - "graphql-extensions": "^0.0.x" + "lru-cache": "^4.1.3" } }, + "apollo-server-core": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/apollo-server-core/-/apollo-server-core-2.1.0.tgz", + "integrity": "sha512-D1Tw0o3NzCQ2KGM8EWh9AHELHmn/SE361dtlqJxkbelxXqAkCIGIFywF30h+0ezhMbgbO7eqBBJfvRilF/oJHA==", + "requires": { + "@apollographql/apollo-upload-server": "^5.0.3", + "@types/ws": "^5.1.2", + "apollo-cache-control": "^0.2.5", + "apollo-datasource": "^0.1.3", + "apollo-engine-reporting": "^0.0.6", + "apollo-server-caching": "^0.1.2", + "apollo-server-env": "^2.0.3", + "apollo-server-errors": "^2.0.2", + "apollo-tracing": "^0.2.5", + "graphql-extensions": "^0.2.1", + "graphql-subscriptions": "^0.5.8", + "graphql-tag": "^2.9.2", + "graphql-tools": "^3.0.4", + "hash.js": "^1.1.3", + "lodash": "^4.17.10", + "subscriptions-transport-ws": "^0.9.11", + "ws": "^5.2.0" + } + }, + "apollo-server-env": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/apollo-server-env/-/apollo-server-env-2.0.3.tgz", + "integrity": "sha512-uIfKFH8n8xKO0eLb9Fa79+s2DdMuVethgznvW6SrOYq5VzgkIIobqKEuZPKa5wObw9CkCyju/+Sr7b7WWMFxUQ==", + "requires": { + "node-fetch": "^2.1.2", + "util.promisify": "^1.0.0" + } + }, + "apollo-server-errors": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/apollo-server-errors/-/apollo-server-errors-2.0.2.tgz", + "integrity": "sha512-zyWDqAVDCkj9espVsoUpZr9PwDznM8UW6fBfhV+i1br//s2AQb07N6ektZ9pRIEvkhykDZW+8tQbDwAO0vUROg==" + }, "apollo-server-express": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-1.3.6.tgz", - "integrity": "sha1-ISCwUCGofe9E+v2EbooOKjKFLbc=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/apollo-server-express/-/apollo-server-express-2.1.0.tgz", + "integrity": "sha512-jLFIz1VLduMA/rme4OAy3IPeoaMEZOPoQXpio8AhfjIqCijRPPfoWJ2QMqz56C/g3vas7rZtgcVOrHpjBKudjw==", "requires": { - "apollo-server-core": "^1.3.6", - "apollo-server-module-graphiql": "^1.3.4" + "@apollographql/apollo-upload-server": "^5.0.3", + "@apollographql/graphql-playground-html": "^1.6.0", + "@types/accepts": "^1.3.5", + "@types/body-parser": "1.17.0", + "@types/cors": "^2.8.4", + "@types/express": "4.16.0", + "accepts": "^1.3.5", + "apollo-server-core": "^2.1.0", + "body-parser": "^1.18.3", + "cors": "^2.8.4", + "graphql-subscriptions": "^0.5.8", + "graphql-tools": "^3.0.4", + "type-is": "^1.6.16" + }, + "dependencies": { + "body-parser": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz", + "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=", + "requires": { + "bytes": "3.0.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "~1.6.3", + "iconv-lite": "0.4.23", + "on-finished": "~2.3.0", + "qs": "6.5.2", + "raw-body": "2.3.3", + "type-is": "~1.6.16" + } + }, + "iconv-lite": { + "version": "0.4.23", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", + "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + }, + "raw-body": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", + "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.3", + "iconv-lite": "0.4.23", + "unpipe": "1.0.0" + } + } } }, - "apollo-server-module-graphiql": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/apollo-server-module-graphiql/-/apollo-server-module-graphiql-1.3.4.tgz", - "integrity": "sha1-UDmbfFG3Jn0MhBUp9Rc+X8cwTeQ=" - }, "apollo-tracing": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.1.4.tgz", - "integrity": "sha512-Uv+1nh5AsNmC3m130i2u3IqbS+nrxyVV3KYimH5QKsdPjxxIQB3JAT+jJmpeDxBel8gDVstNmCh82QSLxLSIdQ==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/apollo-tracing/-/apollo-tracing-0.2.5.tgz", + "integrity": "sha512-DZO7pfL5LATHeJdVFoTZ/N3HwA+IMf1YnIt5K+uMQW+/MrRgYOtTszUv5tYX2cUIqHYHcbdDaBQUuIXwSpaV2Q==", "requires": { - "graphql-extensions": "~0.0.9" + "apollo-server-env": "^2.0.3", + "graphql-extensions": "^0.2.1" } }, "apollo-utilities": { @@ -3383,6 +3595,14 @@ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" }, + "async-retry": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.2.3.tgz", + "integrity": "sha512-tfDb02Th6CE6pJUF2gjW5ZVjsgwlucVXOEQMvEX9JgSJMs9gAX+Nz3xRuJBKuUYjTSYORqvDBORdAQ3LU59g7Q==", + "requires": { + "retry": "0.12.0" + } + }, "async-settle": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", @@ -5716,7 +5936,8 @@ "buffer-from": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", - "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==" + "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", + "dev": true }, "buffer-indexof": { "version": "1.1.1", @@ -5772,6 +5993,38 @@ "resolved": "https://registry.npmjs.org/bunyan-prettystream/-/bunyan-prettystream-0.1.3.tgz", "integrity": "sha1-bDtxMmb2rTIAfHtqsemYokU0nZg=" }, + "busboy": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz", + "integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=", + "requires": { + "dicer": "0.2.5", + "readable-stream": "1.1.x" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -8083,6 +8336,38 @@ "kuler": "1.0.x" } }, + "dicer": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz", + "integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=", + "requires": { + "readable-stream": "1.1.x", + "streamsearch": "0.1.2" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "diff": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", @@ -9485,7 +9770,6 @@ "version": "1.12.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", - "dev": true, "requires": { "es-to-primitive": "^1.1.1", "function-bind": "^1.1.1", @@ -9498,7 +9782,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", - "dev": true, "requires": { "is-callable": "^1.1.1", "is-date-object": "^1.0.1", @@ -11232,8 +11515,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" }, "function.prototype.name": { "version": "1.1.0", @@ -11644,12 +11926,11 @@ } }, "graphql-extensions": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.0.10.tgz", - "integrity": "sha512-TnQueqUDCYzOSrpQb3q1ngDSP2otJSF+9yNLrQGPzkMsvnQ+v6e2d5tl+B35D4y+XpmvVnAn4T3ZK28mkILveA==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/graphql-extensions/-/graphql-extensions-0.2.1.tgz", + "integrity": "sha512-/1FTPSWSffDjlRyMAV2UwQhojLmca9aQD0ieo1IYiqT5SE+uOWi4r83QF1CoER0sREIsH3s+nTmdH3cvQVG3MA==", "requires": { - "core-js": "^2.5.3", - "source-map-support": "^0.5.1" + "apollo-server-env": "^2.0.3" } }, "graphql-fields": { @@ -11722,6 +12003,11 @@ "iterall": "^1.2.1" } }, + "graphql-tag": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/graphql-tag/-/graphql-tag-2.10.0.tgz", + "integrity": "sha512-9FD6cw976TLLf9WYIUPCaaTpniawIjHWZSwIRZSjrfufJamcXbVVYfN2TWvJYbw0Xf2JjYbl1/f2+wDnBVw3/w==" + }, "graphql-tools": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-3.0.5.tgz", @@ -12204,7 +12490,6 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, "requires": { "function-bind": "^1.1.1" } @@ -12273,7 +12558,6 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.4.tgz", "integrity": "sha512-A6RlQvvZEtFS5fLU43IDu0QUmBy+fDO9VMdTXvufKwIkt/rFfvICAViCax5fbDO4zdNzaC3/27ZhKUok5bAJyw==", - "dev": true, "requires": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.0" @@ -13247,8 +13531,7 @@ "is-callable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", - "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", - "dev": true + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=" }, "is-ci": { "version": "1.1.0", @@ -13280,8 +13563,7 @@ "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" }, "is-decimal": { "version": "1.0.2", @@ -13548,7 +13830,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, "requires": { "has": "^1.0.1" } @@ -13618,8 +13899,7 @@ "is-symbol": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=" }, "is-there": { "version": "4.4.3", @@ -16978,7 +17258,6 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", - "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" @@ -17441,8 +17720,7 @@ "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, "minimalistic-crypto-utils": { "version": "1.0.1", @@ -18232,6 +18510,11 @@ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==" }, + "object-path": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", + "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=" + }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -18291,7 +18574,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "dev": true, "requires": { "define-properties": "^1.1.2", "es-abstract": "^1.5.1" @@ -21345,6 +21627,33 @@ } } }, + "protobufjs": { + "version": "6.8.8", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", + "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.0", + "@types/node": "^10.1.0", + "long": "^4.0.0" + }, + "dependencies": { + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + } + } + }, "proxy-addr": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", @@ -23187,6 +23496,11 @@ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=" + }, "right-align": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", @@ -23878,6 +24192,7 @@ "version": "0.5.6", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz", "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==", + "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" @@ -23886,7 +24201,8 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true } } }, @@ -24132,6 +24448,11 @@ "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", "dev": true }, + "streamsearch": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz", + "integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo=" + }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -26026,7 +26347,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", - "dev": true, "requires": { "define-properties": "^1.1.2", "object.getownpropertydescriptors": "^2.0.3" diff --git a/package.json b/package.json index 4a4f4d4c0..8d3e07e9c 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "license": "Apache-2.0", "dependencies": { "akismet-api": "^4.2.0", - "apollo-server-express": "^1.3.6", + "apollo-server-express": "^2.1.0", "bcryptjs": "^2.4.3", "bull": "^3.4.4", "bunyan": "^1.8.12", @@ -67,6 +67,7 @@ "fs-extra": "^6.0.1", "graphql": "^0.13.2", "graphql-config": "^2.0.1", + "graphql-extensions": "^0.2.1", "graphql-fields": "^1.1.0", "graphql-playground-html": "^1.6.0", "graphql-redis-subscriptions": "^1.5.0", diff --git a/src/core/server/graph/common/context.ts b/src/core/server/graph/common/context.ts index 016aa37d6..e229e7f57 100644 --- a/src/core/server/graph/common/context.ts +++ b/src/core/server/graph/common/context.ts @@ -1,4 +1,7 @@ +import uuid from "uuid"; + import { Config } from "talk-common/config"; +import logger from "talk-server/logger"; import { User } from "talk-server/models/user"; import { Request } from "talk-server/types/express"; @@ -9,9 +12,14 @@ export interface CommonContextOptions { } export default class CommonContext { - public user?: User; - public req?: Request; - public config: Config; + public readonly user?: User; + public readonly req?: Request; + public readonly config: Config; + + public readonly logger = logger.child({ + context: "graph", + contextID: uuid.v4(), + }); constructor({ user, req, config }: CommonContextOptions) { this.user = user; diff --git a/src/core/server/graph/common/middleware/extensions/logger.ts b/src/core/server/graph/common/middleware/extensions/logger.ts new file mode 100644 index 000000000..76afbc750 --- /dev/null +++ b/src/core/server/graph/common/middleware/extensions/logger.ts @@ -0,0 +1,42 @@ +import { formatApolloErrors } from "apollo-server-errors"; +import { GraphQLError } from "graphql"; +import { GraphQLExtension, GraphQLResponse } from "graphql-extensions"; + +import CommonContext from "talk-server/graph/common/context"; + +export class LoggerExtension implements GraphQLExtension { + private logError = (ctx: CommonContext) => (err: Error) => { + if (err instanceof GraphQLError) { + ctx.logger.error({ err: err.originalError }, "graphql error"); + } else { + ctx.logger.error({ err }, "graphql query error"); + } + + return err; + }; + + public requestDidStart(o: { + operationName?: string; + context: CommonContext; + }) { + o.context.logger.debug({ operationName: o.operationName }, "graphql query"); + } + + public willSendResponse(o: { + graphqlResponse: GraphQLResponse; + context: CommonContext; + }): void | { graphqlResponse: GraphQLResponse; context: CommonContext } { + if (o.graphqlResponse.errors) { + return { + ...o, + graphqlResponse: { + ...o.graphqlResponse, + errors: formatApolloErrors(o.graphqlResponse.errors, { + formatter: this.logError(o.context), + debug: false, + }), + }, + }; + } + } +} diff --git a/src/core/server/graph/common/middleware/index.ts b/src/core/server/graph/common/middleware/index.ts index e7d47c292..ac3d451fb 100644 --- a/src/core/server/graph/common/middleware/index.ts +++ b/src/core/server/graph/common/middleware/index.ts @@ -1,11 +1,16 @@ -import { resolveGraphqlOptions } from "apollo-server-core"; +import { GraphQLOptions } from "apollo-server-express"; +import { Handler } from "express"; +import { FieldDefinitionNode, GraphQLError, ValidationContext } from "graphql"; + +// TODO: when https://github.com/apollographql/apollo-server/pull/1907 is merged, update this import path import { ExpressGraphQLOptionsFunction, graphqlExpress, - GraphQLOptions, -} from "apollo-server-express"; -import { FieldDefinitionNode, GraphQLError, ValidationContext } from "graphql"; +} from "apollo-server-express/dist/expressApollo"; + import { Config } from "talk-common/config"; +import { Omit } from "talk-common/types"; +import { LoggerExtension } from "talk-server/graph/common/middleware/extensions/logger"; // Sourced from: https://github.com/apollographql/apollo-server/blob/958846887598491fadea57b3f9373d129300f250/packages/apollo-server-core/src/ApolloServer.ts#L46-L57 const NoIntrospection = (context: ValidationContext) => ({ @@ -23,26 +28,33 @@ const NoIntrospection = (context: ValidationContext) => ({ export const graphqlMiddleware = ( config: Config, - baseOptions: GraphQLOptions | ExpressGraphQLOptionsFunction -) => { - // Generate the validation rules. - const validationRules: Array<(context: ValidationContext) => any> = []; + requestOptions: ExpressGraphQLOptionsFunction +): Handler => { + // Create a new baseOptions that will be merged into the new options. + const baseOptions: Omit = { + // Disable the debug mode, as we already add in our logging function. + debug: false, + // Include extensions. + extensions: [ + // Log queries and errors. + () => new LoggerExtension(), + ], + }; if (config.get("env") === "production" && !config.get("enable_graphiql")) { // Disable introspection in production. - validationRules.push(NoIntrospection); + baseOptions.validationRules = [NoIntrospection]; } // Generate the actual middleware. return graphqlExpress(async (req, res) => { - // Resolve the base options. - const requestOptions = await resolveGraphqlOptions(baseOptions, req, res); + // Resolve the options for the GraphQL middleware. + const options = await requestOptions(req, res); - // Apply the validators, sourced from: https://github.com/apollographql/apollo-server/blob/958846887598491fadea57b3f9373d129300f250/packages/apollo-server-core/src/ApolloServer.ts#L104-L107 - requestOptions.validationRules = requestOptions.validationRules - ? requestOptions.validationRules.concat(validationRules) - : validationRules; - - return requestOptions; + // Provide the options. + return { + ...options, + ...baseOptions, + }; }); }; diff --git a/src/core/server/graph/management/context.ts b/src/core/server/graph/management/context.ts index 41e59e094..a384d49b1 100644 --- a/src/core/server/graph/management/context.ts +++ b/src/core/server/graph/management/context.ts @@ -11,7 +11,7 @@ export interface ManagementContextOptions { } export default class ManagementContext extends CommonContext { - public mongo: Db; + public readonly mongo: Db; constructor({ req, mongo, config }: ManagementContextOptions) { super({ req, config }); diff --git a/src/core/server/graph/tenant/context.ts b/src/core/server/graph/tenant/context.ts index 3456e8029..d8785338b 100644 --- a/src/core/server/graph/tenant/context.ts +++ b/src/core/server/graph/tenant/context.ts @@ -24,14 +24,14 @@ export interface TenantContextOptions { } export default class TenantContext extends CommonContext { - public tenant: Tenant; - public tenantCache: TenantCache; - public user?: User; - public mongo: Db; - public redis: Redis; - public queue: TaskQueue; - public loaders: ReturnType; - public mutators: ReturnType; + public readonly tenant: Tenant; + public readonly tenantCache: TenantCache; + public readonly user?: User; + public readonly mongo: Db; + public readonly redis: Redis; + public readonly queue: TaskQueue; + public readonly loaders: ReturnType; + public readonly mutators: ReturnType; constructor({ req,