Skip to content

Commit

Permalink
types: added http header types to reply (#5046)
Browse files Browse the repository at this point in the history
* added http header types to reply

* fix lint

* patch accordingly

* update PR

* fix

---------

Co-authored-by: Uzlopak <aras.abbasi@googlemail.com>
  • Loading branch information
skwee357 and Uzlopak committed Dec 8, 2023
1 parent f2be4c5 commit 5e23534
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 16 deletions.
31 changes: 25 additions & 6 deletions test/types/reply.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ const getHandler: RouteHandlerMethod = function (_request, reply) {
expectType<number>(reply.statusCode)
expectType<boolean>(reply.sent)
expectType<((payload?: unknown) => FastifyReply)>(reply.send)
expectType<(key: string, value: any) => FastifyReply>(reply.header)
expectType<(values: {[key: string]: any}) => FastifyReply>(reply.headers)
expectType<(key: string) => number | string | string[] | undefined>(reply.getHeader)
expectType<() => { [key: string]: number | string | string[] | undefined }>(reply.getHeaders)
expectType<(key: string) => FastifyReply>(reply.removeHeader)
expectType<(key: string) => boolean>(reply.hasHeader)
expectAssignable<(key: string, value: any) => FastifyReply>(reply.header)
expectAssignable<(values: {[key: string]: any}) => FastifyReply>(reply.headers)
expectAssignable<(key: string) => number | string | string[] | undefined>(reply.getHeader)
expectAssignable<() => { [key: string]: number | string | string[] | undefined }>(reply.getHeaders)
expectAssignable<(key: string) => FastifyReply>(reply.removeHeader)
expectAssignable<(key: string) => boolean>(reply.hasHeader)
expectType<{(statusCode: number, url: string): FastifyReply; (url: string): FastifyReply }>(reply.redirect)
expectType<() => FastifyReply>(reply.hijack)
expectType<() => void>(reply.callNotFound)
Expand Down Expand Up @@ -162,3 +162,22 @@ server.get<InvalidReplyHttpCodes>('get-invalid-http-codes-reply-error', async fu
999: false
})
})

const httpHeaderHandler: RouteHandlerMethod = function (_request, reply) {
// accept is a header provided by @types/node
reply.getHeader('accept')
reply.getHeaders().accept // eslint-disable-line no-unused-expressions
reply.hasHeader('accept')
reply.header('accept', 'test')
reply.headers({ accept: 'test' })
reply.removeHeader('accept')

// x-fastify-test is not a header provided by @types/node
// and should not result in a typing error
reply.getHeader('x-fastify-test')
reply.getHeaders()['x-fastify-test'] // eslint-disable-line no-unused-expressions
reply.hasHeader('x-fastify-test')
reply.header('x-fastify-test', 'test')
reply.headers({ 'x-fastify-test': 'test' })
reply.removeHeader('x-fastify-test')
}
17 changes: 7 additions & 10 deletions types/reply.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { FastifyRequest } from './request'
import { RouteGenericInterface } from './route'
import { FastifySchema } from './schema'
import { FastifyReplyType, FastifyTypeProvider, FastifyTypeProviderDefault, ResolveFastifyReplyType } from './type-provider'
import { CodeToReplyKey, ContextConfigDefault, HttpKeys, RawReplyDefaultExpression, RawRequestDefaultExpression, RawServerBase, RawServerDefault, ReplyDefault, ReplyKeysToCodes } from './utils'
import { CodeToReplyKey, ContextConfigDefault, HttpKeys, RawReplyDefaultExpression, RawRequestDefaultExpression, RawServerBase, RawServerDefault, ReplyDefault, ReplyKeysToCodes, HttpHeader } from './utils'

export interface ReplyGenericInterface {
Reply?: ReplyDefault;
Expand Down Expand Up @@ -48,15 +48,12 @@ export interface FastifyReply<
statusCode: number;
sent: boolean;
send(payload?: ReplyType): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
header(key: string, value: any): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
headers(values: {[key: string]: any}): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
getHeader(key: string): number | string | string[] | undefined;
getHeaders(): {
// Node's `getHeaders()` can return numbers and arrays, so they're included here as possible types.
[key: string]: number | string | string[] | undefined;
};
removeHeader(key: string): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
hasHeader(key: string): boolean;
header(key: HttpHeader, value: any): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
headers(values: Partial<Record<HttpHeader, number | string | string[] | undefined>>): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
getHeader(key: HttpHeader): number | string | string[] | undefined;
getHeaders(): Record<HttpHeader, number | string | string[] | undefined>;
removeHeader(key: HttpHeader): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
hasHeader(key: HttpHeader): boolean;
// Note: should consider refactoring the argument order for redirect. statusCode is optional so it should be after the required url param
redirect(statusCode: number, url: string): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
redirect(url: string): FastifyReply<RawServer, RawRequest, RawReply, RouteGeneric, ContextConfig, SchemaCompiler, TypeProvider>;
Expand Down
10 changes: 10 additions & 0 deletions types/utils.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,13 @@ export type RecordKeysToLowercase<Input> = Input extends Record<string, unknown>
]: Input[Key];
}
: Input;

type OmitIndexSignature<T> = {
[K in keyof T as string extends K ? never : number extends K ? never : K]: T[K];
};

/**
* HTTP header strings
* Use this type only for input values, not for output values.
*/
export type HttpHeader = keyof OmitIndexSignature<http.OutgoingHttpHeaders> | (string & Record<never, never>);

0 comments on commit 5e23534

Please sign in to comment.