mirror of
https://github.com/vale981/apollo-server
synced 2025-03-05 09:41:40 -05:00
* feat(fastify) Apollo Fastify server integration resolve #626 * feat(fastify) Use createHandler instead of applyMiddleware #626 * feat(fastify) Fix integration test for node 10 #626 * feat(fastify) Update README's with fastify createHandler interface #626 * feat(fastify) Implement the fastify createHandler as a synchronous method #626 * (fastify) Tweaks to re-align with the parallel work in #2054. * (fastify): Use port 9999 rather than 8888 for tests. Because Gatsby. This specific port per integration is pretty brittle to begin with, but it does work. Currently, the fact that it works is facilitated by the fact that most people don't use 5555 (Hapi) and 6666 (Express) for anything. That said, the ever-popular Gatsby uses 8888 by default, so let's use 9999! * (fastify) Remove duplicative assertion in upload initialization. * (fastify) Implement fastify upload middleware * (fastify) Fix linting issues * (fastify) Update package-lock
This commit is contained in:
parent
7d5468800f
commit
069110b353
18 changed files with 1847 additions and 22 deletions
|
@ -44,6 +44,7 @@ client reference ID, Apollo Server will now default to the values present in the
|
|||
of the request (`apollographql-client-name`, `apollographql-client-reference-id` and
|
||||
`apollographql-client-version` respectively). As a last resort, when those headers are not set,
|
||||
the query extensions' `clientInfo` values will be used. [PR #1960](https://github.com/apollographql/apollo-server/pull/1960)
|
||||
- Added `apollo-server-fastify` integration ([@rkorrelboom](https://github.com/rkorrelboom) in [#1971](https://github.com/apollostack/apollo-server/pull/1971))
|
||||
|
||||
### v2.2.2
|
||||
|
||||
|
|
20
README.md
20
README.md
|
@ -86,6 +86,7 @@ Often times, Apollo Server needs to be run with a particular integration. To sta
|
|||
- `apollo-server-express`
|
||||
- `apollo-server-koa`
|
||||
- `apollo-server-hapi`
|
||||
- `apollo-server-fastify`
|
||||
- `apollo-server-lambda`
|
||||
- `apollo-server-azure-functions`
|
||||
- `apollo-server-cloud-functions`
|
||||
|
@ -235,6 +236,25 @@ new ApolloServer({
|
|||
})
|
||||
```
|
||||
|
||||
## Fastify
|
||||
|
||||
```js
|
||||
const { ApolloServer, gql } = require('apollo-server-fastify');
|
||||
const { typeDefs, resolvers } = require('./module');
|
||||
|
||||
const server = new ApolloServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
});
|
||||
|
||||
const app = require('fastify')();
|
||||
|
||||
(async function () {
|
||||
app.register(server.createHandler());
|
||||
await app.listen(3000);
|
||||
})();
|
||||
```
|
||||
|
||||
### AWS Lambda
|
||||
|
||||
Apollo Server can be run on Lambda and deployed with AWS Serverless Application Model (SAM). It requires an API Gateway with Lambda Proxy Integration.
|
||||
|
|
438
package-lock.json
generated
438
package-lock.json
generated
|
@ -77,7 +77,7 @@
|
|||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
@ -109,7 +109,7 @@
|
|||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
@ -1501,6 +1501,16 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/pino": {
|
||||
"version": "4.16.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/pino/-/pino-4.16.1.tgz",
|
||||
"integrity": "sha512-uYEhZ3jsuiYFsPcR34fbxVlrqzqphc+QQ3fU4rWR6PXH8ka2TKvPBjtkNqj8oBHouVGf4GCRfyPb7FG2TEtPZA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/events": "*",
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"@types/podium": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/podium/-/podium-1.0.0.tgz",
|
||||
|
@ -1616,6 +1626,12 @@
|
|||
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
|
||||
"dev": true
|
||||
},
|
||||
"abstract-logging": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/abstract-logging/-/abstract-logging-1.0.0.tgz",
|
||||
"integrity": "sha1-i33q/TEFWbwo93ck3RuzAXcnjBs=",
|
||||
"dev": true
|
||||
},
|
||||
"accept": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/accept/-/accept-3.0.2.tgz",
|
||||
|
@ -2246,6 +2262,17 @@
|
|||
"type-is": "^1.6.16"
|
||||
}
|
||||
},
|
||||
"apollo-server-fastify": {
|
||||
"version": "file:packages/apollo-server-fastify",
|
||||
"requires": {
|
||||
"@apollographql/graphql-playground-html": "^1.6.6",
|
||||
"apollo-server-core": "file:packages/apollo-server-core",
|
||||
"fastify-accepts": "^0.5.0",
|
||||
"fastify-cors": "^0.2.0",
|
||||
"graphql-subscriptions": "^1.0.0",
|
||||
"graphql-tools": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"apollo-server-hapi": {
|
||||
"version": "file:packages/apollo-server-hapi",
|
||||
"requires": {
|
||||
|
@ -2554,6 +2581,33 @@
|
|||
"integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
|
||||
"dev": true
|
||||
},
|
||||
"avvio": {
|
||||
"version": "5.9.0",
|
||||
"resolved": "https://registry.npmjs.org/avvio/-/avvio-5.9.0.tgz",
|
||||
"integrity": "sha512-bzgrSPRdU1T/AkhEuXWAA6cJCFA3zApLk+5fkpcQt4US9YAI52AFYnsGX1HSCF2bHSltEYfk7fbffYu4WnazmA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"debug": "^3.1.0",
|
||||
"fastq": "^1.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"debug": {
|
||||
"version": "3.2.6",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
|
@ -3342,7 +3396,7 @@
|
|||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
@ -4105,6 +4159,12 @@
|
|||
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
|
||||
"dev": true
|
||||
},
|
||||
"deepmerge": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.0.0.tgz",
|
||||
"integrity": "sha512-a8z8bkgHsAML+uHLqmMS83HHlpy3PvZOOuiTQqaa3wu8ZVg3h0hqHk6aCsGdOnZV2XMM/FRimNGjUh0KCcmHBw==",
|
||||
"dev": true
|
||||
},
|
||||
"default-require-extensions": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz",
|
||||
|
@ -4200,7 +4260,7 @@
|
|||
"dependencies": {
|
||||
"globby": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
|
||||
"resolved": "http://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
|
||||
"integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
@ -4213,7 +4273,7 @@
|
|||
"dependencies": {
|
||||
"pify": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
|
||||
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
|
||||
"dev": true
|
||||
}
|
||||
|
@ -4748,6 +4808,12 @@
|
|||
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-decode-uri-component": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-decode-uri-component/-/fast-decode-uri-component-1.0.0.tgz",
|
||||
"integrity": "sha512-WQSYVKn6tDW/3htASeUkrx5LcnuTENQIZQPCVlwdnvIJ7bYtSpoJYq38MgUJnx1CQIR1gjZ8HJxAEcN4gqugBg==",
|
||||
"dev": true
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
|
||||
|
@ -5080,17 +5146,157 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"fast-json-parse": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-parse/-/fast-json-parse-1.0.3.tgz",
|
||||
"integrity": "sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw==",
|
||||
"dev": true
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
|
||||
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
|
||||
},
|
||||
"fast-json-stringify": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-1.10.0.tgz",
|
||||
"integrity": "sha512-qO+GSdwCQHXJjoRbS/pYJzzz8BNUrCk0jdPhDg68mdIG/hOC0k66PUKFz300LAH42vNQkuPFvpwa0JV44ZG3Uw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.5.4",
|
||||
"deepmerge": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ajv": {
|
||||
"version": "6.6.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz",
|
||||
"integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^2.0.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
|
||||
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"fast-levenshtein": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-safe-stringify": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-1.2.3.tgz",
|
||||
"integrity": "sha512-QJYT/i0QYoiZBQ71ivxdyTqkwKkQ0oxACXHYxH2zYHJEgzi2LsbjgvtzTbLi1SZcF190Db2YP7I7eTsU2egOlw==",
|
||||
"dev": true
|
||||
},
|
||||
"fastify": {
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/fastify/-/fastify-1.13.0.tgz",
|
||||
"integrity": "sha512-0aqsHEk2WtgGxPVDTOqDLv5XLHQE2EuH7eCq4XRLLnktLehNvr3/Afi/nEn6pPoLiVGMrbWHv4l1+wDhiSIFoA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/pino": "^4.16.0",
|
||||
"abstract-logging": "^1.0.0",
|
||||
"ajv": "^6.5.4",
|
||||
"avvio": "^5.8.0",
|
||||
"end-of-stream": "^1.4.1",
|
||||
"fast-json-stringify": "^1.8.0",
|
||||
"find-my-way": "^1.15.3",
|
||||
"flatstr": "^1.0.8",
|
||||
"light-my-request": "^3.0.0",
|
||||
"middie": "^3.1.0",
|
||||
"pino": "^4.17.3",
|
||||
"proxy-addr": "^2.0.3",
|
||||
"tiny-lru": "^1.6.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ajv": {
|
||||
"version": "6.6.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz",
|
||||
"integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^2.0.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
|
||||
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"fastify-accepts": {
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/fastify-accepts/-/fastify-accepts-0.5.0.tgz",
|
||||
"integrity": "sha1-wXwgEnjyv8Ub+5P/5I78T8QP02M=",
|
||||
"requires": {
|
||||
"accepts": "^1.3.3",
|
||||
"fastify-plugin": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"fastify-cors": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fastify-cors/-/fastify-cors-0.2.0.tgz",
|
||||
"integrity": "sha512-bw14FmjHm8oF4TDLkwj2TpssH6O2gE0NpsRqLe7F1Gh9Jf30Lx9ZzIznhqaAKOYS+LJqLIt5snurv7urgqYntA==",
|
||||
"requires": {
|
||||
"fastify-plugin": "^1.2.0",
|
||||
"vary": "^1.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"fastify-plugin": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-1.4.0.tgz",
|
||||
"integrity": "sha512-l6uqDyBp3gBjLQRAi3j2NwSvlbe9LuqULZugnO9iRFfYHWd2SpsZBLI1l4Jakk0VMGfYlB322JPIPYh/2qSHig==",
|
||||
"requires": {
|
||||
"semver": "^5.5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fastify-plugin": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "http://registry.npmjs.org/fastify-plugin/-/fastify-plugin-0.2.2.tgz",
|
||||
"integrity": "sha512-oRJdjdudgCkQQUARNeh2rkbxFAmj2OhCJSVBNBLUbhS0orF+IMQ4u/bc661N1jh/wDI2J+YKmXmmHSVFQI4e7A==",
|
||||
"requires": {
|
||||
"semver": "^5.4.1"
|
||||
}
|
||||
},
|
||||
"fastq": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz",
|
||||
"integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"reusify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"fb-watchman": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz",
|
||||
|
@ -5179,6 +5385,17 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"find-my-way": {
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-1.17.0.tgz",
|
||||
"integrity": "sha512-V/ROUAESJakNZXmvgJmaCwhB8d4M79/RgWWiKn4tu/6FGjiySYfJuYXip1rV7fORWEzbL0pmfg9smkRQ+tmXjg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-decode-uri-component": "^1.0.0",
|
||||
"safe-regex": "^1.1.0",
|
||||
"semver-store": "^0.3.0"
|
||||
}
|
||||
},
|
||||
"find-npm-prefix": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/find-npm-prefix/-/find-npm-prefix-1.0.2.tgz",
|
||||
|
@ -5200,6 +5417,12 @@
|
|||
"locate-path": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"flatstr": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/flatstr/-/flatstr-1.0.9.tgz",
|
||||
"integrity": "sha512-qFlJnOBWDfIaunF54/lBqNKmXOI0HqNhu+mHkLmbaBXlS71PUd9OjFOdyevHt/aHoHB1+eW7eKHgRKOG5aHSpw==",
|
||||
"dev": true
|
||||
},
|
||||
"flush-write-stream": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz",
|
||||
|
@ -5423,7 +5646,8 @@
|
|||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"aproba": {
|
||||
"version": "1.2.0",
|
||||
|
@ -5447,13 +5671,15 @@
|
|||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
|
@ -5470,19 +5696,22 @@
|
|||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
|
||||
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"console-control-strings": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
|
||||
"integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
|
@ -5613,7 +5842,8 @@
|
|||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.5",
|
||||
|
@ -5627,6 +5857,7 @@
|
|||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
|
||||
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"number-is-nan": "^1.0.0"
|
||||
}
|
||||
|
@ -5643,6 +5874,7 @@
|
|||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
|
@ -5651,13 +5883,15 @@
|
|||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"minipass": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz",
|
||||
"integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.1.1",
|
||||
"yallist": "^3.0.0"
|
||||
|
@ -5678,6 +5912,7 @@
|
|||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
|
@ -5766,7 +6001,8 @@
|
|||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
|
||||
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"object-assign": {
|
||||
"version": "4.1.1",
|
||||
|
@ -5780,6 +6016,7 @@
|
|||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
|
@ -5875,7 +6112,8 @@
|
|||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
|
@ -5917,6 +6155,7 @@
|
|||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
|
||||
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"code-point-at": "^1.0.0",
|
||||
"is-fullwidth-code-point": "^1.0.0",
|
||||
|
@ -5938,6 +6177,7 @@
|
|||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"ansi-regex": "^2.0.0"
|
||||
}
|
||||
|
@ -5986,13 +6226,15 @@
|
|||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz",
|
||||
"integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=",
|
||||
"dev": true
|
||||
"dev": true,
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -8807,6 +9049,62 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"light-my-request": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/light-my-request/-/light-my-request-3.1.0.tgz",
|
||||
"integrity": "sha512-ZSFO3XnQNSKsHR/E2ZMga5btdiIa3sNoT6CZIZ8Hr1VHJWBNcRRurVYpQlaJqvQqwg3aOl09QpVOnjB9ajnYHQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.0.0",
|
||||
"readable-stream": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ajv": {
|
||||
"version": "6.6.2",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz",
|
||||
"integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^2.0.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
|
||||
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz",
|
||||
"integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"inherits": "^2.0.3",
|
||||
"string_decoder": "^1.1.1",
|
||||
"util-deprecate": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz",
|
||||
"integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "~5.1.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"version": "8.1.0",
|
||||
"resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-8.1.0.tgz",
|
||||
|
@ -9216,7 +9514,7 @@
|
|||
},
|
||||
"chalk": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
|
||||
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
@ -9248,7 +9546,7 @@
|
|||
},
|
||||
"strip-ansi": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
|
@ -9828,6 +10126,24 @@
|
|||
"regex-cache": "^0.4.2"
|
||||
}
|
||||
},
|
||||
"middie": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/middie/-/middie-3.2.0.tgz",
|
||||
"integrity": "sha512-anXJ0QJfQcgneQvcWAJBwVvNckRLI68zWNEUv/7/7z/Wb/UMFTHmugpM93T4Q75+DclC9FHdms8cTseDQEV3yA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-to-regexp": "^2.0.0",
|
||||
"reusify": "^1.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"path-to-regexp": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.4.0.tgz",
|
||||
"integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"mime": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
|
||||
|
@ -10877,6 +11193,41 @@
|
|||
"pinkie": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"pino": {
|
||||
"version": "4.17.6",
|
||||
"resolved": "https://registry.npmjs.org/pino/-/pino-4.17.6.tgz",
|
||||
"integrity": "sha512-LFDwmhyWLBnmwO/2UFbWu1jEGVDzaPupaVdx0XcZ3tIAx1EDEBauzxXf2S0UcFK7oe+X9MApjH0hx9U1XMgfCA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^2.4.1",
|
||||
"fast-json-parse": "^1.0.3",
|
||||
"fast-safe-stringify": "^1.2.3",
|
||||
"flatstr": "^1.0.5",
|
||||
"pino-std-serializers": "^2.0.0",
|
||||
"pump": "^3.0.0",
|
||||
"quick-format-unescaped": "^1.1.2",
|
||||
"split2": "^2.2.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"chalk": {
|
||||
"version": "2.4.1",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
|
||||
"integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"pino-std-serializers": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-2.3.0.tgz",
|
||||
"integrity": "sha512-klfGoOsP6sJH7ON796G4xoUSx2fkpFgKHO4YVVO2zmz31jR+etzc/QzGJILaOIiCD6HTCFgkPx+XN8nk+ruqPw==",
|
||||
"dev": true
|
||||
},
|
||||
"pkg-dir": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
|
||||
|
@ -11160,6 +11511,15 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"quick-format-unescaped": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-1.1.2.tgz",
|
||||
"integrity": "sha1-DKWB3jF0vs7yWsPC6JVjQjgdtpg=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-safe-stringify": "^1.0.8"
|
||||
}
|
||||
},
|
||||
"quick-lru": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz",
|
||||
|
@ -11552,6 +11912,12 @@
|
|||
"resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
|
||||
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs="
|
||||
},
|
||||
"reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
|
||||
"dev": true
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
|
||||
|
@ -11927,8 +12293,7 @@
|
|||
"semver": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
|
||||
"integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg=="
|
||||
},
|
||||
"semver-compare": {
|
||||
"version": "1.0.0",
|
||||
|
@ -11936,6 +12301,12 @@
|
|||
"integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=",
|
||||
"dev": true
|
||||
},
|
||||
"semver-store": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/semver-store/-/semver-store-0.3.0.tgz",
|
||||
"integrity": "sha512-TcZvGMMy9vodEFSse30lWinkj+JgOBvPn8wRItpQRSayhc+4ssDs335uklkfvQQJgL/WvmHLVj4Ycv2s7QCQMg==",
|
||||
"dev": true
|
||||
},
|
||||
"send": {
|
||||
"version": "0.16.2",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
|
||||
|
@ -12080,7 +12451,7 @@
|
|||
},
|
||||
"slice-ansi": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
|
||||
"resolved": "http://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
|
||||
"integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
|
||||
"dev": true
|
||||
},
|
||||
|
@ -12760,6 +13131,12 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"tiny-lru": {
|
||||
"version": "1.6.4",
|
||||
"resolved": "https://registry.npmjs.org/tiny-lru/-/tiny-lru-1.6.4.tgz",
|
||||
"integrity": "sha512-Et+J3Css66XPSLWjLF9wmgbECsGiExlEL+jxsFerTQF6N6dpxswDTPAfIrAbQKO5c1uhgq2xvo5zMk1W+kBDNA==",
|
||||
"dev": true
|
||||
},
|
||||
"tmp": {
|
||||
"version": "0.0.33",
|
||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
|
||||
|
@ -12907,7 +13284,7 @@
|
|||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||
"dev": true
|
||||
},
|
||||
|
@ -13161,6 +13538,23 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"uri-js": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
|
||||
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"punycode": "^2.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"urijs": {
|
||||
"version": "1.19.1",
|
||||
"resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.1.tgz",
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
"apollo-server-env": "file:packages/apollo-server-env",
|
||||
"apollo-server-errors": "file:packages/apollo-server-errors",
|
||||
"apollo-server-express": "file:packages/apollo-server-express",
|
||||
"apollo-server-fastify": "file:packages/apollo-server-fastify",
|
||||
"apollo-server-hapi": "file:packages/apollo-server-hapi",
|
||||
"apollo-server-integration-testsuite": "file:packages/apollo-server-integration-testsuite",
|
||||
"apollo-server-koa": "file:packages/apollo-server-koa",
|
||||
|
@ -94,6 +95,7 @@
|
|||
"codecov": "3.1.0",
|
||||
"connect": "3.6.6",
|
||||
"express": "4.16.4",
|
||||
"fastify": "1.13.0",
|
||||
"fibers": "3.1.1",
|
||||
"form-data": "2.3.3",
|
||||
"graphql": "14.1.1",
|
||||
|
|
6
packages/apollo-server-fastify/.npmignore
Normal file
6
packages/apollo-server-fastify/.npmignore
Normal file
|
@ -0,0 +1,6 @@
|
|||
*
|
||||
!src/**/*
|
||||
!dist/**/*
|
||||
dist/**/*.test.*
|
||||
!package.json
|
||||
!README.md
|
41
packages/apollo-server-fastify/README.md
Normal file
41
packages/apollo-server-fastify/README.md
Normal file
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
title: Fastify
|
||||
description: Setting up Apollo Server with Fastify
|
||||
---
|
||||
|
||||
[](https://badge.fury.io/js/apollo-server-fastify) [](https://circleci.com/gh/apollographql/apollo-server) [](https://coveralls.io/github/apollographql/apollo-server?branch=master) [](https://www.apollographql.com/#slack)
|
||||
|
||||
This is the Fastify integration of GraphQL Server. Apollo Server is a community-maintained open-source GraphQL server that works with many Node.js HTTP server frameworks. [Read the docs](https://www.apollographql.com/docs/apollo-server/). [Read the CHANGELOG.](https://github.com/apollographql/apollo-server/blob/master/CHANGELOG.md)
|
||||
|
||||
```sh
|
||||
npm install apollo-server-fastify
|
||||
```
|
||||
|
||||
## Fastify
|
||||
|
||||
```js
|
||||
const { ApolloServer, gql } = require('apollo-server-fastify');
|
||||
const { typeDefs, resolvers } = require('./module');
|
||||
|
||||
const server = new ApolloServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
});
|
||||
|
||||
const app = require('fastify')();
|
||||
|
||||
(async function () {
|
||||
app.register(server.createHandler());
|
||||
await app.listen(3000);
|
||||
})();
|
||||
```
|
||||
|
||||
## Principles
|
||||
|
||||
GraphQL Server is built with the following principles in mind:
|
||||
|
||||
* **By the community, for the community**: GraphQL Server's development is driven by the needs of developers
|
||||
* **Simplicity**: by keeping things simple, GraphQL Server is easier to use, easier to contribute to, and more secure
|
||||
* **Performance**: GraphQL Server is well-tested and production-ready - no modifications needed
|
||||
|
||||
Anyone is welcome to contribute to GraphQL Server, just read [CONTRIBUTING.md](https://github.com/apollographql/apollo-server/blob/master/CONTRIBUTING.md), take a look at the [roadmap](https://github.com/apollographql/apollo-server/blob/master/ROADMAP.md) and make your first PR!
|
3
packages/apollo-server-fastify/jest.config.js
Normal file
3
packages/apollo-server-fastify/jest.config.js
Normal file
|
@ -0,0 +1,3 @@
|
|||
const config = require('../../jest.config.base');
|
||||
|
||||
module.exports = Object.assign(Object.create(null), config);
|
41
packages/apollo-server-fastify/package.json
Normal file
41
packages/apollo-server-fastify/package.json
Normal file
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"name": "apollo-server-fastify",
|
||||
"version": "2.2.2",
|
||||
"description": "Production-ready Node.js GraphQL server for Fastify",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/apollographql/apollo-server/tree/master/packages/apollo-server-fastify"
|
||||
},
|
||||
"keywords": [
|
||||
"GraphQL",
|
||||
"Apollo",
|
||||
"Server",
|
||||
"Fastify",
|
||||
"Javascript"
|
||||
],
|
||||
"author": "opensource@apollographql.com",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/apollographql/apollo-server/issues"
|
||||
},
|
||||
"homepage": "https://github.com/apollographql/apollo-server#readme",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"dependencies": {
|
||||
"@apollographql/graphql-playground-html": "^1.6.6",
|
||||
"apollo-server-core": "file:../apollo-server-core",
|
||||
"fastify-accepts": "^0.5.0",
|
||||
"fastify-cors": "^0.2.0",
|
||||
"graphql-subscriptions": "^1.0.0",
|
||||
"graphql-tools": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"apollo-server-integration-testsuite": "file:../apollo-server-integration-testsuite"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"graphql": "^0.12.0 || ^0.13.0 || ^14.0.0"
|
||||
}
|
||||
}
|
191
packages/apollo-server-fastify/src/ApolloServer.ts
Normal file
191
packages/apollo-server-fastify/src/ApolloServer.ts
Normal file
|
@ -0,0 +1,191 @@
|
|||
import { renderPlaygroundPage } from '@apollographql/graphql-playground-html';
|
||||
import { Accepts } from 'accepts';
|
||||
import {
|
||||
ApolloServerBase,
|
||||
FileUploadOptions,
|
||||
formatApolloErrors,
|
||||
PlaygroundRenderPageOptions,
|
||||
processFileUploads,
|
||||
} from 'apollo-server-core';
|
||||
import { FastifyInstance, FastifyReply, FastifyRequest } from 'fastify';
|
||||
import { IncomingMessage, OutgoingMessage, Server } from 'http';
|
||||
import { graphqlFastify } from './fastifyApollo';
|
||||
|
||||
const kMultipart = Symbol('multipart');
|
||||
const fastJson = require('fast-json-stringify');
|
||||
|
||||
export interface ServerRegistration {
|
||||
path?: string;
|
||||
cors?: object | boolean;
|
||||
onHealthCheck?: (req: FastifyRequest<IncomingMessage>) => Promise<any>;
|
||||
disableHealthCheck?: boolean;
|
||||
}
|
||||
|
||||
const stringifyHealthCheck = fastJson({
|
||||
type: 'object',
|
||||
properties: {
|
||||
status: {
|
||||
type: 'string',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const fileUploadMiddleware = (
|
||||
uploadsConfig: FileUploadOptions,
|
||||
server: ApolloServerBase,
|
||||
) => (
|
||||
req: FastifyRequest<IncomingMessage>,
|
||||
reply: FastifyReply<OutgoingMessage>,
|
||||
done: (err: Error | null, body?: any) => void,
|
||||
) => {
|
||||
if (
|
||||
(req.req as any)[kMultipart] &&
|
||||
typeof processFileUploads === 'function'
|
||||
) {
|
||||
processFileUploads(req.req, reply.res, uploadsConfig)
|
||||
.then(body => {
|
||||
req.body = body;
|
||||
done(null);
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.status && error.expose) reply.status(error.status);
|
||||
|
||||
throw formatApolloErrors([error], {
|
||||
formatter: server.requestOptions.formatError,
|
||||
debug: server.requestOptions.debug,
|
||||
});
|
||||
});
|
||||
} else {
|
||||
done(null);
|
||||
}
|
||||
};
|
||||
|
||||
export class ApolloServer extends ApolloServerBase {
|
||||
protected supportsSubscriptions(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
protected supportsUploads(): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
public createHandler({
|
||||
path,
|
||||
cors,
|
||||
disableHealthCheck,
|
||||
onHealthCheck,
|
||||
}: ServerRegistration = {}) {
|
||||
this.graphqlPath = path ? path : '/graphql';
|
||||
const promiseWillStart = this.willStart();
|
||||
|
||||
return async (
|
||||
app: FastifyInstance<Server, IncomingMessage, OutgoingMessage>,
|
||||
) => {
|
||||
await promiseWillStart;
|
||||
|
||||
if (!disableHealthCheck) {
|
||||
app.get('/.well-known/apollo/server-health', async (req, res) => {
|
||||
// Response follows https://tools.ietf.org/html/draft-inadarei-api-health-check-01
|
||||
res.type('application/health+json');
|
||||
|
||||
if (onHealthCheck) {
|
||||
try {
|
||||
await onHealthCheck(req);
|
||||
res.send(stringifyHealthCheck({ status: 'pass' }));
|
||||
} catch (e) {
|
||||
res.status(503).send(stringifyHealthCheck({ status: 'fail' }));
|
||||
}
|
||||
} else {
|
||||
res.send(stringifyHealthCheck({ status: 'pass' }));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
app.register(
|
||||
async instance => {
|
||||
instance.register(require('fastify-accepts'));
|
||||
|
||||
if (cors === true) {
|
||||
instance.register(require('fastify-cors'));
|
||||
} else if (cors !== false) {
|
||||
instance.register(require('fastify-cors'), cors);
|
||||
}
|
||||
|
||||
instance.setNotFoundHandler((_request, reply) => {
|
||||
reply.code(405);
|
||||
reply.header('allow', 'GET, POST');
|
||||
reply.send();
|
||||
});
|
||||
|
||||
const beforeHandlers = [
|
||||
(
|
||||
req: FastifyRequest<IncomingMessage>,
|
||||
reply: FastifyReply<OutgoingMessage>,
|
||||
done: () => void,
|
||||
) => {
|
||||
// Note: if you enable playground in production and expect to be able to see your
|
||||
// schema, you'll need to manually specify `introspection: true` in the
|
||||
// ApolloServer constructor; by default, the introspection query is only
|
||||
// enabled in dev.
|
||||
if (this.playgroundOptions && req.req.method === 'GET') {
|
||||
// perform more expensive content-type check only if necessary
|
||||
const accept = (req as any).accepts() as Accepts;
|
||||
const types = accept.types() as string[];
|
||||
const prefersHTML =
|
||||
types.find(
|
||||
(x: string) =>
|
||||
x === 'text/html' || x === 'application/json',
|
||||
) === 'text/html';
|
||||
|
||||
if (prefersHTML) {
|
||||
const playgroundRenderPageOptions: PlaygroundRenderPageOptions = {
|
||||
endpoint: this.graphqlPath,
|
||||
subscriptionEndpoint: this.subscriptionsPath,
|
||||
...this.playgroundOptions,
|
||||
};
|
||||
reply.type('text/html');
|
||||
const playground = renderPlaygroundPage(
|
||||
playgroundRenderPageOptions,
|
||||
);
|
||||
reply.send(playground);
|
||||
return;
|
||||
}
|
||||
}
|
||||
done();
|
||||
},
|
||||
];
|
||||
|
||||
if (typeof processFileUploads === 'function' && this.uploadsConfig) {
|
||||
instance.addContentTypeParser(
|
||||
'multipart',
|
||||
(
|
||||
request: IncomingMessage,
|
||||
done: (err: Error | null, body?: any) => void,
|
||||
) => {
|
||||
(request as any)[kMultipart] = true;
|
||||
done(null);
|
||||
},
|
||||
);
|
||||
beforeHandlers.push(fileUploadMiddleware(this.uploadsConfig, this));
|
||||
}
|
||||
|
||||
instance.route({
|
||||
method: ['GET', 'POST'],
|
||||
url: '/',
|
||||
beforeHandler: beforeHandlers,
|
||||
handler: await graphqlFastify(this.graphQLServerOptions.bind(this)),
|
||||
});
|
||||
},
|
||||
{
|
||||
prefix: this.graphqlPath,
|
||||
},
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export const registerServer = () => {
|
||||
throw new Error(
|
||||
'Please use server.createHandler instead of registerServer. This warning will be removed in the next release',
|
||||
);
|
||||
};
|
|
@ -0,0 +1,836 @@
|
|||
import { FastifyInstance } from 'fastify';
|
||||
import fastify from 'fastify';
|
||||
|
||||
import http from 'http';
|
||||
|
||||
import request from 'request';
|
||||
import FormData from 'form-data';
|
||||
import fs from 'fs';
|
||||
import { createApolloFetch } from 'apollo-fetch';
|
||||
|
||||
import { gql, AuthenticationError, Config } from 'apollo-server-core';
|
||||
import { ApolloServer, ServerRegistration } from '../ApolloServer';
|
||||
|
||||
import {
|
||||
NODE_MAJOR_VERSION,
|
||||
testApolloServer,
|
||||
createServerInfo,
|
||||
} from 'apollo-server-integration-testsuite';
|
||||
|
||||
const typeDefs = gql`
|
||||
type Query {
|
||||
hello: String
|
||||
}
|
||||
`;
|
||||
|
||||
const resolvers = {
|
||||
Query: {
|
||||
hello: () => 'hi',
|
||||
},
|
||||
};
|
||||
|
||||
const port = 9999;
|
||||
|
||||
describe('apollo-server-fastify', () => {
|
||||
let server: ApolloServer;
|
||||
let httpServer: http.Server;
|
||||
let app: FastifyInstance;
|
||||
|
||||
testApolloServer(
|
||||
async options => {
|
||||
server = new ApolloServer(options);
|
||||
app = fastify();
|
||||
app.register(server.createHandler());
|
||||
await app.listen(port);
|
||||
return createServerInfo(server, app.server);
|
||||
},
|
||||
async () => {
|
||||
if (server) await server.stop();
|
||||
if (app) await new Promise(resolve => app.close(() => resolve()));
|
||||
if (httpServer && httpServer.listening) await httpServer.close();
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
describe('apollo-server-fastify', () => {
|
||||
let server: ApolloServer;
|
||||
let app: FastifyInstance;
|
||||
let httpServer: http.Server;
|
||||
|
||||
async function createServer(
|
||||
serverOptions: Config,
|
||||
options: Partial<ServerRegistration> = {},
|
||||
) {
|
||||
server = new ApolloServer(serverOptions);
|
||||
app = fastify();
|
||||
|
||||
app.register(server.createHandler(options));
|
||||
await app.listen(port);
|
||||
|
||||
return createServerInfo(server, app.server);
|
||||
}
|
||||
|
||||
afterEach(async () => {
|
||||
if (server) await server.stop();
|
||||
if (app) await new Promise(resolve => app.close(() => resolve()));
|
||||
if (httpServer) await httpServer.close();
|
||||
});
|
||||
|
||||
describe('constructor', async () => {
|
||||
it('accepts typeDefs and resolvers', () => {
|
||||
return createServer({ typeDefs, resolvers });
|
||||
});
|
||||
});
|
||||
|
||||
describe('applyMiddleware', async () => {
|
||||
it('can be queried', async () => {
|
||||
const { url: uri } = await createServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
});
|
||||
const apolloFetch = createApolloFetch({ uri });
|
||||
const result = await apolloFetch({ query: '{hello}' });
|
||||
|
||||
expect(result.data).toEqual({ hello: 'hi' });
|
||||
expect(result.errors).toBeUndefined();
|
||||
});
|
||||
|
||||
// XXX Unclear why this would be something somebody would want (vs enabling
|
||||
// introspection without graphql-playground, which seems reasonable, eg you
|
||||
// have your own graphql-playground setup with a custom link)
|
||||
it('can enable playground separately from introspection during production', async () => {
|
||||
const INTROSPECTION_QUERY = `
|
||||
{
|
||||
__schema {
|
||||
directives {
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const { url: uri } = await createServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
introspection: false,
|
||||
});
|
||||
|
||||
const apolloFetch = createApolloFetch({ uri });
|
||||
const result = await apolloFetch({ query: INTROSPECTION_QUERY });
|
||||
|
||||
expect(result.errors.length).toEqual(1);
|
||||
expect(result.errors[0].extensions.code).toEqual(
|
||||
'GRAPHQL_VALIDATION_FAILED',
|
||||
);
|
||||
|
||||
return new Promise<http.Server>((resolve, reject) => {
|
||||
request(
|
||||
{
|
||||
url: uri,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
accept:
|
||||
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
|
||||
},
|
||||
},
|
||||
(error, response, body) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
expect(body).toMatch('GraphQLPlayground');
|
||||
expect(response.statusCode).toEqual(200);
|
||||
resolve();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders GraphQL playground by default when browser requests', async () => {
|
||||
const nodeEnv = process.env.NODE_ENV;
|
||||
delete process.env.NODE_ENV;
|
||||
|
||||
const { url } = await createServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
});
|
||||
|
||||
return new Promise<http.Server>((resolve, reject) => {
|
||||
request(
|
||||
{
|
||||
url,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
accept:
|
||||
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
|
||||
},
|
||||
},
|
||||
(error, response, body) => {
|
||||
process.env.NODE_ENV = nodeEnv;
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
expect(body).toMatch('GraphQLPlayground');
|
||||
expect(body).not.toMatch('settings');
|
||||
expect(response.statusCode).toEqual(200);
|
||||
resolve();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
const playgroundPartialOptionsTest = async () => {
|
||||
const defaultQuery = 'query { foo { bar } }';
|
||||
const endpoint = '/fumanchupacabra';
|
||||
const { url } = await createServer(
|
||||
{
|
||||
typeDefs,
|
||||
resolvers,
|
||||
playground: {
|
||||
// https://github.com/apollographql/graphql-playground/blob/0e452d2005fcd26f10fbdcc4eed3b2e2af935e3a/packages/graphql-playground-html/src/render-playground-page.ts#L16-L24
|
||||
// must be made partial
|
||||
settings: {
|
||||
'editor.theme': 'light',
|
||||
} as any,
|
||||
tabs: [
|
||||
{
|
||||
query: defaultQuery,
|
||||
},
|
||||
{
|
||||
endpoint,
|
||||
} as any,
|
||||
],
|
||||
},
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
return new Promise<http.Server>((resolve, reject) => {
|
||||
request(
|
||||
{
|
||||
url,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
accept:
|
||||
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
|
||||
Folo: 'bar',
|
||||
},
|
||||
},
|
||||
(error, response, body) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
expect(body).toMatch('GraphQLPlayground');
|
||||
expect(body).toMatch(`"editor.theme": "light"`);
|
||||
expect(body).toMatch(defaultQuery);
|
||||
expect(body).toMatch(endpoint);
|
||||
expect(response.statusCode).toEqual(200);
|
||||
resolve();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
it('accepts partial GraphQL Playground Options in production', async () => {
|
||||
const nodeEnv = process.env.NODE_ENV;
|
||||
process.env.NODE_ENV = 'production';
|
||||
await playgroundPartialOptionsTest();
|
||||
process.env.NODE_ENV = nodeEnv;
|
||||
});
|
||||
|
||||
it(
|
||||
'accepts partial GraphQL Playground Options when an environment is ' +
|
||||
'not specified',
|
||||
async () => {
|
||||
const nodeEnv = process.env.NODE_ENV;
|
||||
delete process.env.NODE_ENV;
|
||||
await playgroundPartialOptionsTest();
|
||||
process.env.NODE_ENV = nodeEnv;
|
||||
},
|
||||
);
|
||||
|
||||
it('accepts playground options as a boolean', async () => {
|
||||
const nodeEnv = process.env.NODE_ENV;
|
||||
delete process.env.NODE_ENV;
|
||||
|
||||
const { url } = await createServer(
|
||||
{
|
||||
typeDefs,
|
||||
resolvers,
|
||||
playground: false,
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
return new Promise<http.Server>((resolve, reject) => {
|
||||
request(
|
||||
{
|
||||
url,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
accept:
|
||||
'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
|
||||
},
|
||||
},
|
||||
(error, response, body) => {
|
||||
process.env.NODE_ENV = nodeEnv;
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
expect(body).not.toMatch('GraphQLPlayground');
|
||||
expect(response.statusCode).not.toEqual(200);
|
||||
resolve();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('accepts cors configuration', async () => {
|
||||
const { url: uri } = await createServer(
|
||||
{
|
||||
typeDefs,
|
||||
resolvers,
|
||||
},
|
||||
{
|
||||
cors: { origin: 'apollographql.com' },
|
||||
},
|
||||
);
|
||||
|
||||
const apolloFetch = createApolloFetch({ uri }).useAfter(
|
||||
(response, next) => {
|
||||
expect(
|
||||
response.response.headers.get('access-control-allow-origin'),
|
||||
).toEqual('apollographql.com');
|
||||
next();
|
||||
},
|
||||
);
|
||||
await apolloFetch({ query: '{hello}' });
|
||||
});
|
||||
|
||||
describe('healthchecks', () => {
|
||||
afterEach(async () => {
|
||||
await server.stop();
|
||||
});
|
||||
|
||||
it('creates a healthcheck endpoint', async () => {
|
||||
const { port } = await createServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
});
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
request(
|
||||
{
|
||||
url: `http://localhost:${port}/.well-known/apollo/server-health`,
|
||||
method: 'GET',
|
||||
},
|
||||
(error, response, body) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
expect(body).toEqual(JSON.stringify({ status: 'pass' }));
|
||||
expect(response.statusCode).toEqual(200);
|
||||
resolve();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('provides a callback for the healthcheck', async () => {
|
||||
const { port } = await createServer(
|
||||
{
|
||||
typeDefs,
|
||||
resolvers,
|
||||
},
|
||||
{
|
||||
onHealthCheck: async () => {
|
||||
throw Error("can't connect to DB");
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
request(
|
||||
{
|
||||
url: `http://localhost:${port}/.well-known/apollo/server-health`,
|
||||
method: 'GET',
|
||||
},
|
||||
(error, response, body) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
expect(body).toEqual(JSON.stringify({ status: 'fail' }));
|
||||
expect(response.statusCode).toEqual(503);
|
||||
resolve();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('can disable the healthCheck', async () => {
|
||||
const { port } = await createServer(
|
||||
{
|
||||
typeDefs,
|
||||
resolvers,
|
||||
},
|
||||
{
|
||||
disableHealthCheck: true,
|
||||
},
|
||||
);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
request(
|
||||
{
|
||||
url: `http://localhost:${port}/.well-known/apollo/server-health`,
|
||||
method: 'GET',
|
||||
},
|
||||
(error, response) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
expect(response.statusCode).toEqual(404);
|
||||
resolve();
|
||||
}
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
// NODE: Skip Node.js 6, but only because `graphql-upload`
|
||||
// doesn't support it.
|
||||
(NODE_MAJOR_VERSION === 6 ? describe.skip : describe)(
|
||||
'file uploads',
|
||||
() => {
|
||||
it('enabled uploads', async () => {
|
||||
const { port } = await createServer({
|
||||
typeDefs: gql`
|
||||
type File {
|
||||
filename: String!
|
||||
mimetype: String!
|
||||
encoding: String!
|
||||
}
|
||||
|
||||
type Query {
|
||||
uploads: [File]
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
singleUpload(file: Upload!): File!
|
||||
}
|
||||
`,
|
||||
resolvers: {
|
||||
Query: {
|
||||
uploads: () => {},
|
||||
},
|
||||
Mutation: {
|
||||
singleUpload: async (_, args) => {
|
||||
expect((await args.file).stream).toBeDefined();
|
||||
return args.file;
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const body = new FormData();
|
||||
|
||||
body.append(
|
||||
'operations',
|
||||
JSON.stringify({
|
||||
query: `
|
||||
mutation($file: Upload!) {
|
||||
singleUpload(file: $file) {
|
||||
filename
|
||||
encoding
|
||||
mimetype
|
||||
}
|
||||
}
|
||||
`,
|
||||
variables: {
|
||||
file: null,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
body.append('map', JSON.stringify({ 1: ['variables.file'] }));
|
||||
body.append('1', fs.createReadStream('package.json'));
|
||||
|
||||
try {
|
||||
const resolved = await fetch(`http://localhost:${port}/graphql`, {
|
||||
method: 'POST',
|
||||
body: body as any,
|
||||
});
|
||||
const text = await resolved.text();
|
||||
const response = JSON.parse(text);
|
||||
|
||||
expect(response.data.singleUpload).toEqual({
|
||||
filename: 'package.json',
|
||||
encoding: '7bit',
|
||||
mimetype: 'application/json',
|
||||
});
|
||||
} catch (error) {
|
||||
// This error began appearing randomly and seems to be a dev dependency bug.
|
||||
// https://github.com/jaydenseric/apollo-upload-server/blob/18ecdbc7a1f8b69ad51b4affbd986400033303d4/test.js#L39-L42
|
||||
if (error.code !== 'EPIPE') throw error;
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
describe('errors', () => {
|
||||
it('returns thrown context error as a valid graphql result', async () => {
|
||||
const nodeEnv = process.env.NODE_ENV;
|
||||
delete process.env.NODE_ENV;
|
||||
const typeDefs = gql`
|
||||
type Query {
|
||||
hello: String
|
||||
}
|
||||
`;
|
||||
const resolvers = {
|
||||
Query: {
|
||||
hello: () => {
|
||||
throw Error('never get here');
|
||||
},
|
||||
},
|
||||
};
|
||||
const { url: uri } = await createServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
context: () => {
|
||||
throw new AuthenticationError('valid result');
|
||||
},
|
||||
});
|
||||
|
||||
const apolloFetch = createApolloFetch({ uri });
|
||||
|
||||
const result = await apolloFetch({ query: '{hello}' });
|
||||
expect(result.errors.length).toEqual(1);
|
||||
expect(result.data).toBeUndefined();
|
||||
|
||||
const e = result.errors[0];
|
||||
expect(e.message).toMatch('valid result');
|
||||
expect(e.extensions).toBeDefined();
|
||||
expect(e.extensions.code).toEqual('UNAUTHENTICATED');
|
||||
expect(e.extensions.exception.stacktrace).toBeDefined();
|
||||
|
||||
process.env.NODE_ENV = nodeEnv;
|
||||
});
|
||||
|
||||
it('propogates error codes in dev mode', async () => {
|
||||
const nodeEnv = process.env.NODE_ENV;
|
||||
delete process.env.NODE_ENV;
|
||||
|
||||
const { url: uri } = await createServer({
|
||||
typeDefs: gql`
|
||||
type Query {
|
||||
error: String
|
||||
}
|
||||
`,
|
||||
resolvers: {
|
||||
Query: {
|
||||
error: () => {
|
||||
throw new AuthenticationError('we the best music');
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const apolloFetch = createApolloFetch({ uri });
|
||||
|
||||
const result = await apolloFetch({ query: `{error}` });
|
||||
expect(result.data).toBeDefined();
|
||||
expect(result.data).toEqual({ error: null });
|
||||
|
||||
expect(result.errors).toBeDefined();
|
||||
expect(result.errors.length).toEqual(1);
|
||||
expect(result.errors[0].extensions.code).toEqual('UNAUTHENTICATED');
|
||||
expect(result.errors[0].extensions.exception).toBeDefined();
|
||||
expect(result.errors[0].extensions.exception.stacktrace).toBeDefined();
|
||||
|
||||
process.env.NODE_ENV = nodeEnv;
|
||||
});
|
||||
|
||||
it('propogates error codes in production', async () => {
|
||||
const nodeEnv = process.env.NODE_ENV;
|
||||
process.env.NODE_ENV = 'production';
|
||||
|
||||
const { url: uri } = await createServer({
|
||||
typeDefs: gql`
|
||||
type Query {
|
||||
error: String
|
||||
}
|
||||
`,
|
||||
resolvers: {
|
||||
Query: {
|
||||
error: () => {
|
||||
throw new AuthenticationError('we the best music');
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const apolloFetch = createApolloFetch({ uri });
|
||||
|
||||
const result = await apolloFetch({ query: `{error}` });
|
||||
expect(result.data).toBeDefined();
|
||||
expect(result.data).toEqual({ error: null });
|
||||
|
||||
expect(result.errors).toBeDefined();
|
||||
expect(result.errors.length).toEqual(1);
|
||||
expect(result.errors[0].extensions.code).toEqual('UNAUTHENTICATED');
|
||||
expect(result.errors[0].extensions.exception).toBeUndefined();
|
||||
|
||||
process.env.NODE_ENV = nodeEnv;
|
||||
});
|
||||
|
||||
it('propogates error codes with null response in production', async () => {
|
||||
const nodeEnv = process.env.NODE_ENV;
|
||||
process.env.NODE_ENV = 'production';
|
||||
|
||||
const { url: uri } = await createServer({
|
||||
typeDefs: gql`
|
||||
type Query {
|
||||
error: String!
|
||||
}
|
||||
`,
|
||||
resolvers: {
|
||||
Query: {
|
||||
error: () => {
|
||||
throw new AuthenticationError('we the best music');
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const apolloFetch = createApolloFetch({ uri });
|
||||
|
||||
const result = await apolloFetch({ query: `{error}` });
|
||||
expect(result.data).toBeNull();
|
||||
|
||||
expect(result.errors).toBeDefined();
|
||||
expect(result.errors.length).toEqual(1);
|
||||
expect(result.errors[0].extensions.code).toEqual('UNAUTHENTICATED');
|
||||
expect(result.errors[0].extensions.exception).toBeUndefined();
|
||||
|
||||
process.env.NODE_ENV = nodeEnv;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('extensions', () => {
|
||||
const books = [
|
||||
{
|
||||
title: 'H',
|
||||
author: 'J',
|
||||
},
|
||||
];
|
||||
|
||||
const typeDefs = gql`
|
||||
type Book {
|
||||
title: String
|
||||
author: String
|
||||
}
|
||||
|
||||
type Cook @cacheControl(maxAge: 200) {
|
||||
title: String
|
||||
author: String
|
||||
}
|
||||
|
||||
type Pook @cacheControl(maxAge: 200) {
|
||||
title: String
|
||||
books: [Book] @cacheControl(maxAge: 20, scope: PRIVATE)
|
||||
}
|
||||
|
||||
type Query {
|
||||
books: [Book]
|
||||
cooks: [Cook]
|
||||
pooks: [Pook]
|
||||
}
|
||||
`;
|
||||
|
||||
const resolvers = {
|
||||
Query: {
|
||||
books: () => books,
|
||||
cooks: () => books,
|
||||
pooks: () => [{ title: 'pook', books }],
|
||||
},
|
||||
};
|
||||
|
||||
describe('Cache Control Headers', () => {
|
||||
it('applies cacheControl Headers and strips out extension', async () => {
|
||||
const { url: uri } = await createServer({ typeDefs, resolvers });
|
||||
|
||||
const apolloFetch = createApolloFetch({ uri }).useAfter(
|
||||
(response, next) => {
|
||||
expect(response.response.headers.get('cache-control')).toEqual(
|
||||
'max-age=200, public',
|
||||
);
|
||||
next();
|
||||
},
|
||||
);
|
||||
const result = await apolloFetch({
|
||||
query: `{ cooks { title author } }`,
|
||||
});
|
||||
expect(result.data).toEqual({ cooks: books });
|
||||
expect(result.extensions).toBeUndefined();
|
||||
});
|
||||
|
||||
it('contains no cacheControl Headers and keeps extension with engine proxy', async () => {
|
||||
const { url: uri } = await createServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
cacheControl: true,
|
||||
});
|
||||
|
||||
const apolloFetch = createApolloFetch({ uri }).useAfter(
|
||||
(response, next) => {
|
||||
expect(response.response.headers.get('cache-control')).toBeNull();
|
||||
next();
|
||||
},
|
||||
);
|
||||
const result = await apolloFetch({
|
||||
query: `{ cooks { title author } }`,
|
||||
});
|
||||
expect(result.data).toEqual({ cooks: books });
|
||||
expect(result.extensions).toBeDefined();
|
||||
expect(result.extensions.cacheControl).toBeDefined();
|
||||
});
|
||||
|
||||
it('contains no cacheControl Headers when uncachable', async () => {
|
||||
const { url: uri } = await createServer({ typeDefs, resolvers });
|
||||
|
||||
const apolloFetch = createApolloFetch({ uri }).useAfter(
|
||||
(response, next) => {
|
||||
expect(response.response.headers.get('cache-control')).toBeNull();
|
||||
next();
|
||||
},
|
||||
);
|
||||
const result = await apolloFetch({
|
||||
query: `{ books { title author } }`,
|
||||
});
|
||||
expect(result.data).toEqual({ books });
|
||||
expect(result.extensions).toBeUndefined();
|
||||
});
|
||||
|
||||
it('contains private cacheControl Headers when scoped', async () => {
|
||||
const { url: uri } = await createServer({ typeDefs, resolvers });
|
||||
|
||||
const apolloFetch = createApolloFetch({ uri }).useAfter(
|
||||
(response, next) => {
|
||||
expect(response.response.headers.get('cache-control')).toEqual(
|
||||
'max-age=20, private',
|
||||
);
|
||||
next();
|
||||
},
|
||||
);
|
||||
const result = await apolloFetch({
|
||||
query: `{ pooks { title books { title author } } }`,
|
||||
});
|
||||
expect(result.data).toEqual({
|
||||
pooks: [{ title: 'pook', books }],
|
||||
});
|
||||
expect(result.extensions).toBeUndefined();
|
||||
});
|
||||
|
||||
it('runs when cache-control is false', async () => {
|
||||
const { url: uri } = await createServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
cacheControl: false,
|
||||
});
|
||||
|
||||
const apolloFetch = createApolloFetch({ uri }).useAfter(
|
||||
(response, next) => {
|
||||
expect(response.response.headers.get('cache-control')).toBeNull();
|
||||
next();
|
||||
},
|
||||
);
|
||||
const result = await apolloFetch({
|
||||
query: `{ pooks { title books { title author } } }`,
|
||||
});
|
||||
expect(result.data).toEqual({
|
||||
pooks: [{ title: 'pook', books }],
|
||||
});
|
||||
expect(result.extensions).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Tracing', () => {
|
||||
const typeDefs = gql`
|
||||
type Book {
|
||||
title: String
|
||||
author: String
|
||||
}
|
||||
|
||||
type Query {
|
||||
books: [Book]
|
||||
}
|
||||
`;
|
||||
|
||||
const resolvers = {
|
||||
Query: {
|
||||
books: () => books,
|
||||
},
|
||||
};
|
||||
|
||||
it('applies tracing extension', async () => {
|
||||
const { url: uri } = await createServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
tracing: true,
|
||||
});
|
||||
|
||||
const apolloFetch = createApolloFetch({ uri });
|
||||
const result = await apolloFetch({
|
||||
query: `{ books { title author } }`,
|
||||
});
|
||||
expect(result.data).toEqual({ books });
|
||||
expect(result.extensions).toBeDefined();
|
||||
expect(result.extensions.tracing).toBeDefined();
|
||||
});
|
||||
|
||||
it('applies tracing extension with cache control enabled', async () => {
|
||||
const { url: uri } = await createServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
tracing: true,
|
||||
cacheControl: true,
|
||||
});
|
||||
|
||||
const apolloFetch = createApolloFetch({ uri });
|
||||
const result = await apolloFetch({
|
||||
query: `{ books { title author } }`,
|
||||
});
|
||||
expect(result.data).toEqual({ books });
|
||||
expect(result.extensions).toBeDefined();
|
||||
expect(result.extensions.tracing).toBeDefined();
|
||||
});
|
||||
|
||||
xit('applies tracing extension with engine enabled', async () => {
|
||||
const { url: uri } = await createServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
tracing: true,
|
||||
engine: {
|
||||
apiKey: 'service:my-app:secret',
|
||||
maxAttempts: 0,
|
||||
endpointUrl: 'l',
|
||||
reportErrorFunction: () => {},
|
||||
},
|
||||
});
|
||||
|
||||
const apolloFetch = createApolloFetch({ uri });
|
||||
const result = await apolloFetch({
|
||||
query: `{ books { title author } }`,
|
||||
});
|
||||
expect(result.data).toEqual({ books });
|
||||
expect(result.extensions).toBeDefined();
|
||||
expect(result.extensions.tracing).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
140
packages/apollo-server-fastify/src/__tests__/datasource.test.ts
Normal file
140
packages/apollo-server-fastify/src/__tests__/datasource.test.ts
Normal file
|
@ -0,0 +1,140 @@
|
|||
import fastify, { FastifyInstance } from 'fastify';
|
||||
|
||||
import { RESTDataSource } from 'apollo-datasource-rest';
|
||||
|
||||
import { createApolloFetch } from 'apollo-fetch';
|
||||
import { ApolloServer } from '../ApolloServer';
|
||||
|
||||
import { createServerInfo } from 'apollo-server-integration-testsuite';
|
||||
import { gql } from '../index';
|
||||
|
||||
const restPort = 4001;
|
||||
|
||||
export class IdAPI extends RESTDataSource {
|
||||
baseURL = `http://localhost:${restPort}/`;
|
||||
|
||||
async getId(id: string) {
|
||||
return this.get(`id/${id}`);
|
||||
}
|
||||
|
||||
async getStringId(id: string) {
|
||||
return this.get(`str/${id}`);
|
||||
}
|
||||
}
|
||||
|
||||
const typeDefs = gql`
|
||||
type Query {
|
||||
id: String
|
||||
stringId: String
|
||||
}
|
||||
`;
|
||||
|
||||
const resolvers = {
|
||||
Query: {
|
||||
id: async (_source, _args, { dataSources }) => {
|
||||
return (await dataSources.id.getId('hi')).id;
|
||||
},
|
||||
stringId: async (_source, _args, { dataSources }) => {
|
||||
return dataSources.id.getStringId('hi');
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
let restCalls = 0;
|
||||
const restAPI = fastify();
|
||||
|
||||
restAPI.get('/id/:id', (req, res) => {
|
||||
const id = req.params.id;
|
||||
restCalls++;
|
||||
res.header('Content-Type', 'application/json');
|
||||
res.header('Cache-Control', 'max-age=2000, public');
|
||||
res.send({ id });
|
||||
});
|
||||
|
||||
restAPI.get('/str/:id', (req, res) => {
|
||||
const id = req.params.id;
|
||||
restCalls++;
|
||||
res.header('Content-Type', 'text/plain');
|
||||
res.header('Cache-Control', 'max-age=2000, public');
|
||||
res.send(id);
|
||||
});
|
||||
|
||||
describe('apollo-server-fastify', () => {
|
||||
let restServer: FastifyInstance;
|
||||
let app: FastifyInstance;
|
||||
|
||||
beforeAll(async () => {
|
||||
await restAPI.listen(restPort);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await new Promise(resolve => restServer.close(() => resolve()));
|
||||
});
|
||||
|
||||
let server: ApolloServer;
|
||||
|
||||
beforeEach(() => {
|
||||
restCalls = 0;
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await server.stop();
|
||||
await new Promise(resolve => app.close(() => resolve()));
|
||||
});
|
||||
|
||||
it('uses the cache', async () => {
|
||||
server = new ApolloServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
dataSources: () => ({
|
||||
id: new IdAPI(),
|
||||
}),
|
||||
});
|
||||
app = fastify();
|
||||
|
||||
app.register(server.createHandler());
|
||||
await app.listen(6667);
|
||||
const { url: uri } = createServerInfo(server, app.server);
|
||||
|
||||
const apolloFetch = createApolloFetch({ uri });
|
||||
const firstResult = await apolloFetch({ query: '{ id }' });
|
||||
|
||||
expect(firstResult.data).toEqual({ id: 'hi' });
|
||||
expect(firstResult.errors).toBeUndefined();
|
||||
expect(restCalls).toEqual(1);
|
||||
|
||||
const secondResult = await apolloFetch({ query: '{ id }' });
|
||||
|
||||
expect(secondResult.data).toEqual({ id: 'hi' });
|
||||
expect(secondResult.errors).toBeUndefined();
|
||||
expect(restCalls).toEqual(1);
|
||||
});
|
||||
|
||||
it('can cache a string from the backend', async () => {
|
||||
server = new ApolloServer({
|
||||
typeDefs,
|
||||
resolvers,
|
||||
dataSources: () => ({
|
||||
id: new IdAPI(),
|
||||
}),
|
||||
});
|
||||
app = fastify();
|
||||
|
||||
app.register(server.createHandler());
|
||||
await app.listen(6668);
|
||||
const { url: uri } = createServerInfo(server, app.server);
|
||||
|
||||
const apolloFetch = createApolloFetch({ uri });
|
||||
const firstResult = await apolloFetch({ query: '{ id: stringId }' });
|
||||
|
||||
expect(firstResult.data).toEqual({ id: 'hi' });
|
||||
expect(firstResult.errors).toBeUndefined();
|
||||
expect(restCalls).toEqual(1);
|
||||
|
||||
const secondResult = await apolloFetch({ query: '{ id: stringId }' });
|
||||
|
||||
expect(secondResult.data).toEqual({ id: 'hi' });
|
||||
expect(secondResult.errors).toBeUndefined();
|
||||
expect(restCalls).toEqual(1);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,40 @@
|
|||
import fastify from 'fastify';
|
||||
import { Server } from 'http';
|
||||
import { ApolloServer } from '../ApolloServer';
|
||||
import testSuite, {
|
||||
schema as Schema,
|
||||
CreateAppOptions,
|
||||
} from 'apollo-server-integration-testsuite';
|
||||
import { GraphQLOptions, Config } from 'apollo-server-core';
|
||||
|
||||
async function createApp(options: CreateAppOptions = {}) {
|
||||
const app = fastify();
|
||||
|
||||
const server = new ApolloServer(
|
||||
(options.graphqlOptions as Config) || { schema: Schema },
|
||||
);
|
||||
|
||||
app.register(server.createHandler());
|
||||
await app.listen();
|
||||
|
||||
return app.server;
|
||||
}
|
||||
|
||||
async function destroyApp(app: Server) {
|
||||
if (!app || !app.close) {
|
||||
return;
|
||||
}
|
||||
await new Promise(resolve => app.close(resolve));
|
||||
}
|
||||
|
||||
describe('fastifyApollo', () => {
|
||||
it('throws error if called without schema', function() {
|
||||
expect(() => new ApolloServer(undefined as GraphQLOptions)).toThrow(
|
||||
'ApolloServer requires options.',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('integration:Fastify', () => {
|
||||
testSuite(createApp, destroyApp);
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.test.base",
|
||||
"include": ["**/*"],
|
||||
"references": [
|
||||
{ "path": "../../" },
|
||||
{ "path": "../../../apollo-server-integration-testsuite" }
|
||||
]
|
||||
}
|
59
packages/apollo-server-fastify/src/fastifyApollo.ts
Normal file
59
packages/apollo-server-fastify/src/fastifyApollo.ts
Normal file
|
@ -0,0 +1,59 @@
|
|||
import {
|
||||
convertNodeHttpToRequest,
|
||||
GraphQLOptions,
|
||||
runHttpQuery,
|
||||
} from 'apollo-server-core';
|
||||
import { FastifyReply, FastifyRequest, RequestHandler } from 'fastify';
|
||||
import { IncomingMessage, OutgoingMessage } from 'http';
|
||||
|
||||
export async function graphqlFastify(
|
||||
options: (
|
||||
req?: FastifyRequest<IncomingMessage>,
|
||||
res?: FastifyReply<OutgoingMessage>,
|
||||
) => GraphQLOptions | Promise<GraphQLOptions>,
|
||||
): Promise<RequestHandler<IncomingMessage, OutgoingMessage>> {
|
||||
if (!options) {
|
||||
throw new Error('Apollo Server requires options.');
|
||||
}
|
||||
|
||||
return async (
|
||||
request: FastifyRequest<IncomingMessage>,
|
||||
reply: FastifyReply<OutgoingMessage>,
|
||||
) => {
|
||||
try {
|
||||
const { graphqlResponse, responseInit } = await runHttpQuery(
|
||||
[request, reply],
|
||||
{
|
||||
method: request.req.method as string,
|
||||
options,
|
||||
query: request.req.method === 'POST' ? request.body : request.query,
|
||||
request: convertNodeHttpToRequest(request.raw),
|
||||
},
|
||||
);
|
||||
|
||||
if (responseInit.headers) {
|
||||
for (const [name, value] of Object.entries<string>(
|
||||
responseInit.headers,
|
||||
)) {
|
||||
reply.header(name, value);
|
||||
}
|
||||
}
|
||||
reply.serializer((payload: string) => payload);
|
||||
reply.send(graphqlResponse);
|
||||
} catch (error) {
|
||||
if ('HttpQueryError' !== error.name) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
if (error.headers) {
|
||||
Object.keys(error.headers).forEach(header => {
|
||||
reply.header(header, error.headers[header]);
|
||||
});
|
||||
}
|
||||
|
||||
reply.code(error.statusCode);
|
||||
reply.serializer((payload: string) => payload);
|
||||
reply.send(error.message);
|
||||
}
|
||||
};
|
||||
}
|
29
packages/apollo-server-fastify/src/index.ts
Normal file
29
packages/apollo-server-fastify/src/index.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
export {
|
||||
GraphQLUpload,
|
||||
GraphQLOptions,
|
||||
GraphQLExtension,
|
||||
Config,
|
||||
gql,
|
||||
// Errors
|
||||
ApolloError,
|
||||
toApolloError,
|
||||
SyntaxError,
|
||||
ValidationError,
|
||||
AuthenticationError,
|
||||
ForbiddenError,
|
||||
UserInputError,
|
||||
// playground
|
||||
defaultPlaygroundOptions,
|
||||
PlaygroundConfig,
|
||||
PlaygroundRenderPageOptions,
|
||||
} from 'apollo-server-core';
|
||||
|
||||
export * from 'graphql-tools';
|
||||
export * from 'graphql-subscriptions';
|
||||
|
||||
// ApolloServer integration.
|
||||
export {
|
||||
ApolloServer,
|
||||
registerServer,
|
||||
ServerRegistration,
|
||||
} from './ApolloServer';
|
12
packages/apollo-server-fastify/tsconfig.json
Normal file
12
packages/apollo-server-fastify/tsconfig.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"extends": "../../tsconfig.base",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist",
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["**/__tests__", "**/__mocks__"],
|
||||
"references": [
|
||||
{ "path": "../apollo-server-core" },
|
||||
]
|
||||
}
|
|
@ -19,6 +19,7 @@
|
|||
{ "path": "./packages/apollo-server-core" },
|
||||
{ "path": "./packages/apollo-server-errors" },
|
||||
{ "path": "./packages/apollo-server-express" },
|
||||
{ "path": "./packages/apollo-server-fastify" },
|
||||
{ "path": "./packages/apollo-server-hapi" },
|
||||
{ "path": "./packages/apollo-server-koa" },
|
||||
{ "path": "./packages/apollo-server-lambda" },
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
{ "path": "./packages/apollo-server-cloud-functions/src/__tests__/" },
|
||||
{ "path": "./packages/apollo-server-core/src/__tests__/" },
|
||||
{ "path": "./packages/apollo-server-express/src/__tests__/" },
|
||||
{ "path": "./packages/apollo-server-fastify/src/__tests__/" },
|
||||
{ "path": "./packages/apollo-server-hapi/src/__tests__/" },
|
||||
{ "path": "./packages/apollo-server-koa/src/__tests__/" },
|
||||
{ "path": "./packages/apollo-server-lambda/src/__tests__/" },
|
||||
|
|
Loading…
Add table
Reference in a new issue