axios-stream-auth-refresh 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("rxjs");function i(e,u){var t,s;if(!e||!(e!=null&&e.config)||!(e!=null&&e.response))return!1;const{config:n}=e;return!u.statusCodes||!u.statusCodes.length||n!=null&&n.retry||(n.retry=!0,(t=e.config)!=null&&t.skipAuthRefresh)||e.response&&e.request.status===0||!e.response||!((s=u.statusCodes)!=null&&s.includes(e.response.status))?!1:(e.response||(e.response={config:e.config,data:void 0,status:0,statusText:"",headers:{}}),!0)}function a(e,u,n,t){return t.isRefreshing||(t.isRefreshing=!0,t.refreshTokenSubject.next(null),f.from(u(n)).subscribe({next:s=>{t.isRefreshing=!1,t.refreshTokenSubject.next(s)},error:s=>{t.isRefreshing=!1,t.refreshTokenSubject.error(s)}})),t.refreshTokenSubject.pipe(f.filter(s=>s!=null),f.take(1),f.switchMap(()=>f.from(e.request(n).then(s=>s.data))))}function o(e,u,n={statusCodes:[401]}){if(typeof u!="function")throw new Error("axios-stream-refresh requires `refreshAuthCall` to be a function that returns a promise.");const t={isRefreshing:!1,refreshTokenSubject:new f.BehaviorSubject(null)};e.interceptors.response.use(s=>s,async s=>{if(!i(s,n))return Promise.reject(s);const r=a(e,u,s.config,t);return f.firstValueFrom(r)})}exports.createStreamRefreshInterceptor=o;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const f=require("rxjs");function i(e,u){var t,s;if(!e||!(e!=null&&e.config)||!(e!=null&&e.response))return!1;const{config:n}=e;return!u.statusCodes||!u.statusCodes.length||n!=null&&n.retry||(n.retry=!0,(t=e.config)!=null&&t.skipAuthRefresh)||e.response&&e.request.status===0||!e.response||!((s=u.statusCodes)!=null&&s.includes(e.response.status))?!1:(e.response||(e.response={config:e.config,data:void 0,status:0,statusText:"",headers:{}}),!0)}function a(e,u,n,t){return t.isRefreshing||(t.isRefreshing=!0,t.refreshTokenSubject.next(null),f.from(u(n)).subscribe({next:s=>{t.isRefreshing=!1,t.refreshTokenSubject.next(s)},error:s=>{t.isRefreshing=!1,t.refreshTokenSubject.error(s)}})),t.refreshTokenSubject.pipe(f.filter(s=>s!=null),f.take(1),f.switchMap(()=>f.from(e.request(n))))}function o(e,u,n={statusCodes:[401]}){if(typeof u!="function")throw new Error("axios-stream-refresh requires `refreshAuthCall` to be a function that returns a promise.");const t={isRefreshing:!1,refreshTokenSubject:new f.BehaviorSubject(null)};e.interceptors.response.use(s=>s,async s=>{if(!i(s,n))return Promise.reject(s);const r=a(e,u,s.config,t);return f.firstValueFrom(r)})}exports.createStreamRefreshInterceptor=o;
2
2
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":["../src/utils.ts","../src/index.ts"],"sourcesContent":["import { filter, from, switchMap, take } from 'rxjs'\r\nimport type { Observable } from 'rxjs'\r\nimport type {\r\n AxiosError,\r\n AxiosInstance,\r\n AxiosRequestConfig,\r\n InternalAxiosRequestConfig,\r\n} from 'axios'\r\nimport type {\r\n AxiosStreamRefreshCache,\r\n AxiosStreamRefreshOptions,\r\n} from './model'\r\n\r\n/**\r\n * Returns TRUE: when error.response.status is contained in options.statusCodes\r\n * Returns FALSE: when error or error.response doesn't exist or options.statusCodes doesn't include response status\r\n *\r\n * @return {boolean}\r\n */\r\nexport function shouldInterceptError(\r\n error: AxiosError,\r\n options: AxiosStreamRefreshOptions\r\n): boolean {\r\n if (!error || !error?.config || !error?.response) {\r\n return false\r\n }\r\n const { config } = error\r\n\r\n if (!options.statusCodes || !options.statusCodes.length) {\r\n return false\r\n }\r\n\r\n // avoid infinite loop\r\n if (config?.retry) {\r\n return false\r\n }\r\n config.retry = true\r\n\r\n if (error.config?.skipAuthRefresh) {\r\n return false\r\n }\r\n\r\n if (\r\n (error.response && error.request.status === 0) ||\r\n !error.response ||\r\n !options.statusCodes?.includes(error.response.status)\r\n ) {\r\n return false\r\n }\r\n\r\n // Copy config to response if there's a network error, so config can be modified and used in the retry\r\n if (!error.response) {\r\n error.response = {\r\n config: error.config as InternalAxiosRequestConfig,\r\n data: undefined,\r\n status: 0,\r\n statusText: '',\r\n headers: {},\r\n }\r\n }\r\n\r\n return true\r\n}\r\n\r\nexport function enqueueRequestAfterRefresh<T = unknown>(\r\n instance: AxiosInstance,\r\n refreshAuthCall: (originalConfig: AxiosRequestConfig) => Promise<boolean>,\r\n originalConfig: AxiosRequestConfig,\r\n cache: AxiosStreamRefreshCache\r\n): Observable<T> {\r\n if (!cache.isRefreshing) {\r\n cache.isRefreshing = true\r\n cache.refreshTokenSubject.next(null)\r\n\r\n from(refreshAuthCall(originalConfig)).subscribe({\r\n next: (newToken) => {\r\n cache.isRefreshing = false\r\n cache.refreshTokenSubject.next(newToken)\r\n },\r\n error: (err) => {\r\n cache.isRefreshing = false\r\n cache.refreshTokenSubject.error(err)\r\n },\r\n })\r\n }\r\n\r\n return cache.refreshTokenSubject.pipe(\r\n filter((token): token is boolean => token != null),\r\n take(1),\r\n switchMap(() => {\r\n return from(\r\n instance.request<T>(originalConfig).then((response) => response.data)\r\n )\r\n })\r\n )\r\n}\r\n","import { BehaviorSubject, firstValueFrom } from 'rxjs'\r\nimport { enqueueRequestAfterRefresh, shouldInterceptError } from './utils'\r\nimport type { AxiosError, AxiosInstance, AxiosRequestConfig } from 'axios'\r\nimport type {\r\n AxiosStreamRefreshCache,\r\n AxiosStreamRefreshOptions,\r\n} from './model'\r\n\r\nexport function createStreamRefreshInterceptor(\r\n instance: AxiosInstance,\r\n refreshAuthCall: (originalConfig: AxiosRequestConfig) => Promise<boolean>,\r\n options: AxiosStreamRefreshOptions = {\r\n statusCodes: [401],\r\n }\r\n) {\r\n if (typeof refreshAuthCall !== 'function') {\r\n throw new Error(\r\n 'axios-stream-refresh requires `refreshAuthCall` to be a function that returns a promise.'\r\n )\r\n }\r\n\r\n const cache: AxiosStreamRefreshCache = {\r\n isRefreshing: false,\r\n refreshTokenSubject: new BehaviorSubject<boolean | null>(null),\r\n }\r\n\r\n instance.interceptors.response.use(\r\n (response) => response,\r\n async (error: AxiosError) => {\r\n if (!shouldInterceptError(error, options)) {\r\n return Promise.reject(error)\r\n }\r\n\r\n // we can confirm that error.config are defined here because of shouldInterceptError check\r\n const result$ = enqueueRequestAfterRefresh(\r\n instance,\r\n refreshAuthCall,\r\n error.config!,\r\n cache\r\n )\r\n return firstValueFrom(result$)\r\n }\r\n )\r\n}\r\n"],"names":["shouldInterceptError","error","options","config","_a","_b","enqueueRequestAfterRefresh","instance","refreshAuthCall","originalConfig","cache","from","newToken","err","filter","token","take","switchMap","response","createStreamRefreshInterceptor","BehaviorSubject","result$","firstValueFrom"],"mappings":"wGAmBO,SAASA,EACdC,EACAC,EACS,SACT,GAAI,CAACD,GAAS,EAACA,GAAA,MAAAA,EAAO,SAAU,EAACA,GAAA,MAAAA,EAAO,UACtC,MAAO,GAET,KAAM,CAAE,OAAAE,GAAWF,EAgBnB,MAdI,CAACC,EAAQ,aAAe,CAACA,EAAQ,YAAY,QAK7CC,GAAA,MAAAA,EAAQ,QAGZA,EAAO,MAAQ,IAEXC,EAAAH,EAAM,SAAN,MAAAG,EAAc,kBAKfH,EAAM,UAAYA,EAAM,QAAQ,SAAW,GAC5C,CAACA,EAAM,UACP,GAACI,EAAAH,EAAQ,cAAR,MAAAG,EAAqB,SAASJ,EAAM,SAAS,SAEvC,IAIJA,EAAM,WACTA,EAAM,SAAW,CACf,OAAQA,EAAM,OACd,KAAM,OACN,OAAQ,EACR,WAAY,GACZ,QAAS,CAAA,CAAC,GAIP,GACT,CAEO,SAASK,EACdC,EACAC,EACAC,EACAC,EACe,CACf,OAAKA,EAAM,eACTA,EAAM,aAAe,GACrBA,EAAM,oBAAoB,KAAK,IAAI,EAEnCC,EAAAA,KAAKH,EAAgBC,CAAc,CAAC,EAAE,UAAU,CAC9C,KAAOG,GAAa,CAClBF,EAAM,aAAe,GACrBA,EAAM,oBAAoB,KAAKE,CAAQ,CACzC,EACA,MAAQC,GAAQ,CACdH,EAAM,aAAe,GACrBA,EAAM,oBAAoB,MAAMG,CAAG,CACrC,CAAA,CACD,GAGIH,EAAM,oBAAoB,KAC/BI,EAAAA,OAAQC,GAA4BA,GAAS,IAAI,EACjDC,EAAAA,KAAK,CAAC,EACNC,EAAAA,UAAU,IACDN,EAAAA,KACLJ,EAAS,QAAWE,CAAc,EAAE,KAAMS,GAAaA,EAAS,IAAI,CAAA,CAEvE,CAAA,CAEL,CCvFO,SAASC,EACdZ,EACAC,EACAN,EAAqC,CACnC,YAAa,CAAC,GAAG,CACnB,EACA,CACA,GAAI,OAAOM,GAAoB,WAC7B,MAAM,IAAI,MACR,0FAAA,EAIJ,MAAME,EAAiC,CACrC,aAAc,GACd,oBAAqB,IAAIU,EAAAA,gBAAgC,IAAI,CAAA,EAG/Db,EAAS,aAAa,SAAS,IAC5BW,GAAaA,EACd,MAAOjB,GAAsB,CAC3B,GAAI,CAACD,EAAqBC,EAAOC,CAAO,EACtC,OAAO,QAAQ,OAAOD,CAAK,EAI7B,MAAMoB,EAAUf,EACdC,EACAC,EACAP,EAAM,OACNS,CAAA,EAEF,OAAOY,EAAAA,eAAeD,CAAO,CAC/B,CAAA,CAEJ"}
1
+ {"version":3,"file":"index.cjs.js","sources":["../src/utils.ts","../src/index.ts"],"sourcesContent":["import { filter, from, switchMap, take } from 'rxjs'\nimport type { Observable } from 'rxjs'\nimport type {\n AxiosError,\n AxiosInstance,\n AxiosRequestConfig,\n AxiosResponse,\n} from 'axios'\nimport type {\n AxiosStreamRefreshCache,\n AxiosStreamRefreshOptions,\n} from './model'\n\n/**\n * Returns TRUE: when error.response.status is contained in options.statusCodes\n * Returns FALSE: when error or error.response doesn't exist or options.statusCodes doesn't include response status\n *\n * @return {boolean}\n */\nexport function shouldInterceptError(\n error: AxiosError,\n options: AxiosStreamRefreshOptions\n): boolean {\n if (!error || !error?.config || !error?.response) {\n return false\n }\n const { config } = error\n\n if (!options.statusCodes || !options.statusCodes.length) {\n return false\n }\n\n // avoid infinite loop\n if (config?.retry) {\n return false\n }\n config.retry = true\n\n if (error.config?.skipAuthRefresh) {\n return false\n }\n\n if (\n (error.response && error.request.status === 0) ||\n !error.response ||\n !options.statusCodes?.includes(error.response.status)\n ) {\n return false\n }\n\n // Copy config to response if there's a network error, so config can be modified and used in the retry\n if (!error.response) {\n error.response = {\n config: error.config,\n data: undefined,\n status: 0,\n statusText: '',\n headers: {},\n }\n }\n\n return true\n}\n\nexport function enqueueRequestAfterRefresh<T = unknown>(\n instance: AxiosInstance,\n refreshAuthCall: (originalConfig: AxiosRequestConfig) => Promise<boolean>,\n originalConfig: AxiosRequestConfig,\n cache: AxiosStreamRefreshCache\n): Observable<AxiosResponse<T, unknown, {}>> {\n if (!cache.isRefreshing) {\n cache.isRefreshing = true\n cache.refreshTokenSubject.next(null)\n\n from(refreshAuthCall(originalConfig)).subscribe({\n next: (newToken) => {\n cache.isRefreshing = false\n cache.refreshTokenSubject.next(newToken)\n },\n error: (err) => {\n cache.isRefreshing = false\n cache.refreshTokenSubject.error(err)\n },\n })\n }\n\n return cache.refreshTokenSubject.pipe(\n filter((token): token is boolean => token != null),\n take(1),\n switchMap(() => {\n return from(instance.request<T>(originalConfig))\n })\n )\n}\n","import { BehaviorSubject, firstValueFrom } from 'rxjs'\r\nimport { enqueueRequestAfterRefresh, shouldInterceptError } from './utils'\r\nimport type { AxiosError, AxiosInstance, AxiosRequestConfig } from 'axios'\r\nimport type {\r\n AxiosStreamRefreshCache,\r\n AxiosStreamRefreshOptions,\r\n} from './model'\r\n\r\nexport function createStreamRefreshInterceptor(\r\n instance: AxiosInstance,\r\n refreshAuthCall: (originalConfig: AxiosRequestConfig) => Promise<boolean>,\r\n options: AxiosStreamRefreshOptions = {\r\n statusCodes: [401],\r\n }\r\n) {\r\n if (typeof refreshAuthCall !== 'function') {\r\n throw new Error(\r\n 'axios-stream-refresh requires `refreshAuthCall` to be a function that returns a promise.'\r\n )\r\n }\r\n\r\n const cache: AxiosStreamRefreshCache = {\r\n isRefreshing: false,\r\n refreshTokenSubject: new BehaviorSubject<boolean | null>(null),\r\n }\r\n\r\n instance.interceptors.response.use(\r\n (response) => response,\r\n async (error: AxiosError) => {\r\n if (!shouldInterceptError(error, options)) {\r\n return Promise.reject(error)\r\n }\r\n\r\n // we can confirm that error.config are defined here because of shouldInterceptError check\r\n const result$ = enqueueRequestAfterRefresh(\r\n instance,\r\n refreshAuthCall,\r\n error.config!,\r\n cache\r\n )\r\n return firstValueFrom(result$)\r\n }\r\n )\r\n}\r\n"],"names":["shouldInterceptError","error","options","config","_a","_b","enqueueRequestAfterRefresh","instance","refreshAuthCall","originalConfig","cache","from","newToken","err","filter","token","take","switchMap","createStreamRefreshInterceptor","BehaviorSubject","response","result$","firstValueFrom"],"mappings":"wGAmBO,SAASA,EACdC,EACAC,EACS,SACT,GAAI,CAACD,GAAS,EAACA,GAAA,MAAAA,EAAO,SAAU,EAACA,GAAA,MAAAA,EAAO,UACtC,MAAO,GAET,KAAM,CAAE,OAAAE,GAAWF,EAgBnB,MAdI,CAACC,EAAQ,aAAe,CAACA,EAAQ,YAAY,QAK7CC,GAAA,MAAAA,EAAQ,QAGZA,EAAO,MAAQ,IAEXC,EAAAH,EAAM,SAAN,MAAAG,EAAc,kBAKfH,EAAM,UAAYA,EAAM,QAAQ,SAAW,GAC5C,CAACA,EAAM,UACP,GAACI,EAAAH,EAAQ,cAAR,MAAAG,EAAqB,SAASJ,EAAM,SAAS,SAEvC,IAIJA,EAAM,WACTA,EAAM,SAAW,CACf,OAAQA,EAAM,OACd,KAAM,OACN,OAAQ,EACR,WAAY,GACZ,QAAS,CAAA,CAAC,GAIP,GACT,CAEO,SAASK,EACdC,EACAC,EACAC,EACAC,EAC2C,CAC3C,OAAKA,EAAM,eACTA,EAAM,aAAe,GACrBA,EAAM,oBAAoB,KAAK,IAAI,EAEnCC,EAAAA,KAAKH,EAAgBC,CAAc,CAAC,EAAE,UAAU,CAC9C,KAAOG,GAAa,CAClBF,EAAM,aAAe,GACrBA,EAAM,oBAAoB,KAAKE,CAAQ,CACzC,EACA,MAAQC,GAAQ,CACdH,EAAM,aAAe,GACrBA,EAAM,oBAAoB,MAAMG,CAAG,CACrC,CAAA,CACD,GAGIH,EAAM,oBAAoB,KAC/BI,EAAAA,OAAQC,GAA4BA,GAAS,IAAI,EACjDC,EAAAA,KAAK,CAAC,EACNC,EAAAA,UAAU,IACDN,OAAKJ,EAAS,QAAWE,CAAc,CAAC,CAChD,CAAA,CAEL,CCrFO,SAASS,EACdX,EACAC,EACAN,EAAqC,CACnC,YAAa,CAAC,GAAG,CACnB,EACA,CACA,GAAI,OAAOM,GAAoB,WAC7B,MAAM,IAAI,MACR,0FAAA,EAIJ,MAAME,EAAiC,CACrC,aAAc,GACd,oBAAqB,IAAIS,EAAAA,gBAAgC,IAAI,CAAA,EAG/DZ,EAAS,aAAa,SAAS,IAC5Ba,GAAaA,EACd,MAAOnB,GAAsB,CAC3B,GAAI,CAACD,EAAqBC,EAAOC,CAAO,EACtC,OAAO,QAAQ,OAAOD,CAAK,EAI7B,MAAMoB,EAAUf,EACdC,EACAC,EACAP,EAAM,OACNS,CAAA,EAEF,OAAOY,EAAAA,eAAeD,CAAO,CAC/B,CAAA,CAEJ"}
package/dist/index.es.js CHANGED
@@ -23,12 +23,10 @@ function c(e, u, n, t) {
23
23
  })), t.refreshTokenSubject.pipe(
24
24
  r((s) => s != null),
25
25
  a(1),
26
- o(() => f(
27
- e.request(n).then((s) => s.data)
28
- ))
26
+ o(() => f(e.request(n)))
29
27
  );
30
28
  }
31
- function b(e, u, n = {
29
+ function d(e, u, n = {
32
30
  statusCodes: [401]
33
31
  }) {
34
32
  if (typeof u != "function")
@@ -55,6 +53,6 @@ function b(e, u, n = {
55
53
  );
56
54
  }
57
55
  export {
58
- b as createStreamRefreshInterceptor
56
+ d as createStreamRefreshInterceptor
59
57
  };
60
58
  //# sourceMappingURL=index.es.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.es.js","sources":["../src/utils.ts","../src/index.ts"],"sourcesContent":["import { filter, from, switchMap, take } from 'rxjs'\r\nimport type { Observable } from 'rxjs'\r\nimport type {\r\n AxiosError,\r\n AxiosInstance,\r\n AxiosRequestConfig,\r\n InternalAxiosRequestConfig,\r\n} from 'axios'\r\nimport type {\r\n AxiosStreamRefreshCache,\r\n AxiosStreamRefreshOptions,\r\n} from './model'\r\n\r\n/**\r\n * Returns TRUE: when error.response.status is contained in options.statusCodes\r\n * Returns FALSE: when error or error.response doesn't exist or options.statusCodes doesn't include response status\r\n *\r\n * @return {boolean}\r\n */\r\nexport function shouldInterceptError(\r\n error: AxiosError,\r\n options: AxiosStreamRefreshOptions\r\n): boolean {\r\n if (!error || !error?.config || !error?.response) {\r\n return false\r\n }\r\n const { config } = error\r\n\r\n if (!options.statusCodes || !options.statusCodes.length) {\r\n return false\r\n }\r\n\r\n // avoid infinite loop\r\n if (config?.retry) {\r\n return false\r\n }\r\n config.retry = true\r\n\r\n if (error.config?.skipAuthRefresh) {\r\n return false\r\n }\r\n\r\n if (\r\n (error.response && error.request.status === 0) ||\r\n !error.response ||\r\n !options.statusCodes?.includes(error.response.status)\r\n ) {\r\n return false\r\n }\r\n\r\n // Copy config to response if there's a network error, so config can be modified and used in the retry\r\n if (!error.response) {\r\n error.response = {\r\n config: error.config as InternalAxiosRequestConfig,\r\n data: undefined,\r\n status: 0,\r\n statusText: '',\r\n headers: {},\r\n }\r\n }\r\n\r\n return true\r\n}\r\n\r\nexport function enqueueRequestAfterRefresh<T = unknown>(\r\n instance: AxiosInstance,\r\n refreshAuthCall: (originalConfig: AxiosRequestConfig) => Promise<boolean>,\r\n originalConfig: AxiosRequestConfig,\r\n cache: AxiosStreamRefreshCache\r\n): Observable<T> {\r\n if (!cache.isRefreshing) {\r\n cache.isRefreshing = true\r\n cache.refreshTokenSubject.next(null)\r\n\r\n from(refreshAuthCall(originalConfig)).subscribe({\r\n next: (newToken) => {\r\n cache.isRefreshing = false\r\n cache.refreshTokenSubject.next(newToken)\r\n },\r\n error: (err) => {\r\n cache.isRefreshing = false\r\n cache.refreshTokenSubject.error(err)\r\n },\r\n })\r\n }\r\n\r\n return cache.refreshTokenSubject.pipe(\r\n filter((token): token is boolean => token != null),\r\n take(1),\r\n switchMap(() => {\r\n return from(\r\n instance.request<T>(originalConfig).then((response) => response.data)\r\n )\r\n })\r\n )\r\n}\r\n","import { BehaviorSubject, firstValueFrom } from 'rxjs'\r\nimport { enqueueRequestAfterRefresh, shouldInterceptError } from './utils'\r\nimport type { AxiosError, AxiosInstance, AxiosRequestConfig } from 'axios'\r\nimport type {\r\n AxiosStreamRefreshCache,\r\n AxiosStreamRefreshOptions,\r\n} from './model'\r\n\r\nexport function createStreamRefreshInterceptor(\r\n instance: AxiosInstance,\r\n refreshAuthCall: (originalConfig: AxiosRequestConfig) => Promise<boolean>,\r\n options: AxiosStreamRefreshOptions = {\r\n statusCodes: [401],\r\n }\r\n) {\r\n if (typeof refreshAuthCall !== 'function') {\r\n throw new Error(\r\n 'axios-stream-refresh requires `refreshAuthCall` to be a function that returns a promise.'\r\n )\r\n }\r\n\r\n const cache: AxiosStreamRefreshCache = {\r\n isRefreshing: false,\r\n refreshTokenSubject: new BehaviorSubject<boolean | null>(null),\r\n }\r\n\r\n instance.interceptors.response.use(\r\n (response) => response,\r\n async (error: AxiosError) => {\r\n if (!shouldInterceptError(error, options)) {\r\n return Promise.reject(error)\r\n }\r\n\r\n // we can confirm that error.config are defined here because of shouldInterceptError check\r\n const result$ = enqueueRequestAfterRefresh(\r\n instance,\r\n refreshAuthCall,\r\n error.config!,\r\n cache\r\n )\r\n return firstValueFrom(result$)\r\n }\r\n )\r\n}\r\n"],"names":["shouldInterceptError","error","options","config","_a","_b","enqueueRequestAfterRefresh","instance","refreshAuthCall","originalConfig","cache","from","newToken","err","filter","token","take","switchMap","response","createStreamRefreshInterceptor","BehaviorSubject","result$","firstValueFrom"],"mappings":";AAmBO,SAASA,EACdC,GACAC,GACS;;AACT,MAAI,CAACD,KAAS,EAACA,KAAA,QAAAA,EAAO,WAAU,EAACA,KAAA,QAAAA,EAAO;AACtC,WAAO;AAET,QAAM,EAAE,QAAAE,MAAWF;AAgBnB,SAdI,CAACC,EAAQ,eAAe,CAACA,EAAQ,YAAY,UAK7CC,KAAA,QAAAA,EAAQ,UAGZA,EAAO,QAAQ,KAEXC,IAAAH,EAAM,WAAN,QAAAG,EAAc,oBAKfH,EAAM,YAAYA,EAAM,QAAQ,WAAW,KAC5C,CAACA,EAAM,YACP,GAACI,IAAAH,EAAQ,gBAAR,QAAAG,EAAqB,SAASJ,EAAM,SAAS,WAEvC,MAIJA,EAAM,aACTA,EAAM,WAAW;AAAA,IACf,QAAQA,EAAM;AAAA,IACd,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,SAAS,CAAA;AAAA,EAAC,IAIP;AACT;AAEO,SAASK,EACdC,GACAC,GACAC,GACAC,GACe;AACf,SAAKA,EAAM,iBACTA,EAAM,eAAe,IACrBA,EAAM,oBAAoB,KAAK,IAAI,GAEnCC,EAAKH,EAAgBC,CAAc,CAAC,EAAE,UAAU;AAAA,IAC9C,MAAM,CAACG,MAAa;AAClB,MAAAF,EAAM,eAAe,IACrBA,EAAM,oBAAoB,KAAKE,CAAQ;AAAA,IACzC;AAAA,IACA,OAAO,CAACC,MAAQ;AACd,MAAAH,EAAM,eAAe,IACrBA,EAAM,oBAAoB,MAAMG,CAAG;AAAA,IACrC;AAAA,EAAA,CACD,IAGIH,EAAM,oBAAoB;AAAA,IAC/BI,EAAO,CAACC,MAA4BA,KAAS,IAAI;AAAA,IACjDC,EAAK,CAAC;AAAA,IACNC,EAAU,MACDN;AAAA,MACLJ,EAAS,QAAWE,CAAc,EAAE,KAAK,CAACS,MAAaA,EAAS,IAAI;AAAA,IAAA,CAEvE;AAAA,EAAA;AAEL;ACvFO,SAASC,EACdZ,GACAC,GACAN,IAAqC;AAAA,EACnC,aAAa,CAAC,GAAG;AACnB,GACA;AACA,MAAI,OAAOM,KAAoB;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAIJ,QAAME,IAAiC;AAAA,IACrC,cAAc;AAAA,IACd,qBAAqB,IAAIU,EAAgC,IAAI;AAAA,EAAA;AAG/D,EAAAb,EAAS,aAAa,SAAS;AAAA,IAC7B,CAACW,MAAaA;AAAA,IACd,OAAOjB,MAAsB;AAC3B,UAAI,CAACD,EAAqBC,GAAOC,CAAO;AACtC,eAAO,QAAQ,OAAOD,CAAK;AAI7B,YAAMoB,IAAUf;AAAA,QACdC;AAAA,QACAC;AAAA,QACAP,EAAM;AAAA,QACNS;AAAA,MAAA;AAEF,aAAOY,EAAeD,CAAO;AAAA,IAC/B;AAAA,EAAA;AAEJ;"}
1
+ {"version":3,"file":"index.es.js","sources":["../src/utils.ts","../src/index.ts"],"sourcesContent":["import { filter, from, switchMap, take } from 'rxjs'\nimport type { Observable } from 'rxjs'\nimport type {\n AxiosError,\n AxiosInstance,\n AxiosRequestConfig,\n AxiosResponse,\n} from 'axios'\nimport type {\n AxiosStreamRefreshCache,\n AxiosStreamRefreshOptions,\n} from './model'\n\n/**\n * Returns TRUE: when error.response.status is contained in options.statusCodes\n * Returns FALSE: when error or error.response doesn't exist or options.statusCodes doesn't include response status\n *\n * @return {boolean}\n */\nexport function shouldInterceptError(\n error: AxiosError,\n options: AxiosStreamRefreshOptions\n): boolean {\n if (!error || !error?.config || !error?.response) {\n return false\n }\n const { config } = error\n\n if (!options.statusCodes || !options.statusCodes.length) {\n return false\n }\n\n // avoid infinite loop\n if (config?.retry) {\n return false\n }\n config.retry = true\n\n if (error.config?.skipAuthRefresh) {\n return false\n }\n\n if (\n (error.response && error.request.status === 0) ||\n !error.response ||\n !options.statusCodes?.includes(error.response.status)\n ) {\n return false\n }\n\n // Copy config to response if there's a network error, so config can be modified and used in the retry\n if (!error.response) {\n error.response = {\n config: error.config,\n data: undefined,\n status: 0,\n statusText: '',\n headers: {},\n }\n }\n\n return true\n}\n\nexport function enqueueRequestAfterRefresh<T = unknown>(\n instance: AxiosInstance,\n refreshAuthCall: (originalConfig: AxiosRequestConfig) => Promise<boolean>,\n originalConfig: AxiosRequestConfig,\n cache: AxiosStreamRefreshCache\n): Observable<AxiosResponse<T, unknown, {}>> {\n if (!cache.isRefreshing) {\n cache.isRefreshing = true\n cache.refreshTokenSubject.next(null)\n\n from(refreshAuthCall(originalConfig)).subscribe({\n next: (newToken) => {\n cache.isRefreshing = false\n cache.refreshTokenSubject.next(newToken)\n },\n error: (err) => {\n cache.isRefreshing = false\n cache.refreshTokenSubject.error(err)\n },\n })\n }\n\n return cache.refreshTokenSubject.pipe(\n filter((token): token is boolean => token != null),\n take(1),\n switchMap(() => {\n return from(instance.request<T>(originalConfig))\n })\n )\n}\n","import { BehaviorSubject, firstValueFrom } from 'rxjs'\r\nimport { enqueueRequestAfterRefresh, shouldInterceptError } from './utils'\r\nimport type { AxiosError, AxiosInstance, AxiosRequestConfig } from 'axios'\r\nimport type {\r\n AxiosStreamRefreshCache,\r\n AxiosStreamRefreshOptions,\r\n} from './model'\r\n\r\nexport function createStreamRefreshInterceptor(\r\n instance: AxiosInstance,\r\n refreshAuthCall: (originalConfig: AxiosRequestConfig) => Promise<boolean>,\r\n options: AxiosStreamRefreshOptions = {\r\n statusCodes: [401],\r\n }\r\n) {\r\n if (typeof refreshAuthCall !== 'function') {\r\n throw new Error(\r\n 'axios-stream-refresh requires `refreshAuthCall` to be a function that returns a promise.'\r\n )\r\n }\r\n\r\n const cache: AxiosStreamRefreshCache = {\r\n isRefreshing: false,\r\n refreshTokenSubject: new BehaviorSubject<boolean | null>(null),\r\n }\r\n\r\n instance.interceptors.response.use(\r\n (response) => response,\r\n async (error: AxiosError) => {\r\n if (!shouldInterceptError(error, options)) {\r\n return Promise.reject(error)\r\n }\r\n\r\n // we can confirm that error.config are defined here because of shouldInterceptError check\r\n const result$ = enqueueRequestAfterRefresh(\r\n instance,\r\n refreshAuthCall,\r\n error.config!,\r\n cache\r\n )\r\n return firstValueFrom(result$)\r\n }\r\n )\r\n}\r\n"],"names":["shouldInterceptError","error","options","config","_a","_b","enqueueRequestAfterRefresh","instance","refreshAuthCall","originalConfig","cache","from","newToken","err","filter","token","take","switchMap","createStreamRefreshInterceptor","BehaviorSubject","response","result$","firstValueFrom"],"mappings":";AAmBO,SAASA,EACdC,GACAC,GACS;;AACT,MAAI,CAACD,KAAS,EAACA,KAAA,QAAAA,EAAO,WAAU,EAACA,KAAA,QAAAA,EAAO;AACtC,WAAO;AAET,QAAM,EAAE,QAAAE,MAAWF;AAgBnB,SAdI,CAACC,EAAQ,eAAe,CAACA,EAAQ,YAAY,UAK7CC,KAAA,QAAAA,EAAQ,UAGZA,EAAO,QAAQ,KAEXC,IAAAH,EAAM,WAAN,QAAAG,EAAc,oBAKfH,EAAM,YAAYA,EAAM,QAAQ,WAAW,KAC5C,CAACA,EAAM,YACP,GAACI,IAAAH,EAAQ,gBAAR,QAAAG,EAAqB,SAASJ,EAAM,SAAS,WAEvC,MAIJA,EAAM,aACTA,EAAM,WAAW;AAAA,IACf,QAAQA,EAAM;AAAA,IACd,MAAM;AAAA,IACN,QAAQ;AAAA,IACR,YAAY;AAAA,IACZ,SAAS,CAAA;AAAA,EAAC,IAIP;AACT;AAEO,SAASK,EACdC,GACAC,GACAC,GACAC,GAC2C;AAC3C,SAAKA,EAAM,iBACTA,EAAM,eAAe,IACrBA,EAAM,oBAAoB,KAAK,IAAI,GAEnCC,EAAKH,EAAgBC,CAAc,CAAC,EAAE,UAAU;AAAA,IAC9C,MAAM,CAACG,MAAa;AAClB,MAAAF,EAAM,eAAe,IACrBA,EAAM,oBAAoB,KAAKE,CAAQ;AAAA,IACzC;AAAA,IACA,OAAO,CAACC,MAAQ;AACd,MAAAH,EAAM,eAAe,IACrBA,EAAM,oBAAoB,MAAMG,CAAG;AAAA,IACrC;AAAA,EAAA,CACD,IAGIH,EAAM,oBAAoB;AAAA,IAC/BI,EAAO,CAACC,MAA4BA,KAAS,IAAI;AAAA,IACjDC,EAAK,CAAC;AAAA,IACNC,EAAU,MACDN,EAAKJ,EAAS,QAAWE,CAAc,CAAC,CAChD;AAAA,EAAA;AAEL;ACrFO,SAASS,EACdX,GACAC,GACAN,IAAqC;AAAA,EACnC,aAAa,CAAC,GAAG;AACnB,GACA;AACA,MAAI,OAAOM,KAAoB;AAC7B,UAAM,IAAI;AAAA,MACR;AAAA,IAAA;AAIJ,QAAME,IAAiC;AAAA,IACrC,cAAc;AAAA,IACd,qBAAqB,IAAIS,EAAgC,IAAI;AAAA,EAAA;AAG/D,EAAAZ,EAAS,aAAa,SAAS;AAAA,IAC7B,CAACa,MAAaA;AAAA,IACd,OAAOnB,MAAsB;AAC3B,UAAI,CAACD,EAAqBC,GAAOC,CAAO;AACtC,eAAO,QAAQ,OAAOD,CAAK;AAI7B,YAAMoB,IAAUf;AAAA,QACdC;AAAA,QACAC;AAAA,QACAP,EAAM;AAAA,QACNS;AAAA,MAAA;AAEF,aAAOY,EAAeD,CAAO;AAAA,IAC/B;AAAA,EAAA;AAEJ;"}
package/dist/utils.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Observable } from 'rxjs';
2
- import { AxiosError, AxiosInstance, AxiosRequestConfig } from 'axios';
2
+ import { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
3
3
  import { AxiosStreamRefreshCache, AxiosStreamRefreshOptions } from './model';
4
4
  /**
5
5
  * Returns TRUE: when error.response.status is contained in options.statusCodes
@@ -8,4 +8,4 @@ import { AxiosStreamRefreshCache, AxiosStreamRefreshOptions } from './model';
8
8
  * @return {boolean}
9
9
  */
10
10
  export declare function shouldInterceptError(error: AxiosError, options: AxiosStreamRefreshOptions): boolean;
11
- export declare function enqueueRequestAfterRefresh<T = unknown>(instance: AxiosInstance, refreshAuthCall: (originalConfig: AxiosRequestConfig) => Promise<boolean>, originalConfig: AxiosRequestConfig, cache: AxiosStreamRefreshCache): Observable<T>;
11
+ export declare function enqueueRequestAfterRefresh<T = unknown>(instance: AxiosInstance, refreshAuthCall: (originalConfig: AxiosRequestConfig) => Promise<boolean>, originalConfig: AxiosRequestConfig, cache: AxiosStreamRefreshCache): Observable<AxiosResponse<T, unknown, {}>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "axios-stream-auth-refresh",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Parallel refresh token handler using RxJS and Axios",
5
5
  "author": "Pourya Alipanah <pourya.alipanah2@gmail.com>",
6
6
  "license": "MIT",