UNPKG

@amadeus-it-group/kassette

Version:

Development server, used mainly for testing, which proxies requests and is able to easily manage local mocks.

1,257 lines (1,230 loc) 71.4 kB
/** * kassette is a development server, used mainly for testing, which proxies requests and is able to easily manage local mocks. * * @packageDocumentation */ import * as crypto_2 from 'crypto'; import { Http2ServerRequest } from 'http2'; import { Http2ServerResponse } from 'http2'; import { IncomingHttpHeaders } from 'http'; import { IncomingMessage } from 'http'; import { ServerHttp2Stream } from 'http2'; import { ServerResponse } from 'http'; import { Socket } from 'net'; import { URL as URL_2 } from 'url'; /** * Specifies the argument expected to start kassette programmatically with {@link runFromAPI}. * * @public */ export declare interface APIOptions { /** * kassette configuration passed through the API. * * @remarks * * If {@link APIOptions.configurationPath|configurationPath} is also specified, both configurations are merged, * but `apiConfiguration` has the least precedence. * However, this object is also forwarded to the configuration file's {@link IConfigurationFile.getConfiguration|getConfiguration} * method, as {@link GetConfigurationProps.apiConfiguration|apiConfiguration}, so you can apply your own logic to determine what configuration * to actually use. */ readonly apiConfiguration?: ConfigurationSpec; /** * Path to a configuration file, if the configuration should be loaded from a configuration file. */ readonly configurationPath?: string; /** * Specifies the context argument passed to the {@link IConfigurationFile.getConfiguration|getConfiguration} function defined in the * configuration file (only used if {@link APIOptions.configurationPath|configurationPath} is specified). */ readonly fileConfigurationContext?: any; } /** * Type of the argument expected by {@link IMock.checksum|checksum}. * It specifies which data from the request to include in the checksum. * * @remarks * To include or exclude data, not every kind of data from the request has the * same complexity. For instance, the HTTP method is simple: use it or don't * use it. But for things like query parameters, headers, body: you might want to * select/filter. * * @public */ export declare interface ChecksumArgs { /** * Specifies the hash algorithm. Default value is `sha256`. * Check Node.js API for more information: {@link https://nodejs.org/api/crypto.html#crypto_crypto_createhash_algorithm_options|crypto.createHash(type)}. */ type?: string; /** * Specifies the output format. Default value is `hex`. * Check Node.js API for more information: {@link https://nodejs.org/api/crypto.html#crypto_hash_digest_encoding|hash.digest(format)}. */ format?: crypto_2.BinaryToTextEncoding; /** * Specifies whether to include the protocol in the hash. The default value is `false`. */ protocol?: IncludableSpec | boolean; /** * Specifies whether and how to include the hostname in the hash. The default value is `false`. */ hostname?: FilterableSpec<string> | boolean; /** * Specifies whether to include the port in the hash. The default value is `false`. */ port?: IncludableSpec | boolean; /** * Specifies whether to include the method in the hash. The default value is `false`. */ method?: IncludableSpec | boolean; /** * Specifies whether and how to include the pathname part of the url in the hash. The default value is `false`. */ pathname?: FilterableSpec<string> | boolean; /** * Specifies whether and how to include the body of the request in the hash. The default value is `true`. */ body?: FilterableSpec<Buffer, Buffer | string> | boolean; /** * Specifies whether and how to include the query part of the url in the hash. The default value is `true`. */ query?: ListOrFilter | boolean; /** * Specifies whether and how to include the headers in the hash. * The default value is `false`. */ headers?: ListOrFilter | boolean; /** * Any custom value (which can be JSON stringified) to be added in the content * to be hashed. */ customData?: any | null; } /** * The set of possible properties defined through the CLI * (it is reduced since it can't contain runtime values) * * @public */ export declare interface CLIConfigurationSpec { /** * If true, will simplify the logging output, logging only one line * when the request is received but nothing else afterwards. */ readonly skipLog?: boolean; /** * The port on which the proxy should listen. Note that kassette accepts both http and https connections on this port. * * @remarks * * If the port is not available, it will fail and stop the program; try again with another, available port. * If the port is set to 0, the proxy will listen on a random port * (actually depends on the OS implementation): use the callback {@link ConfigurationSpec.onListen|onListen} to catch its value. */ readonly port?: number; /** * The hostname on which the proxy should listen. * Uses `127.0.0.1` by default, which only allows local connections. * To allow remote connections, use the ip address of the specific network interface that should be allowed to connect * or the unspecified IPv4 (`0.0.0.0`) or IPv6 (`::`) address. * * @remarks * * Note that kassette has not been reviewed for security issues. * It is intended to be used in a safe local/testing environment. * Binding it to an open connection can result in compromising your * computer or your network. */ readonly hostname?: string; /** * The default mode. * * @remarks * * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method * through {@link IMock.setMode|mock.setMode}. */ readonly mode?: Mode; /** * The default mocks format. * * @remarks * * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method * through {@link IMock.setMocksFormat|mock.setMocksFormat}. * * The default value of the global `mocksFormat` setting is `folder`, except in the following case: * if the global {@link CLIConfigurationSpec.mocksHarFile|mocksHarFile} setting is defined * and the global {@link CLIConfigurationSpec.mocksFolder|mocksFolder} setting is not defined, * then the default value of the global `mocksFormat` setting is `har`. */ readonly mocksFormat?: MocksFormat; /** * Whether to save the content used to create a checksum when creating a new mock with a checksum. * * @remarks * * The default value of the global `saveChecksumContent` setting is `true`. * * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method * through {@link IMock.setSaveChecksumContent|mock.setSaveChecksumContent}. */ readonly saveChecksumContent?: boolean; /** * Whether to save {@link RequestTimings | detailed timings} when creating a new mock. * * @remarks * * The default value of the global `saveDetailedTimings` setting is `true`. * * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method * through {@link IMock.setSaveDetailedTimings|mock.setSaveDetailedTimings}. */ readonly saveDetailedTimings?: boolean; /** * Whether to save the input request data (headers, method, URL) when creating a new mock. * * @remarks * * The default value of the global `saveInputRequestData` setting is `true`. * * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method * through {@link IMock.setSaveInputRequestData|mock.setSaveInputRequestData}. */ readonly saveInputRequestData?: boolean; /** * Whether to save the content of the input request body when creating a new mock. * * @remarks * * The default value of the global `saveInputRequestBody` setting is `true`. * * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method * through {@link IMock.setSaveInputRequestBody|mock.setSaveInputRequestBody}. */ readonly saveInputRequestBody?: boolean; /** * Whether to save the forwarded request data (headers, method, URL) when creating a new mock. * * @remarks * * The default value of the global `saveForwardedRequestData` setting is `null`, which means * `true` when `mocksFormat` is `folder` (for backward-compatibility), and * `false` when `mocksFormat` is `har`. * * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method * through {@link IMock.setSaveForwardedRequestData|mock.setSaveForwardedRequestData}. */ readonly saveForwardedRequestData?: boolean | null; /** * Whether to save the forwarded request body when creating a new mock. * * @remarks * * The default value of the global `saveForwardedRequestData` setting is `null`, which means * `true` when `mocksFormat` is `folder` (for backward-compatibility), and * `false` when `mocksFormat` is `har`. * * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method * through {@link IMock.setSaveForwardedRequestBody|mock.setSaveForwardedRequestBody}. */ readonly saveForwardedRequestBody?: boolean | null; /** * The default delay. * * @remarks * * It can be changed at request level in the {@link ConfigurationSpec.hook|hook} method * through {@link IMock.setDelay|mock.setDelay}. */ readonly delay?: Delay; /** * When the {@link CLIConfigurationSpec.mocksFormat|mocks format} is 'folder', specifies * the default root folder of all mocks, from which specific mocks paths will be resolved. * * @remarks * * It can be changed at a request level in the {@link ConfigurationSpec.hook|hook} method * through {@link IMock.setMocksFolder|mock.setMocksFolder}. */ readonly mocksFolder?: string; /** * When the {@link CLIConfigurationSpec.mocksFormat|mocks format} is 'har', specifies * the default har file to use. If the file name has the `.yml` or `.yaml` extension, the YAML format * is used instead of the standard JSON format to read and write the file. * * @remarks * * It can be changed at a request level in the {@link ConfigurationSpec.hook|hook} method * through {@link IMock.setMocksHarFile|mock.setMocksHarFile}. */ readonly mocksHarFile?: string; /** * Time in milliseconds during which a har file is kept in memory after its last usage. */ readonly harFileCacheTime?: number; /** * The URL of the remote backend, from which only the protocol, hostname and port are used. * Can be left `null`, in which case anything leading to sending the request to the remote backend will trigger an exception. * Can also contain the special `"*"` value, which means reading from the request the remote backend to target. This is useful when using kassette as a browser proxy. * * @remarks * * It can be changed at a request level in the {@link ConfigurationSpec.hook|hook} method * through {@link IMock.setRemoteURL|mock.setRemoteURL}. */ readonly remoteURL?: string | null; /** * Default mode for `CONNECT` requests. * * @remarks * * It can be changed at a request level in the {@link ConfigurationSpec.onProxyConnect|onProxyConnect} method * through {@link IProxyConnectAPI.setMode|setMode}. */ readonly proxyConnectMode?: ProxyConnectMode; /** * Path to a PEM-encoded CA (Certificate Authority) certificate and key file, * created if it does not exist. If not provided, the certificate and key are * generated but only kept in memory. This certificate and key are used as needed * to sign certificates generated on the fly for any HTTPS connection intercepted * by kassette. * * @remarks * * You can optionally import in the browser the TLS certificate from this * file in order to remove the warning when connecting to HTTPS websites * through kassette. */ readonly tlsCAKeyPath?: string | null; /** * Size in bits of generated RSA keys. */ readonly tlsKeySize?: number; /** * Enables http/2.0 protocol in the kassette server. */ readonly http2?: boolean; } /* Excluded from this release type: CLIOptions */ /** * The id of the source of the resolved value. * * @public */ export declare type ConfigurationPropertySource = 'cli' | 'file' | 'api' | 'default'; /** * Augments the CLI spec to add all pure runtime properties, * that can be defined through the configuration file only * * @public */ export declare interface ConfigurationSpec extends CLIConfigurationSpec { /** * Callback called for every HTTP request that kassette receives (with the exception of `CONNECT` requests, * which trigger the call of {@link ConfigurationSpec.onProxyConnect|onProxyConnect} instead). * @param parameters - exposes the API to control how to process the request */ hook?(parameters: HookAPI): void | Promise<void>; /** * Function called to get or set the key of a mock in a har file, as explained in {@link HarKeyManager}. * * @remarks * * It can be changed at a request level in the {@link ConfigurationSpec.hook|hook} method * through {@link IMock.setMocksHarKeyManager|mock.setMocksHarKeyManager}. */ readonly mocksHarKeyManager?: HarKeyManager; /** * Callback called when kassette receives a request with the * {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT|HTTP CONNECT method}, * which usually happens when kassette is used as a browser proxy and the browser is trying to * connect to a secure web site with the https protocol. * @param parameters - exposes the API to control how to process the request */ onProxyConnect?(parameters: IProxyConnectAPI): void | Promise<void>; /** * Callback called when the proxy is started and listening. * * @param parameters - the port property contains the port on which the * proxy is listening. */ onListen?(parameters: { port: number; }): void; /** * Callback called when the proxy is programmatically closed (which can * be done by using the callback returned from {@link runFromAPI}) */ onExit?(): void; /** * Custom implementation of the {@link ConsoleSpec} interface, with methods * {@link ConsoleSpec.log|log} and {@link ConsoleSpec.error|error}, * each receiving one single argument of any type. * Useful to capture the logs of the application. */ readonly console?: ConsoleSpec; /** * Used only when the {@link IMock.mocksFormat|mocks format} is 'har', * specifies a list of mime types that will attempt to parse the request/response body as JSON. * If the list includes an empty string: '' and there is no mimeType set in the request, it will attempt to parse the body as JSON. * This will only be applicable to request bodies if {@link IMock.saveInputRequestBody|saveInputRequestBody} is set to true * Default value will be [] and will only be overridden by {@link IMock.setHarMimeTypesParseJson|setHarMimeTypesParseJson} */ readonly harMimeTypesParseJson?: string[]; } /** * A connection intercepted by kassette * * @public */ export declare interface Connection { /** protocol such as `http` or `https`, without the trailing `:` */ protocol: string; /** target hostname */ hostname: string; /** target port */ port: number; } /** * Console with logging methods. * @public */ export declare interface ConsoleSpec { /** * Logs a message. * @param message - message to log */ log(message: any): void; /** * Logs an error message. * @param message - error message to log */ error(message: any): void; } /** * Delay that will be used to send the response to the client * when the data is taken from the local mock. * * @remarks * * It can be expressed either as a direct value (in milliseconds) or as the * `'recorded'` string, which means to use the delay recorded * in the local mock (in the {@link MockData.time|time} field). * * @public */ export declare type Delay = 'recorded' | number; /** * Interface used in {@link ChecksumArgs} for each piece of data that can be filtered (i.e. modified) before it is included * in the hash computed by the {@link IMock.checksum|checksum} method. * * @public */ export declare interface FilterableSpec<I, O = I> extends IncludableSpec { /** * A function used to filter (i.e. modify) the piece of data before it is included in the hash. * If no function is given, the unmodified piece of data is used. * @param input - piece of data to filter * @returns The modified piece of data. Note that the filter function can optionally be * asynchronous, in which case it is expected to return a promise of the modified piece * of data. */ filter?(input: I): O | Promise<O>; } /** * Parameter of the {@link IConfigurationFile.getConfiguration|getConfiguration} function * (which a kassette configuration file is supposed to export). * * @public */ export declare interface GetConfigurationProps { /** * If run from the CLI, this is the configuration coming from the CLI. * Otherwise it is an empty object. */ cliConfiguration: CLIConfigurationSpec; /** * If run from the API, this is the configuration coming from the {@link runFromAPI} call. * Otherwise it is an empty object. */ apiConfiguration: ConfigurationSpec; /** * If run from the API, this is the context value provided (if any) through {@link runFromAPI}. * Otherwise it is undefined. */ context: any; } /** * Information about the response body, as stored in a har file. * * @public */ export declare interface HarFormatContent { /** * Size of the content in bytes. */ size?: number; /** * Number of bytes saved by compression. This is not implemented by kassette. */ compression?: number; /** * Value of the `Content-Type` response header. */ mimeType?: string; /** * Response body. * * @remarks * * The response body can be encoded in base64 if this is specified in the {@link HarFormatContent.encoding | encoding} field. */ text?: string; /** * Encoding used for the {@link HarFormatContent.text | text} field, such as "base64". */ encoding?: string; /** * Any comment as a string. This is not used by kassette. */ comment?: string; /** * Response body saved as an object. */ json?: any; } /** * Detailed information about a request and its response, as stored in a har file. * * @public */ export declare interface HarFormatEntry { /** * Content used to create a checksum * * @remarks * * kassette only includes this field if {@link IMock.saveChecksumContent | saveChecksumContent} is true and * if the {@link IMock.checksum | checksum} method was called. */ _kassetteChecksumContent?: string; /** * Key used by kassette to select the correct mock to replay. * * @remarks * * This field contains the value passed to {@link IMock.setMockHarKey} when used with the default * {@link ConfigurationSpec.mocksHarKeyManager | mocksHarKeyManager}. */ _kassetteMockKey?: string; /** * Detailed information about the request forwarded to the remote server. * * @remarks * * kassette only includes this field if {@link IMock.saveForwardedRequestData | saveInputRequestData} is true. */ _kassetteForwardedRequest?: HarFormatRequest; /** * Reference to the parent page. This is not implemented in kassette. */ pageref?: string; /** * Date and time of the request start, as a string in ISO format (YYYY-MM-DDThh:mm:ss.sTZD). */ startedDateTime?: string; /** * Total time of the request, in milliseconds. This is the sum of all timings in the {@link HarFormatEntry.timings | timings object}. */ time?: number; /** * Detailed information about the input request. * * @remarks * * kassette only includes this field if {@link IMock.saveInputRequestData | saveInputRequestData} is true. */ request?: HarFormatRequest; /** * Detailed information about the response. */ response?: HarFormatResponse; /** * Information about the cache. This is not implemented in kassette. */ cache?: any; /** * Detailed timing information about request/response round trip. * * @remarks * * kassette only includes this field if {@link IMock.saveDetailedTimings | saveDetailedTimings} is true. */ timings?: HarFormatTimings; /** * Server IP address. This is not implemented in kassette. */ serverIPAddress?: string; /** * Unique ID of the TCP/IP connection. This is not implemented in kassette. */ connection?: string; /** * Any comment as a string. This is not used by kassette. */ comment?: string; } /** * Information about a header or a query parameter, as stored in a har file. * * @public */ export declare interface HarFormatNameValuePair { /** * Name of the header or query parameter. */ name: string; /** * Value of the header or the query parameter. */ value: string; /** * Any comment as a string. This is not used by kassette. */ comment?: string; } /** * Information about a request body, as stored in a har file. * * @public */ export declare interface HarFormatPostData { /** * Value of the `Content-Type` request header, if present. */ mimeType?: string; /** * List of posted parameters. This is not implemented in kassette. * * @remarks * * kassette always fills the {@link HarFormatPostData.text | text field} and never uses the params field. */ params?: any[]; /** * Posted data, as a (binary) string. */ text?: string; /** * Any comment as a string. This is not used by kassette. */ comment?: string; /** * Response body saved as an object. */ json?: any; } /** * Detailed information about a request, as stored in a har file. * * @public */ export declare interface HarFormatRequest { /** * Request method, such as "GET" or "POST". */ method?: string; /** * Request URL. */ url?: string; /** * Request HTTP version, such as "HTTP/1.1". */ httpVersion?: string; /** * Information about cookies. This is not implemented in kassette. */ cookies?: any[]; /** * List of request headers. */ headers?: HarFormatNameValuePair[]; /** * List of query parameters. */ queryString?: HarFormatNameValuePair[]; /** * Information about the request body. * * @remarks * * kassette only includes this field if {@link IMock.saveInputRequestBody | saveInputRequestBody} is true * (or, for the {@link HarFormatEntry._kassetteForwardedRequest | _kassetteForwardedRequest}.postData field, * if {@link IMock.saveForwardedRequestBody | saveForwardedRequestBody} is true). */ postData?: HarFormatPostData; /** * Total number of bytes from the start of the HTTP request message until (and including) the double CRLF before the body, * or -1 if it is unknown. kassette always sets -1 for this field. */ headersSize?: number; /** * Size of the request body in bytes or -1 if it is unknown. */ bodySize?: number; /** * Any comment as a string. This is not used by kassette. */ comment?: string; } /** * Detailed information about a response, as stored in a har file. * * @public */ export declare interface HarFormatResponse { /** * Response status. */ status?: number; /** * Response status text. */ statusText?: string; /** * Response HTTP version, such as "HTTP/1.1". */ httpVersion?: string; /** * Information about cookies. This is not implemented in kassette. */ cookies?: any[]; /** * List of response headers. */ headers?: HarFormatNameValuePair[]; /** * Information about the response body. */ content?: HarFormatContent; /** * Content of the `Location` response header if present. */ redirectURL?: string; /** * Total number of bytes from the start of the HTTP response message until (and including) the double CRLF before the body, * or -1 if it is unknown. kassette always sets -1 for this field. */ headersSize?: number; /** * Size of the response body in bytes, or -1 if it is unknown. */ bodySize?: number; /** * Any comment as a string. This is not used by kassette. */ comment?: string; } /** * Details about the time spent for each phase of a request-response round trip, as stored in a har file. * * @public */ export declare interface HarFormatTimings extends RequestTimings { /** * Any comment as a string. This is not used by kassette. */ comment?: string; } /** * Each entry in a har file is supposed to have a corresponding unique key (a string). * The har key manager is both a getter and a setter for the key of an entry. * * @remarks * * The har key manager is a function that is called either to get the key of an entry (when * the key parameter is undefined) or to set it (when the key parameter is defined). * * It should not modify the entry when the key parameter is undefined. * * When the key parameter is defined, the har key manager is supposed to change the provided entry, in order to store the * key in it, because after the call, the entry will be persisted in the har file. In this case, the key parameter either * comes from a call to {@link IMock.setMockHarKey}, or from {@link IMock.defaultMockHarKey | defaultMockHarKey}. * * In order to compute the {@link IMock.defaultMockHarKey | defaultMockHarKey} property, the har key manager * is called with an entry that includes the request but not the response (and with an undefined key parameter). * * In all cases, the har key manager is expected to return the key of the entry. If an array is returned (which can * be nested), it is flattened with null items removed, and joined with forward slashes to produce a string. * * The default har key manager is expected to work fine for most use cases, especially when working with a har file recorded * with kassette. With the default har key manager, if a key is set with {@link IMock.setMockHarKey}, it is stored in the * {@link HarFormatEntry._kassetteMockKey | _kassetteMockKey} field. Otherwise, the default key is the concatenation of the request * method and url, with a separating forward slash. It can be useful to replace the default har key manager with a custom one especially * when working with har files that are produced by other applications than kassette, if the default key is not convenient. * * @example * * Here is the default har key manager: * ```ts * export const defaultHarKeyManager: HarKeyManager = (entry: HarFormatEntry, key?: string) => { * const defaultKey = joinPath(entry._kassetteMockKey ?? [entry.request?.method, entry.request?.url]); * if (key && key !== defaultKey) { * entry._kassetteMockKey = key; * return key; * } * return defaultKey; * }; * ``` * * @public */ export declare type HarKeyManager = (entry: HarFormatEntry, key?: string) => RecursiveArray<string | null | undefined>; /** * A map from strings to strings or array of strings * * @public */ declare type Headers_2 = IncomingHttpHeaders; export { Headers_2 as Headers } /** * Parameter of the {@link ConfigurationSpec.hook|hook} callback, that is called for every * HTTP request that kassette receives. * @public */ export declare interface HookAPI { /** * Provides the API to specify how to handle the HTTP request. */ mock: IMock; /** * The console object as specified in the {@link ConfigurationSpec.console|configuration}, * otherwise it is the global console object (usually the one of the platform). */ console: ConsoleSpec; } /** * Interface that a kassette configuration file should export. * * @public */ export declare interface IConfigurationFile { /** * Function returning the configuration to be used by kassette. * @param arg - contains information that can be used to build * the configuration. */ getConfiguration(arg: GetConfigurationProps): ConfigurationSpec | Promise<ConfigurationSpec>; } /** * Contains the value and origin of a configuration property. * @public */ export declare interface IConfigurationProperty<PropertyType> { /** The resolved value of the property */ readonly value: PropertyType; /** The id of the source of the resolved value of the property */ readonly origin: ConfigurationPropertySource; } /** * A handier wrapper around a request * * @public */ export declare interface IFetchedRequest { /** The original Node.js object representing the request */ readonly original: IncomingMessage | Http2ServerRequest; /** The connections stack */ readonly connectionsStack: readonly Readonly<Connection>[]; /** The last connection in connectionsStack */ readonly connection: Readonly<Connection>; /** The URL */ readonly url: URL_2; /** The headers */ readonly headers: IncomingHttpHeaders; /** The query parameters taken from the URL, as a read-only map of strings */ readonly queryParameters: Readonly<Record<string, string>>; /** The protocol part of the URL, without the trailing `:` */ readonly protocol: string; /** The hostname part of the URL */ readonly hostname: string; /** The port part of the URL */ readonly port: string; /** The HTTP method */ readonly method: string; /** The path part of the URL */ readonly pathname: string; /** The body content */ readonly body: Buffer; } /** * The resulting configuration that was merged from its different {@link ConfigurationPropertySource|sources}. * * @remarks * * It contains the path to the configuration file in `filePath`, and also for each property defined in {@link ConfigurationSpec}, * there is an {@link IConfigurationProperty} object describing the {@link IConfigurationProperty.origin|origin} of the property * and its {@link IConfigurationProperty.value|value}. * * @public */ export declare type IMergedConfiguration = { /** * The path of the configuration file */ readonly filePath: string | null; } & { readonly [k in keyof ConfigurationSpec]-?: IConfigurationProperty<Required<ConfigurationSpec>[k]>; }; /** * The public interface exposed to the end user to handle a given request and the associated mock and response. * * An object implementing this interface is passed to the {@link ConfigurationSpec.hook|hook} function, under property `mock` of the single argument object. * * @public */ export declare interface IMock { /** * The wrapper around the input request */ readonly request: IFetchedRequest; /** * The wrapper around the output response */ readonly response: IResponse; /** * Link to global configuration options */ readonly options: MockingOptions; /** * The current mode, configured either by a call to {@link IMock.setMode|setMode}, * or by {@link CLIConfigurationSpec.mode|the global setting}. */ readonly mode: Mode; /** * Sets the {@link IMock.mode|mode} for the current request. * @param mode - mode to set, or null to use the default value from {@link CLIConfigurationSpec.mode|the global setting} */ setMode(mode: Mode | null): void; /** * The current remote URL, configured either by a call to {@link IMock.setRemoteURL|setRemoteURL}, * or by {@link CLIConfigurationSpec.remoteURL|the global setting}. */ readonly remoteURL: string | null; /** * Sets the {@link IMock.remoteURL|remote URL} for the current request. * @param url - the URL to set, or null to use the default value from {@link CLIConfigurationSpec.remoteURL|the global setting} */ setRemoteURL(url: string | null): void; /** * The currently computed delay that will be applied, configured either by a call to {@link IMock.setDelay|setDelay}, * or by {@link CLIConfigurationSpec.delay|the global setting}. Note that if the delay is set to `recorded` and the local mock * to use is not yet loaded, the value returned by this getter will be the default delay and not the recorded delay. */ readonly delay: number; /** * Sets the {@link IMock.delay|delay} that will be used to send the response to the client * when the data is taken from the local mock. * @param delay - can be either a number (to directly specify the delay in milliseconds), * `'recorded'` (to read the delay from the {@link MockData.time|time} property of an already recorded mock if any) * or `null` (to remove the effect of any previous call of `setDelay` and use the default value from {@link CLIConfigurationSpec.delay|the global setting} instead). */ setDelay(delay: Delay | null): void; /** * Used only when the {@link IMock.mocksFormat|mocks format} is 'folder', specifies the root folder of all mocks, * from which specific mocks paths will be resolved * (resolved against {@link MockingOptions.root|options.root}). */ readonly mocksFolder: string; /** * Sets the {@link IMock.mocksFolder|mocksFolder} value. * * @param value - any combination of arrays of path parts, * (as it is also possible for {@link IMock.setLocalPath|setLocalPath}). * You can pass an absolute path, or a relative one which will be resolved against {@link MockingOptions.root|options.root}. * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.mocksFolder|the global setting}. */ setMocksFolder(value: RecursiveArray<string | null | undefined> | null): void; /** * Used only when the {@link IMock.mocksFormat|mocks format} is 'har', contains the full path of the the har file to use. * If the file name has the `.yml` or `.yaml` extension, the YAML format is used instead of the standard JSON format to read and write the file. */ readonly mocksHarFile: string; /** * Sets the {@link IMock.mocksHarFile|mocksHarFile} value. * * @param value - any combination of arrays of path parts. * You can pass an absolute path, or a relative one which will be resolved against {@link MockingOptions.root|options.root}. * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.mocksHarFile|the global setting}. */ setMocksHarFile(value: RecursiveArray<string | null | undefined> | null): void; /** * Used only when the {@link IMock.mocksFormat|mocks format} is 'har', specifies the default mock har key to use in case * {@link IMock.setMockHarKey | setMockHarKey} is not called with a non-null value. * It is computed by calling the {@link IMock.mocksHarKeyManager|mocks har key manager} with the current request. * * @remarks * * Note that it is lazily computed, but once computed, it is not re-computed even if * {@link IMock.mocksHarKeyManager | mocksHarKeyManager} changes. */ readonly defaultMockHarKey?: string; /** * Used only when the {@link IMock.mocksFormat|mocks format} is 'har', specifies the key to use inside the har file to either * read or write a mock. * * @remarks * * The way the key is stored inside the har file depends on the value of {@link IMock.mocksHarKeyManager|mocksHarKeyManager}. */ readonly mockHarKey?: string; /** * Sets the {@link IMock.mockHarKey|mockHarKey} value. * * @param value - specifies the key to use inside the har file to either read or write a mock. If an array is set (which can be nested), * it is flattened with null items removed, and joined with forward slashes to produce a string. * Passing null resets the value to {@link IMock.defaultMockHarKey|the default value}. */ setMockHarKey(value: RecursiveArray<string | null | undefined> | null): void; /** * Used only when the {@link IMock.mocksFormat|mocks format} is 'har', specifies the {@link HarKeyManager|har key manager} to use. */ readonly mocksHarKeyManager: HarKeyManager; /** * Sets the {@link IMock.mocksHarKeyManager|mocksHarKeyManager} value. * * @param value - the {@link HarKeyManager|har key manager} to use for this request. * Passing null resets the value to the default coming from {@link ConfigurationSpec.mocksHarKeyManager|the global setting}. */ setMocksHarKeyManager(value: HarKeyManager | null): void; /** * Used only when the {@link IMock.mocksFormat|mocks format} is 'har', * specifies a list of mime types that will attempt to parse the request/response body as JSON. * This will only be applicable to request bodies if {@link IMock.saveInputRequestBody|saveInputRequestBody} is set to true * Default value will be [] and will only be overridden by {@link IMock.setHarMimeTypesParseJson|setHarMimeTypesParseJson} */ readonly harMimeTypesParseJson: string[]; /** * Sets the {@link IMock.harMimeTypesParseJson|harMimeTypesParseJson} value. * * @param value - The mime types that should attempt to parse the body as json */ setHarMimeTypesParseJson(value: string[]): void; /** * Used only when the {@link IMock.mocksFormat|mocks format} is 'folder', specifies the local path of the mock, relative to {@link IMock.mocksFolder|mocksFolder}. * It is either the one set by the user through {@link IMock.setLocalPath|setLocalPath} or {@link IMock.defaultLocalPath|defaultLocalPath}. */ readonly localPath: string; /** * Used only when the {@link IMock.mocksFormat|mocks format} is 'folder', specifies the default local path of the mock, relative to {@link IMock.mocksFolder|mocksFolder}, . * It uses the URL pathname to build an equivalent folders hierarchy, * and appends the HTTP method as a leaf folder. */ readonly defaultLocalPath: string; /** * Used only when the {@link IMock.mocksFormat|mocks format} is 'folder', specifies the full, absolute path of the mock, built from {@link IMock.localPath|localPath}/{@link IMock.defaultLocalPath|defaultLocalPath}, {@link IMock.mocksFolder|mocksFolder} * and possibly {@link MockingOptions.root|options.root} if {@link IMock.mocksFolder|mocksFolder} is not absolute. */ readonly mockFolderFullPath: string; /** * Content produced by the last call to the {@link IMock.checksum|checksum} method, * as it was passed to the hash algorithm. */ readonly checksumContent: string | null; /** * Compute a checksum using content from the request. * * @remarks * The computed checksum is intended to be added to the path of the mock * so that semantically different requests use different mocks. * * It is difficult to predict what will actually be relevant to include in * the checksum or not for your use case, and that's why we provide many options * to include/exclude/transform data (cf {@link ChecksumArgs}). * * Note that we designed the API so that it is usually not needed to * call the checksum method more than once for a given request/mock. * * The method stores the computed content (which is passed to the hash * algorithm) in property {@link IMock.checksumContent|checksumContent} * (in the `mock` object), as a string. It is built according to your options * and the request's data. It is also persisted, so that you can debug more easily, * especially by committing it into your SCM to analyze changes across versions of * your code. File is along with the other files of the mock under file name `checksum`. * * @param spec - specifies which data from the request to include in the checksum * @returns The actual checksum value, that you can then * use for instance to add to the mock's path. */ checksum(spec: ChecksumArgs): Promise<string>; /** * Sets the {@link IMock.localPath|localPath} value. * * @param pathParts - Any combination of values and array of values, * which will eventually all be flattened, converted to strings and * joined to build a path. * * @example * The following example will use the HTTP method followed by the URL pathname: * ``` * mock.setLocalPath([mock.request.method, mock.request.pathname]) * ``` * @example * The following example will concatenate `prefix`, all portions of the * URL pathname except the first one (also excluding the very first one which is empty since {@link IFetchedRequest.pathname} has a leading slash) * and optionally a suffix sequence depending on a boolean. * * ``` * mock.setLocalPath([prefix, mock.request.pathname.split('/').slice(2), addSuffix ? [suffix, '-static-suffix'] : null]) * ``` */ setLocalPath(pathParts: RecursiveArray<string | null | undefined>): void; /** * Returns true if the mock exists locally. * * @deprecated Use {@link IMock.hasLocalMock} instead. * * @remarks * * {@link IMock.hasNoLocalFiles|hasNoLocalFiles} returns the opposite boolean value. */ hasLocalFiles(): Promise<boolean>; /** * Returns true if the mock does not exist locally. * * @deprecated Use {@link IMock.hasNoLocalMock} instead. * * @remarks * * {@link IMock.hasLocalFiles|hasLocalFiles} returns the opposite boolean value. */ hasNoLocalFiles(): Promise<boolean>; /** * Returns true if the mock exists locally. * * @remarks * * {@link IMock.hasNoLocalMock|hasNoLocalMock} returns the opposite boolean value. */ hasLocalMock(): Promise<boolean>; /** * Returns true if the mock does not exist locally. * * @remarks * * {@link IMock.hasLocalMock|hasLocalMock} returns the opposite boolean value. */ hasNoLocalMock(): Promise<boolean>; /** * The mocks format used for this request. */ readonly mocksFormat: MocksFormat; /** * Sets the {@link IMock.mocksFormat|mocksFormat} value. * * @param value - the mocks format to use for this request. * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.mocksFormat|the global setting}. */ setMocksFormat(value: MocksFormat | null): void; /** * Whether to save the content used to create a checksum when creating a new mock with a checksum for this request. */ readonly saveChecksumContent: boolean; /** * Sets the {@link IMock.saveChecksumContent|saveChecksumContent} value. * * @param value - whether to save the content used to create a checksum when creating a new mock with a checksum for this request. * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.saveChecksumContent|the global setting}. */ setSaveChecksumContent(value: boolean | null): void; /** * Whether to save {@link RequestTimings | detailed timings} when creating a new mock for this request. */ readonly saveDetailedTimings: boolean; /** * Sets the {@link IMock.saveDetailedTimings|saveDetailedTimings} value. * * @param value - whether to save {@link RequestTimings | detailed timings} when creating a new mock with a checksum for this request. * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.saveDetailedTimings|the global setting}. */ setSaveDetailedTimings(value: boolean | null): void; /** * Whether to save the input request data (headers, method, URL) when creating a new mock for this request. */ readonly saveInputRequestData: boolean; /** * Sets the {@link IMock.saveInputRequestData|saveInputRequestData} value. * * @param value - whether to save the input request data (headers, method, URL) when creating a new mock for this request. * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.saveInputRequestData|the global setting}. */ setSaveInputRequestData(value: boolean | null): void; /** * Whether to save the content of the input request body when creating a new mock for this request. */ readonly saveInputRequestBody: boolean; /** * Sets the {@link IMock.saveInputRequestBody|saveInputRequestBody} value. * * @param value - whether to save the content of the input request body when creating a new mock for this request. * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.saveInputRequestBody|the global setting}. */ setSaveInputRequestBody(value: boolean | null): void; /** * Whether to save the forwarded request data (headers, method, URL) when creating a new mock for this request. */ readonly saveForwardedRequestData: boolean; /** * Sets the {@link IMock.saveForwardedRequestData|saveForwardedRequestData} value. * * @param value - whether to save the forwarded request data (headers, method, URL) when creating a new mock for this request. * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.saveForwardedRequestData|the global setting}. */ setSaveForwardedRequestData(value: boolean | null): void; /** * Whether to save the forwarded request body when creating a new mock for this request. */ readonly saveForwardedRequestBody: boolean; /** * Sets the {@link IMock.saveForwardedRequestBody|saveForwardedRequestBody} value. * * @param value - whether to save the forwarded request body when creating a new mock for this request. * Passing null resets the value to the default coming from {@link CLIConfigurationSpec.saveForwardedRequestBody|the global setting}. */ setSaveForwardedRequestBody(value: boolean | null): void; /** * Returns a wrapped payload built from data persisted in local files. * If no local file is present, returns `undefined`. */ readLocalPayload(): Promise<PayloadWithOrigin<'local' | 'user'> | undefined>; /** * Take the given wrapped payload and persist it in local files. * @param payload - payload to persist in local files */ persistPayload(payload: PayloadWithOrigin): Promise<void>; /** * Forward the client request to the remote backend and get a wrapped payload from the response in output. */ fetchPayload(): Promise<RemotePayload>; /** * Create a wrapped payload (with `user` origin) from the given payload data. * @param payload - payload data */ createPayload(payload: Payload): PayloadWithOrigin<'user'>; /** * Sets the current local payload, with a custom one you would have created. * @param payload - payload to set */ setPayload(payload: PayloadWithOrigin<'local' | 'user'>): void; /** * Combines {@link IMock.fetchPayload|fetchPayload} and {@link IMock.persistPayload|persistPayload} * and returns the wrapped payload. */ downloadPayload(): Promise<RemotePayload>; /** * Returns the wrapped local payload using {@link IMock.readLocalPayload|readLocalPayload} if it exists, * otherwise use {@link IMock.downloadPayload