@0xchain/request 1.1.0-beta.63 → 1.1.0-beta.65

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.d.ts CHANGED
@@ -12,5 +12,6 @@ export interface ApiError extends AxiosError {
12
12
  declare const axiosInstance: import('axios').AxiosInstance;
13
13
  export default axiosInstance;
14
14
  export { setServerHeaderProvider } from './interceptors/commonHeader';
15
+ export { refreshAccessToken, getCurrentAccessToken } from './tokenRefresh';
15
16
  export type { ApiRequestConfig, ServerHeaderProvider, Pagination, Status, IResponse, IFilters, IPageRequest, } from './types';
16
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC;AAQ/C,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,IAAI,EAAE,CAAC,CAAC;CACT;AAED,MAAM,WAAW,QAAS,SAAQ,UAAU;IAC1C,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAGD,QAAA,MAAM,aAAa,+BAYjB,CAAC;AASH,eAAe,aAAa,CAAC;AAE7B,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAEtE,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,UAAU,EACV,MAAM,EACN,SAAS,EACT,QAAQ,EACR,YAAY,GACb,MAAM,SAAS,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC;AAQ/C,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;IACF,IAAI,EAAE,CAAC,CAAC;CACT;AAED,MAAM,WAAW,QAAS,SAAQ,UAAU;IAC1C,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAGD,QAAA,MAAM,aAAa,+BAYjB,CAAC;AASH,eAAe,aAAa,CAAC;AAE7B,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AAEtE,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAE3E,YAAY,EACV,gBAAgB,EAChB,oBAAoB,EACpB,UAAU,EACV,MAAM,EACN,SAAS,EACT,QAAQ,EACR,YAAY,GACb,MAAM,SAAS,CAAA"}
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import axios, { isAxiosError, AxiosError } from "axios";
2
2
  import qs from "qs";
3
3
  import jsCookie from "js-cookie";
4
+ import { envCookieName, getToken, isTokenExpired } from "@0xchain/token";
4
5
  import { logger } from "@0xchain/logger";
5
- import { getToken, setToken, isTokenExpired } from "@0xchain/token";
6
6
  const isSimplifiedChinese = () => {
7
7
  return /^(zh-hans|zh-cn|zh-sg|zh-my)$/.test(window?.navigator.language.toLowerCase());
8
8
  };
@@ -71,7 +71,7 @@ async function commonHeader(config) {
71
71
  const startLanguage = getHeader(config, "Accept-Language");
72
72
  const { cookies, headers } = await import("next/headers");
73
73
  const cookieStore = await cookies();
74
- access_token = cookieStore.get("access_token")?.value || "";
74
+ access_token = cookieStore.get(envCookieName("access_token"))?.value || "";
75
75
  const hList = await headers();
76
76
  language = startLanguage || hList.get("x-next-intl-locale") || "en";
77
77
  } catch (error) {
@@ -79,7 +79,7 @@ async function commonHeader(config) {
79
79
  }
80
80
  }
81
81
  } else {
82
- access_token = jsCookie.get("access_token") || "";
82
+ access_token = jsCookie.get(envCookieName("access_token")) || "";
83
83
  language = jsCookie.get("NEXT_LOCALE") || matchSystemLanguage() || "en";
84
84
  }
85
85
  const isRefreshToken = config.headers?.["isRefreshToken"];
@@ -203,10 +203,16 @@ const refreshClient = axios.create({
203
203
  }
204
204
  });
205
205
  let refreshPromise = null;
206
+ const REFRESH_DEDUPE_MS = 2e3;
207
+ let lastRefreshAt = 0;
208
+ let lastRefreshResult = null;
206
209
  function refreshAccessToken() {
207
210
  if (refreshPromise) {
208
211
  return refreshPromise;
209
212
  }
213
+ if (Date.now() - lastRefreshAt < REFRESH_DEDUPE_MS) {
214
+ return Promise.resolve(lastRefreshResult);
215
+ }
210
216
  const refresh_token = getToken("refresh_token");
211
217
  if (!refresh_token) {
212
218
  return Promise.resolve(null);
@@ -222,18 +228,21 @@ function refreshAccessToken() {
222
228
  }).then((res) => {
223
229
  const data = res?.data?.data;
224
230
  if (data?.access_token) {
225
- setToken(data);
226
231
  return data.access_token;
227
232
  }
228
233
  return null;
229
- }).catch(() => null).finally(() => {
234
+ }).catch(() => null).then((result) => {
235
+ lastRefreshAt = Date.now();
236
+ lastRefreshResult = result;
237
+ return result;
238
+ }).finally(() => {
230
239
  refreshPromise = null;
231
240
  });
232
241
  refreshPromise = pending;
233
242
  return pending;
234
243
  }
235
244
  function getCurrentAccessToken() {
236
- return jsCookie.get("access_token") || getToken("access_token") || "";
245
+ return jsCookie.get(envCookieName("access_token")) || getToken("access_token") || "";
237
246
  }
238
247
  function shouldSkipRefresh(config) {
239
248
  const url = typeof config?.url === "string" ? config.url : "";
@@ -361,5 +370,7 @@ axiosInstance.interceptors.request.use(commonHeader, errorInterceptor);
361
370
  axiosInstance.interceptors.response.use(createResponseInterceptor(axiosInstance), errorInterceptor);
362
371
  export {
363
372
  axiosInstance as default,
373
+ getCurrentAccessToken,
374
+ refreshAccessToken,
364
375
  setServerHeaderProvider
365
376
  };
@@ -1 +1 @@
1
- {"version":3,"file":"commonHeader.d.ts","sourceRoot":"","sources":["../../src/interceptors/commonHeader.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,0BAA0B,EAAE,MAAM,OAAO,CAAC;AACrE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAQrD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,oBAAoB,QAErE;AAyBD,wBAAsB,YAAY,CAChC,MAAM,EAAE,0BAA0B,4CAwDnC"}
1
+ {"version":3,"file":"commonHeader.d.ts","sourceRoot":"","sources":["../../src/interceptors/commonHeader.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoB,0BAA0B,EAAE,MAAM,OAAO,CAAC;AACrE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAQrD,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,oBAAoB,QAErE;AAyBD,wBAAsB,YAAY,CAChC,MAAM,EAAE,0BAA0B,4CAwDnC"}
@@ -1,5 +1,9 @@
1
1
  /**
2
- * 触发一次 token 刷新;并发调用共享同一个在途请求。
2
+ * 触发一次 token 刷新;并发/紧邻调用共享同一个结果。
3
+ *
4
+ * 关键设计:cookie 由服务端 `/api/refresh/token` 的 Set-Cookie 统一写入,
5
+ * 客户端这里「绝不」再用 js-cookie 写一遍,避免双写竞态把 cookie 写坏。
6
+ *
3
7
  * @returns 新的 access_token;刷新失败返回 null。
4
8
  */
5
9
  export declare function refreshAccessToken(): Promise<string | null>;
@@ -1 +1 @@
1
- {"version":3,"file":"tokenRefresh.d.ts","sourceRoot":"","sources":["../src/tokenRefresh.ts"],"names":[],"mappings":"AA+BA;;;GAGG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAmC3D;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C"}
1
+ {"version":3,"file":"tokenRefresh.d.ts","sourceRoot":"","sources":["../src/tokenRefresh.ts"],"names":[],"mappings":"AAqCA;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA6C3D;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xchain/request",
3
- "version": "1.1.0-beta.63",
3
+ "version": "1.1.0-beta.65",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",
@@ -32,8 +32,8 @@
32
32
  "qs": "6.14.0"
33
33
  },
34
34
  "dependencies": {
35
- "@0xchain/logger": "1.1.0-beta.63",
36
- "@0xchain/token": "1.1.0-beta.63"
35
+ "@0xchain/token": "1.1.0-beta.65",
36
+ "@0xchain/logger": "1.1.0-beta.65"
37
37
  },
38
38
  "nx": {
39
39
  "tags": [