import { HttpSchema, HttpSchemaMethod, HttpSchemaPath, HttpStatusCode } from '@zimic/http'; import { Default } from '@zimic/utils/types'; import HttpInterceptorImplementation from '../interceptor/HttpInterceptorImplementation'; import HttpRequestHandlerImplementation from './HttpRequestHandlerImplementation'; import { InternalHttpRequestHandler } from './types/public'; import { HttpInterceptorRequest, HttpInterceptorResponse, HttpRequestHandlerResponseDeclaration, HttpRequestHandlerResponseDeclarationFactory, HttpRequestHandlerResponseDelayFactory, InterceptedHttpInterceptorRequest, } from './types/requests'; import { HttpRequestHandlerRestriction } from './types/restrictions'; class LocalHttpRequestHandler< Schema extends HttpSchema, Method extends HttpSchemaMethod, Path extends HttpSchemaPath, StatusCode extends HttpStatusCode = never, > implements InternalHttpRequestHandler { readonly type = 'local'; implementation: HttpRequestHandlerImplementation; constructor(interceptor: HttpInterceptorImplementation, method: Method, path: Path) { this.implementation = new HttpRequestHandlerImplementation(interceptor, method, path, this); } get method() { return this.implementation.method; } get path() { return this.implementation.path; } with(restriction: HttpRequestHandlerRestriction): this { this.implementation.with(restriction); return this; } delay( minMilliseconds: number | HttpRequestHandlerResponseDelayFactory>, maxMilliseconds?: number, ): this { this.implementation.delay(minMilliseconds, maxMilliseconds); return this; } respond( declaration: | HttpRequestHandlerResponseDeclaration, NewStatusCode> | HttpRequestHandlerResponseDeclarationFactory, NewStatusCode>, ): LocalHttpRequestHandler { this.implementation.respond(declaration); const newThis = this as unknown as LocalHttpRequestHandler; return newThis; } times(minNumberOfRequests: number, maxNumberOfRequests?: number): this { this.implementation.times(minNumberOfRequests, maxNumberOfRequests); return this; } checkTimes() { this.implementation.checkTimes(); } clear(): this { this.implementation.clear(); return this; } get requests(): readonly InterceptedHttpInterceptorRequest, StatusCode>[] { return this.implementation.requests; } async matchesRequest(request: HttpInterceptorRequest>) { const requestMatch = await this.implementation.matchesRequest(request); if (requestMatch.success) { this.implementation.markRequestAsMatched(request); } else if (requestMatch.cause === 'unmatchedRestrictions') { this.implementation.markRequestAsUnmatched(request, { diff: requestMatch.diff }); } else { this.implementation.markRequestAsMatched(request); } return requestMatch; } async applyResponseDeclaration(request: HttpInterceptorRequest>) { return this.implementation.applyResponseDeclaration(request); } saveInterceptedRequest( request: HttpInterceptorRequest>, response: HttpInterceptorResponse, StatusCode>, ) { this.implementation.saveInterceptedRequest(request, response); } } export type AnyLocalHttpRequestHandler = // eslint-disable-next-line @typescript-eslint/no-explicit-any | LocalHttpRequestHandler // eslint-disable-next-line @typescript-eslint/no-explicit-any | LocalHttpRequestHandler; export default LocalHttpRequestHandler;