Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
205 changes: 160 additions & 45 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,21 +44,30 @@ export declare interface App {
[namespace: string]: Package;
}

export declare type Middleware = (
req: Request,
res: Response,
export declare type Middleware<
TRequest extends Request = Request,
TResponse extends Response = Response
> = (
req: TRequest,
res: TResponse,
next: NextFunction
) => void;
export declare type ErrorHandlingMiddleware = (
export declare type ErrorHandlingMiddleware<
TRequest extends Request = Request,
TResponse extends Response = Response
> = (
error: Error,
req: Request,
res: Response,
req: TRequest,
res: TResponse,
next: NextFunction
) => void;
export declare type ErrorCallback = (error?: Error) => void;
export declare type HandlerFunction = (
req: Request,
res: Response,
export declare type HandlerFunction<
TRequest extends Request = Request,
TResponse extends Response = Response
> = (
req: TRequest,
res: TResponse,
next?: NextFunction
) => void | any | Promise<any>;

Expand Down Expand Up @@ -196,7 +205,7 @@ export declare class Request {
[key: string]: any;
}

export declare class Response {
export declare class Response<TBody = any> {
status(code: number): this;

sendStatus(code: number): void;
Expand All @@ -219,11 +228,11 @@ export declare class Response {
callback?: ErrorCallback
): Promise<string>;

send(body: any): void;
send(body: TBody): void;

json(body: any): void;
json(body: TBody): void;

jsonp(body: any): void;
jsonp(body: TBody): void;

html(body: any): void;

Expand Down Expand Up @@ -269,62 +278,157 @@ export declare class API {
app(namespace: string, package: Package): App;
app(packages: App): App;

get(
get<TRequest extends Request = Request, TResponse extends Response = Response>(
path: string,
...middlewaresAndHandler: (Middleware | HandlerFunction)[]
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;
get<TRequest extends Request = Request, TResponse extends Response = Response>(
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;
get(...middlewaresAndHandler: (Middleware | HandlerFunction)[]): void;

post(
post<
TRequest extends Request = Request,
TResponse extends Response = Response
>(
path: string,
...middlewaresAndHandler: (Middleware | HandlerFunction)[]
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;
post<
TRequest extends Request = Request,
TResponse extends Response = Response
>(
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;
post(...middlewaresAndHandler: (Middleware | HandlerFunction)[]): void;

put(
put<TRequest extends Request = Request, TResponse extends Response = Response>(
path: string,
...middlewaresAndHandler: (Middleware | HandlerFunction)[]
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;
put<TRequest extends Request = Request, TResponse extends Response = Response>(
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;
put(...middlewaresAndHandler: (Middleware | HandlerFunction)[]): void;

patch(
patch<
TRequest extends Request = Request,
TResponse extends Response = Response
>(
path: string,
...middlewaresAndHandler: (Middleware | HandlerFunction)[]
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;
patch<
TRequest extends Request = Request,
TResponse extends Response = Response
>(
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;
patch(...middlewaresAndHandler: (Middleware | HandlerFunction)[]): void;

delete(
delete<
TRequest extends Request = Request,
TResponse extends Response = Response
>(
path: string,
...middlewaresAndHandler: (Middleware | HandlerFunction)[]
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;
delete(...middlewaresAndHandler: HandlerFunction[]): void;

options(
delete<
TRequest extends Request = Request,
TResponse extends Response = Response
>(...middlewaresAndHandler: HandlerFunction<TRequest, TResponse>[]): void;

options<
TRequest extends Request = Request,
TResponse extends Response = Response
>(
path: string,
...middlewaresAndHandler: (Middleware | HandlerFunction)[]
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;
options<
TRequest extends Request = Request,
TResponse extends Response = Response
>(
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;
options(...middlewaresAndHandler: (Middleware | HandlerFunction)[]): void;

head(
head<TRequest extends Request = Request, TResponse extends Response = Response>(
path: string,
...middlewaresAndHandler: (Middleware | HandlerFunction)[]
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;
head<TRequest extends Request = Request, TResponse extends Response = Response>(
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;
head(...middlewaresAndHandler: (Middleware | HandlerFunction)[]): void;

any(
any<TRequest extends Request = Request, TResponse extends Response = Response>(
path: string,
...middlewaresAndHandler: (Middleware | HandlerFunction)[]
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;
any<TRequest extends Request = Request, TResponse extends Response = Response>(
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;
any(...middlewaresAndHandler: (Middleware | HandlerFunction)[]): void;

METHOD(
METHOD<
TRequest extends Request = Request,
TResponse extends Response = Response
>(
method: METHODS | METHODS[],
path: string,
...middlewaresAndHandler: (Middleware | HandlerFunction)[]
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;
METHOD(
METHOD<
TRequest extends Request = Request,
TResponse extends Response = Response
>(
method: METHODS | METHODS[],
...middlewaresAndHandler: (Middleware | HandlerFunction)[]
...middlewaresAndHandler: (
| Middleware<TRequest, TResponse>
| HandlerFunction<TRequest, TResponse>
)[]
): void;

register(
Expand All @@ -336,9 +440,20 @@ export declare class API {
routes(format: false): string[][];
routes(): string[][];

use(path: string, ...middleware: Middleware[]): void;
use(paths: string[], ...middleware: Middleware[]): void;
use(...middleware: (Middleware | ErrorHandlingMiddleware)[]): void;
use<TRequest extends Request = Request, TResponse extends Response = Response>(
path: string,
...middleware: Middleware<TRequest, TResponse>[]
): void;
use<TRequest extends Request = Request, TResponse extends Response = Response>(
paths: string[],
...middleware: Middleware<TRequest, TResponse>[]
): void;
use<TRequest extends Request = Request, TResponse extends Response = Response>(
...middleware: (
| Middleware<TRequest, TResponse>
| ErrorHandlingMiddleware<TRequest, TResponse>
)[]
): void;

finally(callback: FinallyFunction): void;

Expand Down
52 changes: 52 additions & 0 deletions index.test-d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,23 @@ import {
ALBEvent,
} from 'aws-lambda';

type MetricsLogger = {
setProperty(name: string, value: boolean): void;
};

interface TypedRequest extends Request {
params: {
thingId: string;
anotherThingId: string;
};
context: Context & { metrics: MetricsLogger };
}

interface TypedResponseBody {
hello: string;
foo: string;
}

const options: Options = {
base: '/api',
version: 'v1',
Expand Down Expand Up @@ -174,6 +191,10 @@ expectType<void>(

expectType<void>(res.redirect('/new-path'));

const typedRes = {} as Response<TypedResponseBody>;
expectType<void>(typedRes.json({ hello: 'thing', foo: 'another-thing' }));
expectError(typedRes.json({ hello: 'thing' }));

const middleware: Middleware = (req, res, next) => {
next();
};
Expand All @@ -189,6 +210,37 @@ const handler: HandlerFunction = (req, res) => {
};
expectType<HandlerFunction>(handler);

const typedHandler: HandlerFunction<TypedRequest, Response<TypedResponseBody>> = (
req,
res
) => {
const { metrics } = req.context;
metrics.setProperty('test', true);
res.json({
hello: req.params.thingId,
foo: req.params.anotherThingId,
});
};
expectType<HandlerFunction<TypedRequest, Response<TypedResponseBody>>>(
typedHandler
);

api.get<TypedRequest, Response<TypedResponseBody>>('/typed', typedHandler);
const invalidTypedHandler: HandlerFunction<
TypedRequest,
Response<TypedResponseBody>
> = (req, res) => {
expectError(
res.json({
hello: req.params.thingId,
})
);
};
api.get<TypedRequest, Response<TypedResponseBody>>(
'/typed-invalid',
invalidTypedHandler
);

const cookieOptions: CookieOptions = {
domain: 'example.com',
httpOnly: true,
Expand Down
Loading