{"version":3,"sources":["../src/utils/apiClient.ts"],"names":["ApiClient","tokenStore","accountApi","onRefreshTokenError","url","options","retried","accessToken","response","NaluriRefreshTokenError","refreshToken","error"],"mappings":";yCAIO,IAAMA,EAAN,KAAgB,CACJ,YACA,WACA,WACA,oBAEjB,YACEC,EACAC,EACAC,EACA,CACA,KAAK,YACH,OAAO,OAAW,IAAc,MAAQ,OAAO,MAAM,KAAK,MAAM,EAClE,KAAK,WAAaF,EAClB,KAAK,WAAaC,EAClB,KAAK,oBAAsBC,CAC7B,CAEA,MAAa,MAAMC,EAAaC,EAAyC,CACvE,OAAO,MAAM,KAAK,QAAQD,EAAKC,CAAO,CACxC,CAEA,MAAc,QACZD,EACAC,EACAC,EAAU,GACS,CACnB,IAAMC,EAAc,KAAK,WAAW,QAAQ,aAAa,EAErDA,IACFF,EAAQ,QAAU,CAChB,GAAGA,EAAQ,QACX,cAAe,UAAUE,CAAW,EACtC,GAGF,IAAMC,EAAW,MAAM,KAAK,YAAYJ,EAAKC,CAAO,EAEpD,GAAIG,EAAS,SAAW,KAAOF,EAAS,CACtC,GAAI,KAAK,oBACP,aAAM,KAAK,oBAAoB,EAGxB,CACL,GAAI,GACJ,KAAM,KAAO,CACX,QAAS,kCACT,WAAY,IACd,GACA,OAAQ,GACV,EAGF,MAAM,IAAIG,CACZ,CAEA,GAAID,EAAS,SAAW,IAAK,CAC3B,IAAME,EAAe,KAAK,WAAW,QAAQ,cAAc,EAE3D,GAAI,CAACA,EAAc,CACjB,GAAI,KAAK,oBACP,aAAM,KAAK,oBAAoB,EAExB,CACL,GAAI,GACJ,KAAM,KAAO,CACX,QAAS,wBACT,WAAY,IACd,GACA,OAAQ,GACV,EAGF,MAAM,IAAID,CACZ,CAEA,GAAI,CACF,GAAM,CAAE,YAAAF,CAAY,EAAI,MAAM,KAAK,WAAW,QAAQG,CAAY,EAElE,KAAK,WAAW,QAAQ,cAAeH,CAAW,CACpD,OAASI,EAAO,CACd,GAAI,KAAK,oBACP,aAAM,KAAK,oBAAoB,EAExB,CACL,GAAI,GACJ,KAAM,KAAO,CACX,WAAY,KACZ,QAAS,uBACNA,EAAgB,SAAWA,CAC9B,EACF,GACA,OAAQ,GACV,EAEF,MAAM,IAAIF,CACZ,CAEA,OAAO,KAAK,QAAQL,EAAKC,EAAS,EAAI,CACxC,CAEA,OAAOG,CACT,CACF","sourcesContent":["import { AccountApi } from '@/api/account.api';\nimport { NaluriRefreshTokenError } from '@/errors';\nimport type { TokenStore } from '@/utils/tokenStore';\n\nexport class ApiClient {\n  private readonly fetchClient: typeof fetch;\n  private readonly tokenStore: TokenStore;\n  private readonly accountApi: AccountApi;\n  private readonly onRefreshTokenError?: () => Promise<void>;\n\n  constructor(\n    tokenStore: TokenStore,\n    accountApi: AccountApi,\n    onRefreshTokenError?: () => Promise<void>,\n  ) {\n    this.fetchClient =\n      typeof window === 'undefined' ? fetch : window.fetch.bind(window);\n    this.tokenStore = tokenStore;\n    this.accountApi = accountApi;\n    this.onRefreshTokenError = onRefreshTokenError;\n  }\n\n  public async fetch(url: string, options: RequestInit): Promise<Response> {\n    return await this.doFetch(url, options);\n  }\n\n  private async doFetch(\n    url: string,\n    options: RequestInit,\n    retried = false,\n  ): Promise<Response> {\n    const accessToken = this.tokenStore.getItem('accessToken');\n\n    if (accessToken) {\n      options.headers = {\n        ...options.headers,\n        Authorization: `Bearer ${accessToken}`,\n      };\n    }\n\n    const response = await this.fetchClient(url, options);\n\n    if (response.status === 401 && retried) {\n      if (this.onRefreshTokenError) {\n        await this.onRefreshTokenError();\n\n        // @ts-expect-error\n        return {\n          ok: false,\n          json: () => ({\n            message: 'Refresh flow retried but failed',\n            statusCode: 8888,\n          }),\n          status: 401,\n        } as Response;\n      }\n\n      throw new NaluriRefreshTokenError();\n    }\n\n    if (response.status === 401) {\n      const refreshToken = this.tokenStore.getItem('refreshToken');\n\n      if (!refreshToken) {\n        if (this.onRefreshTokenError) {\n          await this.onRefreshTokenError();\n          // @ts-expect-error\n          return {\n            ok: false,\n            json: () => ({\n              message: 'Missing refresh token',\n              statusCode: 8888,\n            }),\n            status: 401,\n          } as Response;\n        }\n\n        throw new NaluriRefreshTokenError();\n      }\n\n      try {\n        const { accessToken } = await this.accountApi.refresh(refreshToken);\n\n        this.tokenStore.setItem('accessToken', accessToken);\n      } catch (error) {\n        if (this.onRefreshTokenError) {\n          await this.onRefreshTokenError();\n          // @ts-expect-error\n          return {\n            ok: false,\n            json: () => ({\n              statusCode: 8888,\n              message: `Refresh API failed: ${\n                (error as Error).message || error\n              }`,\n            }),\n            status: 401,\n          } as Response;\n        }\n        throw new NaluriRefreshTokenError();\n      }\n\n      return this.doFetch(url, options, true);\n    }\n\n    return response;\n  }\n}\n"]}