Skip to content

Commit f9b2a96

Browse files
Ethan-Arrowoodmcollina
authored andcommitted
Add TypeScript typings (#39)
* add init typings * Perfect typings and add tsd * Update docs and remove test file
1 parent f06c85f commit f9b2a96

File tree

5 files changed

+160
-4
lines changed

5 files changed

+160
-4
lines changed

README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,42 @@ try {
6565
}
6666
```
6767

68+
This module ships with a handwritten TypeScript declaration file for TS support. The declaration exports a single namespace `LightMyRequest`. You can import it one of two ways:
69+
```typescript
70+
import * as LightMyRequest from 'light-my-request'
71+
72+
const dispatch: LightMyRequest.DispatchFunc = function (req, res) {
73+
const reply = 'Hello World'
74+
res.writeHead(200, { 'Content-Type': 'text/plain', 'Content-Length': reply.length })
75+
res.end(reply)
76+
}
77+
78+
LightMyRequest.inject(dispatch, { method: 'get', url: '/' }, (err, res) => {
79+
console.log(res.payload)
80+
})
81+
82+
// or
83+
import { inject, DistpatchFunc } from 'light-my-request'
84+
85+
const dispatch: DispatchFunc = function (req, res) {
86+
const reply = 'Hello World'
87+
res.writeHead(200, { 'Content-Type': 'text/plain', 'Content-Length': reply.length })
88+
res.end(reply)
89+
}
90+
91+
inject(dispatch, { method: 'get', url: '/' }, (err, res) => {
92+
console.log(res.payload)
93+
})
94+
```
95+
The declaration file exports types for the following parts of the API:
96+
- `inject` - standard light-my-request `inject` method
97+
- `DispatchFunc` - the fake HTTP dispatch function
98+
- `InjectPayload` - a union type for valid payload types
99+
- `isInjection` - standard light-my-request `isInjection` method
100+
- `InjectOptions` - options object for `inject` method
101+
- `Request` - custom light-my-request `request` object interface. Extends Node.js `stream.Readable` type
102+
- `Response` - custom light-my-re uest `response` object interface. Extends Node.js `http.ServerResponse` type
103+
68104
## API
69105

70106
#### `inject(dispatchFunc, options, callback)`

index.d.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import * as stream from 'stream'
2+
import * as http from 'http'
3+
4+
type HTTPMethods = 'DELETE' | 'delete' |
5+
'GET' | 'get' |
6+
'HEAD' | 'head' |
7+
'PATCH' | 'patch' |
8+
'POST' | 'post' |
9+
'PUT' | 'put' |
10+
'OPTIONS' | 'options'
11+
12+
declare namespace LightMyRequest {
13+
function inject (
14+
dispatchFunc: DispatchFunc,
15+
options: string | InjectOptions
16+
): Promise<Response>
17+
function inject (
18+
dispatchFunc: DispatchFunc,
19+
options: string | InjectOptions,
20+
callback: (err: Error, response: Response) => void
21+
): void
22+
23+
type DispatchFunc = (req: Request, res: Response) => void
24+
25+
type InjectPayload = string | object | Buffer | NodeJS.ReadableStream
26+
27+
function isInjection (obj: Request | Response): boolean
28+
29+
interface InjectOptions {
30+
url: string | {
31+
pathname: string
32+
protocal?: string
33+
hostname?: string
34+
port?: string | number
35+
query?: string
36+
}
37+
headers?: http.IncomingHttpHeaders | http.OutgoingHttpHeaders
38+
query?: string
39+
simulate?: {
40+
end: boolean,
41+
split: boolean,
42+
error: boolean,
43+
close: boolean
44+
}
45+
authority?: string
46+
remoteAddress?: string
47+
method?: HTTPMethods
48+
validate?: boolean
49+
payload?: InjectPayload
50+
server?: http.Server
51+
}
52+
53+
interface Request extends stream.Readable {
54+
url: string
55+
httpVersion: string
56+
method: HTTPMethods
57+
headers: http.IncomingHttpHeaders
58+
prepare: (next: () => void) => void
59+
}
60+
61+
interface Response extends http.ServerResponse {
62+
raw: {
63+
res: http.ServerResponse
64+
}
65+
rawPayload: Buffer
66+
headers: http.OutgoingHttpHeaders
67+
statusCode: number
68+
statusMessage: string
69+
trailers: { [key: string]: string }
70+
payload: string
71+
body: string
72+
addTrailers: (trailers: { [key: string]: string }) => void
73+
}
74+
}
75+
76+
export = LightMyRequest

package.json

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,21 @@
77
"ajv": "^6.8.1",
88
"readable-stream": "^3.1.1"
99
},
10+
"types": "index.d.ts",
1011
"devDependencies": {
12+
"@types/node": "^11.11.4",
1113
"form-data": "^2.3.3",
1214
"pre-commit": "^1.2.2",
1315
"standard": "^12.0.0",
14-
"tap": "^12.5.1"
16+
"tap": "^12.5.1",
17+
"tsd": "^0.7.0"
1518
},
1619
"scripts": {
17-
"test": "npm run lint && npm run unit",
20+
"test": "npm run lint && npm run unit && npm run tsd",
1821
"lint": "standard",
1922
"unit": "tap test/test.js",
20-
"coverage": "npm run unit -- --cov --coverage-report=html"
23+
"coverage": "npm run unit -- --cov --coverage-report=html",
24+
"tsd": "tsd"
2125
},
2226
"repository": {
2327
"type": "git",
@@ -35,5 +39,8 @@
3539
"bugs": {
3640
"url": "https://github.com/fastify/light-my-request/issues"
3741
},
38-
"homepage": "https://github.com/fastify/light-my-request/blob/master/README.md"
42+
"homepage": "https://github.com/fastify/light-my-request/blob/master/README.md",
43+
"tsd": {
44+
"directory": "test"
45+
}
3946
}

test/index.test-d.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { inject, isInjection, Request, Response, DispatchFunc, InjectOptions } from '../index'
2+
import { expectType } from 'tsd'
3+
4+
expectType<InjectOptions>({ url: '/' })
5+
6+
const dispatch = function (req: Request, res: Response) {
7+
expectType<boolean>(isInjection(req))
8+
expectType<boolean>(isInjection(res))
9+
10+
const reply = 'Hello World'
11+
res.writeHead(200, { 'Content-Type': 'text/plain', 'Content-Length': reply.length })
12+
res.end(reply)
13+
}
14+
15+
expectType<DispatchFunc>(dispatch)
16+
17+
inject(dispatch, { method: 'get', url: '/' }, (err, res) => {
18+
expectType<Error>(err)
19+
expectType<Response>(res)
20+
console.log(res.payload)
21+
})
22+
23+
expectType<Promise<Response>>(inject(dispatch, { method: 'get', url: '/' }))
24+
// @ts-ignore tsd supports top-level await, but normal ts does not so ignore
25+
expectType<Response>(await inject(dispatch, { method: 'get', url: '/' }))

tsconfig.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es6",
4+
"module": "commonjs",
5+
"noEmit": true,
6+
"strict": true,
7+
"noImplicitAny": true
8+
},
9+
"files": [
10+
"./test/index.test-d.ts"
11+
]
12+
}

0 commit comments

Comments
 (0)