pi-cursor-sdk 0.1.46 → 0.1.48
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/README.md +2 -2
- package/docs/cursor-live-smoke-checklist.md +4 -4
- package/docs/cursor-model-ux-spec.md +1 -1
- package/docs/cursor-native-tool-visual-audit.md +1 -1
- package/docs/cursor-testing-lessons.md +1 -1
- package/node_modules/@connectrpc/connect-node/README.md +141 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/compression.d.ts +15 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/compression.js +89 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/connect-node-adapter.d.ts +42 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/connect-node-adapter.js +61 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/connect-transport.d.ts +100 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/connect-transport.js +25 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/grpc-transport.d.ts +96 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/grpc-transport.js +25 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/grpc-web-transport.d.ts +96 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/grpc-web-transport.js +25 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/http2-session-manager.d.ts +146 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/http2-session-manager.js +536 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/index.d.ts +15 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/index.js +36 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/node-error.d.ts +45 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/node-error.js +154 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/node-headers-polyfill.d.ts +1 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/node-headers-polyfill.js +29 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/node-transport-options.d.ts +89 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/node-transport-options.js +58 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/node-universal-client.d.ts +54 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/node-universal-client.js +326 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/node-universal-handler.d.ts +41 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/node-universal-handler.js +234 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/node-universal-header.d.ts +19 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/node-universal-header.js +97 -0
- package/node_modules/@connectrpc/connect-node/dist/cjs/package.json +1 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/compression.d.ts +15 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/compression.js +86 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/connect-node-adapter.d.ts +42 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/connect-node-adapter.js +58 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/connect-transport.d.ts +100 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/connect-transport.js +22 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/grpc-transport.d.ts +96 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/grpc-transport.js +22 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/grpc-web-transport.d.ts +96 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/grpc-web-transport.js +22 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/http2-session-manager.d.ts +146 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/http2-session-manager.js +532 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/index.d.ts +15 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/index.js +23 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/node-error.d.ts +45 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/node-error.js +147 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/node-headers-polyfill.d.ts +1 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/node-headers-polyfill.js +27 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/node-transport-options.d.ts +89 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/node-transport-options.js +58 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/node-universal-client.d.ts +54 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/node-universal-client.js +324 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/node-universal-handler.d.ts +41 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/node-universal-handler.js +230 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/node-universal-header.d.ts +19 -0
- package/node_modules/@connectrpc/connect-node/dist/esm/node-universal-header.js +93 -0
- package/node_modules/@connectrpc/connect-node/package.json +46 -0
- package/node_modules/undici/LICENSE +21 -0
- package/node_modules/undici/README.md +741 -0
- package/node_modules/undici/docs/docs/api/Agent.md +84 -0
- package/node_modules/undici/docs/docs/api/BalancedPool.md +99 -0
- package/node_modules/undici/docs/docs/api/CacheStorage.md +30 -0
- package/node_modules/undici/docs/docs/api/CacheStore.md +164 -0
- package/node_modules/undici/docs/docs/api/Client.md +288 -0
- package/node_modules/undici/docs/docs/api/ClientStats.md +27 -0
- package/node_modules/undici/docs/docs/api/Connector.md +115 -0
- package/node_modules/undici/docs/docs/api/ContentType.md +57 -0
- package/node_modules/undici/docs/docs/api/Cookies.md +128 -0
- package/node_modules/undici/docs/docs/api/Debug.md +62 -0
- package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +315 -0
- package/node_modules/undici/docs/docs/api/Dispatcher.md +1392 -0
- package/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +159 -0
- package/node_modules/undici/docs/docs/api/Errors.md +49 -0
- package/node_modules/undici/docs/docs/api/EventSource.md +45 -0
- package/node_modules/undici/docs/docs/api/Fetch.md +60 -0
- package/node_modules/undici/docs/docs/api/GlobalInstallation.md +139 -0
- package/node_modules/undici/docs/docs/api/H2CClient.md +263 -0
- package/node_modules/undici/docs/docs/api/MockAgent.md +603 -0
- package/node_modules/undici/docs/docs/api/MockCallHistory.md +197 -0
- package/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +43 -0
- package/node_modules/undici/docs/docs/api/MockClient.md +81 -0
- package/node_modules/undici/docs/docs/api/MockErrors.md +12 -0
- package/node_modules/undici/docs/docs/api/MockPool.md +555 -0
- package/node_modules/undici/docs/docs/api/Pool.md +84 -0
- package/node_modules/undici/docs/docs/api/PoolStats.md +35 -0
- package/node_modules/undici/docs/docs/api/ProxyAgent.md +229 -0
- package/node_modules/undici/docs/docs/api/RedirectHandler.md +93 -0
- package/node_modules/undici/docs/docs/api/RetryAgent.md +50 -0
- package/node_modules/undici/docs/docs/api/RetryHandler.md +118 -0
- package/node_modules/undici/docs/docs/api/RoundRobinPool.md +145 -0
- package/node_modules/undici/docs/docs/api/SnapshotAgent.md +616 -0
- package/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +275 -0
- package/node_modules/undici/docs/docs/api/Util.md +25 -0
- package/node_modules/undici/docs/docs/api/WebSocket.md +141 -0
- package/node_modules/undici/docs/docs/api/api-lifecycle.md +91 -0
- package/node_modules/undici/docs/docs/best-practices/client-certificate.md +64 -0
- package/node_modules/undici/docs/docs/best-practices/crawling.md +58 -0
- package/node_modules/undici/docs/docs/best-practices/mocking-request.md +190 -0
- package/node_modules/undici/docs/docs/best-practices/proxy.md +127 -0
- package/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +224 -0
- package/node_modules/undici/docs/docs/best-practices/writing-tests.md +63 -0
- package/node_modules/undici/index-fetch.js +65 -0
- package/node_modules/undici/index.d.ts +3 -0
- package/node_modules/undici/index.js +234 -0
- package/node_modules/undici/lib/api/abort-signal.js +59 -0
- package/node_modules/undici/lib/api/api-connect.js +110 -0
- package/node_modules/undici/lib/api/api-pipeline.js +252 -0
- package/node_modules/undici/lib/api/api-request.js +214 -0
- package/node_modules/undici/lib/api/api-stream.js +209 -0
- package/node_modules/undici/lib/api/api-upgrade.js +111 -0
- package/node_modules/undici/lib/api/index.js +7 -0
- package/node_modules/undici/lib/api/readable.js +580 -0
- package/node_modules/undici/lib/cache/memory-cache-store.js +234 -0
- package/node_modules/undici/lib/cache/sqlite-cache-store.js +461 -0
- package/node_modules/undici/lib/core/connect.js +153 -0
- package/node_modules/undici/lib/core/constants.js +143 -0
- package/node_modules/undici/lib/core/diagnostics.js +227 -0
- package/node_modules/undici/lib/core/errors.js +477 -0
- package/node_modules/undici/lib/core/request.js +453 -0
- package/node_modules/undici/lib/core/socks5-client.js +422 -0
- package/node_modules/undici/lib/core/socks5-utils.js +212 -0
- package/node_modules/undici/lib/core/symbols.js +75 -0
- package/node_modules/undici/lib/core/tree.js +160 -0
- package/node_modules/undici/lib/core/util.js +992 -0
- package/node_modules/undici/lib/dispatcher/agent.js +158 -0
- package/node_modules/undici/lib/dispatcher/balanced-pool.js +219 -0
- package/node_modules/undici/lib/dispatcher/client-h1.js +1722 -0
- package/node_modules/undici/lib/dispatcher/client-h2.js +995 -0
- package/node_modules/undici/lib/dispatcher/client.js +664 -0
- package/node_modules/undici/lib/dispatcher/dispatcher-base.js +184 -0
- package/node_modules/undici/lib/dispatcher/dispatcher.js +48 -0
- package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +146 -0
- package/node_modules/undici/lib/dispatcher/fixed-queue.js +135 -0
- package/node_modules/undici/lib/dispatcher/h2c-client.js +51 -0
- package/node_modules/undici/lib/dispatcher/pool-base.js +214 -0
- package/node_modules/undici/lib/dispatcher/pool.js +118 -0
- package/node_modules/undici/lib/dispatcher/proxy-agent.js +319 -0
- package/node_modules/undici/lib/dispatcher/retry-agent.js +35 -0
- package/node_modules/undici/lib/dispatcher/round-robin-pool.js +137 -0
- package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +260 -0
- package/node_modules/undici/lib/encoding/index.js +33 -0
- package/node_modules/undici/lib/global.js +59 -0
- package/node_modules/undici/lib/handler/cache-handler.js +578 -0
- package/node_modules/undici/lib/handler/cache-revalidation-handler.js +124 -0
- package/node_modules/undici/lib/handler/decorator-handler.js +67 -0
- package/node_modules/undici/lib/handler/deduplication-handler.js +460 -0
- package/node_modules/undici/lib/handler/redirect-handler.js +238 -0
- package/node_modules/undici/lib/handler/retry-handler.js +394 -0
- package/node_modules/undici/lib/handler/unwrap-handler.js +106 -0
- package/node_modules/undici/lib/handler/wrap-handler.js +105 -0
- package/node_modules/undici/lib/interceptor/cache.js +495 -0
- package/node_modules/undici/lib/interceptor/decompress.js +259 -0
- package/node_modules/undici/lib/interceptor/deduplicate.js +117 -0
- package/node_modules/undici/lib/interceptor/dns.js +571 -0
- package/node_modules/undici/lib/interceptor/dump.js +112 -0
- package/node_modules/undici/lib/interceptor/redirect.js +21 -0
- package/node_modules/undici/lib/interceptor/response-error.js +95 -0
- package/node_modules/undici/lib/interceptor/retry.js +19 -0
- package/node_modules/undici/lib/llhttp/.gitkeep +0 -0
- package/node_modules/undici/lib/llhttp/constants.d.ts +195 -0
- package/node_modules/undici/lib/llhttp/constants.js +531 -0
- package/node_modules/undici/lib/llhttp/llhttp-wasm.js +15 -0
- package/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +15 -0
- package/node_modules/undici/lib/llhttp/utils.d.ts +2 -0
- package/node_modules/undici/lib/llhttp/utils.js +12 -0
- package/node_modules/undici/lib/mock/mock-agent.js +232 -0
- package/node_modules/undici/lib/mock/mock-call-history.js +248 -0
- package/node_modules/undici/lib/mock/mock-client.js +68 -0
- package/node_modules/undici/lib/mock/mock-errors.js +29 -0
- package/node_modules/undici/lib/mock/mock-interceptor.js +209 -0
- package/node_modules/undici/lib/mock/mock-pool.js +68 -0
- package/node_modules/undici/lib/mock/mock-symbols.js +32 -0
- package/node_modules/undici/lib/mock/mock-utils.js +486 -0
- package/node_modules/undici/lib/mock/pending-interceptors-formatter.js +43 -0
- package/node_modules/undici/lib/mock/snapshot-agent.js +353 -0
- package/node_modules/undici/lib/mock/snapshot-recorder.js +588 -0
- package/node_modules/undici/lib/mock/snapshot-utils.js +158 -0
- package/node_modules/undici/lib/util/cache.js +414 -0
- package/node_modules/undici/lib/util/date.js +653 -0
- package/node_modules/undici/lib/util/promise.js +28 -0
- package/node_modules/undici/lib/util/runtime-features.js +124 -0
- package/node_modules/undici/lib/util/stats.js +32 -0
- package/node_modules/undici/lib/util/timers.js +425 -0
- package/node_modules/undici/lib/web/cache/cache.js +864 -0
- package/node_modules/undici/lib/web/cache/cachestorage.js +152 -0
- package/node_modules/undici/lib/web/cache/util.js +45 -0
- package/node_modules/undici/lib/web/cookies/constants.js +12 -0
- package/node_modules/undici/lib/web/cookies/index.js +199 -0
- package/node_modules/undici/lib/web/cookies/parse.js +314 -0
- package/node_modules/undici/lib/web/cookies/util.js +282 -0
- package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +399 -0
- package/node_modules/undici/lib/web/eventsource/eventsource.js +501 -0
- package/node_modules/undici/lib/web/eventsource/util.js +29 -0
- package/node_modules/undici/lib/web/fetch/LICENSE +21 -0
- package/node_modules/undici/lib/web/fetch/body.js +509 -0
- package/node_modules/undici/lib/web/fetch/constants.js +131 -0
- package/node_modules/undici/lib/web/fetch/data-url.js +596 -0
- package/node_modules/undici/lib/web/fetch/formdata-parser.js +586 -0
- package/node_modules/undici/lib/web/fetch/formdata.js +259 -0
- package/node_modules/undici/lib/web/fetch/global.js +40 -0
- package/node_modules/undici/lib/web/fetch/headers.js +719 -0
- package/node_modules/undici/lib/web/fetch/index.js +2413 -0
- package/node_modules/undici/lib/web/fetch/request.js +1115 -0
- package/node_modules/undici/lib/web/fetch/response.js +641 -0
- package/node_modules/undici/lib/web/fetch/util.js +1522 -0
- package/node_modules/undici/lib/web/infra/index.js +229 -0
- package/node_modules/undici/lib/web/subresource-integrity/Readme.md +9 -0
- package/node_modules/undici/lib/web/subresource-integrity/subresource-integrity.js +307 -0
- package/node_modules/undici/lib/web/webidl/index.js +1006 -0
- package/node_modules/undici/lib/web/websocket/connection.js +329 -0
- package/node_modules/undici/lib/web/websocket/constants.js +126 -0
- package/node_modules/undici/lib/web/websocket/events.js +331 -0
- package/node_modules/undici/lib/web/websocket/frame.js +133 -0
- package/node_modules/undici/lib/web/websocket/permessage-deflate.js +100 -0
- package/node_modules/undici/lib/web/websocket/receiver.js +507 -0
- package/node_modules/undici/lib/web/websocket/sender.js +109 -0
- package/node_modules/undici/lib/web/websocket/stream/websocketerror.js +104 -0
- package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +498 -0
- package/node_modules/undici/lib/web/websocket/util.js +347 -0
- package/node_modules/undici/lib/web/websocket/websocket.js +758 -0
- package/node_modules/undici/package.json +152 -0
- package/node_modules/undici/scripts/strip-comments.js +10 -0
- package/node_modules/undici/types/README.md +6 -0
- package/node_modules/undici/types/agent.d.ts +32 -0
- package/node_modules/undici/types/api.d.ts +43 -0
- package/node_modules/undici/types/balanced-pool.d.ts +30 -0
- package/node_modules/undici/types/cache-interceptor.d.ts +179 -0
- package/node_modules/undici/types/cache.d.ts +36 -0
- package/node_modules/undici/types/client-stats.d.ts +15 -0
- package/node_modules/undici/types/client.d.ts +139 -0
- package/node_modules/undici/types/connector.d.ts +36 -0
- package/node_modules/undici/types/content-type.d.ts +21 -0
- package/node_modules/undici/types/cookies.d.ts +30 -0
- package/node_modules/undici/types/diagnostics-channel.d.ts +74 -0
- package/node_modules/undici/types/dispatcher.d.ts +275 -0
- package/node_modules/undici/types/env-http-proxy-agent.d.ts +22 -0
- package/node_modules/undici/types/errors.d.ts +177 -0
- package/node_modules/undici/types/eventsource.d.ts +66 -0
- package/node_modules/undici/types/fetch.d.ts +231 -0
- package/node_modules/undici/types/formdata.d.ts +114 -0
- package/node_modules/undici/types/global-dispatcher.d.ts +9 -0
- package/node_modules/undici/types/global-origin.d.ts +7 -0
- package/node_modules/undici/types/h2c-client.d.ts +73 -0
- package/node_modules/undici/types/handlers.d.ts +14 -0
- package/node_modules/undici/types/header.d.ts +160 -0
- package/node_modules/undici/types/index.d.ts +91 -0
- package/node_modules/undici/types/interceptors.d.ts +80 -0
- package/node_modules/undici/types/mock-agent.d.ts +68 -0
- package/node_modules/undici/types/mock-call-history.d.ts +111 -0
- package/node_modules/undici/types/mock-client.d.ts +27 -0
- package/node_modules/undici/types/mock-errors.d.ts +12 -0
- package/node_modules/undici/types/mock-interceptor.d.ts +94 -0
- package/node_modules/undici/types/mock-pool.d.ts +27 -0
- package/node_modules/undici/types/patch.d.ts +29 -0
- package/node_modules/undici/types/pool-stats.d.ts +19 -0
- package/node_modules/undici/types/pool.d.ts +41 -0
- package/node_modules/undici/types/proxy-agent.d.ts +29 -0
- package/node_modules/undici/types/readable.d.ts +68 -0
- package/node_modules/undici/types/retry-agent.d.ts +8 -0
- package/node_modules/undici/types/retry-handler.d.ts +125 -0
- package/node_modules/undici/types/round-robin-pool.d.ts +41 -0
- package/node_modules/undici/types/snapshot-agent.d.ts +109 -0
- package/node_modules/undici/types/socks5-proxy-agent.d.ts +25 -0
- package/node_modules/undici/types/util.d.ts +18 -0
- package/node_modules/undici/types/utility.d.ts +7 -0
- package/node_modules/undici/types/webidl.d.ts +347 -0
- package/node_modules/undici/types/websocket.d.ts +188 -0
- package/package.json +10 -5
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
PoolBase,
|
|
5
|
+
kClients,
|
|
6
|
+
kNeedDrain,
|
|
7
|
+
kAddClient,
|
|
8
|
+
kGetDispatcher,
|
|
9
|
+
kRemoveClient
|
|
10
|
+
} = require('./pool-base')
|
|
11
|
+
const Client = require('./client')
|
|
12
|
+
const {
|
|
13
|
+
InvalidArgumentError
|
|
14
|
+
} = require('../core/errors')
|
|
15
|
+
const util = require('../core/util')
|
|
16
|
+
const { kUrl } = require('../core/symbols')
|
|
17
|
+
const buildConnector = require('../core/connect')
|
|
18
|
+
|
|
19
|
+
const kOptions = Symbol('options')
|
|
20
|
+
const kConnections = Symbol('connections')
|
|
21
|
+
const kFactory = Symbol('factory')
|
|
22
|
+
const kIndex = Symbol('index')
|
|
23
|
+
|
|
24
|
+
function defaultFactory (origin, opts) {
|
|
25
|
+
return new Client(origin, opts)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
class RoundRobinPool extends PoolBase {
|
|
29
|
+
constructor (origin, {
|
|
30
|
+
connections,
|
|
31
|
+
factory = defaultFactory,
|
|
32
|
+
connect,
|
|
33
|
+
connectTimeout,
|
|
34
|
+
tls,
|
|
35
|
+
maxCachedSessions,
|
|
36
|
+
socketPath,
|
|
37
|
+
autoSelectFamily,
|
|
38
|
+
autoSelectFamilyAttemptTimeout,
|
|
39
|
+
allowH2,
|
|
40
|
+
clientTtl,
|
|
41
|
+
...options
|
|
42
|
+
} = {}) {
|
|
43
|
+
if (connections != null && (!Number.isFinite(connections) || connections < 0)) {
|
|
44
|
+
throw new InvalidArgumentError('invalid connections')
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (typeof factory !== 'function') {
|
|
48
|
+
throw new InvalidArgumentError('factory must be a function.')
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (connect != null && typeof connect !== 'function' && typeof connect !== 'object') {
|
|
52
|
+
throw new InvalidArgumentError('connect must be a function or an object')
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (typeof connect !== 'function') {
|
|
56
|
+
connect = buildConnector({
|
|
57
|
+
...tls,
|
|
58
|
+
maxCachedSessions,
|
|
59
|
+
allowH2,
|
|
60
|
+
socketPath,
|
|
61
|
+
timeout: connectTimeout,
|
|
62
|
+
...(typeof autoSelectFamily === 'boolean' ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } : undefined),
|
|
63
|
+
...connect
|
|
64
|
+
})
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
super()
|
|
68
|
+
|
|
69
|
+
this[kConnections] = connections || null
|
|
70
|
+
this[kUrl] = util.parseOrigin(origin)
|
|
71
|
+
this[kOptions] = { ...util.deepClone(options), connect, allowH2, clientTtl, socketPath }
|
|
72
|
+
this[kOptions].interceptors = options.interceptors
|
|
73
|
+
? { ...options.interceptors }
|
|
74
|
+
: undefined
|
|
75
|
+
this[kFactory] = factory
|
|
76
|
+
this[kIndex] = -1
|
|
77
|
+
|
|
78
|
+
this.on('connect', (origin, targets) => {
|
|
79
|
+
if (clientTtl != null && clientTtl > 0) {
|
|
80
|
+
for (const target of targets) {
|
|
81
|
+
Object.assign(target, { ttl: Date.now() })
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
this.on('connectionError', (origin, targets, error) => {
|
|
87
|
+
for (const target of targets) {
|
|
88
|
+
const idx = this[kClients].indexOf(target)
|
|
89
|
+
if (idx !== -1) {
|
|
90
|
+
this[kClients].splice(idx, 1)
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
[kGetDispatcher] () {
|
|
97
|
+
const clientTtlOption = this[kOptions].clientTtl
|
|
98
|
+
const clientsLength = this[kClients].length
|
|
99
|
+
|
|
100
|
+
// If we have no clients yet, create one
|
|
101
|
+
if (clientsLength === 0) {
|
|
102
|
+
const dispatcher = this[kFactory](this[kUrl], this[kOptions])
|
|
103
|
+
this[kAddClient](dispatcher)
|
|
104
|
+
return dispatcher
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Round-robin through existing clients
|
|
108
|
+
let checked = 0
|
|
109
|
+
while (checked < clientsLength) {
|
|
110
|
+
this[kIndex] = (this[kIndex] + 1) % clientsLength
|
|
111
|
+
const client = this[kClients][this[kIndex]]
|
|
112
|
+
|
|
113
|
+
// Check if client is stale (TTL expired)
|
|
114
|
+
if (clientTtlOption != null && clientTtlOption > 0 && client.ttl && ((Date.now() - client.ttl) > clientTtlOption)) {
|
|
115
|
+
this[kRemoveClient](client)
|
|
116
|
+
checked++
|
|
117
|
+
continue
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Return client if it's not draining
|
|
121
|
+
if (!client[kNeedDrain]) {
|
|
122
|
+
return client
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
checked++
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// All clients are busy, create a new one if we haven't reached the limit
|
|
129
|
+
if (!this[kConnections] || clientsLength < this[kConnections]) {
|
|
130
|
+
const dispatcher = this[kFactory](this[kUrl], this[kOptions])
|
|
131
|
+
this[kAddClient](dispatcher)
|
|
132
|
+
return dispatcher
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
module.exports = RoundRobinPool
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { URL } = require('node:url')
|
|
4
|
+
|
|
5
|
+
let tls // include tls conditionally since it is not always available
|
|
6
|
+
const DispatcherBase = require('./dispatcher-base')
|
|
7
|
+
const { InvalidArgumentError } = require('../core/errors')
|
|
8
|
+
const { Socks5Client, STATES } = require('../core/socks5-client')
|
|
9
|
+
const { kDispatch, kClose, kDestroy } = require('../core/symbols')
|
|
10
|
+
const Pool = require('./pool')
|
|
11
|
+
const buildConnector = require('../core/connect')
|
|
12
|
+
const { debuglog } = require('node:util')
|
|
13
|
+
|
|
14
|
+
const debug = debuglog('undici:socks5-proxy')
|
|
15
|
+
|
|
16
|
+
const kProxyUrl = Symbol('proxy url')
|
|
17
|
+
const kProxyHeaders = Symbol('proxy headers')
|
|
18
|
+
const kProxyAuth = Symbol('proxy auth')
|
|
19
|
+
const kProxyProtocol = Symbol('proxy protocol')
|
|
20
|
+
const kPools = Symbol('pools')
|
|
21
|
+
const kConnector = Symbol('connector')
|
|
22
|
+
const kRequestTls = Symbol('request tls settings')
|
|
23
|
+
|
|
24
|
+
// Static flag to ensure warning is only emitted once per process
|
|
25
|
+
let experimentalWarningEmitted = false
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* SOCKS5 proxy agent for dispatching requests through a SOCKS5 proxy
|
|
29
|
+
*/
|
|
30
|
+
class Socks5ProxyAgent extends DispatcherBase {
|
|
31
|
+
constructor (proxyUrl, options = {}) {
|
|
32
|
+
super()
|
|
33
|
+
|
|
34
|
+
// Emit experimental warning only once
|
|
35
|
+
if (!experimentalWarningEmitted) {
|
|
36
|
+
process.emitWarning(
|
|
37
|
+
'SOCKS5 proxy support is experimental and subject to change',
|
|
38
|
+
'ExperimentalWarning'
|
|
39
|
+
)
|
|
40
|
+
experimentalWarningEmitted = true
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!proxyUrl) {
|
|
44
|
+
throw new InvalidArgumentError('Proxy URL is mandatory')
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Parse proxy URL
|
|
48
|
+
const url = typeof proxyUrl === 'string' ? new URL(proxyUrl) : proxyUrl
|
|
49
|
+
|
|
50
|
+
if (url.protocol !== 'socks5:' && url.protocol !== 'socks:') {
|
|
51
|
+
throw new InvalidArgumentError('Proxy URL must use socks5:// or socks:// protocol')
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
this[kProxyUrl] = url
|
|
55
|
+
this[kProxyHeaders] = options.headers || {}
|
|
56
|
+
this[kProxyProtocol] = options.proxyTls ? 'https:' : 'http:'
|
|
57
|
+
this[kRequestTls] = options.requestTls
|
|
58
|
+
|
|
59
|
+
// Extract auth from URL or options
|
|
60
|
+
this[kProxyAuth] = {
|
|
61
|
+
username: options.username || (url.username ? decodeURIComponent(url.username) : null),
|
|
62
|
+
password: options.password || (url.password ? decodeURIComponent(url.password) : null)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Create connector for proxy connection
|
|
66
|
+
this[kConnector] = options.connect || buildConnector({
|
|
67
|
+
...options.proxyTls,
|
|
68
|
+
servername: options.proxyTls?.servername || url.hostname
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
// Pools for the actual HTTP connections (with SOCKS5 tunnel connect function), keyed by origin
|
|
72
|
+
this[kPools] = new Map()
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Create a SOCKS5 connection to the proxy
|
|
77
|
+
*/
|
|
78
|
+
async createSocks5Connection (targetHost, targetPort) {
|
|
79
|
+
const proxyHost = this[kProxyUrl].hostname
|
|
80
|
+
const proxyPort = parseInt(this[kProxyUrl].port) || 1080
|
|
81
|
+
|
|
82
|
+
debug('creating SOCKS5 connection to', proxyHost, proxyPort)
|
|
83
|
+
|
|
84
|
+
// Connect to the SOCKS5 proxy
|
|
85
|
+
const socket = await new Promise((resolve, reject) => {
|
|
86
|
+
this[kConnector]({
|
|
87
|
+
hostname: proxyHost,
|
|
88
|
+
host: proxyHost,
|
|
89
|
+
port: proxyPort,
|
|
90
|
+
protocol: this[kProxyProtocol]
|
|
91
|
+
}, (err, socket) => {
|
|
92
|
+
if (err) {
|
|
93
|
+
reject(err)
|
|
94
|
+
} else {
|
|
95
|
+
resolve(socket)
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
// Create SOCKS5 client
|
|
101
|
+
const socks5Client = new Socks5Client(socket, this[kProxyAuth])
|
|
102
|
+
|
|
103
|
+
// Handle SOCKS5 errors
|
|
104
|
+
socks5Client.on('error', (err) => {
|
|
105
|
+
debug('SOCKS5 error:', err)
|
|
106
|
+
socket.destroy()
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
// Perform SOCKS5 handshake
|
|
110
|
+
await socks5Client.handshake()
|
|
111
|
+
|
|
112
|
+
// Wait for authentication (if required)
|
|
113
|
+
await new Promise((resolve, reject) => {
|
|
114
|
+
const timeout = setTimeout(() => {
|
|
115
|
+
reject(new Error('SOCKS5 authentication timeout'))
|
|
116
|
+
}, 5000)
|
|
117
|
+
|
|
118
|
+
const onAuthenticated = () => {
|
|
119
|
+
clearTimeout(timeout)
|
|
120
|
+
socks5Client.removeListener('error', onError)
|
|
121
|
+
resolve()
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const onError = (err) => {
|
|
125
|
+
clearTimeout(timeout)
|
|
126
|
+
socks5Client.removeListener('authenticated', onAuthenticated)
|
|
127
|
+
reject(err)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Check if already authenticated (for NO_AUTH method)
|
|
131
|
+
if (socks5Client.state === STATES.AUTHENTICATED) {
|
|
132
|
+
clearTimeout(timeout)
|
|
133
|
+
resolve()
|
|
134
|
+
} else {
|
|
135
|
+
socks5Client.once('authenticated', onAuthenticated)
|
|
136
|
+
socks5Client.once('error', onError)
|
|
137
|
+
}
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
// Send CONNECT command
|
|
141
|
+
await socks5Client.connect(targetHost, targetPort)
|
|
142
|
+
|
|
143
|
+
// Wait for connection
|
|
144
|
+
await new Promise((resolve, reject) => {
|
|
145
|
+
const timeout = setTimeout(() => {
|
|
146
|
+
reject(new Error('SOCKS5 connection timeout'))
|
|
147
|
+
}, 5000)
|
|
148
|
+
|
|
149
|
+
const onConnected = (info) => {
|
|
150
|
+
debug('SOCKS5 tunnel established to', targetHost, targetPort, 'via', info)
|
|
151
|
+
clearTimeout(timeout)
|
|
152
|
+
socks5Client.removeListener('error', onError)
|
|
153
|
+
resolve()
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const onError = (err) => {
|
|
157
|
+
clearTimeout(timeout)
|
|
158
|
+
socks5Client.removeListener('connected', onConnected)
|
|
159
|
+
reject(err)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
socks5Client.once('connected', onConnected)
|
|
163
|
+
socks5Client.once('error', onError)
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
return socket
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Dispatch a request through the SOCKS5 proxy
|
|
171
|
+
*/
|
|
172
|
+
[kDispatch] (opts, handler) {
|
|
173
|
+
const { origin } = opts
|
|
174
|
+
|
|
175
|
+
debug('dispatching request to', origin, 'via SOCKS5')
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
const originKey = String(origin)
|
|
179
|
+
let pool = this[kPools].get(originKey)
|
|
180
|
+
// Create a Pool per origin so requests are not routed to the wrong host
|
|
181
|
+
if (!pool || pool.destroyed || pool.closed) {
|
|
182
|
+
pool = new Pool(origin, {
|
|
183
|
+
pipelining: opts.pipelining,
|
|
184
|
+
connections: opts.connections,
|
|
185
|
+
connect: async (connectOpts, callback) => {
|
|
186
|
+
try {
|
|
187
|
+
const url = new URL(origin)
|
|
188
|
+
const targetHost = url.hostname
|
|
189
|
+
const targetPort = parseInt(url.port) || (url.protocol === 'https:' ? 443 : 80)
|
|
190
|
+
|
|
191
|
+
debug('establishing SOCKS5 connection to', targetHost, targetPort)
|
|
192
|
+
|
|
193
|
+
// Create SOCKS5 tunnel
|
|
194
|
+
const socket = await this.createSocks5Connection(targetHost, targetPort)
|
|
195
|
+
|
|
196
|
+
// Handle TLS if needed
|
|
197
|
+
let finalSocket = socket
|
|
198
|
+
if (url.protocol === 'https:') {
|
|
199
|
+
if (!tls) {
|
|
200
|
+
tls = require('node:tls')
|
|
201
|
+
}
|
|
202
|
+
debug('upgrading to TLS')
|
|
203
|
+
finalSocket = tls.connect({
|
|
204
|
+
...this[kRequestTls],
|
|
205
|
+
socket,
|
|
206
|
+
servername: this[kRequestTls]?.servername || targetHost
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
await new Promise((resolve, reject) => {
|
|
210
|
+
finalSocket.once('secureConnect', resolve)
|
|
211
|
+
finalSocket.once('error', reject)
|
|
212
|
+
})
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
callback(null, finalSocket)
|
|
216
|
+
} catch (err) {
|
|
217
|
+
debug('SOCKS5 connection error:', err)
|
|
218
|
+
callback(err)
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
})
|
|
222
|
+
this[kPools].set(originKey, pool)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Dispatch the request through the per-origin pool
|
|
226
|
+
return pool[kDispatch](opts, handler)
|
|
227
|
+
} catch (err) {
|
|
228
|
+
debug('dispatch error:', err)
|
|
229
|
+
if (typeof handler.onResponseError === 'function') {
|
|
230
|
+
handler.onResponseError(null, err)
|
|
231
|
+
return false
|
|
232
|
+
} else if (typeof handler.onError === 'function') {
|
|
233
|
+
handler.onError(err)
|
|
234
|
+
return false
|
|
235
|
+
} else {
|
|
236
|
+
throw err
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
async [kClose] () {
|
|
242
|
+
const closePromises = []
|
|
243
|
+
for (const pool of this[kPools].values()) {
|
|
244
|
+
closePromises.push(pool.close())
|
|
245
|
+
}
|
|
246
|
+
this[kPools].clear()
|
|
247
|
+
await Promise.all(closePromises)
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
async [kDestroy] (err) {
|
|
251
|
+
const destroyPromises = []
|
|
252
|
+
for (const pool of this[kPools].values()) {
|
|
253
|
+
destroyPromises.push(pool.destroy(err))
|
|
254
|
+
}
|
|
255
|
+
this[kPools].clear()
|
|
256
|
+
await Promise.all(destroyPromises)
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
module.exports = Socks5ProxyAgent
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const textDecoder = new TextDecoder()
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @see https://encoding.spec.whatwg.org/#utf-8-decode
|
|
7
|
+
* @param {Uint8Array} buffer
|
|
8
|
+
*/
|
|
9
|
+
function utf8DecodeBytes (buffer) {
|
|
10
|
+
if (buffer.length === 0) {
|
|
11
|
+
return ''
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// 1. Let buffer be the result of peeking three bytes from
|
|
15
|
+
// ioQueue, converted to a byte sequence.
|
|
16
|
+
|
|
17
|
+
// 2. If buffer is 0xEF 0xBB 0xBF, then read three
|
|
18
|
+
// bytes from ioQueue. (Do nothing with those bytes.)
|
|
19
|
+
if (buffer[0] === 0xEF && buffer[1] === 0xBB && buffer[2] === 0xBF) {
|
|
20
|
+
buffer = buffer.subarray(3)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// 3. Process a queue with an instance of UTF-8’s
|
|
24
|
+
// decoder, ioQueue, output, and "replacement".
|
|
25
|
+
const output = textDecoder.decode(buffer)
|
|
26
|
+
|
|
27
|
+
// 4. Return output.
|
|
28
|
+
return output
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = {
|
|
32
|
+
utf8DecodeBytes
|
|
33
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// We include a version number for the Dispatcher API. In case of breaking changes,
|
|
4
|
+
// this version number must be increased to avoid conflicts.
|
|
5
|
+
const globalDispatcher = Symbol.for('undici.globalDispatcher.2')
|
|
6
|
+
const legacyGlobalDispatcher = Symbol.for('undici.globalDispatcher.1')
|
|
7
|
+
const { InvalidArgumentError } = require('./core/errors')
|
|
8
|
+
const Agent = require('./dispatcher/agent')
|
|
9
|
+
|
|
10
|
+
if (getGlobalDispatcher() === undefined) {
|
|
11
|
+
setGlobalDispatcher(new Agent())
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function setGlobalDispatcher (agent) {
|
|
15
|
+
if (!agent || typeof agent.dispatch !== 'function') {
|
|
16
|
+
throw new InvalidArgumentError('Argument agent must implement Agent')
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
Object.defineProperty(globalThis, globalDispatcher, {
|
|
20
|
+
value: agent,
|
|
21
|
+
writable: true,
|
|
22
|
+
enumerable: false,
|
|
23
|
+
configurable: false
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
Object.defineProperty(globalThis, legacyGlobalDispatcher, {
|
|
27
|
+
value: agent,
|
|
28
|
+
writable: true,
|
|
29
|
+
enumerable: false,
|
|
30
|
+
configurable: false
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getGlobalDispatcher () {
|
|
35
|
+
return globalThis[legacyGlobalDispatcher]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// These are the globals that can be installed by undici.install().
|
|
39
|
+
// Not exported by index.js to avoid use outside of this module.
|
|
40
|
+
const installedExports = /** @type {const} */ (
|
|
41
|
+
[
|
|
42
|
+
'fetch',
|
|
43
|
+
'Headers',
|
|
44
|
+
'Response',
|
|
45
|
+
'Request',
|
|
46
|
+
'FormData',
|
|
47
|
+
'WebSocket',
|
|
48
|
+
'CloseEvent',
|
|
49
|
+
'ErrorEvent',
|
|
50
|
+
'MessageEvent',
|
|
51
|
+
'EventSource'
|
|
52
|
+
]
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
module.exports = {
|
|
56
|
+
setGlobalDispatcher,
|
|
57
|
+
getGlobalDispatcher,
|
|
58
|
+
installedExports
|
|
59
|
+
}
|