{
  "type": "module",
  "source": "doc/api/api-snapshotagent.md",
  "modules": [
    {
      "textRaw": "SnapshotAgent",
      "name": "snapshotagent",
      "introduced_in": "v7.13.0",
      "type": "module",
      "stability": 1,
      "stabilityText": "Experimental",
      "desc": "<p><code>SnapshotAgent</code> records real HTTP responses and replays them on later requests,\nallowing tests to run against deterministic, captured data instead of a live\nnetwork. It extends <a href=\"MockAgent.html#class-mockagent\"><code>MockAgent</code></a>, so it can be installed with\n<a href=\"Dispatcher.html#setglobaldispatcherdispatcher\"><code>setGlobalDispatcher()</code></a> or passed explicitly through the <code>dispatcher</code>\noption, and it works with every undici API (<code>fetch</code>, <code>request</code>, <code>stream</code>,\n<code>pipeline</code>, and so on).</p>\n<p>A <code>SnapshotAgent</code> operates in one of three modes. In <code>'record'</code> mode it performs\nreal requests and writes the responses to a snapshot file. In <code>'playback'</code> mode\nit serves responses from the snapshot file without touching the network. In\n<code>'update'</code> mode it replays existing snapshots and records any request that has no\nmatching snapshot.</p>\n<pre><code class=\"language-mjs\">import { SnapshotAgent, setGlobalDispatcher, fetch } from 'undici'\n\nconst agent = new SnapshotAgent({\n  mode: 'record',\n  snapshotPath: './snapshots/api.json'\n})\nsetGlobalDispatcher(agent)\n\nconst response = await fetch('https://api.example.com/users')\nconst users = await response.json()\n\nawait agent.close()\n</code></pre>\n<p>Constructing a <code>SnapshotAgent</code> emits an <code>ExperimentalWarning</code> once per process.</p>",
      "classes": [
        {
          "textRaw": "Class: `SnapshotAgent`",
          "name": "SnapshotAgent",
          "type": "class",
          "meta": {
            "added": [
              "v7.13.0"
            ],
            "changes": []
          },
          "desc": "<ul>\n<li>Extends: <a href=\"MockAgent.md#class-mockagent\"><code>&#x3C;MockAgent></code></a></li>\n</ul>\n<p>The captured interactions are managed by an internal <code>SnapshotRecorder</code>, which\nis accessible through <a href=\"#agentgetrecorder\"><code>agent.getRecorder()</code></a>. Because <code>SnapshotAgent</code> extends\n<a href=\"MockAgent.html#class-mockagent\"><code>MockAgent</code></a>, all <code>MockAgent</code> and <a href=\"Dispatcher.html#class-dispatcher\"><code>Dispatcher</code></a> methods and events are also\navailable.</p>",
          "signatures": [
            {
              "textRaw": "`new SnapshotAgent([options])`",
              "name": "SnapshotAgent",
              "type": "ctor",
              "meta": {
                "added": [
                  "v7.13.0"
                ],
                "changes": []
              },
              "params": [
                {
                  "textRaw": "`options` {Object} (optional) Accepts all `MockAgent` options plus the following snapshot-specific options.",
                  "name": "options",
                  "type": "Object",
                  "desc": "(optional) Accepts all `MockAgent` options plus the following snapshot-specific options.",
                  "options": [
                    {
                      "textRaw": "`mode` {string} The snapshot mode. One of `'record'`, `'playback'`, or `'update'`. **Default:** `'record'`.",
                      "name": "mode",
                      "type": "string",
                      "default": "`'record'`",
                      "desc": "The snapshot mode. One of `'record'`, `'playback'`, or `'update'`."
                    },
                    {
                      "textRaw": "`snapshotPath` {string} Path to the snapshot file used for loading and saving. Required when `mode` is `'playback'` or `'update'`. **Default:** `null`.",
                      "name": "snapshotPath",
                      "type": "string",
                      "default": "`null`",
                      "desc": "Path to the snapshot file used for loading and saving. Required when `mode` is `'playback'` or `'update'`."
                    },
                    {
                      "textRaw": "`maxSnapshots` {number} Maximum number of snapshots to keep in memory. **Default:** `Infinity`.",
                      "name": "maxSnapshots",
                      "type": "number",
                      "default": "`Infinity`",
                      "desc": "Maximum number of snapshots to keep in memory."
                    },
                    {
                      "textRaw": "`autoFlush` {boolean} When `true`, snapshots are written to `snapshotPath` automatically as they are recorded. **Default:** `false`.",
                      "name": "autoFlush",
                      "type": "boolean",
                      "default": "`false`",
                      "desc": "When `true`, snapshots are written to `snapshotPath` automatically as they are recorded."
                    },
                    {
                      "textRaw": "`flushInterval` {number} Interval, in milliseconds, between automatic flushes when `autoFlush` is enabled. **Default:** `30000`.",
                      "name": "flushInterval",
                      "type": "number",
                      "default": "`30000`",
                      "desc": "Interval, in milliseconds, between automatic flushes when `autoFlush` is enabled."
                    },
                    {
                      "textRaw": "`matchHeaders` {string}[] Names of the only headers to include when matching a request against a snapshot. When omitted, all headers are matched.",
                      "name": "matchHeaders",
                      "type": "string",
                      "desc": "[] Names of the only headers to include when matching a request against a snapshot. When omitted, all headers are matched."
                    },
                    {
                      "textRaw": "`ignoreHeaders` {string}[] Header names to ignore when matching a request.",
                      "name": "ignoreHeaders",
                      "type": "string",
                      "desc": "[] Header names to ignore when matching a request."
                    },
                    {
                      "textRaw": "`excludeHeaders` {string}[] Header names to strip from snapshots entirely, so that sensitive values are never written to disk.",
                      "name": "excludeHeaders",
                      "type": "string",
                      "desc": "[] Header names to strip from snapshots entirely, so that sensitive values are never written to disk."
                    },
                    {
                      "textRaw": "`matchBody` {boolean} When `true`, the request body is included in request matching. **Default:** `true`.",
                      "name": "matchBody",
                      "type": "boolean",
                      "default": "`true`",
                      "desc": "When `true`, the request body is included in request matching."
                    },
                    {
                      "textRaw": "`normalizeBody` {Function} Normalizes the request body before it is matched or stored, for example to strip volatile fields such as timestamps. Only applied when `matchBody` is `true`.",
                      "name": "normalizeBody",
                      "type": "Function",
                      "desc": "Normalizes the request body before it is matched or stored, for example to strip volatile fields such as timestamps. Only applied when `matchBody` is `true`.",
                      "options": [
                        {
                          "textRaw": "`body` {string|Buffer|null|undefined} The raw request body.",
                          "name": "body",
                          "type": "string|Buffer|null|undefined",
                          "desc": "The raw request body."
                        },
                        {
                          "textRaw": "Returns: {string} The normalized body used for matching.",
                          "name": "return",
                          "type": "string",
                          "desc": "The normalized body used for matching."
                        }
                      ]
                    },
                    {
                      "textRaw": "`matchQuery` {boolean} When `true`, query parameters are included in request matching. **Default:** `true`.",
                      "name": "matchQuery",
                      "type": "boolean",
                      "default": "`true`",
                      "desc": "When `true`, query parameters are included in request matching."
                    },
                    {
                      "textRaw": "`normalizeQuery` {Function} Normalizes the query string before it is matched, for example to strip cache-busting parameters. Only applied when `matchQuery` is `true`.",
                      "name": "normalizeQuery",
                      "type": "Function",
                      "desc": "Normalizes the query string before it is matched, for example to strip cache-busting parameters. Only applied when `matchQuery` is `true`.",
                      "options": [
                        {
                          "textRaw": "`query` {URLSearchParams} The parsed query parameters.",
                          "name": "query",
                          "type": "URLSearchParams",
                          "desc": "The parsed query parameters."
                        },
                        {
                          "textRaw": "Returns: {string} The normalized query string used for matching.",
                          "name": "return",
                          "type": "string",
                          "desc": "The normalized query string used for matching."
                        }
                      ]
                    },
                    {
                      "textRaw": "`caseSensitive` {boolean} When `true`, header matching is case-sensitive. **Default:** `false`.",
                      "name": "caseSensitive",
                      "type": "boolean",
                      "default": "`false`",
                      "desc": "When `true`, header matching is case-sensitive."
                    },
                    {
                      "textRaw": "`shouldRecord` {Function} Decides whether a given request is recorded. Only used in `'record'` and `'update'` modes.",
                      "name": "shouldRecord",
                      "type": "Function",
                      "desc": "Decides whether a given request is recorded. Only used in `'record'` and `'update'` modes.",
                      "options": [
                        {
                          "textRaw": "`requestOpts` {Object} The dispatch options of the request.",
                          "name": "requestOpts",
                          "type": "Object",
                          "desc": "The dispatch options of the request."
                        },
                        {
                          "textRaw": "Returns: {boolean} `true` to record the request.",
                          "name": "return",
                          "type": "boolean",
                          "desc": "`true` to record the request."
                        }
                      ]
                    },
                    {
                      "textRaw": "`shouldPlayback` {Function} Decides whether a given request is served from a snapshot. Only used in `'playback'` and `'update'` modes.",
                      "name": "shouldPlayback",
                      "type": "Function",
                      "desc": "Decides whether a given request is served from a snapshot. Only used in `'playback'` and `'update'` modes.",
                      "options": [
                        {
                          "textRaw": "`requestOpts` {Object} The dispatch options of the request.",
                          "name": "requestOpts",
                          "type": "Object",
                          "desc": "The dispatch options of the request."
                        },
                        {
                          "textRaw": "Returns: {boolean} `true` to play the request back from a snapshot.",
                          "name": "return",
                          "type": "boolean",
                          "desc": "`true` to play the request back from a snapshot."
                        }
                      ]
                    },
                    {
                      "textRaw": "`excludeUrls` {Array}<{string|RegExp}> URL patterns that are excluded from recording and playback. String patterns match case-insensitively as substrings of the URL; `RegExp` patterns are tested against the URL. Matching requests are passed through to a real `Agent` instead.",
                      "name": "excludeUrls",
                      "type": "Array",
                      "desc": "<{string|RegExp}> URL patterns that are excluded from recording and playback. String patterns match case-insensitively as substrings of the URL; `RegExp` patterns are tested against the URL. Matching requests are passed through to a real `Agent` instead."
                    }
                  ],
                  "optional": true
                }
              ],
              "desc": "<p>Creates a new <code>SnapshotAgent</code>. Throws an <a href=\"Errors.html#undicierrorsundiciinvalidargumenterror\"><code>InvalidArgumentError</code></a> when <code>mode</code>\nis <code>'playback'</code> or <code>'update'</code> and <code>snapshotPath</code> is not provided, and throws an\n<code>InvalidArgumentError</code> when <code>mode</code> is not one of the supported values.</p>\n<p>When <code>mode</code> is <code>'playback'</code> or <code>'update'</code> and <code>snapshotPath</code> is set, snapshots\nare loaded from the file automatically; a missing file is ignored until the first\nrequest requires it.</p>\n<pre><code class=\"language-mjs\">import { SnapshotAgent, setGlobalDispatcher } from 'undici'\n\nconst agent = new SnapshotAgent({\n  mode: 'playback',\n  snapshotPath: './snapshots/api.json'\n})\nsetGlobalDispatcher(agent)\n</code></pre>\n<p>The mode controls how requests are handled:</p>\n<ul>\n<li>\n<p><code>'record'</code> performs the real request and stores the response.</p>\n<pre><code class=\"language-mjs\">import { SnapshotAgent, setGlobalDispatcher, fetch } from 'undici'\n\nconst agent = new SnapshotAgent({\n  mode: 'record',\n  snapshotPath: './snapshots/api.json'\n})\nsetGlobalDispatcher(agent)\n\nawait fetch('https://api.example.com/users')\nawait agent.saveSnapshots()\n</code></pre>\n</li>\n<li>\n<p><code>'playback'</code> serves the recorded response without any network access. A\nrequest with no matching snapshot rejects with an <a href=\"Errors.html#undicierrorsundicierror\"><code>UndiciError</code></a> whose\nmessage begins with <code>No snapshot found</code>.</p>\n<pre><code class=\"language-mjs\">import { SnapshotAgent, setGlobalDispatcher, fetch } from 'undici'\n\nconst agent = new SnapshotAgent({\n  mode: 'playback',\n  snapshotPath: './snapshots/api.json'\n})\nsetGlobalDispatcher(agent)\n\nconst response = await fetch('https://api.example.com/users')\n</code></pre>\n</li>\n<li>\n<p><code>'update'</code> replays an existing snapshot when one is found and otherwise records\nthe request like <code>'record'</code> mode.</p>\n<pre><code class=\"language-mjs\">import { SnapshotAgent, setGlobalDispatcher, fetch } from 'undici'\n\nconst agent = new SnapshotAgent({\n  mode: 'update',\n  snapshotPath: './snapshots/api.json'\n})\nsetGlobalDispatcher(agent)\n\nawait fetch('https://api.example.com/new-endpoint')\n</code></pre>\n</li>\n</ul>"
            }
          ],
          "methods": [
            {
              "textRaw": "`agent.loadSnapshots([filePath])`",
              "name": "loadSnapshots",
              "type": "method",
              "meta": {
                "added": [
                  "v7.13.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`filePath` {string} (optional) Path to read snapshots from. **Default:** the `snapshotPath` given to the constructor.",
                      "name": "filePath",
                      "type": "string",
                      "default": "the `snapshotPath` given to the constructor",
                      "desc": "(optional) Path to read snapshots from.",
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Promise<void>} Resolves when the snapshots have been loaded.",
                    "name": "return",
                    "type": "Promise<void>",
                    "desc": "Resolves when the snapshots have been loaded."
                  }
                }
              ],
              "desc": "<p>Loads snapshots from disk into memory. In <code>'playback'</code> mode this also installs\nthe corresponding <a href=\"MockAgent.html#class-mockagent\"><code>MockAgent</code></a> interceptors so that subsequent requests are\nmatched against the loaded snapshots.</p>\n<pre><code class=\"language-mjs\">await agent.loadSnapshots('./snapshots/api.json')\n</code></pre>"
            },
            {
              "textRaw": "`agent.saveSnapshots([filePath])`",
              "name": "saveSnapshots",
              "type": "method",
              "meta": {
                "added": [
                  "v7.13.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`filePath` {string} (optional) Path to write snapshots to. **Default:** the `snapshotPath` given to the constructor.",
                      "name": "filePath",
                      "type": "string",
                      "default": "the `snapshotPath` given to the constructor",
                      "desc": "(optional) Path to write snapshots to.",
                      "optional": true
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Promise<void>} Resolves when the snapshots have been written.",
                    "name": "return",
                    "type": "Promise<void>",
                    "desc": "Resolves when the snapshots have been written."
                  }
                }
              ],
              "desc": "<p>Writes all recorded snapshots to disk.</p>\n<pre><code class=\"language-mjs\">await agent.saveSnapshots('./snapshots/api.json')\n</code></pre>"
            },
            {
              "textRaw": "`agent.getRecorder()`",
              "name": "getRecorder",
              "type": "method",
              "meta": {
                "added": [
                  "v7.13.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [],
                  "return": {
                    "textRaw": "Returns: {SnapshotRecorder} The internal recorder that stores the captured interactions.",
                    "name": "return",
                    "type": "SnapshotRecorder",
                    "desc": "The internal recorder that stores the captured interactions."
                  }
                }
              ],
              "desc": "<p>Returns the underlying <code>SnapshotRecorder</code>. The recorder exposes lower-level\noperations over the captured data, including <code>record()</code>, <code>findSnapshot()</code>,\n<code>getSnapshots()</code>, <code>size()</code>, and <code>clear()</code>. The recorder is an internal type\nreturned for inspection; it is not exported from the package root.</p>\n<pre><code class=\"language-mjs\">const recorder = agent.getRecorder()\nconsole.log(`Recorded ${recorder.size()} interactions`)\n</code></pre>"
            },
            {
              "textRaw": "`agent.getMode()`",
              "name": "getMode",
              "type": "method",
              "meta": {
                "added": [
                  "v7.13.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [],
                  "return": {
                    "textRaw": "Returns: {string} The current mode: `'record'`, `'playback'`, or `'update'`.",
                    "name": "return",
                    "type": "string",
                    "desc": "The current mode: `'record'`, `'playback'`, or `'update'`."
                  }
                }
              ],
              "desc": "<p>Returns the mode the agent was constructed with.</p>"
            },
            {
              "textRaw": "`agent.clearSnapshots()`",
              "name": "clearSnapshots",
              "type": "method",
              "meta": {
                "added": [
                  "v7.13.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [],
                  "return": {
                    "textRaw": "Returns: {undefined}",
                    "name": "return",
                    "type": "undefined"
                  }
                }
              ],
              "desc": "<p>Removes all snapshots from memory.</p>\n<pre><code class=\"language-mjs\">agent.clearSnapshots()\n</code></pre>"
            },
            {
              "textRaw": "`agent.resetCallCounts()`",
              "name": "resetCallCounts",
              "type": "method",
              "meta": {
                "added": [
                  "v7.13.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [],
                  "return": {
                    "textRaw": "Returns: {undefined}",
                    "name": "return",
                    "type": "undefined"
                  }
                }
              ],
              "desc": "<p>Resets the call count of every snapshot to zero. Useful between tests when the\nsame agent is reused, since matching a snapshot in <code>'playback'</code> mode increments\nits call count.</p>\n<pre><code class=\"language-mjs\">agent.resetCallCounts()\n</code></pre>"
            },
            {
              "textRaw": "`agent.deleteSnapshot(requestOpts)`",
              "name": "deleteSnapshot",
              "type": "method",
              "meta": {
                "added": [
                  "v7.13.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`requestOpts` {Object} Dispatch options identifying the snapshot to remove.",
                      "name": "requestOpts",
                      "type": "Object",
                      "desc": "Dispatch options identifying the snapshot to remove."
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {boolean} `true` if a matching snapshot was deleted, `false` if none was found.",
                    "name": "return",
                    "type": "boolean",
                    "desc": "`true` if a matching snapshot was deleted, `false` if none was found."
                  }
                }
              ],
              "desc": "<p>Deletes a single snapshot that matches the given request options.</p>\n<pre><code class=\"language-mjs\">const deleted = agent.deleteSnapshot({\n  method: 'GET',\n  origin: 'https://api.example.com',\n  path: '/users'\n})\n</code></pre>"
            },
            {
              "textRaw": "`agent.getSnapshotInfo(requestOpts)`",
              "name": "getSnapshotInfo",
              "type": "method",
              "meta": {
                "added": [
                  "v7.13.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`requestOpts` {Object} Dispatch options identifying the snapshot to inspect.",
                      "name": "requestOpts",
                      "type": "Object",
                      "desc": "Dispatch options identifying the snapshot to inspect."
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {Object|null} Information about the matching snapshot, or `null` when none is found.",
                    "name": "return",
                    "type": "Object|null",
                    "desc": "Information about the matching snapshot, or `null` when none is found.",
                    "options": [
                      {
                        "textRaw": "`hash` {string} The hash used to key the snapshot.",
                        "name": "hash",
                        "type": "string",
                        "desc": "The hash used to key the snapshot."
                      },
                      {
                        "textRaw": "`request` {Object} The recorded request.",
                        "name": "request",
                        "type": "Object",
                        "desc": "The recorded request.",
                        "options": [
                          {
                            "textRaw": "`method` {string} The request method.",
                            "name": "method",
                            "type": "string",
                            "desc": "The request method."
                          },
                          {
                            "textRaw": "`url` {string} The request URL.",
                            "name": "url",
                            "type": "string",
                            "desc": "The request URL."
                          },
                          {
                            "textRaw": "`headers` {Record}<{string}, {string}> The recorded request headers.",
                            "name": "headers",
                            "type": "Record",
                            "desc": "<{string}, {string}> The recorded request headers."
                          },
                          {
                            "textRaw": "`body` {string} The recorded request body, when present.",
                            "name": "body",
                            "type": "string",
                            "desc": "The recorded request body, when present."
                          }
                        ]
                      },
                      {
                        "textRaw": "`responseCount` {number} The number of recorded responses for the request.",
                        "name": "responseCount",
                        "type": "number",
                        "desc": "The number of recorded responses for the request."
                      },
                      {
                        "textRaw": "`callCount` {number} The number of times the snapshot has been matched.",
                        "name": "callCount",
                        "type": "number",
                        "desc": "The number of times the snapshot has been matched."
                      },
                      {
                        "textRaw": "`timestamp` {string} The ISO timestamp at which the snapshot was recorded.",
                        "name": "timestamp",
                        "type": "string",
                        "desc": "The ISO timestamp at which the snapshot was recorded."
                      }
                    ]
                  }
                }
              ],
              "desc": "<p>Returns metadata about a snapshot without returning the response payload.</p>\n<pre><code class=\"language-mjs\">const info = agent.getSnapshotInfo({\n  method: 'GET',\n  origin: 'https://api.example.com',\n  path: '/users'\n})\n</code></pre>"
            },
            {
              "textRaw": "`agent.replaceSnapshots(snapshotData)`",
              "name": "replaceSnapshots",
              "type": "method",
              "meta": {
                "added": [
                  "v7.13.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [
                    {
                      "textRaw": "`snapshotData` {Array} The snapshot data to load, replacing any existing snapshots.",
                      "name": "snapshotData",
                      "type": "Array",
                      "desc": "The snapshot data to load, replacing any existing snapshots.",
                      "options": [
                        {
                          "textRaw": "`hash` {string} The hash used to key the snapshot.",
                          "name": "hash",
                          "type": "string",
                          "desc": "The hash used to key the snapshot."
                        },
                        {
                          "textRaw": "`snapshot` {Object} The snapshot entry.",
                          "name": "snapshot",
                          "type": "Object",
                          "desc": "The snapshot entry."
                        }
                      ]
                    }
                  ],
                  "return": {
                    "textRaw": "Returns: {undefined}",
                    "name": "return",
                    "type": "undefined"
                  }
                }
              ],
              "desc": "<p>Replaces all in-memory snapshots with the provided data.</p>\n<pre><code class=\"language-mjs\">const recorder = agent.getRecorder()\nconst snapshots = recorder.getSnapshots()\n\nagent.replaceSnapshots(snapshots.map((snapshot, index) => ({\n  hash: `snapshot-${index}`,\n  snapshot\n})))\n</code></pre>"
            },
            {
              "textRaw": "`agent.close()`",
              "name": "close",
              "type": "method",
              "meta": {
                "added": [
                  "v7.13.0"
                ],
                "changes": []
              },
              "signatures": [
                {
                  "params": [],
                  "return": {
                    "textRaw": "Returns: {Promise<void>} Resolves once the agent and its resources are closed.",
                    "name": "return",
                    "type": "Promise<void>",
                    "desc": "Resolves once the agent and its resources are closed."
                  }
                }
              ],
              "desc": "<p>Closes the agent and releases its resources. In <code>'record'</code> and <code>'update'</code> modes\nthe recorder is flushed to disk first. In <code>'playback'</code> mode nothing is written,\nbecause matching a snapshot mutates its call count and saving would needlessly\nrewrite the snapshot file. The real <a href=\"Agent.html#class-agent\"><code>Agent</code></a>, when one was created, and the\nunderlying <a href=\"MockAgent.html#class-mockagent\"><code>MockAgent</code></a> are closed as well.</p>\n<pre><code class=\"language-mjs\">await agent.close()\n</code></pre>"
            }
          ]
        }
      ]
    }
  ]
}