@ctil/gql 1.1.7 → 1.1.9
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 +66 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +66 -42
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -93,6 +93,8 @@ declare class CCRequest {
|
|
|
93
93
|
private headers;
|
|
94
94
|
private deviceInfoPromise;
|
|
95
95
|
private interceptors;
|
|
96
|
+
private refreshPromise;
|
|
97
|
+
private logoutPromise;
|
|
96
98
|
constructor(config: RequestConfig);
|
|
97
99
|
/** 注册一个拦截器(支持多个) */
|
|
98
100
|
use(interceptor: RequestInterceptor): void;
|
|
@@ -117,10 +119,11 @@ declare class CCRequest {
|
|
|
117
119
|
getHeaders(): Record<string, string>;
|
|
118
120
|
removeHeader(key: string): void;
|
|
119
121
|
clearHeaders(): void;
|
|
120
|
-
private
|
|
122
|
+
private logoutOnce;
|
|
121
123
|
/** 无感刷新 token */
|
|
122
124
|
private ensureTokenValid;
|
|
123
|
-
|
|
125
|
+
private refreshToken;
|
|
126
|
+
request<T = any>(query: string | DocumentNode, variables?: Record<string, any>, _retry?: boolean): Promise<T>;
|
|
124
127
|
}
|
|
125
128
|
|
|
126
129
|
/** 初始化全局客户端 */
|
package/dist/index.d.ts
CHANGED
|
@@ -93,6 +93,8 @@ declare class CCRequest {
|
|
|
93
93
|
private headers;
|
|
94
94
|
private deviceInfoPromise;
|
|
95
95
|
private interceptors;
|
|
96
|
+
private refreshPromise;
|
|
97
|
+
private logoutPromise;
|
|
96
98
|
constructor(config: RequestConfig);
|
|
97
99
|
/** 注册一个拦截器(支持多个) */
|
|
98
100
|
use(interceptor: RequestInterceptor): void;
|
|
@@ -117,10 +119,11 @@ declare class CCRequest {
|
|
|
117
119
|
getHeaders(): Record<string, string>;
|
|
118
120
|
removeHeader(key: string): void;
|
|
119
121
|
clearHeaders(): void;
|
|
120
|
-
private
|
|
122
|
+
private logoutOnce;
|
|
121
123
|
/** 无感刷新 token */
|
|
122
124
|
private ensureTokenValid;
|
|
123
|
-
|
|
125
|
+
private refreshToken;
|
|
126
|
+
request<T = any>(query: string | DocumentNode, variables?: Record<string, any>, _retry?: boolean): Promise<T>;
|
|
124
127
|
}
|
|
125
128
|
|
|
126
129
|
/** 初始化全局客户端 */
|
package/dist/index.js
CHANGED
|
@@ -1680,6 +1680,7 @@ var CCRequest = class {
|
|
|
1680
1680
|
this._remember = false;
|
|
1681
1681
|
this.interceptors = [];
|
|
1682
1682
|
this.refreshPromise = null;
|
|
1683
|
+
this.logoutPromise = null;
|
|
1683
1684
|
this.deviceInfoPromise = getDeviceInfo();
|
|
1684
1685
|
this.headers = this.buildHeaders(config);
|
|
1685
1686
|
const loginInfo = this.loadLoginInfo();
|
|
@@ -1821,65 +1822,79 @@ var CCRequest = class {
|
|
|
1821
1822
|
clearHeaders() {
|
|
1822
1823
|
this.headers = { "Content-Type": "application/json" };
|
|
1823
1824
|
}
|
|
1824
|
-
|
|
1825
|
+
async logoutOnce() {
|
|
1826
|
+
if (!this.logoutPromise) {
|
|
1827
|
+
this.logoutPromise = (async () => {
|
|
1828
|
+
await this.removeLoginInfo();
|
|
1829
|
+
})();
|
|
1830
|
+
}
|
|
1831
|
+
return this.logoutPromise;
|
|
1832
|
+
}
|
|
1825
1833
|
/** 无感刷新 token */
|
|
1826
1834
|
async ensureTokenValid() {
|
|
1827
|
-
const loginInfo = this.getLoginInfo();
|
|
1835
|
+
const loginInfo = await this.getLoginInfo();
|
|
1828
1836
|
if (!loginInfo) return;
|
|
1829
1837
|
const now = Date.now();
|
|
1830
|
-
const
|
|
1838
|
+
const accessExpire = new Date(loginInfo.expireAt).getTime() <= now + 6e5;
|
|
1831
1839
|
const refreshExpired = new Date(loginInfo.refreshExpireAt).getTime() <= now;
|
|
1832
1840
|
if (refreshExpired) {
|
|
1833
|
-
this.
|
|
1841
|
+
await this.logoutOnce();
|
|
1834
1842
|
throw new Error("Login expired. Please login again.");
|
|
1835
1843
|
}
|
|
1836
|
-
if (
|
|
1837
|
-
|
|
1838
|
-
|
|
1844
|
+
if (accessExpire) {
|
|
1845
|
+
await this.refreshToken();
|
|
1846
|
+
}
|
|
1847
|
+
}
|
|
1848
|
+
async refreshToken() {
|
|
1849
|
+
const loginInfo = await this.getLoginInfo();
|
|
1850
|
+
if (!loginInfo) return;
|
|
1851
|
+
if (!this.refreshPromise) {
|
|
1852
|
+
this.refreshPromise = (async () => {
|
|
1853
|
+
try {
|
|
1854
|
+
const newToken = await auth.refreshToken({
|
|
1855
|
+
refreshToken: loginInfo.refreshToken,
|
|
1856
|
+
remember: this._remember
|
|
1857
|
+
});
|
|
1858
|
+
this.setToken(newToken.refreshToken.token);
|
|
1859
|
+
} catch (e) {
|
|
1860
|
+
await this.logoutOnce();
|
|
1861
|
+
throw e;
|
|
1862
|
+
} finally {
|
|
1863
|
+
this.refreshPromise = null;
|
|
1864
|
+
}
|
|
1865
|
+
})();
|
|
1839
1866
|
}
|
|
1840
|
-
this.refreshPromise = (async () => {
|
|
1841
|
-
try {
|
|
1842
|
-
const result = await auth.refreshToken({
|
|
1843
|
-
refreshToken: loginInfo.refreshToken,
|
|
1844
|
-
remember: this._remember
|
|
1845
|
-
});
|
|
1846
|
-
const newInfo = result.refreshToken ?? result;
|
|
1847
|
-
this.setLoginInfo(newInfo, this._remember);
|
|
1848
|
-
} finally {
|
|
1849
|
-
this.refreshPromise = null;
|
|
1850
|
-
}
|
|
1851
|
-
})();
|
|
1852
1867
|
return this.refreshPromise;
|
|
1853
1868
|
}
|
|
1854
1869
|
// ===== 请求逻辑 =====
|
|
1855
|
-
async request(query2, variables) {
|
|
1870
|
+
async request(query2, variables, _retry = false) {
|
|
1856
1871
|
let queryStr = typeof query2 === "string" ? query2 : print(query2);
|
|
1857
|
-
const { deviceId, deviceName } = await this.deviceInfoPromise;
|
|
1858
|
-
let headersWithDevice = Object.fromEntries(
|
|
1859
|
-
Object.entries({
|
|
1860
|
-
...this.headers,
|
|
1861
|
-
"X-Device-Id": deviceId,
|
|
1862
|
-
"X-Device-Name": deviceName
|
|
1863
|
-
}).filter(([_, v]) => v !== void 0)
|
|
1864
|
-
);
|
|
1865
|
-
for (const interceptor of this.interceptors) {
|
|
1866
|
-
if (interceptor.onRequest) {
|
|
1867
|
-
const result = await interceptor.onRequest({
|
|
1868
|
-
query: queryStr,
|
|
1869
|
-
variables,
|
|
1870
|
-
headers: headersWithDevice
|
|
1871
|
-
});
|
|
1872
|
-
queryStr = result.query;
|
|
1873
|
-
variables = result.variables;
|
|
1874
|
-
headersWithDevice = Object.fromEntries(
|
|
1875
|
-
Object.entries(result.headers).filter(([_, v]) => v !== void 0)
|
|
1876
|
-
);
|
|
1877
|
-
}
|
|
1878
|
-
}
|
|
1879
1872
|
try {
|
|
1880
1873
|
if (!/refreshToken/i.test(queryStr)) {
|
|
1881
1874
|
await this.ensureTokenValid();
|
|
1882
1875
|
}
|
|
1876
|
+
const { deviceId, deviceName } = await this.deviceInfoPromise;
|
|
1877
|
+
let headersWithDevice = Object.fromEntries(
|
|
1878
|
+
Object.entries({
|
|
1879
|
+
...this.headers,
|
|
1880
|
+
"X-Device-Id": deviceId,
|
|
1881
|
+
"X-Device-Name": deviceName
|
|
1882
|
+
}).filter(([_, v]) => v !== void 0)
|
|
1883
|
+
);
|
|
1884
|
+
for (const interceptor of this.interceptors) {
|
|
1885
|
+
if (interceptor.onRequest) {
|
|
1886
|
+
const result = await interceptor.onRequest({
|
|
1887
|
+
query: queryStr,
|
|
1888
|
+
variables,
|
|
1889
|
+
headers: headersWithDevice
|
|
1890
|
+
});
|
|
1891
|
+
queryStr = result.query;
|
|
1892
|
+
variables = result.variables;
|
|
1893
|
+
headersWithDevice = Object.fromEntries(
|
|
1894
|
+
Object.entries(result.headers).filter(([_, v]) => v !== void 0)
|
|
1895
|
+
);
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1883
1898
|
const res = await this.client.rawRequest(
|
|
1884
1899
|
queryStr,
|
|
1885
1900
|
variables,
|
|
@@ -1895,6 +1910,15 @@ var CCRequest = class {
|
|
|
1895
1910
|
} catch (err) {
|
|
1896
1911
|
const message = err.response?.errors?.[0]?.message ?? err.message;
|
|
1897
1912
|
const status = err.response?.errors?.[0]?.extensions?.code ?? 500;
|
|
1913
|
+
if (status === 401 && !_retry && !/refreshToken/i.test(queryStr)) {
|
|
1914
|
+
try {
|
|
1915
|
+
await this.refreshToken();
|
|
1916
|
+
return this.request(queryStr, variables);
|
|
1917
|
+
} catch {
|
|
1918
|
+
await this.logoutOnce();
|
|
1919
|
+
throw err;
|
|
1920
|
+
}
|
|
1921
|
+
}
|
|
1898
1922
|
const formattedError = {
|
|
1899
1923
|
message,
|
|
1900
1924
|
status,
|