@zimic/interceptor 0.16.0-canary.1 → 0.16.0-canary.11

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 (41) hide show
  1. package/README.md +4 -5
  2. package/dist/{chunk-6TSSHQW5.mjs → chunk-NTRC2S4I.mjs} +253 -312
  3. package/dist/chunk-NTRC2S4I.mjs.map +1 -0
  4. package/dist/{chunk-R2ROSKU4.js → chunk-O6ZIPCUJ.js} +254 -313
  5. package/dist/chunk-O6ZIPCUJ.js.map +1 -0
  6. package/dist/cli.js +9 -9
  7. package/dist/cli.js.map +1 -1
  8. package/dist/cli.mjs +5 -5
  9. package/dist/cli.mjs.map +1 -1
  10. package/dist/http.d.ts +156 -176
  11. package/dist/http.js +265 -324
  12. package/dist/http.js.map +1 -1
  13. package/dist/http.mjs +263 -323
  14. package/dist/http.mjs.map +1 -1
  15. package/dist/server.d.ts +20 -46
  16. package/dist/server.js +7 -7
  17. package/dist/server.mjs +1 -1
  18. package/package.json +8 -8
  19. package/src/cli/browser/init.ts +2 -2
  20. package/src/cli/server/start.ts +2 -2
  21. package/src/http/index.ts +6 -13
  22. package/src/http/interceptor/HttpInterceptorClient.ts +30 -15
  23. package/src/http/interceptor/LocalHttpInterceptor.ts +8 -8
  24. package/src/http/interceptor/RemoteHttpInterceptor.ts +8 -8
  25. package/src/http/interceptor/errors/RequestSavingSafeLimitExceededError.ts +22 -0
  26. package/src/http/interceptor/factory.ts +1 -1
  27. package/src/http/interceptor/types/options.ts +4 -11
  28. package/src/http/interceptor/types/public.ts +44 -12
  29. package/src/http/interceptor/types/schema.ts +2 -2
  30. package/src/http/interceptorWorker/HttpInterceptorWorker.ts +6 -31
  31. package/src/http/requestHandler/HttpRequestHandlerClient.ts +15 -5
  32. package/src/http/requestHandler/errors/DisabledRequestSavingError.ts +2 -2
  33. package/src/http/requestHandler/errors/TimesCheckError.ts +15 -14
  34. package/src/http/requestHandler/types/public.ts +16 -8
  35. package/src/server/index.ts +1 -11
  36. package/src/utils/console.ts +2 -2
  37. package/dist/chunk-6TSSHQW5.mjs.map +0 -1
  38. package/dist/chunk-R2ROSKU4.js.map +0 -1
  39. package/src/http/interceptorWorker/HttpInterceptorWorkerStore.ts +0 -34
  40. package/src/http/namespace/HttpInterceptorNamespace.ts +0 -81
  41. package/src/server/namespace/InterceptorServerNamespace.ts +0 -21
@@ -13,7 +13,7 @@ import {
13
13
  } from '@zimic/http';
14
14
  import isDefined from '@zimic/utils/data/isDefined';
15
15
  import { Default, PossiblePromise } from '@zimic/utils/types';
16
- import chalk from 'chalk';
16
+ import color from 'picocolors';
17
17
 
18
18
  import { removeArrayElement } from '@/utils/arrays';
19
19
  import { formatValueToLog, logWithPrefix } from '@/utils/console';
@@ -35,7 +35,6 @@ import {
35
35
  import { DEFAULT_UNHANDLED_REQUEST_STRATEGY } from './constants';
36
36
  import InvalidFormDataError from './errors/InvalidFormDataError';
37
37
  import InvalidJSONError from './errors/InvalidJSONError';
38
- import HttpInterceptorWorkerStore from './HttpInterceptorWorkerStore';
39
38
  import { HttpResponseFactory } from './types/requests';
40
39
 
41
40
  abstract class HttpInterceptorWorker {
@@ -47,8 +46,6 @@ abstract class HttpInterceptorWorker {
47
46
  private startingPromise?: Promise<void>;
48
47
  private stoppingPromise?: Promise<void>;
49
48
 
50
- private store = new HttpInterceptorWorkerStore();
51
-
52
49
  private runningInterceptors: AnyHttpInterceptorClient[] = [];
53
50
 
54
51
  abstract start(): Promise<void>;
@@ -142,7 +139,7 @@ abstract class HttpInterceptorWorker {
142
139
  request: Request,
143
140
  interceptorType: HttpInterceptorType,
144
141
  ): Promise<UnhandledRequestStrategy.Declaration[]> {
145
- const globalDefaultStrategy = this.getGlobalDefaultUnhandledRequestStrategy(interceptorType);
142
+ const globalDefaultStrategy = DEFAULT_UNHANDLED_REQUEST_STRATEGY[interceptorType];
146
143
 
147
144
  try {
148
145
  const interceptor = this.findInterceptorByRequestBaseURL(request);
@@ -152,20 +149,13 @@ abstract class HttpInterceptorWorker {
152
149
  }
153
150
 
154
151
  const requestClone = request.clone();
152
+ const interceptorStrategy = await this.getInterceptorUnhandledRequestStrategy(requestClone, interceptor);
155
153
 
156
- const [defaultStrategy, interceptorStrategy] = await Promise.all([
157
- this.getDefaultUnhandledRequestStrategy(request, interceptorType),
158
- this.getInterceptorUnhandledRequestStrategy(requestClone, interceptor),
159
- ]);
160
-
161
- const candidatesOrPromises = [interceptorStrategy, defaultStrategy, globalDefaultStrategy];
162
- const candidateStrategies = await Promise.all(candidatesOrPromises.filter(isDefined));
163
- return candidateStrategies;
154
+ return [interceptorStrategy, globalDefaultStrategy].filter(isDefined);
164
155
  } catch (error) {
165
156
  console.error(error);
166
157
 
167
- const candidateStrategies = [globalDefaultStrategy];
168
- return candidateStrategies;
158
+ return [globalDefaultStrategy];
169
159
  }
170
160
  }
171
161
 
@@ -185,21 +175,6 @@ abstract class HttpInterceptorWorker {
185
175
  return interceptor;
186
176
  }
187
177
 
188
- private getGlobalDefaultUnhandledRequestStrategy(interceptorType: HttpInterceptorType) {
189
- return DEFAULT_UNHANDLED_REQUEST_STRATEGY[interceptorType];
190
- }
191
-
192
- private async getDefaultUnhandledRequestStrategy(request: Request, interceptorType: HttpInterceptorType) {
193
- const defaultStrategyOrFactory = this.store.defaultOnUnhandledRequest(interceptorType);
194
-
195
- if (typeof defaultStrategyOrFactory === 'function') {
196
- const parsedRequest = await HttpInterceptorWorker.parseRawUnhandledRequest(request);
197
- return defaultStrategyOrFactory(parsedRequest);
198
- }
199
-
200
- return defaultStrategyOrFactory;
201
- }
202
-
203
178
  private async getInterceptorUnhandledRequestStrategy(request: Request, interceptor: AnyHttpInterceptorClient) {
204
179
  if (typeof interceptor.onUnhandledRequest === 'function') {
205
180
  const parsedRequest = await HttpInterceptorWorker.parseRawUnhandledRequest(request);
@@ -502,7 +477,7 @@ abstract class HttpInterceptorWorker {
502
477
  logWithPrefix(
503
478
  [
504
479
  `${action === 'bypass' ? 'Warning:' : 'Error:'} Request was not handled and was ` +
505
- `${action === 'bypass' ? chalk.yellow('bypassed') : chalk.red('rejected')}.\n\n `,
480
+ `${action === 'bypass' ? color.yellow('bypassed') : color.red('rejected')}.\n\n `,
506
481
  `${request.method} ${request.url}`,
507
482
  '\n Headers:',
508
483
  formattedHeaders,
@@ -91,7 +91,8 @@ class HttpRequestHandlerClient<
91
91
 
92
92
  newThis.numberOfMatchedRequests = 0;
93
93
  newThis.unmatchedRequestGroups.length = 0;
94
- newThis._requests.length = 0;
94
+
95
+ newThis.clearInterceptedRequests();
95
96
 
96
97
  this.interceptor.registerRequestHandler(this.handler);
97
98
 
@@ -132,7 +133,7 @@ class HttpRequestHandlerClient<
132
133
  declarationPointer: this.timesDeclarationPointer,
133
134
  unmatchedRequestGroups: this.unmatchedRequestGroups,
134
135
  hasRestrictions: this.restrictions.length > 0,
135
- hasSavedRequests: this.interceptor.saveRequests,
136
+ requestSaving: this.interceptor.requestSaving,
136
137
  });
137
138
  }
138
139
  }
@@ -148,7 +149,8 @@ class HttpRequestHandlerClient<
148
149
 
149
150
  this.numberOfMatchedRequests = 0;
150
151
  this.unmatchedRequestGroups.length = 0;
151
- this._requests.length = 0;
152
+
153
+ this.clearInterceptedRequests();
152
154
 
153
155
  this.createResponseDeclaration = undefined;
154
156
 
@@ -168,7 +170,9 @@ class HttpRequestHandlerClient<
168
170
  this.numberOfMatchedRequests++;
169
171
  } else {
170
172
  const shouldSaveUnmatchedGroup =
171
- this.interceptor.saveRequests && this.restrictions.length > 0 && this.timesDeclarationPointer !== undefined;
173
+ this.interceptor.requestSaving.enabled &&
174
+ this.restrictions.length > 0 &&
175
+ this.timesDeclarationPointer !== undefined;
172
176
 
173
177
  if (shouldSaveUnmatchedGroup) {
174
178
  this.unmatchedRequestGroups.push({ request, diff: restrictionsMatch.diff });
@@ -378,6 +382,12 @@ class HttpRequestHandlerClient<
378
382
  ) {
379
383
  const interceptedRequest = this.createInterceptedRequest(request, response);
380
384
  this._requests.push(interceptedRequest);
385
+ this.interceptor.incrementNumberOfSavedRequests(1);
386
+ }
387
+
388
+ private clearInterceptedRequests() {
389
+ this.interceptor.incrementNumberOfSavedRequests(-this._requests.length);
390
+ this._requests.length = 0;
381
391
  }
382
392
 
383
393
  private createInterceptedRequest(
@@ -401,7 +411,7 @@ class HttpRequestHandlerClient<
401
411
  }
402
412
 
403
413
  get requests(): readonly InterceptedHttpInterceptorRequest<Path, Default<Schema[Path][Method]>, StatusCode>[] {
404
- if (!this.interceptor.saveRequests) {
414
+ if (!this.interceptor.requestSaving.enabled) {
405
415
  throw new DisabledRequestSavingError();
406
416
  }
407
417
 
@@ -6,8 +6,8 @@
6
6
  class DisabledRequestSavingError extends TypeError {
7
7
  constructor() {
8
8
  super(
9
- 'Intercepted requests are not saved by default. ' +
10
- 'Did you forget to use `saveRequests: true` when creating the interceptor?\n\n' +
9
+ 'Intercepted requests are not being saved. ' +
10
+ 'Did you forget to use `requestSaving.enabled: true` in your interceptor?\n\n' +
11
11
  'Learn more: https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests',
12
12
  );
13
13
  this.name = 'DisabledRequestSavingError';
@@ -1,7 +1,8 @@
1
1
  import isNonEmpty from '@zimic/utils/data/isNonEmpty';
2
2
  import { Range } from '@zimic/utils/types';
3
- import chalk from 'chalk';
3
+ import color from 'picocolors';
4
4
 
5
+ import { HttpInterceptorRequestSaving } from '@/http/interceptor/types/public';
5
6
  import { stringifyValueToLog } from '@/utils/console';
6
7
 
7
8
  import { UnmatchedHttpInterceptorRequestGroup } from '../types/restrictions';
@@ -13,7 +14,7 @@ interface TimesCheckErrorOptions {
13
14
  declarationPointer: TimesDeclarationPointer | undefined;
14
15
  unmatchedRequestGroups: UnmatchedHttpInterceptorRequestGroup[];
15
16
  hasRestrictions: boolean;
16
- hasSavedRequests: boolean;
17
+ requestSaving: HttpInterceptorRequestSaving;
17
18
  }
18
19
 
19
20
  function createMessageHeader({
@@ -45,15 +46,15 @@ function createMessageHeader({
45
46
  '.',
46
47
 
47
48
  unmatchedRequestGroups.length > 0 &&
48
- `\n\nRequests evaluated by this handler:\n\n ${chalk.green('- Expected')}\n ${chalk.red('+ Received')}`,
49
+ `\n\nRequests evaluated by this handler:\n\n ${color.green('- Expected')}\n ${color.red('+ Received')}`,
49
50
  ]
50
51
  .filter((part) => part !== false)
51
52
  .join('');
52
53
  }
53
54
 
54
- function createMessageDiffs({ hasSavedRequests, unmatchedRequestGroups }: TimesCheckErrorOptions) {
55
- if (!hasSavedRequests) {
56
- return 'Tip: enable `saveRequests: true` in your interceptor for more details about the unmatched requests.';
55
+ function createMessageDiffs({ requestSaving, unmatchedRequestGroups }: TimesCheckErrorOptions) {
56
+ if (!requestSaving.enabled) {
57
+ return 'Tip: use `requestSaving.enabled: true` in your interceptor for more details about the unmatched requests.';
57
58
  }
58
59
 
59
60
  return unmatchedRequestGroups
@@ -68,8 +69,8 @@ function createMessageDiffs({ hasSavedRequests, unmatchedRequestGroups }: TimesC
68
69
  const stringifiedExpected = stringifyValueToLog(diff.computed.expected);
69
70
  const stringifiedReceived = stringifyValueToLog(diff.computed.received);
70
71
 
71
- messageParts.push(` ${chalk.green(`- return ${stringifiedExpected}`)}`);
72
- messageParts.push(` ${chalk.red(`+ return ${stringifiedReceived}`)}`);
72
+ messageParts.push(` ${color.green(`- return ${stringifiedExpected}`)}`);
73
+ messageParts.push(` ${color.red(`+ return ${stringifiedReceived}`)}`);
73
74
  }
74
75
 
75
76
  if (diff.headers) {
@@ -78,8 +79,8 @@ function createMessageDiffs({ hasSavedRequests, unmatchedRequestGroups }: TimesC
78
79
  const stringifiedExpected = stringifyValueToLog(diff.headers.expected);
79
80
  const stringifiedReceived = stringifyValueToLog(diff.headers.received);
80
81
 
81
- messageParts.push(` ${chalk.green(`- ${stringifiedExpected}`)}`);
82
- messageParts.push(` ${chalk.red(`+ ${stringifiedReceived}`)}`);
82
+ messageParts.push(` ${color.green(`- ${stringifiedExpected}`)}`);
83
+ messageParts.push(` ${color.red(`+ ${stringifiedReceived}`)}`);
83
84
  }
84
85
 
85
86
  if (diff.searchParams) {
@@ -88,8 +89,8 @@ function createMessageDiffs({ hasSavedRequests, unmatchedRequestGroups }: TimesC
88
89
  const stringifiedExpected = stringifyValueToLog(diff.searchParams.expected);
89
90
  const stringifiedReceived = stringifyValueToLog(diff.searchParams.received);
90
91
 
91
- messageParts.push(` ${chalk.green(`- ${stringifiedExpected}`)}`);
92
- messageParts.push(` ${chalk.red(`+ ${stringifiedReceived}`)}`);
92
+ messageParts.push(` ${color.green(`- ${stringifiedExpected}`)}`);
93
+ messageParts.push(` ${color.red(`+ ${stringifiedReceived}`)}`);
93
94
  }
94
95
 
95
96
  if (diff.body) {
@@ -102,8 +103,8 @@ function createMessageDiffs({ hasSavedRequests, unmatchedRequestGroups }: TimesC
102
103
  includeClassName: { searchParams: true },
103
104
  });
104
105
 
105
- messageParts.push(` ${chalk.green(`- ${stringifiedExpected}`)}`);
106
- messageParts.push(` ${chalk.red(`+ ${stringifiedReceived}`)}`);
106
+ messageParts.push(` ${color.green(`- ${stringifiedExpected}`)}`);
107
+ messageParts.push(` ${color.red(`+ ${stringifiedReceived}`)}`);
107
108
  }
108
109
 
109
110
  return messageParts.join('\n ');
@@ -147,8 +147,9 @@ export interface LocalHttpRequestHandler<
147
147
  * that was not satisfied.
148
148
  *
149
149
  * When
150
- * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httpinterceptorcreateoptions `saveRequests: true`}
151
- * is enabled in your interceptor, the `TimesCheckError` errors will also list each unmatched request with diff of the
150
+ * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests
151
+ * `requestSaving.enabled`} is
152
+ * `true` in your interceptor, the `TimesCheckError` errors will also list each unmatched request with diff of the
152
153
  * expected and received data. This is useful for debugging requests that did not match a handler with
153
154
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerwithrestriction restrictions}.
154
155
  *
@@ -178,11 +179,14 @@ export interface LocalHttpRequestHandler<
178
179
  * The intercepted requests that matched this handler, along with the responses returned to each of them. This is
179
180
  * useful for testing that the correct requests were made by your application.
180
181
  *
181
- * **Important**: This method can only be used if `saveRequests` was set to `true` when creating the interceptor. See
182
+ * **Important**: This method can only be used if
183
+ * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests
184
+ * `requestSaving.enabled`} is
185
+ * `true` in the interceptor. See
182
186
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests Saving intercepted requests}
183
187
  * for more information.
184
188
  *
185
- * @throws {DisabledRequestSavingError} If the interceptor was not created with `saveRequests: true`.
189
+ * @throws {DisabledRequestSavingError} If the interceptor has `requestSaving.enabled: false`.
186
190
  * @readonly
187
191
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerrequests `handler.requests` API reference}
188
192
  */
@@ -284,8 +288,9 @@ export interface SyncedRemoteHttpRequestHandler<
284
288
  * that was not satisfied.
285
289
  *
286
290
  * When
287
- * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#httpinterceptorcreateoptions `saveRequests: true`}
288
- * is enabled in your interceptor, the `TimesCheckError` errors will also list each unmatched request with diff of the
291
+ * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests
292
+ * `requestSaving.enabled`} is
293
+ * true in your interceptor, the `TimesCheckError` errors will also list each unmatched request with diff of the
289
294
  * expected and received data. This is useful for debugging requests that did not match a handler with
290
295
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerwithrestriction restrictions}.
291
296
  *
@@ -315,11 +320,14 @@ export interface SyncedRemoteHttpRequestHandler<
315
320
  * The intercepted requests that matched this handler, along with the responses returned to each of them. This is
316
321
  * useful for testing that the correct requests were made by your application.
317
322
  *
318
- * **Important**: This method can only be used if `saveRequests` was set to `true` when creating the interceptor. See
323
+ * **Important**: This method can only be used if
324
+ * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests
325
+ * `requestSaving.enabled`} is
326
+ * `true` in the interceptor. See
319
327
  * {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#saving-requests Saving intercepted requests}
320
328
  * for more information.
321
329
  *
322
- * @throws {DisabledRequestSavingError} If the interceptor was not created with `saveRequests: true`.
330
+ * @throws {DisabledRequestSavingError} If the interceptor has `requestSaving.enabled: false`.
323
331
  * @readonly
324
332
  * @see {@link https://github.com/zimicjs/zimic/wiki/api‐zimic‐interceptor‐http#http-handlerrequests `handler.requests` API reference}
325
333
  */
@@ -1,5 +1,3 @@
1
- import InterceptorServerNamespace from './namespace/InterceptorServerNamespace';
2
-
3
1
  export { default as RunningInterceptorServerError } from './errors/RunningInterceptorServerError';
4
2
  export { default as NotRunningInterceptorServerError } from './errors/NotRunningInterceptorServerError';
5
3
 
@@ -8,12 +6,4 @@ export type { InterceptorServer } from './types/public';
8
6
 
9
7
  export { DEFAULT_ACCESS_CONTROL_HEADERS, DEFAULT_PREFLIGHT_STATUS_CODE } from './constants';
10
8
 
11
- /**
12
- * A namespace of interceptor server resources for handling HTTP requests.
13
- *
14
- * @see {@link https://github.com/zimicjs/zimic/wiki/cli‐zimic‐server#zimic-server `zimic-interceptor server` API reference}
15
- * @see {@link https://github.com/zimicjs/zimic/wiki/getting‐started#remote-http-interceptors Remote HTTP Interceptors} .
16
- */
17
- export const interceptorServer = Object.freeze(new InterceptorServerNamespace());
18
-
19
- export type { InterceptorServerNamespace };
9
+ export { createInterceptorServer } from './factory';
@@ -1,6 +1,6 @@
1
1
  import { HttpFormData, HttpHeaders, HttpSearchParams } from '@zimic/http';
2
2
  import createCachedDynamicImport from '@zimic/utils/import/createCachedDynamicImport';
3
- import chalk from 'chalk';
3
+ import color from 'picocolors';
4
4
 
5
5
  import { isClientSide } from './environment';
6
6
  import { isGlobalFileAvailable } from './files';
@@ -84,5 +84,5 @@ export function logWithPrefix(messageOrMessages: unknown, options: { method?: 'l
84
84
  const { method = 'log' } = options;
85
85
 
86
86
  const messages = Array.isArray(messageOrMessages) ? messageOrMessages : [messageOrMessages];
87
- console[method](chalk.cyan('[@zimic/interceptor]'), ...messages);
87
+ console[method](color.cyan('[@zimic/interceptor]'), ...messages);
88
88
  }