xref: /third_party/node/deps/undici/src/index.js (revision 1cb0ef41)
1'use strict'
2
3const Client = require('./lib/client')
4const Dispatcher = require('./lib/dispatcher')
5const errors = require('./lib/core/errors')
6const Pool = require('./lib/pool')
7const BalancedPool = require('./lib/balanced-pool')
8const Agent = require('./lib/agent')
9const util = require('./lib/core/util')
10const { InvalidArgumentError } = errors
11const api = require('./lib/api')
12const buildConnector = require('./lib/core/connect')
13const MockClient = require('./lib/mock/mock-client')
14const MockAgent = require('./lib/mock/mock-agent')
15const MockPool = require('./lib/mock/mock-pool')
16const mockErrors = require('./lib/mock/mock-errors')
17const ProxyAgent = require('./lib/proxy-agent')
18const RetryHandler = require('./lib/handler/RetryHandler')
19const { getGlobalDispatcher, setGlobalDispatcher } = require('./lib/global')
20const DecoratorHandler = require('./lib/handler/DecoratorHandler')
21const RedirectHandler = require('./lib/handler/RedirectHandler')
22const createRedirectInterceptor = require('./lib/interceptor/redirectInterceptor')
23
24let hasCrypto
25try {
26  require('crypto')
27  hasCrypto = true
28} catch {
29  hasCrypto = false
30}
31
32Object.assign(Dispatcher.prototype, api)
33
34module.exports.Dispatcher = Dispatcher
35module.exports.Client = Client
36module.exports.Pool = Pool
37module.exports.BalancedPool = BalancedPool
38module.exports.Agent = Agent
39module.exports.ProxyAgent = ProxyAgent
40module.exports.RetryHandler = RetryHandler
41
42module.exports.DecoratorHandler = DecoratorHandler
43module.exports.RedirectHandler = RedirectHandler
44module.exports.createRedirectInterceptor = createRedirectInterceptor
45
46module.exports.buildConnector = buildConnector
47module.exports.errors = errors
48
49function makeDispatcher (fn) {
50  return (url, opts, handler) => {
51    if (typeof opts === 'function') {
52      handler = opts
53      opts = null
54    }
55
56    if (!url || (typeof url !== 'string' && typeof url !== 'object' && !(url instanceof URL))) {
57      throw new InvalidArgumentError('invalid url')
58    }
59
60    if (opts != null && typeof opts !== 'object') {
61      throw new InvalidArgumentError('invalid opts')
62    }
63
64    if (opts && opts.path != null) {
65      if (typeof opts.path !== 'string') {
66        throw new InvalidArgumentError('invalid opts.path')
67      }
68
69      let path = opts.path
70      if (!opts.path.startsWith('/')) {
71        path = `/${path}`
72      }
73
74      url = new URL(util.parseOrigin(url).origin + path)
75    } else {
76      if (!opts) {
77        opts = typeof url === 'object' ? url : {}
78      }
79
80      url = util.parseURL(url)
81    }
82
83    const { agent, dispatcher = getGlobalDispatcher() } = opts
84
85    if (agent) {
86      throw new InvalidArgumentError('unsupported opts.agent. Did you mean opts.client?')
87    }
88
89    return fn.call(dispatcher, {
90      ...opts,
91      origin: url.origin,
92      path: url.search ? `${url.pathname}${url.search}` : url.pathname,
93      method: opts.method || (opts.body ? 'PUT' : 'GET')
94    }, handler)
95  }
96}
97
98module.exports.setGlobalDispatcher = setGlobalDispatcher
99module.exports.getGlobalDispatcher = getGlobalDispatcher
100
101if (util.nodeMajor > 16 || (util.nodeMajor === 16 && util.nodeMinor >= 8)) {
102  let fetchImpl = null
103  module.exports.fetch = async function fetch (resource) {
104    if (!fetchImpl) {
105      fetchImpl = require('./lib/fetch').fetch
106    }
107
108    try {
109      return await fetchImpl(...arguments)
110    } catch (err) {
111      if (typeof err === 'object') {
112        Error.captureStackTrace(err, this)
113      }
114
115      throw err
116    }
117  }
118  module.exports.Headers = require('./lib/fetch/headers').Headers
119  module.exports.Response = require('./lib/fetch/response').Response
120  module.exports.Request = require('./lib/fetch/request').Request
121  module.exports.FormData = require('./lib/fetch/formdata').FormData
122  module.exports.File = require('./lib/fetch/file').File
123  module.exports.FileReader = require('./lib/fileapi/filereader').FileReader
124
125  const { setGlobalOrigin, getGlobalOrigin } = require('./lib/fetch/global')
126
127  module.exports.setGlobalOrigin = setGlobalOrigin
128  module.exports.getGlobalOrigin = getGlobalOrigin
129
130  const { CacheStorage } = require('./lib/cache/cachestorage')
131  const { kConstruct } = require('./lib/cache/symbols')
132
133  // Cache & CacheStorage are tightly coupled with fetch. Even if it may run
134  // in an older version of Node, it doesn't have any use without fetch.
135  module.exports.caches = new CacheStorage(kConstruct)
136}
137
138if (util.nodeMajor >= 16) {
139  const { deleteCookie, getCookies, getSetCookies, setCookie } = require('./lib/cookies')
140
141  module.exports.deleteCookie = deleteCookie
142  module.exports.getCookies = getCookies
143  module.exports.getSetCookies = getSetCookies
144  module.exports.setCookie = setCookie
145
146  const { parseMIMEType, serializeAMimeType } = require('./lib/fetch/dataURL')
147
148  module.exports.parseMIMEType = parseMIMEType
149  module.exports.serializeAMimeType = serializeAMimeType
150}
151
152if (util.nodeMajor >= 18 && hasCrypto) {
153  const { WebSocket } = require('./lib/websocket/websocket')
154
155  module.exports.WebSocket = WebSocket
156}
157
158module.exports.request = makeDispatcher(api.request)
159module.exports.stream = makeDispatcher(api.stream)
160module.exports.pipeline = makeDispatcher(api.pipeline)
161module.exports.connect = makeDispatcher(api.connect)
162module.exports.upgrade = makeDispatcher(api.upgrade)
163
164module.exports.MockClient = MockClient
165module.exports.MockPool = MockPool
166module.exports.MockAgent = MockAgent
167module.exports.mockErrors = mockErrors
168