nock 15.0.0 → 15.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +39 -0
  2. package/dist/index.d.ts +60 -0
  3. package/dist/index.js +109 -0
  4. package/dist/lib/back.d.ts +44 -0
  5. package/{lib → dist/lib}/back.js +111 -84
  6. package/dist/lib/common.d.ts +27 -0
  7. package/{lib → dist/lib}/common.js +80 -190
  8. package/dist/lib/debug.d.ts +9 -0
  9. package/dist/lib/debug.js +17 -0
  10. package/dist/lib/global_emitter.d.ts +11 -0
  11. package/dist/lib/global_emitter.js +13 -0
  12. package/dist/lib/handle-request.d.ts +2 -0
  13. package/{lib → dist/lib}/handle-request.js +24 -39
  14. package/dist/lib/intercept.d.ts +25 -0
  15. package/{lib → dist/lib}/intercept.js +81 -94
  16. package/dist/lib/interceptor.d.ts +44 -0
  17. package/{lib → dist/lib}/interceptor.js +223 -119
  18. package/dist/lib/interceptors/builtin.d.ts +3 -0
  19. package/dist/lib/interceptors/builtin.js +56 -0
  20. package/dist/lib/match_body.d.ts +1 -0
  21. package/{lib → dist/lib}/match_body.js +20 -27
  22. package/dist/lib/playback_interceptor.d.ts +8 -0
  23. package/{lib → dist/lib}/playback_interceptor.js +52 -62
  24. package/dist/lib/recorder.d.ts +13 -0
  25. package/{lib → dist/lib}/recorder.js +63 -92
  26. package/dist/lib/scope.d.ts +59 -0
  27. package/{lib → dist/lib}/scope.js +158 -87
  28. package/dist/lib/stringify.d.ts +24 -0
  29. package/dist/lib/stringify.js +50 -0
  30. package/dist/lib/utils/node/index.d.ts +4 -0
  31. package/dist/lib/utils/node/index.js +16 -0
  32. package/package.json +25 -22
  33. package/index.js +0 -55
  34. package/lib/create_response.js +0 -53
  35. package/lib/debug.js +0 -12
  36. package/lib/global_emitter.js +0 -5
  37. package/lib/interceptors/builtin.js +0 -67
  38. package/lib/interceptors/undici.js +0 -78
  39. package/lib/utils/node/index.js +0 -33
  40. package/types/index.d.ts +0 -319
@@ -1,32 +1,16 @@
1
- 'use strict'
2
-
3
- const common = require('./common')
4
- const { intercept: debug } = require('./debug')
5
- const builtinMock = require('./interceptors/builtin')
6
- let undiciMock // Lazy-loaded, optional peer dependency
7
-
8
- let allInterceptors = {}
9
- let allowNetConnect
10
- let isActive = false
11
-
12
- /**
13
- * Enabled real request.
14
- * @public
15
- * @param {String|RegExp} matcher=RegExp.new('.*') Expression to match
16
- * @example
17
- * // Enables all real requests
18
- * nock.enableNetConnect();
19
- * @example
20
- * // Enables real requests for url that matches google
21
- * nock.enableNetConnect('google');
22
- * @example
23
- * // Enables real requests for url that matches google and amazon
24
- * nock.enableNetConnect(/(google|amazon)/);
25
- * @example
26
- * // Enables real requests for url that includes google
27
- * nock.enableNetConnect(host => host.includes('google'));
28
- */
29
- function enableNetConnect(matcher) {
1
+
2
+
3
+ import * as common from './common.js'
4
+ import { intercept as debug } from './debug.js'
5
+ import * as builtinMock from './interceptors/builtin.js'
6
+
7
+ let allInterceptors = {}
8
+ let allowNetConnect
9
+ let _isActive = false
10
+
11
+ function enableNetConnect(
12
+ matcher ,
13
+ ) {
30
14
  if (typeof matcher === 'string') {
31
15
  allowNetConnect = new RegExp(matcher)
32
16
  } else if (matcher instanceof RegExp) {
@@ -38,18 +22,12 @@ function enableNetConnect(matcher) {
38
22
  }
39
23
  }
40
24
 
41
- function isEnabledForNetConnect(url) {
42
- const enabled = allowNetConnect && allowNetConnect.test(url)
25
+ function isEnabledForNetConnect(url ) {
26
+ const enabled = !!(allowNetConnect && allowNetConnect.test(url))
43
27
  debug('Net connect', enabled ? '' : 'not', 'enabled for', url)
44
28
  return enabled
45
29
  }
46
30
 
47
- /**
48
- * Disable all real requests.
49
- * @public
50
- * @example
51
- * nock.disableNetConnect();
52
- */
53
31
  function disableNetConnect() {
54
32
  allowNetConnect = undefined
55
33
  }
@@ -62,7 +40,13 @@ function isOff() {
62
40
  return process.env.NOCK_OFF === 'true'
63
41
  }
64
42
 
65
- function addInterceptor(key, interceptor, scope, scopeOptions, host) {
43
+ function addInterceptor(
44
+ key ,
45
+ interceptor ,
46
+ scope ,
47
+ scopeOptions ,
48
+ host ,
49
+ ) {
66
50
  if (!(key in allInterceptors)) {
67
51
  allInterceptors[key] = { key, interceptors: [] }
68
52
  }
@@ -80,39 +64,35 @@ function addInterceptor(key, interceptor, scope, scopeOptions, host) {
80
64
  allInterceptors[key].interceptors.push(interceptor)
81
65
  }
82
66
 
83
- function remove(interceptor) {
84
- if (interceptor.__nock_scope.shouldPersist() || --interceptor.counter > 0) {
67
+ function remove(interceptor ) {
68
+ if (interceptor.__nock_scope?.shouldPersist() || --interceptor.counter > 0) {
85
69
  return
86
70
  }
87
71
 
88
- const { basePath } = interceptor
72
+ const basePath = interceptor.basePath
89
73
  const interceptors =
90
74
  (allInterceptors[basePath] && allInterceptors[basePath].interceptors) || []
91
75
 
92
76
  // TODO: There is a clearer way to write that we want to delete the first
93
77
  // matching instance. I'm also not sure why we couldn't delete _all_
94
78
  // matching instances.
95
- interceptors.some(function (thisInterceptor, i) {
79
+ interceptors.some(function (thisInterceptor , i ) {
96
80
  return thisInterceptor === interceptor ? interceptors.splice(i, 1) : false
97
81
  })
98
82
  }
99
83
 
100
84
  function removeAll() {
101
85
  Object.keys(allInterceptors).forEach(function (key) {
102
- allInterceptors[key].interceptors.forEach(function (interceptor) {
86
+ allInterceptors[key].interceptors.forEach(function (
87
+ interceptor ,
88
+ ) {
103
89
  interceptor.scope.keyedInterceptors = {}
104
90
  })
105
91
  })
106
92
  allInterceptors = {}
107
93
  }
108
94
 
109
- /**
110
- * Return all the Interceptors whose Scopes match against the base path of the provided options.
111
- *
112
- * @param {URL} url
113
- * @returns {Interceptor[]}
114
- */
115
- function interceptorsFor(url) {
95
+ function interceptorsFor(url ) {
116
96
  debug('interceptors for %j', url.host)
117
97
 
118
98
  const port = url.port || (url.protocol === 'https:' ? 443 : 80)
@@ -135,7 +115,7 @@ function interceptorsFor(url) {
135
115
 
136
116
  // Keep the filtered scope (its key) to signal the rest of the module
137
117
  // that this wasn't an exact but filtered match.
138
- interceptors.forEach(ic => {
118
+ interceptors.forEach((ic ) => {
139
119
  ic.__nock_filteredScope = ic.__nock_scopeKey
140
120
  })
141
121
  return interceptors
@@ -167,21 +147,30 @@ function interceptorsFor(url) {
167
147
  return undefined
168
148
  }
169
149
 
170
- function removeInterceptor(options) {
171
- // Lazily import to avoid circular imports.
172
- const Interceptor = require('./interceptor')
150
+ import { Interceptor as InterceptorClass } from './interceptor.js'
173
151
 
152
+ function removeInterceptor(
153
+ options
154
+
155
+ ,
156
+ ) {
174
157
  let baseUrl, key, method, proto
175
- if (options instanceof Interceptor) {
176
- baseUrl = options.basePath
177
- key = options._key
158
+ if (options instanceof InterceptorClass) {
159
+ baseUrl = (options ).basePath
160
+ key = (options )._key
178
161
  } else {
179
- proto = options.proto ? options.proto : 'http'
180
-
181
- common.normalizeRequestOptions(options)
182
- baseUrl = `${proto}://${options.host}`
183
- method = (options.method && options.method.toUpperCase()) || 'GET'
184
- key = `${method} ${baseUrl}${options.path || '/'}`
162
+ const opts = options
163
+
164
+
165
+
166
+
167
+
168
+ proto = opts.proto ? opts.proto : 'http'
169
+
170
+ common.normalizeRequestOptions(opts)
171
+ baseUrl = `${proto}://${opts.host}`
172
+ method = (opts.method && opts.method.toUpperCase()) || 'GET'
173
+ key = `${method} ${baseUrl}${opts.path || '/'}`
185
174
  }
186
175
 
187
176
  if (
@@ -191,12 +180,16 @@ function removeInterceptor(options) {
191
180
  for (let i = 0; i < allInterceptors[baseUrl].interceptors.length; i++) {
192
181
  const interceptor = allInterceptors[baseUrl].interceptors[i]
193
182
  if (
194
- options instanceof Interceptor
183
+ options instanceof InterceptorClass
195
184
  ? interceptor === options
196
185
  : interceptor._key === key
197
186
  ) {
198
187
  allInterceptors[baseUrl].interceptors.splice(i, 1)
199
188
  interceptor.scope.remove(key, interceptor)
189
+ interceptor.scope.interceptors.splice(
190
+ interceptor.scope.interceptors.indexOf(interceptor),
191
+ 1,
192
+ )
200
193
  break
201
194
  }
202
195
  }
@@ -209,10 +202,14 @@ function removeInterceptor(options) {
209
202
 
210
203
  function interceptorScopes() {
211
204
  const nestedInterceptors = Object.values(allInterceptors).map(
212
- i => i.interceptors,
205
+ (i ) => i.interceptors,
206
+ )
207
+ const scopes = new Set(
208
+ ([] )
209
+ .concat(...nestedInterceptors)
210
+ .map((i ) => i.scope),
213
211
  )
214
- const scopes = new Set([].concat(...nestedInterceptors).map(i => i.scope))
215
- return [...scopes]
212
+ return [...scopes]
216
213
  }
217
214
 
218
215
  function isDone() {
@@ -220,61 +217,51 @@ function isDone() {
220
217
  }
221
218
 
222
219
  function pendingMocks() {
223
- return [].concat(...interceptorScopes().map(scope => scope.pendingMocks()))
220
+ return ([] ).concat(
221
+ ...interceptorScopes().map(scope => scope.pendingMocks()),
222
+ )
224
223
  }
225
224
 
226
225
  function activeMocks() {
227
- return [].concat(...interceptorScopes().map(scope => scope.activeMocks()))
226
+ return ([] ).concat(
227
+ ...interceptorScopes().map(scope => scope.activeMocks()),
228
+ )
228
229
  }
229
230
 
230
231
  function activate() {
231
- if (!isActive) {
232
+ if (!_isActive) {
232
233
  builtinMock.activate()
233
-
234
- // Lazy load undiciMock only when activate is called
235
- if (!undiciMock) {
236
- try {
237
- undiciMock = require('./interceptors/undici')
238
- } catch (err) {
239
- if (err.code !== 'MODULE_NOT_FOUND') {
240
- throw err
241
- }
242
- debug(
243
- 'Undici mocking is disabled because the undici module is not installed',
244
- )
245
- }
246
- }
247
-
248
- undiciMock?.activate()
249
- isActive = true
234
+ _isActive = true
250
235
  } else {
251
236
  throw new Error('Nock already active')
252
237
  }
253
238
  }
254
239
 
255
240
  function deactivate() {
256
- if (isActive) {
241
+ if (_isActive) {
257
242
  builtinMock.deactivate()
258
- undiciMock?.deactivate()
259
- isActive = false
243
+ _isActive = false
260
244
  }
261
245
  }
262
246
 
263
- module.exports = {
247
+ const isActiveFn = () => _isActive
248
+ const abortPendingRequests = common.removeAllTimers
249
+
250
+ export {
264
251
  addInterceptor,
265
252
  remove,
266
253
  removeAll,
267
254
  removeInterceptor,
268
255
  isOn,
269
256
  activate,
270
- isActive: () => isActive,
257
+ isActiveFn as isActive,
271
258
  isDone,
272
259
  pendingMocks,
273
260
  activeMocks,
274
261
  enableNetConnect,
275
262
  disableNetConnect,
276
- restoreOverriddenClientRequest: deactivate,
277
- abortPendingRequests: common.removeAllTimers,
263
+ deactivate as restoreOverriddenClientRequest,
264
+ abortPendingRequests,
278
265
  interceptorsFor,
279
266
  isEnabledForNetConnect,
280
267
  }
@@ -0,0 +1,44 @@
1
+ import type { ReadStream } from 'node:fs';
2
+ import type { Scope, Options } from './scope.ts';
3
+ export type DataMatcher = boolean | number | string | null | undefined | RegExp | DataMatcherArray | DataMatcherMap;
4
+ export type DataMatcherArray = ReadonlyArray<DataMatcher>;
5
+ export type DataMatcherMap = {
6
+ [key: string]: DataMatcher;
7
+ };
8
+ export type RequestBodyMatcher = string | Buffer | RegExp | DataMatcherArray | DataMatcherMap | ((body: any) => boolean);
9
+ export type RequestHeaderMatcher = string | RegExp | ((fieldValue: string | null) => boolean);
10
+ export type Body = string | Record<string, any>;
11
+ export type ReplyBody = Body | Buffer | ReadStream;
12
+ export type ReplyHeaderFunction = (req: Request, body?: string | Buffer) => string | string[] | Promise<string | string[]>;
13
+ export type ReplyHeaderValue = string | string[] | ReplyHeaderFunction;
14
+ export type ReplyHeaders = Record<string, ReplyHeaderValue> | Map<string, ReplyHeaderValue> | ReplyHeaderValue[];
15
+ export type StatusCode = number;
16
+ export type ReplyFnResult = readonly [StatusCode] | readonly [StatusCode, ReplyBody] | readonly [StatusCode, ReplyBody, ReplyHeaders];
17
+ import { URLSearchParams } from 'node:url';
18
+ declare class Interceptor {
19
+ constructor(scope: Scope, uri: string | RegExp | ((path: string) => boolean), method: string, requestBody?: RequestBodyMatcher, interceptorOptions?: Options);
20
+ optionally(flag?: boolean): this;
21
+ passthrough(): Scope;
22
+ replyWithError(errorMessage: string | Error | Record<string, any>): Scope;
23
+ reply(statusCode: any, body?: any, rawHeaders?: ReplyHeaders): Scope;
24
+ replyWithFile(statusCode: number, filePath: string, headers?: ReplyHeaders): Scope;
25
+ reqheaderMatches(expected: RequestHeaderMatcher, actual: string | null, key: string): boolean;
26
+ match(request: Request, body: string): string[];
27
+ matchOrigin(request: Request): boolean;
28
+ matchHostName(hostname: string): boolean;
29
+ matchQuery(options: Record<string, any>): any;
30
+ filteringPath(...args: any[]): this;
31
+ markConsumed(): void;
32
+ matchHeader(name: string, value: RequestHeaderMatcher): this;
33
+ basicAuth({ user, pass }: {
34
+ user: string;
35
+ pass?: string;
36
+ }): this;
37
+ query(queries: boolean | string | URLSearchParams | Record<string, any> | ((queryObject: Record<string, any>) => boolean)): this;
38
+ times(newCounter: number): this;
39
+ once(): this;
40
+ twice(): this;
41
+ thrice(): this;
42
+ delay(ms: number): this;
43
+ }
44
+ export { Interceptor };