@easecation/ecapi-sdk 3.0.6 → 3.0.12
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/README.md +18 -1
- package/dist/client.d.ts +5 -1
- package/dist/client.js +5 -0
- package/dist/custom-fetch.d.ts +3 -1
- package/dist/custom-fetch.js +22 -2
- package/dist/http.d.ts +5 -1
- package/dist/http.js +17 -3
- package/dist/types.d.ts +7 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -65,7 +65,24 @@ new ECAPIClient({
|
|
|
65
65
|
});
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
如果认证来自 IAM callback、短期 token 或其它异步来源,可以使用 `authProvider`。`ECAPIClient`、`configureECAPIFetch` 和 `createECAPIFetch` 都支持它,SDK 会在每次请求前调用:
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
const client = new ECAPIClient({
|
|
72
|
+
authProvider: async () => {
|
|
73
|
+
const token = await getAppSessionTokenFromIamCallback();
|
|
74
|
+
return token ? { type: 'appSessionToken', appSessionToken: token } : null;
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
认证优先级:
|
|
80
|
+
|
|
81
|
+
1. 单次请求 `options.auth` 最高;传 `null` 表示本次请求不发送认证,也不会调用 `authProvider`。
|
|
82
|
+
2. 客户端 `authProvider` 次之;返回 `null`/`undefined` 表示本次请求不发送认证。
|
|
83
|
+
3. 客户端静态 `auth`、`apiKey`、`appSessionToken`、`bearerToken`、`jwt` 作为兼容简写。
|
|
84
|
+
|
|
85
|
+
SDK 不做 401 自动重试;如果 token 需要刷新,请在 IAM callback / `authProvider` 侧处理,下一次请求会重新解析认证。
|
|
69
86
|
|
|
70
87
|
## 类型提示与 Docstring
|
|
71
88
|
|
package/dist/client.d.ts
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
import { AdminApi, AuditApi, AuthApi, BroadcastApi, CfgLangApi, CountApi, EaseChatApi, GamelogApi, GlobalKVApi, ItemApi, LobbyApi, LogApi, MonitorApi, OrderApi, PermissionApi, PlayerApi, PullConfigApi, PunishApi, ServersApi, StageApi, SystemApi, UserApi } from './apis';
|
|
3
3
|
import { ECAPIError } from './errors';
|
|
4
4
|
import { ECAPIHttpClient, HttpMethod } from './http';
|
|
5
|
-
import { AuthCredentials, ClientOptions, HeaderMap, RequestOptions } from './types';
|
|
5
|
+
import { AuthCredentials, AuthProvider, ClientOptions, HeaderMap, RequestOptions } from './types';
|
|
6
6
|
export interface ECAPIClientConfig extends ClientOptions {
|
|
7
7
|
/** API 根地址,默认 https://api.easecation.net。 */
|
|
8
8
|
baseUrl?: string;
|
|
9
|
+
/** 动态默认认证;每次请求调用,优先于 auth 和 token 简写。 */
|
|
10
|
+
authProvider?: AuthProvider;
|
|
9
11
|
/** IAM API Key 简写;与 auth 同时存在时优先使用 auth。 */
|
|
10
12
|
apiKey?: string;
|
|
11
13
|
/** App Session Token 简写;与 auth 同时存在时优先使用 auth。 */
|
|
@@ -56,6 +58,8 @@ export declare class ECAPIClient {
|
|
|
56
58
|
request<T = unknown>(method: HttpMethod, path: string, options?: RequestOptions): Promise<T>;
|
|
57
59
|
/** 设置默认认证。 */
|
|
58
60
|
setAuth(auth?: AuthCredentials): void;
|
|
61
|
+
/** 设置动态默认认证;每次请求都会重新解析。 */
|
|
62
|
+
setAuthProvider(authProvider?: AuthProvider): void;
|
|
59
63
|
/** 清空默认认证。 */
|
|
60
64
|
clearAuth(): void;
|
|
61
65
|
/** 使用 IAM API Key 作为默认认证。 */
|
package/dist/client.js
CHANGED
|
@@ -29,6 +29,7 @@ class ECAPIClient {
|
|
|
29
29
|
this.http = new http_1.ECAPIHttpClient({
|
|
30
30
|
baseUrl: config.baseUrl,
|
|
31
31
|
auth: resolveAuth(config),
|
|
32
|
+
authProvider: config.authProvider,
|
|
32
33
|
timeoutMs: config.timeoutMs ?? config.timeout,
|
|
33
34
|
defaultHeaders: config.defaultHeaders,
|
|
34
35
|
});
|
|
@@ -63,6 +64,10 @@ class ECAPIClient {
|
|
|
63
64
|
setAuth(auth) {
|
|
64
65
|
this.http.setAuth(auth);
|
|
65
66
|
}
|
|
67
|
+
/** 设置动态默认认证;每次请求都会重新解析。 */
|
|
68
|
+
setAuthProvider(authProvider) {
|
|
69
|
+
this.http.setAuthProvider(authProvider);
|
|
70
|
+
}
|
|
66
71
|
/** 清空默认认证。 */
|
|
67
72
|
clearAuth() {
|
|
68
73
|
this.http.clearAuth();
|
package/dist/custom-fetch.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ResponseType } from './types';
|
|
1
|
+
import type { AuthProvider, ResponseType } from './types';
|
|
2
2
|
export interface CustomFetchConfig {
|
|
3
3
|
/** API 根地址;浏览器同源调用可以留空,Node.js 中建议显式配置。 */
|
|
4
4
|
baseUrl?: string;
|
|
@@ -10,6 +10,8 @@ export interface CustomFetchConfig {
|
|
|
10
10
|
bearerToken?: string;
|
|
11
11
|
/** Bearer/JWT token 的简写别名,会写入 `Authorization: Bearer ...`。 */
|
|
12
12
|
jwt?: string;
|
|
13
|
+
/** 动态默认认证;优先于静态 token 字段,每次请求前调用。 */
|
|
14
|
+
authProvider?: AuthProvider;
|
|
13
15
|
/** 请求超时时间,单位毫秒,默认 30000。 */
|
|
14
16
|
timeout?: number;
|
|
15
17
|
/** 发送到每个请求的默认 header。 */
|
package/dist/custom-fetch.js
CHANGED
|
@@ -110,7 +110,20 @@ async function parsePayload(response, responseType) {
|
|
|
110
110
|
}
|
|
111
111
|
return response.arrayBuffer();
|
|
112
112
|
}
|
|
113
|
-
function
|
|
113
|
+
function applyAuthCredentials(headers, auth) {
|
|
114
|
+
if (!auth)
|
|
115
|
+
return;
|
|
116
|
+
if (auth.type === 'apiKey' && !headers.has('X-API-Key')) {
|
|
117
|
+
headers.set('X-API-Key', auth.apiKey);
|
|
118
|
+
}
|
|
119
|
+
if (auth.type === 'appSessionToken' && !headers.has('X-App-Session-Token')) {
|
|
120
|
+
headers.set('X-App-Session-Token', auth.appSessionToken);
|
|
121
|
+
}
|
|
122
|
+
if ((auth.type === 'bearer' || auth.type === 'jwt') && !headers.has('Authorization')) {
|
|
123
|
+
headers.set('Authorization', `Bearer ${auth.token}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
function applyStaticAuth(headers, config) {
|
|
114
127
|
if (config.apiKey && !headers.has('X-API-Key')) {
|
|
115
128
|
headers.set('X-API-Key', config.apiKey);
|
|
116
129
|
}
|
|
@@ -122,6 +135,13 @@ function applyAuth(headers, config) {
|
|
|
122
135
|
headers.set('Authorization', `Bearer ${bearer}`);
|
|
123
136
|
}
|
|
124
137
|
}
|
|
138
|
+
async function applyAuth(headers, config) {
|
|
139
|
+
if (config.authProvider) {
|
|
140
|
+
applyAuthCredentials(headers, await config.authProvider());
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
applyStaticAuth(headers, config);
|
|
144
|
+
}
|
|
125
145
|
/** 配置 Orval 生成式函数默认使用的 baseUrl、认证和超时。 */
|
|
126
146
|
function configureECAPIFetch(config) {
|
|
127
147
|
globalFetchConfig = {
|
|
@@ -160,7 +180,7 @@ async function customFetch(url, config = {}, fetchConfig) {
|
|
|
160
180
|
shouldUseJsonContentType(config.body)) {
|
|
161
181
|
headers.set('Content-Type', 'application/json');
|
|
162
182
|
}
|
|
163
|
-
applyAuth(headers, effectiveConfig);
|
|
183
|
+
await applyAuth(headers, effectiveConfig);
|
|
164
184
|
const timeout = config.timeout ?? effectiveConfig.timeout ?? 30000;
|
|
165
185
|
const { signal, cleanup } = createTimeoutSignal(timeout, config.signal ?? undefined);
|
|
166
186
|
const body = serializeBody(config.body);
|
package/dist/http.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AuthCredentials, ClientOptions, RequestOptions } from './types';
|
|
1
|
+
import { AuthCredentials, AuthProvider, ClientOptions, RequestOptions } from './types';
|
|
2
2
|
import { ECAPIError } from './errors';
|
|
3
3
|
export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
4
4
|
export declare class ECAPIHttpClient {
|
|
@@ -6,11 +6,15 @@ export declare class ECAPIHttpClient {
|
|
|
6
6
|
private readonly defaultHeaders;
|
|
7
7
|
private readonly timeoutMs;
|
|
8
8
|
private auth?;
|
|
9
|
+
private authProvider?;
|
|
9
10
|
constructor(options: ClientOptions);
|
|
10
11
|
setAuth(auth?: AuthCredentials): void;
|
|
12
|
+
/** 设置动态默认认证;每次请求都会重新解析。 */
|
|
13
|
+
setAuthProvider(authProvider?: AuthProvider): void;
|
|
11
14
|
clearAuth(): void;
|
|
12
15
|
setApiKey(apiKey: string): void;
|
|
13
16
|
setAppSessionToken(appSessionToken: string): void;
|
|
17
|
+
private resolveAuth;
|
|
14
18
|
request<T = unknown>(method: HttpMethod, path: string, options?: RequestOptions): Promise<T>;
|
|
15
19
|
}
|
|
16
20
|
export { ECAPIError };
|
package/dist/http.js
CHANGED
|
@@ -45,24 +45,38 @@ class ECAPIHttpClient {
|
|
|
45
45
|
this.defaultHeaders = { ...(options.defaultHeaders || {}) };
|
|
46
46
|
this.timeoutMs = options.timeoutMs ?? 15000;
|
|
47
47
|
this.auth = options.auth;
|
|
48
|
+
this.authProvider = options.authProvider;
|
|
48
49
|
}
|
|
49
50
|
setAuth(auth) {
|
|
50
51
|
this.auth = auth;
|
|
52
|
+
this.authProvider = undefined;
|
|
53
|
+
}
|
|
54
|
+
/** 设置动态默认认证;每次请求都会重新解析。 */
|
|
55
|
+
setAuthProvider(authProvider) {
|
|
56
|
+
this.authProvider = authProvider;
|
|
51
57
|
}
|
|
52
58
|
clearAuth() {
|
|
53
59
|
this.auth = undefined;
|
|
60
|
+
this.authProvider = undefined;
|
|
54
61
|
}
|
|
55
62
|
setApiKey(apiKey) {
|
|
56
|
-
this.
|
|
63
|
+
this.setAuth({ type: 'apiKey', apiKey });
|
|
57
64
|
}
|
|
58
65
|
setAppSessionToken(appSessionToken) {
|
|
59
|
-
this.
|
|
66
|
+
this.setAuth({ type: 'appSessionToken', appSessionToken });
|
|
67
|
+
}
|
|
68
|
+
async resolveAuth(requestAuth) {
|
|
69
|
+
if (requestAuth !== undefined)
|
|
70
|
+
return requestAuth;
|
|
71
|
+
if (this.authProvider)
|
|
72
|
+
return this.authProvider();
|
|
73
|
+
return this.auth;
|
|
60
74
|
}
|
|
61
75
|
async request(method, path, options = {}) {
|
|
62
76
|
const requestPath = path.startsWith('/') ? path : `/${path}`;
|
|
63
77
|
const queryString = toQueryString(options.query);
|
|
64
78
|
const url = `${requestPath}${queryString}`;
|
|
65
|
-
const resolvedAuth =
|
|
79
|
+
const resolvedAuth = await this.resolveAuth(options.auth);
|
|
66
80
|
const fetchConfig = {
|
|
67
81
|
baseUrl: this.baseUrl,
|
|
68
82
|
timeout: this.timeoutMs,
|
package/dist/types.d.ts
CHANGED
|
@@ -98,6 +98,10 @@ export type AuthCredentials = {
|
|
|
98
98
|
type: 'jwt';
|
|
99
99
|
token: string;
|
|
100
100
|
};
|
|
101
|
+
/** 动态认证提供器的解析结果;null/undefined 表示本次不发送认证。 */
|
|
102
|
+
export type AuthProviderResult = AuthCredentials | null | undefined;
|
|
103
|
+
/** 每次请求前解析的动态认证提供器,适合 IAM callback / STS 短期凭证。 */
|
|
104
|
+
export type AuthProvider = () => AuthProviderResult | Promise<AuthProviderResult>;
|
|
101
105
|
/** 统一成功响应 envelope。 */
|
|
102
106
|
export interface ApiEnvelope<T = unknown> {
|
|
103
107
|
success: true;
|
|
@@ -130,6 +134,8 @@ export interface ClientOptions {
|
|
|
130
134
|
baseUrl?: string;
|
|
131
135
|
/** 默认认证信息;单次请求可通过 RequestOptions.auth 覆盖。 */
|
|
132
136
|
auth?: AuthCredentials;
|
|
137
|
+
/** 动态默认认证;优先于 auth,返回 null/undefined 表示不发送认证。 */
|
|
138
|
+
authProvider?: AuthProvider;
|
|
133
139
|
/** 请求超时时间,单位毫秒,默认 15000。 */
|
|
134
140
|
timeoutMs?: number;
|
|
135
141
|
/** 合并到每个请求中的默认 header。 */
|
|
@@ -147,6 +153,6 @@ export interface RequestOptions {
|
|
|
147
153
|
signal?: AbortSignal;
|
|
148
154
|
/** 当前请求的响应解析模式。 */
|
|
149
155
|
responseType?: ResponseType;
|
|
150
|
-
/** 覆盖客户端默认认证;传 null
|
|
156
|
+
/** 覆盖客户端默认认证;传 null 表示当前请求不发送认证且不会调用 authProvider。 */
|
|
151
157
|
auth?: AuthCredentials | null;
|
|
152
158
|
}
|