UNPKG

mockttp

Version:

Mock HTTP server for testing HTTP clients and stubbing webservices

407 lines 13.2 kB
import type * as stream from 'stream'; import type * as http from 'http'; import type { EventEmitter } from 'events'; export declare const DEFAULT_ADMIN_SERVER_PORT = 45454; export declare enum Method { GET = 0, POST = 1, PUT = 2, DELETE = 3, PATCH = 4, HEAD = 5, OPTIONS = 6 } export declare enum RulePriority { FALLBACK = 0, DEFAULT = 1 } export interface Headers { host?: string; 'content-length'?: string; 'content-type'?: string; 'user-agent'?: string; cookie?: string; ':method'?: string; ':scheme'?: string; ':authority'?: string; ':path'?: string; [key: string]: undefined | string | string[]; } export interface Trailers { [key: string]: undefined | string | string[]; } export type RawHeaders = Array<[key: string, value: string]>; export type RawTrailers = RawHeaders; export interface Destination { hostname: string; port: number; } export interface Request { id: string; matchedRuleId?: string; protocol: string; httpVersion: string; method: string; url: string; path: string; remoteIpAddress?: string; remotePort?: number; /** * The best guess at the target host + port of the request. This uses tunnelling metadata * wherever possible, or the headers if not. */ destination: Destination; headers: Headers; rawHeaders: RawHeaders; timingEvents: TimingEvents; tags: string[]; } export interface TlsConnectionEvent { remoteIpAddress?: string; remotePort?: number; tags: string[]; timingEvents: TlsTimingEvents; destination?: Destination; tlsMetadata: TlsSocketMetadata; } export interface TlsSocketMetadata { sniHostname?: string; clientAlpn?: string[]; ja3Fingerprint?: string; ja4Fingerprint?: string; } export interface TlsPassthroughEvent extends RawPassthroughEvent, TlsConnectionEvent { destination: Destination; remoteIpAddress: string; remotePort: number; timingEvents: TlsTimingEvents; } export interface TlsHandshakeFailure extends TlsConnectionEvent { failureCause: 'closed' | 'reset' | 'cert-rejected' | 'no-shared-cipher' | 'handshake-timeout' | 'unknown'; timingEvents: TlsFailureTimingEvents; } export interface RawPassthroughEvent { id: string; destination: Destination; /** * The IP address of the remote client that initiated the connection. */ remoteIpAddress: string; /** * The port of the remote client that initiated the connection. */ remotePort: number; tags: string[]; timingEvents: ConnectionTimingEvents; } export interface RawPassthroughDataEvent { /** * The id of the passthrough tunnel. */ id: string; /** * The direction of the message, from the downstream perspective (received from the client, * or sent back to the client). */ direction: 'sent' | 'received'; /** * The contents of the message as a raw buffer. */ content: Uint8Array; /** * A high-precision floating-point monotonically increasing timestamp. * Comparable and precise, but not related to specific current time. * * To link this to the current time, compare it to `timingEvents.startTime`. */ eventTimestamp: number; } export interface ConnectionTimingEvents { /** * When the socket initially connected, in MS since the unix * epoch. */ startTime: number; /** * When the socket initially connected, equivalent to startTime. * * High-precision floating-point monotonically increasing timestamps. * Comparable and precise, but not related to specific current time. */ connectTimestamp: number; /** * When the outer tunnel (e.g. a preceeding CONNECT request/SOCKS * connection) was created, if there was one. */ tunnelTimestamp?: number; /** * When the connection was closed, if it has been closed. */ disconnectTimestamp?: number; } export interface TlsTimingEvents extends ConnectionTimingEvents { /** * When Mockttp's handshake for this connection was completed (if there * was one). This is not set for passed through connections. */ handshakeTimestamp?: number; } export interface TlsFailureTimingEvents extends TlsTimingEvents { /** * When the TLS connection failed. This may be due to a failed handshake * (in which case `handshakeTimestamp` will be undefined) or due to a * subsequent error which means the TLS connection was not usable (like * an immediate closure due to an async certificate rejection). */ failureTimestamp: number; } export interface OngoingRequest extends Request, EventEmitter { body: OngoingBody; rawTrailers?: RawHeaders; } export interface OngoingBody { asStream: () => stream.Readable; asBuffer: () => Promise<Buffer>; asDecodedBuffer: () => Promise<Buffer>; asText: () => Promise<string>; asJson: () => Promise<object>; asFormData: () => Promise<{ [key: string]: string | string[] | undefined; }>; } export interface CompletedBody { /** * The raw bytes of the response. If a content encoding was used, this is * the raw encoded data. */ buffer: Buffer; /** * The decoded bytes of the response. If no encoding was used, this is the * same as `.buffer`. The response is decoded and returned asynchronously * as a Promise. */ getDecodedBuffer(): Promise<Buffer | undefined>; /** * The contents of the response, decoded and parsed as a UTF-8 string. * The response is decoded and returned asynchronously as a Promise. */ getText(): Promise<string | undefined>; /** * The contents of the response, decoded, parsed as UTF-8 string, and * then parsed a JSON. The response is decoded and returned asynchronously * as a Promise. */ getJson(): Promise<object | undefined>; /** * The contents of the response, decoded, and then parsed automatically as * either one of the form encoding types (either URL-encoded or multipart), * determined automatically from the message content-type header. * * This method is convenient and offers a single mechanism to parse both * formats, but you may want to consider parsing on format explicitly with * the `getUrlEncodedFormData()` or `getMultipartFormData()` methods instead. * * After parsing & decoding, the result is returned asynchronously as a * Promise for a key-value(s) object. */ getFormData(): Promise<{ [key: string]: string | string[] | undefined; } | undefined>; /** * The contents of the response, decoded, parsed as UTF-8 string, and then * parsed as URL-encoded form data. After parsing & decoding, the result is * returned asynchronously as a Promise for a key-value(s) object. */ getUrlEncodedFormData(): Promise<{ [key: string]: string | string[] | undefined; } | undefined>; /** * The contents of the response, decoded, and then parsed as multi-part * form data. The response is result is returned asynchronously as a * Promise for an array of parts with their names, data and metadata. */ getMultipartFormData(): Promise<Array<{ name?: string; filename?: string; type?: string; data: Buffer; }> | undefined>; } export type InitiatedRequest = Request; export interface AbortedRequest extends InitiatedRequest { error?: { name?: string; code?: string; message?: string; stack?: string; }; } export interface CompletedRequest extends Request { body: CompletedBody; rawTrailers: RawTrailers; trailers: Trailers; } export interface TimingEvents { startTime: number; startTimestamp: number; bodyReceivedTimestamp?: number; headersSentTimestamp?: number; responseSentTimestamp?: number; wsAcceptedTimestamp?: number; wsClosedTimestamp?: number; abortedTimestamp?: number; } export interface OngoingResponse extends http.ServerResponse { id: string; getHeaders(): Headers; getRawHeaders(): RawHeaders; body: OngoingBody; getRawTrailers(): RawTrailers; timingEvents: TimingEvents; tags: string[]; } export interface CompletedResponse { id: string; statusCode: number; statusMessage: string; headers: Headers; rawHeaders: RawHeaders; body: CompletedBody; rawTrailers: RawTrailers; trailers: Trailers; timingEvents: TimingEvents; tags: string[]; } export interface WebSocketMessage { /** * The id of this websocket stream. This will match the id of the request, * the initial connection response, and any other WebSocket events for the * same connection stream. */ streamId: string; /** * Whether the message was sent by Mockttp, or received from a Mockttp client. */ direction: 'sent' | 'received'; /** * The contents of the message as a raw buffer. This is already decompressed, * if the WebSocket uses compression. */ content: Uint8Array; /** * Whether this is a string message or a raw binary data message. */ isBinary: boolean; /** * A high-precision floating-point monotonically increasing timestamp. * Comparable and precise, but not related to specific current time. * * To link this to the current time, compare it to `timingEvents.startTime`. */ eventTimestamp: number; timingEvents: TimingEvents; tags: string[]; } export interface WebSocketClose { /** * The id of this websocket stream. This will match the id of the request, * the initial connection response, and any other WebSocket events for the * same connection stream. */ streamId: string; /** * The close code of the shutdown. This is the close code that was received * from the remote client (either initiated remotely, or echoing our own sent * close frame). * * This may be undefined only if a close frame was received but did not contain * any close code. If no close frame was received before the connection was * lost (i.e. the connection was not cleanly closed) this event will not * fire at all, and an 'abort' event will fire instead. */ closeCode: number | undefined; /** * The close reason of the shutdown. */ closeReason: string; timingEvents: TimingEvents; tags: string[]; } /** * A client error event describes a request (or our best guess at parsing it), * that wasn't correctly completed, and the error response it received, or * 'aborted' if the connection was disconnected before we could respond. */ export interface ClientError { errorCode?: string; request: { id: string; timingEvents: TimingEvents; tags: string[]; protocol?: string; httpVersion: string; method?: string; url?: string; path?: string; destination?: Destination; headers: Headers; rawHeaders: RawHeaders; remoteIpAddress?: string; remotePort?: number; }; response: CompletedResponse | 'aborted'; } /** * An event fired from an individual rule during request processing. */ export interface RuleEvent<T = unknown> { requestId: string; ruleId: string; eventType: string; eventData: T; } /** * A mocked endpoint provides methods to see the current state of * a mock rule. */ export interface MockedEndpoint { id: string; /** * Get the requests that this endpoint has seen so far. * * This method returns a promise, which resolves with the requests seen * up until now, once all ongoing requests have terminated. The returned * lists are immutable, so won't change if more requests arrive in future. * Call `getSeenRequests` again later to get an updated list. * * Requests are included here once the response is completed, even if the request * itself failed, the responses failed or exceptions are thrown elsewhere. To * watch for errors or detailed response info, look at the various server.on(event) * methods. */ getSeenRequests(): Promise<CompletedRequest[]>; /** * Reports whether this endpoint is still pending: if it either hasn't seen the * specified number of requests (if one was specified e.g. with .twice()) * or if it hasn't seen at least one request, by default. * * This method returns a promise, which resolves with the result once all * ongoing requests have terminated. */ isPending(): Promise<boolean>; } export interface MockedEndpointData { id: string; explanation?: string; seenRequests: CompletedRequest[]; isPending: boolean; } export interface Explainable { explain(): string; } export interface ProxyEnvConfig { HTTP_PROXY: string; HTTPS_PROXY: string; } export type defaultMaxListeners = typeof EventEmitter.defaultMaxListeners; //# sourceMappingURL=types.d.ts.map