Skip to content

fix(types): align Definition with runtime; add rawHeaders, drop headers#2955

Merged
mikicho merged 2 commits into
nock:mainfrom
timcharper:tim/sync-types-with-reality
Apr 20, 2026
Merged

fix(types): align Definition with runtime; add rawHeaders, drop headers#2955
mikicho merged 2 commits into
nock:mainfrom
timcharper:tim/sync-types-with-reality

Conversation

@timcharper

@timcharper timcharper commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

Definition type changes: research and rationale

Fixes #2926

Problem

  • Definition typed headers as optional and did not include rawHeaders.
  • At runtime, recorded definitions have no headers property (it is never set), and response headers live on rawHeaders.
  • Consumers (e.g. before(def) in nock back) had to cast or extend the type to use def.rawHeaders.

Research

Where definitions come from

  • The only place that creates Definition-shaped objects is lib/recorder.jsgenerateRequestAndResponseObject, called from the unified recordResponse() used by both ClientRequest and fetch interceptors.

headers on Definition

  • Never set: generateRequestAndResponseObject returns an object with rawHeaders, response, scope, etc., and does not set headers.
  • Never read: lib/scope.js (e.g. in the code path that calls define()/loadDefs) only uses nockDef.rawHeaders; there is no reference to nockDef.headers anywhere in the codebase.
  • So headers on Definition was dead; the type suggested a property that does not exist at runtime.

Shape of rawHeaders

  • Always object form in recording: recordResponse() builds res once for both interceptors as:
    const headers = Object.fromEntries(response.headers.entries())
    const res = { statusCode: response.status, headers, rawHeaders: headers }
    So recorded definitions always have rawHeaders as a Record, not a string[].
  • Consumption: scope.js does const rawHeaders = nockDef.rawHeaders || [] and passes it to .reply(status, response, rawHeaders). The interceptor’s reply() uses common.headersInputToRawArray(rawHeaders), which accepts array, Map, or plain object. So at runtime, an array form would still work (e.g. legacy fixtures), but nock’s recorder never produces it; the type reflects what nock actually records.

Multi-value headers (string | string[])

  • Recording: Object.fromEntries(response.headers.entries()) collapses duplicate keys to the last value, so recording only ever produces Record<string, string>.
  • Loaded/hand-written definitions: Fixtures or hand-written definitions can use multi-value headers (e.g. set-cookie) as arrays. reply() accepts this via ReplyHeaderValue = string | string[], and common.addHeaderLine() explicitly handles array values. So the consumed shape can be Record<string, string | string[]>.

Changes made

  1. Removed headers from Definition
    So the type matches reality: nock never sets or reads it; only rawHeaders exists.

  2. Added rawHeaders to Definition
    Typed as Record<string, string | string[]>:

    • Object form only (no string[] for the top-level type), matching what the recorder produces and what define() uses.
    • Values as string | string[] so multi-value headers (e.g. set-cookie) in fixtures or hand-written defs are correctly typed.
  3. JSDoc
    Clarifies that response headers live on rawHeaders, that nock never sets/reads headers on definitions, and that multi-value headers may be string[] when definitions are loaded or hand-written.

Result

  • before((def: Definition) => { ... def.rawHeaders ... }) and similar code type-check without casts or custom extensions.
  • The type accurately describes what nock records and what define() / loadDefs() accept.

@mikicho mikicho enabled auto-merge (squash) April 20, 2026 20:43
@mikicho mikicho merged commit 07fbfab into nock:main Apr 20, 2026
13 of 14 checks passed
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 14.0.13 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Type definitions for nock.Definition out-of-alignment with reality

2 participants