@orbis-systems/orbis-api-clients 0.4.5 → 0.5.0

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.esm.js CHANGED
@@ -96,7 +96,7 @@ class $e176194f300187e4$export$4f22f74eddb7716a {
96
96
  if (contentType === "multipart/form-data" && typeof data === 'object') requestConfig.data = this.createFormData(data);
97
97
  if (contentType === "text/plain" && typeof data !== 'string') requestConfig.data = JSON.stringify(data);
98
98
  }
99
- const mergedConfig = (0, $ikBRU$merge)(requestConfig.secure ?? this.config.defaultSecure ? await this.prepareAuthRequestConfig() : {}, contentType ? {
99
+ const mergedConfig = (0, $ikBRU$merge)(requestConfig.secure ?? this.config.defaultSecure ?? true ? await this.prepareAuthRequestConfig() : {}, contentType ? {
100
100
  headers: {
101
101
  'Content-Type': contentType
102
102
  }
@@ -1 +1 @@
1
- {"mappings":";;;;;;;;;;;;;;;;;ACGO,MAAM;IAIT,iCAAiC;IACjC,yBAAyB;IACzB,+BAA+B;IAC/B,2BAA2B;IAC3B,iCAAiC;IACjC,2BAA2B;IAC3B,yBAAyB;IACzB,6BAA6B;IAE7B,YAAY,AAAmB,SAAoB,CAAE;aAAtB,YAAA;QAC3B,CAAA,GAAA,eAAO,EAAE,IAAI;IACb,sCAAsC;IACtC,8BAA8B;IAC9B,oCAAoC;IACpC,gCAAgC;IAChC,sCAAsC;IACtC,gCAAgC;IAChC,8BAA8B;IAC9B,kCAAkC;IAClC,8BAA8B;IAClC;IAEA,eAA0B;QACtB,OAAO,IAAI,CAAC,SAAS;IACzB;AACJ;;;;;;;;;;;ACTO,IAAA,AAAK,mEAAA;;;;;WAAA;;AAiCL,MAAe;IAIlB,YAAY,AAAmB,MAAqC,CAAE;aAAvC,SAAA;QAC3B,CAAA,GAAA,eAAO,EAAE,IAAI;QACb,IAAI,CAAC,OAAO,GAAG,OAAO,OAAO,IAAI;QACjC,IAAI,CAAC,aAAa,GAAG,CAAA,GAAA,YAAI,EAAE,MAAM,CAAC;YAC9B,SAAS,OAAO,OAAO;YACvB,SAAS;gBACL,gBAAgB;gBAChB,GAAG,OAAO,cAAc;YAC5B;QACJ;QACA,CAAA,GAAA,4BAAoB,EAAE,IAAI,CAAC,aAAa;IAC5C;IAEU,kBAAkB,QAAiB,EAAE;QAC3C,IAAI,OAAO,aAAa,YAAY,aAAa,MAC7C,OAAO,KAAK,SAAS,CAAC;aAEtB,OAAO,GAAG,UAAU;IAE5B;IAEU,eAAe,KAA8B,EAAY;QAC/D,IAAI,iBAAiB,UACjB,OAAO;QAGX,OAAO,OAAO,IAAI,CAAC,OAAO,MAAM,CAAC,CAAC,UAAU;YACxC,MAAM,WAAW,KAAK,CAAC,IAAI;YAC3B,MAAM,kBAAyB,oBAAoB,QAAQ,WAAW;gBAAC;aAAS;YAEhF,KAAK,MAAM,YAAY,gBAAiB;gBACpC,MAAM,aAAa,oBAAoB,QAAQ,oBAAoB;gBACnE,SAAS,MAAM,CAAC,KAAK,aAAa,WAAW,IAAI,CAAC,iBAAiB,CAAC;YACxE;YAEA,OAAO;QACX,GAAG,IAAI;IACX;IAEA,MAAM,QACF,aAAkC,EACQ;QAC1C,MAAM,eAAE,WAAW,QAAE,IAAI,EAAE,GAAG;QAE9B,IAAI,CAAC,CAAA,GAAA,YAAI,EAAE,OAAO;YACd,IAAI,yCAAwC,OAAO,SAAS,UACxD,cAAc,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC;YAG7C,IAAI,gCAAoC,OAAO,SAAS,UACpD,cAAc,IAAI,GAAG,KAAK,SAAS,CAAC;QAE5C;QAEA,MAAM,eAAe,CAAA,GAAA,YAAI,EACrB,AAAC,cAAc,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,GAAI,MAAM,IAAI,CAAC,wBAAwB,KAAK,CAAC,GAC/F,cAAc;YAAE,SAAS;gBAAE,gBAAgB;YAAY;QAAE,IAAI,CAAC,GAC9D;QAGJ,IAAI;YACA,MAAM,QAAE,IAAI,UAAE,MAAM,cAAE,UAAU,EAAE,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,OAAO,CACjE;YAGJ,OAAO;gBACH,SAAS;sBACT;wBACA;4BACA;YACJ;QACJ,EAAE,OAAO,OAAO;YACZ,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,CAAC,cAAc,WAAW,EACtD,MAAM;YAGV,MAAM,SAA8B;gBAChC,SAAS;gBACT,QAAQ;gBACR,YAAY,OAAO;uBACnB;YACJ;YAEA,IAAI,CAAA,GAAA,mBAAW,EAAe,QAAQ;gBAClC,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG;gBAC3B,OAAO,IAAI,GAAG,MAAM,QAAQ,EAAE;gBAC9B,OAAO,MAAM,GAAG,MAAM,QAAQ,EAAE,UAAU,OAAO,MAAM;gBACvD,OAAO,UAAU,GAAG,MAAM,QAAQ,EAAE,cAAc,OAAO,UAAU;YACvE;YAEA,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG;YAEtB,OAAO;QACX;IACJ;IAEA,IAAqD,GAAW,EAAE,MAA4B,EAAE;QAC5F,OAAO,IAAI,CAAC,OAAO,CAAoB;YACnC,GAAG,MAAM;YACT,QAAQ;iBACR;QACJ;IACJ;IAEA,OAAwD,GAAW,EAAE,MAA4B,EAAE;QAC/F,OAAO,IAAI,CAAC,OAAO,CAAoB;YACnC,GAAG,MAAM;YACT,QAAQ;iBACR;QACJ;IACJ;IAEA,KAAsD,GAAW,EAAE,MAA4B,EAAE;QAC7F,OAAO,IAAI,CAAC,OAAO,CAAoB;YACnC,GAAG,MAAM;YACT,QAAQ;iBACR;QACJ;IACJ;IAEA,QAAyD,GAAW,EAAE,MAA4B,EAAE;QAChG,OAAO,IAAI,CAAC,OAAO,CAAoB;YACnC,GAAG,MAAM;YACT,QAAQ;iBACR;QACJ;IACJ;IAEA,KAAsD,GAAW,EAAE,IAAW,EAAE,MAA4B,EAAE;QAC1G,OAAO,IAAI,CAAC,OAAO,CAAoB;YACnC,GAAG,MAAM;YACT,QAAQ;iBACR;kBACA;QACJ;IACJ;IAEA,IAAqD,GAAW,EAAE,IAAW,EAAE,MAA4B,EAAE;QACzG,OAAO,IAAI,CAAC,OAAO,CAAoB;YACnC,GAAG,MAAM;YACT,QAAQ;iBACR;kBACA;QACJ;IACJ;IAEA,MAAuD,GAAW,EAAE,IAAW,EAAE,MAA4B,EAAE;QAC3G,OAAO,IAAI,CAAC,OAAO,CAAoB;YACnC,GAAG,MAAM;YACT,QAAQ;iBACR;kBACA;QACJ;IACJ;IAEA,WAA0B;QACtB,OAAO,IAAI,CAAC,aAAa;IAC7B;IAEA,YAAY,IAAqB,EAAE;QAC/B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,IAAI,QAAQ,KAAK,SAAS,CAAC;IAClF;IAEA,cAA+B;QAC3B,MAAM,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,kBAAkB,IAAI;QACpE,OAAO,OAAQ,KAAK,KAAK,CAAC,QAAqB;IACnD;IAEA,YAA2C;QACvC,OAAO,IAAI,CAAC,MAAM;IACtB;AAGJ;;;;;;;;;;;ACzNO,MAAM,kDAGH,CAAA,GAAA,yCAAS;IAIf,YAAY,AAA4B,MAAoC,CAAE;QAC1E,KAAK,CAAC,cAD8B,SAAA,aAHvB,OAAO,IAAI,CAAA,GAAA,YAAI;IAKhC;IAES,YAA0C;QAC/C,OAAO,KAAK,CAAC;IACjB;IAEA,sBAAsB,kBAA2C,EAAE;QAC/D,IAAI,CAAC,kBAAkB,GAAG;IAC9B;IAEA,MAAyB,2BAEvB;QACE,IAAI,eAAE,WAAW,EAAE,GAAG,IAAI,CAAC,WAAW,MAAM,CAAC;QAE7C,IAAI,CAAC,aAAa;YACd,CAAA,GAAA,cAAM,EAAE,IAAI,CAAC;YACb,OAAO,CAAC;QACZ;QAEA,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,KAAK,SAAS,IAAI,CAAC,cAAc,CAAC,cAC5D,IAAI;YACA,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;gBACzB,CAAA,GAAA,cAAM,EAAE,IAAI,CAAC;gBACb,MAAM,IAAI,CAAC,UAAU;gBACrB,IAAI,CAAC,IAAI,CAAC,MAAM;YACpB;QACJ,EAAE,OAAO,OAAO;YACZ,IAAI,UAAU,CAAA,GAAA,iBAAS,GACnB,cAAc,IAAI,CAAC,WAAW,IAAI;iBAElC,MAAM;QAEd;QAGJ,OAAO;YACH,SAAS;gBACL,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,SAAS,CAAC,EAAE,aAAa;YACzE;QACJ;IACJ;IAEQ,eAAe,KAAa,EAAW;QAC3C,MAAM,UAAU,CAAA,GAAA,gBAAQ,EAAE;QAE1B,IAAI,CAAC,QAAQ,GAAG,EACZ,OAAO;QAGX,OAAO,CAAA,GAAA,eAAO,EAAE,CAAA,GAAA,iBAAS,EAAE,QAAQ,GAAG,GAAG,MAAM,IAAI,KAAK,GAAG;IAC/D;IAEA,MAAM,aAAa;QACf,IAAI,CAAC,IAAI,CAAC,kBAAkB,EACxB,MAAM,IAAI,MAAM;QAGpB,MAAM,WAAW,MAAM,IAAI,CAAC,kBAAkB;QAC9C,IAAI,CAAC,WAAW,CAAC;IACrB;AACJ;","sources":["src/index.ts","src/BaseApi.ts","src/BaseClient.ts","src/JwtClient.ts"],"sourcesContent":["export * from './BaseApi';\r\nexport * from './BaseClient';\r\nexport * from './JwtClient';\r\n","import autoBind from 'auto-bind';\r\nimport { BaseClient } from './BaseClient';\r\n\r\nexport class BaseApi<\r\n HandleError extends boolean = boolean,\r\n ApiClient extends BaseClient<HandleError> = BaseClient<HandleError>,\r\n> {\r\n // request: ApiClient['request'];\r\n // get: ApiClient['get'];\r\n // delete: ApiClient['delete'];\r\n // head: ApiClient['head'];\r\n // options: ApiClient['options'];\r\n // post: ApiClient['post'];\r\n // put: ApiClient['put'];\r\n // patch: ApiClient['patch'];\r\n\r\n constructor(protected readonly apiClient: ApiClient) {\r\n autoBind(this);\r\n // this.request = this.client.request;\r\n // this.get = this.client.get;\r\n // this.delete = this.client.delete;\r\n // this.head = this.client.head;\r\n // this.options = this.client.options;\r\n // this.post = this.client.post;\r\n // this.put = this.client.put;\r\n // this.patch = this.client.patch;\r\n // this.get = this.client.get;\r\n }\r\n\r\n getApiClient(): ApiClient {\r\n return this.apiClient;\r\n }\r\n}\r\n","import autoBind from 'auto-bind';\nimport axios, {\n AxiosError,\n AxiosInstance,\n AxiosRequestConfig,\n AxiosResponse,\n HttpStatusCode,\n isAxiosError,\n} from 'axios';\nimport axiosBetterStacktrace from 'axios-better-stacktrace';\nimport { isNil, merge } from 'lodash';\n\nexport interface BaseClientConfig<HandleError extends boolean = boolean> {\n baseUrl: string;\n handleError?: HandleError;\n storage?: Storage;\n defaultHeaders?: Record<string, string>;\n defaultSecure?: boolean;\n authDataStorageKey?: string;\n onAxiosError?: (error: AxiosError) => void;\n onError?: (error: unknown) => void;\n}\n\nexport enum ContentType {\n Json = 'application/json',\n FormData = 'multipart/form-data',\n UrlEncoded = 'application/x-www-form-urlencoded',\n Text = 'text/plain',\n}\n\nexport type RequestConfig<Body = unknown> = AxiosRequestConfig<Body> & {\n secure?: boolean;\n contentType?: ContentType;\n handleError?: boolean;\n};\n\nexport type ResponseStatus = {\n status: HttpStatusCode | -1;\n statusText: string;\n};\n\nexport type SuccessClientResponse<Data = unknown> = ResponseStatus & {\n success: true;\n data: Data;\n};\n\nexport type ErrorClientResponse = ResponseStatus & {\n success: false;\n data?: any;\n error: unknown;\n};\n\nexport type ClientResponse<Data = unknown, HandleError extends boolean = boolean> = HandleError extends true\n ? SuccessClientResponse<Data> | ErrorClientResponse\n : SuccessClientResponse<Data>;\n\nexport abstract class BaseClient<HandleError extends boolean = boolean, AuthData = unknown> {\n protected readonly axiosInstance: AxiosInstance;\n protected readonly storage: Storage;\n\n constructor(protected readonly config: BaseClientConfig<HandleError>) {\n autoBind(this);\n this.storage = config.storage ?? sessionStorage;\n this.axiosInstance = axios.create({\n baseURL: config.baseUrl,\n headers: {\n 'Content-Type': 'application/json',\n ...config.defaultHeaders,\n },\n });\n axiosBetterStacktrace(this.axiosInstance);\n }\n\n protected stringifyFormItem(formItem: unknown) {\n if (typeof formItem === 'object' && formItem !== null) {\n return JSON.stringify(formItem);\n } else {\n return `${formItem}`;\n }\n }\n\n protected createFormData(input: Record<string, unknown>): FormData {\n if (input instanceof FormData) {\n return input;\n }\n\n return Object.keys(input).reduce((formData, key) => {\n const property = input[key];\n const propertyContent: any[] = property instanceof Array ? property : [property];\n\n for (const formItem of propertyContent) {\n const isFileType = formItem instanceof Blob || formItem instanceof File;\n formData.append(key, isFileType ? formItem : this.stringifyFormItem(formItem));\n }\n\n return formData;\n }, new FormData());\n }\n\n async request<Data = unknown, Error = unknown, Body = unknown>(\n requestConfig: RequestConfig<Body>,\n ): Promise<ClientResponse<Data, HandleError>> {\n const { contentType, data } = requestConfig;\n\n if (!isNil(data)) {\n if (contentType === ContentType.FormData && typeof data === 'object') {\n requestConfig.data = this.createFormData(data as Record<string, unknown>) as any;\n }\n\n if (contentType === ContentType.Text && typeof data !== 'string') {\n requestConfig.data = JSON.stringify(data) as any;\n }\n }\n\n const mergedConfig = merge(\n (requestConfig.secure ?? this.config.defaultSecure) ? await this.prepareAuthRequestConfig() : {},\n contentType ? { headers: { 'Content-Type': contentType } } : {},\n requestConfig,\n );\n\n try {\n const { data, status, statusText } = await this.axiosInstance.request<Data, AxiosResponse<Data>, Body>(\n mergedConfig,\n );\n\n return {\n success: true,\n data,\n status,\n statusText,\n };\n } catch (error) {\n if (!this.config.handleError && !requestConfig.handleError) {\n throw error;\n }\n\n const result: ErrorClientResponse = {\n success: false,\n status: -1,\n statusText: String(error),\n error,\n };\n\n if (isAxiosError<Error, Data>(error)) {\n this.config.onAxiosError?.(error);\n result.data = error.response?.data;\n result.status = error.response?.status ?? result.status;\n result.statusText = error.response?.statusText ?? result.statusText;\n }\n\n this.config.onError?.(error);\n\n return result as ClientResponse<Data, HandleError>;\n }\n }\n\n get<Data = unknown, Error = unknown, Body = unknown>(url: string, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'GET',\n url,\n });\n }\n\n delete<Data = unknown, Error = unknown, Body = unknown>(url: string, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'DELETE',\n url,\n });\n }\n\n head<Data = unknown, Error = unknown, Body = unknown>(url: string, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'HEAD',\n url,\n });\n }\n\n options<Data = unknown, Error = unknown, Body = unknown>(url: string, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'OPTIONS',\n url,\n });\n }\n\n post<Data = unknown, Error = unknown, Body = unknown>(url: string, data?: Body, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'POST',\n url,\n data,\n });\n }\n\n put<Data = unknown, Error = unknown, Body = unknown>(url: string, data?: Body, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'PUT',\n url,\n data,\n });\n }\n\n patch<Data = unknown, Error = unknown, Body = unknown>(url: string, data?: Body, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'PATCH',\n url,\n data,\n });\n }\n\n getAxios(): AxiosInstance {\n return this.axiosInstance;\n }\n\n setAuthData(data: AuthData | null) {\n this.storage.setItem(this.config.authDataStorageKey || 'auth', JSON.stringify(data));\n }\n\n getAuthData(): AuthData | null {\n const data = this.storage.getItem(this.config.authDataStorageKey || 'auth');\n return data ? (JSON.parse(data) as AuthData) : null;\n }\n\n getConfig(): BaseClientConfig<HandleError> {\n return this.config;\n }\n\n protected abstract prepareAuthRequestConfig(): Promise<Pick<RequestConfig<any>, 'headers' | 'data' | 'params'>>;\n}\n","import { E_CANCELED, Mutex } from 'async-mutex';\nimport { consola } from 'consola';\nimport { isBefore, subMinutes } from 'date-fns';\nimport { jwtDecode } from 'jwt-decode';\nimport { BaseClient, BaseClientConfig, RequestConfig } from './BaseClient';\n\nexport interface JwtClientConfig<HandleError extends boolean = boolean> extends BaseClientConfig<HandleError> {\n authSchema?: string;\n autoRenewToken?: boolean;\n}\n\nexport interface JwtAuthData {\n accessToken: string;\n refreshToken?: string;\n}\n\nexport class JwtClient<\n HandleError extends boolean = boolean,\n AuthData extends JwtAuthData = JwtAuthData,\n> extends BaseClient<HandleError, AuthData> {\n private readonly lock = new Mutex();\n private renewTokenCallback?: () => Promise<AuthData>;\n\n constructor(protected override readonly config: JwtClientConfig<HandleError>) {\n super(config);\n }\n\n override getConfig(): JwtClientConfig<HandleError> {\n return super.getConfig() as JwtClientConfig<HandleError>;\n }\n\n setRenewTokenCallback(renewTokenCallback: () => Promise<AuthData>) {\n this.renewTokenCallback = renewTokenCallback;\n }\n\n protected override async prepareAuthRequestConfig(): Promise<\n Pick<RequestConfig<any>, 'headers' | 'data' | 'params'>\n > {\n let { accessToken } = this.getAuthData() || {};\n\n if (!accessToken) {\n consola.warn('No access token found. Please set auth data after authorization.');\n return {};\n }\n\n if (this.config.autoRenewToken !== false && this.isTokenExpired(accessToken)) {\n try {\n await this.lock.runExclusive(async () => {\n consola.info('Token expired. Renewing…');\n await this.renewToken();\n this.lock.cancel();\n });\n } catch (error) {\n if (error === E_CANCELED) {\n accessToken = this.getAuthData()?.accessToken;\n } else {\n throw error;\n }\n }\n }\n\n return {\n headers: {\n Authorization: `${this.config.authSchema ?? 'Bearer'} ${accessToken}`,\n },\n };\n }\n\n private isTokenExpired(token: string): boolean {\n const payload = jwtDecode(token);\n\n if (!payload.exp) {\n return true;\n }\n\n return isBefore(subMinutes(payload.exp * 1000, 5), Date.now());\n }\n\n async renewToken() {\n if (!this.renewTokenCallback) {\n throw new Error('No renew token callback provided');\n }\n\n const authData = await this.renewTokenCallback();\n this.setAuthData(authData);\n }\n}\n"],"names":[],"version":3,"file":"index.esm.js.map","sourceRoot":"../"}
1
+ {"mappings":"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","sources":["src/index.ts","src/BaseApi.ts","src/BaseClient.ts","src/JwtClient.ts"],"sourcesContent":["export * from './BaseApi';\r\nexport * from './BaseClient';\r\nexport * from './JwtClient';\r\n","import autoBind from 'auto-bind';\r\nimport { BaseClient } from './BaseClient';\r\n\r\nexport class BaseApi<\r\n HandleError extends boolean = boolean,\r\n ApiClient extends BaseClient<HandleError> = BaseClient<HandleError>,\r\n> {\r\n // request: ApiClient['request'];\r\n // get: ApiClient['get'];\r\n // delete: ApiClient['delete'];\r\n // head: ApiClient['head'];\r\n // options: ApiClient['options'];\r\n // post: ApiClient['post'];\r\n // put: ApiClient['put'];\r\n // patch: ApiClient['patch'];\r\n\r\n constructor(protected readonly apiClient: ApiClient) {\r\n autoBind(this);\r\n // this.request = this.client.request;\r\n // this.get = this.client.get;\r\n // this.delete = this.client.delete;\r\n // this.head = this.client.head;\r\n // this.options = this.client.options;\r\n // this.post = this.client.post;\r\n // this.put = this.client.put;\r\n // this.patch = this.client.patch;\r\n // this.get = this.client.get;\r\n }\r\n\r\n getApiClient(): ApiClient {\r\n return this.apiClient;\r\n }\r\n}\r\n","import autoBind from 'auto-bind';\nimport axios, {\n AxiosError,\n AxiosInstance,\n AxiosRequestConfig,\n AxiosResponse,\n HttpStatusCode,\n isAxiosError,\n} from 'axios';\nimport axiosBetterStacktrace from 'axios-better-stacktrace';\nimport { isNil, merge } from 'lodash';\n\nexport interface BaseClientConfig<HandleError extends boolean = boolean> {\n baseUrl: string;\n handleError?: HandleError;\n storage?: Storage;\n defaultHeaders?: Record<string, string>;\n defaultSecure?: boolean;\n authDataStorageKey?: string;\n onAxiosError?: (error: AxiosError) => void;\n onError?: (error: unknown) => void;\n}\n\nexport enum ContentType {\n Json = 'application/json',\n FormData = 'multipart/form-data',\n UrlEncoded = 'application/x-www-form-urlencoded',\n Text = 'text/plain',\n}\n\nexport type RequestConfig<Body = unknown> = AxiosRequestConfig<Body> & {\n secure?: boolean;\n contentType?: ContentType;\n handleError?: boolean;\n};\n\nexport type ResponseStatus = {\n status: HttpStatusCode | -1;\n statusText: string;\n};\n\nexport type SuccessClientResponse<Data = unknown> = ResponseStatus & {\n success: true;\n data: Data;\n};\n\nexport type ErrorClientResponse = ResponseStatus & {\n success: false;\n data?: any;\n error: unknown;\n};\n\nexport type ClientResponse<Data = unknown, HandleError extends boolean = boolean> = HandleError extends true\n ? SuccessClientResponse<Data> | ErrorClientResponse\n : SuccessClientResponse<Data>;\n\nexport abstract class BaseClient<HandleError extends boolean = boolean, AuthData = unknown> {\n protected readonly axiosInstance: AxiosInstance;\n protected readonly storage: Storage;\n\n constructor(protected readonly config: BaseClientConfig<HandleError>) {\n autoBind(this);\n this.storage = config.storage ?? sessionStorage;\n this.axiosInstance = axios.create({\n baseURL: config.baseUrl,\n headers: {\n 'Content-Type': 'application/json',\n ...config.defaultHeaders,\n },\n });\n axiosBetterStacktrace(this.axiosInstance);\n }\n\n protected stringifyFormItem(formItem: unknown) {\n if (typeof formItem === 'object' && formItem !== null) {\n return JSON.stringify(formItem);\n } else {\n return `${formItem}`;\n }\n }\n\n protected createFormData(input: Record<string, unknown>): FormData {\n if (input instanceof FormData) {\n return input;\n }\n\n return Object.keys(input).reduce((formData, key) => {\n const property = input[key];\n const propertyContent: any[] = property instanceof Array ? property : [property];\n\n for (const formItem of propertyContent) {\n const isFileType = formItem instanceof Blob || formItem instanceof File;\n formData.append(key, isFileType ? formItem : this.stringifyFormItem(formItem));\n }\n\n return formData;\n }, new FormData());\n }\n\n async request<Data = unknown, Error = unknown, Body = unknown>(\n requestConfig: RequestConfig<Body>,\n ): Promise<ClientResponse<Data, HandleError>> {\n const { contentType, data } = requestConfig;\n\n if (!isNil(data)) {\n if (contentType === ContentType.FormData && typeof data === 'object') {\n requestConfig.data = this.createFormData(data as Record<string, unknown>) as any;\n }\n\n if (contentType === ContentType.Text && typeof data !== 'string') {\n requestConfig.data = JSON.stringify(data) as any;\n }\n }\n\n const mergedConfig = merge(\n (requestConfig.secure ?? this.config.defaultSecure ?? true) ? await this.prepareAuthRequestConfig() : {},\n contentType ? { headers: { 'Content-Type': contentType } } : {},\n requestConfig,\n );\n\n try {\n const { data, status, statusText } = await this.axiosInstance.request<Data, AxiosResponse<Data>, Body>(\n mergedConfig,\n );\n\n return {\n success: true,\n data,\n status,\n statusText,\n };\n } catch (error) {\n if (!this.config.handleError && !requestConfig.handleError) {\n throw error;\n }\n\n const result: ErrorClientResponse = {\n success: false,\n status: -1,\n statusText: String(error),\n error,\n };\n\n if (isAxiosError<Error, Data>(error)) {\n this.config.onAxiosError?.(error);\n result.data = error.response?.data;\n result.status = error.response?.status ?? result.status;\n result.statusText = error.response?.statusText ?? result.statusText;\n }\n\n this.config.onError?.(error);\n\n return result as ClientResponse<Data, HandleError>;\n }\n }\n\n get<Data = unknown, Error = unknown, Body = unknown>(url: string, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'GET',\n url,\n });\n }\n\n delete<Data = unknown, Error = unknown, Body = unknown>(url: string, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'DELETE',\n url,\n });\n }\n\n head<Data = unknown, Error = unknown, Body = unknown>(url: string, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'HEAD',\n url,\n });\n }\n\n options<Data = unknown, Error = unknown, Body = unknown>(url: string, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'OPTIONS',\n url,\n });\n }\n\n post<Data = unknown, Error = unknown, Body = unknown>(url: string, data?: Body, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'POST',\n url,\n data,\n });\n }\n\n put<Data = unknown, Error = unknown, Body = unknown>(url: string, data?: Body, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'PUT',\n url,\n data,\n });\n }\n\n patch<Data = unknown, Error = unknown, Body = unknown>(url: string, data?: Body, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'PATCH',\n url,\n data,\n });\n }\n\n getAxios(): AxiosInstance {\n return this.axiosInstance;\n }\n\n setAuthData(data: AuthData | null) {\n this.storage.setItem(this.config.authDataStorageKey || 'auth', JSON.stringify(data));\n }\n\n getAuthData(): AuthData | null {\n const data = this.storage.getItem(this.config.authDataStorageKey || 'auth');\n return data ? (JSON.parse(data) as AuthData) : null;\n }\n\n getConfig(): BaseClientConfig<HandleError> {\n return this.config;\n }\n\n protected abstract prepareAuthRequestConfig(): Promise<Pick<RequestConfig<any>, 'headers' | 'data' | 'params'>>;\n}\n","import { E_CANCELED, Mutex } from 'async-mutex';\nimport { consola } from 'consola';\nimport { isBefore, subMinutes } from 'date-fns';\nimport { jwtDecode } from 'jwt-decode';\nimport { BaseClient, BaseClientConfig, RequestConfig } from './BaseClient';\n\nexport interface JwtClientConfig<HandleError extends boolean = boolean> extends BaseClientConfig<HandleError> {\n authSchema?: string;\n autoRenewToken?: boolean;\n}\n\nexport interface JwtAuthData {\n accessToken: string;\n refreshToken?: string;\n}\n\nexport class JwtClient<\n HandleError extends boolean = boolean,\n AuthData extends JwtAuthData = JwtAuthData,\n> extends BaseClient<HandleError, AuthData> {\n private readonly lock = new Mutex();\n private renewTokenCallback?: () => Promise<AuthData>;\n\n constructor(protected override readonly config: JwtClientConfig<HandleError>) {\n super(config);\n }\n\n override getConfig(): JwtClientConfig<HandleError> {\n return super.getConfig() as JwtClientConfig<HandleError>;\n }\n\n setRenewTokenCallback(renewTokenCallback: () => Promise<AuthData>) {\n this.renewTokenCallback = renewTokenCallback;\n }\n\n protected override async prepareAuthRequestConfig(): Promise<\n Pick<RequestConfig<any>, 'headers' | 'data' | 'params'>\n > {\n let { accessToken } = this.getAuthData() || {};\n\n if (!accessToken) {\n consola.warn('No access token found. Please set auth data after authorization.');\n return {};\n }\n\n if (this.config.autoRenewToken !== false && this.isTokenExpired(accessToken)) {\n try {\n await this.lock.runExclusive(async () => {\n consola.info('Token expired. Renewing…');\n await this.renewToken();\n this.lock.cancel();\n });\n } catch (error) {\n if (error === E_CANCELED) {\n accessToken = this.getAuthData()?.accessToken;\n } else {\n throw error;\n }\n }\n }\n\n return {\n headers: {\n Authorization: `${this.config.authSchema ?? 'Bearer'} ${accessToken}`,\n },\n };\n }\n\n private isTokenExpired(token: string): boolean {\n const payload = jwtDecode(token);\n\n if (!payload.exp) {\n return true;\n }\n\n return isBefore(subMinutes(payload.exp * 1000, 5), Date.now());\n }\n\n async renewToken() {\n if (!this.renewTokenCallback) {\n throw new Error('No renew token callback provided');\n }\n\n const authData = await this.renewTokenCallback();\n this.setAuthData(authData);\n }\n}\n"],"names":[],"version":3,"file":"index.esm.js.map","sourceRoot":"../"}
package/dist/index.js CHANGED
@@ -117,7 +117,7 @@ class $3621850f1f570615$export$4f22f74eddb7716a {
117
117
  if (contentType === "multipart/form-data" && typeof data === 'object') requestConfig.data = this.createFormData(data);
118
118
  if (contentType === "text/plain" && typeof data !== 'string') requestConfig.data = JSON.stringify(data);
119
119
  }
120
- const mergedConfig = (0, $7TMtJ$lodash.merge)(requestConfig.secure ?? this.config.defaultSecure ? await this.prepareAuthRequestConfig() : {}, contentType ? {
120
+ const mergedConfig = (0, $7TMtJ$lodash.merge)(requestConfig.secure ?? this.config.defaultSecure ?? true ? await this.prepareAuthRequestConfig() : {}, contentType ? {
121
121
  headers: {
122
122
  'Content-Type': contentType
123
123
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"mappings":"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","sources":["src/index.ts","src/BaseApi.ts","src/BaseClient.ts","src/JwtClient.ts"],"sourcesContent":["export * from './BaseApi';\r\nexport * from './BaseClient';\r\nexport * from './JwtClient';\r\n","import autoBind from 'auto-bind';\r\nimport { BaseClient } from './BaseClient';\r\n\r\nexport class BaseApi<\r\n HandleError extends boolean = boolean,\r\n ApiClient extends BaseClient<HandleError> = BaseClient<HandleError>,\r\n> {\r\n // request: ApiClient['request'];\r\n // get: ApiClient['get'];\r\n // delete: ApiClient['delete'];\r\n // head: ApiClient['head'];\r\n // options: ApiClient['options'];\r\n // post: ApiClient['post'];\r\n // put: ApiClient['put'];\r\n // patch: ApiClient['patch'];\r\n\r\n constructor(protected readonly apiClient: ApiClient) {\r\n autoBind(this);\r\n // this.request = this.client.request;\r\n // this.get = this.client.get;\r\n // this.delete = this.client.delete;\r\n // this.head = this.client.head;\r\n // this.options = this.client.options;\r\n // this.post = this.client.post;\r\n // this.put = this.client.put;\r\n // this.patch = this.client.patch;\r\n // this.get = this.client.get;\r\n }\r\n\r\n getApiClient(): ApiClient {\r\n return this.apiClient;\r\n }\r\n}\r\n","import autoBind from 'auto-bind';\nimport axios, {\n AxiosError,\n AxiosInstance,\n AxiosRequestConfig,\n AxiosResponse,\n HttpStatusCode,\n isAxiosError,\n} from 'axios';\nimport axiosBetterStacktrace from 'axios-better-stacktrace';\nimport { isNil, merge } from 'lodash';\n\nexport interface BaseClientConfig<HandleError extends boolean = boolean> {\n baseUrl: string;\n handleError?: HandleError;\n storage?: Storage;\n defaultHeaders?: Record<string, string>;\n defaultSecure?: boolean;\n authDataStorageKey?: string;\n onAxiosError?: (error: AxiosError) => void;\n onError?: (error: unknown) => void;\n}\n\nexport enum ContentType {\n Json = 'application/json',\n FormData = 'multipart/form-data',\n UrlEncoded = 'application/x-www-form-urlencoded',\n Text = 'text/plain',\n}\n\nexport type RequestConfig<Body = unknown> = AxiosRequestConfig<Body> & {\n secure?: boolean;\n contentType?: ContentType;\n handleError?: boolean;\n};\n\nexport type ResponseStatus = {\n status: HttpStatusCode | -1;\n statusText: string;\n};\n\nexport type SuccessClientResponse<Data = unknown> = ResponseStatus & {\n success: true;\n data: Data;\n};\n\nexport type ErrorClientResponse = ResponseStatus & {\n success: false;\n data?: any;\n error: unknown;\n};\n\nexport type ClientResponse<Data = unknown, HandleError extends boolean = boolean> = HandleError extends true\n ? SuccessClientResponse<Data> | ErrorClientResponse\n : SuccessClientResponse<Data>;\n\nexport abstract class BaseClient<HandleError extends boolean = boolean, AuthData = unknown> {\n protected readonly axiosInstance: AxiosInstance;\n protected readonly storage: Storage;\n\n constructor(protected readonly config: BaseClientConfig<HandleError>) {\n autoBind(this);\n this.storage = config.storage ?? sessionStorage;\n this.axiosInstance = axios.create({\n baseURL: config.baseUrl,\n headers: {\n 'Content-Type': 'application/json',\n ...config.defaultHeaders,\n },\n });\n axiosBetterStacktrace(this.axiosInstance);\n }\n\n protected stringifyFormItem(formItem: unknown) {\n if (typeof formItem === 'object' && formItem !== null) {\n return JSON.stringify(formItem);\n } else {\n return `${formItem}`;\n }\n }\n\n protected createFormData(input: Record<string, unknown>): FormData {\n if (input instanceof FormData) {\n return input;\n }\n\n return Object.keys(input).reduce((formData, key) => {\n const property = input[key];\n const propertyContent: any[] = property instanceof Array ? property : [property];\n\n for (const formItem of propertyContent) {\n const isFileType = formItem instanceof Blob || formItem instanceof File;\n formData.append(key, isFileType ? formItem : this.stringifyFormItem(formItem));\n }\n\n return formData;\n }, new FormData());\n }\n\n async request<Data = unknown, Error = unknown, Body = unknown>(\n requestConfig: RequestConfig<Body>,\n ): Promise<ClientResponse<Data, HandleError>> {\n const { contentType, data } = requestConfig;\n\n if (!isNil(data)) {\n if (contentType === ContentType.FormData && typeof data === 'object') {\n requestConfig.data = this.createFormData(data as Record<string, unknown>) as any;\n }\n\n if (contentType === ContentType.Text && typeof data !== 'string') {\n requestConfig.data = JSON.stringify(data) as any;\n }\n }\n\n const mergedConfig = merge(\n (requestConfig.secure ?? this.config.defaultSecure) ? await this.prepareAuthRequestConfig() : {},\n contentType ? { headers: { 'Content-Type': contentType } } : {},\n requestConfig,\n );\n\n try {\n const { data, status, statusText } = await this.axiosInstance.request<Data, AxiosResponse<Data>, Body>(\n mergedConfig,\n );\n\n return {\n success: true,\n data,\n status,\n statusText,\n };\n } catch (error) {\n if (!this.config.handleError && !requestConfig.handleError) {\n throw error;\n }\n\n const result: ErrorClientResponse = {\n success: false,\n status: -1,\n statusText: String(error),\n error,\n };\n\n if (isAxiosError<Error, Data>(error)) {\n this.config.onAxiosError?.(error);\n result.data = error.response?.data;\n result.status = error.response?.status ?? result.status;\n result.statusText = error.response?.statusText ?? result.statusText;\n }\n\n this.config.onError?.(error);\n\n return result as ClientResponse<Data, HandleError>;\n }\n }\n\n get<Data = unknown, Error = unknown, Body = unknown>(url: string, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'GET',\n url,\n });\n }\n\n delete<Data = unknown, Error = unknown, Body = unknown>(url: string, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'DELETE',\n url,\n });\n }\n\n head<Data = unknown, Error = unknown, Body = unknown>(url: string, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'HEAD',\n url,\n });\n }\n\n options<Data = unknown, Error = unknown, Body = unknown>(url: string, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'OPTIONS',\n url,\n });\n }\n\n post<Data = unknown, Error = unknown, Body = unknown>(url: string, data?: Body, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'POST',\n url,\n data,\n });\n }\n\n put<Data = unknown, Error = unknown, Body = unknown>(url: string, data?: Body, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'PUT',\n url,\n data,\n });\n }\n\n patch<Data = unknown, Error = unknown, Body = unknown>(url: string, data?: Body, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'PATCH',\n url,\n data,\n });\n }\n\n getAxios(): AxiosInstance {\n return this.axiosInstance;\n }\n\n setAuthData(data: AuthData | null) {\n this.storage.setItem(this.config.authDataStorageKey || 'auth', JSON.stringify(data));\n }\n\n getAuthData(): AuthData | null {\n const data = this.storage.getItem(this.config.authDataStorageKey || 'auth');\n return data ? (JSON.parse(data) as AuthData) : null;\n }\n\n getConfig(): BaseClientConfig<HandleError> {\n return this.config;\n }\n\n protected abstract prepareAuthRequestConfig(): Promise<Pick<RequestConfig<any>, 'headers' | 'data' | 'params'>>;\n}\n","import { E_CANCELED, Mutex } from 'async-mutex';\nimport { consola } from 'consola';\nimport { isBefore, subMinutes } from 'date-fns';\nimport { jwtDecode } from 'jwt-decode';\nimport { BaseClient, BaseClientConfig, RequestConfig } from './BaseClient';\n\nexport interface JwtClientConfig<HandleError extends boolean = boolean> extends BaseClientConfig<HandleError> {\n authSchema?: string;\n autoRenewToken?: boolean;\n}\n\nexport interface JwtAuthData {\n accessToken: string;\n refreshToken?: string;\n}\n\nexport class JwtClient<\n HandleError extends boolean = boolean,\n AuthData extends JwtAuthData = JwtAuthData,\n> extends BaseClient<HandleError, AuthData> {\n private readonly lock = new Mutex();\n private renewTokenCallback?: () => Promise<AuthData>;\n\n constructor(protected override readonly config: JwtClientConfig<HandleError>) {\n super(config);\n }\n\n override getConfig(): JwtClientConfig<HandleError> {\n return super.getConfig() as JwtClientConfig<HandleError>;\n }\n\n setRenewTokenCallback(renewTokenCallback: () => Promise<AuthData>) {\n this.renewTokenCallback = renewTokenCallback;\n }\n\n protected override async prepareAuthRequestConfig(): Promise<\n Pick<RequestConfig<any>, 'headers' | 'data' | 'params'>\n > {\n let { accessToken } = this.getAuthData() || {};\n\n if (!accessToken) {\n consola.warn('No access token found. Please set auth data after authorization.');\n return {};\n }\n\n if (this.config.autoRenewToken !== false && this.isTokenExpired(accessToken)) {\n try {\n await this.lock.runExclusive(async () => {\n consola.info('Token expired. Renewing…');\n await this.renewToken();\n this.lock.cancel();\n });\n } catch (error) {\n if (error === E_CANCELED) {\n accessToken = this.getAuthData()?.accessToken;\n } else {\n throw error;\n }\n }\n }\n\n return {\n headers: {\n Authorization: `${this.config.authSchema ?? 'Bearer'} ${accessToken}`,\n },\n };\n }\n\n private isTokenExpired(token: string): boolean {\n const payload = jwtDecode(token);\n\n if (!payload.exp) {\n return true;\n }\n\n return isBefore(subMinutes(payload.exp * 1000, 5), Date.now());\n }\n\n async renewToken() {\n if (!this.renewTokenCallback) {\n throw new Error('No renew token callback provided');\n }\n\n const authData = await this.renewTokenCallback();\n this.setAuthData(authData);\n }\n}\n"],"names":[],"version":3,"file":"index.js.map","sourceRoot":"../"}
1
+ {"mappings":"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","sources":["src/index.ts","src/BaseApi.ts","src/BaseClient.ts","src/JwtClient.ts"],"sourcesContent":["export * from './BaseApi';\r\nexport * from './BaseClient';\r\nexport * from './JwtClient';\r\n","import autoBind from 'auto-bind';\r\nimport { BaseClient } from './BaseClient';\r\n\r\nexport class BaseApi<\r\n HandleError extends boolean = boolean,\r\n ApiClient extends BaseClient<HandleError> = BaseClient<HandleError>,\r\n> {\r\n // request: ApiClient['request'];\r\n // get: ApiClient['get'];\r\n // delete: ApiClient['delete'];\r\n // head: ApiClient['head'];\r\n // options: ApiClient['options'];\r\n // post: ApiClient['post'];\r\n // put: ApiClient['put'];\r\n // patch: ApiClient['patch'];\r\n\r\n constructor(protected readonly apiClient: ApiClient) {\r\n autoBind(this);\r\n // this.request = this.client.request;\r\n // this.get = this.client.get;\r\n // this.delete = this.client.delete;\r\n // this.head = this.client.head;\r\n // this.options = this.client.options;\r\n // this.post = this.client.post;\r\n // this.put = this.client.put;\r\n // this.patch = this.client.patch;\r\n // this.get = this.client.get;\r\n }\r\n\r\n getApiClient(): ApiClient {\r\n return this.apiClient;\r\n }\r\n}\r\n","import autoBind from 'auto-bind';\nimport axios, {\n AxiosError,\n AxiosInstance,\n AxiosRequestConfig,\n AxiosResponse,\n HttpStatusCode,\n isAxiosError,\n} from 'axios';\nimport axiosBetterStacktrace from 'axios-better-stacktrace';\nimport { isNil, merge } from 'lodash';\n\nexport interface BaseClientConfig<HandleError extends boolean = boolean> {\n baseUrl: string;\n handleError?: HandleError;\n storage?: Storage;\n defaultHeaders?: Record<string, string>;\n defaultSecure?: boolean;\n authDataStorageKey?: string;\n onAxiosError?: (error: AxiosError) => void;\n onError?: (error: unknown) => void;\n}\n\nexport enum ContentType {\n Json = 'application/json',\n FormData = 'multipart/form-data',\n UrlEncoded = 'application/x-www-form-urlencoded',\n Text = 'text/plain',\n}\n\nexport type RequestConfig<Body = unknown> = AxiosRequestConfig<Body> & {\n secure?: boolean;\n contentType?: ContentType;\n handleError?: boolean;\n};\n\nexport type ResponseStatus = {\n status: HttpStatusCode | -1;\n statusText: string;\n};\n\nexport type SuccessClientResponse<Data = unknown> = ResponseStatus & {\n success: true;\n data: Data;\n};\n\nexport type ErrorClientResponse = ResponseStatus & {\n success: false;\n data?: any;\n error: unknown;\n};\n\nexport type ClientResponse<Data = unknown, HandleError extends boolean = boolean> = HandleError extends true\n ? SuccessClientResponse<Data> | ErrorClientResponse\n : SuccessClientResponse<Data>;\n\nexport abstract class BaseClient<HandleError extends boolean = boolean, AuthData = unknown> {\n protected readonly axiosInstance: AxiosInstance;\n protected readonly storage: Storage;\n\n constructor(protected readonly config: BaseClientConfig<HandleError>) {\n autoBind(this);\n this.storage = config.storage ?? sessionStorage;\n this.axiosInstance = axios.create({\n baseURL: config.baseUrl,\n headers: {\n 'Content-Type': 'application/json',\n ...config.defaultHeaders,\n },\n });\n axiosBetterStacktrace(this.axiosInstance);\n }\n\n protected stringifyFormItem(formItem: unknown) {\n if (typeof formItem === 'object' && formItem !== null) {\n return JSON.stringify(formItem);\n } else {\n return `${formItem}`;\n }\n }\n\n protected createFormData(input: Record<string, unknown>): FormData {\n if (input instanceof FormData) {\n return input;\n }\n\n return Object.keys(input).reduce((formData, key) => {\n const property = input[key];\n const propertyContent: any[] = property instanceof Array ? property : [property];\n\n for (const formItem of propertyContent) {\n const isFileType = formItem instanceof Blob || formItem instanceof File;\n formData.append(key, isFileType ? formItem : this.stringifyFormItem(formItem));\n }\n\n return formData;\n }, new FormData());\n }\n\n async request<Data = unknown, Error = unknown, Body = unknown>(\n requestConfig: RequestConfig<Body>,\n ): Promise<ClientResponse<Data, HandleError>> {\n const { contentType, data } = requestConfig;\n\n if (!isNil(data)) {\n if (contentType === ContentType.FormData && typeof data === 'object') {\n requestConfig.data = this.createFormData(data as Record<string, unknown>) as any;\n }\n\n if (contentType === ContentType.Text && typeof data !== 'string') {\n requestConfig.data = JSON.stringify(data) as any;\n }\n }\n\n const mergedConfig = merge(\n (requestConfig.secure ?? this.config.defaultSecure ?? true) ? await this.prepareAuthRequestConfig() : {},\n contentType ? { headers: { 'Content-Type': contentType } } : {},\n requestConfig,\n );\n\n try {\n const { data, status, statusText } = await this.axiosInstance.request<Data, AxiosResponse<Data>, Body>(\n mergedConfig,\n );\n\n return {\n success: true,\n data,\n status,\n statusText,\n };\n } catch (error) {\n if (!this.config.handleError && !requestConfig.handleError) {\n throw error;\n }\n\n const result: ErrorClientResponse = {\n success: false,\n status: -1,\n statusText: String(error),\n error,\n };\n\n if (isAxiosError<Error, Data>(error)) {\n this.config.onAxiosError?.(error);\n result.data = error.response?.data;\n result.status = error.response?.status ?? result.status;\n result.statusText = error.response?.statusText ?? result.statusText;\n }\n\n this.config.onError?.(error);\n\n return result as ClientResponse<Data, HandleError>;\n }\n }\n\n get<Data = unknown, Error = unknown, Body = unknown>(url: string, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'GET',\n url,\n });\n }\n\n delete<Data = unknown, Error = unknown, Body = unknown>(url: string, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'DELETE',\n url,\n });\n }\n\n head<Data = unknown, Error = unknown, Body = unknown>(url: string, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'HEAD',\n url,\n });\n }\n\n options<Data = unknown, Error = unknown, Body = unknown>(url: string, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'OPTIONS',\n url,\n });\n }\n\n post<Data = unknown, Error = unknown, Body = unknown>(url: string, data?: Body, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'POST',\n url,\n data,\n });\n }\n\n put<Data = unknown, Error = unknown, Body = unknown>(url: string, data?: Body, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'PUT',\n url,\n data,\n });\n }\n\n patch<Data = unknown, Error = unknown, Body = unknown>(url: string, data?: Body, config?: RequestConfig<Body>) {\n return this.request<Data, Error, Body>({\n ...config,\n method: 'PATCH',\n url,\n data,\n });\n }\n\n getAxios(): AxiosInstance {\n return this.axiosInstance;\n }\n\n setAuthData(data: AuthData | null) {\n this.storage.setItem(this.config.authDataStorageKey || 'auth', JSON.stringify(data));\n }\n\n getAuthData(): AuthData | null {\n const data = this.storage.getItem(this.config.authDataStorageKey || 'auth');\n return data ? (JSON.parse(data) as AuthData) : null;\n }\n\n getConfig(): BaseClientConfig<HandleError> {\n return this.config;\n }\n\n protected abstract prepareAuthRequestConfig(): Promise<Pick<RequestConfig<any>, 'headers' | 'data' | 'params'>>;\n}\n","import { E_CANCELED, Mutex } from 'async-mutex';\nimport { consola } from 'consola';\nimport { isBefore, subMinutes } from 'date-fns';\nimport { jwtDecode } from 'jwt-decode';\nimport { BaseClient, BaseClientConfig, RequestConfig } from './BaseClient';\n\nexport interface JwtClientConfig<HandleError extends boolean = boolean> extends BaseClientConfig<HandleError> {\n authSchema?: string;\n autoRenewToken?: boolean;\n}\n\nexport interface JwtAuthData {\n accessToken: string;\n refreshToken?: string;\n}\n\nexport class JwtClient<\n HandleError extends boolean = boolean,\n AuthData extends JwtAuthData = JwtAuthData,\n> extends BaseClient<HandleError, AuthData> {\n private readonly lock = new Mutex();\n private renewTokenCallback?: () => Promise<AuthData>;\n\n constructor(protected override readonly config: JwtClientConfig<HandleError>) {\n super(config);\n }\n\n override getConfig(): JwtClientConfig<HandleError> {\n return super.getConfig() as JwtClientConfig<HandleError>;\n }\n\n setRenewTokenCallback(renewTokenCallback: () => Promise<AuthData>) {\n this.renewTokenCallback = renewTokenCallback;\n }\n\n protected override async prepareAuthRequestConfig(): Promise<\n Pick<RequestConfig<any>, 'headers' | 'data' | 'params'>\n > {\n let { accessToken } = this.getAuthData() || {};\n\n if (!accessToken) {\n consola.warn('No access token found. Please set auth data after authorization.');\n return {};\n }\n\n if (this.config.autoRenewToken !== false && this.isTokenExpired(accessToken)) {\n try {\n await this.lock.runExclusive(async () => {\n consola.info('Token expired. Renewing…');\n await this.renewToken();\n this.lock.cancel();\n });\n } catch (error) {\n if (error === E_CANCELED) {\n accessToken = this.getAuthData()?.accessToken;\n } else {\n throw error;\n }\n }\n }\n\n return {\n headers: {\n Authorization: `${this.config.authSchema ?? 'Bearer'} ${accessToken}`,\n },\n };\n }\n\n private isTokenExpired(token: string): boolean {\n const payload = jwtDecode(token);\n\n if (!payload.exp) {\n return true;\n }\n\n return isBefore(subMinutes(payload.exp * 1000, 5), Date.now());\n }\n\n async renewToken() {\n if (!this.renewTokenCallback) {\n throw new Error('No renew token callback provided');\n }\n\n const authData = await this.renewTokenCallback();\n this.setAuthData(authData);\n }\n}\n"],"names":[],"version":3,"file":"index.js.map","sourceRoot":"../"}
@@ -1005,6 +1005,10 @@ export interface InsightGetScreenerPresetsResponse {
1005
1005
  default_presets: InsightScreenerPreset[];
1006
1006
  details: InsightScreenerPreset[];
1007
1007
  }
1008
+ export interface InsightGetSliderArticlesResponse {
1009
+ slider_articles: number[];
1010
+ updated_at: string;
1011
+ }
1008
1012
  export interface InsightGetSymbolFundamentalsRequest {
1009
1013
  mode?: string;
1010
1014
  symbol?: string;
@@ -2277,6 +2281,9 @@ export interface InsightUpdateCustomIndexRequest {
2277
2281
  name?: string;
2278
2282
  private_name?: string;
2279
2283
  }
2284
+ export interface InsightUpsertSliderArticlesRequest {
2285
+ slider_articles?: number[];
2286
+ }
2280
2287
  export interface InsightUsageDataEntry {
2281
2288
  branch_code: string;
2282
2289
  details: Record<string, number>;
@@ -3369,6 +3376,22 @@ export class Passport<HandleError extends boolean = boolean> {
3369
3376
  * @secure
3370
3377
  */
3371
3378
  passportSearchArticle(filter: InsightSearchArticleRequest, config?: RequestConfig<HandleError>): Promise<ClientResponse<InsightArticle[], HandleError>>;
3379
+ /**
3380
+ * @description Retrieve slider articles
3381
+ * @tags Passport
3382
+ * @name GetPassportSliderArticles
3383
+ * @summary Get Slider Articles
3384
+ * @request GET:/passport/slider-articles
3385
+ */
3386
+ getPassportSliderArticles(config?: RequestConfig<HandleError>): Promise<ClientResponse<InsightGetSliderArticlesResponse, HandleError>>;
3387
+ /**
3388
+ * @description Upsert slider articles
3389
+ * @tags Passport
3390
+ * @name UpsertPassportSliderArticles
3391
+ * @summary Upsert slider articles
3392
+ * @request POST:/passport/slider-articles
3393
+ */
3394
+ upsertPassportSliderArticles(request: InsightUpsertSliderArticlesRequest, config?: RequestConfig<HandleError>): Promise<ClientResponse<InsightGetSliderArticlesResponse, HandleError>>;
3372
3395
  }
3373
3396
  export class Public<HandleError extends boolean = boolean> {
3374
3397
  protected readonly apiClient: JwtClient<HandleError>;