diff --git a/.eslintrc b/.eslintrc
index 466fc67d..9bcdb468 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -2,16 +2,5 @@
"extends": [
"eslint-config-egg/typescript",
"eslint-config-egg/lib/rules/enforce-node-prefix"
- ],
- "parserOptions": {
- // recommend to use another config file like tsconfig.eslint.json and extends tsconfig.json in it.
- // because you may be need to lint test/**/*.test.ts but no need to emit to js.
- // @see https://github.com/typescript-eslint/typescript-eslint/issues/890
- "project": "./tsconfig.eslint.json"
- },
- "ignorePatterns": [
- "src/**/*.js",
- "src/esm",
- "src/cjs"
]
}
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
deleted file mode 100644
index 4285be1f..00000000
--- a/.github/workflows/codeql-analysis.yml
+++ /dev/null
@@ -1,70 +0,0 @@
-# For most projects, this workflow file will not need changing; you simply need
-# to commit it to your repository.
-#
-# You may wish to alter this file to override the set of languages analyzed,
-# or to provide custom queries or build logic.
-#
-# ******** NOTE ********
-# We have attempted to detect the languages in your repository. Please check
-# the `language` matrix defined below to confirm you have the correct set of
-# supported CodeQL languages.
-#
-name: "CodeQL"
-
-on:
- push:
- branches: [ "master" ]
- pull_request:
- # The branches below must be a subset of the branches above
- branches: [ "master" ]
-
-jobs:
- analyze:
- name: Analyze
- runs-on: ubuntu-latest
- permissions:
- actions: read
- contents: read
- security-events: write
-
- strategy:
- fail-fast: false
- matrix:
- language: [ 'javascript', 'typescript' ]
- # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
- # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
-
- # Initializes the CodeQL tools for scanning.
- - name: Initialize CodeQL
- uses: github/codeql-action/init@v3
- with:
- languages: ${{ matrix.language }}
- # If you wish to specify custom queries, you can do so here or in a config file.
- # By default, queries listed here will override any specified in a config file.
- # Prefix the list here with "+" to use these queries and those in the config file.
-
- # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
- # queries: security-extended,security-and-quality
-
-
- # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
- # If this step fails, then you should remove it and run the build manually (see below)
- - name: Autobuild
- uses: github/codeql-action/autobuild@v3
-
- # ℹ️ Command-line programs to run using the OS shell.
- # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
-
- # If the Autobuild fails above, remove it and uncomment the following three lines.
- # modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
-
- # - run: |
- # echo "Run, Build Application using script"
- # ./location_of_script_within_repo/buildscript.sh
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v3
diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml
index 9e51f0d3..271cd4b1 100644
--- a/.github/workflows/nodejs.yml
+++ b/.github/workflows/nodejs.yml
@@ -12,6 +12,6 @@ jobs:
uses: node-modules/github-actions/.github/workflows/node-test.yml@master
with:
os: 'ubuntu-latest, macos-latest, windows-latest'
- version: '14.19.3, 14, 16, 18, 20, 22'
+ version: '18.19.0, 20, 22'
secrets:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
diff --git a/README.md b/README.md
index ec5c9a63..48332177 100644
--- a/README.md
+++ b/README.md
@@ -283,25 +283,14 @@ Fork [undici benchmarks script](https://github.com/fengmk2/undici/blob/urllib-be
| undici - stream | 45 | 12523.45 req/sec | ± 2.97 % | + 754.61 % |
| undici - dispatch | 51 | 12970.18 req/sec | ± 3.15 % | + 785.10 % |
+## License
+
+[MIT](LICENSE)
## Contributors
-|[
fengmk2](https://github.com/fengmk2)
|[
dead-horse](https://github.com/dead-horse)
|[
semantic-release-bot](https://github.com/semantic-release-bot)
|[
xingrz](https://github.com/xingrz)
|[
popomore](https://github.com/popomore)
|[
JacksonTian](https://github.com/JacksonTian)
|
-| :---: | :---: | :---: | :---: | :---: | :---: |
-|[
ibigbug](https://github.com/ibigbug)
|[
greenkeeperio-bot](https://github.com/greenkeeperio-bot)
|[
atian25](https://github.com/atian25)
|[
killagu](https://github.com/killagu)
|[
paambaati](https://github.com/paambaati)
|[
tremby](https://github.com/tremby)
|
-|[
denghongcai](https://github.com/denghongcai)
|[
gemwuu](https://github.com/gemwuu)
|[
XadillaX](https://github.com/XadillaX)
|[
alsotang](https://github.com/alsotang)
|[
leoner](https://github.com/leoner)
|[
hyj1991](https://github.com/hyj1991)
|
-|[
isayme](https://github.com/isayme)
|[
cyjake](https://github.com/cyjake)
|[
whxaxes](https://github.com/whxaxes)
|[
chadxz](https://github.com/chadxz)
|[
adapt0](https://github.com/adapt0)
|[
danielwpz](https://github.com/danielwpz)
|
-|[
danielsss](https://github.com/danielsss)
|[
Jeff-Tian](https://github.com/Jeff-Tian)
|[
nick-ng](https://github.com/nick-ng)
|[
rishavsharan](https://github.com/rishavsharan)
|[
willizm](https://github.com/willizm)
|[
davidkhala](https://github.com/davidkhala)
|
-|[
aleafs](https://github.com/aleafs)
|[
Amunu](https://github.com/Amunu)
|[
azure-pipelines[bot]](https://github.com/apps/azure-pipelines)
|[
capsice](https://github.com/capsice)
|[
changzhiwin](https://github.com/changzhiwin)
|[
yuzhigang33](https://github.com/yuzhigang33)
|
-|[
elrrrrrrr](https://github.com/elrrrrrrr)
|[
fishbar](https://github.com/fishbar)
|[
gxcsoccer](https://github.com/gxcsoccer)
|[
mars-coder](https://github.com/mars-coder)
|[
rockdai](https://github.com/rockdai)
|[
dickeylth](https://github.com/dickeylth)
|
-[
aladdin-add](https://github.com/aladdin-add)
-
-This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Mon Dec 04 2023 00:13:39 GMT+0800`.
+[![Contributors](https://contrib.rocks/image?repo=node-modules/urllib)](https://github.com/node-modules/urllib/graphs/contributors)
-
-
-## License
-
-[MIT](LICENSE)
+Made with [contributors-img](https://contrib.rocks).
diff --git a/package.json b/package.json
index cecb688a..a1fff8c9 100644
--- a/package.json
+++ b/package.json
@@ -1,10 +1,10 @@
{
"name": "urllib",
- "version": "3.25.1",
+ "version": "4.0.0",
"publishConfig": {
"tag": "latest"
},
- "description": "Help in opening URLs (mostly HTTP) in a complex world — basic and digest authentication, redirections, cookies and more. Base undici fetch API.",
+ "description": "Help in opening URLs (mostly HTTP) in a complex world — basic and digest authentication, redirections, timeout and more. Base undici API.",
"keywords": [
"urllib",
"http",
@@ -39,42 +39,35 @@
"test": "npm run lint && vitest run",
"test-keepalive": "cross-env TEST_KEEPALIVE_COUNT=50 vitest run --test-timeout 180000 keep-alive-header.test.ts",
"cov": "vitest run --coverage",
- "preci": "node scripts/pre_test.js",
- "ci": "npm run lint && npm run cov && node scripts/build_test.js",
- "contributor": "git-contributor",
+ "ci": "npm run lint && npm run cov && npm run prepublishOnly && attw --pack",
"clean": "rm -rf dist",
"prepublishOnly": "npm run build"
},
"dependencies": {
- "default-user-agent": "^1.0.0",
- "digest-header": "^1.0.0",
- "form-data-encoder": "^1.7.2",
- "formdata-node": "^4.3.3",
- "formstream": "^1.1.1",
+ "formstream": "^1.5.1",
"mime-types": "^2.1.35",
- "pump": "^3.0.0",
- "qs": "^6.11.2",
- "type-fest": "^4.3.1",
- "undici": "^5.28.2",
- "ylru": "^1.3.2"
+ "qs": "^6.12.1",
+ "type-fest": "^4.20.1",
+ "undici": "^6.19.2",
+ "ylru": "^2.0.0"
},
"devDependencies": {
+ "@arethetypeswrong/cli": "^0.15.3",
+ "@eggjs/tsconfig": "^1.3.3",
"@tsconfig/node18": "^18.2.1",
"@tsconfig/strictest": "^2.0.2",
"@types/busboy": "^1.5.0",
- "@types/default-user-agent": "^1.0.0",
"@types/mime-types": "^2.1.1",
"@types/node": "^20.2.1",
- "@types/pump": "^1.1.1",
+ "@types/proxy": "^1.0.4",
"@types/qs": "^6.9.7",
"@types/selfsigned": "^2.0.1",
"@types/tar-stream": "^2.2.2",
- "@vitest/coverage-v8": "^1.3.1",
+ "@vitest/coverage-v8": "^1.6.0",
"busboy": "^1.6.0",
"cross-env": "^7.0.3",
- "eslint": "^8.25.0",
- "eslint-config-egg": "^12.1.0",
- "git-contributor": "^2.0.0",
+ "eslint": "8",
+ "eslint-config-egg": "13",
"iconv-lite": "^0.6.3",
"proxy": "^1.0.2",
"selfsigned": "^2.0.1",
@@ -82,10 +75,10 @@
"tshy": "^1.0.0",
"tshy-after": "^1.0.0",
"typescript": "^5.0.4",
- "vitest": "^1.3.1"
+ "vitest": "^1.6.0"
},
"engines": {
- "node": ">= 14.19.3"
+ "node": ">= 18.19.0"
},
"license": "MIT",
"type": "module",
@@ -98,10 +91,12 @@
"exports": {
".": {
"import": {
+ "source": "./src/index.ts",
"types": "./dist/esm/index.d.ts",
"default": "./dist/esm/index.js"
},
"require": {
+ "source": "./src/index.ts",
"types": "./dist/commonjs/index.d.ts",
"default": "./dist/commonjs/index.js"
}
diff --git a/scripts/build_test.js b/scripts/build_test.js
deleted file mode 100644
index d2b06180..00000000
--- a/scripts/build_test.js
+++ /dev/null
@@ -1,15 +0,0 @@
-import { execSync } from 'child_process';
-
-function main() {
- if (process.version.startsWith('v14.')) {
- console.log(`ignore build:test on Node.js ${process.version}`);
- return;
- }
- const cwd = process.cwd()
- execSync('npm run build:test', {
- cwd,
- stdio: [ 'inherit', 'inherit', 'inherit' ],
- });
-}
-
-main();
diff --git a/scripts/pre_test.js b/scripts/pre_test.js
deleted file mode 100644
index f79e535d..00000000
--- a/scripts/pre_test.js
+++ /dev/null
@@ -1,24 +0,0 @@
-import { execSync } from 'node:child_process';
-import { writeFileSync, readFileSync } from 'node:fs';
-import { join } from 'node:path';
-
-function main() {
- if (!process.version.startsWith('v14.')) {
- return;
- }
- console.log(`use vitest@^0.33.0 on Node.js ${process.version}`);
- const cwd = process.cwd()
- execSync('npm i vitest@^0.33.0 @vitest/coverage-v8@^0.33.0', {
- cwd,
- stdio: [ 'inherit', 'inherit', 'inherit' ],
- });
- if (process.env.CI) {
- // add --no-threads
- const pkgFile = join(process.cwd(), 'package.json');
- const pkg = JSON.parse(readFileSync(pkgFile, 'utf-8'));
- pkg.scripts.cov = `${pkg.scripts.cov} --no-threads`;
- writeFileSync(pkgFile, JSON.stringify(pkg));
- }
-}
-
-main();
diff --git a/scripts/replace_urllib_version.js b/scripts/replace_urllib_version.js
index 0efb7b02..ee06f779 100644
--- a/scripts/replace_urllib_version.js
+++ b/scripts/replace_urllib_version.js
@@ -1,7 +1,7 @@
#!/usr/bin/env node
-import fs from 'fs/promises';
-import path from 'path';
+import fs from 'node:fs/promises';
+import path from 'node:path';
async function main() {
const root = process.cwd();
@@ -12,9 +12,9 @@ async function main() {
];
for (const file of files) {
const content = await fs.readFile(file, 'utf-8');
- // replace "('node-urllib', 'VERSION')" to "('node-urllib', 'pkg.version')"
- const newContent = content.replace(/\(\'node-urllib\', \'VERSION\'\)/, (match) => {
- const after = `('node-urllib', '${pkg.version}')`;
+ // replace "const VERSION = 'VERSION';" to "const VERSION = '4.0.0';"
+ const newContent = content.replace(/const VERSION = 'VERSION';/, match => {
+ const after = `const VERSION = '${pkg.version}';`;
console.log('[%s] %s => %s', file, match, after);
return after;
});
diff --git a/src/HttpClient.ts b/src/HttpClient.ts
index 5bf5e7d2..dad15287 100644
--- a/src/HttpClient.ts
+++ b/src/HttpClient.ts
@@ -11,34 +11,33 @@ import {
} from 'node:zlib';
import { Blob } from 'node:buffer';
import { Readable, pipeline } from 'node:stream';
-import stream from 'node:stream';
+import { pipeline as pipelinePromise } from 'node:stream/promises';
import { basename } from 'node:path';
import { createReadStream } from 'node:fs';
import { format as urlFormat } from 'node:url';
import { performance } from 'node:perf_hooks';
import querystring from 'node:querystring';
+import { setTimeout as sleep } from 'node:timers/promises';
import {
- FormData as FormDataNative,
+ FormData,
request as undiciRequest,
Dispatcher,
Agent,
getGlobalDispatcher,
Pool,
} from 'undici';
+// eslint-disable-next-line @typescript-eslint/ban-ts-comment
+// @ts-ignore
import undiciSymbols from 'undici/lib/core/symbols.js';
-import { FormData as FormDataNode } from 'formdata-node';
-import { FormDataEncoder } from 'form-data-encoder';
-import createUserAgent from 'default-user-agent';
import mime from 'mime-types';
import qs from 'qs';
-import pump from 'pump';
// Compatible with old style formstream
import FormStream from 'formstream';
import { HttpAgent, CheckAddressFunction } from './HttpAgent.js';
import type { IncomingHttpHeaders } from './IncomingHttpHeaders.js';
import { RequestURL, RequestOptions, HttpMethod, RequestMeta } from './Request.js';
import { RawResponseWithMeta, HttpClientResponse, SocketInfo } from './Response.js';
-import { parseJSON, sleep, digestAuthHeader, globalId, performanceTime, isReadable } from './utils.js';
+import { parseJSON, digestAuthHeader, globalId, performanceTime, isReadable } from './utils.js';
import symbols from './symbols.js';
import { initDiagnosticsChannel } from './diagnosticsChannel.js';
import { HttpClientConnectTimeoutError, HttpClientRequestTimeoutError } from './HttpClientError.js';
@@ -49,24 +48,12 @@ type PropertyShouldBe = Omit & { [P in K]: V };
type IUndiciRequestOption = PropertyShouldBe;
const PROTO_RE = /^https?:\/\//i;
-const FormData = FormDataNative ?? FormDataNode;
-// impl promise pipeline on Node.js 14
-const pipelinePromise = stream.promises?.pipeline ?? function pipeline(...args: any[]) {
- return new Promise((resolve, reject) => {
- pump(...args, (err?: Error) => {
- if (err) return reject(err);
- resolve();
- });
- });
-};
function noop() {
// noop
}
const debug = debuglog('urllib:HttpClient');
-// Node.js 14 or 16
-const isNode14Or16 = /v1[46]\./.test(process.version);
export type ClientOptions = {
defaultArgs?: RequestOptions;
@@ -125,7 +112,10 @@ class BlobFromStream {
}
}
-export const HEADER_USER_AGENT = createUserAgent('node-urllib', 'VERSION');
+export const VERSION = 'VERSION';
+// 'node-urllib/4.0.0 Node.js/18.19.0 (darwin; x64)'
+export const HEADER_USER_AGENT =
+ `node-urllib/${VERSION} Node.js/${process.version.substring(1)} (${process.platform}; ${process.arch})`;
function getFileName(stream: Readable) {
const filePath: string = (stream as any).path;
@@ -207,13 +197,13 @@ export class HttpClient extends EventEmitter {
getDispatcherPoolStats() {
const agent = this.getDispatcher();
// origin => Pool Instance
- const clients: Map> | undefined = agent[undiciSymbols.kClients];
+ const clients: Map> | undefined = Reflect.get(agent, undiciSymbols.kClients);
const poolStatsMap: Record = {};
if (!clients) {
return poolStatsMap;
}
for (const [ key, ref ] of clients) {
- const pool = ref.deref();
+ const pool = typeof ref.deref === 'function' ? ref.deref() : ref as unknown as Pool;
const stats = pool?.stats;
if (!stats) continue;
poolStatsMap[key] = {
@@ -451,9 +441,11 @@ export class HttpClient extends EventEmitter {
} else if (typeof args.files === 'string' || Buffer.isBuffer(args.files)) {
uploadFiles.push([ 'file', args.files ]);
} else if (typeof args.files === 'object') {
- for (const field in args.files) {
+ const files = args.files as Record;
+ for (const field in files) {
// set custom fileName
- uploadFiles.push([ field, args.files[field], field ]);
+ const file = files[field];
+ uploadFiles.push([ field, file, field ]);
}
}
// set normal fields first
@@ -478,18 +470,7 @@ export class HttpClient extends EventEmitter {
isStreamingRequest = true;
}
}
-
- if (FormDataNative) {
- requestOptions.body = formData;
- } else {
- // Node.js 14 does not support spec-compliant FormData
- // https://github.com/octet-stream/form-data#usage
- const encoder = new FormDataEncoder(formData as any);
- Object.assign(headers, encoder.headers);
- // fix "Content-Length":"NaN"
- delete headers['Content-Length'];
- requestOptions.body = Readable.from(encoder);
- }
+ requestOptions.body = formData;
} else if (args.content) {
if (!isGETOrHEAD) {
// handle content
@@ -507,7 +488,7 @@ export class HttpClient extends EventEmitter {
|| isReadable(args.data);
if (isGETOrHEAD) {
if (!isStringOrBufferOrReadable) {
- let query;
+ let query: string;
if (args.nestedQuerystring) {
query = qs.stringify(args.data);
} else {
@@ -608,9 +589,6 @@ export class HttpClient extends EventEmitter {
res = Object.assign(response.body, res);
}
} else if (args.writeStream) {
- if (isNode14Or16 && args.writeStream.destroyed) {
- throw new Error('writeStream is destroyed');
- }
if (args.compressed === true && isCompressedContent) {
const decoder = contentEncoding === 'gzip' ? createGunzip() : createBrotliDecompress();
await pipelinePromise(response.body, decoder, args.writeStream);
diff --git a/src/diagnosticsChannel.ts b/src/diagnosticsChannel.ts
index 97780e00..38b8e2a4 100644
--- a/src/diagnosticsChannel.ts
+++ b/src/diagnosticsChannel.ts
@@ -20,15 +20,14 @@ let initedDiagnosticsChannel = false;
// -> undici:request:trailers => { request, trailers }
function subscribe(name: string, listener: (message: unknown, channelName: string | symbol) => void) {
- if (typeof diagnosticsChannel.subscribe === 'function') {
- diagnosticsChannel.subscribe(name, listener);
- } else {
- // TODO: support Node.js 14, will be removed on the next major version
- diagnosticsChannel.channel(name).subscribe(listener);
- }
+ diagnosticsChannel.subscribe(name, listener);
}
-function formatSocket(socket: Socket) {
+type SocketExtend = Socket & {
+ [key: symbol]: string | number | Date | undefined;
+};
+
+function formatSocket(socket: SocketExtend) {
if (!socket) return socket;
return {
localAddress: socket[symbols.kSocketLocalAddress],
@@ -41,8 +40,7 @@ function formatSocket(socket: Socket) {
}
// make sure error contains socket info
-const kDestroy = Symbol('kDestroy');
-Socket.prototype[kDestroy] = Socket.prototype.destroy;
+const destroySocket = Socket.prototype.destroy;
Socket.prototype.destroy = function(err?: any) {
if (err) {
Object.defineProperty(err, symbols.kErrorSocket, {
@@ -51,12 +49,12 @@ Socket.prototype.destroy = function(err?: any) {
value: this,
});
}
- return this[kDestroy](err);
+ return destroySocket.call(this, err);
};
function getRequestOpaque(request: DiagnosticsChannel.Request, kHandler?: symbol) {
if (!kHandler) return;
- const handler = request[kHandler];
+ const handler = Reflect.get(request, kHandler);
// maxRedirects = 0 will get [Symbol(handler)]: RequestHandler {
// responseHeaders: null,
// opaque: {
@@ -70,7 +68,7 @@ function getRequestOpaque(request: DiagnosticsChannel.Request, kHandler?: symbol
}
export function initDiagnosticsChannel() {
- // makre sure init global DiagnosticsChannel once
+ // make sure init global DiagnosticsChannel once
if (initedDiagnosticsChannel) return;
initedDiagnosticsChannel = true;
@@ -97,29 +95,27 @@ export function initDiagnosticsChannel() {
opaque[symbols.kRequestTiming].queuing = performanceTime(opaque[symbols.kRequestStartTime]);
});
- // diagnosticsChannel.channel('undici:client:beforeConnect')
-
subscribe('undici:client:connectError', (message, name) => {
- const { error, connectParams } = message as DiagnosticsChannel.ClientConnectErrorMessage & { error: any };
- let { socket } = message as DiagnosticsChannel.ClientConnectErrorMessage;
- if (!socket && error[symbols.kErrorSocket]) {
- socket = error[symbols.kErrorSocket];
+ const { error, connectParams, socket } = message as DiagnosticsChannel.ClientConnectErrorMessage & { error: any, socket: SocketExtend };
+ let sock = socket;
+ if (!sock && error[symbols.kErrorSocket]) {
+ sock = error[symbols.kErrorSocket];
}
- if (socket) {
- socket[symbols.kSocketId] = globalId('UndiciSocket');
- socket[symbols.kSocketConnectErrorTime] = new Date();
- socket[symbols.kHandledRequests] = 0;
- socket[symbols.kHandledResponses] = 0;
+ if (sock) {
+ sock[symbols.kSocketId] = globalId('UndiciSocket');
+ sock[symbols.kSocketConnectErrorTime] = new Date();
+ sock[symbols.kHandledRequests] = 0;
+ sock[symbols.kHandledResponses] = 0;
// copy local address to symbol, avoid them be reset after request error throw
- if (socket.localAddress) {
- socket[symbols.kSocketLocalAddress] = socket.localAddress;
- socket[symbols.kSocketLocalPort] = socket.localPort;
+ if (sock.localAddress) {
+ sock[symbols.kSocketLocalAddress] = sock.localAddress;
+ sock[symbols.kSocketLocalPort] = sock.localPort;
}
- socket[symbols.kSocketConnectProtocol] = connectParams.protocol;
- socket[symbols.kSocketConnectHost] = connectParams.host;
- socket[symbols.kSocketConnectPort] = connectParams.port;
+ sock[symbols.kSocketConnectProtocol] = connectParams.protocol;
+ sock[symbols.kSocketConnectHost] = connectParams.host;
+ sock[symbols.kSocketConnectPort] = connectParams.port;
debug('[%s] Socket#%d connectError, connectParams: %o, error: %s, (sock: %o)',
- name, socket[symbols.kSocketId], connectParams, (error as Error).message, formatSocket(socket));
+ name, sock[symbols.kSocketId], connectParams, (error as Error).message, formatSocket(sock));
} else {
debug('[%s] connectError, connectParams: %o, error: %o',
name, connectParams, error);
@@ -128,7 +124,7 @@ export function initDiagnosticsChannel() {
// This message is published after a connection is established.
subscribe('undici:client:connected', (message, name) => {
- const { socket, connectParams } = message as DiagnosticsChannel.ClientConnectedMessage;
+ const { socket, connectParams } = message as DiagnosticsChannel.ClientConnectedMessage & { socket: SocketExtend };
socket[symbols.kSocketId] = globalId('UndiciSocket');
socket[symbols.kSocketStartTime] = performance.now();
socket[symbols.kSocketConnectedTime] = new Date();
@@ -145,11 +141,11 @@ export function initDiagnosticsChannel() {
// This message is published right before the first byte of the request is written to the socket.
subscribe('undici:client:sendHeaders', (message, name) => {
- const { request, socket } = message as DiagnosticsChannel.ClientSendHeadersMessage;
+ const { request, socket } = message as DiagnosticsChannel.ClientSendHeadersMessage & { socket: SocketExtend };
const opaque = getRequestOpaque(request, kHandler);
if (!opaque || !opaque[symbols.kRequestId]) return;
- socket[symbols.kHandledRequests]++;
+ (socket[symbols.kHandledRequests] as number)++;
// attach socket to opaque
opaque[symbols.kRequestSocket] = socket;
debug('[%s] Request#%d send headers on Socket#%d (handled %d requests, sock: %o)',
@@ -158,11 +154,11 @@ export function initDiagnosticsChannel() {
if (!opaque[symbols.kEnableRequestTiming]) return;
opaque[symbols.kRequestTiming].requestHeadersSent = performanceTime(opaque[symbols.kRequestStartTime]);
- // first socket need to caculate the connected time
+ // first socket need to calculate the connected time
if (socket[symbols.kHandledRequests] === 1) {
// kSocketStartTime - kRequestStartTime = connected time
opaque[symbols.kRequestTiming].connected =
- performanceTime(opaque[symbols.kRequestStartTime], socket[symbols.kSocketStartTime]);
+ performanceTime(opaque[symbols.kRequestStartTime], socket[symbols.kSocketStartTime] as number);
}
});
diff --git a/src/index.ts b/src/index.ts
index cc3cec4d..6cbf7d1c 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,4 +1,4 @@
-import LRU from 'ylru';
+import { LRU } from 'ylru';
import { HttpClient, HEADER_USER_AGENT } from './HttpClient.js';
import { RequestOptions, RequestURL } from './Request.js';
diff --git a/src/utils.ts b/src/utils.ts
index bde49674..1f24c443 100644
--- a/src/utils.ts
+++ b/src/utils.ts
@@ -3,7 +3,7 @@ import { Readable } from 'node:stream';
import { performance } from 'node:perf_hooks';
import type { FixJSONCtlChars } from './Request.js';
-const JSONCtlCharsMap = {
+const JSONCtlCharsMap: Record = {
'"': '\\"', // \u0022
'\\': '\\\\', // \u005c
'\b': '\\b', // \u0008
@@ -49,12 +49,6 @@ export function parseJSON(data: string, fixJSONCtlChars?: FixJSONCtlChars) {
return data;
}
-export function sleep(ms: number) {
- return new Promise(resolve => {
- setTimeout(resolve, ms);
- });
-}
-
function md5(s: string) {
const sum = createHash('md5');
sum.update(s, 'utf8');
diff --git a/test/HttpClient.connect.rejectUnauthorized.test.ts b/test/HttpClient.connect.rejectUnauthorized.test.ts
index 47591c8b..f28192ad 100644
--- a/test/HttpClient.connect.rejectUnauthorized.test.ts
+++ b/test/HttpClient.connect.rejectUnauthorized.test.ts
@@ -1,7 +1,7 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import { HttpClient } from '../src';
-import { startServer } from './fixtures/server';
+import { HttpClient } from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('HttpClient.connect.rejectUnauthorized.test.ts', () => {
let close: any;
diff --git a/test/HttpClient.events.test.ts b/test/HttpClient.events.test.ts
index b1c4ce78..fb434c7c 100644
--- a/test/HttpClient.events.test.ts
+++ b/test/HttpClient.events.test.ts
@@ -1,7 +1,7 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import { HttpClient } from '../src';
-import { startServer } from './fixtures/server';
+import { HttpClient } from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('HttpClient.events.test.ts', () => {
let close: any;
diff --git a/test/HttpClient.test.ts b/test/HttpClient.test.ts
index 07ecdacc..c9e02825 100644
--- a/test/HttpClient.test.ts
+++ b/test/HttpClient.test.ts
@@ -1,9 +1,8 @@
import { strict as assert } from 'node:assert';
import dns from 'node:dns';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import { HttpClient } from '../src';
-import { RawResponseWithMeta } from '../src/Response';
-import { startServer } from './fixtures/server';
+import { HttpClient, RawResponseWithMeta } from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('HttpClient.test.ts', () => {
let close: any;
diff --git a/test/diagnostics_channel.test.ts b/test/diagnostics_channel.test.ts
index a31f9f8b..f3796494 100644
--- a/test/diagnostics_channel.test.ts
+++ b/test/diagnostics_channel.test.ts
@@ -1,14 +1,14 @@
import { strict as assert } from 'node:assert';
import diagnosticsChannel from 'node:diagnostics_channel';
+import { setTimeout as sleep } from 'node:timers/promises';
import { describe, it, beforeEach, afterEach } from 'vitest';
-import urllib from '../src';
+import urllib from '../src/index.js';
import type {
RequestDiagnosticsMessage,
ResponseDiagnosticsMessage,
-} from '../src';
-import symbols from '../src/symbols';
-import { startServer } from './fixtures/server';
-import { sleep } from './utils';
+} from '../src/index.js';
+import symbols from '../src/symbols.js';
+import { startServer } from './fixtures/server.js';
describe('diagnostics_channel.test.ts', () => {
let close: any;
@@ -62,9 +62,9 @@ describe('diagnostics_channel.test.ts', () => {
lastRequestOpaque = opaque;
// console.log(request);
}
- diagnosticsChannel.channel('undici:client:connected').subscribe(onMessage);
- diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(onMessage);
- diagnosticsChannel.channel('undici:request:trailers').subscribe(onMessage);
+ diagnosticsChannel.subscribe('undici:client:connected', onMessage);
+ diagnosticsChannel.subscribe('undici:client:sendHeaders', onMessage);
+ diagnosticsChannel.subscribe('undici:request:trailers', onMessage);
let traceId = `mock-traceid-${Date.now()}`;
// _url = 'https://registry.npmmirror.com/';
@@ -130,9 +130,9 @@ describe('diagnostics_channel.test.ts', () => {
assert.equal(lastRequestOpaque.tracer.socket.requests, 2 + 1000 - count);
}
- diagnosticsChannel.channel('undici:client:connected').unsubscribe(onMessage);
- diagnosticsChannel.channel('undici:client:sendHeaders').unsubscribe(onMessage);
- diagnosticsChannel.channel('undici:request:trailers').unsubscribe(onMessage);
+ diagnosticsChannel.unsubscribe('undici:client:connected', onMessage);
+ diagnosticsChannel.unsubscribe('undici:client:sendHeaders', onMessage);
+ diagnosticsChannel.unsubscribe('undici:request:trailers', onMessage);
});
it('should support trace request by urllib:request and urllib:response', async () => {
@@ -147,8 +147,8 @@ describe('diagnostics_channel.test.ts', () => {
socket = response.socket;
assert.equal(request.args.opaque, lastRequestOpaque);
}
- diagnosticsChannel.channel('urllib:request').subscribe(onRequestMessage);
- diagnosticsChannel.channel('urllib:response').subscribe(onResponseMessage);
+ diagnosticsChannel.subscribe('urllib:request', onRequestMessage);
+ diagnosticsChannel.subscribe('urllib:response', onResponseMessage);
let traceId = `mock-traceid-${Date.now()}`;
// _url = 'https://registry.npmmirror.com/';
@@ -218,8 +218,8 @@ describe('diagnostics_channel.test.ts', () => {
assert.equal(socket.handledResponses, 2 + 1000 - count);
}
- diagnosticsChannel.channel('urllib:request').unsubscribe(onRequestMessage);
- diagnosticsChannel.channel('urllib:response').unsubscribe(onResponseMessage);
+ diagnosticsChannel.unsubscribe('urllib:request', onRequestMessage);
+ diagnosticsChannel.unsubscribe('urllib:response', onResponseMessage);
});
it('should support trace request error by urllib:request and urllib:response', async () => {
@@ -236,8 +236,8 @@ describe('diagnostics_channel.test.ts', () => {
assert.equal(request.args.opaque, lastRequestOpaque);
lastError = error;
}
- diagnosticsChannel.channel('urllib:request').subscribe(onRequestMessage);
- diagnosticsChannel.channel('urllib:response').subscribe(onResponseMessage);
+ diagnosticsChannel.subscribe('urllib:request', onRequestMessage);
+ diagnosticsChannel.subscribe('urllib:response', onResponseMessage);
let traceId = `mock-traceid-${Date.now()}`;
// handle network error
@@ -311,7 +311,7 @@ describe('diagnostics_channel.test.ts', () => {
assert.equal(socket.handledRequests, 2);
assert.equal(socket.handledResponses, 2);
- diagnosticsChannel.channel('urllib:request').unsubscribe(onRequestMessage);
- diagnosticsChannel.channel('urllib:response').unsubscribe(onResponseMessage);
+ diagnosticsChannel.unsubscribe('urllib:request', onRequestMessage);
+ diagnosticsChannel.unsubscribe('urllib:response', onResponseMessage);
});
});
diff --git a/test/fixtures/server.ts b/test/fixtures/server.ts
index 1e62bb6e..6bdd593b 100644
--- a/test/fixtures/server.ts
+++ b/test/fixtures/server.ts
@@ -3,11 +3,12 @@ import { createServer, Server, IncomingMessage, ServerResponse } from 'node:http
import { createServer as createHttpsServer } from 'node:https';
import { createBrotliCompress, createGzip, gzipSync, brotliCompressSync } from 'node:zlib';
import { createReadStream } from 'node:fs';
+import { setTimeout as sleep } from 'node:timers/promises';
import busboy from 'busboy';
import iconv from 'iconv-lite';
import selfsigned from 'selfsigned';
import qs from 'qs';
-import { readableToBytes, sleep } from '../utils';
+import { readableToBytes } from '../utils.js';
const requestsPerSocket = Symbol('requestsPerSocket');
diff --git a/test/index.test.ts b/test/index.test.ts
index 90a677c0..9a403c2f 100644
--- a/test/index.test.ts
+++ b/test/index.test.ts
@@ -2,10 +2,12 @@ import { strict as assert } from 'node:assert';
import { parse as urlparse } from 'node:url';
import { readFileSync } from 'node:fs';
import { describe, it, beforeAll, afterAll, afterEach, beforeEach } from 'vitest';
-import urllib, { HttpClient, getDefaultHttpClient } from '../src';
-import { MockAgent, setGlobalDispatcher, getGlobalDispatcher } from '../src';
-import { startServer } from './fixtures/server';
-import { readableToBytes } from './utils';
+import urllib, {
+ HttpClient, getDefaultHttpClient,
+ MockAgent, setGlobalDispatcher, getGlobalDispatcher,
+} from '../src/index.js';
+import { startServer } from './fixtures/server.js';
+import { readableToBytes } from './utils.js';
describe('index.test.ts', () => {
let close: any;
diff --git a/test/keep-alive-header.test.ts b/test/keep-alive-header.test.ts
index 3d797062..83e1d620 100644
--- a/test/keep-alive-header.test.ts
+++ b/test/keep-alive-header.test.ts
@@ -1,8 +1,9 @@
import { strict as assert } from 'node:assert';
+import { setTimeout as sleep } from 'node:timers/promises';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import { HttpClient } from '../src';
-import { startServer } from './fixtures/server';
-import { isWindows, nodeMajorVersion, sleep } from './utils';
+import { HttpClient } from '../src/index.js';
+import { startServer } from './fixtures/server.js';
+import { isWindows } from './utils.js';
describe('keep-alive-header.test.ts', () => {
// should shorter than server keepalive timeout
@@ -33,8 +34,8 @@ describe('keep-alive-header.test.ts', () => {
const task = httpClient.request(_url);
// console.log('after request stats: %o', httpClient.getDispatcherPoolStats());
if (httpClient.getDispatcherPoolStats()[origin]) {
- if (!(nodeMajorVersion() === 14 || isWindows())) {
- // ignore node = 14 & windows
+ if (!isWindows()) {
+ // ignore on windows
assert.equal(httpClient.getDispatcherPoolStats()[origin].pending, 1);
assert.equal(httpClient.getDispatcherPoolStats()[origin].size, 1);
}
@@ -42,7 +43,8 @@ describe('keep-alive-header.test.ts', () => {
let response = await task;
// console.log('after response stats: %o', httpClient.getDispatcherPoolStats());
assert.equal(httpClient.getDispatcherPoolStats()[origin].pending, 0);
- assert.equal(httpClient.getDispatcherPoolStats()[origin].connected, 1);
+ // assert.equal(httpClient.getDispatcherPoolStats()[origin].connected, 1);
+ assert.equal(httpClient.getDispatcherPoolStats()[origin].connected, 0);
// console.log(response.res.socket);
assert.equal(response.status, 200);
// console.log(response.headers);
@@ -84,7 +86,7 @@ describe('keep-alive-header.test.ts', () => {
// console.log(response.headers);
assert.equal(response.headers.connection, 'keep-alive');
assert.equal(response.headers['keep-alive'], 'timeout=2');
- assert(parseInt(response.headers['x-requests-persocket'] as string) > 1);
+ assert(parseInt(response.headers['x-requests-persocket'] as string) >= 1, response.headers['x-requests-persocket'] as string);
await sleep(keepAliveTimeout / 2);
response = await httpClient.request(_url);
// console.log(response.res.socket);
@@ -128,11 +130,13 @@ describe('keep-alive-header.test.ts', () => {
// console.log(response.headers);
assert.equal(response.headers.connection, 'keep-alive');
assert.equal(response.headers['keep-alive'], 'timeout=2');
- assert(parseInt(response.headers['x-requests-persocket'] as string) > 1);
+ assert(parseInt(response.headers['x-requests-persocket'] as string) >= 1, response.headers['x-requests-persocket'] as string);
// console.log('before sleep stats: %o', httpClient.getDispatcherPoolStats());
// { connected: 2, free: 1, pending: 0, queued: 0, running: 0, size: 0 }
- assert.equal(httpClient.getDispatcherPoolStats()[origin].connected, 2);
- assert.equal(httpClient.getDispatcherPoolStats()[origin].free, 1);
+ // assert.equal(httpClient.getDispatcherPoolStats()[origin].connected, 2);
+ assert.equal(httpClient.getDispatcherPoolStats()[origin].connected, 0);
+ // assert.equal(httpClient.getDispatcherPoolStats()[origin].free, 1);
+ assert.equal(httpClient.getDispatcherPoolStats()[origin].free, 0);
await sleep(keepAliveTimeout);
// console.log('after sleep stats: %o', httpClient.getDispatcherPoolStats());
// clients maybe all gone => after sleep stats: {}
@@ -144,7 +148,7 @@ describe('keep-alive-header.test.ts', () => {
assert(httpClient.getDispatcherPoolStats()[origin].free <= 2);
assert.equal(httpClient.getDispatcherPoolStats()[origin].size, 0);
}
- } catch (err) {
+ } catch (err: any) {
if (err.message === 'other side closed') {
console.log(err);
otherSideClosed++;
diff --git a/test/non-ascii-request-header.test.ts b/test/non-ascii-request-header.test.ts
index e7073f95..1517dd25 100644
--- a/test/non-ascii-request-header.test.ts
+++ b/test/non-ascii-request-header.test.ts
@@ -1,7 +1,7 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
// https://github.com/node-modules/urllib/issues/198
describe('non-ascii-request-header.test.ts', () => {
diff --git a/test/options.auth.test.ts b/test/options.auth.test.ts
index aaeb8ea1..93b2bf65 100644
--- a/test/options.auth.test.ts
+++ b/test/options.auth.test.ts
@@ -1,7 +1,7 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.auth.test.ts', () => {
let close: any;
diff --git a/test/options.compressed.test.ts b/test/options.compressed.test.ts
index 1a17ad3b..ae64e486 100644
--- a/test/options.compressed.test.ts
+++ b/test/options.compressed.test.ts
@@ -1,9 +1,9 @@
import { strict as assert } from 'node:assert';
import { createWriteStream, createReadStream } from 'node:fs';
import { describe, it, beforeAll, afterAll, beforeEach, afterEach } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
-import { readableToString, createTempfile, nodeMajorVersion } from './utils';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
+import { readableToString, createTempfile, nodeMajorVersion } from './utils.js';
describe('options.compressed.test.ts', () => {
let close: any;
diff --git a/test/options.content.test.ts b/test/options.content.test.ts
index d8399522..0bcf9a8d 100644
--- a/test/options.content.test.ts
+++ b/test/options.content.test.ts
@@ -2,8 +2,8 @@ import { strict as assert } from 'node:assert';
import { createReadStream } from 'node:fs';
import { describe, it, beforeAll, afterAll } from 'vitest';
import fs from 'node:fs/promises';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.content.test.ts', () => {
let close: any;
diff --git a/test/options.data.test.ts b/test/options.data.test.ts
index f804bc7f..55dd5508 100644
--- a/test/options.data.test.ts
+++ b/test/options.data.test.ts
@@ -3,8 +3,8 @@ import { createReadStream } from 'node:fs';
import { Readable } from 'node:stream';
import qs from 'qs';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.data.test.ts', () => {
let close: any;
diff --git a/test/options.dataType.test.ts b/test/options.dataType.test.ts
index 725b7a58..36f32c1b 100644
--- a/test/options.dataType.test.ts
+++ b/test/options.dataType.test.ts
@@ -1,8 +1,8 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
-import { nodeMajorVersion, readableToBytes } from './utils';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
+import { nodeMajorVersion, readableToBytes } from './utils.js';
describe('options.dataType.test.ts', () => {
let close: any;
diff --git a/test/options.digestAuth.test.ts b/test/options.digestAuth.test.ts
index 463c9b61..e9385a3d 100644
--- a/test/options.digestAuth.test.ts
+++ b/test/options.digestAuth.test.ts
@@ -1,7 +1,7 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.digestAuth.test.ts', () => {
let close: any;
diff --git a/test/options.dispatcher.test.ts b/test/options.dispatcher.test.ts
index bde1e00e..ea133064 100644
--- a/test/options.dispatcher.test.ts
+++ b/test/options.dispatcher.test.ts
@@ -1,8 +1,8 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
import setup from 'proxy';
-import { request, ProxyAgent, getGlobalDispatcher, setGlobalDispatcher, Agent } from '../src';
-import { startServer } from './fixtures/server';
+import { request, ProxyAgent, getGlobalDispatcher, setGlobalDispatcher, Agent } from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.dispatcher.test.ts', () => {
let close: any;
diff --git a/test/options.files.test.ts b/test/options.files.test.ts
index 0550b5fc..60739d09 100644
--- a/test/options.files.test.ts
+++ b/test/options.files.test.ts
@@ -4,8 +4,8 @@ import fs from 'node:fs/promises';
import { createReadStream } from 'node:fs';
import { Readable } from 'node:stream';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.files.test.ts', () => {
let close: any;
@@ -274,7 +274,8 @@ describe('options.files.test.ts', () => {
const response = await urllib.request(`${_url}multipart`, {
files: {
'buffer.js': Buffer.from(rawData),
- 'readable.js': Readable.from([ rawData ]),
+ // Readable.from data must be Buffer or Bytes
+ 'readable.js': Readable.from([ Buffer.from(rawData) ]),
},
data: {
hello: 'hello world,😄😓',
diff --git a/test/options.fixJSONCtlChars.test.ts b/test/options.fixJSONCtlChars.test.ts
index 381362e3..54b84849 100644
--- a/test/options.fixJSONCtlChars.test.ts
+++ b/test/options.fixJSONCtlChars.test.ts
@@ -1,7 +1,7 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.fixJSONCtlChars.test.ts', () => {
let close: any;
diff --git a/test/options.followRedirect.test.ts b/test/options.followRedirect.test.ts
index f001101b..1a399751 100644
--- a/test/options.followRedirect.test.ts
+++ b/test/options.followRedirect.test.ts
@@ -1,7 +1,7 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.followRedirect.test.js', () => {
let close: any;
diff --git a/test/options.gzip.test.ts b/test/options.gzip.test.ts
index 6f30d43e..292c9f35 100644
--- a/test/options.gzip.test.ts
+++ b/test/options.gzip.test.ts
@@ -1,7 +1,7 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.gzip.test.ts', () => {
let close: any;
diff --git a/test/options.headers.test.ts b/test/options.headers.test.ts
index 0b3e8ad1..12acfacc 100644
--- a/test/options.headers.test.ts
+++ b/test/options.headers.test.ts
@@ -1,7 +1,7 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.headers.test.ts', () => {
let close: any;
diff --git a/test/options.method.test.ts b/test/options.method.test.ts
index 6590d162..a3adadb7 100644
--- a/test/options.method.test.ts
+++ b/test/options.method.test.ts
@@ -1,7 +1,7 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.method.test.ts', () => {
let close: any;
diff --git a/test/options.opaque.test.ts b/test/options.opaque.test.ts
index 02d3287d..eccecc0a 100644
--- a/test/options.opaque.test.ts
+++ b/test/options.opaque.test.ts
@@ -1,7 +1,7 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.opaque.test.ts', () => {
let close: any;
diff --git a/test/options.reset.test.ts b/test/options.reset.test.ts
index 889ffcd0..590bd590 100644
--- a/test/options.reset.test.ts
+++ b/test/options.reset.test.ts
@@ -1,7 +1,7 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.reset.test.ts', () => {
let close: any;
diff --git a/test/options.retry.test.ts b/test/options.retry.test.ts
index 8313e64c..1b52f7bf 100644
--- a/test/options.retry.test.ts
+++ b/test/options.retry.test.ts
@@ -1,9 +1,9 @@
import { strict as assert } from 'node:assert';
import { createWriteStream, createReadStream } from 'node:fs';
import { describe, it, beforeAll, afterAll, beforeEach, afterEach } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
-import { readableToString, createTempfile } from './utils';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
+import { readableToString, createTempfile } from './utils.js';
describe('options.retry.test.ts', () => {
let close: any;
diff --git a/test/options.signal.test.ts b/test/options.signal.test.ts
index 3f2d4b85..6c67a8f1 100644
--- a/test/options.signal.test.ts
+++ b/test/options.signal.test.ts
@@ -1,9 +1,9 @@
import { strict as assert } from 'node:assert';
import { EventEmitter } from 'node:events';
+import { setTimeout as sleep } from 'node:timers/promises';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
-import { sleep } from './utils';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.signal.test.ts', () => {
let close: any;
@@ -18,7 +18,7 @@ describe('options.signal.test.ts', () => {
await close();
});
- it.skipIf(typeof global.AbortController === 'undefined')('should throw error when AbortController abort', async () => {
+ it('should throw error when AbortController abort', async () => {
await assert.rejects(async () => {
const abortController = new AbortController();
const p = urllib.request(`${_url}?timeout=2000`, {
@@ -28,10 +28,9 @@ describe('options.signal.test.ts', () => {
abortController.abort();
await p;
}, (err: any) => {
- // console.error(err);
assert.equal(err.name, 'AbortError');
- assert.equal(err.message, 'Request aborted');
- assert.equal(err.code, 'UND_ERR_ABORTED');
+ assert.equal(err.message, 'This operation was aborted');
+ assert.equal(err.code, 20);
return true;
});
});
diff --git a/test/options.socketErrorRetry.test.ts b/test/options.socketErrorRetry.test.ts
index 1006241d..5831785c 100644
--- a/test/options.socketErrorRetry.test.ts
+++ b/test/options.socketErrorRetry.test.ts
@@ -1,9 +1,9 @@
import { strict as assert } from 'node:assert';
import { createWriteStream, createReadStream } from 'node:fs';
import { describe, it, beforeAll, afterAll, beforeEach, afterEach } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
-import { createTempfile } from './utils';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
+import { createTempfile } from './utils.js';
describe('options.socketErrorRetry.test.ts', () => {
let close: any;
diff --git a/test/options.socketPath.test.ts b/test/options.socketPath.test.ts
index c696222a..fc6bcf3c 100644
--- a/test/options.socketPath.test.ts
+++ b/test/options.socketPath.test.ts
@@ -1,8 +1,8 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/socket_server';
-import { isWindows } from './utils';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/socket_server.js';
+import { isWindows } from './utils.js';
describe.skipIf(isWindows())('options.socketPath.test.ts', () => {
let close: any;
diff --git a/test/options.stream.test.ts b/test/options.stream.test.ts
index 17a5f681..2c905488 100644
--- a/test/options.stream.test.ts
+++ b/test/options.stream.test.ts
@@ -7,10 +7,10 @@ import { Readable } from 'node:stream';
import { describe, it, beforeAll, afterAll, beforeEach, afterEach } from 'vitest';
import tar from 'tar-stream';
import FormStream from 'formstream';
-import urllib from '../src';
-import { isReadable } from '../src/utils';
-import { startServer } from './fixtures/server';
-import { createTempfile } from './utils';
+import urllib from '../src/index.js';
+import { isReadable } from '../src/utils.js';
+import { startServer } from './fixtures/server.js';
+import { createTempfile } from './utils.js';
describe('options.stream.test.ts', () => {
let close: any;
diff --git a/test/options.streaming.test.ts b/test/options.streaming.test.ts
index a98f998a..f0e97dac 100644
--- a/test/options.streaming.test.ts
+++ b/test/options.streaming.test.ts
@@ -2,10 +2,10 @@ import { strict as assert } from 'node:assert';
import { pipeline } from 'node:stream';
import { createBrotliDecompress } from 'node:zlib';
import { describe, it, beforeEach, afterEach } from 'vitest';
-import urllib from '../src';
-import { isReadable } from '../src/utils';
-import { startServer } from './fixtures/server';
-import { readableToBytes } from './utils';
+import urllib from '../src/index.js';
+import { isReadable } from '../src/utils.js';
+import { startServer } from './fixtures/server.js';
+import { readableToBytes } from './utils.js';
describe('options.streaming.test.ts', () => {
let close: any;
diff --git a/test/options.timeout.test.ts b/test/options.timeout.test.ts
index d5e9d521..b065096b 100644
--- a/test/options.timeout.test.ts
+++ b/test/options.timeout.test.ts
@@ -1,7 +1,7 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib, { HttpClientRequestTimeoutError } from '../src';
-import { startServer } from './fixtures/server';
+import urllib, { HttpClientRequestTimeoutError } from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.timeout.test.ts', () => {
let close: any;
@@ -25,12 +25,9 @@ describe('options.timeout.test.ts', () => {
// console.error(err);
assert.equal(err.name, 'HttpClientRequestTimeoutError');
assert.equal(err.message, 'Request timeout for 10 ms');
- if (err.cause) {
- // not work on Node.js 14
- assert.equal(err.cause.name, 'HeadersTimeoutError');
- assert.equal(err.cause.message, 'Headers Timeout Error');
- assert.equal(err.cause.code, 'UND_ERR_HEADERS_TIMEOUT');
- }
+ assert.equal(err.cause.name, 'HeadersTimeoutError');
+ assert.equal(err.cause.message, 'Headers Timeout Error');
+ assert.equal(err.cause.code, 'UND_ERR_HEADERS_TIMEOUT');
assert.equal(err.res.status, -1);
assert(err.res.rt > 10, `actual ${err.res.rt}`);
diff --git a/test/options.timing.test.ts b/test/options.timing.test.ts
index c6d2ca41..680686c2 100644
--- a/test/options.timing.test.ts
+++ b/test/options.timing.test.ts
@@ -1,9 +1,8 @@
import { strict as assert } from 'node:assert';
+import { setTimeout as sleep } from 'node:timers/promises';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { RawResponseWithMeta } from '../src/Response';
-import { startServer } from './fixtures/server';
-import { sleep } from './utils';
+import urllib, { RawResponseWithMeta } from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.timing.test.ts', () => {
let close: any;
diff --git a/test/options.type.test.ts b/test/options.type.test.ts
index 91ffaabc..7bbf3049 100644
--- a/test/options.type.test.ts
+++ b/test/options.type.test.ts
@@ -1,7 +1,7 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('options.type.test.ts', () => {
let close: any;
diff --git a/test/options.writeStream.test.ts b/test/options.writeStream.test.ts
index 42cbfc20..bc17e41d 100644
--- a/test/options.writeStream.test.ts
+++ b/test/options.writeStream.test.ts
@@ -3,10 +3,11 @@ import { createWriteStream } from 'node:fs';
import { join } from 'node:path';
import { gunzipSync } from 'node:zlib';
import { stat, readFile } from 'node:fs/promises';
+import { setTimeout as sleep } from 'node:timers/promises';
import { describe, it, beforeAll, afterAll, beforeEach, afterEach } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
-import { createTempfile, sleep } from './utils';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
+import { createTempfile } from './utils.js';
describe('options.writeStream.test.ts', () => {
let close: any;
diff --git a/test/response-charset-gbk.test.ts b/test/response-charset-gbk.test.ts
index c6735da1..3c929754 100644
--- a/test/response-charset-gbk.test.ts
+++ b/test/response-charset-gbk.test.ts
@@ -1,7 +1,7 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('response-charset-gbk.test.ts', () => {
let close: any;
diff --git a/test/user-agent.test.ts b/test/user-agent.test.ts
index 61e489dd..3d869e0b 100644
--- a/test/user-agent.test.ts
+++ b/test/user-agent.test.ts
@@ -1,7 +1,7 @@
import { strict as assert } from 'node:assert';
import { describe, it, beforeAll, afterAll } from 'vitest';
-import urllib from '../src';
-import { startServer } from './fixtures/server';
+import urllib from '../src/index.js';
+import { startServer } from './fixtures/server.js';
describe('keep-alive-header.test.ts', () => {
let close: any;
diff --git a/test/utils.test.ts b/test/utils.test.ts
index 92ba28a6..8d7f7ec0 100644
--- a/test/utils.test.ts
+++ b/test/utils.test.ts
@@ -1,6 +1,6 @@
import { strict as assert } from 'node:assert';
import { describe, it } from 'vitest';
-import { globalId } from '../src/utils';
+import { globalId } from '../src/utils.js';
describe('utils.test.ts', () => {
describe('globalId()', () => {
diff --git a/test/utils.ts b/test/utils.ts
index 61f36657..e3ff1044 100644
--- a/test/utils.ts
+++ b/test/utils.ts
@@ -5,12 +5,6 @@ import { join } from 'node:path';
import { tmpdir, platform } from 'node:os';
import { randomUUID } from 'node:crypto';
-export async function sleep(ms: number) {
- await new Promise(resolve => {
- setTimeout(resolve, ms);
- });
-}
-
export async function readableToBytes(stream: Readable | ReadableStream) {
const chunks: Buffer[] = [];
let chunk: Buffer;
diff --git a/tsconfig.eslint.json b/tsconfig.eslint.json
deleted file mode 100644
index 91644d12..00000000
--- a/tsconfig.eslint.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "extends": "./tsconfig.json",
- "include": [
- "src/**/*.ts",
- "test/**/*.ts"
- ]
-}
diff --git a/tsconfig.json b/tsconfig.json
index 241f0504..ff41b734 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,35 +1,10 @@
{
+ "extends": "@eggjs/tsconfig",
"compilerOptions": {
- "useUnknownInCatchVariables": true,
- "allowSyntheticDefaultImports": true,
- "declaration": true,
- "downlevelIteration": true,
- "emitDecoratorMetadata": true,
- "experimentalDecorators": true,
- "importHelpers": false,
- "module": "NodeNext",
- "moduleResolution": "NodeNext",
- "newLine": "LF",
- "checkJs": false,
- "allowJs": true,
"strict": true,
- "skipLibCheck": true,
- "noImplicitAny": false,
- "forceConsistentCasingInFileNames": true,
+ "noImplicitAny": true,
"target": "ES2022",
- "sourceMap": false,
- "esModuleInterop": true,
- "stripInternal": true,
- "lib": [
- "ES2022"
- ],
- "composite": true,
- "types": [
- "node"
- ],
- "rootDir": "src"
- },
- "include": [
- "src/**/*.ts"
- ]
+ "module": "NodeNext",
+ "moduleResolution": "NodeNext"
+ }
}