From e9681012e4ce22dbc99f2a9747433a4893c3352a Mon Sep 17 00:00:00 2001 From: Yurii Bliuchak <1957659+bliuchak@users.noreply.github.com> Date: Tue, 13 Jan 2026 23:09:10 +0100 Subject: [PATCH] feat: migrate from CJS to ESM --- ...eta-release.js => before-beta-release.cjs} | 0 .github/workflows/release.yaml | 2 +- .mocharc.json | 1 - README.md | 36 ++--- examples/apify_proxy_tunnel.js | 2 +- package.json | 7 + src/anonymize_proxy.ts | 4 +- src/chain.ts | 10 +- src/chain_socks.ts | 6 +- src/direct.ts | 4 +- src/forward.ts | 10 +- src/forward_socks.ts | 6 +- src/index.ts | 12 +- src/server.ts | 36 ++--- src/tcp_tunnel_tools.ts | 4 +- src/utils/get_basic.ts | 2 +- src/utils/valid_headers_only.ts | 2 +- test/anonymize_proxy.js | 24 ++-- test/anonymize_proxy_no_password.js | 22 +-- test/ee-memory-leak.js | 8 +- test/http-agent.js | 25 ++-- test/https-server.js | 15 +- test/https-stress-test.js | 21 +-- test/server.js | 134 +++++++++--------- test/socks.js | 10 +- test/tcp_tunnel.js | 12 +- test/tools.js | 10 +- test/utils/run_locally.js | 6 +- test/utils/target_server.js | 20 +-- test/utils/testing_tcp_service.js | 2 +- test/utils/throws_async.js | 4 +- tsconfig.json | 15 +- 32 files changed, 246 insertions(+), 226 deletions(-) rename .github/scripts/{before-beta-release.js => before-beta-release.cjs} (100%) diff --git a/.github/scripts/before-beta-release.js b/.github/scripts/before-beta-release.cjs similarity index 100% rename from .github/scripts/before-beta-release.js rename to .github/scripts/before-beta-release.cjs diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index c86c2615..46046219 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -44,7 +44,7 @@ jobs: # Check version consistency and increment pre-release version number for beta only. - name: Bump pre-release version if: steps.get_release_tag.outputs.release_tag == 'beta' - run: node ./.github/scripts/before-beta-release.js + run: node ./.github/scripts/before-beta-release.cjs - name: Publish to NPM run: npm publish --tag ${{ steps.get_release_tag.outputs.release_tag }} diff --git a/.mocharc.json b/.mocharc.json index d22cea1b..2c63c085 100644 --- a/.mocharc.json +++ b/.mocharc.json @@ -1,3 +1,2 @@ { - "require": "ts-node/register" } diff --git a/README.md b/README.md index cb682c1b..1696d544 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ The proxy-chain package currently supports HTTP/SOCKS forwarding and HTTP CONNEC ## Run a simple HTTP/HTTPS proxy server ```javascript -const ProxyChain = require('proxy-chain'); +import ProxyChain from 'proxy-chain'; const server = new ProxyChain.Server({ port: 8000 }); @@ -33,7 +33,7 @@ server.listen(() => { ## Run a HTTP/HTTPS proxy server with credentials and upstream proxy ```javascript -const ProxyChain = require('proxy-chain'); +import ProxyChain from 'proxy-chain'; const server = new ProxyChain.Server({ // Port where the server will listen. By default 8000. @@ -115,9 +115,12 @@ server.on('requestFailed', ({ request, error }) => { This example demonstrates how to create an HTTPS proxy server with a self-signed certificate. The HTTPS proxy server works identically to the HTTP version but with TLS encryption. ```javascript -const fs = require('fs'); -const path = require('path'); -const ProxyChain = require('proxy-chain'); +import ProxyChain from 'proxy-chain'; +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); (async () => { // TODO: update these lines to use your own key and cert @@ -208,9 +211,9 @@ curl --proxy-insecure -x https://localhost:8443 -k https://example.com You can provide custom HTTP/HTTPS agents to enable connection pooling and reuse with upstream proxies. This is particularly useful for maintaining sticky IP addresses or reducing connection overhead: ```javascript -const http = require('http'); -const https = require('https'); -const ProxyChain = require('proxy-chain'); +import http from 'node:http'; +import https from 'node:https'; +import ProxyChain from 'proxy-chain'; // Create agents with keepAlive to enable connection pooling const httpAgent = new http.Agent({ @@ -309,7 +312,7 @@ The class constructor has the following parameters: `RequestError(body, statusCo By default, the response will have `Content-Type: text/plain; charset=utf-8`. ```javascript -const ProxyChain = require('proxy-chain'); +import ProxyChain from 'proxy-chain'; const server = new ProxyChain.Server({ prepareRequestFunction: ({ request, username, password, hostname, port, isHttp, connectionId }) => { @@ -379,7 +382,7 @@ with the following properties: Here is a simple example: ```javascript -const ProxyChain = require('proxy-chain'); +import ProxyChain from 'proxy-chain'; const server = new ProxyChain.Server({ port: 8000, @@ -406,8 +409,8 @@ While `customResponseFunction` enables custom handling methods such as `GET` and It's possible to route those requests differently using the `customConnectServer` option. It accepts an instance of Node.js HTTP server. ```javascript -const http = require('http'); -const ProxyChain = require('proxy-chain'); +import http from 'node:http'; +import ProxyChain from 'proxy-chain'; const exampleServer = http.createServer((request, response) => { response.end('Hello from a custom server!'); @@ -437,8 +440,9 @@ This is an unsecure server, so it accepts only `http:` requests. In order to intercept `https:` requests, `https.createServer` should be used instead, along with a self signed certificate. ```javascript -const https = require('https'); -const fs = require('fs'); +import https from 'node:https'; +import fs from 'node:fs'; + const key = fs.readFileSync('./test/ssl.key'); const cert = fs.readFileSync('./test/ssl.crt'); @@ -522,8 +526,8 @@ from headless Chrome and [Puppeteer](https://github.com/GoogleChrome/puppeteer). For details, read this [blog post](https://blog.apify.com/how-to-make-headless-chrome-and-puppeteer-use-a-proxy-server-with-authentication-249a21a79212). ```javascript -const puppeteer = require('puppeteer'); -const proxyChain = require('proxy-chain'); +import puppeteer from 'puppeteer'; +import proxyChain from 'proxy-chain'; (async() => { const oldProxyUrl = 'http://bob:password123@proxy.example.com:8000'; diff --git a/examples/apify_proxy_tunnel.js b/examples/apify_proxy_tunnel.js index f06556ae..b5bbf870 100644 --- a/examples/apify_proxy_tunnel.js +++ b/examples/apify_proxy_tunnel.js @@ -1,4 +1,4 @@ -const { createTunnel, closeTunnel, redactUrl } = require('proxy-chain'); +import { closeTunnel, createTunnel, redactUrl } from 'proxy-chain'; // This example demonstrates how to create a tunnel via Apify's HTTP proxy service. // For details, see https://blog.apify.com/tunneling-arbitrary-protocols-over-http-proxy-with-static-ip-address-b3a2222191ff diff --git a/package.json b/package.json index cac6b1d5..7b5d48d1 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,13 @@ "version": "2.7.0", "description": "Node.js implementation of a proxy server (think Squid) with support for SSL, authentication, upstream proxy chaining, and protocol tunneling.", "main": "dist/index.js", + "type": "module", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, "keywords": [ "proxy", "squid", diff --git a/src/anonymize_proxy.ts b/src/anonymize_proxy.ts index 9b7cbd8e..243c3c40 100644 --- a/src/anonymize_proxy.ts +++ b/src/anonymize_proxy.ts @@ -3,8 +3,8 @@ import type http from 'node:http'; import type net from 'node:net'; import { URL } from 'node:url'; -import { Server, SOCKS_PROTOCOLS } from './server'; -import { nodeify } from './utils/nodeify'; +import { Server, SOCKS_PROTOCOLS } from './server.js'; +import { nodeify } from './utils/nodeify.js'; // Dictionary, key is value returned from anonymizeProxy(), value is Server instance. const anonymizedProxyUrlToServer: Record = {}; diff --git a/src/chain.ts b/src/chain.ts index 1cf64b58..5e02bfd0 100644 --- a/src/chain.ts +++ b/src/chain.ts @@ -5,11 +5,11 @@ import http from 'node:http'; import https from 'node:https'; import type { URL } from 'node:url'; -import type { Socket } from './socket'; -import { badGatewayStatusCodes, createCustomStatusHttpResponse, errorCodeToStatusCode } from './statuses'; -import type { SocketWithPreviousStats } from './utils/count_target_bytes'; -import { countTargetBytes } from './utils/count_target_bytes'; -import { getBasicAuthorizationHeader } from './utils/get_basic'; +import type { Socket } from './socket.js'; +import { badGatewayStatusCodes, createCustomStatusHttpResponse, errorCodeToStatusCode } from './statuses.js'; +import type { SocketWithPreviousStats } from './utils/count_target_bytes.js'; +import { countTargetBytes } from './utils/count_target_bytes.js'; +import { getBasicAuthorizationHeader } from './utils/get_basic.js'; interface Options { method: string; diff --git a/src/chain_socks.ts b/src/chain_socks.ts index 1b03c70c..2b874835 100644 --- a/src/chain_socks.ts +++ b/src/chain_socks.ts @@ -6,9 +6,9 @@ import { URL } from 'node:url'; import { SocksClient, type SocksClientError, type SocksProxy } from 'socks'; -import type { Socket } from './socket'; -import { createCustomStatusHttpResponse, socksErrorMessageToStatusCode } from './statuses'; -import { countTargetBytes } from './utils/count_target_bytes'; +import type { Socket } from './socket.js'; +import { createCustomStatusHttpResponse, socksErrorMessageToStatusCode } from './statuses.js'; +import { countTargetBytes } from './utils/count_target_bytes.js'; export interface HandlerOpts { upstreamProxyUrlParsed: URL; diff --git a/src/direct.ts b/src/direct.ts index f4c7d68d..b81335dd 100644 --- a/src/direct.ts +++ b/src/direct.ts @@ -4,8 +4,8 @@ import type { EventEmitter } from 'node:events'; import net from 'node:net'; import { URL } from 'node:url'; -import type { Socket } from './socket'; -import { countTargetBytes } from './utils/count_target_bytes'; +import type { Socket } from './socket.js'; +import { countTargetBytes } from './utils/count_target_bytes.js'; export interface HandlerOpts { localAddress?: string; diff --git a/src/forward.ts b/src/forward.ts index 2c9b6ab9..1292b04c 100644 --- a/src/forward.ts +++ b/src/forward.ts @@ -5,11 +5,11 @@ import stream from 'node:stream'; import type { URL } from 'node:url'; import util from 'node:util'; -import { badGatewayStatusCodes, errorCodeToStatusCode } from './statuses'; -import type { SocketWithPreviousStats } from './utils/count_target_bytes'; -import { countTargetBytes } from './utils/count_target_bytes'; -import { getBasicAuthorizationHeader } from './utils/get_basic'; -import { validHeadersOnly } from './utils/valid_headers_only'; +import { badGatewayStatusCodes, errorCodeToStatusCode } from './statuses.js'; +import type { SocketWithPreviousStats } from './utils/count_target_bytes.js'; +import { countTargetBytes } from './utils/count_target_bytes.js'; +import { getBasicAuthorizationHeader } from './utils/get_basic.js'; +import { validHeadersOnly } from './utils/valid_headers_only.js'; const pipeline = util.promisify(stream.pipeline); diff --git a/src/forward_socks.ts b/src/forward_socks.ts index 95867586..71f9a74b 100644 --- a/src/forward_socks.ts +++ b/src/forward_socks.ts @@ -5,9 +5,9 @@ import util from 'node:util'; import { SocksProxyAgent } from 'socks-proxy-agent'; -import { badGatewayStatusCodes, errorCodeToStatusCode } from './statuses'; -import { countTargetBytes } from './utils/count_target_bytes'; -import { validHeadersOnly } from './utils/valid_headers_only'; +import { badGatewayStatusCodes, errorCodeToStatusCode } from './statuses.js'; +import { countTargetBytes } from './utils/count_target_bytes.js'; +import { validHeadersOnly } from './utils/valid_headers_only.js'; const pipeline = util.promisify(stream.pipeline); diff --git a/src/index.ts b/src/index.ts index f945ef87..f03c370f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,7 @@ -export * from './request_error'; -export * from './server'; -export * from './utils/redact_url'; -export * from './anonymize_proxy'; -export * from './tcp_tunnel_tools'; +export * from './request_error.js'; +export * from './server.js'; +export * from './utils/redact_url.js'; +export * from './anonymize_proxy.js'; +export * from './tcp_tunnel_tools.js'; -export { CustomResponse } from './custom_response'; +export { CustomResponse } from './custom_response.js'; diff --git a/src/server.ts b/src/server.ts index 6295c724..d241b9d8 100644 --- a/src/server.ts +++ b/src/server.ts @@ -8,24 +8,24 @@ import type net from 'node:net'; import { URL } from 'node:url'; import util from 'node:util'; -import type { HandlerOpts as ChainOpts } from './chain'; -import { chain } from './chain'; -import { chainSocks } from './chain_socks'; -import { customConnect } from './custom_connect'; -import type { HandlerOpts as CustomResponseOpts } from './custom_response'; -import { handleCustomResponse } from './custom_response'; -import { direct } from './direct'; -import type { HandlerOpts as ForwardOpts } from './forward'; -import { forward } from './forward'; -import { forwardSocks } from './forward_socks'; -import { RequestError } from './request_error'; -import type { Socket, TLSSocket } from './socket'; -import { badGatewayStatusCodes } from './statuses'; -import { getTargetStats } from './utils/count_target_bytes'; -import { nodeify } from './utils/nodeify'; -import { normalizeUrlPort } from './utils/normalize_url_port'; -import { parseAuthorizationHeader } from './utils/parse_authorization_header'; -import { redactUrl } from './utils/redact_url'; +import type { HandlerOpts as ChainOpts } from './chain.js'; +import { chain } from './chain.js'; +import { chainSocks } from './chain_socks.js'; +import { customConnect } from './custom_connect.js'; +import type { HandlerOpts as CustomResponseOpts } from './custom_response.js'; +import { handleCustomResponse } from './custom_response.js'; +import { direct } from './direct.js'; +import type { HandlerOpts as ForwardOpts } from './forward.js'; +import { forward } from './forward.js'; +import { forwardSocks } from './forward_socks.js'; +import { RequestError } from './request_error.js'; +import type { Socket, TLSSocket } from './socket.js'; +import { badGatewayStatusCodes } from './statuses.js'; +import { getTargetStats } from './utils/count_target_bytes.js'; +import { nodeify } from './utils/nodeify.js'; +import { normalizeUrlPort } from './utils/normalize_url_port.js'; +import { parseAuthorizationHeader } from './utils/parse_authorization_header.js'; +import { redactUrl } from './utils/redact_url.js'; export const SOCKS_PROTOCOLS = ['socks:', 'socks4:', 'socks4a:', 'socks5:', 'socks5h:']; diff --git a/src/tcp_tunnel_tools.ts b/src/tcp_tunnel_tools.ts index c2cb9ff0..1e2cc566 100644 --- a/src/tcp_tunnel_tools.ts +++ b/src/tcp_tunnel_tools.ts @@ -1,8 +1,8 @@ import net from 'node:net'; import { URL } from 'node:url'; -import { chain } from './chain'; -import { nodeify } from './utils/nodeify'; +import { chain } from './chain.js'; +import { nodeify } from './utils/nodeify.js'; const runningServers: Record }> = {}; diff --git a/src/utils/get_basic.ts b/src/utils/get_basic.ts index 6ccbf608..d5e94dab 100644 --- a/src/utils/get_basic.ts +++ b/src/utils/get_basic.ts @@ -1,6 +1,6 @@ import type { URL } from 'node:url'; -import { decodeURIComponentSafe } from './decode_uri_component_safe'; +import { decodeURIComponentSafe } from './decode_uri_component_safe.js'; export const getBasicAuthorizationHeader = (url: URL): string => { const username = decodeURIComponentSafe(url.username); diff --git a/src/utils/valid_headers_only.ts b/src/utils/valid_headers_only.ts index 936851f6..a5f6b4f6 100644 --- a/src/utils/valid_headers_only.ts +++ b/src/utils/valid_headers_only.ts @@ -1,6 +1,6 @@ import { validateHeaderName, validateHeaderValue } from 'node:http'; -import { isHopByHopHeader } from './is_hop_by_hop_header'; +import { isHopByHopHeader } from './is_hop_by_hop_header.js'; /** * @see https://nodejs.org/api/http.html#http_message_rawheaders diff --git a/test/anonymize_proxy.js b/test/anonymize_proxy.js index 82da37a5..e0c1b87f 100644 --- a/test/anonymize_proxy.js +++ b/test/anonymize_proxy.js @@ -1,15 +1,15 @@ -const _ = require('underscore'); -const util = require('util'); -const { expect, assert } = require('chai'); -const proxy = require('proxy'); -const http = require('http'); -const portastic = require('portastic'); -const basicAuthParser = require('basic-auth-parser'); -const request = require('request'); -const express = require('express'); - -const { anonymizeProxy, closeAnonymizedProxy, listenConnectAnonymizedProxy } = require('../src/index'); -const { expectThrowsAsync } = require('./utils/throws_async'); +import _ from 'underscore'; +import util from 'node:util'; +import { expect, assert } from 'chai'; +import proxy from 'proxy'; +import http from 'node:http'; +import portastic from 'portastic'; +import basicAuthParser from 'basic-auth-parser'; +import request from 'request'; +import express from 'express'; + +import { anonymizeProxy, closeAnonymizedProxy, listenConnectAnonymizedProxy } from '../dist/index.js'; +import { expectThrowsAsync } from './utils/throws_async.js'; let expressServer; let proxyServer; diff --git a/test/anonymize_proxy_no_password.js b/test/anonymize_proxy_no_password.js index d7406ba9..d9d846f0 100644 --- a/test/anonymize_proxy_no_password.js +++ b/test/anonymize_proxy_no_password.js @@ -1,14 +1,14 @@ -const _ = require('underscore'); -const { expect, assert } = require('chai'); -const proxy = require('proxy'); -const http = require('http'); -const util = require('util'); -const portastic = require('portastic'); -const basicAuthParser = require('basic-auth-parser'); -const request = require('request'); -const express = require('express'); - -const { anonymizeProxy, closeAnonymizedProxy } = require('../src/index'); +import _ from 'underscore'; +import { expect, assert } from 'chai'; +import proxy from 'proxy'; +import http from 'node:http'; +import util from 'node:util'; +import portastic from 'portastic'; +import basicAuthParser from 'basic-auth-parser'; +import request from 'request'; +import express from 'express'; + +import { anonymizeProxy, closeAnonymizedProxy } from '../dist/index.js'; let expressServer; let proxyServer; diff --git a/test/ee-memory-leak.js b/test/ee-memory-leak.js index e92d1ca0..d0b71cb8 100644 --- a/test/ee-memory-leak.js +++ b/test/ee-memory-leak.js @@ -1,7 +1,7 @@ -const net = require('net'); -const http = require('http'); -const { assert } = require('chai'); -const ProxyChain = require('../src/index'); +import net from 'node:net'; +import http from 'node:http'; +import { assert } from 'chai'; +import * as ProxyChain from '../dist/index.js'; describe('ProxyChain server', () => { let proxyServer; diff --git a/test/http-agent.js b/test/http-agent.js index d4368f37..1d783627 100644 --- a/test/http-agent.js +++ b/test/http-agent.js @@ -1,14 +1,17 @@ -const fs = require('fs'); -const path = require('path'); -const http = require('http'); -const https = require('https'); -const { expect } = require('chai'); -const portastic = require('portastic'); -const proxy = require('proxy'); -const request = require('request'); - -const { Server } = require('../src/index'); -const { TargetServer } = require('./utils/target_server'); +import fs from 'node:fs'; +import path from 'node:path'; +import http from 'node:http'; +import https from 'node:https'; +import { fileURLToPath } from 'node:url'; +import { expect } from 'chai'; +import portastic from 'portastic'; +import proxy from 'proxy'; +import request from 'request'; + +import { Server } from '../dist/index.js'; +import { TargetServer } from './utils/target_server.js'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const sslKey = fs.readFileSync(path.join(__dirname, 'ssl.key')); const sslCrt = fs.readFileSync(path.join(__dirname, 'ssl.crt')); diff --git a/test/https-server.js b/test/https-server.js index d38c2e30..75e69bd9 100644 --- a/test/https-server.js +++ b/test/https-server.js @@ -1,9 +1,12 @@ -const fs = require('fs'); -const path = require('path'); -const tls = require('tls'); -const { expect } = require('chai'); -const http = require('http'); -const { Server } = require('../src/index'); +import fs from 'node:fs'; +import path from 'node:path'; +import tls from 'node:tls'; +import { fileURLToPath } from 'node:url'; +import { expect } from 'chai'; +import http from 'node:http'; +import { Server } from '../dist/index.js'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); const sslKey = fs.readFileSync(path.join(__dirname, 'ssl.key')); const sslCrt = fs.readFileSync(path.join(__dirname, 'ssl.crt')); diff --git a/test/https-stress-test.js b/test/https-stress-test.js index a63d7660..ac3b4650 100644 --- a/test/https-stress-test.js +++ b/test/https-stress-test.js @@ -1,12 +1,15 @@ -const fs = require('fs'); -const http = require('http'); -const path = require('path'); -const tls = require('tls'); -const util = require('util'); -const request = require('request'); -const { expect } = require('chai'); -const { Server } = require('../src/index'); -const { TargetServer } = require('./utils/target_server'); +import fs from 'node:fs'; +import http from 'node:http'; +import path from 'node:path'; +import tls from 'node:tls'; +import util from 'node:util'; +import { fileURLToPath } from 'node:url'; +import request from 'request'; +import { expect } from 'chai'; +import { Server } from '../dist/index.js'; +import { TargetServer } from './utils/target_server.js'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); // Node.js 20+ enables HTTP keep-alive by default in the global agent, // which causes connection tracking issues in tests. Disable it. diff --git a/test/server.js b/test/server.js index c4c02e50..310f8466 100644 --- a/test/server.js +++ b/test/server.js @@ -1,25 +1,28 @@ -const fs = require('fs'); -const zlib = require('zlib'); -const path = require('path'); -const stream = require('stream'); -const childProcess = require('child_process'); -const tls = require('tls'); -const net = require('net'); -const dns = require('dns'); -const util = require('util'); -const { expect, assert } = require('chai'); -const proxy = require('proxy'); -const http = require('http'); -const https = require('https'); -const portastic = require('portastic'); -const request = require('request'); -const WebSocket = require('faye-websocket'); -const { gotScraping } = require('got-scraping'); - -const { parseAuthorizationHeader } = require('../src/utils/parse_authorization_header'); -const { Server, RequestError } = require('../src/index'); -const { TargetServer } = require('./utils/target_server'); -const ProxyChain = require('../src/index'); +import fs from 'node:fs'; +import zlib from 'node:zlib'; +import path from 'node:path'; +import stream from 'node:stream'; +import childProcess from 'node:child_process'; +import tls from 'node:tls'; +import net from 'node:net'; +import dns from 'node:dns'; +import util from 'node:util'; +import { fileURLToPath } from 'node:url'; +import { expect, assert } from 'chai'; +import proxy from 'proxy'; +import http from 'node:http'; +import https from 'node:https'; +import portastic from 'portastic'; +import request from 'request'; +import WebSocket from 'faye-websocket'; +import { gotScraping } from 'got-scraping'; + +import { parseAuthorizationHeader } from '../dist/utils/parse_authorization_header.js'; +import { Server, RequestError } from '../dist/index.js'; +import { TargetServer } from './utils/target_server.js'; +import * as ProxyChain from '../dist/index.js'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); /* TODO - add following tests: @@ -69,58 +72,55 @@ const requestPromised = (opts) => { const wait = (timeout) => new Promise((resolve) => setTimeout(resolve, timeout)); // Opens web page in puppeteer and returns the HTML content -const puppeteerGet = (url, proxyUrl) => { - // eslint-disable-next-line global-require - const puppeteer = require('puppeteer'); - - return (async () => { - const parsed = proxyUrl ? new URL(proxyUrl) : undefined; - - const args = [ - '--no-sandbox', - '--disable-setuid-sandbox', - '--disable-dev-shm-usage' - ]; - - const launchOpts = { - ignoreHTTPSErrors: true, - headless: 'new', - args - }; +const puppeteerGet = async (url, proxyUrl) => { + const { default: puppeteer } = await import('puppeteer'); - if (parsed) { - if (parsed.protocol === 'https:') { - args.push(`--proxy-server=${parsed.origin}`); - // For HTTPS proxies with self-signed certificates, - // ignore certificate errors on the proxy connection itself. - args.push('--ignore-certificate-errors'); - } else { - launchOpts.env = { - HTTP_PROXY: parsed.origin, - }; - } - } + const parsed = proxyUrl ? new URL(proxyUrl) : undefined; - const browser = await puppeteer.launch(launchOpts); + const args = [ + '--no-sandbox', + '--disable-setuid-sandbox', + '--disable-dev-shm-usage' + ]; - try { - const page = await browser.newPage(); + const launchOpts = { + ignoreHTTPSErrors: true, + headless: 'new', + args + }; - if (parsed) { - await page.authenticate({ - username: decodeURIComponent(parsed.username), - password: decodeURIComponent(parsed.password), - }); - } + if (parsed) { + if (parsed.protocol === 'https:') { + args.push(`--proxy-server=${parsed.origin}`); + // For HTTPS proxies with self-signed certificates, + // ignore certificate errors on the proxy connection itself. + args.push('--ignore-certificate-errors'); + } else { + launchOpts.env = { + HTTP_PROXY: parsed.origin, + }; + } + } - const response = await page.goto(url); - const text = await response.text(); + const browser = await puppeteer.launch(launchOpts); - return text; - } finally { - await browser.close(); + try { + const page = await browser.newPage(); + + if (parsed) { + await page.authenticate({ + username: decodeURIComponent(parsed.username), + password: decodeURIComponent(parsed.password), + }); } - })(); + + const response = await page.goto(url); + const text = await response.text(); + + return text; + } finally { + await browser.close(); + } }; // Opens web page in curl and returns the HTML content. diff --git a/test/socks.js b/test/socks.js index 2a9e8dc8..dcbd6479 100644 --- a/test/socks.js +++ b/test/socks.js @@ -1,8 +1,8 @@ -const portastic = require('portastic'); -const socksv5 = require('socksv5'); -const { gotScraping } = require('got-scraping'); -const { expect } = require('chai'); -const ProxyChain = require('../src/index'); +import portastic from 'portastic'; +import socksv5 from 'socksv5'; +import { gotScraping } from 'got-scraping'; +import { expect } from 'chai'; +import * as ProxyChain from '../dist/index.js'; describe('SOCKS protocol', () => { let socksServer; diff --git a/test/tcp_tunnel.js b/test/tcp_tunnel.js index 1b9705b4..8b83c0da 100644 --- a/test/tcp_tunnel.js +++ b/test/tcp_tunnel.js @@ -1,10 +1,10 @@ -const net = require('net'); -const { expect, assert } = require('chai'); -const http = require('http'); -const proxy = require('proxy'); +import net from 'node:net'; +import { expect, assert } from 'chai'; +import http from 'node:http'; +import proxy from 'proxy'; -const { createTunnel, closeTunnel } = require('../src/index'); -const { expectThrowsAsync } = require('./utils/throws_async'); +import { createTunnel, closeTunnel } from '../dist/index.js'; +import { expectThrowsAsync } from './utils/throws_async.js'; const destroySocket = (socket) => new Promise((resolve, reject) => { if (!socket || socket.destroyed) return resolve(); diff --git a/test/tools.js b/test/tools.js index 8319453c..dc0021da 100644 --- a/test/tools.js +++ b/test/tools.js @@ -1,8 +1,8 @@ -const { expect } = require('chai'); -const { redactUrl } = require('../src/utils/redact_url'); -const { isHopByHopHeader } = require('../src/utils/is_hop_by_hop_header'); -const { parseAuthorizationHeader } = require('../src/utils/parse_authorization_header'); -const { nodeify } = require('../src/utils/nodeify'); +import { expect } from 'chai'; +import { redactUrl } from '../dist/utils/redact_url.js'; +import { isHopByHopHeader } from '../dist/utils/is_hop_by_hop_header.js'; +import { parseAuthorizationHeader } from '../dist/utils/parse_authorization_header.js'; +import { nodeify } from '../dist/utils/nodeify.js'; describe('tools.redactUrl()', () => { it('works', () => { diff --git a/test/utils/run_locally.js b/test/utils/run_locally.js index 17533224..b6fbd86a 100644 --- a/test/utils/run_locally.js +++ b/test/utils/run_locally.js @@ -9,9 +9,9 @@ * */ -const http = require('http'); -const proxy = require('proxy'); // eslint-disable-line import/no-extraneous-dependencies -const { Server } = require('../../src/server'); +import http from 'node:http'; +import proxy from 'proxy'; // eslint-disable-line import/no-extraneous-dependencies +import { Server } from '../../dist/index.js'; // Set up upstream proxy with no auth const upstreamProxyHttpServer = http.createServer(); diff --git a/test/utils/target_server.js b/test/utils/target_server.js index dbf9778c..946aad8e 100644 --- a/test/utils/target_server.js +++ b/test/utils/target_server.js @@ -1,11 +1,11 @@ -const http = require('http'); -const https = require('https'); -const util = require('util'); -const express = require('express'); -const bodyParser = require('body-parser'); -const WebSocket = require('ws'); -const basicAuth = require('basic-auth'); -const _ = require('underscore'); +import http from 'node:http'; +import https from 'node:https'; +import util from 'node:util'; +import express from 'express'; +import bodyParser from 'body-parser'; +import { WebSocketServer } from 'ws'; +import basicAuth from 'basic-auth'; +import _ from 'underscore'; /** * A HTTP server used for testing. It supports HTTPS and web sockets. @@ -47,7 +47,7 @@ class TargetServer { this.httpServer.keepAliveTimeout = 0; // Web socket server for upgraded HTTP connections - this.wsUpgServer = new WebSocket.Server({ server: this.httpServer }); + this.wsUpgServer = new WebSocketServer({ server: this.httpServer }); this.wsUpgServer.on('connection', this.onWsConnection.bind(this)); } @@ -193,4 +193,4 @@ class TargetServer { } } -exports.TargetServer = TargetServer; +export { TargetServer }; diff --git a/test/utils/testing_tcp_service.js b/test/utils/testing_tcp_service.js index 5db3431e..53cda5e6 100644 --- a/test/utils/testing_tcp_service.js +++ b/test/utils/testing_tcp_service.js @@ -1,4 +1,4 @@ -const net = require('net'); +import net from 'node:net'; // TODO: please move this into ./test dir diff --git a/test/utils/throws_async.js b/test/utils/throws_async.js index c7108924..407c3153 100644 --- a/test/utils/throws_async.js +++ b/test/utils/throws_async.js @@ -1,4 +1,4 @@ -const { expect } = require('chai'); +import { expect } from 'chai'; /** * Expect an async function to throw @@ -22,4 +22,4 @@ const expectThrowsAsync = async (func, errorMessage) => { } }; -exports.expectThrowsAsync = expectThrowsAsync; +export { expectThrowsAsync }; diff --git a/tsconfig.json b/tsconfig.json index 577dddbb..ab959c7c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,9 +1,10 @@ { - "extends": "@apify/tsconfig", - "compilerOptions": { - "outDir": "dist" - }, - "include": [ - "src" - ] + "extends": "@apify/tsconfig", + "compilerOptions": { + "outDir": "dist", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "target": "ES2022" + }, + "include": ["src"] }