-
Notifications
You must be signed in to change notification settings - Fork 8.3k
/
route.ts
246 lines (226 loc) · 8.7 KB
/
route.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { RouteValidatorFullConfig } from './validator';
export function isSafeMethod(method: RouteMethod): method is SafeRouteMethod {
return method === 'get' || method === 'options';
}
/**
* Set of HTTP methods changing the state of the server.
* @public
*/
export type DestructiveRouteMethod = 'post' | 'put' | 'delete' | 'patch';
/**
* Set of HTTP methods not changing the state of the server.
* @public
*/
export type SafeRouteMethod = 'get' | 'options';
/**
* The set of common HTTP methods supported by Kibana routing.
* @public
*/
export type RouteMethod = SafeRouteMethod | DestructiveRouteMethod;
/**
* The set of valid body.output
* @public
*/
export const validBodyOutput = ['data', 'stream'] as const;
/**
* The set of supported parseable Content-Types
* @public
*/
export type RouteContentType =
| 'application/json'
| 'application/*+json'
| 'application/octet-stream'
| 'application/x-www-form-urlencoded'
| 'multipart/form-data'
| 'text/*';
/**
* Additional body options for a route
* @public
*/
export interface RouteConfigOptionsBody {
/**
* A string or an array of strings with the allowed mime types for the endpoint. Use this settings to limit the set of allowed mime types. Note that allowing additional mime types not listed
* above will not enable them to be parsed, and if parse is true, the request will result in an error response.
*
* Default value: allows parsing of the following mime types:
* * application/json
* * application/*+json
* * application/octet-stream
* * application/x-www-form-urlencoded
* * multipart/form-data
* * text/*
*/
accepts?: RouteContentType | RouteContentType[] | string | string[];
/**
* Limits the size of incoming payloads to the specified byte count. Allowing very large payloads may cause the server to run out of memory.
*
* Default value: The one set in the kibana.yml config file under the parameter `server.maxPayloadBytes`.
*/
maxBytes?: number;
/**
* The processed payload format. The value must be one of:
* * 'data' - the incoming payload is read fully into memory. If parse is true, the payload is parsed (JSON, form-decoded, multipart) based on the 'Content-Type' header. If parse is false, a raw
* Buffer is returned.
* * 'stream' - the incoming payload is made available via a Stream.Readable interface. If the payload is 'multipart/form-data' and parse is true, field values are presented as text while files
* are provided as streams. File streams from a 'multipart/form-data' upload will also have a hapi property containing the filename and headers properties. Note that payload streams for multipart
* payloads are a synthetic interface created on top of the entire multipart content loaded into memory. To avoid loading large multipart payloads into memory, set parse to false and handle the
* multipart payload in the handler using a streaming parser (e.g. pez).
*
* Default value: 'data', unless no validation.body is provided in the route definition. In that case the default is 'stream' to alleviate memory pressure.
*/
output?: typeof validBodyOutput[number];
/**
* Determines if the incoming payload is processed or presented raw. Available values:
* * true - if the request 'Content-Type' matches the allowed mime types set by allow (for the whole payload as well as parts), the payload is converted into an object when possible. If the
* format is unknown, a Bad Request (400) error response is sent. Any known content encoding is decoded.
* * false - the raw payload is returned unmodified.
* * 'gunzip' - the raw payload is returned unmodified after any known content encoding is decoded.
*
* Default value: true, unless no validation.body is provided in the route definition. In that case the default is false to alleviate memory pressure.
*/
parse?: boolean | 'gunzip';
}
/**
* Additional route options.
* @public
*/
export interface RouteConfigOptions<Method extends RouteMethod> {
/**
* Defines authentication mode for a route:
* - true. A user has to have valid credentials to access a resource
* - false. A user can access a resource without any credentials.
* - 'optional'. A user can access a resource if has valid credentials or no credentials at all.
* Can be useful when we grant access to a resource but want to identify a user if possible.
*
* Defaults to `true` if an auth mechanism is registered.
*/
authRequired?: boolean | 'optional';
/**
* Defines xsrf protection requirements for a route:
* - true. Requires an incoming POST/PUT/DELETE request to contain `kbn-xsrf` header.
* - false. Disables xsrf protection.
*
* Set to true by default
*/
xsrfRequired?: Method extends 'get' ? never : boolean;
/**
* Additional metadata tag strings to attach to the route.
*/
tags?: readonly string[];
/**
* Additional body options {@link RouteConfigOptionsBody}.
*/
body?: Method extends 'get' | 'options' ? undefined : RouteConfigOptionsBody;
/**
* Defines per-route timeouts.
*/
timeout?: {
/**
* Milliseconds to receive the payload
*/
payload?: Method extends 'get' | 'options' ? undefined : number;
/**
* Milliseconds the socket can be idle before it's closed
*/
idleSocket?: number;
};
}
/**
* Route specific configuration.
* @public
*/
export interface RouteConfig<P, Q, B, Method extends RouteMethod> {
/**
* The endpoint _within_ the router path to register the route.
*
* @remarks
* E.g. if the router is registered at `/elasticsearch` and the route path is
* `/search`, the full path for the route is `/elasticsearch/search`.
* Supports:
* - named path segments `path/{name}`.
* - optional path segments `path/{position?}`.
* - multi-segments `path/{coordinates*2}`.
* Segments are accessible within a handler function as `params` property of {@link KibanaRequest} object.
* To have read access to `params` you *must* specify validation schema with {@link RouteConfig.validate}.
*/
path: string;
/**
* A schema created with `@kbn/config-schema` that every request will be validated against.
*
* @remarks
* You *must* specify a validation schema to be able to read:
* - url path segments
* - request query
* - request body
* To opt out of validating the request, specify `validate: false`. In this case
* request params, query, and body will be **empty** objects and have no
* access to raw values.
* In some cases you may want to use another validation library. To do this, you need to
* instruct the `@kbn/config-schema` library to output **non-validated values** with
* setting schema as `schema.object({}, { unknowns: 'allow' })`;
*
* @example
* ```ts
* import { schema } from '@kbn/config-schema';
* router.get({
* path: 'path/{id}',
* validate: {
* params: schema.object({
* id: schema.string(),
* }),
* query: schema.object({...}),
* body: schema.object({...}),
* },
* },
* (context, req, res,) {
* req.params; // type Readonly<{id: string}>
* console.log(req.params.id); // value
* });
*
* router.get({
* path: 'path/{id}',
* validate: false, // handler has no access to params, query, body values.
* },
* (context, req, res,) {
* req.params; // type Readonly<{}>;
* console.log(req.params.id); // undefined
* });
*
* router.get({
* path: 'path/{id}',
* validate: {
* // handler has access to raw non-validated params in runtime
* params: schema.object({}, { unknowns: 'allow' })
* },
* },
* (context, req, res,) {
* req.params; // type Readonly<{}>;
* console.log(req.params.id); // value
* myValidationLibrary.validate({ params: req.params });
* });
* ```
*/
validate: RouteValidatorFullConfig<P, Q, B> | false;
/**
* Additional route options {@link RouteConfigOptions}.
*/
options?: RouteConfigOptions<Method>;
}