Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 49 additions & 1 deletion MIGRATION.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,57 @@
# MIGRATION GUIDES

## Migration guide from v6.x.x to v7.0.0

- [Node.js v18 is no longer supported.](#nodejs-v18-is-no-longer-supported)
- [When using global fetch with Node.js v22, v23, v24, undici v6 should be installed.](#when-using-global-fetch-with-nodejs-v22-v23-v24-undici-v6-should-be-installed)
- [undici v7 supports](#undici-v7-supports)

### Node.js v18 is no longer supported.

Node.js v18 is no longer supported.

### When using global fetch with Node.js v22, v23, v24, undici v6 should be installed.

The global fetch built-in to Node.js v20, v22, and v23 is undici v6.

So, you should install undici v6 and then load `CookieAgent` from `http-cookie-agent/undici/v6`.

```diff
- import { CookieAgent } from 'http-cookie-agent/undici';
+ import { CookieAgent } from 'http-cookie-agent/undici/v6';
```

### undici v7 supports

When using `CookieClient` or `createCookieClient`, you should replace it with the compose method.

```diff
- import { CookieClient } from 'http-cookie-agent/undici';
+ import { cookie } from 'http-cookie-agent/undici';
+ import { Client } from 'undici';

- const client = new CookieClient('https://example.com', { cookie: { jar } });
+ const client = new Client('https://example.com').compose(cookie({ jar }));
```

When using `CookieAgent`, you can use the code as is.
If you want to redirect like undici v6, you can add a "redirect" feature with the compose method.

```typescript
import { CookieAgent } from 'http-cookie-agent/undici';
import { CookieJar } from 'tough-cookie';
import { fetch, interceptors } from 'undici';

const jar = new CookieJar();
const agent = new CookieAgent({ cookies: { jar } }).compose(interceptors.redirect());

await fetch('https://example.com', { dispatcher: agent, maxRedirections: 3 });
```

## Migration guide from v2.x.x to v4.0.0

- [The import path has been changed.](#the-import-path-has-been-changed)
- [The property name for passing cookiejar to agent has been changed.](#the-property-name-for-passing-cookiejar-to-agent-has-been-changed)
- [The property name for passing CookieJar to Agent has been changed.](#the-property-name-for-passing-cookiejar-to-agent-has-been-changed)
- [Using synchronous CookieJar functions by default.](#using-synchronous-cookiejar-functions-by-default)

### The import path has been changed.
Expand Down
55 changes: 22 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ Allows cookies with every Node.js HTTP clients (e.g. Node.js global fetch, undic
- [Install](#install)
- [Usage](#usage)
- [Supported libraries](#supported-libraries)
- [Using with an asynchronous Cookie store](#using-with-an-asynchronous-cookie-store)
- [Using with another Agent library](#using-with-another-agent-library)
- [Contributing](#contributing)
- [License](#license)
Expand Down Expand Up @@ -86,6 +85,23 @@ const agent = new CookieAgent({ cookies: { jar } });
await fetch('https://example.com', { dispatcher: agent });
```

Alternatively, `http-cookie-agent` can be used as [interceptors](https://github.com/nodejs/undici/blob/v7.0.0/docs/docs/api/Dispatcher.md#dispatchercomposeinterceptors-interceptor).
In this case, the `cookie()` must be placed at the beginning of the interceptors.

```js
import { fetch, interceptors } from 'undici';
import { CookieJar } from 'tough-cookie';
import { cookie } from 'http-cookie-agent/undici';

const jar = new CookieJar();
const agent = new Agent()
.compose(cookie({ jar }))
.compose(interceptors.retry())
.compose(interceptors.redirect({ maxRedirections: 3 }));

await fetch('https://example.com', { dispatcher: agent });
```

#### `node:http` / `node:https`

```js
Expand Down Expand Up @@ -258,7 +274,7 @@ await client.get('https://example.com');
```js
import { request, setGlobalDispatcher } from 'urllib';
import { CookieJar } from 'tough-cookie';
import { CookieClient } from 'http-cookie-agent/undici';
import { CookieAgent } from 'http-cookie-agent/undici';

const jar = new CookieJar();
const agent = new CookieAgent({ cookies: { jar } });
Expand Down Expand Up @@ -290,44 +306,17 @@ https.get('https://example.com', { agent }, (res) => {

#### `undici`

If you want to use another undici Agent library, use `CookieClient` via factory function.
If you want to use another undici Agent library, use `cookie` with the compose method.

```js
import { fetch, ProxyAgent } from 'undici';
import { CookieJar } from 'tough-cookie';
import { CookieClient } from 'http-cookie-agent/undici';
import { cookie } from 'http-cookie-agent/undici';

const jar = new CookieJar();
const agent = new ProxyAgent({
factory: (origin, opts) => {
return new CookieClient(origin, {
...opts,
cookies: { jar },
});
},
});

await fetch('https://example.com', { dispatcher: agent });
```

If you want to use another undici Client library, wrap the client in `createCookieClient`.

```js
import { fetch, Agent, MockClient } from 'undici';
import { CookieJar } from 'tough-cookie';
import { createCookieClient } from 'http-cookie-agent/undici';

const CookieClient = createCookieClient(MockClient);

const jar = new CookieJar();
const agent = new Agent({
factory: (origin, opts) => {
return new CookieClient(origin, {
...opts,
cookies: { jar },
});
},
});
/* ... */
}).compose(cookie({ jar }));

await fetch('https://example.com', { dispatcher: agent });
```
Expand Down
2 changes: 1 addition & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { configs as sharedConfigs } from '@3846masa/configs/eslint';

/** @type {import('eslint').Linter.Config[]} */
const configs = [
{ ignores: ['dist/', 'http/index.js', 'undici/index.js'] },
{ ignores: ['dist/', 'http/index.js', 'undici/index.js', 'undici/v6/index.js'] },
...sharedConfigs,
{
files: ['examples/**/*'],
Expand Down
5 changes: 2 additions & 3 deletions examples/undici/proxy.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import http from 'node:http';

import { CookieClient } from 'http-cookie-agent/undici';
import { cookie } from 'http-cookie-agent/undici';
import { createProxy } from 'proxy';
import { CookieJar } from 'tough-cookie';
import { fetch, ProxyAgent } from 'undici';
Expand All @@ -11,9 +11,8 @@ proxyServer.listen(9000);

const jar = new CookieJar();
const agent = new ProxyAgent({
factory: (origin, /** @type {object} */ opts) => new CookieClient(origin, { ...opts, cookies: { jar } }),
uri: 'http://127.0.0.1:9000',
});
}).compose(cookie({ jar }));

await fetch('https://httpbin.org/cookies/set/session/userid', { dispatcher: agent });

Expand Down
14 changes: 14 additions & 0 deletions examples/undici/with_interceptor.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { CookieAgent } from 'http-cookie-agent/undici';
import { CookieJar } from 'tough-cookie';
import { fetch, interceptors } from 'undici';

const jar = new CookieJar();
const agent = new CookieAgent({ cookies: { jar } }).compose(
interceptors.retry(),
interceptors.redirect({ maxRedirections: 3 }),
);

await fetch('https://httpbin.org/cookies/set/session/userid', { dispatcher: agent });

const cookies = await jar.getCookies('https://httpbin.org');
console.log(cookies);
36 changes: 28 additions & 8 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,33 @@
/** @type {import('jest').Config} */
const config = {
extensionsToTreatAsEsm: ['.ts'],
injectGlobals: false,
roots: ['./src'],
setupFiles: ['./jest/setup.ts'],
testMatch: ['**/__tests__/*.spec.ts'],
transform: {
'\\.+(ts)$': 'babel-jest',
},
projects: [
{
displayName: 'default',
extensionsToTreatAsEsm: ['.ts'],
injectGlobals: false,
roots: ['./src'],
setupFiles: ['./jest/setup.ts'],
testMatch: ['**/__tests__/*.spec.ts', '!**/undici/v6/__tests__/*.spec.ts'],
transform: {
'\\.+(ts)$': 'babel-jest',
},
},
{
displayName: 'undici@6',
extensionsToTreatAsEsm: ['.ts'],
injectGlobals: false,
moduleNameMapper: {
'^undici$': 'undici@v6',
'^undici/(.*)$': 'undici@v6/$1',
},
roots: ['./src'],
setupFiles: ['./jest/setup.ts'],
testMatch: ['**/undici/v6/__tests__/*.spec.ts'],
transform: {
'\\.+(ts)$': 'babel-jest',
},
},
],
};

module.exports = config;
10 changes: 6 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@
"author": "3846masa <[email protected]>",
"exports": {
"./http": "./http/index.js",
"./undici": "./undici/index.js"
"./undici": "./undici/index.js",
"./undici/v6": "./undici/v6/index.js"
},
"files": [
"dist",
Expand Down Expand Up @@ -94,12 +95,13 @@
"superagent": "10.2.0",
"tough-cookie": "5.1.2",
"typescript": "5.8.3",
"undici": "6.21.2",
"urllib": "4.4.0"
"undici": "7.8.0",
"undici@v6": "npm:[email protected]",
"urllib": "4.6.11"
},
"peerDependencies": {
"tough-cookie": "^4.0.0 || ^5.0.0",
"undici": "^5.11.0 || ^6.0.0"
"undici": "^7.0.0"
},
"peerDependenciesMeta": {
"undici": {
Expand Down
50 changes: 41 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading