klaemo opened a new pull request, #382:
URL: https://github.com/apache/couchdb-nano/pull/382
## Overview
Fixes to `lib/nano.d.ts` only; there are no runtime changes. As agreed in
#381, this combines #362, #380 and #381, because they touch the same lines.
1. **`Configuration.parseUrl` was missing (#362).** The runtime still reads
it (`'parseUrl' in cfg`), and the README documents it. The "Set to false to
prevent parsing of url" comment had ended up above `headers`, with the "Custom
request headers" comment after it. This adds `parseUrl?: boolean` back and puts
both comments on the right properties.
2. **`Configuration.agentOptions` is now a Dispatcher instance (#380).** It
used to be a union of `AgentOptions` and constructor types (`typeof
undici.Agent`, ...). nano passes the value unchanged to `fetch` as
`dispatcher`, so it has to be an instance. Before this change, `new
Agent({...})` and `new MockAgent()` failed with TS2322. Passing the `Agent`
class or a plain options object typechecked, but every request then failed with
`TypeError: agent.dispatch is not a function`. The `AgentOptions` interface
stays exported, so existing `nano.AgentOptions` references keep compiling.
3. **`RequestError.request` now describes the object nano attaches (#380).**
That object is the scrubbed `fetchOptions` from `relax()`: `url` (including the
query string), lower-case `method`, `headers`, `body`, `credentials`,
`redirect`, `signal`, `bodyTimeout`, and `dispatcher` when one is configured.
This replaces the old `uri`/`qs` shape, which nano 11 never sets. All
properties stay optional, like the rest of `RequestError`.
4. **No more `undici` import (#381).** This is option 2 from the issue.
`nano.d.ts` declares a structural `nano.Dispatcher` interface
(`dispatch(options: object, handler: object): boolean`) instead of `import
undici from "undici"`. Consumers no longer need undici's types to compile with
`skipLibCheck: false`, and with `skipLibCheck: true` `agentOptions` is no
longer silently `any`. undici remains a devDependency for the test mocks.
Compatibility: the only code that stops compiling is code that was already
broken at runtime. That covers reading `err.request.uri`/`err.request.qs`
(always `undefined` in v11) and passing a class, a plain object or a
non-dispatcher as `agentOptions`. Comparisons like `err.request?.method ===
'GET'` still compile, although at runtime the method is lower case.
## Testing recommendations
`npm test` passes (`tsc lib/nano.d.ts` plus 243 tests). The repo has no
type-level tests, so I checked the changes with consumer projects using
`module`/`moduleResolution: nodenext`, `strict` and `skipLibCheck: false`.
With undici 7 installed, this file compiles cleanly with this PR as both ESM
and CJS (`import Nano = require('nano')`). Against `main` it gives 7 × TS2322
(one per instance line), TS2353 on `parseUrl`, TS2339 on `request.url`, and 3
unused `@ts-expect-error` directives:
```ts
import Nano from 'nano'
import { Agent, MockAgent, Pool, ProxyAgent, RetryAgent, getGlobalDispatcher
} from 'undici'
const url = 'http://localhost:5984'
// accepted: Dispatcher instances, parseUrl
Nano({ url, agentOptions: new Agent({ connections: 10 }) })
Nano({ url, agentOptions: new MockAgent() })
Nano({ url, agentOptions: new Pool(url) })
Nano({ url, agentOptions: new ProxyAgent('http://proxy:8080') })
Nano({ url, agentOptions: new RetryAgent(new Agent()) })
Nano({ url, agentOptions: getGlobalDispatcher() })
Nano({ url, agentOptions: new Agent().compose((d) => d) })
Nano({ url: `${url}/mydb`, parseUrl: false })
// rejected: these all throw "agent.dispatch is not a function" at runtime
// @ts-expect-error class constructor, not an instance
Nano({ url, agentOptions: Agent })
// @ts-expect-error plain options object
Nano({ url, agentOptions: { bodyTimeout: 1000 } })
// RequestError.request matches what nano attaches
const err = {} as Nano.RequestError
const reqUrl: string | undefined = err.request?.url
const method: string | undefined = err.request?.method
// @ts-expect-error not present at runtime; the query string is part of `url`
err.request?.qs
// @ts-expect-error not present at runtime; see `url` (`err.headers.uri`
still exists)
err.request?.uri
```
Without undici installed, this compiles cleanly with this PR. Against `main`
it fails with `TS2307: Cannot find module 'undici'` in `nano.d.ts`:
```ts
import Nano from 'nano'
Nano({ url: 'http://localhost:5984' })
// @ts-expect-error not a Dispatcher
Nano({ url: 'http://localhost:5984', agentOptions: 42 })
```
For reference, this is the runtime `err.request` for a 404 with an `Agent`
configured. I got it against a local stub server with nano 11.0.7 on Node 24.21:
```js
{
url: 'http://localhost:39187/db/doc?revs_info=true',
method: 'get',
headers: { accept: 'application/json', 'user-agent': 'nano/11.0.7 (Node.js
v24.21.0)',
'Accept-Encoding': 'deflate, gzip', Authorization: 'XXXXXXX',
'content-type': 'application/json' },
credentials: 'include',
body: undefined,
redirect: 'error',
signal: undefined,
bodyTimeout: 0,
dispatcher: Agent { ... }
}
```
## GitHub issue number
Fixes #362
Fixes #380
Fixes #381
## Related Pull Requests
None. Separately, the README and migration guide examples pass the agent as
`undiciOptions`, which nano ignores, rather than as `agentOptions`. That's a
docs fix and not part of this PR.
## Checklist
- [x] Code is written and works correctly;
- [x] Changes are covered by tests; (`tsc lib/nano.d.ts` in `npm test`, plus
the consumer snippets above; the repo has no type-test harness)
- [x] Documentation reflects the changes; (JSDoc in `nano.d.ts`)
---
This PR was prepared with Claude Code (AI-assisted, per the ASF generative
tooling guidance). I reviewed the changes and checked them against
`lib/nano.js`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]