{"version":3,"file":"index7.cjs","sources":["../src/request.ts"],"sourcesContent":["import { CustomRequestError, throwCustomRequestError } from './errors'\nimport { convertObjectToCamelCase } from './formatting'\nimport { buildUserAgent } from './utils'\nimport axios, { AxiosHeaders, AxiosRequestConfig } from 'axios'\nimport { IncogniaToken } from './token'\nimport { Method } from './types'\nimport { apiEndpoints } from './endpoints'\nimport QueryString from 'qs'\nimport { TokenStorage } from './token'\nimport https from 'node:https'\n\ntype RequestManagerConstructor = {\n  clientId: string\n  clientSecret: string\n  keepAlive?: boolean\n  maxRetries?: number\n  retryDelayMs?: number\n}\n\nexport class RequestManager {\n  readonly clientId: string\n  readonly clientSecret: string\n\n  readonly httpsAgent: https.Agent\n  readonly maxRetries: number\n  readonly retryDelayMs: number\n\n  readonly tokenStorage: TokenStorage\n\n  lastLatencyMs?: number\n\n  constructor({\n    clientId,\n    clientSecret,\n    keepAlive = true,\n    maxRetries = 0,\n    retryDelayMs = 200\n  }: RequestManagerConstructor) {\n    this.clientId = clientId\n    this.clientSecret = clientSecret\n\n    this.httpsAgent = new https.Agent({ keepAlive })\n    this.maxRetries = maxRetries\n    this.retryDelayMs = retryDelayMs\n\n    this.tokenStorage = new TokenStorage({\n      onRequestToken: async () => this.requestToken()\n    })\n  }\n\n  async requestResource(options: AxiosRequestConfig) {\n    const token = await this.tokenStorage.getToken()\n    const previousLatencyMs = this.lastLatencyMs\n\n    return this.withRetry(async () => {\n      const start = Date.now()\n      const headers = AxiosHeaders.from(options.headers)\n\n      headers.set('Content-Type', 'application/json')\n      headers.set('User-Agent', buildUserAgent())\n      headers.set('Authorization', `${token?.tokenType} ${token?.accessToken}`)\n\n      if (previousLatencyMs !== undefined) {\n        headers.set('X-Incognia-Latency', `${previousLatencyMs}`)\n      }\n\n      const response = await axios({\n        ...options,\n        headers,\n        httpsAgent: this.httpsAgent\n      })\n\n      this.lastLatencyMs = Date.now() - start\n\n      return convertObjectToCamelCase(response.data)\n    }).catch(e => {\n      throwCustomRequestError(e as CustomRequestError)\n    })\n  }\n\n  async requestToken(): Promise<IncogniaToken | undefined> {\n    const response = await this.withRetry(async () => {\n      return axios({\n        method: Method.Post,\n        url: apiEndpoints.TOKEN,\n        data: QueryString.stringify({ grant_type: 'client_credentials' }),\n        auth: {\n          username: this.clientId,\n          password: this.clientSecret\n        },\n        headers: {\n          'Content-Type': 'application/x-www-form-urlencoded',\n          'User-Agent': buildUserAgent()\n        },\n        httpsAgent: this.httpsAgent\n      })\n    }).catch(e => {\n      throwCustomRequestError(e as CustomRequestError)\n    })\n\n    const data = response?.data\n\n    return {\n      createdAt: Math.round(Date.now() / 1000),\n      expiresIn: parseInt(data.expires_in),\n      accessToken: data.access_token,\n      tokenType: data.token_type\n    }\n  }\n\n  private async withRetry<T>(fn: () => Promise<T>): Promise<T> {\n    let attempt = 0\n    let lastError: unknown\n\n    while (attempt <= this.maxRetries) {\n      try {\n        return await fn()\n      } catch (err) {\n        lastError = err\n\n        // Do not retry on client errors (4xx)\n        if (axios.isAxiosError(err)) {\n          const status = err.response?.status\n          if (typeof status === 'number' && status >= 400 && status < 500) {\n            throw err\n          }\n        }\n\n        // No more retries left\n        if (attempt === this.maxRetries) break\n\n        // Wait before next attempt\n        await new Promise(res => setTimeout(res, this.retryDelayMs))\n      }\n      attempt++\n    }\n\n    throw lastError\n  }\n}\n"],"names":["RequestManager","clientId","clientSecret","keepAlive","maxRetries","retryDelayMs","https","TokenStorage","options","token","previousLatencyMs","start","headers","AxiosHeaders","buildUserAgent","response","axios","convertObjectToCamelCase","e","throwCustomRequestError","data","Method","apiEndpoints","QueryString","fn","attempt","lastError","err","status","res"],"mappings":"qWAmBO,MAAMA,CAAe,CAY1B,YAAY,CACV,SAAAC,EACA,aAAAC,EACA,UAAAC,EAAY,GACZ,WAAAC,EAAa,EACb,aAAAC,EAAe,GAAA,EACa,CAC5B,KAAK,SAAWJ,EAChB,KAAK,aAAeC,EAEpB,KAAK,WAAa,IAAII,EAAAA,QAAM,MAAM,CAAE,UAAAH,EAAW,EAC/C,KAAK,WAAaC,EAClB,KAAK,aAAeC,EAEpB,KAAK,aAAe,IAAIE,eAAa,CACnC,eAAgB,SAAY,KAAK,aAAA,CAAa,CAC/C,CACH,CAEA,MAAM,gBAAgBC,EAA6B,CACjD,MAAMC,EAAQ,MAAM,KAAK,aAAa,SAAA,EAChCC,EAAoB,KAAK,cAE/B,OAAO,KAAK,UAAU,SAAY,CAChC,MAAMC,EAAQ,KAAK,IAAA,EACbC,EAAUC,EAAAA,aAAa,KAAKL,EAAQ,OAAO,EAEjDI,EAAQ,IAAI,eAAgB,kBAAkB,EAC9CA,EAAQ,IAAI,aAAcE,EAAAA,gBAAgB,EAC1CF,EAAQ,IAAI,gBAAiB,GAAGH,GAAO,SAAS,IAAIA,GAAO,WAAW,EAAE,EAEpEC,IAAsB,QACxBE,EAAQ,IAAI,qBAAsB,GAAGF,CAAiB,EAAE,EAG1D,MAAMK,EAAW,MAAMC,UAAM,CAC3B,GAAGR,EACH,QAAAI,EACA,WAAY,KAAK,UAAA,CAClB,EAED,YAAK,cAAgB,KAAK,IAAA,EAAQD,EAE3BM,EAAAA,yBAAyBF,EAAS,IAAI,CAC/C,CAAC,EAAE,MAAMG,GAAK,CACZC,EAAAA,wBAAwBD,CAAuB,CACjD,CAAC,CACH,CAEA,MAAM,cAAmD,CAoBvD,MAAME,GAnBW,MAAM,KAAK,UAAU,SAC7BJ,UAAM,CACX,OAAQK,EAAAA,OAAO,KACf,IAAKC,EAAAA,aAAa,MAClB,KAAMC,EAAAA,QAAY,UAAU,CAAE,WAAY,qBAAsB,EAChE,KAAM,CACJ,SAAU,KAAK,SACf,SAAU,KAAK,YAAA,EAEjB,QAAS,CACP,eAAgB,oCAChB,aAAcT,EAAAA,eAAA,CAAe,EAE/B,WAAY,KAAK,UAAA,CAClB,CACF,EAAE,MAAMI,GAAK,CACZC,EAAAA,wBAAwBD,CAAuB,CACjD,CAAC,IAEsB,KAEvB,MAAO,CACL,UAAW,KAAK,MAAM,KAAK,IAAA,EAAQ,GAAI,EACvC,UAAW,SAASE,EAAK,UAAU,EACnC,YAAaA,EAAK,aAClB,UAAWA,EAAK,UAAA,CAEpB,CAEA,MAAc,UAAaI,EAAkC,CAC3D,IAAIC,EAAU,EACVC,EAEJ,KAAOD,GAAW,KAAK,YAAY,CACjC,GAAI,CACF,OAAO,MAAMD,EAAA,CACf,OAASG,EAAK,CAIZ,GAHAD,EAAYC,EAGRX,EAAAA,QAAM,aAAaW,CAAG,EAAG,CAC3B,MAAMC,EAASD,EAAI,UAAU,OAC7B,GAAI,OAAOC,GAAW,UAAYA,GAAU,KAAOA,EAAS,IAC1D,MAAMD,CAEV,CAGA,GAAIF,IAAY,KAAK,WAAY,MAGjC,MAAM,IAAI,QAAQI,GAAO,WAAWA,EAAK,KAAK,YAAY,CAAC,CAC7D,CACAJ,GACF,CAEA,MAAMC,CACR,CACF"}