@autofleet/rapido-http-client 0.0.7 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,`__esModule`,{value:!0});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const c=require(`./utils-Dh5SqGdK.cjs`);let l=require(`node:http`),u=require(`undici`);u=s(u);let d=require(`@autofleet/outbreak`);const f=Symbol.for(`RapidoHttpClientErrorBrand`);let p;(function(e){e.UndiciError=u.errors.UndiciError,e.ConnectTimeoutError=u.errors.ConnectTimeoutError,e.HeadersTimeoutError=u.errors.HeadersTimeoutError,e.HeadersOverflowError=u.errors.HeadersOverflowError,e.BodyTimeoutError=u.errors.BodyTimeoutError,e.ResponseError=u.errors.ResponseError,e.InvalidArgumentError=u.errors.InvalidArgumentError,e.InvalidReturnValueError=u.errors.InvalidReturnValueError,e.RequestAbortedError=u.errors.RequestAbortedError,e.InformationalError=u.errors.InformationalError,e.RequestContentLengthMismatchError=u.errors.RequestContentLengthMismatchError,e.ResponseContentLengthMismatchError=u.errors.ResponseContentLengthMismatchError,e.ClientDestroyedError=u.errors.ClientDestroyedError,e.ClientClosedError=u.errors.ClientClosedError,e.SocketError=u.errors.SocketError,e.NotSupportedError=u.errors.NotSupportedError,e.BalancedPoolMissingUpstreamError=u.errors.BalancedPoolMissingUpstreamError,e.HTTPParserError=u.errors.HTTPParserError,e.ResponseExceededMaxSizeError=u.errors.ResponseExceededMaxSizeError,e.RequestRetryError=u.errors.RequestRetryError,e.SecureProxyConnectionError=u.errors.SecureProxyConnectionError,e.MaxOriginsReachedError=u.errors.MaxOriginsReachedError;function t(e){return typeof e==`object`&&!!e&&f in e}e.isRapidoHttpClientError=t;class n extends u.errors.ResponseError{constructor(e,t,n,r){super(`HTTP Error ${t.statusCode}`,t.statusCode,{headers:t.headers,body:e}),this.response=t,this.data=n,this.status=t.statusCode,this.statusText=l.STATUS_CODES[t.statusCode]||`Unknown Status`,r?.cause&&(this.cause=r.cause),Object.defineProperty(this,f,{value:!0,enumerable:!1,writable:!1})}static isRapidoHttpClientError(e){return t(e)}}e.RapidoHttpClientError=n})(p||={});const m=Symbol(`testAgentParam`),h=e=>function(t,n){let r=(0,d.getCurrentContext)().context;if(r){let e;e=Array.isArray(t.headers)?Object.fromEntries(t.headers):{...t.headers};for(let[t,n]of r)typeof n==`symbol`||n===void 0||(e[t]=n);t.headers=e}return e(t,n)},{cacheStores:g}=u.default,{cache:_,retry:v,decompress:y}=u.interceptors,b=[`GET`,`HEAD`,`OPTIONS`,`PUT`,`DELETE`,`TRACE`,`QUERY`];var x=class{#e;get(e,t){return this.#i(`GET`,e,void 0,t)}post(e,t,n){return this.#i(`POST`,e,t,n)}delete(e,t){return this.#i(`DELETE`,e,void 0,t)}head(e,t){return this.#i(`HEAD`,e,void 0,t)}put(e,t,n){return this.#i(`PUT`,e,t,n)}patch(e,t,n){return this.#i(`PATCH`,e,t,n)}options(e,t){return this.#i(`OPTIONS`,e,void 0,t)}query(e,t,n){return this.#i(`QUERY`,e,t,n)}constructor(e){this.#e=e.logger,this.settings=c.o(e.autoDecompress?c.i:c.r,e),this.#t();let t=globalThis.__RAPIDO_HTTP_CLIENT_MOCK_AGENT__;this.client=this.settings[m]??t??new u.Agent({connect:{timeout:this.settings.timeout},keepAliveTimeout:this.settings.keepAliveTimeout,keepAliveMaxTimeout:this.settings.keepAliveMaxTimeout,connections:this.settings.connections}),this.settings.cache&&(this.client=this.client.compose(_({store:new g.MemoryCacheStore({...this.settings.cache})}))),this.settings.retries&&(this.client=this.client.compose(v({methods:b,...this.settings.retries,retry:(e,t,n)=>{let{counter:r}=t.state,i=t.opts.retryOptions?.maxRetries??5;(this.settings.retries?.retry??c.n)(e,t,a=>{if(!a){let{method:n,origin:a,path:o}=t.opts,s=!a||typeof a==`string`?a:a.origin;this.#e.warn(`Request retry attempt ${r}/${i}: ${c.t(n,s,o)}`,{err:e})}n(a)})}}))),this.settings.autoDecompress&&(this.client=this.client.compose(y({skipErrorResponses:!1}))),this.client=this.client.compose(h)}#t(){let e=c.c(this.settings),t=new URL(e);this.settings.baseURL=t.origin,this.settings.basePath=t.pathname===`/`?``:t.pathname}#n(e,t){if(!e&&!t)return{signal:void 0,timeoutSignal:void 0};if(e&&!t)return{signal:e,timeoutSignal:void 0};let n=AbortSignal.timeout(t);return!e&&t?{signal:n,timeoutSignal:n}:{signal:AbortSignal.any([e,n]),timeoutSignal:n}}#r(e,t){if(e!=null){if(c.a(e))return!t[`Content-Type`]&&!t[`content-type`]&&(t[`Content-Type`]=`application/x-www-form-urlencoded`),e;if(typeof e==`object`&&!Buffer.isBuffer(e)){let n=t[`Content-Type`]||t[`content-type`];if(n&&/application\/x-www-form-urlencoded/i.test(n)){let t=new URLSearchParams;for(let[n,r]of Object.entries(e))Array.isArray(r)?r.forEach(e=>t.append(n,String(e))):r!=null&&t.append(n,String(r));return t.toString()}return!t[`Content-Type`]&&!t[`content-type`]&&(t[`Content-Type`]=`application/json`),JSON.stringify(e)}else if(typeof e==`string`)return e;else if(Buffer.isBuffer(e))return e;return String(e)}}async#i(e,t,n,r={}){let i=c.o(this.settings,r);if(i.signal?.aborted)throw this.#e.error(`Request aborted before start: ${c.t(e,i.baseURL,t)}`),new p.RequestAbortedError(i.signal.reason?.message||`Request aborted`,{cause:i.signal.reason});let a={...i.headers},o=this.#r(n,a),{origin:s,path:u}=c.s(t,i.baseURL,i.basePath),d={method:e,baseURL:s,url:t};if(i.params)for(let[e,t]of Object.entries(i.params))Array.isArray(t)&&!e.endsWith(`[]`)&&(i.params[`${e}[]`]=t,delete i.params[e]);let{signal:f,timeoutSignal:m}=this.#n(i.signal,i.timeout);try{this.#e.info(`Start Request: ${c.t(e,s,u)}`);let t={path:u,origin:s,method:e,signal:f,headers:a,body:o,query:i.params},n=await this.client.request(t);if(!(i.validateStatus??(()=>n.statusCode<400))(n.statusCode)){let t=await this.#a(o,n,r.responseSchema);throw this.#e.error(`Finish Request with error ${c.t(e,s,u)}`,{status:n.statusCode,data:t}),new p.RapidoHttpClientError(o,n,t)}return this.#e.info(`Finish Request: ${c.t(e,s,u)}`),{data:n.statusCode===204?void 0:await this.#a(o,n,r.responseSchema),status:n.statusCode,statusText:l.STATUS_CODES[n.statusCode]||``,headers:n.headers,config:d}}catch(t){if(m&&m.reason===t){this.#e.error(`Request timeout: ${c.t(e,s,u)}`);let t=new p.UndiciError(`Request timeout after ${i.timeout}ms`,{cause:m.reason});throw t.code=`UND_ERR_TIMEOUT`,t}throw f&&f.reason===t?(this.#e.error(`Request aborted: ${c.t(e,s,u)}`),new p.RequestAbortedError(f.reason.message,{cause:f.reason})):(this.#e.error(`Finish Request with error ${c.t(e,s,u)}`,{error:t}),t)}}async#a(e,t,n){let r=t.headers[`content-type`]||``,i=await t.body.text();if(!i)return;if(/text/i.test(r))return i;let a;try{a=JSON.parse(i)}catch(r){if(!n)return i;let a=n.safeParse(i);if(a.success)return a.data;throw new p.RapidoHttpClientError(e,t,void 0,{cause:r})}return n
|
|
1
|
+
Object.defineProperty(exports,`__esModule`,{value:!0});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const c=require(`./utils-Dh5SqGdK.cjs`);let l=require(`node:http`),u=require(`undici`);u=s(u);let d=require(`@autofleet/outbreak`);const f=Symbol.for(`RapidoHttpClientErrorBrand`);let p;(function(e){e.UndiciError=u.errors.UndiciError,e.ConnectTimeoutError=u.errors.ConnectTimeoutError,e.HeadersTimeoutError=u.errors.HeadersTimeoutError,e.HeadersOverflowError=u.errors.HeadersOverflowError,e.BodyTimeoutError=u.errors.BodyTimeoutError,e.ResponseError=u.errors.ResponseError,e.InvalidArgumentError=u.errors.InvalidArgumentError,e.InvalidReturnValueError=u.errors.InvalidReturnValueError,e.RequestAbortedError=u.errors.RequestAbortedError,e.InformationalError=u.errors.InformationalError,e.RequestContentLengthMismatchError=u.errors.RequestContentLengthMismatchError,e.ResponseContentLengthMismatchError=u.errors.ResponseContentLengthMismatchError,e.ClientDestroyedError=u.errors.ClientDestroyedError,e.ClientClosedError=u.errors.ClientClosedError,e.SocketError=u.errors.SocketError,e.NotSupportedError=u.errors.NotSupportedError,e.BalancedPoolMissingUpstreamError=u.errors.BalancedPoolMissingUpstreamError,e.HTTPParserError=u.errors.HTTPParserError,e.ResponseExceededMaxSizeError=u.errors.ResponseExceededMaxSizeError,e.RequestRetryError=u.errors.RequestRetryError,e.SecureProxyConnectionError=u.errors.SecureProxyConnectionError,e.MaxOriginsReachedError=u.errors.MaxOriginsReachedError;function t(e){return typeof e==`object`&&!!e&&f in e}e.isRapidoHttpClientError=t;class n extends u.errors.ResponseError{constructor(e,t,n,r){super(`HTTP Error ${t.statusCode}`,t.statusCode,{headers:t.headers,body:e}),this.response=t,this.data=n,this.status=t.statusCode,this.statusText=l.STATUS_CODES[t.statusCode]||`Unknown Status`,r?.cause&&(this.cause=r.cause),Object.defineProperty(this,f,{value:!0,enumerable:!1,writable:!1})}static isRapidoHttpClientError(e){return t(e)}}e.RapidoHttpClientError=n})(p||={});const m=Symbol(`testAgentParam`),h=e=>function(t,n){let r=(0,d.getCurrentContext)().context;if(r){let e;e=Array.isArray(t.headers)?Object.fromEntries(t.headers):{...t.headers};for(let[t,n]of r)typeof n==`symbol`||n===void 0||(e[t]=n);t.headers=e}return e(t,n)},{cacheStores:g}=u.default,{cache:_,retry:v,decompress:y}=u.interceptors,b=[`GET`,`HEAD`,`OPTIONS`,`PUT`,`DELETE`,`TRACE`,`QUERY`];var x=class{#e;get(e,t){return this.#i(`GET`,e,void 0,t)}post(e,t,n){return this.#i(`POST`,e,t,n)}delete(e,t){return this.#i(`DELETE`,e,void 0,t)}head(e,t){return this.#i(`HEAD`,e,void 0,t)}put(e,t,n){return this.#i(`PUT`,e,t,n)}patch(e,t,n){return this.#i(`PATCH`,e,t,n)}options(e,t){return this.#i(`OPTIONS`,e,void 0,t)}query(e,t,n){return this.#i(`QUERY`,e,t,n)}constructor(e){this.#e=e.logger,this.settings=c.o(e.autoDecompress?c.i:c.r,e),this.#t();let t=globalThis.__RAPIDO_HTTP_CLIENT_MOCK_AGENT__;this.client=this.settings[m]??t??new u.Agent({connect:{timeout:this.settings.timeout},keepAliveTimeout:this.settings.keepAliveTimeout,keepAliveMaxTimeout:this.settings.keepAliveMaxTimeout,connections:this.settings.connections}),this.settings.cache&&(this.client=this.client.compose(_({store:new g.MemoryCacheStore({...this.settings.cache})}))),this.settings.retries&&(this.client=this.client.compose(v({methods:b,...this.settings.retries,retry:(e,t,n)=>{let{counter:r}=t.state,i=t.opts.retryOptions?.maxRetries??5;(this.settings.retries?.retry??c.n)(e,t,a=>{if(!a){let{method:n,origin:a,path:o}=t.opts,s=!a||typeof a==`string`?a:a.origin;this.#e.warn(`Request retry attempt ${r}/${i}: ${c.t(n,s,o)}`,{err:e})}n(a)})}}))),this.settings.autoDecompress&&(this.client=this.client.compose(y({skipErrorResponses:!1}))),this.client=this.client.compose(h)}#t(){let e=c.c(this.settings),t=new URL(e);this.settings.baseURL=t.origin,this.settings.basePath=t.pathname===`/`?``:t.pathname}#n(e,t){if(!e&&!t)return{signal:void 0,timeoutSignal:void 0};if(e&&!t)return{signal:e,timeoutSignal:void 0};let n=AbortSignal.timeout(t);return!e&&t?{signal:n,timeoutSignal:n}:{signal:AbortSignal.any([e,n]),timeoutSignal:n}}#r(e,t){if(e!=null){if(c.a(e))return!t[`Content-Type`]&&!t[`content-type`]&&(t[`Content-Type`]=`application/x-www-form-urlencoded`),e;if(typeof e==`object`&&!Buffer.isBuffer(e)){let n=t[`Content-Type`]||t[`content-type`];if(n&&/application\/x-www-form-urlencoded/i.test(n)){let t=new URLSearchParams;for(let[n,r]of Object.entries(e))Array.isArray(r)?r.forEach(e=>t.append(n,String(e))):r!=null&&t.append(n,String(r));return t.toString()}return!t[`Content-Type`]&&!t[`content-type`]&&(t[`Content-Type`]=`application/json`),JSON.stringify(e)}else if(typeof e==`string`)return e;else if(Buffer.isBuffer(e))return e;return String(e)}}async#i(e,t,n,r={}){let i=c.o(this.settings,r);if(i.signal?.aborted)throw this.#e.error(`Request aborted before start: ${c.t(e,i.baseURL,t)}`),new p.RequestAbortedError(i.signal.reason?.message||`Request aborted`,{cause:i.signal.reason});let a={...i.headers},o=this.#r(n,a),{origin:s,path:u}=c.s(t,i.baseURL,i.basePath),d={method:e,baseURL:s,url:t};if(i.params)for(let[e,t]of Object.entries(i.params))Array.isArray(t)&&!e.endsWith(`[]`)&&(i.params[`${e}[]`]=t,delete i.params[e]);let{signal:f,timeoutSignal:m}=this.#n(i.signal,i.timeout);try{this.#e.info(`Start Request: ${c.t(e,s,u)}`);let t={path:u,origin:s,method:e,signal:f,headers:a,body:o,query:i.params},n=await this.client.request(t);if(!(i.validateStatus??(()=>n.statusCode<400))(n.statusCode)){let t=await this.#a(o,n,r.responseSchema);throw this.#e.error(`Finish Request with error ${c.t(e,s,u)}`,{status:n.statusCode,data:t}),new p.RapidoHttpClientError(o,n,t)}return this.#e.info(`Finish Request: ${c.t(e,s,u)}`),{data:n.statusCode===204?void 0:await this.#a(o,n,r.responseSchema),status:n.statusCode,statusText:l.STATUS_CODES[n.statusCode]||``,headers:n.headers,config:d}}catch(t){if(m&&m.reason===t){this.#e.error(`Request timeout: ${c.t(e,s,u)}`);let t=new p.UndiciError(`Request timeout after ${i.timeout}ms`,{cause:m.reason});throw t.code=`UND_ERR_TIMEOUT`,t}throw f&&f.reason===t?(this.#e.error(`Request aborted: ${c.t(e,s,u)}`),new p.RequestAbortedError(f.reason.message,{cause:f.reason})):(this.#e.error(`Finish Request with error ${c.t(e,s,u)}`,{error:t}),t)}}async#a(e,t,n){let r=t.headers[`content-type`]||``,i=await t.body.text();if(!i)return;if(/text/i.test(r))return i;let a;try{a=JSON.parse(i)}catch(r){if(!n)return i;let a=n.safeParse(i);if(a.success)return a.data;throw new p.RapidoHttpClientError(e,t,void 0,{cause:r})}if(!n)return a;let o=n.safeParse(a);if(o.success)return o.data;throw Object.assign(o.error,{json:a})}async getAllPages(e,t={}){let n=[],r=null,i=null,a={...t,params:{...t.params,page:1}};for(a.params.page||=1;(a.params.page===1||i===r)&&i!==0;){let{data:t}=await this.get(e,a);i=t.length,a.params.page===1&&(r=t.length),a.params.page+=1,Array.prototype.push.apply(n,t)}return n}async getAllPagesFromQueryEndpoint(e,t={},n=100){let r=[],i=!0,a=1;for(;i&&(n===-1||a<n);){let{data:n}=await this.post(e,{...t,page:a}),{rows:o,count:s}=n;a+=1,Array.prototype.push.apply(r,o),i=r.length<s}return r}async close(){await this.client.close()}async[Symbol.asyncDispose](){await this.close()}},S=x;exports.RapidoHttpClient=x,exports.default=S,Object.defineProperty(exports,`errors`,{enumerable:!0,get:function(){return p}}),exports.t=s;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["undiciErrors","response: Dispatcher.ResponseData","data: T","STATUS_CODES","testAgentParam: unique symbol","outbreakInterceptor: Dispatcher.DispatcherComposeInterceptor","headers: Record<string, string | string[]>","Undici","interceptors","retriableMethods: Dispatcher.HttpMethod[]","#logger","#request","mergeConfig","defaultSettingsWithDecompress","defaultSettings","#createBaseUrl","Agent","defaultRetryMethod","createRequestString","resolveServiceUrl","isFormData","headers: Record<string, string>","#prepareRequestBody","parseUrlAndOrigin","#getSignal","requestOptions: Dispatcher.RequestOptions","#parseResponse","STATUS_CODES","error","json: unknown","currentResult: T[]","resultsInFirstPage: number | null","lastResultsSize: number | null"],"sources":["../src/errors.ts","../src/testingHelper.ts","../src/outbreakInterceptor.ts","../src/index.ts"],"sourcesContent":["import { STATUS_CODES } from 'node:http';\nimport { type Dispatcher, errors as undiciErrors } from 'undici';\n\nconst RapidoHttpClientErrorBrand = Symbol.for('RapidoHttpClientErrorBrand');\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace errors {\n export import UndiciError = undiciErrors.UndiciError;\n export import ConnectTimeoutError = undiciErrors.ConnectTimeoutError;\n export import HeadersTimeoutError = undiciErrors.HeadersTimeoutError;\n export import HeadersOverflowError = undiciErrors.HeadersOverflowError;\n export import BodyTimeoutError = undiciErrors.BodyTimeoutError;\n export import ResponseError = undiciErrors.ResponseError;\n export import InvalidArgumentError = undiciErrors.InvalidArgumentError;\n export import InvalidReturnValueError = undiciErrors.InvalidReturnValueError;\n export import RequestAbortedError = undiciErrors.RequestAbortedError;\n export import InformationalError = undiciErrors.InformationalError;\n export import RequestContentLengthMismatchError = undiciErrors.RequestContentLengthMismatchError;\n export import ResponseContentLengthMismatchError = undiciErrors.ResponseContentLengthMismatchError;\n export import ClientDestroyedError = undiciErrors.ClientDestroyedError;\n export import ClientClosedError = undiciErrors.ClientClosedError;\n export import SocketError = undiciErrors.SocketError;\n export import NotSupportedError = undiciErrors.NotSupportedError;\n export import BalancedPoolMissingUpstreamError = undiciErrors.BalancedPoolMissingUpstreamError;\n export import HTTPParserError = undiciErrors.HTTPParserError;\n export import ResponseExceededMaxSizeError = undiciErrors.ResponseExceededMaxSizeError;\n export import RequestRetryError = undiciErrors.RequestRetryError;\n export import SecureProxyConnectionError = undiciErrors.SecureProxyConnectionError;\n export import MaxOriginsReachedError = undiciErrors.MaxOriginsReachedError;\n\n export function isRapidoHttpClientError(value: unknown): value is RapidoHttpClientError<unknown> {\n return typeof value === 'object' && value !== null && RapidoHttpClientErrorBrand in value;\n }\n\n export class RapidoHttpClientError<T> extends undiciErrors.ResponseError {\n public readonly status: number;\n public readonly statusText: string;\n\n constructor(\n body: ConstructorParameters<typeof undiciErrors.ResponseError>[2]['body'],\n public readonly response: Dispatcher.ResponseData,\n public readonly data: T,\n errorOptions?: ErrorOptions,\n ) {\n super(`HTTP Error ${response.statusCode}`, response.statusCode, { headers: response.headers, body });\n this.status = response.statusCode;\n this.statusText = STATUS_CODES[response.statusCode] || 'Unknown Status';\n if (errorOptions?.cause) {\n this.cause = errorOptions.cause;\n }\n\n Object.defineProperty(this, RapidoHttpClientErrorBrand, {\n value: true,\n enumerable: false,\n writable: false,\n });\n }\n\n public static isRapidoHttpClientError(value: unknown): value is RapidoHttpClientError<unknown> {\n return isRapidoHttpClientError(value);\n }\n }\n}\n","export const testAgentParam: unique symbol = Symbol('testAgentParam');\n","import type { Dispatcher } from 'undici';\nimport { getCurrentContext } from '@autofleet/outbreak';\n\nexport const outbreakInterceptor: Dispatcher.DispatcherComposeInterceptor = dispatch => function outbreakInterceptorInner(opts, handler) {\n const currentTraceContext = getCurrentContext().context;\n if (currentTraceContext) {\n // Convert headers to object format if they're in array format\n let headers: Record<string, string | string[]>;\n if (Array.isArray(opts.headers)) {\n /* c8 ignore next */\n headers = Object.fromEntries(opts.headers as unknown as [string, string | string[]][]);\n } else {\n headers = { ...opts.headers as Record<string, string | string[]> };\n }\n\n // Inject outbreak trace headers\n for (const [header, value] of currentTraceContext) {\n if (typeof value === 'symbol' || typeof value === 'undefined') {\n continue;\n }\n headers[header] = value as string;\n }\n opts.headers = headers;\n }\n return dispatch(opts, handler);\n};\n","import { STATUS_CODES } from 'node:http';\nimport type { ZodType, output } from 'zod';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\nimport type CacheHandler from 'undici/types/cache-interceptor';\nimport Undici, { Agent, type Dispatcher, interceptors } from 'undici';\nimport { errors } from './errors';\nimport { testAgentParam } from './testingHelper';\nimport { outbreakInterceptor } from './outbreakInterceptor';\nimport {\n createRequestString,\n defaultRetryMethod,\n defaultSettings,\n defaultSettingsWithDecompress,\n isFormData,\n mergeConfig,\n parseUrlAndOrigin,\n resolveServiceUrl,\n} from './utils';\n\nconst { cacheStores } = Undici;\nconst { cache, retry, decompress } = interceptors;\n\nexport interface RapidoHttpClientSettings {\n [testAgentParam]?: Dispatcher;\n /** The MS name to be used to resolve the base URL using K8S service discovery. Ignored if `serviceUrl` is provided as well. */\n serviceName?: string;\n /** The base URL to be used. Overrides `serviceName` when provided. */\n serviceUrl?: string;\n logger: LoggerInstanceManager;\n /** The request timeout in milliseconds. @default 10_000 */\n timeout?: number;\n /** Settings for retrying requests on failure */\n retries?: interceptors.RetryInterceptorOpts;\n /** Common headers applied to all requests of this `RapidoHttpClient` instance. */\n headers?: Record<string, string> | string[][];\n keepAliveTimeout?: number;\n keepAliveMaxTimeout?: number;\n /** The amount of concurrent connections to be maintained using a connection pool. @default 10 */\n connections?: number;\n /** The settings for caching requests */\n cache?: CacheHandler.MemoryCacheStoreOpts;\n /** Whether to automatically decompress response bodies. When `true` will automatically add an `Accept-Encoding` header. @default false */\n autoDecompress?: boolean;\n /**\n * A function to validate the HTTP response status code.\n * Return `true` to consider the status valid, `false` otherwise.\n *\n * When status is invalid, a {@link errors.RapidoHttpClientError `RapidoHttpClientError`} will be thrown.\n *\n * @example (status) => status >= 200 && status < 300\n * @example (status) => status !== 401\n *\n * @default (status) => status < 400\n */\n validateStatus?(status: number): boolean;\n}\n\nexport interface RequestConfig {\n params?: Record<string, any>;\n body?: any;\n /** The request timeout in milliseconds. This overrides the client's instance setting @default 10_000 */\n timeout?: number;\n /** Headers applied to this request, appending on the client's common headers. */\n headers?: Record<string, string>;\n /** An `AbortSignal` which should abort the request and it's parsing when aborted. */\n signal?: AbortSignal;\n /** A Zod schema defining what the response should look like. This also parses error responses. */\n responseSchema?: ZodType;\n /**\n * A function to validate the HTTP response status code.\n * Return `true` to consider the status valid, `false` otherwise.\n *\n * When status is invalid, a {@link errors.RapidoHttpClientError `RapidoHttpClientError`} will be thrown.\n *\n * @example (status) => status >= 200 && status < 300\n * @example (status) => status !== 401\n *\n * @default (status) => status < 400\n */\n validateStatus?(status: number): boolean;\n}\n\nexport interface RapidoHttpClientResponse<T = any> {\n data: T;\n status: number;\n statusText: string;\n headers: Record<string, string | string[]>;\n config: RequestConfig & { url: string; method: string; baseURL?: string; };\n}\n\nconst retriableMethods: Dispatcher.HttpMethod[] = ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE', 'QUERY'];\n\nexport class RapidoHttpClient {\n readonly #logger: LoggerInstanceManager;\n private readonly settings: RapidoHttpClientSettings & { baseURL?: string; basePath?: string; };\n public readonly client: Dispatcher.ComposedDispatcher;\n\n public get<T = unknown>(url: string, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public get<T extends ZodType>(url: string, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public get<T = unknown>(url: string, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('GET', url, undefined, config);\n }\n\n public post<T = unknown>(url: string, body?: any, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public post<T extends ZodType>(url: string, body: any, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public post<T = unknown>(url: string, body?: any, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('POST', url, body, config);\n }\n\n public delete<T = unknown>(url: string, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public delete<T extends ZodType>(url: string, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public delete<T = unknown>(url: string, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('DELETE', url, undefined, config);\n }\n\n public head<T = unknown>(url: string, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public head<T extends ZodType>(url: string, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public head<T = unknown>(url: string, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('HEAD', url, undefined, config);\n }\n\n public put<T = unknown>(url: string, body?: any, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public put<T extends ZodType>(url: string, body: any, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public put<T = unknown>(url: string, body?: any, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('PUT', url, body, config);\n }\n\n public patch<T = unknown>(url: string, body?: any, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public patch<T extends ZodType>(url: string, body: any, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public patch<T = unknown>(url: string, body?: any, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('PATCH', url, body, config);\n }\n\n public options<T = unknown>(url: string, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public options<T extends ZodType>(url: string, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public options<T = unknown>(url: string, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('OPTIONS', url, undefined, config);\n }\n\n public query<T = unknown>(url: string, body?: any, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public query<T extends ZodType>(url: string, body: any, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public query<T = unknown>(url: string, body?: any, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('QUERY', url, body, config);\n }\n\n constructor(settings: RapidoHttpClientSettings) {\n this.#logger = settings.logger;\n this.settings = mergeConfig<typeof defaultSettings, Partial<typeof settings>>(\n settings.autoDecompress ? defaultSettingsWithDecompress : defaultSettings,\n settings,\n ) as RapidoHttpClientSettings & { baseURL?: string; };\n this.#createBaseUrl();\n\n // In test mode, use the test dispatcher directly (MockAgent or MockPool) Otherwise, create an Agent which creates Client Pools\n // Check for global mock agent first (for testing), then test param, then create real Agent\n /* c8 ignore next */\n const globalMockAgent = (globalThis as any).__RAPIDO_HTTP_CLIENT_MOCK_AGENT__;\n /* c8 ignore next */\n this.client = this.settings[testAgentParam] ?? globalMockAgent ?? new Agent({\n connect: {\n timeout: this.settings.timeout,\n },\n keepAliveTimeout: this.settings.keepAliveTimeout,\n keepAliveMaxTimeout: this.settings.keepAliveMaxTimeout,\n connections: this.settings.connections,\n });\n\n if (this.settings.cache) {\n this.client = this.client.compose(cache({\n store: new cacheStores.MemoryCacheStore({\n ...this.settings.cache,\n }),\n }));\n }\n\n if (this.settings.retries) {\n this.client = this.client.compose(retry({\n methods: retriableMethods,\n ...this.settings.retries,\n retry: (err, context, callback) => {\n const { counter } = context.state;\n /* c8 ignore next */\n const maxRetries = context.opts.retryOptions?.maxRetries ?? 5;\n\n const retryToUse = this.settings.retries?.retry ?? defaultRetryMethod;\n const callbackWithLogging = (result?: Error | null) => {\n if (!result) {\n const { method, origin, path } = context.opts;\n const baseUrl = (!origin || typeof origin === 'string') ? origin : origin.origin;\n this.#logger.warn(`Request retry attempt ${counter}/${maxRetries}: ${createRequestString(method, baseUrl, path)}`, { err });\n }\n callback(result);\n };\n retryToUse(err, context, callbackWithLogging);\n },\n }));\n }\n\n if (this.settings.autoDecompress) {\n this.client = this.client.compose(decompress({ skipErrorResponses: false }));\n }\n\n this.client = this.client.compose(outbreakInterceptor);\n }\n\n #createBaseUrl(): void {\n const fullUrl = resolveServiceUrl(this.settings);\n const urlObj = new URL(fullUrl);\n this.settings.baseURL = urlObj.origin;\n this.settings.basePath = urlObj.pathname !== '/' ? urlObj.pathname : '';\n }\n\n #getSignal(currentSignal?: AbortSignal, timeout?: number): { signal?: AbortSignal; timeoutSignal?: AbortSignal; } {\n if (!currentSignal && !timeout) {\n return { signal: undefined, timeoutSignal: undefined };\n }\n\n if (currentSignal && !timeout) {\n return { signal: currentSignal, timeoutSignal: undefined };\n }\n\n const timeoutSignal = AbortSignal.timeout(timeout!);\n if (!currentSignal && timeout) {\n return { signal: timeoutSignal, timeoutSignal };\n }\n\n return { signal: AbortSignal.any([currentSignal!, timeoutSignal]), timeoutSignal };\n }\n\n #prepareRequestBody(body: any, headers: Record<string, string>): string | Buffer | FormData | undefined {\n if (body === undefined || body === null) {\n return undefined;\n }\n\n // Handle FormData instances automatically\n if (isFormData(body)) {\n if (!headers['Content-Type'] && !headers['content-type']) {\n headers['Content-Type'] = 'application/x-www-form-urlencoded';\n }\n return body;\n }\n\n if (typeof body === 'object' && !Buffer.isBuffer(body)) {\n // Check if Content-Type is set to application/x-www-form-urlencoded\n const contentType = headers['Content-Type'] || headers['content-type'];\n if (contentType && /application\\/x-www-form-urlencoded/i.test(contentType)) {\n // Encode as URL parameters\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(body)) {\n if (Array.isArray(value)) {\n value.forEach(v => params.append(key, String(v)));\n } else if (value !== undefined && value !== null) {\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n params.append(key, String(value));\n }\n }\n return params.toString();\n }\n // Default to JSON\n if (!headers['Content-Type'] && !headers['content-type']) {\n headers['Content-Type'] = 'application/json';\n }\n return JSON.stringify(body);\n } else if (typeof body === 'string') {\n return body;\n } else if (Buffer.isBuffer(body)) {\n return body;\n }\n return String(body);\n }\n\n async #request<T = any>(\n method: Dispatcher.HttpMethod,\n url: string,\n body?: any,\n config: RequestConfig = {},\n ): Promise<RapidoHttpClientResponse<T>> {\n const mergedConfig = mergeConfig(this.settings, config);\n\n if (mergedConfig.signal?.aborted) {\n this.#logger.error(`Request aborted before start: ${createRequestString(method, mergedConfig.baseURL, url)}`);\n throw new errors.RequestAbortedError(mergedConfig.signal.reason?.message || 'Request aborted', { cause: mergedConfig.signal.reason });\n }\n\n const headers: Record<string, string> = { ...mergedConfig.headers };\n const requestBody = this.#prepareRequestBody(body, headers);\n\n const { origin, path } = parseUrlAndOrigin(url, mergedConfig.baseURL!, mergedConfig.basePath);\n const requestInfo = { method, baseURL: origin, url };\n\n if (mergedConfig.params) {\n for (const [key, value] of Object.entries(mergedConfig.params)) {\n if (Array.isArray(value) && !key.endsWith('[]')) {\n mergedConfig.params[`${key}[]`] = value;\n delete mergedConfig.params[key];\n }\n }\n }\n\n const { signal, timeoutSignal } = this.#getSignal(mergedConfig.signal, mergedConfig.timeout);\n\n try {\n this.#logger.info(`Start Request: ${createRequestString(method, origin, path)}`);\n\n const requestOptions: Dispatcher.RequestOptions = {\n path,\n origin,\n method,\n signal,\n headers,\n body: requestBody,\n query: mergedConfig.params,\n };\n\n const response = await this.client.request(requestOptions);\n\n const isStatusValid = mergedConfig.validateStatus ?? (() => response.statusCode < 400);\n if (!isStatusValid(response.statusCode)) {\n const data = await this.#parseResponse<T>(requestBody, response, config.responseSchema);\n this.#logger.error(`Finish Request with error ${createRequestString(method, origin, path)}`, {\n status: response.statusCode,\n data,\n });\n\n throw new errors.RapidoHttpClientError<T>(requestBody, response, data);\n }\n\n this.#logger.info(`Finish Request: ${createRequestString(method, origin, path)}`);\n\n const data = response.statusCode !== 204 ? await this.#parseResponse<T>(requestBody, response, config.responseSchema) : undefined as T;\n\n return {\n data,\n status: response.statusCode,\n statusText: STATUS_CODES[response.statusCode] || '',\n headers: response.headers as Record<string, string | string[]>,\n config: requestInfo,\n };\n } catch (error) {\n if (timeoutSignal && timeoutSignal.reason === error) {\n // If the timeoutSignal aborted (config timeout), throw a timeout-specific error\n this.#logger.error(`Request timeout: ${createRequestString(method, origin, path)}`);\n const error = new errors.UndiciError(`Request timeout after ${mergedConfig.timeout}ms`, { cause: timeoutSignal.reason });\n error.code = 'UND_ERR_TIMEOUT';\n throw error;\n }\n if (signal && signal.reason === error) {\n // If the user's signal aborted, throw RequestAbortedError\n this.#logger.error(`Request aborted: ${createRequestString(method, origin, path)}`);\n throw new errors.RequestAbortedError(signal.reason.message, { cause: signal.reason });\n }\n\n this.#logger.error(`Finish Request with error ${createRequestString(method, origin, path)}`, { error });\n throw error;\n }\n }\n\n async #parseResponse<T>(requestBody: ConstructorParameters<typeof errors.RapidoHttpClientError>[0], response: Dispatcher.ResponseData, schema?: ZodType): Promise<T> {\n const contentType = (response.headers['content-type'] as string) || '';\n const bodyText = await response.body.text();\n\n if (!bodyText) {\n return undefined as T;\n }\n\n if (/text/i.test(contentType)) {\n return bodyText as T;\n }\n\n let json: unknown;\n try {\n json = JSON.parse(bodyText);\n } catch (error) {\n if (!schema) {\n return bodyText as T;\n }\n const parseResult = schema.safeParse(bodyText);\n if (parseResult.success) {\n return parseResult.data as T;\n }\n throw new errors.RapidoHttpClientError(requestBody, response, undefined, { cause: error as Error });\n }\n return (schema ? schema.parse(json) : json) as T;\n }\n\n /**\n * @param url The endpoint URL to send the request to.\n * @param options Additional options to include in the request payload.\n * @returns A promise that resolves to an array of all results.\n */\n async getAllPages<T>(url: string, options: RequestConfig = {}): Promise<T[]> {\n const currentResult: T[] = [];\n let resultsInFirstPage: number | null = null;\n let lastResultsSize: number | null = null;\n\n const localOptions = { ...options, params: { ...options.params, page: 1 } };\n // Make sure even if `options` had `params` we initialize `page` to 1.\n localOptions.params.page ||= 1;\n\n while ((localOptions.params.page === 1 || lastResultsSize === resultsInFirstPage) && lastResultsSize !== 0) {\n const { data } = await this.get<T[]>(url, localOptions as Omit<RequestConfig, 'responseSchema'>);\n lastResultsSize = data.length;\n if (localOptions.params.page === 1) {\n resultsInFirstPage = data.length;\n }\n\n localOptions.params.page += 1;\n Array.prototype.push.apply(currentResult, data);\n }\n\n return currentResult;\n }\n\n /**\n * Fetches all pages from a paginated API endpoint until all results are retrieved\n * or an optional page limit is reached.\n *\n * @param url The endpoint URL to send the request to.\n * @param options Additional options to include in the request payload.\n * @param pageLimit The maximum number of pages to fetch. Set to -1 for no limit.\n * @returns A promise that resolves to an array of all results.\n */\n async getAllPagesFromQueryEndpoint<T>(url: string, options: object = {}, pageLimit = 100): Promise<T[]> {\n const currentResult: T[] = [];\n\n let moreResultsToLoad = true;\n let page = 1;\n while (moreResultsToLoad && (pageLimit === -1 || page < pageLimit)) {\n const { data } = await this.post<{ rows: T[]; count: number; }>(url, {\n ...options,\n page,\n });\n const { rows, count } = data;\n page += 1;\n Array.prototype.push.apply(currentResult, rows);\n moreResultsToLoad = currentResult.length < count;\n }\n\n return currentResult;\n }\n\n async close(): Promise<void> {\n await this.client.close();\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close();\n }\n}\n\nexport default RapidoHttpClient;\nexport { errors };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["undiciErrors","response: Dispatcher.ResponseData","data: T","STATUS_CODES","testAgentParam: unique symbol","outbreakInterceptor: Dispatcher.DispatcherComposeInterceptor","headers: Record<string, string | string[]>","Undici","interceptors","retriableMethods: Dispatcher.HttpMethod[]","#logger","#request","mergeConfig","defaultSettingsWithDecompress","defaultSettings","#createBaseUrl","Agent","defaultRetryMethod","createRequestString","resolveServiceUrl","isFormData","headers: Record<string, string>","#prepareRequestBody","parseUrlAndOrigin","#getSignal","requestOptions: Dispatcher.RequestOptions","#parseResponse","STATUS_CODES","error","json: unknown","parseResult","currentResult: T[]","resultsInFirstPage: number | null","lastResultsSize: number | null"],"sources":["../src/errors.ts","../src/testingHelper.ts","../src/outbreakInterceptor.ts","../src/index.ts"],"sourcesContent":["import { STATUS_CODES } from 'node:http';\nimport { type Dispatcher, errors as undiciErrors } from 'undici';\n\nconst RapidoHttpClientErrorBrand = Symbol.for('RapidoHttpClientErrorBrand');\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace errors {\n export import UndiciError = undiciErrors.UndiciError;\n export import ConnectTimeoutError = undiciErrors.ConnectTimeoutError;\n export import HeadersTimeoutError = undiciErrors.HeadersTimeoutError;\n export import HeadersOverflowError = undiciErrors.HeadersOverflowError;\n export import BodyTimeoutError = undiciErrors.BodyTimeoutError;\n export import ResponseError = undiciErrors.ResponseError;\n export import InvalidArgumentError = undiciErrors.InvalidArgumentError;\n export import InvalidReturnValueError = undiciErrors.InvalidReturnValueError;\n export import RequestAbortedError = undiciErrors.RequestAbortedError;\n export import InformationalError = undiciErrors.InformationalError;\n export import RequestContentLengthMismatchError = undiciErrors.RequestContentLengthMismatchError;\n export import ResponseContentLengthMismatchError = undiciErrors.ResponseContentLengthMismatchError;\n export import ClientDestroyedError = undiciErrors.ClientDestroyedError;\n export import ClientClosedError = undiciErrors.ClientClosedError;\n export import SocketError = undiciErrors.SocketError;\n export import NotSupportedError = undiciErrors.NotSupportedError;\n export import BalancedPoolMissingUpstreamError = undiciErrors.BalancedPoolMissingUpstreamError;\n export import HTTPParserError = undiciErrors.HTTPParserError;\n export import ResponseExceededMaxSizeError = undiciErrors.ResponseExceededMaxSizeError;\n export import RequestRetryError = undiciErrors.RequestRetryError;\n export import SecureProxyConnectionError = undiciErrors.SecureProxyConnectionError;\n export import MaxOriginsReachedError = undiciErrors.MaxOriginsReachedError;\n\n export function isRapidoHttpClientError(value: unknown): value is RapidoHttpClientError<unknown> {\n return typeof value === 'object' && value !== null && RapidoHttpClientErrorBrand in value;\n }\n\n export class RapidoHttpClientError<T> extends undiciErrors.ResponseError {\n public readonly status: number;\n public readonly statusText: string;\n\n constructor(\n body: ConstructorParameters<typeof undiciErrors.ResponseError>[2]['body'],\n public readonly response: Dispatcher.ResponseData,\n public readonly data: T,\n errorOptions?: ErrorOptions,\n ) {\n super(`HTTP Error ${response.statusCode}`, response.statusCode, { headers: response.headers, body });\n this.status = response.statusCode;\n this.statusText = STATUS_CODES[response.statusCode] || 'Unknown Status';\n if (errorOptions?.cause) {\n this.cause = errorOptions.cause;\n }\n\n Object.defineProperty(this, RapidoHttpClientErrorBrand, {\n value: true,\n enumerable: false,\n writable: false,\n });\n }\n\n public static isRapidoHttpClientError(value: unknown): value is RapidoHttpClientError<unknown> {\n return isRapidoHttpClientError(value);\n }\n }\n}\n","export const testAgentParam: unique symbol = Symbol('testAgentParam');\n","import type { Dispatcher } from 'undici';\nimport { getCurrentContext } from '@autofleet/outbreak';\n\nexport const outbreakInterceptor: Dispatcher.DispatcherComposeInterceptor = dispatch => function outbreakInterceptorInner(opts, handler) {\n const currentTraceContext = getCurrentContext().context;\n if (currentTraceContext) {\n // Convert headers to object format if they're in array format\n let headers: Record<string, string | string[]>;\n if (Array.isArray(opts.headers)) {\n /* c8 ignore next */\n headers = Object.fromEntries(opts.headers as unknown as [string, string | string[]][]);\n } else {\n headers = { ...opts.headers as Record<string, string | string[]> };\n }\n\n // Inject outbreak trace headers\n for (const [header, value] of currentTraceContext) {\n if (typeof value === 'symbol' || typeof value === 'undefined') {\n continue;\n }\n headers[header] = value as string;\n }\n opts.headers = headers;\n }\n return dispatch(opts, handler);\n};\n","import { STATUS_CODES } from 'node:http';\nimport type { ZodType, output } from 'zod';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\nimport type CacheHandler from 'undici/types/cache-interceptor';\nimport Undici, { Agent, type Dispatcher, interceptors } from 'undici';\nimport { errors } from './errors';\nimport { testAgentParam } from './testingHelper';\nimport { outbreakInterceptor } from './outbreakInterceptor';\nimport {\n createRequestString,\n defaultRetryMethod,\n defaultSettings,\n defaultSettingsWithDecompress,\n isFormData,\n mergeConfig,\n parseUrlAndOrigin,\n resolveServiceUrl,\n} from './utils';\n\nconst { cacheStores } = Undici;\nconst { cache, retry, decompress } = interceptors;\n\nexport interface RapidoHttpClientSettings {\n [testAgentParam]?: Dispatcher;\n /** The MS name to be used to resolve the base URL using K8S service discovery. Ignored if `serviceUrl` is provided as well. */\n serviceName?: string;\n /** The base URL to be used. Overrides `serviceName` when provided. */\n serviceUrl?: string;\n logger: LoggerInstanceManager;\n /** The request timeout in milliseconds. @default 10_000 */\n timeout?: number;\n /** Settings for retrying requests on failure */\n retries?: interceptors.RetryInterceptorOpts;\n /** Common headers applied to all requests of this `RapidoHttpClient` instance. */\n headers?: Record<string, string> | string[][];\n keepAliveTimeout?: number;\n keepAliveMaxTimeout?: number;\n /** The amount of concurrent connections to be maintained using a connection pool. @default 10 */\n connections?: number;\n /** The settings for caching requests */\n cache?: CacheHandler.MemoryCacheStoreOpts;\n /** Whether to automatically decompress response bodies. When `true` will automatically add an `Accept-Encoding` header. @default false */\n autoDecompress?: boolean;\n /**\n * A function to validate the HTTP response status code.\n * Return `true` to consider the status valid, `false` otherwise.\n *\n * When status is invalid, a {@link errors.RapidoHttpClientError `RapidoHttpClientError`} will be thrown.\n *\n * @example (status) => status >= 200 && status < 300\n * @example (status) => status !== 401\n *\n * @default (status) => status < 400\n */\n validateStatus?(status: number): boolean;\n}\n\nexport interface RequestConfig {\n params?: Record<string, any>;\n body?: any;\n /** The request timeout in milliseconds. This overrides the client's instance setting @default 10_000 */\n timeout?: number;\n /** Headers applied to this request, appending on the client's common headers. */\n headers?: Record<string, string>;\n /** An `AbortSignal` which should abort the request and it's parsing when aborted. */\n signal?: AbortSignal;\n /** A Zod schema defining what the response should look like. This also parses error responses. */\n responseSchema?: ZodType;\n /**\n * A function to validate the HTTP response status code.\n * Return `true` to consider the status valid, `false` otherwise.\n *\n * When status is invalid, a {@link errors.RapidoHttpClientError `RapidoHttpClientError`} will be thrown.\n *\n * @example (status) => status >= 200 && status < 300\n * @example (status) => status !== 401\n *\n * @default (status) => status < 400\n */\n validateStatus?(status: number): boolean;\n}\n\nexport interface RapidoHttpClientResponse<T = any> {\n data: T;\n status: number;\n statusText: string;\n headers: Record<string, string | string[]>;\n config: RequestConfig & { url: string; method: string; baseURL?: string; };\n}\n\nconst retriableMethods: Dispatcher.HttpMethod[] = ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE', 'QUERY'];\n\nexport class RapidoHttpClient {\n readonly #logger: LoggerInstanceManager;\n private readonly settings: RapidoHttpClientSettings & { baseURL?: string; basePath?: string; };\n public readonly client: Dispatcher.ComposedDispatcher;\n\n public get<T = unknown>(url: string, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public get<T extends ZodType>(url: string, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public get<T = unknown>(url: string, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('GET', url, undefined, config);\n }\n\n public post<T = unknown>(url: string, body?: any, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public post<T extends ZodType>(url: string, body: any, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public post<T = unknown>(url: string, body?: any, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('POST', url, body, config);\n }\n\n public delete<T = unknown>(url: string, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public delete<T extends ZodType>(url: string, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public delete<T = unknown>(url: string, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('DELETE', url, undefined, config);\n }\n\n public head<T = unknown>(url: string, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public head<T extends ZodType>(url: string, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public head<T = unknown>(url: string, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('HEAD', url, undefined, config);\n }\n\n public put<T = unknown>(url: string, body?: any, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public put<T extends ZodType>(url: string, body: any, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public put<T = unknown>(url: string, body?: any, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('PUT', url, body, config);\n }\n\n public patch<T = unknown>(url: string, body?: any, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public patch<T extends ZodType>(url: string, body: any, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public patch<T = unknown>(url: string, body?: any, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('PATCH', url, body, config);\n }\n\n public options<T = unknown>(url: string, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public options<T extends ZodType>(url: string, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public options<T = unknown>(url: string, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('OPTIONS', url, undefined, config);\n }\n\n public query<T = unknown>(url: string, body?: any, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public query<T extends ZodType>(url: string, body: any, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public query<T = unknown>(url: string, body?: any, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('QUERY', url, body, config);\n }\n\n constructor(settings: RapidoHttpClientSettings) {\n this.#logger = settings.logger;\n this.settings = mergeConfig<typeof defaultSettings, Partial<typeof settings>>(\n settings.autoDecompress ? defaultSettingsWithDecompress : defaultSettings,\n settings,\n ) as RapidoHttpClientSettings & { baseURL?: string; };\n this.#createBaseUrl();\n\n // In test mode, use the test dispatcher directly (MockAgent or MockPool) Otherwise, create an Agent which creates Client Pools\n // Check for global mock agent first (for testing), then test param, then create real Agent\n /* c8 ignore next */\n const globalMockAgent = (globalThis as any).__RAPIDO_HTTP_CLIENT_MOCK_AGENT__;\n /* c8 ignore next */\n this.client = this.settings[testAgentParam] ?? globalMockAgent ?? new Agent({\n connect: {\n timeout: this.settings.timeout,\n },\n keepAliveTimeout: this.settings.keepAliveTimeout,\n keepAliveMaxTimeout: this.settings.keepAliveMaxTimeout,\n connections: this.settings.connections,\n });\n\n if (this.settings.cache) {\n this.client = this.client.compose(cache({\n store: new cacheStores.MemoryCacheStore({\n ...this.settings.cache,\n }),\n }));\n }\n\n if (this.settings.retries) {\n this.client = this.client.compose(retry({\n methods: retriableMethods,\n ...this.settings.retries,\n retry: (err, context, callback) => {\n const { counter } = context.state;\n /* c8 ignore next */\n const maxRetries = context.opts.retryOptions?.maxRetries ?? 5;\n\n const retryToUse = this.settings.retries?.retry ?? defaultRetryMethod;\n const callbackWithLogging = (result?: Error | null) => {\n if (!result) {\n const { method, origin, path } = context.opts;\n const baseUrl = (!origin || typeof origin === 'string') ? origin : origin.origin;\n this.#logger.warn(`Request retry attempt ${counter}/${maxRetries}: ${createRequestString(method, baseUrl, path)}`, { err });\n }\n callback(result);\n };\n retryToUse(err, context, callbackWithLogging);\n },\n }));\n }\n\n if (this.settings.autoDecompress) {\n this.client = this.client.compose(decompress({ skipErrorResponses: false }));\n }\n\n this.client = this.client.compose(outbreakInterceptor);\n }\n\n #createBaseUrl(): void {\n const fullUrl = resolveServiceUrl(this.settings);\n const urlObj = new URL(fullUrl);\n this.settings.baseURL = urlObj.origin;\n this.settings.basePath = urlObj.pathname !== '/' ? urlObj.pathname : '';\n }\n\n #getSignal(currentSignal?: AbortSignal, timeout?: number): { signal?: AbortSignal; timeoutSignal?: AbortSignal; } {\n if (!currentSignal && !timeout) {\n return { signal: undefined, timeoutSignal: undefined };\n }\n\n if (currentSignal && !timeout) {\n return { signal: currentSignal, timeoutSignal: undefined };\n }\n\n const timeoutSignal = AbortSignal.timeout(timeout!);\n if (!currentSignal && timeout) {\n return { signal: timeoutSignal, timeoutSignal };\n }\n\n return { signal: AbortSignal.any([currentSignal!, timeoutSignal]), timeoutSignal };\n }\n\n #prepareRequestBody(body: any, headers: Record<string, string>): string | Buffer | FormData | undefined {\n if (body === undefined || body === null) {\n return undefined;\n }\n\n // Handle FormData instances automatically\n if (isFormData(body)) {\n if (!headers['Content-Type'] && !headers['content-type']) {\n headers['Content-Type'] = 'application/x-www-form-urlencoded';\n }\n return body;\n }\n\n if (typeof body === 'object' && !Buffer.isBuffer(body)) {\n // Check if Content-Type is set to application/x-www-form-urlencoded\n const contentType = headers['Content-Type'] || headers['content-type'];\n if (contentType && /application\\/x-www-form-urlencoded/i.test(contentType)) {\n // Encode as URL parameters\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(body)) {\n if (Array.isArray(value)) {\n value.forEach(v => params.append(key, String(v)));\n } else if (value !== undefined && value !== null) {\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n params.append(key, String(value));\n }\n }\n return params.toString();\n }\n // Default to JSON\n if (!headers['Content-Type'] && !headers['content-type']) {\n headers['Content-Type'] = 'application/json';\n }\n return JSON.stringify(body);\n } else if (typeof body === 'string') {\n return body;\n } else if (Buffer.isBuffer(body)) {\n return body;\n }\n return String(body);\n }\n\n async #request<T = any>(\n method: Dispatcher.HttpMethod,\n url: string,\n body?: any,\n config: RequestConfig = {},\n ): Promise<RapidoHttpClientResponse<T>> {\n const mergedConfig = mergeConfig(this.settings, config);\n\n if (mergedConfig.signal?.aborted) {\n this.#logger.error(`Request aborted before start: ${createRequestString(method, mergedConfig.baseURL, url)}`);\n throw new errors.RequestAbortedError(mergedConfig.signal.reason?.message || 'Request aborted', { cause: mergedConfig.signal.reason });\n }\n\n const headers: Record<string, string> = { ...mergedConfig.headers };\n const requestBody = this.#prepareRequestBody(body, headers);\n\n const { origin, path } = parseUrlAndOrigin(url, mergedConfig.baseURL!, mergedConfig.basePath);\n const requestInfo = { method, baseURL: origin, url };\n\n if (mergedConfig.params) {\n for (const [key, value] of Object.entries(mergedConfig.params)) {\n if (Array.isArray(value) && !key.endsWith('[]')) {\n mergedConfig.params[`${key}[]`] = value;\n delete mergedConfig.params[key];\n }\n }\n }\n\n const { signal, timeoutSignal } = this.#getSignal(mergedConfig.signal, mergedConfig.timeout);\n\n try {\n this.#logger.info(`Start Request: ${createRequestString(method, origin, path)}`);\n\n const requestOptions: Dispatcher.RequestOptions = {\n path,\n origin,\n method,\n signal,\n headers,\n body: requestBody,\n query: mergedConfig.params,\n };\n\n const response = await this.client.request(requestOptions);\n\n const isStatusValid = mergedConfig.validateStatus ?? (() => response.statusCode < 400);\n if (!isStatusValid(response.statusCode)) {\n const data = await this.#parseResponse<T>(requestBody, response, config.responseSchema);\n this.#logger.error(`Finish Request with error ${createRequestString(method, origin, path)}`, {\n status: response.statusCode,\n data,\n });\n\n throw new errors.RapidoHttpClientError<T>(requestBody, response, data);\n }\n\n this.#logger.info(`Finish Request: ${createRequestString(method, origin, path)}`);\n\n const data = response.statusCode !== 204 ? await this.#parseResponse<T>(requestBody, response, config.responseSchema) : undefined as T;\n\n return {\n data,\n status: response.statusCode,\n statusText: STATUS_CODES[response.statusCode] || '',\n headers: response.headers as Record<string, string | string[]>,\n config: requestInfo,\n };\n } catch (error) {\n if (timeoutSignal && timeoutSignal.reason === error) {\n // If the timeoutSignal aborted (config timeout), throw a timeout-specific error\n this.#logger.error(`Request timeout: ${createRequestString(method, origin, path)}`);\n const error = new errors.UndiciError(`Request timeout after ${mergedConfig.timeout}ms`, { cause: timeoutSignal.reason });\n error.code = 'UND_ERR_TIMEOUT';\n throw error;\n }\n if (signal && signal.reason === error) {\n // If the user's signal aborted, throw RequestAbortedError\n this.#logger.error(`Request aborted: ${createRequestString(method, origin, path)}`);\n throw new errors.RequestAbortedError(signal.reason.message, { cause: signal.reason });\n }\n\n this.#logger.error(`Finish Request with error ${createRequestString(method, origin, path)}`, { error });\n throw error;\n }\n }\n\n async #parseResponse<T>(requestBody: ConstructorParameters<typeof errors.RapidoHttpClientError>[0], response: Dispatcher.ResponseData, schema?: ZodType): Promise<T> {\n const contentType = (response.headers['content-type'] as string) || '';\n const bodyText = await response.body.text();\n\n if (!bodyText) {\n return undefined as T;\n }\n\n if (/text/i.test(contentType)) {\n return bodyText as T;\n }\n\n let json: unknown;\n try {\n json = JSON.parse(bodyText);\n } catch (error) {\n if (!schema) {\n return bodyText as T;\n }\n const parseResult = schema.safeParse(bodyText);\n if (parseResult.success) {\n return parseResult.data as T;\n }\n throw new errors.RapidoHttpClientError(requestBody, response, undefined, { cause: error as Error });\n }\n if (!schema) {\n return json as T;\n }\n const parseResult = schema.safeParse(json);\n if (parseResult.success) {\n return parseResult.data as T;\n }\n throw Object.assign(parseResult.error, { json });\n }\n\n /**\n * @param url The endpoint URL to send the request to.\n * @param options Additional options to include in the request payload.\n * @returns A promise that resolves to an array of all results.\n */\n async getAllPages<T>(url: string, options: RequestConfig = {}): Promise<T[]> {\n const currentResult: T[] = [];\n let resultsInFirstPage: number | null = null;\n let lastResultsSize: number | null = null;\n\n const localOptions = { ...options, params: { ...options.params, page: 1 } };\n // Make sure even if `options` had `params` we initialize `page` to 1.\n localOptions.params.page ||= 1;\n\n while ((localOptions.params.page === 1 || lastResultsSize === resultsInFirstPage) && lastResultsSize !== 0) {\n const { data } = await this.get<T[]>(url, localOptions as Omit<RequestConfig, 'responseSchema'>);\n lastResultsSize = data.length;\n if (localOptions.params.page === 1) {\n resultsInFirstPage = data.length;\n }\n\n localOptions.params.page += 1;\n Array.prototype.push.apply(currentResult, data);\n }\n\n return currentResult;\n }\n\n /**\n * Fetches all pages from a paginated API endpoint until all results are retrieved\n * or an optional page limit is reached.\n *\n * @param url The endpoint URL to send the request to.\n * @param options Additional options to include in the request payload.\n * @param pageLimit The maximum number of pages to fetch. Set to -1 for no limit.\n * @returns A promise that resolves to an array of all results.\n */\n async getAllPagesFromQueryEndpoint<T>(url: string, options: object = {}, pageLimit = 100): Promise<T[]> {\n const currentResult: T[] = [];\n\n let moreResultsToLoad = true;\n let page = 1;\n while (moreResultsToLoad && (pageLimit === -1 || page < pageLimit)) {\n const { data } = await this.post<{ rows: T[]; count: number; }>(url, {\n ...options,\n page,\n });\n const { rows, count } = data;\n page += 1;\n Array.prototype.push.apply(currentResult, rows);\n moreResultsToLoad = currentResult.length < count;\n }\n\n return currentResult;\n }\n\n async close(): Promise<void> {\n await this.client.close();\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close();\n }\n}\n\nexport default RapidoHttpClient;\nexport { errors };\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{a as e,c as t,i as n,n as r,o as i,r as a,s as o,t as s}from"./utils-CN26OYva.js";import{STATUS_CODES as c}from"node:http";import l,{Agent as u,errors as d,interceptors as f}from"undici";import{getCurrentContext as p}from"@autofleet/outbreak";const m=Symbol.for(`RapidoHttpClientErrorBrand`);let h;(function(e){e.UndiciError=d.UndiciError,e.ConnectTimeoutError=d.ConnectTimeoutError,e.HeadersTimeoutError=d.HeadersTimeoutError,e.HeadersOverflowError=d.HeadersOverflowError,e.BodyTimeoutError=d.BodyTimeoutError,e.ResponseError=d.ResponseError,e.InvalidArgumentError=d.InvalidArgumentError,e.InvalidReturnValueError=d.InvalidReturnValueError,e.RequestAbortedError=d.RequestAbortedError,e.InformationalError=d.InformationalError,e.RequestContentLengthMismatchError=d.RequestContentLengthMismatchError,e.ResponseContentLengthMismatchError=d.ResponseContentLengthMismatchError,e.ClientDestroyedError=d.ClientDestroyedError,e.ClientClosedError=d.ClientClosedError,e.SocketError=d.SocketError,e.NotSupportedError=d.NotSupportedError,e.BalancedPoolMissingUpstreamError=d.BalancedPoolMissingUpstreamError,e.HTTPParserError=d.HTTPParserError,e.ResponseExceededMaxSizeError=d.ResponseExceededMaxSizeError,e.RequestRetryError=d.RequestRetryError,e.SecureProxyConnectionError=d.SecureProxyConnectionError,e.MaxOriginsReachedError=d.MaxOriginsReachedError;function t(e){return typeof e==`object`&&!!e&&m in e}e.isRapidoHttpClientError=t;class n extends d.ResponseError{constructor(e,t,n,r){super(`HTTP Error ${t.statusCode}`,t.statusCode,{headers:t.headers,body:e}),this.response=t,this.data=n,this.status=t.statusCode,this.statusText=c[t.statusCode]||`Unknown Status`,r?.cause&&(this.cause=r.cause),Object.defineProperty(this,m,{value:!0,enumerable:!1,writable:!1})}static isRapidoHttpClientError(e){return t(e)}}e.RapidoHttpClientError=n})(h||={});const g=Symbol(`testAgentParam`),_=e=>function(t,n){let r=p().context;if(r){let e;e=Array.isArray(t.headers)?Object.fromEntries(t.headers):{...t.headers};for(let[t,n]of r)typeof n==`symbol`||n===void 0||(e[t]=n);t.headers=e}return e(t,n)},{cacheStores:v}=l,{cache:y,retry:b,decompress:x}=f,S=[`GET`,`HEAD`,`OPTIONS`,`PUT`,`DELETE`,`TRACE`,`QUERY`];var C=class{#e;get(e,t){return this.#i(`GET`,e,void 0,t)}post(e,t,n){return this.#i(`POST`,e,t,n)}delete(e,t){return this.#i(`DELETE`,e,void 0,t)}head(e,t){return this.#i(`HEAD`,e,void 0,t)}put(e,t,n){return this.#i(`PUT`,e,t,n)}patch(e,t,n){return this.#i(`PATCH`,e,t,n)}options(e,t){return this.#i(`OPTIONS`,e,void 0,t)}query(e,t,n){return this.#i(`QUERY`,e,t,n)}constructor(e){this.#e=e.logger,this.settings=i(e.autoDecompress?n:a,e),this.#t();let t=globalThis.__RAPIDO_HTTP_CLIENT_MOCK_AGENT__;this.client=this.settings[g]??t??new u({connect:{timeout:this.settings.timeout},keepAliveTimeout:this.settings.keepAliveTimeout,keepAliveMaxTimeout:this.settings.keepAliveMaxTimeout,connections:this.settings.connections}),this.settings.cache&&(this.client=this.client.compose(y({store:new v.MemoryCacheStore({...this.settings.cache})}))),this.settings.retries&&(this.client=this.client.compose(b({methods:S,...this.settings.retries,retry:(e,t,n)=>{let{counter:i}=t.state,a=t.opts.retryOptions?.maxRetries??5;(this.settings.retries?.retry??r)(e,t,r=>{if(!r){let{method:n,origin:r,path:o}=t.opts,c=!r||typeof r==`string`?r:r.origin;this.#e.warn(`Request retry attempt ${i}/${a}: ${s(n,c,o)}`,{err:e})}n(r)})}}))),this.settings.autoDecompress&&(this.client=this.client.compose(x({skipErrorResponses:!1}))),this.client=this.client.compose(_)}#t(){let e=t(this.settings),n=new URL(e);this.settings.baseURL=n.origin,this.settings.basePath=n.pathname===`/`?``:n.pathname}#n(e,t){if(!e&&!t)return{signal:void 0,timeoutSignal:void 0};if(e&&!t)return{signal:e,timeoutSignal:void 0};let n=AbortSignal.timeout(t);return!e&&t?{signal:n,timeoutSignal:n}:{signal:AbortSignal.any([e,n]),timeoutSignal:n}}#r(t,n){if(t!=null){if(e(t))return!n[`Content-Type`]&&!n[`content-type`]&&(n[`Content-Type`]=`application/x-www-form-urlencoded`),t;if(typeof t==`object`&&!Buffer.isBuffer(t)){let e=n[`Content-Type`]||n[`content-type`];if(e&&/application\/x-www-form-urlencoded/i.test(e)){let e=new URLSearchParams;for(let[n,r]of Object.entries(t))Array.isArray(r)?r.forEach(t=>e.append(n,String(t))):r!=null&&e.append(n,String(r));return e.toString()}return!n[`Content-Type`]&&!n[`content-type`]&&(n[`Content-Type`]=`application/json`),JSON.stringify(t)}else if(typeof t==`string`)return t;else if(Buffer.isBuffer(t))return t;return String(t)}}async#i(e,t,n,r={}){let a=i(this.settings,r);if(a.signal?.aborted)throw this.#e.error(`Request aborted before start: ${s(e,a.baseURL,t)}`),new h.RequestAbortedError(a.signal.reason?.message||`Request aborted`,{cause:a.signal.reason});let l={...a.headers},u=this.#r(n,l),{origin:d,path:f}=o(t,a.baseURL,a.basePath),p={method:e,baseURL:d,url:t};if(a.params)for(let[e,t]of Object.entries(a.params))Array.isArray(t)&&!e.endsWith(`[]`)&&(a.params[`${e}[]`]=t,delete a.params[e]);let{signal:m,timeoutSignal:g}=this.#n(a.signal,a.timeout);try{this.#e.info(`Start Request: ${s(e,d,f)}`);let t={path:f,origin:d,method:e,signal:m,headers:l,body:u,query:a.params},n=await this.client.request(t);if(!(a.validateStatus??(()=>n.statusCode<400))(n.statusCode)){let t=await this.#a(u,n,r.responseSchema);throw this.#e.error(`Finish Request with error ${s(e,d,f)}`,{status:n.statusCode,data:t}),new h.RapidoHttpClientError(u,n,t)}return this.#e.info(`Finish Request: ${s(e,d,f)}`),{data:n.statusCode===204?void 0:await this.#a(u,n,r.responseSchema),status:n.statusCode,statusText:c[n.statusCode]||``,headers:n.headers,config:p}}catch(t){if(g&&g.reason===t){this.#e.error(`Request timeout: ${s(e,d,f)}`);let t=new h.UndiciError(`Request timeout after ${a.timeout}ms`,{cause:g.reason});throw t.code=`UND_ERR_TIMEOUT`,t}throw m&&m.reason===t?(this.#e.error(`Request aborted: ${s(e,d,f)}`),new h.RequestAbortedError(m.reason.message,{cause:m.reason})):(this.#e.error(`Finish Request with error ${s(e,d,f)}`,{error:t}),t)}}async#a(e,t,n){let r=t.headers[`content-type`]||``,i=await t.body.text();if(!i)return;if(/text/i.test(r))return i;let a;try{a=JSON.parse(i)}catch(r){if(!n)return i;let a=n.safeParse(i);if(a.success)return a.data;throw new h.RapidoHttpClientError(e,t,void 0,{cause:r})}return n
|
|
1
|
+
import{a as e,c as t,i as n,n as r,o as i,r as a,s as o,t as s}from"./utils-CN26OYva.js";import{STATUS_CODES as c}from"node:http";import l,{Agent as u,errors as d,interceptors as f}from"undici";import{getCurrentContext as p}from"@autofleet/outbreak";const m=Symbol.for(`RapidoHttpClientErrorBrand`);let h;(function(e){e.UndiciError=d.UndiciError,e.ConnectTimeoutError=d.ConnectTimeoutError,e.HeadersTimeoutError=d.HeadersTimeoutError,e.HeadersOverflowError=d.HeadersOverflowError,e.BodyTimeoutError=d.BodyTimeoutError,e.ResponseError=d.ResponseError,e.InvalidArgumentError=d.InvalidArgumentError,e.InvalidReturnValueError=d.InvalidReturnValueError,e.RequestAbortedError=d.RequestAbortedError,e.InformationalError=d.InformationalError,e.RequestContentLengthMismatchError=d.RequestContentLengthMismatchError,e.ResponseContentLengthMismatchError=d.ResponseContentLengthMismatchError,e.ClientDestroyedError=d.ClientDestroyedError,e.ClientClosedError=d.ClientClosedError,e.SocketError=d.SocketError,e.NotSupportedError=d.NotSupportedError,e.BalancedPoolMissingUpstreamError=d.BalancedPoolMissingUpstreamError,e.HTTPParserError=d.HTTPParserError,e.ResponseExceededMaxSizeError=d.ResponseExceededMaxSizeError,e.RequestRetryError=d.RequestRetryError,e.SecureProxyConnectionError=d.SecureProxyConnectionError,e.MaxOriginsReachedError=d.MaxOriginsReachedError;function t(e){return typeof e==`object`&&!!e&&m in e}e.isRapidoHttpClientError=t;class n extends d.ResponseError{constructor(e,t,n,r){super(`HTTP Error ${t.statusCode}`,t.statusCode,{headers:t.headers,body:e}),this.response=t,this.data=n,this.status=t.statusCode,this.statusText=c[t.statusCode]||`Unknown Status`,r?.cause&&(this.cause=r.cause),Object.defineProperty(this,m,{value:!0,enumerable:!1,writable:!1})}static isRapidoHttpClientError(e){return t(e)}}e.RapidoHttpClientError=n})(h||={});const g=Symbol(`testAgentParam`),_=e=>function(t,n){let r=p().context;if(r){let e;e=Array.isArray(t.headers)?Object.fromEntries(t.headers):{...t.headers};for(let[t,n]of r)typeof n==`symbol`||n===void 0||(e[t]=n);t.headers=e}return e(t,n)},{cacheStores:v}=l,{cache:y,retry:b,decompress:x}=f,S=[`GET`,`HEAD`,`OPTIONS`,`PUT`,`DELETE`,`TRACE`,`QUERY`];var C=class{#e;get(e,t){return this.#i(`GET`,e,void 0,t)}post(e,t,n){return this.#i(`POST`,e,t,n)}delete(e,t){return this.#i(`DELETE`,e,void 0,t)}head(e,t){return this.#i(`HEAD`,e,void 0,t)}put(e,t,n){return this.#i(`PUT`,e,t,n)}patch(e,t,n){return this.#i(`PATCH`,e,t,n)}options(e,t){return this.#i(`OPTIONS`,e,void 0,t)}query(e,t,n){return this.#i(`QUERY`,e,t,n)}constructor(e){this.#e=e.logger,this.settings=i(e.autoDecompress?n:a,e),this.#t();let t=globalThis.__RAPIDO_HTTP_CLIENT_MOCK_AGENT__;this.client=this.settings[g]??t??new u({connect:{timeout:this.settings.timeout},keepAliveTimeout:this.settings.keepAliveTimeout,keepAliveMaxTimeout:this.settings.keepAliveMaxTimeout,connections:this.settings.connections}),this.settings.cache&&(this.client=this.client.compose(y({store:new v.MemoryCacheStore({...this.settings.cache})}))),this.settings.retries&&(this.client=this.client.compose(b({methods:S,...this.settings.retries,retry:(e,t,n)=>{let{counter:i}=t.state,a=t.opts.retryOptions?.maxRetries??5;(this.settings.retries?.retry??r)(e,t,r=>{if(!r){let{method:n,origin:r,path:o}=t.opts,c=!r||typeof r==`string`?r:r.origin;this.#e.warn(`Request retry attempt ${i}/${a}: ${s(n,c,o)}`,{err:e})}n(r)})}}))),this.settings.autoDecompress&&(this.client=this.client.compose(x({skipErrorResponses:!1}))),this.client=this.client.compose(_)}#t(){let e=t(this.settings),n=new URL(e);this.settings.baseURL=n.origin,this.settings.basePath=n.pathname===`/`?``:n.pathname}#n(e,t){if(!e&&!t)return{signal:void 0,timeoutSignal:void 0};if(e&&!t)return{signal:e,timeoutSignal:void 0};let n=AbortSignal.timeout(t);return!e&&t?{signal:n,timeoutSignal:n}:{signal:AbortSignal.any([e,n]),timeoutSignal:n}}#r(t,n){if(t!=null){if(e(t))return!n[`Content-Type`]&&!n[`content-type`]&&(n[`Content-Type`]=`application/x-www-form-urlencoded`),t;if(typeof t==`object`&&!Buffer.isBuffer(t)){let e=n[`Content-Type`]||n[`content-type`];if(e&&/application\/x-www-form-urlencoded/i.test(e)){let e=new URLSearchParams;for(let[n,r]of Object.entries(t))Array.isArray(r)?r.forEach(t=>e.append(n,String(t))):r!=null&&e.append(n,String(r));return e.toString()}return!n[`Content-Type`]&&!n[`content-type`]&&(n[`Content-Type`]=`application/json`),JSON.stringify(t)}else if(typeof t==`string`)return t;else if(Buffer.isBuffer(t))return t;return String(t)}}async#i(e,t,n,r={}){let a=i(this.settings,r);if(a.signal?.aborted)throw this.#e.error(`Request aborted before start: ${s(e,a.baseURL,t)}`),new h.RequestAbortedError(a.signal.reason?.message||`Request aborted`,{cause:a.signal.reason});let l={...a.headers},u=this.#r(n,l),{origin:d,path:f}=o(t,a.baseURL,a.basePath),p={method:e,baseURL:d,url:t};if(a.params)for(let[e,t]of Object.entries(a.params))Array.isArray(t)&&!e.endsWith(`[]`)&&(a.params[`${e}[]`]=t,delete a.params[e]);let{signal:m,timeoutSignal:g}=this.#n(a.signal,a.timeout);try{this.#e.info(`Start Request: ${s(e,d,f)}`);let t={path:f,origin:d,method:e,signal:m,headers:l,body:u,query:a.params},n=await this.client.request(t);if(!(a.validateStatus??(()=>n.statusCode<400))(n.statusCode)){let t=await this.#a(u,n,r.responseSchema);throw this.#e.error(`Finish Request with error ${s(e,d,f)}`,{status:n.statusCode,data:t}),new h.RapidoHttpClientError(u,n,t)}return this.#e.info(`Finish Request: ${s(e,d,f)}`),{data:n.statusCode===204?void 0:await this.#a(u,n,r.responseSchema),status:n.statusCode,statusText:c[n.statusCode]||``,headers:n.headers,config:p}}catch(t){if(g&&g.reason===t){this.#e.error(`Request timeout: ${s(e,d,f)}`);let t=new h.UndiciError(`Request timeout after ${a.timeout}ms`,{cause:g.reason});throw t.code=`UND_ERR_TIMEOUT`,t}throw m&&m.reason===t?(this.#e.error(`Request aborted: ${s(e,d,f)}`),new h.RequestAbortedError(m.reason.message,{cause:m.reason})):(this.#e.error(`Finish Request with error ${s(e,d,f)}`,{error:t}),t)}}async#a(e,t,n){let r=t.headers[`content-type`]||``,i=await t.body.text();if(!i)return;if(/text/i.test(r))return i;let a;try{a=JSON.parse(i)}catch(r){if(!n)return i;let a=n.safeParse(i);if(a.success)return a.data;throw new h.RapidoHttpClientError(e,t,void 0,{cause:r})}if(!n)return a;let o=n.safeParse(a);if(o.success)return o.data;throw Object.assign(o.error,{json:a})}async getAllPages(e,t={}){let n=[],r=null,i=null,a={...t,params:{...t.params,page:1}};for(a.params.page||=1;(a.params.page===1||i===r)&&i!==0;){let{data:t}=await this.get(e,a);i=t.length,a.params.page===1&&(r=t.length),a.params.page+=1,Array.prototype.push.apply(n,t)}return n}async getAllPagesFromQueryEndpoint(e,t={},n=100){let r=[],i=!0,a=1;for(;i&&(n===-1||a<n);){let{data:n}=await this.post(e,{...t,page:a}),{rows:o,count:s}=n;a+=1,Array.prototype.push.apply(r,o),i=r.length<s}return r}async close(){await this.client.close()}async[Symbol.asyncDispose](){await this.close()}},w=C;export{C as RapidoHttpClient,w as default,h as errors};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["undiciErrors","response: Dispatcher.ResponseData","data: T","testAgentParam: unique symbol","outbreakInterceptor: Dispatcher.DispatcherComposeInterceptor","headers: Record<string, string | string[]>","retriableMethods: Dispatcher.HttpMethod[]","#logger","#request","#createBaseUrl","headers: Record<string, string>","#prepareRequestBody","#getSignal","requestOptions: Dispatcher.RequestOptions","#parseResponse","error","json: unknown","currentResult: T[]","resultsInFirstPage: number | null","lastResultsSize: number | null"],"sources":["../src/errors.ts","../src/testingHelper.ts","../src/outbreakInterceptor.ts","../src/index.ts"],"sourcesContent":["import { STATUS_CODES } from 'node:http';\nimport { type Dispatcher, errors as undiciErrors } from 'undici';\n\nconst RapidoHttpClientErrorBrand = Symbol.for('RapidoHttpClientErrorBrand');\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace errors {\n export import UndiciError = undiciErrors.UndiciError;\n export import ConnectTimeoutError = undiciErrors.ConnectTimeoutError;\n export import HeadersTimeoutError = undiciErrors.HeadersTimeoutError;\n export import HeadersOverflowError = undiciErrors.HeadersOverflowError;\n export import BodyTimeoutError = undiciErrors.BodyTimeoutError;\n export import ResponseError = undiciErrors.ResponseError;\n export import InvalidArgumentError = undiciErrors.InvalidArgumentError;\n export import InvalidReturnValueError = undiciErrors.InvalidReturnValueError;\n export import RequestAbortedError = undiciErrors.RequestAbortedError;\n export import InformationalError = undiciErrors.InformationalError;\n export import RequestContentLengthMismatchError = undiciErrors.RequestContentLengthMismatchError;\n export import ResponseContentLengthMismatchError = undiciErrors.ResponseContentLengthMismatchError;\n export import ClientDestroyedError = undiciErrors.ClientDestroyedError;\n export import ClientClosedError = undiciErrors.ClientClosedError;\n export import SocketError = undiciErrors.SocketError;\n export import NotSupportedError = undiciErrors.NotSupportedError;\n export import BalancedPoolMissingUpstreamError = undiciErrors.BalancedPoolMissingUpstreamError;\n export import HTTPParserError = undiciErrors.HTTPParserError;\n export import ResponseExceededMaxSizeError = undiciErrors.ResponseExceededMaxSizeError;\n export import RequestRetryError = undiciErrors.RequestRetryError;\n export import SecureProxyConnectionError = undiciErrors.SecureProxyConnectionError;\n export import MaxOriginsReachedError = undiciErrors.MaxOriginsReachedError;\n\n export function isRapidoHttpClientError(value: unknown): value is RapidoHttpClientError<unknown> {\n return typeof value === 'object' && value !== null && RapidoHttpClientErrorBrand in value;\n }\n\n export class RapidoHttpClientError<T> extends undiciErrors.ResponseError {\n public readonly status: number;\n public readonly statusText: string;\n\n constructor(\n body: ConstructorParameters<typeof undiciErrors.ResponseError>[2]['body'],\n public readonly response: Dispatcher.ResponseData,\n public readonly data: T,\n errorOptions?: ErrorOptions,\n ) {\n super(`HTTP Error ${response.statusCode}`, response.statusCode, { headers: response.headers, body });\n this.status = response.statusCode;\n this.statusText = STATUS_CODES[response.statusCode] || 'Unknown Status';\n if (errorOptions?.cause) {\n this.cause = errorOptions.cause;\n }\n\n Object.defineProperty(this, RapidoHttpClientErrorBrand, {\n value: true,\n enumerable: false,\n writable: false,\n });\n }\n\n public static isRapidoHttpClientError(value: unknown): value is RapidoHttpClientError<unknown> {\n return isRapidoHttpClientError(value);\n }\n }\n}\n","export const testAgentParam: unique symbol = Symbol('testAgentParam');\n","import type { Dispatcher } from 'undici';\nimport { getCurrentContext } from '@autofleet/outbreak';\n\nexport const outbreakInterceptor: Dispatcher.DispatcherComposeInterceptor = dispatch => function outbreakInterceptorInner(opts, handler) {\n const currentTraceContext = getCurrentContext().context;\n if (currentTraceContext) {\n // Convert headers to object format if they're in array format\n let headers: Record<string, string | string[]>;\n if (Array.isArray(opts.headers)) {\n /* c8 ignore next */\n headers = Object.fromEntries(opts.headers as unknown as [string, string | string[]][]);\n } else {\n headers = { ...opts.headers as Record<string, string | string[]> };\n }\n\n // Inject outbreak trace headers\n for (const [header, value] of currentTraceContext) {\n if (typeof value === 'symbol' || typeof value === 'undefined') {\n continue;\n }\n headers[header] = value as string;\n }\n opts.headers = headers;\n }\n return dispatch(opts, handler);\n};\n","import { STATUS_CODES } from 'node:http';\nimport type { ZodType, output } from 'zod';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\nimport type CacheHandler from 'undici/types/cache-interceptor';\nimport Undici, { Agent, type Dispatcher, interceptors } from 'undici';\nimport { errors } from './errors';\nimport { testAgentParam } from './testingHelper';\nimport { outbreakInterceptor } from './outbreakInterceptor';\nimport {\n createRequestString,\n defaultRetryMethod,\n defaultSettings,\n defaultSettingsWithDecompress,\n isFormData,\n mergeConfig,\n parseUrlAndOrigin,\n resolveServiceUrl,\n} from './utils';\n\nconst { cacheStores } = Undici;\nconst { cache, retry, decompress } = interceptors;\n\nexport interface RapidoHttpClientSettings {\n [testAgentParam]?: Dispatcher;\n /** The MS name to be used to resolve the base URL using K8S service discovery. Ignored if `serviceUrl` is provided as well. */\n serviceName?: string;\n /** The base URL to be used. Overrides `serviceName` when provided. */\n serviceUrl?: string;\n logger: LoggerInstanceManager;\n /** The request timeout in milliseconds. @default 10_000 */\n timeout?: number;\n /** Settings for retrying requests on failure */\n retries?: interceptors.RetryInterceptorOpts;\n /** Common headers applied to all requests of this `RapidoHttpClient` instance. */\n headers?: Record<string, string> | string[][];\n keepAliveTimeout?: number;\n keepAliveMaxTimeout?: number;\n /** The amount of concurrent connections to be maintained using a connection pool. @default 10 */\n connections?: number;\n /** The settings for caching requests */\n cache?: CacheHandler.MemoryCacheStoreOpts;\n /** Whether to automatically decompress response bodies. When `true` will automatically add an `Accept-Encoding` header. @default false */\n autoDecompress?: boolean;\n /**\n * A function to validate the HTTP response status code.\n * Return `true` to consider the status valid, `false` otherwise.\n *\n * When status is invalid, a {@link errors.RapidoHttpClientError `RapidoHttpClientError`} will be thrown.\n *\n * @example (status) => status >= 200 && status < 300\n * @example (status) => status !== 401\n *\n * @default (status) => status < 400\n */\n validateStatus?(status: number): boolean;\n}\n\nexport interface RequestConfig {\n params?: Record<string, any>;\n body?: any;\n /** The request timeout in milliseconds. This overrides the client's instance setting @default 10_000 */\n timeout?: number;\n /** Headers applied to this request, appending on the client's common headers. */\n headers?: Record<string, string>;\n /** An `AbortSignal` which should abort the request and it's parsing when aborted. */\n signal?: AbortSignal;\n /** A Zod schema defining what the response should look like. This also parses error responses. */\n responseSchema?: ZodType;\n /**\n * A function to validate the HTTP response status code.\n * Return `true` to consider the status valid, `false` otherwise.\n *\n * When status is invalid, a {@link errors.RapidoHttpClientError `RapidoHttpClientError`} will be thrown.\n *\n * @example (status) => status >= 200 && status < 300\n * @example (status) => status !== 401\n *\n * @default (status) => status < 400\n */\n validateStatus?(status: number): boolean;\n}\n\nexport interface RapidoHttpClientResponse<T = any> {\n data: T;\n status: number;\n statusText: string;\n headers: Record<string, string | string[]>;\n config: RequestConfig & { url: string; method: string; baseURL?: string; };\n}\n\nconst retriableMethods: Dispatcher.HttpMethod[] = ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE', 'QUERY'];\n\nexport class RapidoHttpClient {\n readonly #logger: LoggerInstanceManager;\n private readonly settings: RapidoHttpClientSettings & { baseURL?: string; basePath?: string; };\n public readonly client: Dispatcher.ComposedDispatcher;\n\n public get<T = unknown>(url: string, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public get<T extends ZodType>(url: string, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public get<T = unknown>(url: string, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('GET', url, undefined, config);\n }\n\n public post<T = unknown>(url: string, body?: any, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public post<T extends ZodType>(url: string, body: any, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public post<T = unknown>(url: string, body?: any, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('POST', url, body, config);\n }\n\n public delete<T = unknown>(url: string, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public delete<T extends ZodType>(url: string, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public delete<T = unknown>(url: string, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('DELETE', url, undefined, config);\n }\n\n public head<T = unknown>(url: string, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public head<T extends ZodType>(url: string, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public head<T = unknown>(url: string, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('HEAD', url, undefined, config);\n }\n\n public put<T = unknown>(url: string, body?: any, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public put<T extends ZodType>(url: string, body: any, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public put<T = unknown>(url: string, body?: any, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('PUT', url, body, config);\n }\n\n public patch<T = unknown>(url: string, body?: any, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public patch<T extends ZodType>(url: string, body: any, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public patch<T = unknown>(url: string, body?: any, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('PATCH', url, body, config);\n }\n\n public options<T = unknown>(url: string, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public options<T extends ZodType>(url: string, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public options<T = unknown>(url: string, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('OPTIONS', url, undefined, config);\n }\n\n public query<T = unknown>(url: string, body?: any, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public query<T extends ZodType>(url: string, body: any, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public query<T = unknown>(url: string, body?: any, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('QUERY', url, body, config);\n }\n\n constructor(settings: RapidoHttpClientSettings) {\n this.#logger = settings.logger;\n this.settings = mergeConfig<typeof defaultSettings, Partial<typeof settings>>(\n settings.autoDecompress ? defaultSettingsWithDecompress : defaultSettings,\n settings,\n ) as RapidoHttpClientSettings & { baseURL?: string; };\n this.#createBaseUrl();\n\n // In test mode, use the test dispatcher directly (MockAgent or MockPool) Otherwise, create an Agent which creates Client Pools\n // Check for global mock agent first (for testing), then test param, then create real Agent\n /* c8 ignore next */\n const globalMockAgent = (globalThis as any).__RAPIDO_HTTP_CLIENT_MOCK_AGENT__;\n /* c8 ignore next */\n this.client = this.settings[testAgentParam] ?? globalMockAgent ?? new Agent({\n connect: {\n timeout: this.settings.timeout,\n },\n keepAliveTimeout: this.settings.keepAliveTimeout,\n keepAliveMaxTimeout: this.settings.keepAliveMaxTimeout,\n connections: this.settings.connections,\n });\n\n if (this.settings.cache) {\n this.client = this.client.compose(cache({\n store: new cacheStores.MemoryCacheStore({\n ...this.settings.cache,\n }),\n }));\n }\n\n if (this.settings.retries) {\n this.client = this.client.compose(retry({\n methods: retriableMethods,\n ...this.settings.retries,\n retry: (err, context, callback) => {\n const { counter } = context.state;\n /* c8 ignore next */\n const maxRetries = context.opts.retryOptions?.maxRetries ?? 5;\n\n const retryToUse = this.settings.retries?.retry ?? defaultRetryMethod;\n const callbackWithLogging = (result?: Error | null) => {\n if (!result) {\n const { method, origin, path } = context.opts;\n const baseUrl = (!origin || typeof origin === 'string') ? origin : origin.origin;\n this.#logger.warn(`Request retry attempt ${counter}/${maxRetries}: ${createRequestString(method, baseUrl, path)}`, { err });\n }\n callback(result);\n };\n retryToUse(err, context, callbackWithLogging);\n },\n }));\n }\n\n if (this.settings.autoDecompress) {\n this.client = this.client.compose(decompress({ skipErrorResponses: false }));\n }\n\n this.client = this.client.compose(outbreakInterceptor);\n }\n\n #createBaseUrl(): void {\n const fullUrl = resolveServiceUrl(this.settings);\n const urlObj = new URL(fullUrl);\n this.settings.baseURL = urlObj.origin;\n this.settings.basePath = urlObj.pathname !== '/' ? urlObj.pathname : '';\n }\n\n #getSignal(currentSignal?: AbortSignal, timeout?: number): { signal?: AbortSignal; timeoutSignal?: AbortSignal; } {\n if (!currentSignal && !timeout) {\n return { signal: undefined, timeoutSignal: undefined };\n }\n\n if (currentSignal && !timeout) {\n return { signal: currentSignal, timeoutSignal: undefined };\n }\n\n const timeoutSignal = AbortSignal.timeout(timeout!);\n if (!currentSignal && timeout) {\n return { signal: timeoutSignal, timeoutSignal };\n }\n\n return { signal: AbortSignal.any([currentSignal!, timeoutSignal]), timeoutSignal };\n }\n\n #prepareRequestBody(body: any, headers: Record<string, string>): string | Buffer | FormData | undefined {\n if (body === undefined || body === null) {\n return undefined;\n }\n\n // Handle FormData instances automatically\n if (isFormData(body)) {\n if (!headers['Content-Type'] && !headers['content-type']) {\n headers['Content-Type'] = 'application/x-www-form-urlencoded';\n }\n return body;\n }\n\n if (typeof body === 'object' && !Buffer.isBuffer(body)) {\n // Check if Content-Type is set to application/x-www-form-urlencoded\n const contentType = headers['Content-Type'] || headers['content-type'];\n if (contentType && /application\\/x-www-form-urlencoded/i.test(contentType)) {\n // Encode as URL parameters\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(body)) {\n if (Array.isArray(value)) {\n value.forEach(v => params.append(key, String(v)));\n } else if (value !== undefined && value !== null) {\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n params.append(key, String(value));\n }\n }\n return params.toString();\n }\n // Default to JSON\n if (!headers['Content-Type'] && !headers['content-type']) {\n headers['Content-Type'] = 'application/json';\n }\n return JSON.stringify(body);\n } else if (typeof body === 'string') {\n return body;\n } else if (Buffer.isBuffer(body)) {\n return body;\n }\n return String(body);\n }\n\n async #request<T = any>(\n method: Dispatcher.HttpMethod,\n url: string,\n body?: any,\n config: RequestConfig = {},\n ): Promise<RapidoHttpClientResponse<T>> {\n const mergedConfig = mergeConfig(this.settings, config);\n\n if (mergedConfig.signal?.aborted) {\n this.#logger.error(`Request aborted before start: ${createRequestString(method, mergedConfig.baseURL, url)}`);\n throw new errors.RequestAbortedError(mergedConfig.signal.reason?.message || 'Request aborted', { cause: mergedConfig.signal.reason });\n }\n\n const headers: Record<string, string> = { ...mergedConfig.headers };\n const requestBody = this.#prepareRequestBody(body, headers);\n\n const { origin, path } = parseUrlAndOrigin(url, mergedConfig.baseURL!, mergedConfig.basePath);\n const requestInfo = { method, baseURL: origin, url };\n\n if (mergedConfig.params) {\n for (const [key, value] of Object.entries(mergedConfig.params)) {\n if (Array.isArray(value) && !key.endsWith('[]')) {\n mergedConfig.params[`${key}[]`] = value;\n delete mergedConfig.params[key];\n }\n }\n }\n\n const { signal, timeoutSignal } = this.#getSignal(mergedConfig.signal, mergedConfig.timeout);\n\n try {\n this.#logger.info(`Start Request: ${createRequestString(method, origin, path)}`);\n\n const requestOptions: Dispatcher.RequestOptions = {\n path,\n origin,\n method,\n signal,\n headers,\n body: requestBody,\n query: mergedConfig.params,\n };\n\n const response = await this.client.request(requestOptions);\n\n const isStatusValid = mergedConfig.validateStatus ?? (() => response.statusCode < 400);\n if (!isStatusValid(response.statusCode)) {\n const data = await this.#parseResponse<T>(requestBody, response, config.responseSchema);\n this.#logger.error(`Finish Request with error ${createRequestString(method, origin, path)}`, {\n status: response.statusCode,\n data,\n });\n\n throw new errors.RapidoHttpClientError<T>(requestBody, response, data);\n }\n\n this.#logger.info(`Finish Request: ${createRequestString(method, origin, path)}`);\n\n const data = response.statusCode !== 204 ? await this.#parseResponse<T>(requestBody, response, config.responseSchema) : undefined as T;\n\n return {\n data,\n status: response.statusCode,\n statusText: STATUS_CODES[response.statusCode] || '',\n headers: response.headers as Record<string, string | string[]>,\n config: requestInfo,\n };\n } catch (error) {\n if (timeoutSignal && timeoutSignal.reason === error) {\n // If the timeoutSignal aborted (config timeout), throw a timeout-specific error\n this.#logger.error(`Request timeout: ${createRequestString(method, origin, path)}`);\n const error = new errors.UndiciError(`Request timeout after ${mergedConfig.timeout}ms`, { cause: timeoutSignal.reason });\n error.code = 'UND_ERR_TIMEOUT';\n throw error;\n }\n if (signal && signal.reason === error) {\n // If the user's signal aborted, throw RequestAbortedError\n this.#logger.error(`Request aborted: ${createRequestString(method, origin, path)}`);\n throw new errors.RequestAbortedError(signal.reason.message, { cause: signal.reason });\n }\n\n this.#logger.error(`Finish Request with error ${createRequestString(method, origin, path)}`, { error });\n throw error;\n }\n }\n\n async #parseResponse<T>(requestBody: ConstructorParameters<typeof errors.RapidoHttpClientError>[0], response: Dispatcher.ResponseData, schema?: ZodType): Promise<T> {\n const contentType = (response.headers['content-type'] as string) || '';\n const bodyText = await response.body.text();\n\n if (!bodyText) {\n return undefined as T;\n }\n\n if (/text/i.test(contentType)) {\n return bodyText as T;\n }\n\n let json: unknown;\n try {\n json = JSON.parse(bodyText);\n } catch (error) {\n if (!schema) {\n return bodyText as T;\n }\n const parseResult = schema.safeParse(bodyText);\n if (parseResult.success) {\n return parseResult.data as T;\n }\n throw new errors.RapidoHttpClientError(requestBody, response, undefined, { cause: error as Error });\n }\n return (schema ? schema.parse(json) : json) as T;\n }\n\n /**\n * @param url The endpoint URL to send the request to.\n * @param options Additional options to include in the request payload.\n * @returns A promise that resolves to an array of all results.\n */\n async getAllPages<T>(url: string, options: RequestConfig = {}): Promise<T[]> {\n const currentResult: T[] = [];\n let resultsInFirstPage: number | null = null;\n let lastResultsSize: number | null = null;\n\n const localOptions = { ...options, params: { ...options.params, page: 1 } };\n // Make sure even if `options` had `params` we initialize `page` to 1.\n localOptions.params.page ||= 1;\n\n while ((localOptions.params.page === 1 || lastResultsSize === resultsInFirstPage) && lastResultsSize !== 0) {\n const { data } = await this.get<T[]>(url, localOptions as Omit<RequestConfig, 'responseSchema'>);\n lastResultsSize = data.length;\n if (localOptions.params.page === 1) {\n resultsInFirstPage = data.length;\n }\n\n localOptions.params.page += 1;\n Array.prototype.push.apply(currentResult, data);\n }\n\n return currentResult;\n }\n\n /**\n * Fetches all pages from a paginated API endpoint until all results are retrieved\n * or an optional page limit is reached.\n *\n * @param url The endpoint URL to send the request to.\n * @param options Additional options to include in the request payload.\n * @param pageLimit The maximum number of pages to fetch. Set to -1 for no limit.\n * @returns A promise that resolves to an array of all results.\n */\n async getAllPagesFromQueryEndpoint<T>(url: string, options: object = {}, pageLimit = 100): Promise<T[]> {\n const currentResult: T[] = [];\n\n let moreResultsToLoad = true;\n let page = 1;\n while (moreResultsToLoad && (pageLimit === -1 || page < pageLimit)) {\n const { data } = await this.post<{ rows: T[]; count: number; }>(url, {\n ...options,\n page,\n });\n const { rows, count } = data;\n page += 1;\n Array.prototype.push.apply(currentResult, rows);\n moreResultsToLoad = currentResult.length < count;\n }\n\n return currentResult;\n }\n\n async close(): Promise<void> {\n await this.client.close();\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close();\n }\n}\n\nexport default RapidoHttpClient;\nexport { errors };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":["undiciErrors","response: Dispatcher.ResponseData","data: T","testAgentParam: unique symbol","outbreakInterceptor: Dispatcher.DispatcherComposeInterceptor","headers: Record<string, string | string[]>","retriableMethods: Dispatcher.HttpMethod[]","#logger","#request","#createBaseUrl","headers: Record<string, string>","#prepareRequestBody","#getSignal","requestOptions: Dispatcher.RequestOptions","#parseResponse","error","json: unknown","parseResult","currentResult: T[]","resultsInFirstPage: number | null","lastResultsSize: number | null"],"sources":["../src/errors.ts","../src/testingHelper.ts","../src/outbreakInterceptor.ts","../src/index.ts"],"sourcesContent":["import { STATUS_CODES } from 'node:http';\nimport { type Dispatcher, errors as undiciErrors } from 'undici';\n\nconst RapidoHttpClientErrorBrand = Symbol.for('RapidoHttpClientErrorBrand');\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace errors {\n export import UndiciError = undiciErrors.UndiciError;\n export import ConnectTimeoutError = undiciErrors.ConnectTimeoutError;\n export import HeadersTimeoutError = undiciErrors.HeadersTimeoutError;\n export import HeadersOverflowError = undiciErrors.HeadersOverflowError;\n export import BodyTimeoutError = undiciErrors.BodyTimeoutError;\n export import ResponseError = undiciErrors.ResponseError;\n export import InvalidArgumentError = undiciErrors.InvalidArgumentError;\n export import InvalidReturnValueError = undiciErrors.InvalidReturnValueError;\n export import RequestAbortedError = undiciErrors.RequestAbortedError;\n export import InformationalError = undiciErrors.InformationalError;\n export import RequestContentLengthMismatchError = undiciErrors.RequestContentLengthMismatchError;\n export import ResponseContentLengthMismatchError = undiciErrors.ResponseContentLengthMismatchError;\n export import ClientDestroyedError = undiciErrors.ClientDestroyedError;\n export import ClientClosedError = undiciErrors.ClientClosedError;\n export import SocketError = undiciErrors.SocketError;\n export import NotSupportedError = undiciErrors.NotSupportedError;\n export import BalancedPoolMissingUpstreamError = undiciErrors.BalancedPoolMissingUpstreamError;\n export import HTTPParserError = undiciErrors.HTTPParserError;\n export import ResponseExceededMaxSizeError = undiciErrors.ResponseExceededMaxSizeError;\n export import RequestRetryError = undiciErrors.RequestRetryError;\n export import SecureProxyConnectionError = undiciErrors.SecureProxyConnectionError;\n export import MaxOriginsReachedError = undiciErrors.MaxOriginsReachedError;\n\n export function isRapidoHttpClientError(value: unknown): value is RapidoHttpClientError<unknown> {\n return typeof value === 'object' && value !== null && RapidoHttpClientErrorBrand in value;\n }\n\n export class RapidoHttpClientError<T> extends undiciErrors.ResponseError {\n public readonly status: number;\n public readonly statusText: string;\n\n constructor(\n body: ConstructorParameters<typeof undiciErrors.ResponseError>[2]['body'],\n public readonly response: Dispatcher.ResponseData,\n public readonly data: T,\n errorOptions?: ErrorOptions,\n ) {\n super(`HTTP Error ${response.statusCode}`, response.statusCode, { headers: response.headers, body });\n this.status = response.statusCode;\n this.statusText = STATUS_CODES[response.statusCode] || 'Unknown Status';\n if (errorOptions?.cause) {\n this.cause = errorOptions.cause;\n }\n\n Object.defineProperty(this, RapidoHttpClientErrorBrand, {\n value: true,\n enumerable: false,\n writable: false,\n });\n }\n\n public static isRapidoHttpClientError(value: unknown): value is RapidoHttpClientError<unknown> {\n return isRapidoHttpClientError(value);\n }\n }\n}\n","export const testAgentParam: unique symbol = Symbol('testAgentParam');\n","import type { Dispatcher } from 'undici';\nimport { getCurrentContext } from '@autofleet/outbreak';\n\nexport const outbreakInterceptor: Dispatcher.DispatcherComposeInterceptor = dispatch => function outbreakInterceptorInner(opts, handler) {\n const currentTraceContext = getCurrentContext().context;\n if (currentTraceContext) {\n // Convert headers to object format if they're in array format\n let headers: Record<string, string | string[]>;\n if (Array.isArray(opts.headers)) {\n /* c8 ignore next */\n headers = Object.fromEntries(opts.headers as unknown as [string, string | string[]][]);\n } else {\n headers = { ...opts.headers as Record<string, string | string[]> };\n }\n\n // Inject outbreak trace headers\n for (const [header, value] of currentTraceContext) {\n if (typeof value === 'symbol' || typeof value === 'undefined') {\n continue;\n }\n headers[header] = value as string;\n }\n opts.headers = headers;\n }\n return dispatch(opts, handler);\n};\n","import { STATUS_CODES } from 'node:http';\nimport type { ZodType, output } from 'zod';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\nimport type CacheHandler from 'undici/types/cache-interceptor';\nimport Undici, { Agent, type Dispatcher, interceptors } from 'undici';\nimport { errors } from './errors';\nimport { testAgentParam } from './testingHelper';\nimport { outbreakInterceptor } from './outbreakInterceptor';\nimport {\n createRequestString,\n defaultRetryMethod,\n defaultSettings,\n defaultSettingsWithDecompress,\n isFormData,\n mergeConfig,\n parseUrlAndOrigin,\n resolveServiceUrl,\n} from './utils';\n\nconst { cacheStores } = Undici;\nconst { cache, retry, decompress } = interceptors;\n\nexport interface RapidoHttpClientSettings {\n [testAgentParam]?: Dispatcher;\n /** The MS name to be used to resolve the base URL using K8S service discovery. Ignored if `serviceUrl` is provided as well. */\n serviceName?: string;\n /** The base URL to be used. Overrides `serviceName` when provided. */\n serviceUrl?: string;\n logger: LoggerInstanceManager;\n /** The request timeout in milliseconds. @default 10_000 */\n timeout?: number;\n /** Settings for retrying requests on failure */\n retries?: interceptors.RetryInterceptorOpts;\n /** Common headers applied to all requests of this `RapidoHttpClient` instance. */\n headers?: Record<string, string> | string[][];\n keepAliveTimeout?: number;\n keepAliveMaxTimeout?: number;\n /** The amount of concurrent connections to be maintained using a connection pool. @default 10 */\n connections?: number;\n /** The settings for caching requests */\n cache?: CacheHandler.MemoryCacheStoreOpts;\n /** Whether to automatically decompress response bodies. When `true` will automatically add an `Accept-Encoding` header. @default false */\n autoDecompress?: boolean;\n /**\n * A function to validate the HTTP response status code.\n * Return `true` to consider the status valid, `false` otherwise.\n *\n * When status is invalid, a {@link errors.RapidoHttpClientError `RapidoHttpClientError`} will be thrown.\n *\n * @example (status) => status >= 200 && status < 300\n * @example (status) => status !== 401\n *\n * @default (status) => status < 400\n */\n validateStatus?(status: number): boolean;\n}\n\nexport interface RequestConfig {\n params?: Record<string, any>;\n body?: any;\n /** The request timeout in milliseconds. This overrides the client's instance setting @default 10_000 */\n timeout?: number;\n /** Headers applied to this request, appending on the client's common headers. */\n headers?: Record<string, string>;\n /** An `AbortSignal` which should abort the request and it's parsing when aborted. */\n signal?: AbortSignal;\n /** A Zod schema defining what the response should look like. This also parses error responses. */\n responseSchema?: ZodType;\n /**\n * A function to validate the HTTP response status code.\n * Return `true` to consider the status valid, `false` otherwise.\n *\n * When status is invalid, a {@link errors.RapidoHttpClientError `RapidoHttpClientError`} will be thrown.\n *\n * @example (status) => status >= 200 && status < 300\n * @example (status) => status !== 401\n *\n * @default (status) => status < 400\n */\n validateStatus?(status: number): boolean;\n}\n\nexport interface RapidoHttpClientResponse<T = any> {\n data: T;\n status: number;\n statusText: string;\n headers: Record<string, string | string[]>;\n config: RequestConfig & { url: string; method: string; baseURL?: string; };\n}\n\nconst retriableMethods: Dispatcher.HttpMethod[] = ['GET', 'HEAD', 'OPTIONS', 'PUT', 'DELETE', 'TRACE', 'QUERY'];\n\nexport class RapidoHttpClient {\n readonly #logger: LoggerInstanceManager;\n private readonly settings: RapidoHttpClientSettings & { baseURL?: string; basePath?: string; };\n public readonly client: Dispatcher.ComposedDispatcher;\n\n public get<T = unknown>(url: string, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public get<T extends ZodType>(url: string, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public get<T = unknown>(url: string, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('GET', url, undefined, config);\n }\n\n public post<T = unknown>(url: string, body?: any, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public post<T extends ZodType>(url: string, body: any, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public post<T = unknown>(url: string, body?: any, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('POST', url, body, config);\n }\n\n public delete<T = unknown>(url: string, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public delete<T extends ZodType>(url: string, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public delete<T = unknown>(url: string, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('DELETE', url, undefined, config);\n }\n\n public head<T = unknown>(url: string, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public head<T extends ZodType>(url: string, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public head<T = unknown>(url: string, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('HEAD', url, undefined, config);\n }\n\n public put<T = unknown>(url: string, body?: any, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public put<T extends ZodType>(url: string, body: any, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public put<T = unknown>(url: string, body?: any, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('PUT', url, body, config);\n }\n\n public patch<T = unknown>(url: string, body?: any, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public patch<T extends ZodType>(url: string, body: any, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public patch<T = unknown>(url: string, body?: any, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('PATCH', url, body, config);\n }\n\n public options<T = unknown>(url: string, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public options<T extends ZodType>(url: string, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public options<T = unknown>(url: string, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('OPTIONS', url, undefined, config);\n }\n\n public query<T = unknown>(url: string, body?: any, config?: Omit<RequestConfig, 'responseSchema'> & { responseSchema?: never; }): Promise<RapidoHttpClientResponse<T>>;\n public query<T extends ZodType>(url: string, body: any, config: RequestConfig & { responseSchema: T; }): Promise<RapidoHttpClientResponse<output<T>>>;\n public query<T = unknown>(url: string, body?: any, config?: RequestConfig): Promise<RapidoHttpClientResponse<T>> {\n return this.#request<T>('QUERY', url, body, config);\n }\n\n constructor(settings: RapidoHttpClientSettings) {\n this.#logger = settings.logger;\n this.settings = mergeConfig<typeof defaultSettings, Partial<typeof settings>>(\n settings.autoDecompress ? defaultSettingsWithDecompress : defaultSettings,\n settings,\n ) as RapidoHttpClientSettings & { baseURL?: string; };\n this.#createBaseUrl();\n\n // In test mode, use the test dispatcher directly (MockAgent or MockPool) Otherwise, create an Agent which creates Client Pools\n // Check for global mock agent first (for testing), then test param, then create real Agent\n /* c8 ignore next */\n const globalMockAgent = (globalThis as any).__RAPIDO_HTTP_CLIENT_MOCK_AGENT__;\n /* c8 ignore next */\n this.client = this.settings[testAgentParam] ?? globalMockAgent ?? new Agent({\n connect: {\n timeout: this.settings.timeout,\n },\n keepAliveTimeout: this.settings.keepAliveTimeout,\n keepAliveMaxTimeout: this.settings.keepAliveMaxTimeout,\n connections: this.settings.connections,\n });\n\n if (this.settings.cache) {\n this.client = this.client.compose(cache({\n store: new cacheStores.MemoryCacheStore({\n ...this.settings.cache,\n }),\n }));\n }\n\n if (this.settings.retries) {\n this.client = this.client.compose(retry({\n methods: retriableMethods,\n ...this.settings.retries,\n retry: (err, context, callback) => {\n const { counter } = context.state;\n /* c8 ignore next */\n const maxRetries = context.opts.retryOptions?.maxRetries ?? 5;\n\n const retryToUse = this.settings.retries?.retry ?? defaultRetryMethod;\n const callbackWithLogging = (result?: Error | null) => {\n if (!result) {\n const { method, origin, path } = context.opts;\n const baseUrl = (!origin || typeof origin === 'string') ? origin : origin.origin;\n this.#logger.warn(`Request retry attempt ${counter}/${maxRetries}: ${createRequestString(method, baseUrl, path)}`, { err });\n }\n callback(result);\n };\n retryToUse(err, context, callbackWithLogging);\n },\n }));\n }\n\n if (this.settings.autoDecompress) {\n this.client = this.client.compose(decompress({ skipErrorResponses: false }));\n }\n\n this.client = this.client.compose(outbreakInterceptor);\n }\n\n #createBaseUrl(): void {\n const fullUrl = resolveServiceUrl(this.settings);\n const urlObj = new URL(fullUrl);\n this.settings.baseURL = urlObj.origin;\n this.settings.basePath = urlObj.pathname !== '/' ? urlObj.pathname : '';\n }\n\n #getSignal(currentSignal?: AbortSignal, timeout?: number): { signal?: AbortSignal; timeoutSignal?: AbortSignal; } {\n if (!currentSignal && !timeout) {\n return { signal: undefined, timeoutSignal: undefined };\n }\n\n if (currentSignal && !timeout) {\n return { signal: currentSignal, timeoutSignal: undefined };\n }\n\n const timeoutSignal = AbortSignal.timeout(timeout!);\n if (!currentSignal && timeout) {\n return { signal: timeoutSignal, timeoutSignal };\n }\n\n return { signal: AbortSignal.any([currentSignal!, timeoutSignal]), timeoutSignal };\n }\n\n #prepareRequestBody(body: any, headers: Record<string, string>): string | Buffer | FormData | undefined {\n if (body === undefined || body === null) {\n return undefined;\n }\n\n // Handle FormData instances automatically\n if (isFormData(body)) {\n if (!headers['Content-Type'] && !headers['content-type']) {\n headers['Content-Type'] = 'application/x-www-form-urlencoded';\n }\n return body;\n }\n\n if (typeof body === 'object' && !Buffer.isBuffer(body)) {\n // Check if Content-Type is set to application/x-www-form-urlencoded\n const contentType = headers['Content-Type'] || headers['content-type'];\n if (contentType && /application\\/x-www-form-urlencoded/i.test(contentType)) {\n // Encode as URL parameters\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(body)) {\n if (Array.isArray(value)) {\n value.forEach(v => params.append(key, String(v)));\n } else if (value !== undefined && value !== null) {\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n params.append(key, String(value));\n }\n }\n return params.toString();\n }\n // Default to JSON\n if (!headers['Content-Type'] && !headers['content-type']) {\n headers['Content-Type'] = 'application/json';\n }\n return JSON.stringify(body);\n } else if (typeof body === 'string') {\n return body;\n } else if (Buffer.isBuffer(body)) {\n return body;\n }\n return String(body);\n }\n\n async #request<T = any>(\n method: Dispatcher.HttpMethod,\n url: string,\n body?: any,\n config: RequestConfig = {},\n ): Promise<RapidoHttpClientResponse<T>> {\n const mergedConfig = mergeConfig(this.settings, config);\n\n if (mergedConfig.signal?.aborted) {\n this.#logger.error(`Request aborted before start: ${createRequestString(method, mergedConfig.baseURL, url)}`);\n throw new errors.RequestAbortedError(mergedConfig.signal.reason?.message || 'Request aborted', { cause: mergedConfig.signal.reason });\n }\n\n const headers: Record<string, string> = { ...mergedConfig.headers };\n const requestBody = this.#prepareRequestBody(body, headers);\n\n const { origin, path } = parseUrlAndOrigin(url, mergedConfig.baseURL!, mergedConfig.basePath);\n const requestInfo = { method, baseURL: origin, url };\n\n if (mergedConfig.params) {\n for (const [key, value] of Object.entries(mergedConfig.params)) {\n if (Array.isArray(value) && !key.endsWith('[]')) {\n mergedConfig.params[`${key}[]`] = value;\n delete mergedConfig.params[key];\n }\n }\n }\n\n const { signal, timeoutSignal } = this.#getSignal(mergedConfig.signal, mergedConfig.timeout);\n\n try {\n this.#logger.info(`Start Request: ${createRequestString(method, origin, path)}`);\n\n const requestOptions: Dispatcher.RequestOptions = {\n path,\n origin,\n method,\n signal,\n headers,\n body: requestBody,\n query: mergedConfig.params,\n };\n\n const response = await this.client.request(requestOptions);\n\n const isStatusValid = mergedConfig.validateStatus ?? (() => response.statusCode < 400);\n if (!isStatusValid(response.statusCode)) {\n const data = await this.#parseResponse<T>(requestBody, response, config.responseSchema);\n this.#logger.error(`Finish Request with error ${createRequestString(method, origin, path)}`, {\n status: response.statusCode,\n data,\n });\n\n throw new errors.RapidoHttpClientError<T>(requestBody, response, data);\n }\n\n this.#logger.info(`Finish Request: ${createRequestString(method, origin, path)}`);\n\n const data = response.statusCode !== 204 ? await this.#parseResponse<T>(requestBody, response, config.responseSchema) : undefined as T;\n\n return {\n data,\n status: response.statusCode,\n statusText: STATUS_CODES[response.statusCode] || '',\n headers: response.headers as Record<string, string | string[]>,\n config: requestInfo,\n };\n } catch (error) {\n if (timeoutSignal && timeoutSignal.reason === error) {\n // If the timeoutSignal aborted (config timeout), throw a timeout-specific error\n this.#logger.error(`Request timeout: ${createRequestString(method, origin, path)}`);\n const error = new errors.UndiciError(`Request timeout after ${mergedConfig.timeout}ms`, { cause: timeoutSignal.reason });\n error.code = 'UND_ERR_TIMEOUT';\n throw error;\n }\n if (signal && signal.reason === error) {\n // If the user's signal aborted, throw RequestAbortedError\n this.#logger.error(`Request aborted: ${createRequestString(method, origin, path)}`);\n throw new errors.RequestAbortedError(signal.reason.message, { cause: signal.reason });\n }\n\n this.#logger.error(`Finish Request with error ${createRequestString(method, origin, path)}`, { error });\n throw error;\n }\n }\n\n async #parseResponse<T>(requestBody: ConstructorParameters<typeof errors.RapidoHttpClientError>[0], response: Dispatcher.ResponseData, schema?: ZodType): Promise<T> {\n const contentType = (response.headers['content-type'] as string) || '';\n const bodyText = await response.body.text();\n\n if (!bodyText) {\n return undefined as T;\n }\n\n if (/text/i.test(contentType)) {\n return bodyText as T;\n }\n\n let json: unknown;\n try {\n json = JSON.parse(bodyText);\n } catch (error) {\n if (!schema) {\n return bodyText as T;\n }\n const parseResult = schema.safeParse(bodyText);\n if (parseResult.success) {\n return parseResult.data as T;\n }\n throw new errors.RapidoHttpClientError(requestBody, response, undefined, { cause: error as Error });\n }\n if (!schema) {\n return json as T;\n }\n const parseResult = schema.safeParse(json);\n if (parseResult.success) {\n return parseResult.data as T;\n }\n throw Object.assign(parseResult.error, { json });\n }\n\n /**\n * @param url The endpoint URL to send the request to.\n * @param options Additional options to include in the request payload.\n * @returns A promise that resolves to an array of all results.\n */\n async getAllPages<T>(url: string, options: RequestConfig = {}): Promise<T[]> {\n const currentResult: T[] = [];\n let resultsInFirstPage: number | null = null;\n let lastResultsSize: number | null = null;\n\n const localOptions = { ...options, params: { ...options.params, page: 1 } };\n // Make sure even if `options` had `params` we initialize `page` to 1.\n localOptions.params.page ||= 1;\n\n while ((localOptions.params.page === 1 || lastResultsSize === resultsInFirstPage) && lastResultsSize !== 0) {\n const { data } = await this.get<T[]>(url, localOptions as Omit<RequestConfig, 'responseSchema'>);\n lastResultsSize = data.length;\n if (localOptions.params.page === 1) {\n resultsInFirstPage = data.length;\n }\n\n localOptions.params.page += 1;\n Array.prototype.push.apply(currentResult, data);\n }\n\n return currentResult;\n }\n\n /**\n * Fetches all pages from a paginated API endpoint until all results are retrieved\n * or an optional page limit is reached.\n *\n * @param url The endpoint URL to send the request to.\n * @param options Additional options to include in the request payload.\n * @param pageLimit The maximum number of pages to fetch. Set to -1 for no limit.\n * @returns A promise that resolves to an array of all results.\n */\n async getAllPagesFromQueryEndpoint<T>(url: string, options: object = {}, pageLimit = 100): Promise<T[]> {\n const currentResult: T[] = [];\n\n let moreResultsToLoad = true;\n let page = 1;\n while (moreResultsToLoad && (pageLimit === -1 || page < pageLimit)) {\n const { data } = await this.post<{ rows: T[]; count: number; }>(url, {\n ...options,\n page,\n });\n const { rows, count } = data;\n page += 1;\n Array.prototype.push.apply(currentResult, rows);\n moreResultsToLoad = currentResult.length < count;\n }\n\n return currentResult;\n }\n\n async close(): Promise<void> {\n await this.client.close();\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close();\n }\n}\n\nexport default RapidoHttpClient;\nexport { errors };\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@autofleet/rapido-http-client",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "Modern undici-based HTTP client with logging, retries, and global configuration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -61,9 +61,9 @@
|
|
|
61
61
|
"@types/node": "^20.0.0",
|
|
62
62
|
"nock": "^14.0.1",
|
|
63
63
|
"zod": "^4.2.1",
|
|
64
|
-
"@autofleet/logger": "^4.2.
|
|
65
|
-
"@autofleet/
|
|
66
|
-
"@autofleet/
|
|
64
|
+
"@autofleet/logger": "^4.2.39",
|
|
65
|
+
"@autofleet/network": "^1.9.5",
|
|
66
|
+
"@autofleet/outbreak": "^2.5.11"
|
|
67
67
|
},
|
|
68
68
|
"scripts": {
|
|
69
69
|
"test": "vitest",
|