graphql-http 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/README.md +127 -114
- package/lib/audits/common.d.mts +58 -0
- package/lib/audits/index.d.mts +2 -0
- package/lib/audits/server.d.mts +39 -0
- package/lib/audits/server.js +237 -32
- package/lib/audits/server.mjs +238 -33
- package/lib/audits/utils.d.mts +38 -0
- package/lib/audits/utils.d.ts +11 -0
- package/lib/audits/utils.js +33 -1
- package/lib/audits/utils.mjs +31 -0
- package/lib/client.d.mts +155 -0
- package/lib/common.d.mts +31 -0
- package/lib/handler.d.mts +287 -0
- package/lib/handler.d.ts +26 -24
- package/lib/handler.js +17 -7
- package/lib/handler.mjs +18 -8
- package/lib/index.d.mts +4 -0
- package/lib/index.mjs +1 -1
- package/lib/use/express.d.mts +21 -0
- package/lib/use/express.d.ts +21 -0
- package/lib/use/express.js +73 -0
- package/lib/use/express.mjs +69 -0
- package/lib/use/fastify.d.mts +21 -0
- package/lib/use/fastify.d.ts +21 -0
- package/lib/use/fastify.js +69 -0
- package/lib/use/fastify.mjs +65 -0
- package/lib/use/fetch.d.mts +40 -0
- package/lib/use/fetch.d.ts +40 -0
- package/lib/use/fetch.js +81 -0
- package/lib/use/fetch.mjs +77 -0
- package/lib/use/node.d.mts +21 -0
- package/lib/use/node.d.ts +21 -0
- package/lib/use/node.js +72 -0
- package/lib/use/node.mjs +68 -0
- package/lib/utils.d.mts +16 -0
- package/package.json +48 -22
- package/umd/graphql-http.js +0 -2
- package/umd/graphql-http.min.js +1 -1
- package/umd/graphql-http.min.js.gz +0 -0
package/lib/client.d.mts
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* client
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
import type { ExecutionResult } from 'graphql';
|
|
7
|
+
import { RequestParams, Sink } from './common';
|
|
8
|
+
/** This file is the entry point for browsers, re-export common elements. */
|
|
9
|
+
export * from './common';
|
|
10
|
+
/** @category Client */
|
|
11
|
+
export interface ClientOptions {
|
|
12
|
+
/**
|
|
13
|
+
* URL of the GraphQL over HTTP server to connect.
|
|
14
|
+
*
|
|
15
|
+
* If the option is a function, it will be called on each request.
|
|
16
|
+
* Returning a Promise is supported too and the request will stall until it
|
|
17
|
+
* resolves.
|
|
18
|
+
*
|
|
19
|
+
* A good use-case for having a function is when using the URL for authentication,
|
|
20
|
+
* where subsequent requests (due to auth) may have a refreshed identity token.
|
|
21
|
+
*
|
|
22
|
+
* Function receives the request params. Useful for example, to ease up debugging and DevTools
|
|
23
|
+
* navigation you might want to use the operation name in the URL's search params (`/graphql?MyQuery`).
|
|
24
|
+
*/
|
|
25
|
+
url: string | ((request: RequestParams) => Promise<string> | string);
|
|
26
|
+
/**
|
|
27
|
+
* Indicates whether the user agent should send cookies from the other domain in the case
|
|
28
|
+
* of cross-origin requests.
|
|
29
|
+
*
|
|
30
|
+
* Possible options are:
|
|
31
|
+
* - `omit`: Never send or receive cookies.
|
|
32
|
+
* - `same-origin`: Send user credentials (cookies, basic http auth, etc..) if the URL is on the same origin as the calling script.
|
|
33
|
+
* - `include`: Always send user credentials (cookies, basic http auth, etc..), even for cross-origin calls.
|
|
34
|
+
*
|
|
35
|
+
* @default same-origin
|
|
36
|
+
*/
|
|
37
|
+
credentials?: 'omit' | 'same-origin' | 'include';
|
|
38
|
+
/**
|
|
39
|
+
* A string specifying the referrer of the request. This can be a same-origin URL, about:client, or an empty string.
|
|
40
|
+
*
|
|
41
|
+
* @default undefined
|
|
42
|
+
*/
|
|
43
|
+
referrer?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Specifies the referrer policy to use for the request.
|
|
46
|
+
*
|
|
47
|
+
* Possible options are:
|
|
48
|
+
* - `no-referrer`: Does not send referrer information along with requests to any origin.
|
|
49
|
+
* - `no-referrer-when-downgrade`: Sends full referrerURL for requests: whose referrerURL and current URL are both potentially trustworthy URLs, or whose referrerURL is a non-potentially trustworthy URL.
|
|
50
|
+
* - `same-origin`: Sends full referrerURL as referrer information when making same-origin-referrer requests.
|
|
51
|
+
* - `origin`: Sends only the ASCII serialization of the request’s referrerURL when making both same-origin-referrer requests and cross-origin-referrer requests.
|
|
52
|
+
* - `strict-origin`: Sends the ASCII serialization of the origin of the referrerURL for requests: whose referrerURL and current URL are both potentially trustworthy URLs, or whose referrerURL is a non-potentially trustworthy URL
|
|
53
|
+
* - `origin-when-cross-origin`: Sends full referrerURL when making same-origin-referrer requests, and only the ASCII serialization of the origin of the request’s referrerURL is sent when making cross-origin-referrer requests
|
|
54
|
+
* - `strict-origin-when-cross-origin`: Sends full referrerURL when making same-origin-referrer requests, and only the ASCII serialization of the origin of the request’s referrerURL when making cross-origin-referrer requests: whose referrerURL and current URL are both potentially trustworthy URLs, or whose referrerURL is a non-potentially trustworthy URL.
|
|
55
|
+
* - `unsafe-url`: Sends full referrerURL along for both same-origin-referrer requests and cross-origin-referrer requests.
|
|
56
|
+
*
|
|
57
|
+
* @default undefined
|
|
58
|
+
*/
|
|
59
|
+
referrerPolicy?: 'no-referrer' | 'no-referrer-when-downgrade' | 'same-origin' | 'origin' | 'strict-origin' | 'origin-when-cross-origin' | 'strict-origin-when-cross-origin' | 'unsafe-url';
|
|
60
|
+
/**
|
|
61
|
+
* HTTP headers to pass along the request.
|
|
62
|
+
*
|
|
63
|
+
* If the option is a function, it will be called on each request.
|
|
64
|
+
* Returning a Promise is supported too and the request will stall until it
|
|
65
|
+
* resolves.
|
|
66
|
+
*
|
|
67
|
+
* A good use-case for having a function is when using the URL for authentication,
|
|
68
|
+
* where subsequent requests (due to auth) may have a refreshed identity token.
|
|
69
|
+
*/
|
|
70
|
+
headers?: Record<string, string> | (() => Promise<Record<string, string> | null | void> | Record<string, string> | null | void);
|
|
71
|
+
/**
|
|
72
|
+
* Control whether the network request error should be retried.
|
|
73
|
+
*
|
|
74
|
+
* Please note that you can **only** control network errors, all other
|
|
75
|
+
* errors are considered fatal and will be reported immediately.
|
|
76
|
+
*
|
|
77
|
+
* You may implement your own waiting strategy by timing the resolution of the returned promise.
|
|
78
|
+
*
|
|
79
|
+
* Useful for retrying requests that failed because the service is temporarely unavailable.
|
|
80
|
+
*
|
|
81
|
+
* `retries` argument counts actual retries, so it will begin with
|
|
82
|
+
* 0 after the first failed request.
|
|
83
|
+
*
|
|
84
|
+
* Returning `false` will report the `err` argument; however, throwing a different error from
|
|
85
|
+
* the `err` argument, will report it instead.
|
|
86
|
+
*
|
|
87
|
+
* @default '() => false'
|
|
88
|
+
*/
|
|
89
|
+
shouldRetry?: (err: NetworkError, retries: number) => Promise<boolean>;
|
|
90
|
+
/**
|
|
91
|
+
* The Fetch function to use.
|
|
92
|
+
*
|
|
93
|
+
* For NodeJS environments consider using [`node-fetch`](https://github.com/node-fetch/node-fetch).
|
|
94
|
+
*
|
|
95
|
+
* @default global.fetch
|
|
96
|
+
*/
|
|
97
|
+
fetchFn?: unknown;
|
|
98
|
+
/**
|
|
99
|
+
* The AbortController implementation to use.
|
|
100
|
+
*
|
|
101
|
+
* For NodeJS environments before v15 consider using [`node-abort-controller`](https://github.com/southpolesteve/node-abort-controller).
|
|
102
|
+
*
|
|
103
|
+
* @default global.AbortController
|
|
104
|
+
*/
|
|
105
|
+
abortControllerImpl?: unknown;
|
|
106
|
+
}
|
|
107
|
+
/** @category Client */
|
|
108
|
+
export interface Client {
|
|
109
|
+
/**
|
|
110
|
+
* Subscribes to receive a response by making an HTTP request.
|
|
111
|
+
*
|
|
112
|
+
* It uses the `sink` to emit the received data or errors. Returns a _dispose_
|
|
113
|
+
* function used for canceling active requests and cleaning up.
|
|
114
|
+
*/
|
|
115
|
+
subscribe<Data = Record<string, unknown>, Extensions = unknown>(request: RequestParams, sink: Sink<ExecutionResult<Data, Extensions>>): () => void;
|
|
116
|
+
/**
|
|
117
|
+
* Dispose of the client, cancel all active requests and clean up resources.
|
|
118
|
+
*/
|
|
119
|
+
dispose: () => void;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Creates a disposable GraphQL over HTTP client to transmit
|
|
123
|
+
* GraphQL operation results.
|
|
124
|
+
*
|
|
125
|
+
* @category Client
|
|
126
|
+
*/
|
|
127
|
+
export declare function createClient(options: ClientOptions): Client;
|
|
128
|
+
/**
|
|
129
|
+
* A network error caused by the client or an unexpected response from the server.
|
|
130
|
+
*
|
|
131
|
+
* To avoid bundling DOM typings (because the client can run in Node env too),
|
|
132
|
+
* you should supply the `Response` generic depending on your Fetch implementation.
|
|
133
|
+
*
|
|
134
|
+
* @category Client
|
|
135
|
+
*/
|
|
136
|
+
export declare class NetworkError<Response extends ResponseLike = ResponseLike> extends Error {
|
|
137
|
+
/**
|
|
138
|
+
* The underlyig response thats considered an error.
|
|
139
|
+
*
|
|
140
|
+
* Will be undefined when no response is received,
|
|
141
|
+
* instead an unexpected network error.
|
|
142
|
+
*/
|
|
143
|
+
response: Response | undefined;
|
|
144
|
+
constructor(msgOrErrOrResponse: string | Error | Response);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Concrete interface a response needs to implement for the client.
|
|
148
|
+
*
|
|
149
|
+
* @category Client
|
|
150
|
+
*/
|
|
151
|
+
export interface ResponseLike {
|
|
152
|
+
readonly ok: boolean;
|
|
153
|
+
readonly status: number;
|
|
154
|
+
readonly statusText: string;
|
|
155
|
+
}
|
package/lib/common.d.mts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* common
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Parameters for GraphQL's request for execution.
|
|
8
|
+
*
|
|
9
|
+
* Reference: https://graphql.github.io/graphql-over-http/draft/#sec-Request-Parameters
|
|
10
|
+
*
|
|
11
|
+
* @category Common
|
|
12
|
+
*/
|
|
13
|
+
export interface RequestParams {
|
|
14
|
+
operationName?: string | undefined;
|
|
15
|
+
query: string;
|
|
16
|
+
variables?: Record<string, unknown> | undefined;
|
|
17
|
+
extensions?: Record<string, unknown> | undefined;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A representation of any set of values over any amount of time.
|
|
21
|
+
*
|
|
22
|
+
* @category Common
|
|
23
|
+
*/
|
|
24
|
+
export interface Sink<T = unknown> {
|
|
25
|
+
/** Next value arriving. */
|
|
26
|
+
next(value: T): void;
|
|
27
|
+
/** An error that has occured. This function "closes" the sink. */
|
|
28
|
+
error(error: unknown): void;
|
|
29
|
+
/** The sink has completed. This function "closes" the sink. */
|
|
30
|
+
complete(): void;
|
|
31
|
+
}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
*
|
|
3
|
+
* handler
|
|
4
|
+
*
|
|
5
|
+
*/
|
|
6
|
+
import { ExecutionArgs, ExecutionResult, GraphQLSchema, validate as graphqlValidate, execute as graphqlExecute, parse as graphqlParse, getOperationAST as graphqlGetOperationAST, GraphQLError } from 'graphql';
|
|
7
|
+
import { RequestParams } from './common';
|
|
8
|
+
/**
|
|
9
|
+
* The incoming request headers the implementing server should provide.
|
|
10
|
+
*
|
|
11
|
+
* @category Server
|
|
12
|
+
*/
|
|
13
|
+
export declare type RequestHeaders = {
|
|
14
|
+
/**
|
|
15
|
+
* Always an array in Node. Duplicates are added to it.
|
|
16
|
+
* Not necessarily true for other environments.
|
|
17
|
+
*/
|
|
18
|
+
'set-cookie'?: string | string[] | undefined;
|
|
19
|
+
[key: string]: string | string[] | undefined;
|
|
20
|
+
} | {
|
|
21
|
+
get: (key: string) => string | null;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Server agnostic request interface containing the raw request
|
|
25
|
+
* which is server dependant.
|
|
26
|
+
*
|
|
27
|
+
* @category Server
|
|
28
|
+
*/
|
|
29
|
+
export interface Request<Raw, Context> {
|
|
30
|
+
readonly method: string;
|
|
31
|
+
readonly url: string;
|
|
32
|
+
readonly headers: RequestHeaders;
|
|
33
|
+
/**
|
|
34
|
+
* Parsed request body or a parser function.
|
|
35
|
+
*
|
|
36
|
+
* If the provided function throws, the error message "Unparsable JSON body" will
|
|
37
|
+
* be in the erroneous response.
|
|
38
|
+
*/
|
|
39
|
+
readonly body: string | Record<string, unknown> | null | (() => string | Record<string, unknown> | null | Promise<string | Record<string, unknown> | null>);
|
|
40
|
+
/**
|
|
41
|
+
* The raw request itself from the implementing server.
|
|
42
|
+
*
|
|
43
|
+
* For example: `express.Request` when using Express, or maybe
|
|
44
|
+
* `http.IncomingMessage` when just using Node with `http.createServer`.
|
|
45
|
+
*/
|
|
46
|
+
readonly raw: Raw;
|
|
47
|
+
/**
|
|
48
|
+
* Context value about the incoming request, you're free to pass any information here.
|
|
49
|
+
*/
|
|
50
|
+
readonly context: Context;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* The response headers that get returned from graphql-http.
|
|
54
|
+
*
|
|
55
|
+
* @category Server
|
|
56
|
+
*/
|
|
57
|
+
export declare type ResponseHeaders = {
|
|
58
|
+
accept?: string;
|
|
59
|
+
allow?: string;
|
|
60
|
+
'content-type'?: string;
|
|
61
|
+
} & Record<string, string>;
|
|
62
|
+
/**
|
|
63
|
+
* Server agnostic response body returned from `graphql-http` needing
|
|
64
|
+
* to be coerced to the server implementation in use.
|
|
65
|
+
*
|
|
66
|
+
* @category Server
|
|
67
|
+
*/
|
|
68
|
+
export declare type ResponseBody = string;
|
|
69
|
+
/**
|
|
70
|
+
* Server agnostic response options (ex. status and headers) returned from
|
|
71
|
+
* `graphql-http` needing to be coerced to the server implementation in use.
|
|
72
|
+
*
|
|
73
|
+
* @category Server
|
|
74
|
+
*/
|
|
75
|
+
export interface ResponseInit {
|
|
76
|
+
readonly status: number;
|
|
77
|
+
readonly statusText: string;
|
|
78
|
+
readonly headers?: ResponseHeaders;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Server agnostic response returned from `graphql-http` containing the
|
|
82
|
+
* body and init options needing to be coerced to the server implementation in use.
|
|
83
|
+
*
|
|
84
|
+
* @category Server
|
|
85
|
+
*/
|
|
86
|
+
export declare type Response = readonly [body: ResponseBody | null, init: ResponseInit];
|
|
87
|
+
/**
|
|
88
|
+
* Checks whether the passed value is the `graphql-http` server agnostic response.
|
|
89
|
+
*
|
|
90
|
+
* @category Server
|
|
91
|
+
*/
|
|
92
|
+
export declare function isResponse(val: unknown): val is Response;
|
|
93
|
+
/**
|
|
94
|
+
* A concrete GraphQL execution context value type.
|
|
95
|
+
*
|
|
96
|
+
* Mainly used because TypeScript collapes unions
|
|
97
|
+
* with `any` or `unknown` to `any` or `unknown`. So,
|
|
98
|
+
* we use a custom type to allow definitions such as
|
|
99
|
+
* the `context` server option.
|
|
100
|
+
*
|
|
101
|
+
* @category Server
|
|
102
|
+
*/
|
|
103
|
+
export declare type OperationContext = Record<PropertyKey, unknown> | symbol | number | string | boolean | undefined | null;
|
|
104
|
+
/** @category Server */
|
|
105
|
+
export declare type OperationArgs<Context extends OperationContext = undefined> = ExecutionArgs & {
|
|
106
|
+
contextValue?: Context;
|
|
107
|
+
};
|
|
108
|
+
/** @category Server */
|
|
109
|
+
export interface HandlerOptions<RequestRaw = unknown, RequestContext = unknown, Context extends OperationContext = undefined> {
|
|
110
|
+
/**
|
|
111
|
+
* The GraphQL schema on which the operations will
|
|
112
|
+
* be executed and validated against.
|
|
113
|
+
*
|
|
114
|
+
* If a function is provided, it will be called on every
|
|
115
|
+
* operation request allowing you to manipulate schema
|
|
116
|
+
* dynamically.
|
|
117
|
+
*
|
|
118
|
+
* If the schema is left undefined, you're trusted to
|
|
119
|
+
* provide one in the returned `ExecutionArgs` from the
|
|
120
|
+
* `onSubscribe` callback.
|
|
121
|
+
*
|
|
122
|
+
* If you want to respond to the client with a custom status and/or body,
|
|
123
|
+
* you should do by returning a `Request` argument which will stop
|
|
124
|
+
* further execution.
|
|
125
|
+
*/
|
|
126
|
+
schema?: GraphQLSchema | ((req: Request<RequestRaw, RequestContext>, args: Omit<OperationArgs<Context>, 'schema'>) => Promise<GraphQLSchema | Response> | GraphQLSchema | Response);
|
|
127
|
+
/**
|
|
128
|
+
* A value which is provided to every resolver and holds
|
|
129
|
+
* important contextual information like the currently
|
|
130
|
+
* logged in user, or access to a database.
|
|
131
|
+
*/
|
|
132
|
+
context?: Context | ((req: Request<RequestRaw, RequestContext>, params: RequestParams) => Promise<Context | Response> | Context | Response);
|
|
133
|
+
/**
|
|
134
|
+
* A custom GraphQL validate function allowing you to apply your
|
|
135
|
+
* own validation rules.
|
|
136
|
+
*
|
|
137
|
+
* Will not be used when implementing a custom `onSubscribe`.
|
|
138
|
+
*/
|
|
139
|
+
validate?: typeof graphqlValidate;
|
|
140
|
+
/**
|
|
141
|
+
* Is the `execute` function from GraphQL which is
|
|
142
|
+
* used to execute the query and mutation operations.
|
|
143
|
+
*/
|
|
144
|
+
execute?: typeof graphqlExecute;
|
|
145
|
+
/**
|
|
146
|
+
* GraphQL parse function allowing you to apply a custom parser.
|
|
147
|
+
*/
|
|
148
|
+
parse?: typeof graphqlParse;
|
|
149
|
+
/**
|
|
150
|
+
* GraphQL operation AST getter used for detecting the operation type.
|
|
151
|
+
*/
|
|
152
|
+
getOperationAST?: typeof graphqlGetOperationAST;
|
|
153
|
+
/**
|
|
154
|
+
* The subscribe callback executed right after processing the request
|
|
155
|
+
* before proceeding with the GraphQL operation execution.
|
|
156
|
+
*
|
|
157
|
+
* If you return `ExecutionResult` from the callback, it will be used
|
|
158
|
+
* directly for responding to the request. Useful for implementing a response
|
|
159
|
+
* cache.
|
|
160
|
+
*
|
|
161
|
+
* If you return `ExecutionArgs` from the callback, it will be used instead of
|
|
162
|
+
* trying to build one internally. In this case, you are responsible for providing
|
|
163
|
+
* a ready set of arguments which will be directly plugged in the operation execution.
|
|
164
|
+
*
|
|
165
|
+
* You *must* validate the `ExecutionArgs` yourself if returning them.
|
|
166
|
+
*
|
|
167
|
+
* If you return an array of `GraphQLError` from the callback, they will be reported
|
|
168
|
+
* to the client while complying with the spec.
|
|
169
|
+
*
|
|
170
|
+
* Omitting the fields `contextValue` from the returned `ExecutionArgs` will use the
|
|
171
|
+
* provided `context` option, if available.
|
|
172
|
+
*
|
|
173
|
+
* Useful for preparing the execution arguments following a custom logic. A typical
|
|
174
|
+
* use-case is persisted queries. You can identify the query from the request parameters
|
|
175
|
+
* and supply the appropriate GraphQL operation execution arguments.
|
|
176
|
+
*
|
|
177
|
+
* If you want to respond to the client with a custom status and/or body,
|
|
178
|
+
* you should do by returning a `Request` argument which will stop
|
|
179
|
+
* further execution.
|
|
180
|
+
*/
|
|
181
|
+
onSubscribe?: (req: Request<RequestRaw, RequestContext>, params: RequestParams) => Promise<ExecutionResult | OperationArgs<Context> | readonly GraphQLError[] | Response | void> | ExecutionResult | OperationArgs<Context> | readonly GraphQLError[] | Response | void;
|
|
182
|
+
/**
|
|
183
|
+
* Executed after the operation call resolves.
|
|
184
|
+
*
|
|
185
|
+
* The `OperationResult` argument is the result of operation
|
|
186
|
+
* execution. It can be an iterator or already a value.
|
|
187
|
+
*
|
|
188
|
+
* Use this callback to listen for GraphQL operations and
|
|
189
|
+
* execution result manipulation.
|
|
190
|
+
*
|
|
191
|
+
* If you want to respond to the client with a custom status and/or body,
|
|
192
|
+
* you should do by returning a `Request` argument which will stop
|
|
193
|
+
* further execution.
|
|
194
|
+
*/
|
|
195
|
+
onOperation?: (req: Request<RequestRaw, RequestContext>, args: OperationArgs<Context>, result: ExecutionResult) => Promise<ExecutionResult | Response | void> | ExecutionResult | Response | void;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* The ready-to-use handler. Simply plug it in your favourite HTTP framework
|
|
199
|
+
* and enjoy.
|
|
200
|
+
*
|
|
201
|
+
* Errors thrown from **any** of the provided options or callbacks (or even due to
|
|
202
|
+
* library misuse or potential bugs) will reject the handler's promise. They are
|
|
203
|
+
* considered internal errors and you should take care of them accordingly.
|
|
204
|
+
*
|
|
205
|
+
* @category Server
|
|
206
|
+
*/
|
|
207
|
+
export declare type Handler<RequestRaw = unknown, RequestContext = unknown> = (req: Request<RequestRaw, RequestContext>) => Promise<Response>;
|
|
208
|
+
/**
|
|
209
|
+
* Makes a GraphQL over HTTP Protocol compliant server handler. The handler can
|
|
210
|
+
* be used with your favourite server library.
|
|
211
|
+
*
|
|
212
|
+
* Beware that the handler resolves only after the whole operation completes.
|
|
213
|
+
*
|
|
214
|
+
* Errors thrown from **any** of the provided options or callbacks (or even due to
|
|
215
|
+
* library misuse or potential bugs) will reject the handler's promise. They are
|
|
216
|
+
* considered internal errors and you should take care of them accordingly.
|
|
217
|
+
*
|
|
218
|
+
* For production environments, its recommended not to transmit the exact internal
|
|
219
|
+
* error details to the client, but instead report to an error logging tool or simply
|
|
220
|
+
* the console.
|
|
221
|
+
*
|
|
222
|
+
* Simple example usage with Node:
|
|
223
|
+
*
|
|
224
|
+
* ```js
|
|
225
|
+
* import http from 'http';
|
|
226
|
+
* import { createHandler } from 'graphql-http';
|
|
227
|
+
* import { schema } from './my-graphql-schema';
|
|
228
|
+
*
|
|
229
|
+
* // Create the GraphQL over HTTP handler
|
|
230
|
+
* const handler = createHandler({ schema });
|
|
231
|
+
*
|
|
232
|
+
* // Create a HTTP server using the handler on `/graphql`
|
|
233
|
+
* const server = http.createServer(async (req, res) => {
|
|
234
|
+
* if (!req.url.startsWith('/graphql')) {
|
|
235
|
+
* return res.writeHead(404).end();
|
|
236
|
+
* }
|
|
237
|
+
*
|
|
238
|
+
* try {
|
|
239
|
+
* const [body, init] = await handler({
|
|
240
|
+
* url: req.url,
|
|
241
|
+
* method: req.method,
|
|
242
|
+
* headers: req.headers,
|
|
243
|
+
* body: () => new Promise((resolve) => {
|
|
244
|
+
* let body = '';
|
|
245
|
+
* req.on('data', (chunk) => (body += chunk));
|
|
246
|
+
* req.on('end', () => resolve(body));
|
|
247
|
+
* }),
|
|
248
|
+
* raw: req,
|
|
249
|
+
* });
|
|
250
|
+
* res.writeHead(init.status, init.statusText, init.headers).end(body);
|
|
251
|
+
* } catch (err) {
|
|
252
|
+
* // BEWARE not to transmit the exact internal error message in production environments
|
|
253
|
+
* res.writeHead(500).end(err.message);
|
|
254
|
+
* }
|
|
255
|
+
* });
|
|
256
|
+
*
|
|
257
|
+
* server.listen(4000);
|
|
258
|
+
* console.log('Listening to port 4000');
|
|
259
|
+
* ```
|
|
260
|
+
*
|
|
261
|
+
* @category Server
|
|
262
|
+
*/
|
|
263
|
+
export declare function createHandler<RequestRaw = unknown, RequestContext = unknown, Context extends OperationContext = undefined>(options: HandlerOptions<RequestRaw, RequestContext, Context>): Handler<RequestRaw, RequestContext>;
|
|
264
|
+
/**
|
|
265
|
+
* Request's Media-Type that the server accepts.
|
|
266
|
+
*
|
|
267
|
+
* @category Server
|
|
268
|
+
*/
|
|
269
|
+
export declare type AcceptableMediaType = 'application/graphql-response+json' | 'application/json';
|
|
270
|
+
/**
|
|
271
|
+
* Inspects the request and detects the appropriate/acceptable Media-Type
|
|
272
|
+
* looking at the `Accept` header while complying with the GraphQL over HTTP Protocol.
|
|
273
|
+
*
|
|
274
|
+
* @category Server
|
|
275
|
+
*/
|
|
276
|
+
export declare function getAcceptableMediaType(acceptHeader: string | null | undefined): AcceptableMediaType | null;
|
|
277
|
+
/**
|
|
278
|
+
* Creates an appropriate GraphQL over HTTP response following the provided arguments.
|
|
279
|
+
*
|
|
280
|
+
* If the first argument is an `ExecutionResult`, the operation will be treated as "successful".
|
|
281
|
+
*
|
|
282
|
+
* If the first argument is _any_ object without the `data` field, it will be treated as an error (as per the spec)
|
|
283
|
+
* and the response will be constructed with the help of `acceptedMediaType` complying with the GraphQL over HTTP Protocol.
|
|
284
|
+
*
|
|
285
|
+
* @category Server
|
|
286
|
+
*/
|
|
287
|
+
export declare function makeResponse(resultOrErrors: Readonly<ExecutionResult> | Readonly<GraphQLError[]> | Readonly<GraphQLError>, acceptedMediaType: AcceptableMediaType): Response;
|
package/lib/handler.d.ts
CHANGED
|
@@ -8,27 +8,25 @@ import { RequestParams } from './common';
|
|
|
8
8
|
/**
|
|
9
9
|
* The incoming request headers the implementing server should provide.
|
|
10
10
|
*
|
|
11
|
-
* @category
|
|
11
|
+
* @category Server
|
|
12
12
|
*/
|
|
13
|
-
export
|
|
14
|
-
accept?: string | undefined;
|
|
15
|
-
allow?: string | undefined;
|
|
16
|
-
'content-type'?: string | undefined;
|
|
13
|
+
export declare type RequestHeaders = {
|
|
17
14
|
/**
|
|
18
15
|
* Always an array in Node. Duplicates are added to it.
|
|
19
|
-
* Not necessarily true for other environments
|
|
20
|
-
* to check the type during runtime.
|
|
16
|
+
* Not necessarily true for other environments.
|
|
21
17
|
*/
|
|
22
18
|
'set-cookie'?: string | string[] | undefined;
|
|
23
19
|
[key: string]: string | string[] | undefined;
|
|
24
|
-
}
|
|
20
|
+
} | {
|
|
21
|
+
get: (key: string) => string | null;
|
|
22
|
+
};
|
|
25
23
|
/**
|
|
26
24
|
* Server agnostic request interface containing the raw request
|
|
27
25
|
* which is server dependant.
|
|
28
26
|
*
|
|
29
|
-
* @category
|
|
27
|
+
* @category Server
|
|
30
28
|
*/
|
|
31
|
-
export interface Request<
|
|
29
|
+
export interface Request<Raw, Context> {
|
|
32
30
|
readonly method: string;
|
|
33
31
|
readonly url: string;
|
|
34
32
|
readonly headers: RequestHeaders;
|
|
@@ -45,7 +43,7 @@ export interface Request<RawRequest, Context> {
|
|
|
45
43
|
* For example: `express.Request` when using Express, or maybe
|
|
46
44
|
* `http.IncomingMessage` when just using Node with `http.createServer`.
|
|
47
45
|
*/
|
|
48
|
-
readonly raw:
|
|
46
|
+
readonly raw: Raw;
|
|
49
47
|
/**
|
|
50
48
|
* Context value about the incoming request, you're free to pass any information here.
|
|
51
49
|
*/
|
|
@@ -54,7 +52,7 @@ export interface Request<RawRequest, Context> {
|
|
|
54
52
|
/**
|
|
55
53
|
* The response headers that get returned from graphql-http.
|
|
56
54
|
*
|
|
57
|
-
* @category
|
|
55
|
+
* @category Server
|
|
58
56
|
*/
|
|
59
57
|
export declare type ResponseHeaders = {
|
|
60
58
|
accept?: string;
|
|
@@ -65,14 +63,14 @@ export declare type ResponseHeaders = {
|
|
|
65
63
|
* Server agnostic response body returned from `graphql-http` needing
|
|
66
64
|
* to be coerced to the server implementation in use.
|
|
67
65
|
*
|
|
68
|
-
* @category
|
|
66
|
+
* @category Server
|
|
69
67
|
*/
|
|
70
68
|
export declare type ResponseBody = string;
|
|
71
69
|
/**
|
|
72
70
|
* Server agnostic response options (ex. status and headers) returned from
|
|
73
71
|
* `graphql-http` needing to be coerced to the server implementation in use.
|
|
74
72
|
*
|
|
75
|
-
* @category
|
|
73
|
+
* @category Server
|
|
76
74
|
*/
|
|
77
75
|
export interface ResponseInit {
|
|
78
76
|
readonly status: number;
|
|
@@ -83,13 +81,13 @@ export interface ResponseInit {
|
|
|
83
81
|
* Server agnostic response returned from `graphql-http` containing the
|
|
84
82
|
* body and init options needing to be coerced to the server implementation in use.
|
|
85
83
|
*
|
|
86
|
-
* @category
|
|
84
|
+
* @category Server
|
|
87
85
|
*/
|
|
88
86
|
export declare type Response = readonly [body: ResponseBody | null, init: ResponseInit];
|
|
89
87
|
/**
|
|
90
88
|
* Checks whether the passed value is the `graphql-http` server agnostic response.
|
|
91
89
|
*
|
|
92
|
-
* @category
|
|
90
|
+
* @category Server
|
|
93
91
|
*/
|
|
94
92
|
export declare function isResponse(val: unknown): val is Response;
|
|
95
93
|
/**
|
|
@@ -102,9 +100,13 @@ export declare function isResponse(val: unknown): val is Response;
|
|
|
102
100
|
*
|
|
103
101
|
* @category Server
|
|
104
102
|
*/
|
|
105
|
-
export declare type
|
|
103
|
+
export declare type OperationContext = Record<PropertyKey, unknown> | symbol | number | string | boolean | undefined | null;
|
|
104
|
+
/** @category Server */
|
|
105
|
+
export declare type OperationArgs<Context extends OperationContext = undefined> = ExecutionArgs & {
|
|
106
|
+
contextValue?: Context;
|
|
107
|
+
};
|
|
106
108
|
/** @category Server */
|
|
107
|
-
export interface HandlerOptions<
|
|
109
|
+
export interface HandlerOptions<RequestRaw = unknown, RequestContext = unknown, Context extends OperationContext = undefined> {
|
|
108
110
|
/**
|
|
109
111
|
* The GraphQL schema on which the operations will
|
|
110
112
|
* be executed and validated against.
|
|
@@ -121,13 +123,13 @@ export interface HandlerOptions<RawRequest = unknown, Context = unknown> {
|
|
|
121
123
|
* you should do by returning a `Request` argument which will stop
|
|
122
124
|
* further execution.
|
|
123
125
|
*/
|
|
124
|
-
schema?: GraphQLSchema | ((req: Request<
|
|
126
|
+
schema?: GraphQLSchema | ((req: Request<RequestRaw, RequestContext>, args: Omit<OperationArgs<Context>, 'schema'>) => Promise<GraphQLSchema | Response> | GraphQLSchema | Response);
|
|
125
127
|
/**
|
|
126
128
|
* A value which is provided to every resolver and holds
|
|
127
129
|
* important contextual information like the currently
|
|
128
130
|
* logged in user, or access to a database.
|
|
129
131
|
*/
|
|
130
|
-
context?:
|
|
132
|
+
context?: Context | ((req: Request<RequestRaw, RequestContext>, params: RequestParams) => Promise<Context | Response> | Context | Response);
|
|
131
133
|
/**
|
|
132
134
|
* A custom GraphQL validate function allowing you to apply your
|
|
133
135
|
* own validation rules.
|
|
@@ -176,7 +178,7 @@ export interface HandlerOptions<RawRequest = unknown, Context = unknown> {
|
|
|
176
178
|
* you should do by returning a `Request` argument which will stop
|
|
177
179
|
* further execution.
|
|
178
180
|
*/
|
|
179
|
-
onSubscribe?: (req: Request<
|
|
181
|
+
onSubscribe?: (req: Request<RequestRaw, RequestContext>, params: RequestParams) => Promise<ExecutionResult | OperationArgs<Context> | readonly GraphQLError[] | Response | void> | ExecutionResult | OperationArgs<Context> | readonly GraphQLError[] | Response | void;
|
|
180
182
|
/**
|
|
181
183
|
* Executed after the operation call resolves.
|
|
182
184
|
*
|
|
@@ -190,7 +192,7 @@ export interface HandlerOptions<RawRequest = unknown, Context = unknown> {
|
|
|
190
192
|
* you should do by returning a `Request` argument which will stop
|
|
191
193
|
* further execution.
|
|
192
194
|
*/
|
|
193
|
-
onOperation?: (req: Request<
|
|
195
|
+
onOperation?: (req: Request<RequestRaw, RequestContext>, args: OperationArgs<Context>, result: ExecutionResult) => Promise<ExecutionResult | Response | void> | ExecutionResult | Response | void;
|
|
194
196
|
}
|
|
195
197
|
/**
|
|
196
198
|
* The ready-to-use handler. Simply plug it in your favourite HTTP framework
|
|
@@ -202,7 +204,7 @@ export interface HandlerOptions<RawRequest = unknown, Context = unknown> {
|
|
|
202
204
|
*
|
|
203
205
|
* @category Server
|
|
204
206
|
*/
|
|
205
|
-
export declare type Handler<
|
|
207
|
+
export declare type Handler<RequestRaw = unknown, RequestContext = unknown> = (req: Request<RequestRaw, RequestContext>) => Promise<Response>;
|
|
206
208
|
/**
|
|
207
209
|
* Makes a GraphQL over HTTP Protocol compliant server handler. The handler can
|
|
208
210
|
* be used with your favourite server library.
|
|
@@ -258,7 +260,7 @@ export declare type Handler<RawRequest = unknown, Context = unknown> = (req: Req
|
|
|
258
260
|
*
|
|
259
261
|
* @category Server
|
|
260
262
|
*/
|
|
261
|
-
export declare function createHandler<
|
|
263
|
+
export declare function createHandler<RequestRaw = unknown, RequestContext = unknown, Context extends OperationContext = undefined>(options: HandlerOptions<RequestRaw, RequestContext, Context>): Handler<RequestRaw, RequestContext>;
|
|
262
264
|
/**
|
|
263
265
|
* Request's Media-Type that the server accepts.
|
|
264
266
|
*
|