UNPKG

7.95 kBTypeScriptView Raw
1// TypeScript Version: 3.5
2
3import { ReadStream } from 'fs'
4import { ClientRequest, IncomingMessage, RequestOptions } from 'http'
5import { ParsedUrlQuery } from 'querystring'
6import { Url, URLSearchParams } from 'url'
7
8export = nock
9
10declare function nock(
11 basePath: string | RegExp | Url | URL,
12 options?: nock.Options,
13): nock.Scope
14
15declare namespace nock {
16 function cleanAll(): void
17 function activate(): void
18 function isActive(): boolean
19 function isDone(): boolean
20 function pendingMocks(): string[]
21 function activeMocks(): string[]
22 function removeInterceptor(interceptor: Interceptor | ReqOptions): boolean
23 function disableNetConnect(): void
24 function enableNetConnect(
25 matcher?: string | RegExp | ((host: string) => boolean),
26 ): void
27 function load(path: string): Scope[]
28 function loadDefs(path: string): Definition[]
29 function define(defs: Definition[]): Scope[]
30 function restore(): void
31 function abortPendingRequests(): void
32
33 let back: Back
34 let emitter: NodeJS.EventEmitter
35 let recorder: Recorder
36
37 type InterceptFunction = (
38 uri: string | RegExp | { (uri: string): boolean },
39 requestBody?: RequestBodyMatcher,
40 interceptorOptions?: Options,
41 ) => Interceptor
42
43 // Essentially valid, decoded JSON with the addition of possible RegExp. TS doesn't currently have
44 // a great way to represent JSON type data, this data matcher design is based off this comment.
45 // https://github.com/microsoft/TypeScript/issues/1897#issuecomment-338650717
46 type DataMatcher =
47 | boolean
48 | number
49 | string
50 | null
51 | undefined
52 | RegExp
53 | DataMatcherArray
54 | DataMatcherMap
55 interface DataMatcherArray extends ReadonlyArray<DataMatcher> {}
56 interface DataMatcherMap {
57 [key: string]: DataMatcher
58 }
59
60 type RequestBodyMatcher =
61 | string
62 | Buffer
63 | RegExp
64 | DataMatcherArray
65 | DataMatcherMap
66 | { (body: any): boolean }
67
68 type RequestHeaderMatcher =
69 | string
70 | RegExp
71 | { (fieldValue: string): boolean }
72
73 type Body = string | Record<string, any> // a string or decoded JSON
74 type ReplyBody = Body | Buffer | ReadStream
75
76 type ReplyHeaderFunction = (
77 req: ClientRequest,
78 res: IncomingMessage,
79 body: string | Buffer,
80 ) => string | string[]
81 type ReplyHeaderValue = string | string[] | ReplyHeaderFunction
82 type ReplyHeaders =
83 | Record<string, ReplyHeaderValue>
84 | Map<string, ReplyHeaderValue>
85 | ReplyHeaderValue[]
86
87 type StatusCode = number
88 type ReplyFnResult =
89 | readonly [StatusCode]
90 | readonly [StatusCode, ReplyBody]
91 | readonly [StatusCode, ReplyBody, ReplyHeaders]
92
93 interface ReplyFnContext extends Interceptor {
94 req: ClientRequest & {
95 headers: Record<string, string>
96 }
97 }
98
99 interface Scope extends NodeJS.EventEmitter {
100 get: InterceptFunction
101 post: InterceptFunction
102 put: InterceptFunction
103 head: InterceptFunction
104 patch: InterceptFunction
105 merge: InterceptFunction
106 delete: InterceptFunction
107 options: InterceptFunction
108
109 intercept: (
110 uri: string | RegExp | { (uri: string): boolean },
111 method: string,
112 requestBody?: RequestBodyMatcher,
113 options?: Options,
114 ) => Interceptor
115
116 defaultReplyHeaders(headers: ReplyHeaders): this
117 matchHeader(name: string, value: RequestHeaderMatcher): this
118 filteringPath(regex: RegExp, replace: string): this
119 filteringPath(fn: (path: string) => string): this
120 filteringRequestBody(regex: RegExp, replace: string): this
121 filteringRequestBody(
122 fn: (body: string, recordedBody: string) => string,
123 ): this
124
125 persist(flag?: boolean): this
126 replyContentLength(): this
127 replyDate(d?: Date): this
128
129 done(): void
130 isDone(): boolean
131 pendingMocks(): string[]
132 activeMocks(): string[]
133 }
134
135 interface Interceptor {
136 query(
137 matcher:
138 | boolean
139 | string
140 | DataMatcherMap
141 | URLSearchParams
142 | { (parsedObj: ParsedUrlQuery): boolean },
143 ): this
144
145 // tslint (as of 5.16) is under the impression that the callback types can be unified,
146 // however, doing so causes the params to lose their inherited types during use.
147 // the order of the overrides is important for determining the param types in the replay fns.
148 /* tslint:disable:unified-signatures */
149 reply(
150 replyFnWithCallback: (
151 this: ReplyFnContext,
152 uri: string,
153 body: Body,
154 callback: (
155 err: NodeJS.ErrnoException | null,
156 result: ReplyFnResult,
157 ) => void,
158 ) => void,
159 ): Scope
160 reply(
161 replyFn: (
162 this: ReplyFnContext,
163 uri: string,
164 body: Body,
165 ) => ReplyFnResult | Promise<ReplyFnResult>,
166 ): Scope
167 reply(
168 statusCode: StatusCode,
169 replyBodyFnWithCallback: (
170 this: ReplyFnContext,
171 uri: string,
172 body: Body,
173 callback: (
174 err: NodeJS.ErrnoException | null,
175 result: ReplyBody,
176 ) => void,
177 ) => void,
178 headers?: ReplyHeaders,
179 ): Scope
180 reply(
181 statusCode: StatusCode,
182 replyBodyFn: (
183 this: ReplyFnContext,
184 uri: string,
185 body: Body,
186 ) => ReplyBody | Promise<ReplyBody>,
187 headers?: ReplyHeaders,
188 ): Scope
189 reply(responseCode?: StatusCode, body?: Body, headers?: ReplyHeaders): Scope
190 /* tslint:enable:unified-signatures */
191
192 replyWithError(errorMessage: string | object): Scope
193 replyWithFile(
194 statusCode: StatusCode,
195 fileName: string,
196 headers?: ReplyHeaders,
197 ): Scope
198
199 matchHeader(name: string, value: RequestHeaderMatcher): this
200 basicAuth(options: { user: string; pass?: string }): this
201
202 times(newCounter: number): this
203 once(): this
204 twice(): this
205 thrice(): this
206 optionally(flag?: boolean): this
207
208 delay(opts: number | { head?: number; body?: number }): this
209 delayBody(timeMs: number): this
210 delayConnection(timeMs: number): this
211 }
212
213 interface Options {
214 allowUnmocked?: boolean
215 reqheaders?: Record<string, RequestHeaderMatcher>
216 badheaders?: string[]
217 filteringScope?: { (scope: string): boolean }
218 encodedQueryParams?: boolean
219 }
220
221 interface Recorder {
222 rec(options?: boolean | RecorderOptions): void
223 clear(): void
224 play(): string[] | Definition[]
225 }
226
227 interface RecorderOptions {
228 dont_print?: boolean
229 output_objects?: boolean
230 enable_reqheaders_recording?: boolean
231 logging?: (content: string) => void
232 use_separator?: boolean
233 }
234
235 interface Definition {
236 scope: string | RegExp
237 path: string | RegExp
238 port?: number | string
239 method?: string
240 status?: number
241 body?: RequestBodyMatcher
242 reqheaders?: Record<string, RequestHeaderMatcher>
243 response?: ReplyBody
244 headers?: ReplyHeaders
245 options?: Options
246 }
247
248 type BackMode = 'wild' | 'dryrun' | 'record' | 'update' | 'lockdown'
249
250 interface Back {
251 currentMode: BackMode
252 fixtures: string
253 setMode(mode: BackMode): void
254
255 (fixtureName: string, nockedFn: (nockDone: () => void) => void): void
256 (
257 fixtureName: string,
258 options: BackOptions,
259 nockedFn: (nockDone: () => void) => void,
260 ): void
261 (
262 fixtureName: string,
263 options?: BackOptions,
264 ): Promise<{
265 nockDone: () => void
266 context: BackContext
267 }>
268 }
269
270 interface InterceptorSurface {
271 method: string
272 uri: string
273 basePath: string
274 path: string
275 queries?: string
276 counter: number
277 body: string
278 statusCode: number
279 optional: boolean
280 }
281
282 interface BackContext {
283 isLoaded: boolean
284 scopes: Scope[]
285 assertScopesFinished(): void
286 query: InterceptorSurface[]
287 }
288
289 interface BackOptions {
290 before?: (def: Definition) => void
291 after?: (scope: Scope) => void
292 afterRecord?: (defs: Definition[]) => Definition[]
293 recorder?: RecorderOptions
294 }
295}
296
297type ReqOptions = RequestOptions & { proto?: string }