1 | import { FastifyError } from '@fastify/error'
|
2 | import * as http from 'http'
|
3 | import { expectAssignable, expectError, expectType } from 'tsd'
|
4 | import fastify, { FastifyInstance, FastifyReply, FastifyRequest, RouteHandlerMethod } from '../../fastify'
|
5 | import { RequestPayload } from '../../types/hooks'
|
6 | import { FindMyWayFindResult } from '../../types/instance'
|
7 | import { HTTPMethods, RawServerDefault } from '../../types/utils'
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 | declare module '../../fastify' {
|
19 | interface FastifyContextConfig {
|
20 | foo: string;
|
21 | bar: number;
|
22 | }
|
23 | }
|
24 |
|
25 | const routeHandler: RouteHandlerMethod = function (request, reply) {
|
26 | expectType<FastifyInstance>(this)
|
27 | expectType<FastifyRequest>(request)
|
28 | expectType<FastifyReply>(reply)
|
29 | }
|
30 |
|
31 | const routeHandlerWithReturnValue: RouteHandlerMethod = function (request, reply) {
|
32 | expectType<FastifyInstance>(this)
|
33 | expectType<FastifyRequest>(request)
|
34 | expectType<FastifyReply>(reply)
|
35 |
|
36 | return reply.send()
|
37 | }
|
38 |
|
39 | type LowerCaseHTTPMethods = 'get' | 'post' | 'put' | 'patch' | 'head' | 'delete' | 'options';
|
40 |
|
41 | ['GET', 'POST', 'PUT', 'PATCH', 'HEAD', 'DELETE', 'OPTIONS'].forEach(method => {
|
42 |
|
43 | expectType<FastifyInstance>(fastify().route({
|
44 | method: method as HTTPMethods,
|
45 | url: '/',
|
46 | handler: routeHandler
|
47 | }))
|
48 |
|
49 | const lowerCaseMethod: LowerCaseHTTPMethods = method.toLowerCase() as LowerCaseHTTPMethods
|
50 |
|
51 |
|
52 | expectType<FastifyInstance>(fastify()[lowerCaseMethod]('/', routeHandler))
|
53 | expectType<FastifyInstance>(fastify()[lowerCaseMethod]('/', {}, routeHandler))
|
54 | expectType<FastifyInstance>(fastify()[lowerCaseMethod]('/', { handler: routeHandler }))
|
55 |
|
56 | expectType<FastifyInstance>(fastify()[lowerCaseMethod]('/', {
|
57 | handler: routeHandler,
|
58 | errorHandler: (error, request, reply) => {
|
59 | expectType<FastifyError>(error)
|
60 | reply.send('error')
|
61 | },
|
62 | childLoggerFactory: function (logger, bindings, opts) {
|
63 | return logger.child(bindings, opts)
|
64 | }
|
65 | }))
|
66 |
|
67 | interface BodyInterface { prop: string }
|
68 | interface QuerystringInterface { prop: number }
|
69 | interface ParamsInterface { prop: boolean }
|
70 | interface HeadersInterface { prop: string }
|
71 | interface RouteSpecificContextConfigType {
|
72 | extra: boolean
|
73 | }
|
74 | interface RouteGeneric {
|
75 | Body: BodyInterface;
|
76 | Querystring: QuerystringInterface;
|
77 | Params: ParamsInterface;
|
78 | Headers: HeadersInterface;
|
79 | }
|
80 |
|
81 | fastify()[lowerCaseMethod]<RouteGeneric, RouteSpecificContextConfigType>('/', { config: { foo: 'bar', bar: 100, extra: true } }, (req, res) => {
|
82 | expectType<BodyInterface>(req.body)
|
83 | expectType<QuerystringInterface>(req.query)
|
84 | expectType<ParamsInterface>(req.params)
|
85 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
86 | expectType<string>(req.context.config.foo)
|
87 | expectType<number>(req.context.config.bar)
|
88 | expectType<boolean>(req.context.config.extra)
|
89 | expectType<string>(req.context.config.url)
|
90 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
91 | expectType<string>(res.context.config.foo)
|
92 | expectType<number>(res.context.config.bar)
|
93 | expectType<boolean>(res.context.config.extra)
|
94 | expectType<string>(req.routeConfig.url)
|
95 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
96 | })
|
97 |
|
98 | fastify().route<RouteGeneric>({
|
99 | url: '/',
|
100 | method: method as HTTPMethods,
|
101 | config: { foo: 'bar', bar: 100 },
|
102 | prefixTrailingSlash: 'slash',
|
103 | onRequest: (req, res, done) => {
|
104 | expectType<BodyInterface>(req.body)
|
105 | expectType<QuerystringInterface>(req.query)
|
106 | expectType<ParamsInterface>(req.params)
|
107 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
108 | expectType<string>(req.context.config.foo)
|
109 | expectType<number>(req.context.config.bar)
|
110 | expectType<string>(req.context.config.url)
|
111 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
112 | expectType<string>(res.context.config.foo)
|
113 | expectType<number>(res.context.config.bar)
|
114 | expectType<string>(req.routeConfig.url)
|
115 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
116 | },
|
117 | preParsing: (req, res, payload, done) => {
|
118 | expectType<BodyInterface>(req.body)
|
119 | expectType<QuerystringInterface>(req.query)
|
120 | expectType<ParamsInterface>(req.params)
|
121 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
122 | expectType<string>(req.context.config.foo)
|
123 | expectType<number>(req.context.config.bar)
|
124 | expectType<string>(req.context.config.url)
|
125 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
126 | expectType<string>(res.context.config.foo)
|
127 | expectType<number>(res.context.config.bar)
|
128 | expectType<string>(req.routeConfig.url)
|
129 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
130 | expectType<RequestPayload>(payload)
|
131 | expectAssignable<(err?: FastifyError | null, res?: RequestPayload) => void>(done)
|
132 | expectAssignable<(err?: NodeJS.ErrnoException) => void>(done)
|
133 | },
|
134 | preValidation: (req, res, done) => {
|
135 | expectType<BodyInterface>(req.body)
|
136 | expectType<QuerystringInterface>(req.query)
|
137 | expectType<ParamsInterface>(req.params)
|
138 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
139 | expectType<string>(req.context.config.foo)
|
140 | expectType<number>(req.context.config.bar)
|
141 | expectType<string>(req.context.config.url)
|
142 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
143 | expectType<string>(res.context.config.foo)
|
144 | expectType<number>(res.context.config.bar)
|
145 | expectType<string>(req.routeConfig.url)
|
146 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
147 | },
|
148 | preHandler: (req, res, done) => {
|
149 | expectType<BodyInterface>(req.body)
|
150 | expectType<QuerystringInterface>(req.query)
|
151 | expectType<ParamsInterface>(req.params)
|
152 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
153 | expectType<string>(req.context.config.foo)
|
154 | expectType<number>(req.context.config.bar)
|
155 | expectType<string>(req.context.config.url)
|
156 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
157 | expectType<string>(res.context.config.foo)
|
158 | expectType<number>(res.context.config.bar)
|
159 | expectType<string>(req.routeConfig.url)
|
160 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
161 | },
|
162 | onResponse: (req, res, done) => {
|
163 | expectType<BodyInterface>(req.body)
|
164 | expectType<QuerystringInterface>(req.query)
|
165 | expectType<ParamsInterface>(req.params)
|
166 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
167 | expectType<string>(req.context.config.foo)
|
168 | expectType<number>(req.context.config.bar)
|
169 | expectType<string>(req.context.config.url)
|
170 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
171 | expectType<string>(res.context.config.foo)
|
172 | expectType<number>(res.context.config.bar)
|
173 | expectType<string>(req.routeConfig.url)
|
174 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
175 | expectType<number>(res.statusCode)
|
176 | },
|
177 | onError: (req, res, error, done) => {
|
178 | expectType<BodyInterface>(req.body)
|
179 | expectType<QuerystringInterface>(req.query)
|
180 | expectType<ParamsInterface>(req.params)
|
181 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
182 | expectType<string>(req.context.config.foo)
|
183 | expectType<number>(req.context.config.bar)
|
184 | expectType<string>(req.context.config.url)
|
185 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
186 | expectType<string>(res.context.config.foo)
|
187 | expectType<number>(res.context.config.bar)
|
188 | expectType<string>(req.routeConfig.url)
|
189 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
190 | },
|
191 | preSerialization: (req, res, payload, done) => {
|
192 | expectType<BodyInterface>(req.body)
|
193 | expectType<QuerystringInterface>(req.query)
|
194 | expectType<ParamsInterface>(req.params)
|
195 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
196 | expectType<string>(req.context.config.foo)
|
197 | expectType<number>(req.context.config.bar)
|
198 | expectType<string>(req.context.config.url)
|
199 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
200 | expectType<string>(res.context.config.foo)
|
201 | expectType<number>(res.context.config.bar)
|
202 | expectType<string>(req.routeConfig.url)
|
203 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
204 | },
|
205 | onSend: (req, res, payload, done) => {
|
206 | expectType<BodyInterface>(req.body)
|
207 | expectType<QuerystringInterface>(req.query)
|
208 | expectType<ParamsInterface>(req.params)
|
209 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
210 | expectType<string>(req.context.config.foo)
|
211 | expectType<number>(req.context.config.bar)
|
212 | expectType<string>(req.context.config.url)
|
213 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
214 | expectType<string>(res.context.config.foo)
|
215 | expectType<number>(res.context.config.bar)
|
216 | expectType<string>(req.routeConfig.url)
|
217 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
218 | },
|
219 | handler: (req, res) => {
|
220 | expectType<BodyInterface>(req.body)
|
221 | expectType<QuerystringInterface>(req.query)
|
222 | expectType<ParamsInterface>(req.params)
|
223 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
224 | expectType<string>(req.context.config.foo)
|
225 | expectType<number>(req.context.config.bar)
|
226 | expectType<string>(req.context.config.url)
|
227 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
228 | expectType<string>(res.context.config.foo)
|
229 | expectType<number>(res.context.config.bar)
|
230 | expectType<string>(req.routeConfig.url)
|
231 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
232 | }
|
233 | })
|
234 |
|
235 | fastify().route<RouteGeneric>({
|
236 | url: '/',
|
237 | method: method as HTTPMethods,
|
238 | config: { foo: 'bar', bar: 100 },
|
239 | prefixTrailingSlash: 'slash',
|
240 | onRequest: async (req, res, done) => {
|
241 | expectType<BodyInterface>(req.body)
|
242 | expectType<QuerystringInterface>(req.query)
|
243 | expectType<ParamsInterface>(req.params)
|
244 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
245 | expectType<string>(req.context.config.foo)
|
246 | expectType<number>(req.context.config.bar)
|
247 | expectType<string>(req.context.config.url)
|
248 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
249 | expectType<string>(res.context.config.foo)
|
250 | expectType<number>(res.context.config.bar)
|
251 | expectType<string>(req.routeConfig.url)
|
252 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
253 | },
|
254 | preParsing: async (req, res, payload, done) => {
|
255 | expectType<BodyInterface>(req.body)
|
256 | expectType<QuerystringInterface>(req.query)
|
257 | expectType<ParamsInterface>(req.params)
|
258 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
259 | expectType<string>(req.context.config.foo)
|
260 | expectType<number>(req.context.config.bar)
|
261 | expectType<string>(req.context.config.url)
|
262 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
263 | expectType<string>(res.context.config.foo)
|
264 | expectType<number>(res.context.config.bar)
|
265 | expectType<string>(req.routeConfig.url)
|
266 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
267 | expectType<RequestPayload>(payload)
|
268 | expectAssignable<(err?: FastifyError | null, res?: RequestPayload) => void>(done)
|
269 | expectAssignable<(err?: NodeJS.ErrnoException) => void>(done)
|
270 | },
|
271 | preValidation: async (req, res, done) => {
|
272 | expectType<BodyInterface>(req.body)
|
273 | expectType<QuerystringInterface>(req.query)
|
274 | expectType<ParamsInterface>(req.params)
|
275 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
276 | expectType<string>(req.context.config.foo)
|
277 | expectType<number>(req.context.config.bar)
|
278 | expectType<string>(req.context.config.url)
|
279 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
280 | expectType<string>(res.context.config.foo)
|
281 | expectType<number>(res.context.config.bar)
|
282 | expectType<string>(req.routeConfig.url)
|
283 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
284 | },
|
285 | preHandler: async (req, res, done) => {
|
286 | expectType<BodyInterface>(req.body)
|
287 | expectType<QuerystringInterface>(req.query)
|
288 | expectType<ParamsInterface>(req.params)
|
289 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
290 | expectType<string>(req.context.config.foo)
|
291 | expectType<number>(req.context.config.bar)
|
292 | expectType<string>(req.context.config.url)
|
293 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
294 | expectType<string>(res.context.config.foo)
|
295 | expectType<number>(res.context.config.bar)
|
296 | expectType<string>(req.routeConfig.url)
|
297 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
298 | },
|
299 | onResponse: async (req, res, done) => {
|
300 | expectType<BodyInterface>(req.body)
|
301 | expectType<QuerystringInterface>(req.query)
|
302 | expectType<ParamsInterface>(req.params)
|
303 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
304 | expectType<string>(req.context.config.foo)
|
305 | expectType<number>(req.context.config.bar)
|
306 | expectType<string>(req.context.config.url)
|
307 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
308 | expectType<string>(res.context.config.foo)
|
309 | expectType<number>(res.context.config.bar)
|
310 | expectType<string>(req.routeConfig.url)
|
311 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
312 | expectType<number>(res.statusCode)
|
313 | },
|
314 | onError: async (req, res, error, done) => {
|
315 | expectType<BodyInterface>(req.body)
|
316 | expectType<QuerystringInterface>(req.query)
|
317 | expectType<ParamsInterface>(req.params)
|
318 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
319 | expectType<string>(req.context.config.foo)
|
320 | expectType<number>(req.context.config.bar)
|
321 | expectType<string>(req.context.config.url)
|
322 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
323 | expectType<string>(res.context.config.foo)
|
324 | expectType<number>(res.context.config.bar)
|
325 | expectType<string>(req.routeConfig.url)
|
326 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
327 | },
|
328 | preSerialization: async (req, res, payload, done) => {
|
329 | expectType<BodyInterface>(req.body)
|
330 | expectType<QuerystringInterface>(req.query)
|
331 | expectType<ParamsInterface>(req.params)
|
332 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
333 | expectType<string>(req.context.config.foo)
|
334 | expectType<number>(req.context.config.bar)
|
335 | expectType<string>(req.context.config.url)
|
336 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
337 | expectType<string>(res.context.config.foo)
|
338 | expectType<number>(res.context.config.bar)
|
339 | expectType<string>(req.routeConfig.url)
|
340 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
341 | },
|
342 | onSend: async (req, res, payload, done) => {
|
343 | expectType<BodyInterface>(req.body)
|
344 | expectType<QuerystringInterface>(req.query)
|
345 | expectType<ParamsInterface>(req.params)
|
346 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
347 | expectType<string>(req.context.config.foo)
|
348 | expectType<number>(req.context.config.bar)
|
349 | expectType<string>(req.context.config.url)
|
350 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
351 | expectType<string>(res.context.config.foo)
|
352 | expectType<number>(res.context.config.bar)
|
353 | expectType<string>(req.routeConfig.url)
|
354 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
355 | },
|
356 | handler: (req, res) => {
|
357 | expectType<BodyInterface>(req.body)
|
358 | expectType<QuerystringInterface>(req.query)
|
359 | expectType<ParamsInterface>(req.params)
|
360 | expectType<http.IncomingHttpHeaders & HeadersInterface>(req.headers)
|
361 | expectType<string>(req.context.config.foo)
|
362 | expectType<number>(req.context.config.bar)
|
363 | expectType<string>(req.context.config.url)
|
364 | expectType<HTTPMethods | HTTPMethods[]>(req.context.config.method)
|
365 | expectType<string>(res.context.config.foo)
|
366 | expectType<number>(res.context.config.bar)
|
367 | expectType<string>(req.routeConfig.url)
|
368 | expectType<HTTPMethods | HTTPMethods[]>(req.routeConfig.method)
|
369 | }
|
370 | })
|
371 | })
|
372 |
|
373 | expectError(fastify().route({
|
374 | url: '/',
|
375 | method: 'CONNECT',
|
376 | handler: routeHandler
|
377 | }))
|
378 |
|
379 | expectType<FastifyInstance>(fastify().route({
|
380 | url: '/',
|
381 | method: ['GET', 'POST'],
|
382 | handler: routeHandler
|
383 | }))
|
384 |
|
385 | expectError(fastify().route({
|
386 | url: '/',
|
387 | method: ['GET', 'POST', 'OPTION'],
|
388 | handler: routeHandler
|
389 | }))
|
390 |
|
391 | expectError(fastify().route({
|
392 | url: '/',
|
393 | method: 'GET',
|
394 | handler: routeHandler,
|
395 | schemaErrorFormatter: 500
|
396 | }))
|
397 |
|
398 | expectType<FastifyInstance>(fastify().route({
|
399 | url: '/',
|
400 | method: 'GET',
|
401 | handler: routeHandler,
|
402 | schemaErrorFormatter: (errors, dataVar) => new Error('')
|
403 | }))
|
404 |
|
405 | expectError(fastify().route({
|
406 | prefixTrailingSlash: true
|
407 | }))
|
408 |
|
409 | expectType<FastifyInstance>(fastify().route({
|
410 | url: '/',
|
411 | method: 'GET',
|
412 | handler: routeHandlerWithReturnValue
|
413 | }))
|
414 |
|
415 | expectType<boolean>(fastify().hasRoute({
|
416 | url: '/',
|
417 | method: 'GET'
|
418 | }))
|
419 |
|
420 | expectType<boolean>(fastify().hasRoute({
|
421 | url: '/',
|
422 | method: 'GET',
|
423 | constraints: { version: '1.2.0' }
|
424 | }))
|
425 |
|
426 | expectType<boolean>(fastify().hasRoute({
|
427 | url: '/',
|
428 | method: 'GET',
|
429 | constraints: { host: 'auth.fastify.dev' }
|
430 | }))
|
431 |
|
432 | expectType<boolean>(fastify().hasRoute({
|
433 | url: '/',
|
434 | method: 'GET',
|
435 | constraints: { host: /.*\.fastify\.dev$/ }
|
436 | }))
|
437 |
|
438 | expectType<boolean>(fastify().hasRoute({
|
439 | url: '/',
|
440 | method: 'GET',
|
441 | constraints: { host: /.*\.fastify\.dev$/, version: '1.2.3' }
|
442 | }))
|
443 |
|
444 | expectType<boolean>(fastify().hasRoute({
|
445 | url: '/',
|
446 | method: 'GET',
|
447 | constraints: {
|
448 |
|
449 | number: 12,
|
450 | date: new Date(),
|
451 | boolean: true,
|
452 | function: () => {},
|
453 | object: { foo: 'bar' }
|
454 | }
|
455 | }))
|
456 |
|
457 | expectType<Omit<FindMyWayFindResult<RawServerDefault>, 'store'>>(
|
458 | fastify().findRoute({
|
459 | url: '/',
|
460 | method: 'get'
|
461 | })
|
462 | )
|
463 |
|
464 | // we should not expose store
|
465 | expectError(fastify().findRoute({
|
466 | url: '/',
|
467 | method: 'get'
|
468 | }).store)
|
469 |
|
470 | expectType<FastifyInstance>(fastify().route({
|
471 | url: '/',
|
472 | method: 'get',
|
473 | handler: routeHandlerWithReturnValue
|
474 | }))
|
475 |
|
476 | expectType<FastifyInstance>(fastify().route({
|
477 | url: '/',
|
478 | method: ['put', 'patch'],
|
479 | handler: routeHandlerWithReturnValue
|
480 | }))
|
481 |
|
\ | No newline at end of file |