@hyperttp/core 1.5.0 → 1.5.2

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.
@@ -1,2 +1,2 @@
1
- "use strict";import{normalizeBody as b,normalizeUrl as w}from"../utils/normalize.js";import{mergeHeadersFast as U}from"../utils/response.js";function y(i,e){if(typeof AbortSignal.any=="function")return AbortSignal.any([i,AbortSignal.timeout(e)]);const t=new AbortController;let r;const s=()=>{r?.(),t.abort(i.reason)},h=setTimeout(()=>{t.abort(new DOMException("Timeout","TimeoutError"))},e);return r=()=>{clearTimeout(h)},i.addEventListener("abort",s),t.signal.addEventListener("abort",()=>{i.removeEventListener("abort",s),clearTimeout(h)}),t.signal}function p(i,e){return e==null||e<=0?i:i?y(i,e):AbortSignal.timeout(e)}export class RequestBuilder{urlCache=Object.create(null);urlCacheCount=0;MAX_CACHE_SIZE=512;build(e,t,r,s,l,h,a,m){const n=m??{method:"GET",url:"",headers:h,body:void 0,signal:void 0,meta:{responseType:void 0,timings:{networkMs:void 0}},stealth:void 0},f=n.meta;if(typeof t=="string")return n.method=e,n.url=this.resolveUrl(t,a.baseURL),n.headers={...h},n.body=r!==void 0?b(e,r):void 0,n.signal=p(s,a.network?.timeout),f.responseType=l,n.stealth=a.network?.stealth,n;const o=w(t);if(!o)throw new Error(`[HyperCore] URL is undefined for ${e}`);let C;if(t.query){const u=o+"_base";let c=this.urlCache[u];c||(c=a.baseURL?new URL(o,a.baseURL).href:new URL(o).href,this.ensureCacheSpace(),this.urlCache[u]=c,this.urlCacheCount++);const d=new URL(c);this.appendQueryParams(d,t.query),C=d.href}else{let u=this.urlCache[o];u||(u=a.baseURL?new URL(o,a.baseURL).href:new URL(o).href,this.urlCacheCount>=this.MAX_CACHE_SIZE&&(this.urlCache=Object.create(null),this.urlCacheCount=0),this.urlCache[o]=u,this.urlCacheCount++),C=u}return n.method=e,n.url=C,n.headers=t.headers?U({...h},t.headers):{...h},n.body=b(e,t.body??r),n.signal=p(t.signal??s,a.network?.timeout),f.responseType=l??t.meta?.responseType,t.stealth?n.stealth=a.network?.stealth?{...a.network.stealth,...t.stealth}:t.stealth:n.stealth=a.network?.stealth,n}resolveUrl(e,t){if(!e)throw new Error("[HyperCore] URL is undefined");let r=this.urlCache[e];return r||((e.startsWith("http://")||e.startsWith("https://"))&&!e.includes("?")?r=e:r=t?new URL(e,t).href:new URL(e).href,this.urlCacheCount>=this.MAX_CACHE_SIZE&&(this.urlCache=Object.create(null),this.urlCacheCount=0),this.urlCache[e]=r,this.urlCacheCount++,r)}ensureCacheSpace(){this.urlCacheCount>=this.MAX_CACHE_SIZE&&(this.urlCache=Object.create(null),this.urlCacheCount=0)}appendQueryParams(e,t){for(const r in t)if(Object.prototype.hasOwnProperty.call(t,r)){const s=t[r];if(s==null)continue;if(Array.isArray(s))for(let l=0;l<s.length;l++)e.searchParams.append(r,String(s[l]));else e.searchParams.set(r,String(s))}}}
1
+ "use strict";import{CacheManager as U}from"hcacher";import{normalizeBody as b,normalizeUrl as y}from"../utils/normalize.js";import{mergeHeadersFast as C}from"../utils/response.js";class L{activeControllers=[];constructor(){for(let e=0;e<64;e++)this.activeControllers.push(new AbortController)}acquire(e,t,n){const a=this.activeControllers.pop()??new AbortController;let h=!1;const i=()=>{h||(h=!0,e&&e.removeEventListener("abort",f),clearTimeout(o),this.activeControllers.push(a))},o=setTimeout(()=>{a.abort(new DOMException("Timeout","TimeoutError")),i()},t),f=()=>{a.abort(e?.reason),i()};return e&&e.addEventListener("abort",f),n.cleanupSignal=i,a.signal}}const R=new L;function m(u,e,t){return e==null||e<=0?u:R.acquire(u,e,t)}export class RequestBuilder{urlCache=new U({maxSize:512,ttl:6e4});build(e,t,n,a,h,i,o,f){const r=f??{method:"GET",url:"",headers:i,body:void 0,signal:void 0,meta:{responseType:void 0,timings:{networkMs:void 0}},stealth:void 0},p=r.meta;if(typeof t=="string"){if(r.method=e,r.url=this.resolveUrl(t,o.baseURL),n!==void 0){r.headers=Object.create(null);for(const s in i)r.headers[s]=i[s]}else r.headers=i;return r.body=n!==void 0?b(e,n):void 0,r.signal=m(a,o.network?.timeout,p),p.responseType=h,r.stealth=o.network?.stealth,r}const c=y(t);if(!c)throw new Error(`[HyperCore] URL is undefined for ${e}`);let d;if(t.query){const s=c+"_base";let l=this.urlCache.get(s);l||(l=o.baseURL?new URL(c,o.baseURL).href:new URL(c).href,this.urlCache.set(s,l));const w=new URL(l);this.appendQueryParams(w,t.query),d=w.href}else{let s=this.urlCache.get(c);s||(s=o.baseURL?new URL(c,o.baseURL).href:new URL(c).href,this.urlCache.set(c,s)),d=s}if(r.method=e,r.url=d,t.headers){const s=Object.create(null);for(const l in i)s[l]=i[l];r.headers=C(s,t.headers)}else r.headers=i;if(r.body=b(e,t.body??n),r.signal=m(t.signal??a,o.network?.timeout,p),p.responseType=h??t.meta?.responseType,t.stealth)if(o.network?.stealth){const s=Object.create(null);for(const l in o.network.stealth)s[l]=o.network.stealth[l];for(const l in t.stealth)s[l]=t.stealth[l];r.stealth=s}else r.stealth=t.stealth;else r.stealth=o.network?.stealth;return r}resolveUrl(e,t){if(!e)throw new Error("[HyperCore] URL is undefined");let n=this.urlCache.get(e);return n||((e.startsWith("http://")||e.startsWith("https://"))&&!e.includes("?")?n=e:n=t?new URL(e,t).href:new URL(e).href,this.urlCache.set(e,n),n)}appendQueryParams(e,t){for(const n in t)if(Object.prototype.hasOwnProperty.call(t,n)){const a=t[n];if(a==null)continue;if(Array.isArray(a))for(let h=0;h<a.length;h++)e.searchParams.append(n,String(a[h]));else e.searchParams.set(n,String(a))}}}
2
2
  //# sourceMappingURL=RequestBuilder.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/Core/RequestBuilder.ts"],
4
- "sourcesContent": ["import type {\n HttpClientOptions,\n InternalRequest,\n RequestInterface,\n RequestBodyData,\n Method,\n ResponseType,\n} from \"@hyperttp/types\";\nimport { normalizeBody, normalizeUrl } from \"../utils/normalize.js\";\nimport { mergeHeadersFast } from \"../utils/response.js\";\n\nfunction combineSignals(userSignal: AbortSignal, timeoutMs: number): AbortSignal {\n if (typeof AbortSignal.any === \"function\") {\n return AbortSignal.any([userSignal, AbortSignal.timeout(timeoutMs)]);\n }\n\n const controller = new AbortController();\n let cleanup: (() => void) | undefined;\n\n const onUserAbort = () => {\n cleanup?.();\n controller.abort(userSignal.reason);\n };\n\n const onTimeout = () => {\n controller.abort(new DOMException(\"Timeout\", \"TimeoutError\"));\n };\n\n const timeoutId = setTimeout(onTimeout, timeoutMs);\n cleanup = () => {\n clearTimeout(timeoutId);\n };\n\n userSignal.addEventListener(\"abort\", onUserAbort);\n\n controller.signal.addEventListener(\"abort\", () => {\n userSignal.removeEventListener(\"abort\", onUserAbort);\n clearTimeout(timeoutId);\n });\n\n return controller.signal;\n}\n\nfunction applyTimeout(\n signal: AbortSignal | undefined,\n timeout: number | undefined,\n): AbortSignal | undefined {\n if (timeout == null || timeout <= 0) return signal;\n if (!signal) return AbortSignal.timeout(timeout);\n return combineSignals(signal, timeout);\n}\n\nexport class RequestBuilder {\n private urlCache: Record<string, string> = Object.create(null);\n private urlCacheCount = 0;\n private readonly MAX_CACHE_SIZE = 512;\n\n build(\n method: Method,\n req: RequestInterface | string,\n body: RequestBodyData | undefined,\n signal: AbortSignal | undefined,\n responseType: \"stream\" | undefined,\n defaultHeaders: Record<string, string | string[]>,\n config: HttpClientOptions,\n pooled?: InternalRequest,\n ): InternalRequest {\n const internalReq = pooled ?? {\n method: \"GET\" as Method,\n url: \"\",\n headers: defaultHeaders,\n body: undefined,\n signal: undefined,\n meta: {\n responseType: undefined as ResponseType | undefined,\n timings: {\n networkMs: undefined as number | undefined,\n },\n },\n stealth: undefined,\n };\n\n const metaObj = internalReq.meta as {\n responseType: ResponseType | undefined;\n timings: {\n networkMs: number | undefined;\n };\n };\n\n if (typeof req === \"string\") {\n internalReq.method = method;\n internalReq.url = this.resolveUrl(req, config.baseURL);\n internalReq.headers = { ...defaultHeaders };\n internalReq.body = body !== undefined ? normalizeBody(method, body) : undefined;\n internalReq.signal = applyTimeout(signal, config.network?.timeout);\n\n metaObj.responseType = responseType;\n\n internalReq.stealth = config.network?.stealth;\n return internalReq;\n }\n\n const rawUrl = normalizeUrl(req);\n if (!rawUrl) throw new Error(`[HyperCore] URL is undefined for ${method}`);\n\n let finalUrl: string;\n\n if (req.query) {\n const cacheKey = rawUrl + \"_base\";\n let baseUrl = this.urlCache[cacheKey];\n\n if (!baseUrl) {\n baseUrl = config.baseURL ? new URL(rawUrl, config.baseURL).href : new URL(rawUrl).href;\n\n this.ensureCacheSpace();\n this.urlCache[cacheKey] = baseUrl;\n this.urlCacheCount++;\n }\n\n const urlObj = new URL(baseUrl);\n this.appendQueryParams(urlObj, req.query);\n finalUrl = urlObj.href;\n } else {\n let cachedUrl = this.urlCache[rawUrl];\n if (!cachedUrl) {\n cachedUrl = config.baseURL ? new URL(rawUrl, config.baseURL).href : new URL(rawUrl).href;\n\n if (this.urlCacheCount >= this.MAX_CACHE_SIZE) {\n this.urlCache = Object.create(null);\n this.urlCacheCount = 0;\n }\n this.urlCache[rawUrl] = cachedUrl;\n this.urlCacheCount++;\n }\n finalUrl = cachedUrl;\n }\n\n internalReq.method = method;\n internalReq.url = finalUrl;\n internalReq.headers = req.headers\n ? mergeHeadersFast({ ...defaultHeaders }, req.headers)\n : { ...defaultHeaders };\n internalReq.body = normalizeBody(method, req.body ?? body);\n internalReq.signal = applyTimeout(req.signal ?? signal, config.network?.timeout);\n\n metaObj.responseType =\n responseType ?? (req.meta as { responseType?: ResponseType })?.responseType;\n\n if (req.stealth) {\n internalReq.stealth = config.network?.stealth\n ? { ...config.network.stealth, ...req.stealth }\n : req.stealth;\n } else {\n internalReq.stealth = config.network?.stealth;\n }\n\n return internalReq;\n }\n\n private resolveUrl(url: string, baseURL?: string): string {\n if (!url) throw new Error(\"[HyperCore] URL is undefined\");\n\n let finalUrl = this.urlCache[url];\n if (finalUrl) return finalUrl;\n\n const isAbsolute = url.startsWith(\"http://\") || url.startsWith(\"https://\");\n\n if (isAbsolute && !url.includes(\"?\")) {\n finalUrl = url;\n } else {\n finalUrl = baseURL ? new URL(url, baseURL).href : new URL(url).href;\n }\n\n if (this.urlCacheCount >= this.MAX_CACHE_SIZE) {\n this.urlCache = Object.create(null);\n this.urlCacheCount = 0;\n }\n this.urlCache[url] = finalUrl;\n this.urlCacheCount++;\n\n return finalUrl;\n }\n\n private ensureCacheSpace(): void {\n if (this.urlCacheCount >= this.MAX_CACHE_SIZE) {\n this.urlCache = Object.create(null);\n this.urlCacheCount = 0;\n }\n }\n\n private appendQueryParams(url: URL, query: Record<string, unknown>): void {\n for (const k in query) {\n if (Object.prototype.hasOwnProperty.call(query, k)) {\n const v = query[k];\n if (v == null) continue;\n if (Array.isArray(v)) {\n for (let j = 0; j < v.length; j++) url.searchParams.append(k, String(v[j]));\n } else {\n url.searchParams.set(k, String(v));\n }\n }\n }\n }\n}\n"],
5
- "mappings": "aAQA,OAAS,iBAAAA,EAAe,gBAAAC,MAAoB,wBAC5C,OAAS,oBAAAC,MAAwB,uBAEjC,SAASC,EAAeC,EAAyBC,EAAiB,CAChE,GAAI,OAAO,YAAY,KAAQ,WAC7B,OAAO,YAAY,IAAI,CAACD,EAAY,YAAY,QAAQC,CAAS,CAAC,CAAC,EAGrE,MAAMC,EAAa,IAAI,gBACvB,IAAIC,EAEJ,MAAMC,EAAc,IAAK,CACvBD,IAAS,EACTD,EAAW,MAAMF,EAAW,MAAM,CACpC,EAMMK,EAAY,WAJA,IAAK,CACrBH,EAAW,MAAM,IAAI,aAAa,UAAW,cAAc,CAAC,CAC9D,EAEwCD,CAAS,EACjD,OAAAE,EAAU,IAAK,CACb,aAAaE,CAAS,CACxB,EAEAL,EAAW,iBAAiB,QAASI,CAAW,EAEhDF,EAAW,OAAO,iBAAiB,QAAS,IAAK,CAC/CF,EAAW,oBAAoB,QAASI,CAAW,EACnD,aAAaC,CAAS,CACxB,CAAC,EAEMH,EAAW,MACpB,CAEA,SAASI,EACPC,EACAC,EAA2B,CAE3B,OAAIA,GAAW,MAAQA,GAAW,EAAUD,EACvCA,EACER,EAAeQ,EAAQC,CAAO,EADjB,YAAY,QAAQA,CAAO,CAEjD,CAEM,aAAO,cAAc,CACjB,SAAmC,OAAO,OAAO,IAAI,EACrD,cAAgB,EACP,eAAiB,IAElC,MACEC,EACAC,EACAC,EACAJ,EACAK,EACAC,EACAC,EACAC,EAAwB,CAExB,MAAMC,EAAcD,GAAU,CAC5B,OAAQ,MACR,IAAK,GACL,QAASF,EACT,KAAM,OACN,OAAQ,OACR,KAAM,CACJ,aAAc,OACd,QAAS,CACP,UAAW,SAGf,QAAS,QAGLI,EAAUD,EAAY,KAO5B,GAAI,OAAON,GAAQ,SACjB,OAAAM,EAAY,OAASP,EACrBO,EAAY,IAAM,KAAK,WAAWN,EAAKI,EAAO,OAAO,EACrDE,EAAY,QAAU,CAAE,GAAGH,CAAc,EACzCG,EAAY,KAAOL,IAAS,OAAYf,EAAca,EAAQE,CAAI,EAAI,OACtEK,EAAY,OAASV,EAAaC,EAAQO,EAAO,SAAS,OAAO,EAEjEG,EAAQ,aAAeL,EAEvBI,EAAY,QAAUF,EAAO,SAAS,QAC/BE,EAGT,MAAME,EAASrB,EAAaa,CAAG,EAC/B,GAAI,CAACQ,EAAQ,MAAM,IAAI,MAAM,oCAAoCT,CAAM,EAAE,EAEzE,IAAIU,EAEJ,GAAIT,EAAI,MAAO,CACb,MAAMU,EAAWF,EAAS,QAC1B,IAAIG,EAAU,KAAK,SAASD,CAAQ,EAE/BC,IACHA,EAAUP,EAAO,QAAU,IAAI,IAAII,EAAQJ,EAAO,OAAO,EAAE,KAAO,IAAI,IAAII,CAAM,EAAE,KAElF,KAAK,iBAAgB,EACrB,KAAK,SAASE,CAAQ,EAAIC,EAC1B,KAAK,iBAGP,MAAMC,EAAS,IAAI,IAAID,CAAO,EAC9B,KAAK,kBAAkBC,EAAQZ,EAAI,KAAK,EACxCS,EAAWG,EAAO,IACpB,KAAO,CACL,IAAIC,EAAY,KAAK,SAASL,CAAM,EAC/BK,IACHA,EAAYT,EAAO,QAAU,IAAI,IAAII,EAAQJ,EAAO,OAAO,EAAE,KAAO,IAAI,IAAII,CAAM,EAAE,KAEhF,KAAK,eAAiB,KAAK,iBAC7B,KAAK,SAAW,OAAO,OAAO,IAAI,EAClC,KAAK,cAAgB,GAEvB,KAAK,SAASA,CAAM,EAAIK,EACxB,KAAK,iBAEPJ,EAAWI,CACb,CAEA,OAAAP,EAAY,OAASP,EACrBO,EAAY,IAAMG,EAClBH,EAAY,QAAUN,EAAI,QACtBZ,EAAiB,CAAE,GAAGe,CAAc,EAAIH,EAAI,OAAO,EACnD,CAAE,GAAGG,CAAc,EACvBG,EAAY,KAAOpB,EAAca,EAAQC,EAAI,MAAQC,CAAI,EACzDK,EAAY,OAASV,EAAaI,EAAI,QAAUH,EAAQO,EAAO,SAAS,OAAO,EAE/EG,EAAQ,aACNL,GAAiBF,EAAI,MAA0C,aAE7DA,EAAI,QACNM,EAAY,QAAUF,EAAO,SAAS,QAClC,CAAE,GAAGA,EAAO,QAAQ,QAAS,GAAGJ,EAAI,OAAO,EAC3CA,EAAI,QAERM,EAAY,QAAUF,EAAO,SAAS,QAGjCE,CACT,CAEQ,WAAWQ,EAAaC,EAAgB,CAC9C,GAAI,CAACD,EAAK,MAAM,IAAI,MAAM,8BAA8B,EAExD,IAAIL,EAAW,KAAK,SAASK,CAAG,EAChC,OAAIL,KAEeK,EAAI,WAAW,SAAS,GAAKA,EAAI,WAAW,UAAU,IAEvD,CAACA,EAAI,SAAS,GAAG,EACjCL,EAAWK,EAEXL,EAAWM,EAAU,IAAI,IAAID,EAAKC,CAAO,EAAE,KAAO,IAAI,IAAID,CAAG,EAAE,KAG7D,KAAK,eAAiB,KAAK,iBAC7B,KAAK,SAAW,OAAO,OAAO,IAAI,EAClC,KAAK,cAAgB,GAEvB,KAAK,SAASA,CAAG,EAAIL,EACrB,KAAK,gBAEEA,EACT,CAEQ,kBAAgB,CAClB,KAAK,eAAiB,KAAK,iBAC7B,KAAK,SAAW,OAAO,OAAO,IAAI,EAClC,KAAK,cAAgB,EAEzB,CAEQ,kBAAkBK,EAAUE,EAA8B,CAChE,UAAWC,KAAKD,EACd,GAAI,OAAO,UAAU,eAAe,KAAKA,EAAOC,CAAC,EAAG,CAClD,MAAMC,EAAIF,EAAMC,CAAC,EACjB,GAAIC,GAAK,KAAM,SACf,GAAI,MAAM,QAAQA,CAAC,EACjB,QAASC,EAAI,EAAGA,EAAID,EAAE,OAAQC,IAAKL,EAAI,aAAa,OAAOG,EAAG,OAAOC,EAAEC,CAAC,CAAC,CAAC,OAE1EL,EAAI,aAAa,IAAIG,EAAG,OAAOC,CAAC,CAAC,CAErC,CAEJ",
6
- "names": ["normalizeBody", "normalizeUrl", "mergeHeadersFast", "combineSignals", "userSignal", "timeoutMs", "controller", "cleanup", "onUserAbort", "timeoutId", "applyTimeout", "signal", "timeout", "method", "req", "body", "responseType", "defaultHeaders", "config", "pooled", "internalReq", "metaObj", "rawUrl", "finalUrl", "cacheKey", "baseUrl", "urlObj", "cachedUrl", "url", "baseURL", "query", "k", "v", "j"]
4
+ "sourcesContent": ["import type {\n HttpClientOptions,\n InternalRequest,\n RequestInterface,\n RequestBodyData,\n Method,\n ResponseType,\n} from \"@hyperttp/types\";\nimport { CacheManager } from \"hcacher\";\nimport { normalizeBody, normalizeUrl } from \"../utils/normalize.js\";\nimport { mergeHeadersFast } from \"../utils/response.js\";\n\n/**\n * @ru \u041C\u0435\u043D\u0435\u0434\u0436\u0435\u0440 \u043F\u0435\u0440\u0435\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u043C\u044B\u0445 AbortController \u0434\u043B\u044F \u0443\u0441\u0442\u0440\u0430\u043D\u0435\u043D\u0438\u044F \u0430\u043B\u043B\u043E\u043A\u0430\u0446\u0438\u0439 \u043F\u0440\u0438 \u0442\u0430\u0439\u043C-\u0430\u0443\u0442\u0430\u0445.\n * @en Reusable AbortController manager to eliminate allocations on timeouts.\n */\nclass AbortHandlerManager {\n public activeControllers: AbortController[] = [];\n\n constructor() {\n for (let i = 0; i < 64; i++) {\n this.activeControllers.push(new AbortController());\n }\n }\n\n /**\n * @ru \u0417\u0430\u0445\u0432\u0430\u0442\u044B\u0432\u0430\u0435\u0442 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u043B\u0435\u0440 \u0438\u0437 \u043F\u0443\u043B\u0430, \u043D\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442 \u0442\u0430\u0439\u043C-\u0430\u0443\u0442 \u0438 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0439 \u0441\u0438\u0433\u043D\u0430\u043B.\n * @en Acquires a controller from the pool, sets up timeout and user signal.\n * @param userSignal - Optional external abort signal.\n * @param timeoutMs - Timeout in milliseconds.\n * @param meta - Metadata object receiving cleanup function.\n * @returns AbortSignal bound to the timeout and user signal.\n */\n public acquire(userSignal: AbortSignal | undefined, timeoutMs: number, meta: any): AbortSignal {\n const controller = this.activeControllers.pop() ?? new AbortController();\n\n let cleaned = false;\n const cleanup = () => {\n if (cleaned) return;\n cleaned = true;\n\n if (userSignal) {\n userSignal.removeEventListener(\"abort\", onUserAbort);\n }\n clearTimeout(timeoutId);\n\n this.activeControllers.push(controller);\n };\n\n const timeoutId = setTimeout(() => {\n controller.abort(new DOMException(\"Timeout\", \"TimeoutError\"));\n cleanup();\n }, timeoutMs);\n\n const onUserAbort = () => {\n controller.abort(userSignal?.reason);\n cleanup();\n };\n\n if (userSignal) {\n userSignal.addEventListener(\"abort\", onUserAbort);\n }\n\n meta.cleanupSignal = cleanup;\n\n return controller.signal;\n }\n}\n\nconst abortManager = new AbortHandlerManager();\n\n/**\n * @ru \u041F\u0440\u0438\u043C\u0435\u043D\u044F\u0435\u0442 \u0442\u0430\u0439\u043C-\u0430\u0443\u0442 \u043A \u0441\u0438\u0433\u043D\u0430\u043B\u0443 \u043E\u0442\u043C\u0435\u043D\u044B \u0447\u0435\u0440\u0435\u0437 \u043F\u0443\u043B \u043F\u0435\u0440\u0435\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u043C\u044B\u0445 \u043A\u043E\u043D\u0442\u0440\u043E\u043B\u043B\u0435\u0440\u043E\u0432.\n * @en Applies a timeout to the abort signal via a pool of reusable controllers.\n * @param signal - Optional external abort signal.\n * @param timeout - Timeout in milliseconds (skip if null/<=0).\n * @param meta - Metadata object receiving cleanup function.\n * @returns New abort signal with timeout, or the original signal.\n */\nfunction applyTimeout(\n signal: AbortSignal | undefined,\n timeout: number | undefined,\n meta: any,\n): AbortSignal | undefined {\n if (timeout == null || timeout <= 0) return signal;\n return abortManager.acquire(signal, timeout, meta);\n}\n\n/**\n * @ru \u0421\u0442\u0440\u043E\u0438\u0442\u0435\u043B\u044C \u0432\u043D\u0443\u0442\u0440\u0435\u043D\u043D\u0438\u0445 \u0437\u0430\u043F\u0440\u043E\u0441\u043E\u0432 \u0441 \u043A\u044D\u0448\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435\u043C URL \u0438 \u043F\u0443\u043B\u043E\u043C \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432.\n * @en Internal request builder with URL caching and object pooling.\n */\nexport class RequestBuilder {\n private readonly urlCache = new CacheManager<string>({ maxSize: 512, ttl: 60_000 });\n\n /**\n * @ru \u0421\u043E\u0431\u0438\u0440\u0430\u0435\u0442 InternalRequest \u0438\u0437 \u043F\u0443\u0431\u043B\u0438\u0447\u043D\u043E\u0433\u043E API-\u0432\u044B\u0437\u043E\u0432\u0430, \u043F\u0435\u0440\u0435\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u044F \u043F\u0443\u043B\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u043E\u0431\u044A\u0435\u043A\u0442.\n * @en Builds an InternalRequest from a public API call, reusing a pooled object.\n * @param method - HTTP method.\n * @param req - URL string or RequestInterface object.\n * @param body - Optional request body.\n * @param signal - Optional abort signal.\n * @param responseType - Response type hint (\"stream\" or undefined).\n * @param defaultHeaders - Default headers to apply.\n * @param config - Client configuration.\n * @param pooled - Optional pre-allocated InternalRequest to reuse.\n * @returns The built InternalRequest.\n */\n build(\n method: Method,\n req: RequestInterface | string,\n body: RequestBodyData | undefined,\n signal: AbortSignal | undefined,\n responseType: \"stream\" | undefined,\n defaultHeaders: Record<string, string | string[]>,\n config: HttpClientOptions,\n pooled?: InternalRequest,\n ): InternalRequest {\n const internalReq = pooled ?? {\n method: \"GET\" as Method,\n url: \"\",\n headers: defaultHeaders,\n body: undefined,\n signal: undefined,\n meta: {\n responseType: undefined as ResponseType | undefined,\n timings: {\n networkMs: undefined as number | undefined,\n },\n },\n stealth: undefined,\n };\n\n const metaObj = internalReq.meta as {\n responseType: ResponseType | undefined;\n timings: {\n networkMs: number | undefined;\n };\n cleanupSignal?: () => void;\n };\n\n if (typeof req === \"string\") {\n internalReq.method = method;\n internalReq.url = this.resolveUrl(req, config.baseURL);\n\n if (body !== undefined) {\n internalReq.headers = Object.create(null);\n for (const k in defaultHeaders) {\n internalReq.headers[k] = defaultHeaders[k]!;\n }\n } else {\n internalReq.headers = defaultHeaders;\n }\n\n internalReq.body = body !== undefined ? normalizeBody(method, body) : undefined;\n internalReq.signal = applyTimeout(signal, config.network?.timeout, metaObj);\n metaObj.responseType = responseType;\n internalReq.stealth = config.network?.stealth;\n return internalReq;\n }\n\n const rawUrl = normalizeUrl(req);\n if (!rawUrl) throw new Error(`[HyperCore] URL is undefined for ${method}`);\n\n let finalUrl: string;\n\n if (req.query) {\n const cacheKey = rawUrl + \"_base\";\n let baseUrl = this.urlCache.get(cacheKey);\n\n if (!baseUrl) {\n baseUrl = config.baseURL ? new URL(rawUrl, config.baseURL).href : new URL(rawUrl).href;\n this.urlCache.set(cacheKey, baseUrl);\n }\n\n const urlObj = new URL(baseUrl);\n this.appendQueryParams(urlObj, req.query);\n finalUrl = urlObj.href;\n } else {\n let cachedUrl = this.urlCache.get(rawUrl);\n if (!cachedUrl) {\n cachedUrl = config.baseURL ? new URL(rawUrl, config.baseURL).href : new URL(rawUrl).href;\n this.urlCache.set(rawUrl, cachedUrl);\n }\n finalUrl = cachedUrl;\n }\n\n internalReq.method = method;\n internalReq.url = finalUrl;\n\n if (req.headers) {\n const targetHeaders = Object.create(null);\n for (const k in defaultHeaders) {\n targetHeaders[k] = defaultHeaders[k]!;\n }\n internalReq.headers = mergeHeadersFast(targetHeaders, req.headers);\n } else {\n internalReq.headers = defaultHeaders;\n }\n\n internalReq.body = normalizeBody(method, req.body ?? body);\n internalReq.signal = applyTimeout(req.signal ?? signal, config.network?.timeout, metaObj);\n\n metaObj.responseType =\n responseType ?? (req.meta as { responseType?: ResponseType })?.responseType;\n\n if (req.stealth) {\n if (config.network?.stealth) {\n const nextStealth = Object.create(null);\n for (const k in config.network.stealth) {\n nextStealth[k] = (config.network.stealth as any)[k];\n }\n for (const k in req.stealth) {\n nextStealth[k] = (req.stealth as any)[k];\n }\n internalReq.stealth = nextStealth;\n } else {\n internalReq.stealth = req.stealth;\n }\n } else {\n internalReq.stealth = config.network?.stealth;\n }\n\n return internalReq;\n }\n\n /**\n * @ru \u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u0442 URL \u043E\u0442\u043D\u043E\u0441\u0438\u0442\u0435\u043B\u044C\u043D\u043E baseURL \u0441 \u043A\u044D\u0448\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435\u043C \u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0430.\n * @en Resolves a URL against baseURL with result caching.\n * @param url - URL to resolve (absolute or relative).\n * @param baseURL - Optional base URL.\n * @returns The resolved absolute URL.\n */\n public resolveUrl(url: string, baseURL?: string): string {\n if (!url) throw new Error(\"[HyperCore] URL is undefined\");\n\n let finalUrl = this.urlCache.get(url);\n if (finalUrl) return finalUrl;\n\n const isAbsolute = url.startsWith(\"http://\") || url.startsWith(\"https://\");\n if (isAbsolute && !url.includes(\"?\")) {\n finalUrl = url;\n } else {\n finalUrl = baseURL ? new URL(url, baseURL).href : new URL(url).href;\n }\n\n this.urlCache.set(url, finalUrl);\n return finalUrl;\n }\n\n private appendQueryParams(url: URL, query: Record<string, unknown>): void {\n for (const k in query) {\n if (Object.prototype.hasOwnProperty.call(query, k)) {\n const v = query[k];\n if (v == null) continue;\n if (Array.isArray(v)) {\n for (let j = 0; j < v.length; j++) url.searchParams.append(k, String(v[j]));\n } else {\n url.searchParams.set(k, String(v));\n }\n }\n }\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["CacheManager", "normalizeBody", "normalizeUrl", "mergeHeadersFast", "AbortHandlerManager", "i", "userSignal", "timeoutMs", "meta", "controller", "cleaned", "cleanup", "onUserAbort", "timeoutId", "abortManager", "applyTimeout", "signal", "timeout", "method", "req", "body", "responseType", "defaultHeaders", "config", "pooled", "internalReq", "metaObj", "k", "rawUrl", "finalUrl", "cacheKey", "baseUrl", "urlObj", "cachedUrl", "targetHeaders", "nextStealth", "url", "baseURL", "query", "v", "j"]
7
7
  }
@@ -1,3 +1,7 @@
1
1
  import type { HttpClientOptions } from "@hyperttp/types";
2
+ /**
3
+ * @ru Конфигурация по умолчанию для HTTP-клиента Hyperttp.
4
+ * @en Default configuration for the Hyperttp HTTP client.
5
+ */
2
6
  export declare const defaultConfig: HttpClientOptions;
3
7
  //# sourceMappingURL=defaultConfig.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"defaultConfig.d.ts","sourceRoot":"","sources":["../src/defaultConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,eAAO,MAAM,aAAa,EAAE,iBAiB3B,CAAC"}
1
+ {"version":3,"file":"defaultConfig.d.ts","sourceRoot":"","sources":["../src/defaultConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,iBAiB3B,CAAC"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/defaultConfig.ts"],
4
- "sourcesContent": ["import type { HttpClientOptions } from \"@hyperttp/types\";\n\nexport const defaultConfig: HttpClientOptions = {\n network: {\n timeout: 30000,\n maxConcurrent: 128,\n pipelining: 0,\n keepAliveTimeout: 5000,\n followRedirects: true,\n maxRedirects: 5,\n rejectUnauthorized: true,\n },\n retry: {\n maxRetries: 0,\n baseDelay: 100,\n maxDelay: 5000,\n jitter: true,\n },\n verbose: false,\n};\n"],
5
- "mappings": "aAEO,aAAM,cAAmC,CAC9C,QAAS,CACP,QAAS,IACT,cAAe,IACf,WAAY,EACZ,iBAAkB,IAClB,gBAAiB,GACjB,aAAc,EACd,mBAAoB,IAEtB,MAAO,CACL,WAAY,EACZ,UAAW,IACX,SAAU,IACV,OAAQ,IAEV,QAAS",
4
+ "sourcesContent": ["import type { HttpClientOptions } from \"@hyperttp/types\";\n\n/**\n * @ru \u041A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044F \u043F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E \u0434\u043B\u044F HTTP-\u043A\u043B\u0438\u0435\u043D\u0442\u0430 Hyperttp.\n * @en Default configuration for the Hyperttp HTTP client.\n */\nexport const defaultConfig: HttpClientOptions = {\n network: {\n timeout: 30000,\n maxConcurrent: 128,\n pipelining: 0,\n keepAliveTimeout: 5000,\n followRedirects: true,\n maxRedirects: 5,\n rejectUnauthorized: true,\n },\n retry: {\n maxRetries: 0,\n baseDelay: 100,\n maxDelay: 5000,\n jitter: true,\n },\n verbose: false,\n};\n"],
5
+ "mappings": "aAMO,aAAM,cAAmC,CAC9C,QAAS,CACP,QAAS,IACT,cAAe,IACf,WAAY,EACZ,iBAAkB,IAClB,gBAAiB,GACjB,aAAc,EACd,mBAAoB,IAEtB,MAAO,CACL,WAAY,EACZ,UAAW,IACX,SAAU,IACV,OAAQ,IAEV,QAAS",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperttp/core",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
4
4
  "description": "High-performance, extensible HTTP client for Node.js, Bun, Deno and Browser",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -30,9 +30,10 @@
30
30
  "url": "git+https://github.com/IT-IF-OR/hyperttp-core.git"
31
31
  },
32
32
  "peerDependencies": {
33
- "@hyperttp/types": "^0.2.4",
34
- "@hyperttp/transport-bun": "^0.2.3",
35
- "@hyperttp/transport-undici": "^0.2.3"
33
+ "@hyperttp/types": "^0.2.5",
34
+ "@hyperttp/transport-bun": "^0.2.4",
35
+ "@hyperttp/transport-undici": "^0.2.4",
36
+ "hcacher": "^0.1.0"
36
37
  },
37
38
  "peerDependenciesMeta": {
38
39
  "@hyperttp/types": {
@@ -1 +1 @@
1
- {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/transports/browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EAElB,MAAM,iBAAiB,CAAC;AAEzB;;;GAGG;AACH,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;IAC/D;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAaD;;;;;GAKG;AACH,qBAAa,gBAAiB,YAAW,cAAc;IASlC,MAAM,EAAE,sBAAsB;IARjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IAEtC;;;;OAIG;gBACgB,MAAM,EAAE,sBAAsB;IAiBjD;;;;;OAKG;IACU,OAAO,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA8DxE"}
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/transports/browser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EAElB,MAAM,iBAAiB,CAAC;AAEzB;;;GAGG;AACH,MAAM,WAAW,sBAAuB,SAAQ,iBAAiB;IAC/D;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAaD;;;;;GAKG;AACH,qBAAa,gBAAiB,YAAW,cAAc;IASlC,MAAM,EAAE,sBAAsB;IARjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IAEtC;;;;OAIG;IACH,YAAmB,MAAM,EAAE,sBAAsB,EAehD;IAED;;;;;OAKG;IACU,OAAO,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA6DtE;CACF"}
@@ -2,6 +2,6 @@
2
2
  "version": 3,
3
3
  "sources": ["../../src/transports/browser.ts"],
4
4
  "sourcesContent": ["import type {\n HttpClientOptions,\n HyperTransport,\n TransportRequest,\n TransportResponse,\n TransportResponsePayload,\n} from \"@hyperttp/types\";\n\n/**\n * @ru \u041A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044F \u0442\u0440\u0430\u043D\u0441\u043F\u043E\u0440\u0442\u0430 \u0434\u043B\u044F \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430.\n * @en Browser transport configuration.\n */\nexport interface BrowserTransportConfig extends HttpClientOptions {\n /**\n * @ru \u0411\u0430\u0437\u043E\u0432\u044B\u0439 URL \u0434\u043B\u044F \u043E\u0442\u043D\u043E\u0441\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0445 \u043F\u0443\u0442\u0435\u0439. \u041F\u043E \u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E \u2014 window.location.origin.\n * @en Base URL for relative paths. Defaults to window.location.origin.\n */\n baseUrl?: string;\n}\n\n/**\n * @ru \u0418\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0434\u043B\u044F \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0433\u043E \u0434\u043E\u0441\u0442\u0443\u043F\u0430 \u043A \u043C\u0435\u0442\u0430-\u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u044E \u0441\u0431\u043E\u0440\u0449\u0438\u043A\u043E\u0432 (Vite, Webpack \u0438 \u0434\u0440.).\n * @en Interface for safe access to bundler meta-environment (Vite, Webpack, etc.).\n */\ninterface ImportMetaEnv {\n env?: {\n PROD?: boolean;\n [key: string]: unknown;\n };\n}\n\n/**\n * @ru \u0420\u0435\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u044F \u0442\u0440\u0430\u043D\u0441\u043F\u043E\u0440\u0442\u0430 \u0434\u043B\u044F \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430 \u0441 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u043C \u0433\u043B\u043E\u0431\u0430\u043B\u044C\u043D\u043E\u0433\u043E fetch API.\n * \u041E\u043F\u0442\u0438\u043C\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043D \u0434\u043B\u044F \u043C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u0440\u0430\u0437\u043C\u0435\u0440\u0430 \u0438 \u043C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0439 \u0441\u043E\u0432\u043C\u0435\u0441\u0442\u0438\u043C\u043E\u0441\u0442\u0438.\n * @en Browser transport implementation using the global fetch API.\n * Optimized for minimal size and maximum compatibility.\n */\nexport class BrowserTransport implements HyperTransport {\n private readonly isProduction: boolean;\n private readonly cleanBaseUrl: string;\n\n /**\n * @ru \u0421\u043E\u0437\u0434\u0430\u0451\u0442 \u044D\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440 BrowserTransport.\n * @en Creates a BrowserTransport instance.\n * @param config - Transport configuration.\n */\n constructor(public config: BrowserTransportConfig) {\n const isLocalhost =\n typeof window !== \"undefined\" &&\n [\"localhost\", \"127.0.0.1\", \"::1\"].includes(window.location.hostname);\n\n const hasProcess = typeof process !== \"undefined\" && process.env;\n const hasMeta = typeof import.meta !== \"undefined\";\n\n this.isProduction =\n !isLocalhost &&\n ((hasProcess && process.env.NODE_ENV === \"production\") ||\n (hasMeta && (import.meta as unknown as ImportMetaEnv).env?.PROD === true));\n\n const base = config.baseUrl ?? (typeof window !== \"undefined\" ? window.location.origin : \"\");\n this.cleanBaseUrl = base.endsWith(\"/\") ? base.slice(0, -1) : base;\n }\n\n /**\n * @ru \u0412\u044B\u043F\u043E\u043B\u043D\u044F\u0435\u0442 HTTP-\u0437\u0430\u043F\u0440\u043E\u0441 \u0447\u0435\u0440\u0435\u0437 \u0433\u043B\u043E\u0431\u0430\u043B\u044C\u043D\u044B\u0439 fetch.\n * @en Executes an HTTP request via the global fetch.\n * @param req - The normalized transport request.\n * @returns Promise resolving to the transport response.\n */\n public async execute(req: TransportRequest): Promise<TransportResponse> {\n const urlStr = req.url;\n\n const isAbsolute =\n urlStr.startsWith(\"http://\") || urlStr.startsWith(\"https://\") || urlStr.startsWith(\"//\");\n\n const fullUrl = isAbsolute\n ? urlStr\n : urlStr.charCodeAt(0) === 47\n ? this.cleanBaseUrl + urlStr\n : this.cleanBaseUrl + \"/\" + urlStr;\n\n if (this.isProduction && fullUrl.includes(\"//localhost\")) {\n throw new Error(\"Localhost URL detected in production environment\");\n }\n\n const finalHeaders: Record<string, string> = Object.create(null);\n if (req.headers) {\n if (req.headers instanceof Headers) {\n req.headers.forEach((value, key) => {\n finalHeaders[key.toLowerCase()] = value;\n });\n } else if (Array.isArray(req.headers)) {\n for (let i = 0; i < req.headers.length; i++) {\n const pair = req.headers[i] as unknown as [string, string] | undefined;\n if (pair && typeof pair[0] === \"string\") {\n finalHeaders[pair[0].toLowerCase()] = String(pair[1]);\n }\n }\n } else {\n const src = req.headers as Record<string, unknown>;\n for (const key in src) {\n const value = src[key];\n if (value != null) {\n finalHeaders[key.toLowerCase()] = Array.isArray(value)\n ? value.join(\", \")\n : String(value);\n }\n }\n }\n }\n\n const res = await globalThis.fetch(fullUrl, {\n method: req.method,\n headers: finalHeaders as HeadersInit,\n body: req.body as BodyInit | null,\n signal: req.signal,\n });\n\n const resHeaders: Record<string, string> = Object.create(null);\n res.headers.forEach((value, key) => {\n resHeaders[key] = value;\n });\n\n return {\n status: res.status,\n url: res.url,\n body: res.body as unknown as TransportResponsePayload,\n headers: resHeaders,\n _raw: res,\n } as TransportResponse;\n }\n}\n"],
5
- "mappings": "aAqCM,aAAO,gBAAgB,CASR,OARF,aACA,aAOjB,YAAmBA,EAA8B,CAA9B,KAAA,OAAAA,EACjB,MAAMC,EACJ,OAAO,OAAW,KAClB,CAAC,YAAa,YAAa,KAAK,EAAE,SAAS,OAAO,SAAS,QAAQ,EAE/DC,EAAa,OAAO,QAAY,KAAe,QAAQ,IACvDC,EAAU,OAAO,YAAgB,IAEvC,KAAK,aACH,CAACF,IACCC,GAAc,IACbC,GAAY,YAAyC,KAAK,OAAS,IAExE,MAAMC,EAAOJ,EAAO,UAAY,OAAO,OAAW,IAAc,OAAO,SAAS,OAAS,IACzF,KAAK,aAAeI,EAAK,SAAS,GAAG,EAAIA,EAAK,MAAM,EAAG,EAAE,EAAIA,CAC/D,CAQO,MAAM,QAAQC,EAAqB,CACxC,MAAMC,EAASD,EAAI,IAKbE,EAFJD,EAAO,WAAW,SAAS,GAAKA,EAAO,WAAW,UAAU,GAAKA,EAAO,WAAW,IAAI,EAGrFA,EACAA,EAAO,WAAW,CAAC,IAAM,GACvB,KAAK,aAAeA,EACpB,KAAK,aAAe,IAAMA,EAEhC,GAAI,KAAK,cAAgBC,EAAQ,SAAS,aAAa,EACrD,MAAM,IAAI,MAAM,kDAAkD,EAGpE,MAAMC,EAAuC,OAAO,OAAO,IAAI,EAC/D,GAAIH,EAAI,QACN,GAAIA,EAAI,mBAAmB,QACzBA,EAAI,QAAQ,QAAQ,CAACI,EAAOC,IAAO,CACjCF,EAAaE,EAAI,YAAW,CAAE,EAAID,CACpC,CAAC,UACQ,MAAM,QAAQJ,EAAI,OAAO,EAClC,QAASM,EAAI,EAAGA,EAAIN,EAAI,QAAQ,OAAQM,IAAK,CAC3C,MAAMC,EAAOP,EAAI,QAAQM,CAAC,EACtBC,GAAQ,OAAOA,EAAK,CAAC,GAAM,WAC7BJ,EAAaI,EAAK,CAAC,EAAE,YAAW,CAAE,EAAI,OAAOA,EAAK,CAAC,CAAC,EAExD,KACK,CACL,MAAMC,EAAMR,EAAI,QAChB,UAAWK,KAAOG,EAAK,CACrB,MAAMJ,EAAQI,EAAIH,CAAG,EACjBD,GAAS,OACXD,EAAaE,EAAI,YAAW,CAAE,EAAI,MAAM,QAAQD,CAAK,EACjDA,EAAM,KAAK,IAAI,EACf,OAAOA,CAAK,EAEpB,CACF,CAGF,MAAMK,EAAM,MAAM,WAAW,MAAMP,EAAS,CAC1C,OAAQF,EAAI,OACZ,QAASG,EACT,KAAMH,EAAI,KACV,OAAQA,EAAI,OACb,EAEKU,EAAqC,OAAO,OAAO,IAAI,EAC7D,OAAAD,EAAI,QAAQ,QAAQ,CAACL,EAAOC,IAAO,CACjCK,EAAWL,CAAG,EAAID,CACpB,CAAC,EAEM,CACL,OAAQK,EAAI,OACZ,IAAKA,EAAI,IACT,KAAMA,EAAI,KACV,QAASC,EACT,KAAMD,EAEV",
5
+ "mappings": "aAqCM,aAAO,gBAAgB,CASR,OARF,aACA,aAOjB,YAAmBA,EAA8B,aAA9BA,EACjB,MAAMC,EACJ,OAAO,OAAW,KAClB,CAAC,YAAa,YAAa,KAAK,EAAE,SAAS,OAAO,SAAS,QAAQ,EAE/DC,EAAa,OAAO,QAAY,KAAe,QAAQ,IACvDC,EAAU,OAAO,YAAgB,IAEvC,KAAK,aACH,CAACF,IACCC,GAAc,IACbC,GAAY,YAAyC,KAAK,OAAS,IAExE,MAAMC,EAAOJ,EAAO,UAAY,OAAO,OAAW,IAAc,OAAO,SAAS,OAAS,IACzF,KAAK,aAAeI,EAAK,SAAS,GAAG,EAAIA,EAAK,MAAM,EAAG,EAAE,EAAIA,CAC/D,CAQO,MAAM,QAAQC,EAAqB,CACxC,MAAMC,EAASD,EAAI,IAKbE,EAFJD,EAAO,WAAW,SAAS,GAAKA,EAAO,WAAW,UAAU,GAAKA,EAAO,WAAW,IAAI,EAGrFA,EACAA,EAAO,WAAW,CAAC,IAAM,GACvB,KAAK,aAAeA,EACpB,KAAK,aAAe,IAAMA,EAEhC,GAAI,KAAK,cAAgBC,EAAQ,SAAS,aAAa,EACrD,MAAM,IAAI,MAAM,kDAAkD,EAGpE,MAAMC,EAAuC,OAAO,OAAO,IAAI,EAC/D,GAAIH,EAAI,QACN,GAAIA,EAAI,mBAAmB,QACzBA,EAAI,QAAQ,QAAQ,CAACI,EAAOC,IAAO,CACjCF,EAAaE,EAAI,YAAW,CAAE,EAAID,CACpC,CAAC,UACQ,MAAM,QAAQJ,EAAI,OAAO,EAClC,QAASM,EAAI,EAAGA,EAAIN,EAAI,QAAQ,OAAQM,IAAK,CAC3C,MAAMC,EAAOP,EAAI,QAAQM,CAAC,EACtBC,GAAQ,OAAOA,EAAK,CAAC,GAAM,WAC7BJ,EAAaI,EAAK,CAAC,EAAE,YAAW,CAAE,EAAI,OAAOA,EAAK,CAAC,CAAC,EAExD,KACK,CACL,MAAMC,EAAMR,EAAI,QAChB,UAAWK,KAAOG,EAAK,CACrB,MAAMJ,EAAQI,EAAIH,CAAG,EACjBD,GAAS,OACXD,EAAaE,EAAI,YAAW,CAAE,EAAI,MAAM,QAAQD,CAAK,EACjDA,EAAM,KAAK,IAAI,EACf,OAAOA,CAAK,EAEpB,CACF,CAGF,MAAMK,EAAM,MAAM,WAAW,MAAMP,EAAS,CAC1C,OAAQF,EAAI,OACZ,QAASG,EACT,KAAMH,EAAI,KACV,OAAQA,EAAI,OACb,EAEKU,EAAqC,OAAO,OAAO,IAAI,EAC7D,OAAAD,EAAI,QAAQ,QAAQ,CAACL,EAAOC,IAAO,CACjCK,EAAWL,CAAG,EAAID,CACpB,CAAC,EAEM,CACL,OAAQK,EAAI,OACZ,IAAKA,EAAI,IACT,KAAMA,EAAI,KACV,QAASC,EACT,KAAMD,EAEV",
6
6
  "names": ["config", "isLocalhost", "hasProcess", "hasMeta", "base", "req", "urlStr", "fullUrl", "finalHeaders", "value", "key", "i", "pair", "src", "res", "resHeaders"]
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/transports/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEzE;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAyB1D;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,OAK1B,CAAC;AAiLL;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CA+BzF;AAED;;;;;GAKG;AACH,qBAAa,gBAAgB;IAC3B;;;OAGG;IACI,SAAS,EAAE,cAAc,GAAG,IAAI,CAAQ;IAE/C;;;OAGG;IACH,OAAO,CAAC,OAAO,CAAwC;IAEvD;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAoB;IAElC;;;;;OAKG;gBACS,MAAM,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,cAAc;IAY9D;;;;OAIG;IACI,OAAO,IAAI,cAAc,GAAG,IAAI;IAIvC;;;;;;OAMG;IACI,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC;IAYxC;;;;OAIG;IACI,GAAG,IAAI,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC;IAItD;;;;OAIG;IACI,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI;IAajD;;;;;;;OAOG;IACU,OAAO,CAAC,QAAQ,UAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAuBrD"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/transports/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEzE;;;GAGG;AACH,MAAM,MAAM,OAAO,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAyB1D;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,OAK1B,CAAC;AAiLL;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,CA+BzF;AAED;;;;;GAKG;AACH,qBAAa,gBAAgB;IAC3B;;;OAGG;IACI,SAAS,EAAE,cAAc,GAAG,IAAI,CAAQ;IAE/C;;;OAGG;IACH,OAAO,CAAC,OAAO,CAAwC;IAEvD;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAoB;IAElC;;;;;OAKG;IACH,YAAY,MAAM,EAAE,iBAAiB,EAAE,MAAM,CAAC,EAAE,cAAc,EAU7D;IAED;;;;OAIG;IACI,OAAO,IAAI,cAAc,GAAG,IAAI,CAEtC;IAED;;;;;;OAMG;IACI,MAAM,IAAI,OAAO,CAAC,cAAc,CAAC,CAUvC;IAED;;;;OAIG;IACI,GAAG,IAAI,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAErD;IAED;;;;OAIG;IACI,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAWhD;IAED;;;;;;;OAOG;IACU,OAAO,CAAC,QAAQ,UAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAsBnD;CACF"}
@@ -24,6 +24,7 @@ export declare class NodeTransport implements HyperTransport {
24
24
  private readonly isProduction;
25
25
  private readonly cleanBaseUrl;
26
26
  private readonly agentCache;
27
+ private readonly trackedAgents;
27
28
  constructor(config: NodeTransportConfig);
28
29
  execute(req: TransportRequest): Promise<TransportResponse>;
29
30
  close(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/transports/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EAElB,MAAM,iBAAiB,CAAC;AAQzB;;;GAGG;AACH,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC5D;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAmUD;;;GAGG;AACH,qBAAa,aAAc,YAAW,cAAc;IAC3C,MAAM,EAAE,mBAAmB,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA+C;gBAE9D,MAAM,EAAE,mBAAmB;IAQ1B,OAAO,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAuH1D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOtB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAMtC"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/transports/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,iBAAiB,EACjB,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EAElB,MAAM,iBAAiB,CAAC;AASzB;;;GAGG;AACH,MAAM,WAAW,mBAAoB,SAAQ,iBAAiB;IAC5D;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAqUD;;;GAGG;AACH,qBAAa,aAAc,YAAW,cAAc;IAC3C,MAAM,EAAE,mBAAmB,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4E;IACvG,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAuC;IAErE,YAAY,MAAM,EAAE,mBAAmB,EAMtC;IAEY,OAAO,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA2HtE;IAEY,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAMlC;IAEY,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAMpC;CACF"}
@@ -1,2 +1,2 @@
1
- "use strict";import G from"node:http";import U from"node:https";import z from"node:net";import{Readable as R,Transform as D}from"node:stream";import O from"node:tls";import T from"node:zlib";const W={chrome:{"sec-ch-ua":'"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',"sec-ch-ua-mobile":"?0","sec-ch-ua-platform":'"Linux"',"sec-fetch-dest":"document","sec-fetch-mode":"navigate","sec-fetch-site":"none","sec-fetch-user":"?1","upgrade-insecure-requests":"1","accept-language":"en-US,en;q=0.9"},firefox:{"sec-fetch-dest":"document","sec-fetch-mode":"navigate","sec-fetch-site":"none","accept-language":"en-US,en;q=0.5","upgrade-insecure-requests":"1"}},B={chrome:"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",firefox:"Mozilla/5.0 (X11; Linux; rv:126.0) Gecko/20100101 Firefox/126.0",safari:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15",edge:"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0"};function K(t){if(!t)return"";switch(t){case"chrome":case"edge":return["TLS_AES_128_GCM_SHA256","TLS_AES_256_GCM_SHA384","TLS_CHACHA20_POLY1305_SHA256","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES128-GCM-SHA256"].join(":");case"firefox":return["TLS_AES_128_GCM_SHA256","TLS_CHACHA20_POLY1305_SHA256","TLS_AES_256_GCM_SHA384","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES128-GCM-SHA256"].join(":");case"safari":return["TLS_AES_256_GCM_SHA384","TLS_CHACHA20_POLY1305_SHA256","TLS_AES_128_GCM_SHA256","ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-RSA-AES256-GCM-SHA384"].join(":");default:return""}}function N(t,e){if(!e||!e.fingerprint)return t;const i=e.fingerprint,o=W[i];if(o)for(const r in o)t[r]===void 0&&(t[r]=o[r]);const n=t["user-agent"];if(n===void 0||n==="hyperttp/2.0"||n==="Hyperttp/2.0"){const r=B[i];r&&(t["user-agent"]=r)}return t}function j(t,e,i,o){const n=e?.fingerprint??"none",r=e?.fragment??"none",y=e?.http2===!0,C=`${t?"https":"http"}:${n}:${r}:${y?"h2":"1.1"}`;let d=i.get(C);if(d)return d;const h={keepAlive:!0,maxSockets:256};if(o!==void 0&&(h.rejectUnauthorized=o),t){if(h.ciphers=K(e?.fingerprint),r==="split"||y){const L=y?["h2","http/1.1"]:void 0;h.createConnection=(u,p)=>{let a=!1;const f=(l,g)=>{const S=z.connect(u);if(r==="split"){const m=S.write;let b=!0;S.write=function(E,_,x){if(b&&E instanceof Uint8Array&&E.length>5){b=!1,this.write=m;let w,H;typeof _=="function"?H=_:(w=_,H=x);const v=E.subarray(0,3),k=E.subarray(3),P=M=>{H?.(M)};try{m.call(this,v,w)}catch(M){return P(M),!1}return m.call(this,k,w,H)}return this.write=m,m.call(this,E,_,x)}}const c={...u,socket:S,ciphers:h.ciphers};l&&(c.ALPNProtocols=l);const s=O.connect(c);s.once("secureConnect",()=>{if(l&&s.alpnProtocol==="h2"&&!a){a=!0,s.destroy(),f(["http/1.1"],g);return}g(null,s)}),s.once("error",m=>g(m))};return f(L,p)}}d=new U.Agent(h)}else d=new G.Agent(h);return i.set(C,d),d}function $(t){return t.startsWith("http://")||t.startsWith("https://")}function F(t,e){if(!e)throw new Error("URL is empty");return $(e)?e:e.charCodeAt(0)===47?t+e:t+"/"+e}function X(t){const e=t.indexOf("://");if(e===-1)return!1;const i=e+3;let o=t.indexOf("/",i);o===-1&&(o=t.length);const n=t.slice(i,o);return n==="localhost"||n.startsWith("localhost:")}function I(t){const e=Object.create(null);if(!t)return e;if(t instanceof Headers)return t.forEach((o,n)=>{e[n.toLowerCase()]=o}),e;if(Array.isArray(t)){for(let o=0;o<t.length;o++){const n=t[o];!n||typeof n[0]!="string"||(e[n[0].toLowerCase()]=String(n[1]))}return e}const i=t;for(const o in i){const n=i[o];if(n==null)continue;const r=o.toLowerCase();if(Array.isArray(n)){e[r]=r==="cookie"?n.join("; "):n.join(", ");continue}e[r]=String(n)}return e}function V(t){let e=0;return new D({transform(i,o,n){if(e+=i.length,e>t){n(new Error(`[Hyperttp] Response size exceeded limit of ${t} bytes`));return}n(null,i)}})}export class NodeTransport{config;isProduction;cleanBaseUrl;agentCache=new Map;constructor(e){this.config=e,this.isProduction=!0;const i=e.baseUrl??"http://localhost:3000";this.cleanBaseUrl=i.endsWith("/")?i.slice(0,-1):i}async execute(e){const i=F(this.cleanBaseUrl,e.url);if(this.isProduction&&X(i))throw new Error("Localhost URL detected in production environment");let o=I(e.headers);o["accept-encoding"]===void 0&&(o["accept-encoding"]="gzip, deflate, br");const n=e.stealth??this.config.stealth??this.config.network?.stealth;n&&(o=N(o,n));const r=e.body,C=new URL(i).protocol==="https:",d=j(C,n,this.agentCache,this.config.network?.rejectUnauthorized);return new Promise((h,A)=>{const L={method:e.method,headers:o,agent:d,signal:e.signal};let u=!1;const p=(C?U:G).request(i,L,a=>{const f=Object.create(null);for(const c in a.headers){const s=a.headers[c];s!==void 0&&(f[c]=Array.isArray(s)?s.join(", "):s)}let l=a;const g=f["content-encoding"]?.toLowerCase();if(g==="gzip"){const c=T.createGunzip();c.on("error",s=>{a.destroy(s),u||A(s)}),l=a.pipe(c),delete f["content-encoding"],delete f["content-length"]}else if(g==="deflate"){const c=T.createInflate();c.on("error",s=>{a.destroy(s),u||A(s)}),l=a.pipe(c),delete f["content-encoding"],delete f["content-length"]}else if(g==="br"){const c=T.createBrotliDecompress();c.on("error",s=>{a.destroy(s),u||A(s)}),l=a.pipe(c),delete f["content-encoding"],delete f["content-length"]}const S=this.config.network?.maxResponseBytes;if(S!=null&&S>0){const c=V(S);c.on("error",s=>{a.destroy(s),u||A(s)}),l=l.pipe(c)}l.on("error",c=>{u||A(c)}),u=!0,h({status:a.statusCode??200,headers:f,url:i,body:R.toWeb(l)})});p.on("error",a=>{u||A(a)}),r!=null?typeof r=="string"||r instanceof Uint8Array||ArrayBuffer.isView(r)?(p.write(r),p.end()):r instanceof ArrayBuffer?(p.write(Buffer.from(r)),p.end()):typeof ReadableStream<"u"&&r instanceof ReadableStream?R.fromWeb(r).pipe(p):p.end():p.end()})}async close(){for(const e of this.agentCache.values())e.destroy();this.agentCache.clear()}async destroy(){for(const e of this.agentCache.values())e.destroy();this.agentCache.clear()}}
1
+ "use strict";import{CacheManager as D}from"hcacher";import G from"node:http";import U from"node:https";import O from"node:net";import{Readable as R,Transform as W}from"node:stream";import B from"node:tls";import T from"node:zlib";const K={chrome:{"sec-ch-ua":'"Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"',"sec-ch-ua-mobile":"?0","sec-ch-ua-platform":'"Linux"',"sec-fetch-dest":"document","sec-fetch-mode":"navigate","sec-fetch-site":"none","sec-fetch-user":"?1","upgrade-insecure-requests":"1","accept-language":"en-US,en;q=0.9"},firefox:{"sec-fetch-dest":"document","sec-fetch-mode":"navigate","sec-fetch-site":"none","accept-language":"en-US,en;q=0.5","upgrade-insecure-requests":"1"}},N={chrome:"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36",firefox:"Mozilla/5.0 (X11; Linux; rv:126.0) Gecko/20100101 Firefox/126.0",safari:"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15",edge:"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0"};function j(t){if(!t)return"";switch(t){case"chrome":case"edge":return["TLS_AES_128_GCM_SHA256","TLS_AES_256_GCM_SHA384","TLS_CHACHA20_POLY1305_SHA256","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES128-GCM-SHA256"].join(":");case"firefox":return["TLS_AES_128_GCM_SHA256","TLS_CHACHA20_POLY1305_SHA256","TLS_AES_256_GCM_SHA384","ECDHE-ECDSA-AES128-GCM-SHA256","ECDHE-RSA-AES128-GCM-SHA256"].join(":");case"safari":return["TLS_AES_256_GCM_SHA384","TLS_CHACHA20_POLY1305_SHA256","TLS_AES_128_GCM_SHA256","ECDHE-ECDSA-AES256-GCM-SHA384","ECDHE-RSA-AES256-GCM-SHA384"].join(":");default:return""}}function $(t,e){if(!e||!e.fingerprint)return t;const r=e.fingerprint,o=K[r];if(o)for(const i in o)t[i]===void 0&&(t[i]=o[i]);const n=t["user-agent"];if(n===void 0||n==="hyperttp/2.0"||n==="Hyperttp/2.0"){const i=N[r];i&&(t["user-agent"]=i)}return t}function F(t,e,r,o,n){const i=e?.fingerprint??"none",_=e?.fragment??"none",m=e?.http2===!0,y=`${t?"https":"http"}:${i}:${_}:${m?"h2":"1.1"}`;let p=r.get(y);if(p)return p;const f={keepAlive:!0,maxSockets:256};if(n!==void 0&&(f.rejectUnauthorized=n),t){if(f.ciphers=j(e?.fingerprint),_==="split"||m){const h=m?["h2","http/1.1"]:void 0;f.createConnection=(u,a)=>{let l=!1;const d=(A,g)=>{const s=O.connect(u);if(_==="split"){const S=s.write;let k=!0;s.write=function(E,H,x){if(k&&E instanceof Uint8Array&&E.length>5){k=!1,this.write=S;let w,L;typeof H=="function"?L=H:(w=H,L=x);const z=E.subarray(0,3),P=E.subarray(3),v=M=>{L?.(M)};try{S.call(this,z,w)}catch(M){return v(M),!1}return S.call(this,P,w,L)}return this.write=S,S.call(this,E,H,x)}}const c={...u,socket:s,ciphers:f.ciphers};A&&(c.ALPNProtocols=A);const C=B.connect(c);C.once("secureConnect",()=>{if(A&&C.alpnProtocol==="h2"&&!l){l=!0,C.destroy(),d(["http/1.1"],g);return}g(null,C)}),C.once("error",S=>g(S))};return d(h,a)}}p=new U.Agent(f)}else p=new G.Agent(f);return r.set(y,p),o.add(p),p}function X(t){return t.startsWith("http://")||t.startsWith("https://")}function I(t,e){if(!e)throw new Error("URL is empty");return X(e)?e:e.charCodeAt(0)===47?t+e:t+"/"+e}function V(t){const e=t.indexOf("://");if(e===-1)return!1;const r=e+3;let o=t.indexOf("/",r);o===-1&&(o=t.length);const n=t.slice(r,o);return n==="localhost"||n.startsWith("localhost:")}function Y(t){const e=Object.create(null);if(!t)return e;if(t instanceof Headers)return t.forEach((o,n)=>{e[n.toLowerCase()]=o}),e;if(Array.isArray(t)){for(let o=0;o<t.length;o++){const n=t[o];!n||typeof n[0]!="string"||(e[n[0].toLowerCase()]=String(n[1]))}return e}const r=t;for(const o in r){const n=r[o];if(n==null)continue;const i=o.toLowerCase();if(Array.isArray(n)){e[i]=i==="cookie"?n.join("; "):n.join(", ");continue}e[i]=String(n)}return e}function q(t){let e=0;return new W({transform(r,o,n){if(e+=r.length,e>t){n(new Error(`[Hyperttp] Response size exceeded limit of ${t} bytes`));return}n(null,r)}})}export class NodeTransport{config;isProduction;cleanBaseUrl;agentCache=new D({maxSize:32,ttl:6e4});trackedAgents=new Set;constructor(e){this.config=e,this.isProduction=!0;const r=e.baseUrl??"http://localhost:3000";this.cleanBaseUrl=r.endsWith("/")?r.slice(0,-1):r}async execute(e){const r=I(this.cleanBaseUrl,e.url);if(this.isProduction&&V(r))throw new Error("Localhost URL detected in production environment");let o=Y(e.headers);o["accept-encoding"]===void 0&&(o["accept-encoding"]="gzip, deflate, br");const n=e.stealth??this.config.stealth??this.config.network?.stealth;n&&(o=$(o,n));const i=e.body,m=new URL(r).protocol==="https:",y=F(m,n,this.agentCache,this.trackedAgents,this.config.network?.rejectUnauthorized);return new Promise((p,f)=>{const b={method:e.method,headers:o,agent:y,signal:e.signal};let h=!1;const u=(m?U:G).request(r,b,a=>{const l=Object.create(null);for(const s in a.headers){const c=a.headers[s];c!==void 0&&(l[s]=Array.isArray(c)?c.join(", "):c)}let d=a;const A=l["content-encoding"]?.toLowerCase();if(A==="gzip"){const s=T.createGunzip();s.on("error",c=>{a.destroy(c),h||f(c)}),d=a.pipe(s),delete l["content-encoding"],delete l["content-length"]}else if(A==="deflate"){const s=T.createInflate();s.on("error",c=>{a.destroy(c),h||f(c)}),d=a.pipe(s),delete l["content-encoding"],delete l["content-length"]}else if(A==="br"){const s=T.createBrotliDecompress();s.on("error",c=>{a.destroy(c),h||f(c)}),d=a.pipe(s),delete l["content-encoding"],delete l["content-length"]}const g=this.config.network?.maxResponseBytes;if(g!=null&&g>0){const s=q(g);s.on("error",c=>{a.destroy(c),h||f(c)}),d=d.pipe(s)}d.on("error",s=>{h||f(s)}),h=!0,p({status:a.statusCode??200,headers:l,url:r,body:R.toWeb(d)})});u.on("error",a=>{h||f(a)}),i!=null?typeof i=="string"||i instanceof Uint8Array||ArrayBuffer.isView(i)?(u.write(i),u.end()):i instanceof ArrayBuffer?(u.write(Buffer.from(i)),u.end()):typeof ReadableStream<"u"&&i instanceof ReadableStream?R.fromWeb(i).pipe(u):u.end():u.end()})}async close(){for(const e of this.trackedAgents)e.destroy();this.trackedAgents.clear(),this.agentCache.clear()}async destroy(){for(const e of this.trackedAgents)e.destroy();this.trackedAgents.clear(),this.agentCache.clear()}}
2
2
  //# sourceMappingURL=node.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/transports/node.ts"],
4
- "sourcesContent": ["import type {\n Fingerprint,\n HttpClientOptions,\n HyperTransport,\n StealthOptions,\n TransportRequest,\n TransportResponse,\n TransportResponsePayload,\n} from \"@hyperttp/types\";\nimport http from \"node:http\";\nimport https from \"node:https\";\nimport net from \"node:net\";\nimport { Readable, Transform } from \"node:stream\";\nimport tls from \"node:tls\";\nimport zlib from \"node:zlib\";\n\n/**\n * @ru \u041A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044F \u0442\u0440\u0430\u043D\u0441\u043F\u043E\u0440\u0442\u0430 \u0434\u043B\u044F Node.js \u0441 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u043C \u043D\u0430\u0442\u0438\u0432\u043D\u044B\u0445 http/https \u043C\u043E\u0434\u0443\u043B\u0435\u0439.\n * @en Node.js transport configuration using native http/https modules.\n */\nexport interface NodeTransportConfig extends HttpClientOptions {\n /**\n * @ru \u0411\u0430\u0437\u043E\u0432\u044B\u0439 URL \u0434\u043B\u044F \u043E\u0442\u043D\u043E\u0441\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0445 \u043F\u0443\u0442\u0435\u0439.\n * @en Base URL for relative paths.\n */\n baseUrl?: string;\n /**\n * @ru \u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 stealth-\u043C\u0430\u0441\u043A\u0438\u0440\u043E\u0432\u043A\u0438 \u043D\u0430 \u0443\u0440\u043E\u0432\u043D\u0435 \u0442\u0440\u0430\u043D\u0441\u043F\u043E\u0440\u0442\u0430.\n * @en Stealth masking settings at the transport level.\n */\n stealth?: StealthOptions;\n}\n\n/**\n * @ru \u0421\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438\u0435 \u043F\u0440\u0435\u0441\u0435\u0442\u044B \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043D\u044B\u0445 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u043E\u0432 \u0434\u043B\u044F \u043C\u0430\u0441\u043A\u0438\u0440\u043E\u0432\u043A\u0438 \u043F\u043E\u0434 \u0440\u0435\u0430\u043B\u044C\u043D\u044B\u0445 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0435\u0439.\n * \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u044E\u0442\u0441\u044F stealth-\u0440\u0435\u0436\u0438\u043C\u043E\u043C \u0434\u043B\u044F \u043E\u0431\u0445\u043E\u0434\u0430 fingerprint-\u0437\u0430\u0449\u0438\u0442.\n * @en Static presets of browser headers for masking as real users.\n * Used by stealth mode to bypass fingerprint protections.\n */\nconst STEALTH_HEADER_PRESETS: Record<string, Record<string, string>> = {\n chrome: {\n \"sec-ch-ua\": '\"Not/A)Brand\";v=\"8\", \"Chromium\";v=\"126\", \"Google Chrome\";v=\"126\"',\n \"sec-ch-ua-mobile\": \"?0\",\n \"sec-ch-ua-platform\": '\"Linux\"',\n \"sec-fetch-dest\": \"document\",\n \"sec-fetch-mode\": \"navigate\",\n \"sec-fetch-site\": \"none\",\n \"sec-fetch-user\": \"?1\",\n \"upgrade-insecure-requests\": \"1\",\n \"accept-language\": \"en-US,en;q=0.9\",\n },\n firefox: {\n \"sec-fetch-dest\": \"document\",\n \"sec-fetch-mode\": \"navigate\",\n \"sec-fetch-site\": \"none\",\n \"accept-language\": \"en-US,en;q=0.5\",\n \"upgrade-insecure-requests\": \"1\",\n },\n};\n\n/**\n * @ru \u041F\u0440\u0435\u0441\u0435\u0442\u044B User-Agent, \u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0435 TLS-\u043E\u0442\u043F\u0435\u0447\u0430\u0442\u043A\u0430\u043C (JA3/JA4).\n * @en User-Agent presets matching the TLS fingerprints (JA3/JA4).\n */\nconst STEALTH_UA_PRESETS: Record<string, string> = {\n chrome:\n \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36\",\n firefox: \"Mozilla/5.0 (X11; Linux; rv:126.0) Gecko/20100101 Firefox/126.0\",\n safari:\n \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15\",\n edge: \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0\",\n};\n\n/**\n * @ru \u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0442\u0440\u043E\u043A\u0443 \u0448\u0438\u0444\u0440\u043E\u0432 TLS \u0434\u043B\u044F \u0443\u043A\u0430\u0437\u0430\u043D\u043D\u043E\u0433\u043E \u043F\u0440\u043E\u0444\u0438\u043B\u044F \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430.\n * @en Returns the TLS cipher suite string for the specified browser profile.\n * @param fingerprint - Browser fingerprint profile.\n * @returns Colon-separated cipher suite string, or empty string if not found.\n */\nfunction getCiphersForProfile(fingerprint: Fingerprint | undefined): string {\n if (!fingerprint) return \"\";\n\n switch (fingerprint) {\n case \"chrome\":\n case \"edge\":\n return [\n \"TLS_AES_128_GCM_SHA256\",\n \"TLS_AES_256_GCM_SHA384\",\n \"TLS_CHACHA20_POLY1305_SHA256\",\n \"ECDHE-ECDSA-AES128-GCM-SHA256\",\n \"ECDHE-RSA-AES128-GCM-SHA256\",\n ].join(\":\");\n\n case \"firefox\":\n return [\n \"TLS_AES_128_GCM_SHA256\",\n \"TLS_CHACHA20_POLY1305_SHA256\",\n \"TLS_AES_256_GCM_SHA384\",\n \"ECDHE-ECDSA-AES128-GCM-SHA256\",\n \"ECDHE-RSA-AES128-GCM-SHA256\",\n ].join(\":\");\n\n case \"safari\":\n return [\n \"TLS_AES_256_GCM_SHA384\",\n \"TLS_CHACHA20_POLY1305_SHA256\",\n \"TLS_AES_128_GCM_SHA256\",\n \"ECDHE-ECDSA-AES256-GCM-SHA384\",\n \"ECDHE-RSA-AES256-GCM-SHA384\",\n ].join(\":\");\n\n default:\n return \"\";\n }\n}\n\n/**\n * @ru \u0411\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E \u043F\u0440\u0438\u043C\u0435\u043D\u044F\u0435\u0442 \u0441\u0442\u0435\u043B\u0441-\u043F\u0440\u0435\u0441\u0435\u0442\u044B, \u043E\u0442\u0434\u0430\u0432\u0430\u044F \u0430\u0431\u0441\u043E\u043B\u044E\u0442\u043D\u044B\u0439 \u043F\u0440\u0438\u043E\u0440\u0438\u0442\u0435\u0442 \u0440\u0443\u0447\u043D\u044B\u043C \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430\u043C.\n * @en Safely applies stealth presets, giving absolute priority to manual headers.\n * @param headers - The headers object to modify.\n * @param stealth - Stealth configuration options.\n * @returns The modified headers object.\n */\nfunction applyStealthHeaders(\n headers: Record<string, string>,\n stealth: StealthOptions,\n): Record<string, string> {\n if (!stealth || !stealth.fingerprint) return headers;\n\n const presetName = stealth.fingerprint;\n const presetHeaders = STEALTH_HEADER_PRESETS[presetName];\n\n if (presetHeaders) {\n for (const key in presetHeaders) {\n if (headers[key] === undefined) {\n headers[key] = presetHeaders[key]!;\n }\n }\n }\n\n const currentUA = headers[\"user-agent\"];\n if (currentUA === undefined || currentUA === \"hyperttp/2.0\" || currentUA === \"Hyperttp/2.0\") {\n const browserUA = STEALTH_UA_PRESETS[presetName];\n if (browserUA) {\n headers[\"user-agent\"] = browserUA;\n }\n }\n\n return headers;\n}\n\n/**\n * @ru \u0421\u043E\u0437\u0434\u0430\u0451\u0442 \u043D\u0430\u0442\u0438\u0432\u043D\u044B\u0439 HTTP/HTTPS \u0430\u0433\u0435\u043D\u0442 \u0441 \u0443\u0447\u0451\u0442\u043E\u043C stealth-\u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A.\n * @en Creates a native HTTP/HTTPS agent considering stealth settings.\n * @param isHttps - Whether the connection is HTTPS.\n * @param stealth - Optional stealth configuration.\n * @param cache - The agent cache map to use (per-instance).\n * @returns The HTTP or HTTPS agent.\n */\nfunction getNativeAgent(\n isHttps: boolean,\n stealth: StealthOptions | undefined,\n cache: Map<string, http.Agent | https.Agent>,\n rejectUnauthorized?: boolean,\n): http.Agent | https.Agent {\n const fingerprint = stealth?.fingerprint ?? \"none\";\n const fragment = stealth?.fragment ?? \"none\";\n const needHttp2 = stealth?.http2 === true;\n const cacheKey = `${isHttps ? \"https\" : \"http\"}:${fingerprint}:${fragment}:${needHttp2 ? \"h2\" : \"1.1\"}`;\n\n let agent = cache.get(cacheKey);\n if (agent) return agent;\n\n const agentOpts: any = {\n keepAlive: true,\n maxSockets: 256,\n };\n\n if (rejectUnauthorized !== undefined) {\n agentOpts.rejectUnauthorized = rejectUnauthorized;\n }\n\n if (isHttps) {\n agentOpts.ciphers = getCiphersForProfile(stealth?.fingerprint);\n\n const needCustomConnect = fragment === \"split\" || needHttp2;\n\n if (needCustomConnect) {\n const alpnProtocols: string[] | undefined = needHttp2 ? [\"h2\", \"http/1.1\"] : undefined;\n\n agentOpts.createConnection = (\n options: any,\n callback: (err: Error | null, socket?: any) => void,\n ) => {\n let alpnFallback = false;\n\n const createTlsConnection = (\n alpn: string[] | undefined,\n cb: (err: Error | null, socket?: any) => void,\n ) => {\n const socket = net.connect(options);\n\n if (fragment === \"split\") {\n const originalWrite = socket.write;\n let isFirstWrite = true;\n\n socket.write = function (\n this: net.Socket,\n chunk: Uint8Array | string,\n encodingOrCb?: BufferEncoding | ((err?: Error | null) => void),\n cb?: (err?: Error | null) => void,\n ): boolean {\n if (isFirstWrite && chunk instanceof Uint8Array && chunk.length > 5) {\n isFirstWrite = false;\n this.write = originalWrite;\n\n let encoding: BufferEncoding | undefined;\n let callbackRef: ((err?: Error | null) => void) | undefined;\n\n if (typeof encodingOrCb === \"function\") {\n callbackRef = encodingOrCb;\n } else {\n encoding = encodingOrCb;\n callbackRef = cb;\n }\n\n const part1 = chunk.subarray(0, 3);\n const part2 = chunk.subarray(3);\n\n const onError = (err: Error) => {\n callbackRef?.(err);\n };\n\n try {\n originalWrite.call(this, part1, encoding);\n } catch (err) {\n onError(err as Error);\n return false;\n }\n return originalWrite.call(this, part2, encoding, callbackRef);\n }\n\n this.write = originalWrite;\n return originalWrite.call(this, chunk, encodingOrCb as any, cb as any);\n } as any;\n }\n\n const tlsOpts: any = {\n ...options,\n socket,\n ciphers: agentOpts.ciphers,\n };\n if (alpn) tlsOpts.ALPNProtocols = alpn;\n\n const tlsSocket = tls.connect(tlsOpts);\n\n tlsSocket.once(\"secureConnect\", () => {\n if (alpn && tlsSocket.alpnProtocol === \"h2\" && !alpnFallback) {\n alpnFallback = true;\n tlsSocket.destroy();\n createTlsConnection([\"http/1.1\"], cb);\n return;\n }\n cb(null, tlsSocket);\n });\n tlsSocket.once(\"error\", (err) => cb(err));\n };\n\n return createTlsConnection(alpnProtocols, callback);\n };\n }\n\n agent = new https.Agent(agentOpts);\n } else {\n agent = new http.Agent(agentOpts);\n }\n\n cache.set(cacheKey, agent);\n return agent;\n}\n\nfunction isAbsoluteHttpUrl(url: string): boolean {\n return url.startsWith(\"http://\") || url.startsWith(\"https://\");\n}\n\nfunction resolveUrl(baseUrl: string, url: string): string {\n if (!url) throw new Error(\"URL is empty\");\n if (isAbsoluteHttpUrl(url)) return url;\n return url.charCodeAt(0) === 47 ? baseUrl + url : baseUrl + \"/\" + url;\n}\n\nfunction isLocalhostUrl(url: string): boolean {\n const schemeIdx = url.indexOf(\"://\");\n if (schemeIdx === -1) return false;\n\n const hostStart = schemeIdx + 3;\n let hostEnd = url.indexOf(\"/\", hostStart);\n if (hostEnd === -1) hostEnd = url.length;\n\n const host = url.slice(hostStart, hostEnd);\n return host === \"localhost\" || host.startsWith(\"localhost:\");\n}\n\nfunction normalizeHeaders(headers: TransportRequest[\"headers\"]): Record<string, string> {\n const out: Record<string, string> = Object.create(null);\n if (!headers) return out;\n\n if (headers instanceof Headers) {\n headers.forEach((value, key) => {\n out[key.toLowerCase()] = value;\n });\n return out;\n }\n\n if (Array.isArray(headers)) {\n for (let i = 0; i < headers.length; i++) {\n const pair = headers[i] as unknown as [string, string] | undefined;\n if (!pair || typeof pair[0] !== \"string\") continue;\n out[pair[0].toLowerCase()] = String(pair[1]);\n }\n return out;\n }\n\n const src = headers as Record<string, unknown>;\n for (const key in src) {\n const value = src[key];\n if (value == null) continue;\n\n const lKey = key.toLowerCase();\n if (Array.isArray(value)) {\n out[lKey] = lKey === \"cookie\" ? value.join(\"; \") : value.join(\", \");\n continue;\n }\n\n out[lKey] = String(value);\n }\n\n return out;\n}\n\nfunction createSizeLimitTransform(maxBytes: number): Transform {\n let total = 0;\n return new Transform({\n transform(chunk: Buffer, _encoding, callback) {\n total += chunk.length;\n if (total > maxBytes) {\n callback(new Error(`[Hyperttp] Response size exceeded limit of ${maxBytes} bytes`));\n return;\n }\n callback(null, chunk);\n },\n });\n}\n\n/**\n * @ru \u0420\u0435\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u044F \u0442\u0440\u0430\u043D\u0441\u043F\u043E\u0440\u0442\u0430 \u0434\u043B\u044F Node.js \u0441 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u043C \u043D\u0430\u0442\u0438\u0432\u043D\u044B\u0445 http/https \u043C\u043E\u0434\u0443\u043B\u0435\u0439.\n * \u041F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 stealth-\u043C\u0430\u0441\u043A\u0438\u0440\u043E\u0432\u043A\u0443, \u0444\u0440\u0430\u0433\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u044E TLS Client Hello \u0438 \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0443\u044E \u0434\u0435\u043A\u043E\u043C\u043F\u0440\u0435\u0441\u0441\u0438\u044E.\n */\nexport class NodeTransport implements HyperTransport {\n public config: NodeTransportConfig;\n private readonly isProduction: boolean;\n private readonly cleanBaseUrl: string;\n private readonly agentCache = new Map<string, http.Agent | https.Agent>();\n\n constructor(config: NodeTransportConfig) {\n this.config = config;\n this.isProduction = process.env.NODE_ENV === \"production\";\n\n const base = config.baseUrl ?? \"http://localhost:3000\";\n this.cleanBaseUrl = base.endsWith(\"/\") ? base.slice(0, -1) : base;\n }\n\n public async execute(req: TransportRequest): Promise<TransportResponse> {\n const fullUrl = resolveUrl(this.cleanBaseUrl, req.url);\n\n if (this.isProduction && isLocalhostUrl(fullUrl)) {\n throw new Error(\"Localhost URL detected in production environment\");\n }\n\n let headers = normalizeHeaders(req.headers);\n\n if (headers[\"accept-encoding\"] === undefined) {\n headers[\"accept-encoding\"] = \"gzip, deflate, br\";\n }\n\n const stealthOpts = req.stealth ?? this.config.stealth ?? this.config.network?.stealth;\n if (stealthOpts) {\n headers = applyStealthHeaders(headers, stealthOpts);\n }\n\n const body = req.body;\n const urlObj = new URL(fullUrl);\n const isHttps = urlObj.protocol === \"https:\";\n const agent = getNativeAgent(isHttps, stealthOpts, this.agentCache, this.config.network?.rejectUnauthorized);\n\n return new Promise((resolve, reject) => {\n const reqOpts: http.RequestOptions | https.RequestOptions = {\n method: req.method,\n headers,\n agent,\n signal: req.signal,\n };\n\n let settled = false;\n\n const clientReq = (isHttps ? https : http).request(fullUrl, reqOpts, (res) => {\n const resHeaders: Record<string, string> = Object.create(null);\n for (const key in res.headers) {\n const val = res.headers[key];\n if (val !== undefined) {\n resHeaders[key] = Array.isArray(val) ? val.join(\", \") : val;\n }\n }\n\n let responseStream: Readable = res;\n const encoding = resHeaders[\"content-encoding\"]?.toLowerCase();\n\n if (encoding === \"gzip\") {\n const gunzip = zlib.createGunzip();\n gunzip.on(\"error\", (err) => {\n res.destroy(err);\n if (!settled) reject(err);\n });\n responseStream = res.pipe(gunzip);\n delete resHeaders[\"content-encoding\"];\n delete resHeaders[\"content-length\"];\n } else if (encoding === \"deflate\") {\n const inflate = zlib.createInflate();\n inflate.on(\"error\", (err) => {\n res.destroy(err);\n if (!settled) reject(err);\n });\n responseStream = res.pipe(inflate);\n delete resHeaders[\"content-encoding\"];\n delete resHeaders[\"content-length\"];\n } else if (encoding === \"br\") {\n const brotli = zlib.createBrotliDecompress();\n brotli.on(\"error\", (err) => {\n res.destroy(err);\n if (!settled) reject(err);\n });\n responseStream = res.pipe(brotli);\n delete resHeaders[\"content-encoding\"];\n delete resHeaders[\"content-length\"];\n }\n\n const maxBytes = this.config.network?.maxResponseBytes;\n if (maxBytes != null && maxBytes > 0) {\n const limiter = createSizeLimitTransform(maxBytes);\n limiter.on(\"error\", (err) => {\n res.destroy(err);\n if (!settled) reject(err);\n });\n responseStream = responseStream.pipe(limiter);\n }\n\n responseStream.on(\"error\", (err) => {\n if (!settled) reject(err);\n });\n\n settled = true;\n resolve({\n status: res.statusCode ?? 200,\n headers: resHeaders,\n url: fullUrl,\n body: Readable.toWeb(responseStream) as unknown as TransportResponsePayload,\n });\n });\n\n clientReq.on(\"error\", (err) => {\n if (!settled) reject(err);\n });\n\n if (body !== undefined && body !== null) {\n if (typeof body === \"string\" || body instanceof Uint8Array || ArrayBuffer.isView(body)) {\n clientReq.write(body);\n clientReq.end();\n } else if (body instanceof ArrayBuffer) {\n clientReq.write(Buffer.from(body));\n clientReq.end();\n } else if (typeof ReadableStream !== \"undefined\" && body instanceof ReadableStream) {\n Readable.fromWeb(body as any).pipe(clientReq);\n } else {\n clientReq.end();\n }\n } else {\n clientReq.end();\n }\n });\n }\n\n public async close(): Promise<void> {\n for (const agent of this.agentCache.values()) {\n agent.destroy();\n }\n this.agentCache.clear();\n }\n\n public async destroy(): Promise<void> {\n for (const agent of this.agentCache.values()) {\n agent.destroy();\n }\n this.agentCache.clear();\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["http", "https", "net", "Readable", "Transform", "tls", "zlib", "STEALTH_HEADER_PRESETS", "STEALTH_UA_PRESETS", "getCiphersForProfile", "fingerprint", "applyStealthHeaders", "headers", "stealth", "presetName", "presetHeaders", "key", "currentUA", "browserUA", "getNativeAgent", "isHttps", "cache", "rejectUnauthorized", "fragment", "needHttp2", "cacheKey", "agent", "agentOpts", "alpnProtocols", "options", "callback", "alpnFallback", "createTlsConnection", "alpn", "cb", "socket", "originalWrite", "isFirstWrite", "chunk", "encodingOrCb", "encoding", "callbackRef", "part1", "part2", "onError", "err", "tlsOpts", "tlsSocket", "isAbsoluteHttpUrl", "url", "resolveUrl", "baseUrl", "isLocalhostUrl", "schemeIdx", "hostStart", "hostEnd", "host", "normalizeHeaders", "out", "value", "i", "pair", "src", "lKey", "createSizeLimitTransform", "maxBytes", "total", "_encoding", "config", "base", "req", "fullUrl", "stealthOpts", "body", "resolve", "reject", "reqOpts", "settled", "clientReq", "res", "resHeaders", "val", "responseStream", "gunzip", "inflate", "brotli", "limiter"]
4
+ "sourcesContent": ["import type {\n Fingerprint,\n HttpClientOptions,\n HyperTransport,\n StealthOptions,\n TransportRequest,\n TransportResponse,\n TransportResponsePayload,\n} from \"@hyperttp/types\";\nimport { CacheManager } from \"hcacher\";\nimport http from \"node:http\";\nimport https from \"node:https\";\nimport net from \"node:net\";\nimport { Readable, Transform } from \"node:stream\";\nimport tls from \"node:tls\";\nimport zlib from \"node:zlib\";\n\n/**\n * @ru \u041A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044F \u0442\u0440\u0430\u043D\u0441\u043F\u043E\u0440\u0442\u0430 \u0434\u043B\u044F Node.js \u0441 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u043C \u043D\u0430\u0442\u0438\u0432\u043D\u044B\u0445 http/https \u043C\u043E\u0434\u0443\u043B\u0435\u0439.\n * @en Node.js transport configuration using native http/https modules.\n */\nexport interface NodeTransportConfig extends HttpClientOptions {\n /**\n * @ru \u0411\u0430\u0437\u043E\u0432\u044B\u0439 URL \u0434\u043B\u044F \u043E\u0442\u043D\u043E\u0441\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0445 \u043F\u0443\u0442\u0435\u0439.\n * @en Base URL for relative paths.\n */\n baseUrl?: string;\n /**\n * @ru \u041D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438 stealth-\u043C\u0430\u0441\u043A\u0438\u0440\u043E\u0432\u043A\u0438 \u043D\u0430 \u0443\u0440\u043E\u0432\u043D\u0435 \u0442\u0440\u0430\u043D\u0441\u043F\u043E\u0440\u0442\u0430.\n * @en Stealth masking settings at the transport level.\n */\n stealth?: StealthOptions;\n}\n\n/**\n * @ru \u0421\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438\u0435 \u043F\u0440\u0435\u0441\u0435\u0442\u044B \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043D\u044B\u0445 \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u043E\u0432 \u0434\u043B\u044F \u043C\u0430\u0441\u043A\u0438\u0440\u043E\u0432\u043A\u0438 \u043F\u043E\u0434 \u0440\u0435\u0430\u043B\u044C\u043D\u044B\u0445 \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0435\u0439.\n * \u0418\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u044E\u0442\u0441\u044F stealth-\u0440\u0435\u0436\u0438\u043C\u043E\u043C \u0434\u043B\u044F \u043E\u0431\u0445\u043E\u0434\u0430 fingerprint-\u0437\u0430\u0449\u0438\u0442.\n * @en Static presets of browser headers for masking as real users.\n * Used by stealth mode to bypass fingerprint protections.\n */\nconst STEALTH_HEADER_PRESETS: Record<string, Record<string, string>> = {\n chrome: {\n \"sec-ch-ua\": '\"Not/A)Brand\";v=\"8\", \"Chromium\";v=\"126\", \"Google Chrome\";v=\"126\"',\n \"sec-ch-ua-mobile\": \"?0\",\n \"sec-ch-ua-platform\": '\"Linux\"',\n \"sec-fetch-dest\": \"document\",\n \"sec-fetch-mode\": \"navigate\",\n \"sec-fetch-site\": \"none\",\n \"sec-fetch-user\": \"?1\",\n \"upgrade-insecure-requests\": \"1\",\n \"accept-language\": \"en-US,en;q=0.9\",\n },\n firefox: {\n \"sec-fetch-dest\": \"document\",\n \"sec-fetch-mode\": \"navigate\",\n \"sec-fetch-site\": \"none\",\n \"accept-language\": \"en-US,en;q=0.5\",\n \"upgrade-insecure-requests\": \"1\",\n },\n};\n\n/**\n * @ru \u041F\u0440\u0435\u0441\u0435\u0442\u044B User-Agent, \u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0435 TLS-\u043E\u0442\u043F\u0435\u0447\u0430\u0442\u043A\u0430\u043C (JA3/JA4).\n * @en User-Agent presets matching the TLS fingerprints (JA3/JA4).\n */\nconst STEALTH_UA_PRESETS: Record<string, string> = {\n chrome:\n \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36\",\n firefox: \"Mozilla/5.0 (X11; Linux; rv:126.0) Gecko/20100101 Firefox/126.0\",\n safari:\n \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Safari/605.1.15\",\n edge: \"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36 Edg/126.0.0.0\",\n};\n\n/**\n * @ru \u0412\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u0442\u0440\u043E\u043A\u0443 \u0448\u0438\u0444\u0440\u043E\u0432 TLS \u0434\u043B\u044F \u0443\u043A\u0430\u0437\u0430\u043D\u043D\u043E\u0433\u043E \u043F\u0440\u043E\u0444\u0438\u043B\u044F \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430.\n * @en Returns the TLS cipher suite string for the specified browser profile.\n * @param fingerprint - Browser fingerprint profile.\n * @returns Colon-separated cipher suite string, or empty string if not found.\n */\nfunction getCiphersForProfile(fingerprint: Fingerprint | undefined): string {\n if (!fingerprint) return \"\";\n\n switch (fingerprint) {\n case \"chrome\":\n case \"edge\":\n return [\n \"TLS_AES_128_GCM_SHA256\",\n \"TLS_AES_256_GCM_SHA384\",\n \"TLS_CHACHA20_POLY1305_SHA256\",\n \"ECDHE-ECDSA-AES128-GCM-SHA256\",\n \"ECDHE-RSA-AES128-GCM-SHA256\",\n ].join(\":\");\n\n case \"firefox\":\n return [\n \"TLS_AES_128_GCM_SHA256\",\n \"TLS_CHACHA20_POLY1305_SHA256\",\n \"TLS_AES_256_GCM_SHA384\",\n \"ECDHE-ECDSA-AES128-GCM-SHA256\",\n \"ECDHE-RSA-AES128-GCM-SHA256\",\n ].join(\":\");\n\n case \"safari\":\n return [\n \"TLS_AES_256_GCM_SHA384\",\n \"TLS_CHACHA20_POLY1305_SHA256\",\n \"TLS_AES_128_GCM_SHA256\",\n \"ECDHE-ECDSA-AES256-GCM-SHA384\",\n \"ECDHE-RSA-AES256-GCM-SHA384\",\n ].join(\":\");\n\n default:\n return \"\";\n }\n}\n\n/**\n * @ru \u0411\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E \u043F\u0440\u0438\u043C\u0435\u043D\u044F\u0435\u0442 \u0441\u0442\u0435\u043B\u0441-\u043F\u0440\u0435\u0441\u0435\u0442\u044B, \u043E\u0442\u0434\u0430\u0432\u0430\u044F \u0430\u0431\u0441\u043E\u043B\u044E\u0442\u043D\u044B\u0439 \u043F\u0440\u0438\u043E\u0440\u0438\u0442\u0435\u0442 \u0440\u0443\u0447\u043D\u044B\u043C \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430\u043C.\n * @en Safely applies stealth presets, giving absolute priority to manual headers.\n * @param headers - The headers object to modify.\n * @param stealth - Stealth configuration options.\n * @returns The modified headers object.\n */\nfunction applyStealthHeaders(\n headers: Record<string, string>,\n stealth: StealthOptions,\n): Record<string, string> {\n if (!stealth || !stealth.fingerprint) return headers;\n\n const presetName = stealth.fingerprint;\n const presetHeaders = STEALTH_HEADER_PRESETS[presetName];\n\n if (presetHeaders) {\n for (const key in presetHeaders) {\n if (headers[key] === undefined) {\n headers[key] = presetHeaders[key]!;\n }\n }\n }\n\n const currentUA = headers[\"user-agent\"];\n if (currentUA === undefined || currentUA === \"hyperttp/2.0\" || currentUA === \"Hyperttp/2.0\") {\n const browserUA = STEALTH_UA_PRESETS[presetName];\n if (browserUA) {\n headers[\"user-agent\"] = browserUA;\n }\n }\n\n return headers;\n}\n\n/**\n * @ru \u0421\u043E\u0437\u0434\u0430\u0451\u0442 \u043D\u0430\u0442\u0438\u0432\u043D\u044B\u0439 HTTP/HTTPS \u0430\u0433\u0435\u043D\u0442 \u0441 \u0443\u0447\u0451\u0442\u043E\u043C stealth-\u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A.\n * @en Creates a native HTTP/HTTPS agent considering stealth settings.\n * @param isHttps - Whether the connection is HTTPS.\n * @param stealth - Optional stealth configuration.\n * @param cache - The agent cache map to use (per-instance).\n * @returns The HTTP or HTTPS agent.\n */\nfunction getNativeAgent(\n isHttps: boolean,\n stealth: StealthOptions | undefined,\n cache: CacheManager<http.Agent | https.Agent>,\n trackedAgents: Set<http.Agent | https.Agent>,\n rejectUnauthorized?: boolean,\n): http.Agent | https.Agent {\n const fingerprint = stealth?.fingerprint ?? \"none\";\n const fragment = stealth?.fragment ?? \"none\";\n const needHttp2 = stealth?.http2 === true;\n const cacheKey = `${isHttps ? \"https\" : \"http\"}:${fingerprint}:${fragment}:${needHttp2 ? \"h2\" : \"1.1\"}`;\n\n let agent = cache.get(cacheKey);\n if (agent) return agent;\n\n const agentOpts: any = {\n keepAlive: true,\n maxSockets: 256,\n };\n\n if (rejectUnauthorized !== undefined) {\n agentOpts.rejectUnauthorized = rejectUnauthorized;\n }\n\n if (isHttps) {\n agentOpts.ciphers = getCiphersForProfile(stealth?.fingerprint);\n\n const needCustomConnect = fragment === \"split\" || needHttp2;\n\n if (needCustomConnect) {\n const alpnProtocols: string[] | undefined = needHttp2 ? [\"h2\", \"http/1.1\"] : undefined;\n\n agentOpts.createConnection = (\n options: any,\n callback: (err: Error | null, socket?: any) => void,\n ) => {\n let alpnFallback = false;\n\n const createTlsConnection = (\n alpn: string[] | undefined,\n cb: (err: Error | null, socket?: any) => void,\n ) => {\n const socket = net.connect(options);\n\n if (fragment === \"split\") {\n const originalWrite = socket.write;\n let isFirstWrite = true;\n\n socket.write = function (\n this: net.Socket,\n chunk: Uint8Array | string,\n encodingOrCb?: BufferEncoding | ((err?: Error | null) => void),\n cb?: (err?: Error | null) => void,\n ): boolean {\n if (isFirstWrite && chunk instanceof Uint8Array && chunk.length > 5) {\n isFirstWrite = false;\n this.write = originalWrite;\n\n let encoding: BufferEncoding | undefined;\n let callbackRef: ((err?: Error | null) => void) | undefined;\n\n if (typeof encodingOrCb === \"function\") {\n callbackRef = encodingOrCb;\n } else {\n encoding = encodingOrCb;\n callbackRef = cb;\n }\n\n const part1 = chunk.subarray(0, 3);\n const part2 = chunk.subarray(3);\n\n const onError = (err: Error) => {\n callbackRef?.(err);\n };\n\n try {\n originalWrite.call(this, part1, encoding);\n } catch (err) {\n onError(err as Error);\n return false;\n }\n return originalWrite.call(this, part2, encoding, callbackRef);\n }\n\n this.write = originalWrite;\n return originalWrite.call(this, chunk, encodingOrCb as any, cb as any);\n } as any;\n }\n\n const tlsOpts: any = {\n ...options,\n socket,\n ciphers: agentOpts.ciphers,\n };\n if (alpn) tlsOpts.ALPNProtocols = alpn;\n\n const tlsSocket = tls.connect(tlsOpts);\n\n tlsSocket.once(\"secureConnect\", () => {\n if (alpn && tlsSocket.alpnProtocol === \"h2\" && !alpnFallback) {\n alpnFallback = true;\n tlsSocket.destroy();\n createTlsConnection([\"http/1.1\"], cb);\n return;\n }\n cb(null, tlsSocket);\n });\n tlsSocket.once(\"error\", (err) => cb(err));\n };\n\n return createTlsConnection(alpnProtocols, callback);\n };\n }\n\n agent = new https.Agent(agentOpts);\n } else {\n agent = new http.Agent(agentOpts);\n }\n\n cache.set(cacheKey, agent);\n trackedAgents.add(agent);\n return agent;\n}\n\nfunction isAbsoluteHttpUrl(url: string): boolean {\n return url.startsWith(\"http://\") || url.startsWith(\"https://\");\n}\n\nfunction resolveUrl(baseUrl: string, url: string): string {\n if (!url) throw new Error(\"URL is empty\");\n if (isAbsoluteHttpUrl(url)) return url;\n return url.charCodeAt(0) === 47 ? baseUrl + url : baseUrl + \"/\" + url;\n}\n\nfunction isLocalhostUrl(url: string): boolean {\n const schemeIdx = url.indexOf(\"://\");\n if (schemeIdx === -1) return false;\n\n const hostStart = schemeIdx + 3;\n let hostEnd = url.indexOf(\"/\", hostStart);\n if (hostEnd === -1) hostEnd = url.length;\n\n const host = url.slice(hostStart, hostEnd);\n return host === \"localhost\" || host.startsWith(\"localhost:\");\n}\n\nfunction normalizeHeaders(headers: TransportRequest[\"headers\"]): Record<string, string> {\n const out: Record<string, string> = Object.create(null);\n if (!headers) return out;\n\n if (headers instanceof Headers) {\n headers.forEach((value, key) => {\n out[key.toLowerCase()] = value;\n });\n return out;\n }\n\n if (Array.isArray(headers)) {\n for (let i = 0; i < headers.length; i++) {\n const pair = headers[i] as unknown as [string, string] | undefined;\n if (!pair || typeof pair[0] !== \"string\") continue;\n out[pair[0].toLowerCase()] = String(pair[1]);\n }\n return out;\n }\n\n const src = headers as Record<string, unknown>;\n for (const key in src) {\n const value = src[key];\n if (value == null) continue;\n\n const lKey = key.toLowerCase();\n if (Array.isArray(value)) {\n out[lKey] = lKey === \"cookie\" ? value.join(\"; \") : value.join(\", \");\n continue;\n }\n\n out[lKey] = String(value);\n }\n\n return out;\n}\n\nfunction createSizeLimitTransform(maxBytes: number): Transform {\n let total = 0;\n return new Transform({\n transform(chunk: Buffer, _encoding, callback) {\n total += chunk.length;\n if (total > maxBytes) {\n callback(new Error(`[Hyperttp] Response size exceeded limit of ${maxBytes} bytes`));\n return;\n }\n callback(null, chunk);\n },\n });\n}\n\n/**\n * @ru \u0420\u0435\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u044F \u0442\u0440\u0430\u043D\u0441\u043F\u043E\u0440\u0442\u0430 \u0434\u043B\u044F Node.js \u0441 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u043C \u043D\u0430\u0442\u0438\u0432\u043D\u044B\u0445 http/https \u043C\u043E\u0434\u0443\u043B\u0435\u0439.\n * \u041F\u043E\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 stealth-\u043C\u0430\u0441\u043A\u0438\u0440\u043E\u0432\u043A\u0443, \u0444\u0440\u0430\u0433\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u044E TLS Client Hello \u0438 \u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0443\u044E \u0434\u0435\u043A\u043E\u043C\u043F\u0440\u0435\u0441\u0441\u0438\u044E.\n */\nexport class NodeTransport implements HyperTransport {\n public config: NodeTransportConfig;\n private readonly isProduction: boolean;\n private readonly cleanBaseUrl: string;\n private readonly agentCache = new CacheManager<http.Agent | https.Agent>({ maxSize: 32, ttl: 60_000 });\n private readonly trackedAgents = new Set<http.Agent | https.Agent>();\n\n constructor(config: NodeTransportConfig) {\n this.config = config;\n this.isProduction = process.env.NODE_ENV === \"production\";\n\n const base = config.baseUrl ?? \"http://localhost:3000\";\n this.cleanBaseUrl = base.endsWith(\"/\") ? base.slice(0, -1) : base;\n }\n\n public async execute(req: TransportRequest): Promise<TransportResponse> {\n const fullUrl = resolveUrl(this.cleanBaseUrl, req.url);\n\n if (this.isProduction && isLocalhostUrl(fullUrl)) {\n throw new Error(\"Localhost URL detected in production environment\");\n }\n\n let headers = normalizeHeaders(req.headers);\n\n if (headers[\"accept-encoding\"] === undefined) {\n headers[\"accept-encoding\"] = \"gzip, deflate, br\";\n }\n\n const stealthOpts = req.stealth ?? this.config.stealth ?? this.config.network?.stealth;\n if (stealthOpts) {\n headers = applyStealthHeaders(headers, stealthOpts);\n }\n\n const body = req.body;\n const urlObj = new URL(fullUrl);\n const isHttps = urlObj.protocol === \"https:\";\n const agent = getNativeAgent(\n isHttps,\n stealthOpts,\n this.agentCache,\n this.trackedAgents,\n this.config.network?.rejectUnauthorized,\n );\n\n return new Promise((resolve, reject) => {\n const reqOpts: http.RequestOptions | https.RequestOptions = {\n method: req.method,\n headers,\n agent,\n signal: req.signal,\n };\n\n let settled = false;\n\n const clientReq = (isHttps ? https : http).request(fullUrl, reqOpts, (res) => {\n const resHeaders: Record<string, string> = Object.create(null);\n for (const key in res.headers) {\n const val = res.headers[key];\n if (val !== undefined) {\n resHeaders[key] = Array.isArray(val) ? val.join(\", \") : val;\n }\n }\n\n let responseStream: Readable = res;\n const encoding = resHeaders[\"content-encoding\"]?.toLowerCase();\n\n if (encoding === \"gzip\") {\n const gunzip = zlib.createGunzip();\n gunzip.on(\"error\", (err) => {\n res.destroy(err);\n if (!settled) reject(err);\n });\n responseStream = res.pipe(gunzip);\n delete resHeaders[\"content-encoding\"];\n delete resHeaders[\"content-length\"];\n } else if (encoding === \"deflate\") {\n const inflate = zlib.createInflate();\n inflate.on(\"error\", (err) => {\n res.destroy(err);\n if (!settled) reject(err);\n });\n responseStream = res.pipe(inflate);\n delete resHeaders[\"content-encoding\"];\n delete resHeaders[\"content-length\"];\n } else if (encoding === \"br\") {\n const brotli = zlib.createBrotliDecompress();\n brotli.on(\"error\", (err) => {\n res.destroy(err);\n if (!settled) reject(err);\n });\n responseStream = res.pipe(brotli);\n delete resHeaders[\"content-encoding\"];\n delete resHeaders[\"content-length\"];\n }\n\n const maxBytes = this.config.network?.maxResponseBytes;\n if (maxBytes != null && maxBytes > 0) {\n const limiter = createSizeLimitTransform(maxBytes);\n limiter.on(\"error\", (err) => {\n res.destroy(err);\n if (!settled) reject(err);\n });\n responseStream = responseStream.pipe(limiter);\n }\n\n responseStream.on(\"error\", (err) => {\n if (!settled) reject(err);\n });\n\n settled = true;\n resolve({\n status: res.statusCode ?? 200,\n headers: resHeaders,\n url: fullUrl,\n body: Readable.toWeb(responseStream) as unknown as TransportResponsePayload,\n });\n });\n\n clientReq.on(\"error\", (err) => {\n if (!settled) reject(err);\n });\n\n if (body !== undefined && body !== null) {\n if (typeof body === \"string\" || body instanceof Uint8Array || ArrayBuffer.isView(body)) {\n clientReq.write(body);\n clientReq.end();\n } else if (body instanceof ArrayBuffer) {\n clientReq.write(Buffer.from(body));\n clientReq.end();\n } else if (typeof ReadableStream !== \"undefined\" && body instanceof ReadableStream) {\n Readable.fromWeb(body as any).pipe(clientReq);\n } else {\n clientReq.end();\n }\n } else {\n clientReq.end();\n }\n });\n }\n\n public async close(): Promise<void> {\n for (const agent of this.trackedAgents) {\n agent.destroy();\n }\n this.trackedAgents.clear();\n this.agentCache.clear();\n }\n\n public async destroy(): Promise<void> {\n for (const agent of this.trackedAgents) {\n agent.destroy();\n }\n this.trackedAgents.clear();\n this.agentCache.clear();\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["CacheManager", "http", "https", "net", "Readable", "Transform", "tls", "zlib", "STEALTH_HEADER_PRESETS", "STEALTH_UA_PRESETS", "getCiphersForProfile", "fingerprint", "applyStealthHeaders", "headers", "stealth", "presetName", "presetHeaders", "key", "currentUA", "browserUA", "getNativeAgent", "isHttps", "cache", "trackedAgents", "rejectUnauthorized", "fragment", "needHttp2", "cacheKey", "agent", "agentOpts", "alpnProtocols", "options", "callback", "alpnFallback", "createTlsConnection", "alpn", "cb", "socket", "originalWrite", "isFirstWrite", "chunk", "encodingOrCb", "encoding", "callbackRef", "part1", "part2", "onError", "err", "tlsOpts", "tlsSocket", "isAbsoluteHttpUrl", "url", "resolveUrl", "baseUrl", "isLocalhostUrl", "schemeIdx", "hostStart", "hostEnd", "host", "normalizeHeaders", "out", "value", "i", "pair", "src", "lKey", "createSizeLimitTransform", "maxBytes", "total", "_encoding", "config", "base", "req", "fullUrl", "stealthOpts", "body", "resolve", "reject", "reqOpts", "settled", "clientReq", "res", "resHeaders", "val", "responseStream", "gunzip", "inflate", "brotli", "limiter"]
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IAO/B,IAAI,EAAE,MAAM;IACZ,UAAU,CAAC,EAAE,MAAM;IACnB,aAAa,CAAC,EAAE,KAAK;IACrB,GAAG,CAAC,EAAE,MAAM;IACZ,MAAM,CAAC,EAAE,MAAM;IAVxB;;;OAGG;gBAED,OAAO,EAAE,MAAM,EACR,IAAI,GAAE,MAAqB,EAC3B,UAAU,CAAC,EAAE,MAAM,YAAA,EACnB,aAAa,CAAC,EAAE,KAAK,YAAA,EACrB,GAAG,CAAC,EAAE,MAAM,YAAA,EACZ,MAAM,CAAC,EAAE,MAAM,YAAA;CAKzB;AAED;;;GAGG;AACH,qBAAa,YAAa,SAAQ,eAAe;IAC/C;;;OAGG;gBACS,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;CAIzC"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IAO/B,IAAI,EAAE,MAAM;IACZ,UAAU,CAAC,EAAE,MAAM;IACnB,aAAa,CAAC,EAAE,KAAK;IACrB,GAAG,CAAC,EAAE,MAAM;IACZ,MAAM,CAAC,EAAE,MAAM;IAVxB;;;OAGG;IACH,YACE,OAAO,EAAE,MAAM,EACR,IAAI,GAAE,MAAqB,EAC3B,UAAU,CAAC,EAAE,MAAM,YAAA,EACnB,aAAa,CAAC,EAAE,KAAK,YAAA,EACrB,GAAG,CAAC,EAAE,MAAM,YAAA,EACZ,MAAM,CAAC,EAAE,MAAM,YAAA,EAIvB;CACF;AAED;;;GAGG;AACH,qBAAa,YAAa,SAAQ,eAAe;IAC/C;;;OAGG;IACH,YAAY,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAGvC;CACF"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/errors.ts"],
4
- "sourcesContent": ["/**\n * @ru \u0411\u0430\u0437\u043E\u0432\u044B\u0439 \u043A\u043B\u0430\u0441\u0441 \u043E\u0448\u0438\u0431\u043E\u043A \u043A\u043B\u0438\u0435\u043D\u0442\u0430 Hyperttp, \u0430\u0433\u0440\u0435\u0433\u0438\u0440\u0443\u044E\u0449\u0438\u0439 \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442 \u043D\u0435\u0443\u0434\u0430\u0447\u043D\u043E\u0433\u043E \u0441\u0435\u0442\u0435\u0432\u043E\u0433\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0430.\n * @en Base error class for the Hyperttp client, providing explicit layout context for failed requests.\n */\nexport class HttpClientError extends Error {\n /**\n * @ru \u0421\u043E\u0437\u0434\u0430\u0435\u0442 \u043D\u043E\u0432\u044B\u0439 \u044D\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440 HttpClientError.\n * @en Creates a new HttpClientError instance.\n */\n constructor(\n message: string,\n public code: string = \"HTTP_ERROR\",\n public statusCode?: number,\n public originalError?: Error,\n public url?: string,\n public method?: string,\n ) {\n super(message, originalError ? { cause: originalError } : undefined);\n this.name = \"HttpClientError\";\n }\n}\n\n/**\n * @ru \u041E\u0448\u0438\u0431\u043A\u0430, \u0432\u043E\u0437\u043D\u0438\u043A\u0430\u044E\u0449\u0430\u044F \u043F\u0440\u0438 \u043F\u0440\u0435\u0432\u044B\u0448\u0435\u043D\u0438\u0438 \u043B\u0438\u043C\u0438\u0442\u0430 \u0432\u0440\u0435\u043C\u0435\u043D\u0438 \u043E\u0436\u0438\u0434\u0430\u043D\u0438\u044F \u043E\u0442\u0432\u0435\u0442\u0430 \u043E\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.\n * @en Error thrown when a network request exceeds its allocated execution timeout threshold.\n */\nexport class TimeoutError extends HttpClientError {\n /**\n * @ru \u0421\u043E\u0437\u0434\u0430\u0435\u0442 \u043D\u043E\u0432\u044B\u0439 \u044D\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440 TimeoutError.\n * @en Creates a new TimeoutError instance.\n */\n constructor(url: string, timeout: number) {\n super(`Timeout after ${timeout}ms`, \"TIMEOUT\", 408, undefined, url);\n this.name = \"TimeoutError\";\n }\n}\n\n\n"],
5
- "mappings": "aAIM,aAAO,wBAAwB,KAAK,CAO/B,KACA,WACA,cACA,IACA,OANT,YACEA,EACOC,EAAe,aACfC,EACAC,EACAC,EACAC,EAAe,CAEtB,MAAML,EAASG,EAAgB,CAAE,MAAOA,CAAa,EAAK,MAAS,EAN5D,KAAA,KAAAF,EACA,KAAA,WAAAC,EACA,KAAA,cAAAC,EACA,KAAA,IAAAC,EACA,KAAA,OAAAC,EAGP,KAAK,KAAO,iBACd,EAOI,aAAO,qBAAqB,eAAe,CAK/C,YAAYD,EAAaE,EAAe,CACtC,MAAM,iBAAiBA,CAAO,KAAM,UAAW,IAAK,OAAWF,CAAG,EAClE,KAAK,KAAO,cACd",
4
+ "sourcesContent": ["/**\n * @ru \u0411\u0430\u0437\u043E\u0432\u044B\u0439 \u043A\u043B\u0430\u0441\u0441 \u043E\u0448\u0438\u0431\u043E\u043A \u043A\u043B\u0438\u0435\u043D\u0442\u0430 Hyperttp, \u0430\u0433\u0440\u0435\u0433\u0438\u0440\u0443\u044E\u0449\u0438\u0439 \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442 \u043D\u0435\u0443\u0434\u0430\u0447\u043D\u043E\u0433\u043E \u0441\u0435\u0442\u0435\u0432\u043E\u0433\u043E \u0437\u0430\u043F\u0440\u043E\u0441\u0430.\n * @en Base error class for the Hyperttp client, providing explicit layout context for failed requests.\n */\nexport class HttpClientError extends Error {\n /**\n * @ru \u0421\u043E\u0437\u0434\u0430\u0435\u0442 \u043D\u043E\u0432\u044B\u0439 \u044D\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440 HttpClientError.\n * @en Creates a new HttpClientError instance.\n */\n constructor(\n message: string,\n public code: string = \"HTTP_ERROR\",\n public statusCode?: number,\n public originalError?: Error,\n public url?: string,\n public method?: string,\n ) {\n super(message, originalError ? { cause: originalError } : undefined);\n this.name = \"HttpClientError\";\n }\n}\n\n/**\n * @ru \u041E\u0448\u0438\u0431\u043A\u0430, \u0432\u043E\u0437\u043D\u0438\u043A\u0430\u044E\u0449\u0430\u044F \u043F\u0440\u0438 \u043F\u0440\u0435\u0432\u044B\u0448\u0435\u043D\u0438\u0438 \u043B\u0438\u043C\u0438\u0442\u0430 \u0432\u0440\u0435\u043C\u0435\u043D\u0438 \u043E\u0436\u0438\u0434\u0430\u043D\u0438\u044F \u043E\u0442\u0432\u0435\u0442\u0430 \u043E\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430.\n * @en Error thrown when a network request exceeds its allocated execution timeout threshold.\n */\nexport class TimeoutError extends HttpClientError {\n /**\n * @ru \u0421\u043E\u0437\u0434\u0430\u0435\u0442 \u043D\u043E\u0432\u044B\u0439 \u044D\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440 TimeoutError.\n * @en Creates a new TimeoutError instance.\n */\n constructor(url: string, timeout: number) {\n super(`Timeout after ${timeout}ms`, \"TIMEOUT\", 408, undefined, url);\n this.name = \"TimeoutError\";\n }\n}\n"],
5
+ "mappings": "aAIM,aAAO,wBAAwB,KAAK,CAO/B,KACA,WACA,cACA,IACA,OANT,YACEA,EACOC,EAAe,aACfC,EACAC,EACAC,EACAC,EAAe,CAEtB,MAAML,EAASG,EAAgB,CAAE,MAAOA,CAAa,EAAK,MAAS,YAN5DF,kBACAC,qBACAC,WACAC,cACAC,EAGP,KAAK,KAAO,iBACd,EAOI,aAAO,qBAAqB,eAAe,CAK/C,YAAYD,EAAaE,EAAe,CACtC,MAAM,iBAAiBA,CAAO,KAAM,UAAW,IAAK,OAAWF,CAAG,EAClE,KAAK,KAAO,cACd",
6
6
  "names": ["message", "code", "statusCode", "originalError", "url", "method", "timeout"]
7
7
  }
@@ -1,56 +1,34 @@
1
1
  import type { Method, RequestBodyData } from "@hyperttp/types";
2
2
  type NormalizedHeaders = Record<string, string | string[]>;
3
3
  /**
4
- * @ru Извлекает URL из объекта запроса или строки.
5
- * Поддерживает различные форматы: строка, объект с полем `url`, `_url`, или `scheme/host/path`.
6
- * @en Extracts URL from a request object or string.
7
- * Supports various formats: string, object with `url`, `_url`, or `scheme/host/path` fields.
8
- * @param req - The request object or URL string.
4
+ * @ru Извлекает URL из запроса (строка, объект с url/_url или схема+хост+путь).
5
+ * @en Extracts the URL from a request (string, object with url/_url, or scheme+host+path).
6
+ * @param req - URL string or request-like object.
9
7
  * @returns The extracted URL string.
10
- * @throws Error if URL is missing in the request.
11
8
  */
12
9
  export declare function normalizeUrl(req: unknown): string;
13
10
  /**
14
- * @ru Нормализует заголовки запроса в единый формат с ключами в нижнем регистре.
15
- * Поддерживает различные входные форматы: объект, массив пар, плоский массив.
16
- *
17
- * Специальные правила:
18
- * - `set-cookie` всегда хранится как массив
19
- * - `cookie`/`cookie2` объединяются через `; `
20
- * - Остальные множественные заголовки объединяются через `, `
21
- * - Заголовки из SINGLE_VALUE_HEADERS перезаписываются (не объединяются)
22
- *
23
- * @en Normalizes request headers into a unified format with lowercase keys.
24
- * Supports various input formats: object, array of pairs, flat array.
25
- *
26
- * Special rules:
27
- * - `set-cookie` is always stored as an array
28
- * - `cookie`/`cookie2` are joined with `; `
29
- * - Other multiple headers are joined with `, `
30
- * - Headers from SINGLE_VALUE_HEADERS are overwritten (not merged)
31
- *
32
- * @param headers - The headers to normalize (object, array of pairs, or flat array).
33
- * @returns Normalized headers object with lowercase keys.
11
+ * @ru Нормализует заголовки в плоский объект с нижним регистром ключей и обработкой массива/парных форматов.
12
+ * @en Normalizes headers into a flat object with lowercased keys, handling array/pair formats.
13
+ * @param headers - Headers in any supported format (object, array of pairs, flat array).
14
+ * @param out - Optional output object (reused for pooling).
15
+ * @returns Normalized headers object.
34
16
  */
35
- export declare function normalizeHeaders(headers: unknown): NormalizedHeaders;
17
+ export declare function normalizeHeaders(headers: unknown, out?: NormalizedHeaders): NormalizedHeaders;
36
18
  /**
37
- * @ru Нормализует тело запроса, удаляя его для методов GET и HEAD.
38
- * @en Normalizes request body by removing it for GET and HEAD methods.
39
- * @param method - The HTTP method.
40
- * @param body - The request body data.
41
- * @returns The body for methods that support it, or undefined for GET/HEAD.
19
+ * @ru Возвращает undefined для GET/HEAD (тело запрещено), иначе тело как есть.
20
+ * @en Returns undefined for GET/HEAD (body disallowed), otherwise the body as-is.
21
+ * @param method - HTTP method.
22
+ * @param body - Request body.
23
+ * @returns Normalized body or undefined.
42
24
  */
43
25
  export declare function normalizeBody(method: Method, body: RequestBodyData | undefined): RequestBodyData | undefined;
44
26
  /**
45
- * @ru Сериализует тело запроса для транспорта: plain objects → JSON,
46
- * URLSearchParams → string, pass-through для остальных типов.
47
- * Мутирует headers, выставляя content-type если не задан.
48
- * @en Serializes request body for transport: plain objects → JSON,
49
- * URLSearchParams → string, pass-through for other types.
50
- * Mutates headers, setting content-type if not already set.
51
- * @param body - The request body to normalize.
52
- * @param headers - The request headers (mutated in place).
53
- * @returns The transport-ready body.
27
+ * @ru Преобразует тело для транспорта: сериализует объекты в JSON, URLSearchParams в строку, проставляет Content-Type.
28
+ * @en Transforms body for transport: serializes objects to JSON, URLSearchParams to string, sets Content-Type.
29
+ * @param body - Request body.
30
+ * @param headers - Headers object (may be mutated to add Content-Type).
31
+ * @returns Body ready for transport.
54
32
  */
55
33
  export declare function normalizeBodyForTransport(body: RequestBodyData, headers: Record<string, string | string[]>): RequestBodyData;
56
34
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/utils/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAE/D,KAAK,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;AAkG3D;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAwBjD;AAoED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,iBAAiB,CAmDpE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,eAAe,GAAG,SAAS,GAChC,eAAe,GAAG,SAAS,CAE7B;AAWD;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GACzC,eAAe,CA8BjB"}
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/utils/normalize.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAG/D,KAAK,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;AAsE3D;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAwBjD;AA8DD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,OAAO,EAChB,GAAG,GAAE,iBAAuC,GAC3C,iBAAiB,CAoDnB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,eAAe,GAAG,SAAS,GAChC,eAAe,GAAG,SAAS,CAE7B;AASD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,eAAe,EACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GACzC,eAAe,CA8BjB"}
@@ -1,2 +1,2 @@
1
- "use strict";const p=Object.create(null);for(const n of["content-type","content-length","content-encoding","content-disposition","host","authorization","proxy-authorization","user-agent","referer","origin","location","etag","last-modified"])p[n]=1;const y=2048,a=Object.create(null),s=["accept","accept-encoding","accept-language","authorization","cache-control","connection","content-encoding","content-length","content-type","cookie","date","etag","host","if-modified-since","if-none-match","keep-alive","location","origin","pragma","proxy-authorization","referer","sec-ch-ua","server","set-cookie","transfer-encoding","user-agent","x-forwarded-for","x-requested-with"];for(let n=0;n<s.length;n++){const t=s[n];a[t]=t}let l=s.length;function u(n){const t=a[n];if(t!==void 0)return t;const e=n.toLowerCase();return l<y&&(a[n]=e,l++),e}export function normalizeUrl(n){if(typeof n=="string")return n;if(n&&typeof n=="object"){const t=n,e=t.url;if(typeof e=="string")return e;if(e!=null)return String(e);const i=t._url;if(typeof i=="string")return i;if(i!=null)return String(i);const r=t.scheme,o=t.host,c=t.path;if(typeof r=="string"&&typeof o=="string"&&typeof c=="string")return`${r}://${o}${c}`}throw new Error("URL missing in request")}function f(n,t,e){if(e=e.replace(/[\r\n]/g,""),p[t]===1){n[t]=e;return}const i=n[t];if(i===void 0){n[t]=t==="set-cookie"?[e]:e;return}if(t==="set-cookie"){Array.isArray(i)?i.push(e):n[t]=[i,e];return}if(t==="cookie"||t==="cookie2"){n[t]=i+"; "+e;return}n[t]=i+", "+e}function d(n,t,e){if(e!=null){if(Array.isArray(e)){const i=e.length;for(let r=0;r<i;r++){const o=e[r];o!=null&&f(n,t,typeof o=="string"?o:String(o))}return}f(n,t,typeof e=="string"?e:String(e))}}export function normalizeHeaders(n){const t=Object.create(null);if(!n||typeof n!="object")return t;if(!Array.isArray(n)){for(const i in n){const r=n[i];r!=null&&d(t,u(i),r)}return t}const e=n.length;if(e===0)return t;if(Array.isArray(n[0]))for(let i=0;i<e;i++){const r=n[i];if(!Array.isArray(r))continue;const o=r[0];if(typeof o!="string"||o.length===0)continue;const c=r[1];c!=null&&f(t,u(o),typeof c=="string"?c:String(c))}else for(let i=0;i<e;i+=2){const r=n[i];if(typeof r!="string"||r.length===0)continue;const o=n[i+1];o!=null&&f(t,u(r),typeof o=="string"?o:String(o))}return t}export function normalizeBody(n,t){return n==="GET"||n==="HEAD"?void 0:t}function g(n){const t=n["content-type"];if(typeof t=="string")return t;if(Array.isArray(t))return t[0]}export function normalizeBodyForTransport(n,t){return n==null?n:typeof URLSearchParams<"u"&&n instanceof URLSearchParams?(g(t)||(t["content-type"]="application/x-www-form-urlencoded"),n.toString()):typeof n=="object"&&n!==null&&!(n instanceof Uint8Array)&&!(n instanceof ArrayBuffer)&&!(typeof ArrayBuffer<"u"&&ArrayBuffer.isView?.(n))&&!(typeof URLSearchParams<"u"&&n instanceof URLSearchParams)&&!(typeof FormData<"u"&&n instanceof FormData)&&!(typeof Blob<"u"&&n instanceof Blob)&&!(typeof ReadableStream<"u"&&n instanceof ReadableStream)&&!("pipe"in n&&typeof n.pipe=="function")?(g(t)||(t["content-type"]="application/json"),JSON.stringify(n)):n}
1
+ "use strict";import{CacheManager as y}from"hcacher";const u=Object.create(null),p=["content-type","content-length","content-encoding","content-disposition","host","authorization","proxy-authorization","user-agent","referer","origin","location","etag","last-modified"];for(let n=0;n<p.length;n++)u[p[n]]=1;const a=new y({maxSize:2048,ttl:6e4}),l=["accept","accept-encoding","accept-language","authorization","cache-control","connection","content-encoding","content-length","content-type","cookie","date","etag","host","if-modified-since","if-none-match","keep-alive","location","origin","pragma","proxy-authorization","referer","sec-ch-ua","server","set-cookie","transfer-encoding","user-agent","x-forwarded-for","x-requested-with"];for(let n=0;n<l.length;n++){const t=l[n];a.set(t,t)}function s(n){const t=a.get(n);if(t!==void 0)return t;const e=n.toLowerCase();return a.set(n,e),e}export function normalizeUrl(n){if(typeof n=="string")return n;if(n&&typeof n=="object"){const t=n,e=t.url;if(typeof e=="string")return e;if(e!=null)return String(e);const i=t._url;if(typeof i=="string")return i;if(i!=null)return String(i);const r=t.scheme,o=t.host,f=t.path;if(typeof r=="string"&&typeof o=="string"&&typeof f=="string")return r+"://"+o+f}throw new Error("URL missing in request")}function d(n){const t=n.length;for(let e=0;e<t;e++){const i=n.charCodeAt(e);if(i===10||i===13)return!0}return!1}function c(n,t,e){if(d(e)&&(e=e.replace(/[\r\n]/g,"")),u[t]===1){n[t]=e;return}const i=n[t];if(i===void 0){n[t]=t==="set-cookie"?[e]:e;return}if(t==="set-cookie"){Array.isArray(i)?i.push(e):n[t]=[i,e];return}if(t==="cookie"||t==="cookie2"){n[t]=i+"; "+e;return}n[t]=i+", "+e}function m(n,t,e){if(e!=null){if(Array.isArray(e)){const i=e.length;for(let r=0;r<i;r++){const o=e[r];o!=null&&c(n,t,typeof o=="string"?o:String(o))}return}c(n,t,typeof e=="string"?e:String(e))}}export function normalizeHeaders(n,t=Object.create(null)){if(!n||typeof n!="object")return t;if(!Array.isArray(n)){for(const i in n)if(Object.prototype.hasOwnProperty.call(n,i)){const r=n[i];r!=null&&m(t,s(i),r)}return t}const e=n.length;if(e===0)return t;if(Array.isArray(n[0]))for(let i=0;i<e;i++){const r=n[i];if(!Array.isArray(r))continue;const o=r[0];if(typeof o!="string"||o.length===0)continue;const f=r[1];f!=null&&c(t,s(o),typeof f=="string"?f:String(f))}else for(let i=0;i<e;i+=2){const r=n[i];if(typeof r!="string"||r.length===0)continue;const o=n[i+1];o!=null&&c(t,s(r),typeof o=="string"?o:String(o))}return t}export function normalizeBody(n,t){return n==="GET"||n==="HEAD"?void 0:t}function g(n){const t=n["content-type"];if(typeof t=="string")return t;if(Array.isArray(t))return t[0]}export function normalizeBodyForTransport(n,t){return n==null?n:typeof URLSearchParams<"u"&&n instanceof URLSearchParams?(g(t)||(t["content-type"]="application/x-www-form-urlencoded"),n.toString()):typeof n=="object"&&n!==null&&!(n instanceof Uint8Array)&&!(n instanceof ArrayBuffer)&&!(typeof ArrayBuffer<"u"&&ArrayBuffer.isView?.(n))&&!(typeof URLSearchParams<"u"&&n instanceof URLSearchParams)&&!(typeof FormData<"u"&&n instanceof FormData)&&!(typeof Blob<"u"&&n instanceof Blob)&&!(typeof ReadableStream<"u"&&n instanceof ReadableStream)&&!("pipe"in n&&typeof n.pipe=="function")?(g(t)||(t["content-type"]="application/json"),JSON.stringify(n)):n}
2
2
  //# sourceMappingURL=normalize.js.map