@snail-js/api 0.1.22 → 0.1.23
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 +40 -39
- package/README_EN.md +34 -19
- package/dist/core/snailMethod.d.ts +4 -4
- package/dist/core/snailServer.d.ts +4 -4
- package/dist/decorators/api.d.ts +0 -36
- package/dist/decorators/method.d.ts +38 -0
- package/dist/index.d.ts +2 -1
- package/dist/snail-api.js +116 -111
- package/dist/snail-api.umd.cjs +116 -111
- package/dist/typings/api.option.d.ts +0 -6
- package/dist/typings/apiProxy.d.ts +6 -10
- package/dist/typings/index.d.ts +0 -1
- package/dist/typings/response.data.d.ts +1 -2
- package/dist/typings/snail.method.d.ts +14 -3
- package/dist/typings/snail.option.d.ts +2 -2
- package/package.json +1 -1
- package/dist/typings/request.method.d.ts +0 -10
package/README.md
CHANGED
|
@@ -60,7 +60,7 @@ export const Service = new BackEnd();
|
|
|
60
60
|
|
|
61
61
|
```typescript
|
|
62
62
|
// user.ts
|
|
63
|
-
import { Api, Get, Post, Query, Data,SnailApi } from "@snail-js/api";
|
|
63
|
+
import { Api, Get, Post, Query, Data, SnailApi } from "@snail-js/api";
|
|
64
64
|
|
|
65
65
|
import { Service } from "./service";
|
|
66
66
|
|
|
@@ -81,40 +81,38 @@ export const userApi = Service.createApi(UserApi);
|
|
|
81
81
|
```typescript
|
|
82
82
|
import { userApi } from "./user";
|
|
83
83
|
|
|
84
|
-
const getUser = await userApi.get(
|
|
85
|
-
|
|
86
|
-
const data = await
|
|
84
|
+
const { send:getUser, onSuccess, onError, onHitCache } = await userApi.get();
|
|
85
|
+
|
|
86
|
+
const data = await getUser("1");
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
## `SnailMethod` 实例
|
|
90
|
+
|
|
90
91
|
- 调用`Service.createApi(ApiInstance)`后会为`ApiInstance`内被`RequestMethod`(如:@Get、@Post...)装饰的方法创建一个代理,返回一个函数,此函数包含请求参数,调用此函数返回`SnailMethod` 实例
|
|
91
92
|
|
|
92
93
|
### `SnailMethod` 实例方法
|
|
93
94
|
|
|
94
95
|
- `send` 发送请求
|
|
95
|
-
|
|
96
|
+
_异步函数,发送当前请求_
|
|
96
97
|
- `onSuccess` 请求成功回调
|
|
97
|
-
|
|
98
|
+
_注册请求成功事件_
|
|
98
99
|
- `onError` 请求失败回调
|
|
99
|
-
|
|
100
|
+
_注册请求失败事件_
|
|
100
101
|
- `onHitCache` 请求命中缓存回调
|
|
101
|
-
|
|
102
|
+
_注册请求命中缓存事件_
|
|
102
103
|
- `onFinish` 请求完成回调
|
|
103
|
-
|
|
104
|
-
- `
|
|
105
|
-
|
|
106
|
-
- `emit` 触发事件
|
|
107
|
-
_触发自定义事件_
|
|
108
|
-
- `off` 取消监听事件
|
|
109
|
-
_取消自定义事件监听_
|
|
104
|
+
_注册请求完成事件_
|
|
105
|
+
- `registerStrategies` 注册策略
|
|
106
|
+
_注册方法级策略_
|
|
110
107
|
|
|
111
108
|
|
|
112
109
|
### `SnailMethod` 实例属性
|
|
110
|
+
|
|
113
111
|
- response : AxiosResponse
|
|
114
|
-
- request : AxiosRequestConfig ,最终请求的request,这个request是被Versioning和Strategy处理过的
|
|
115
|
-
- version : string,最终请求的版本,如果没有开启Versioning则为undefine
|
|
116
|
-
- name : string,完整的SnailMethod名称,格式为`ServerName.ApiName.MethodName`
|
|
117
|
-
- error : Error | null,请求失败的错误信息,无错误为null
|
|
112
|
+
- request : AxiosRequestConfig ,最终请求的 request,这个 request 是被 Versioning 和 Strategy 处理过的
|
|
113
|
+
- version : string,最终请求的版本,如果没有开启 Versioning 则为 undefine
|
|
114
|
+
- name : string,完整的 SnailMethod 名称,格式为`ServerName.ApiName.MethodName`
|
|
115
|
+
- error : Error | null,请求失败的错误信息,无错误为 null
|
|
118
116
|
|
|
119
117
|
### Server 配置
|
|
120
118
|
|
|
@@ -188,7 +186,8 @@ const data = await send();
|
|
|
188
186
|
</table>
|
|
189
187
|
|
|
190
188
|
### Api 配置
|
|
191
|
-
|
|
189
|
+
|
|
190
|
+
- 请使用`@Api()`装饰自定义 Api 类并继承`SnailApi`
|
|
192
191
|
|
|
193
192
|
<table>
|
|
194
193
|
<tr>
|
|
@@ -305,7 +304,7 @@ class UserApi {
|
|
|
305
304
|
### 请求策略
|
|
306
305
|
|
|
307
306
|
- 在请求发送前执行,后面的策略返回结果会覆盖前面的策略
|
|
308
|
-
- 若返回处理后的request,则使用处理后的 request 发送请求,否则使用原始 request 或上一个策略返回的request发送请求
|
|
307
|
+
- 若返回处理后的 request,则使用处理后的 request 发送请求,否则使用原始 request 或上一个策略返回的 request 发送请求
|
|
309
308
|
|
|
310
309
|
```typescript
|
|
311
310
|
class CustomStrategy extends Strategy {
|
|
@@ -346,15 +345,16 @@ class Test {
|
|
|
346
345
|
// 发送请求前注册策略
|
|
347
346
|
const TestApi = Service.createApi(Test);
|
|
348
347
|
const getSomething = TestApi.get();
|
|
349
|
-
getSomething.registerStrategies(CustomStrategy);
|
|
350
348
|
{ send, registerStrategies } = getSomething;
|
|
349
|
+
getSomething.registerStrategies(CustomStrategy);
|
|
350
|
+
|
|
351
351
|
|
|
352
352
|
```
|
|
353
353
|
|
|
354
354
|
### 响应策略
|
|
355
355
|
|
|
356
356
|
- 在收到服务器响应后执行
|
|
357
|
-
- 若返回处理后的response,则使用处理后的response进行下一个策略或返回,否则使用原始response或上一个策略返回的response返回
|
|
357
|
+
- 若返回处理后的 response,则使用处理后的 response 进行下一个策略或返回,否则使用原始 response 或上一个策略返回的 response 返回
|
|
358
358
|
|
|
359
359
|
```typescript
|
|
360
360
|
// 如何定义
|
|
@@ -465,11 +465,11 @@ class Test {
|
|
|
465
465
|
|
|
466
466
|
- `@HitSource(name:string)`
|
|
467
467
|
- 为被装饰的方法设置缓存失效源,当设置的名称方法被调用且正常响应时,被装饰的方法缓存失效
|
|
468
|
-
- name格式为:`serverName:apiName:methodName`
|
|
469
|
-
> 注意:若您配置了SnailServer/SnailApi的name选项,请使用此name作为名称,否则使用类名作为名称
|
|
468
|
+
- name 格式为:`serverName:apiName:methodName`
|
|
469
|
+
> 注意:若您配置了 SnailServer/SnailApi 的 name 选项,请使用此 name 作为名称,否则使用类名作为名称
|
|
470
470
|
|
|
471
471
|
```typescript
|
|
472
|
-
@Api("test",{name:
|
|
472
|
+
@Api("test", { name: "api1" })
|
|
473
473
|
@HitSource("api1")
|
|
474
474
|
class Test {
|
|
475
475
|
@Get("HelloWorld")
|
|
@@ -487,7 +487,7 @@ class Test {
|
|
|
487
487
|
```
|
|
488
488
|
|
|
489
489
|
> 当请求`[Post]test`成功时,`[Get]test/HelloWorld`的缓存失效
|
|
490
|
-
> 默认仅Get方法会进行缓存ing缓存,若要开启其他方法的缓存,请使用`@Server({cacheFor:'all'})`配置
|
|
490
|
+
> 默认仅 Get 方法会进行缓存 ing 缓存,若要开启其他方法的缓存,请使用`@Server({cacheFor:'all'})`配置
|
|
491
491
|
|
|
492
492
|
> `test3`方法请求成功时,不缓存
|
|
493
493
|
|
|
@@ -611,10 +611,10 @@ class User {
|
|
|
611
611
|
age: number;
|
|
612
612
|
}
|
|
613
613
|
|
|
614
|
-
const getUser = userApi.get<User>(
|
|
614
|
+
const getUser = userApi.get<User>();
|
|
615
615
|
const { send } = getUser;
|
|
616
616
|
|
|
617
|
-
const res = await send();
|
|
617
|
+
const res = await send("1");
|
|
618
618
|
|
|
619
619
|
// 默认情况,以data为key存储数据
|
|
620
620
|
// res.data => CustomResponse & { data : User}
|
|
@@ -623,15 +623,15 @@ const res = await send();
|
|
|
623
623
|
> API 被调用的返回格式
|
|
624
624
|
|
|
625
625
|
```typescript
|
|
626
|
-
const getUser = userApi.get<User>(
|
|
626
|
+
const getUser = userApi.get<User>();
|
|
627
627
|
const { send } = getUser;
|
|
628
|
-
const res = await send();
|
|
628
|
+
const res = await send("1");
|
|
629
629
|
|
|
630
630
|
// res.data => CustomResponse & { data: User }
|
|
631
631
|
|
|
632
|
-
const getUser = userApi.get<Blob>(
|
|
632
|
+
const getUser = userApi.get<Blob>();
|
|
633
633
|
const { send } = getUser;
|
|
634
|
-
const res = await send();
|
|
634
|
+
const res = await send("1");
|
|
635
635
|
// res => AxiosResponse<Blob>
|
|
636
636
|
```
|
|
637
637
|
|
|
@@ -648,16 +648,17 @@ const res = await send();
|
|
|
648
648
|
baseURL: "/api",
|
|
649
649
|
timeout: 5000,
|
|
650
650
|
})
|
|
651
|
-
class BackEnd extends Snail<CustomResponse, "
|
|
651
|
+
class BackEnd extends Snail<CustomResponse, "records"> {}
|
|
652
652
|
|
|
653
|
-
const res = await userApi.get<User>(
|
|
653
|
+
const res = await userApi.get<User>();
|
|
654
654
|
// 自定义数据key
|
|
655
|
-
// res.data => CustomResponse & {
|
|
655
|
+
// res.data => CustomResponse & { records : User}
|
|
656
656
|
```
|
|
657
657
|
|
|
658
|
-
### 非json数据的返回
|
|
659
|
-
|
|
660
|
-
- 若后端返回的content-type
|
|
658
|
+
### 非 json 数据的返回
|
|
659
|
+
|
|
660
|
+
- 若后端返回的 content-type 不是 json 类型,send 方法返回的将是`AxiosResponse`
|
|
661
|
+
- 若后端返回的 content-type 是 json 类型,send 方法返回的将是`AxiosResponse.data`
|
|
661
662
|
|
|
662
663
|
### 代码仓库
|
|
663
664
|
|
package/README_EN.md
CHANGED
|
@@ -80,9 +80,9 @@ export const userApi = Service.createApi(UserApi);
|
|
|
80
80
|
```ts
|
|
81
81
|
import { userApi } from "./user";
|
|
82
82
|
|
|
83
|
-
const getUser = await userApi.get(
|
|
84
|
-
|
|
85
|
-
const data = await
|
|
83
|
+
const { send:getUser, onSuccess, onError, onHitCache } = await userApi.get();
|
|
84
|
+
|
|
85
|
+
const data = await getUser("1");
|
|
86
86
|
```
|
|
87
87
|
|
|
88
88
|
## `SnailMethod` Instance
|
|
@@ -102,13 +102,8 @@ const data = await send();
|
|
|
102
102
|
_Register cache hit event handler_
|
|
103
103
|
- `onFinish`: Request completion callback
|
|
104
104
|
_Register completion event handler (fires on both success/error)_
|
|
105
|
-
- `
|
|
106
|
-
_Register
|
|
107
|
-
_Register custom event handlers_
|
|
108
|
-
- `emit`: Trigger custom events
|
|
109
|
-
_Emit custom events_
|
|
110
|
-
- `off`: Remove event listeners
|
|
111
|
-
_Unregister custom event handlers_
|
|
105
|
+
- `registerStrategies` Register Strategies
|
|
106
|
+
_Register Strategies of this method instance_
|
|
112
107
|
|
|
113
108
|
### `SnailMethod` Properties
|
|
114
109
|
- `response`: AxiosResponse - Raw response object
|
|
@@ -172,6 +167,13 @@ const data = await send();
|
|
|
172
167
|
<td>Get</td>
|
|
173
168
|
<td>Methods to enable caching</td>
|
|
174
169
|
</tr>
|
|
170
|
+
<tr>
|
|
171
|
+
<td>serverStatusCodeRule</td>
|
|
172
|
+
<td><a href="#SnailServerStatusCodeRuleOptions">SnailServerStatusCodeRuleOptions</a></td>
|
|
173
|
+
<td>否</td>
|
|
174
|
+
<td>undefined</td>
|
|
175
|
+
<td>Server status code validation rules (triggers error when rule function returns false)</td>
|
|
176
|
+
</tr>
|
|
175
177
|
<tr>
|
|
176
178
|
<td>enableLog</td>
|
|
177
179
|
<td>boolean</td>
|
|
@@ -303,8 +305,9 @@ class Test {
|
|
|
303
305
|
// Register strategy before request
|
|
304
306
|
const TestApi = Service.createApi(Test);
|
|
305
307
|
const getSomething = TestApi.get();
|
|
306
|
-
getSomething.registerStrategies(CustomStrategy);
|
|
307
308
|
{ send, registerStrategies } = getSomething;
|
|
309
|
+
registerStrategies(CustomStrategy);
|
|
310
|
+
|
|
308
311
|
```
|
|
309
312
|
|
|
310
313
|
### Response Strategy
|
|
@@ -385,6 +388,18 @@ export type VersioningOption =
|
|
|
385
388
|
| VersioningCustomOption;
|
|
386
389
|
```
|
|
387
390
|
|
|
391
|
+
### <a id="SnailServerStatusCodeRuleOptions">SnailServerStatusCodeRuleOptions</a> Type
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
export class SnailServerStatusCodeRuleOptions {
|
|
395
|
+
// Defines validation rules for server status codes
|
|
396
|
+
// Triggers error when rule function returns false
|
|
397
|
+
rule: (statusCode: number) => boolean;
|
|
398
|
+
// Specifies the key in response.data for status code (default: 'code')
|
|
399
|
+
key?: string;
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
388
403
|
### Temporary Version Modifier @Version
|
|
389
404
|
- Override version for specific methods
|
|
390
405
|
```typescript
|
|
@@ -533,10 +548,10 @@ class User {
|
|
|
533
548
|
age: number;
|
|
534
549
|
}
|
|
535
550
|
|
|
536
|
-
const getUser = userApi.get<User>(
|
|
551
|
+
const getUser = userApi.get<User>();
|
|
537
552
|
const { send } = getUser;
|
|
538
553
|
|
|
539
|
-
const res = await send();
|
|
554
|
+
const res = await send("1");
|
|
540
555
|
|
|
541
556
|
// Default data key:
|
|
542
557
|
// res.data => CustomResponse & { data: User }
|
|
@@ -544,15 +559,15 @@ const res = await send();
|
|
|
544
559
|
|
|
545
560
|
> API response format:
|
|
546
561
|
```typescript
|
|
547
|
-
const getUser = userApi.get<User>(
|
|
562
|
+
const getUser = userApi.get<User>();
|
|
548
563
|
const { send } = getUser;
|
|
549
|
-
const res = await send();
|
|
564
|
+
const res = await send("1");
|
|
550
565
|
|
|
551
566
|
// res.data => CustomResponse & { data: User }
|
|
552
567
|
|
|
553
|
-
const getUser = userApi.get<Blob>(
|
|
568
|
+
const getUser = userApi.get<Blob>();
|
|
554
569
|
const { send } = getUser;
|
|
555
|
-
const res = await send();
|
|
570
|
+
const res = await send("1");
|
|
556
571
|
// res => AxiosResponse<Blob>
|
|
557
572
|
```
|
|
558
573
|
|
|
@@ -565,8 +580,8 @@ const res = await send();
|
|
|
565
580
|
})
|
|
566
581
|
class BackEnd extends Snail<CustomResponse, "record"> {}
|
|
567
582
|
|
|
568
|
-
const { send } = userApi.get<User>(
|
|
569
|
-
const res = await send();
|
|
583
|
+
const { send } = userApi.get<User>();
|
|
584
|
+
const res = await send("1");
|
|
570
585
|
// Custom data key:
|
|
571
586
|
// res.data => CustomResponse & { record: User }
|
|
572
587
|
```
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AxiosResponse, AxiosRequestConfig } from "axios";
|
|
2
|
-
import { Strategy, ResponseData,
|
|
2
|
+
import { Strategy, ResponseData, StandardResponseData, SnailSuccessListener, SnailErrorListener, SnailHitCacheListener, SnailFinishListener } from "../typings";
|
|
3
3
|
import { SnailApi } from "./snailApi";
|
|
4
4
|
/**
|
|
5
5
|
* SnailMethod
|
|
@@ -19,10 +19,10 @@ export declare class SnailMethod<RT extends ResponseData = StandardResponseData>
|
|
|
19
19
|
private Url;
|
|
20
20
|
private Path;
|
|
21
21
|
private Method;
|
|
22
|
+
private Adapter;
|
|
22
23
|
private Version?;
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
send: SendRequest<RT>;
|
|
24
|
+
constructor(apiInstance: SnailApi, target: Object, propertyKey: string | symbol);
|
|
25
|
+
send: (...args: any) => Promise<unknown>;
|
|
26
26
|
private init;
|
|
27
27
|
private initUrl;
|
|
28
28
|
private initVersion;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
import "reflect-metadata";
|
|
2
2
|
import { AxiosInstance } from "axios";
|
|
3
|
-
import { Strategy, ApiInstanceOptions, VersioningOption, CacheStorage, ApiProxy,
|
|
3
|
+
import { Strategy, ApiInstanceOptions, VersioningOption, CacheStorage, ApiProxy, StandardResponseWithoutData, SnailServerStatusCodeRuleOptions, ResponseJsonData } from "../typings";
|
|
4
4
|
import { SnailApi } from "./snailApi";
|
|
5
5
|
import { SnailSse } from "./snailSse";
|
|
6
6
|
export declare const CacheStorageMap: Map<string, CacheStorage>;
|
|
7
7
|
export declare const CacheTtlMap: Map<string, number>;
|
|
8
|
-
export declare const CacheForMap: Map<string,
|
|
8
|
+
export declare const CacheForMap: Map<string, string[]>;
|
|
9
9
|
export declare const ExpireSourceMap: Map<string, Set<string>>;
|
|
10
10
|
export declare const AxiosInstanceMap: Map<string, AxiosInstance>;
|
|
11
11
|
export declare const StrategyMap: Map<string, (new () => Strategy)[]>;
|
|
12
12
|
export declare const VersioningMap: Map<string, VersioningOption>;
|
|
13
13
|
export declare const ServerStatusCodeRuleMap: Map<string, SnailServerStatusCodeRuleOptions>;
|
|
14
|
-
export declare class SnailServer<RT extends
|
|
14
|
+
export declare class SnailServer<RT extends StandardResponseWithoutData | ResponseJsonData = StandardResponseWithoutData, DK extends string = "data"> {
|
|
15
15
|
private Name;
|
|
16
16
|
private BaseURL;
|
|
17
17
|
private Version;
|
|
@@ -23,7 +23,7 @@ export declare class SnailServer<RT extends ResponseData = Omit<StandardResponse
|
|
|
23
23
|
private initStrategy;
|
|
24
24
|
private initVersioning;
|
|
25
25
|
registerStrategies: (...strategys: Array<new () => Strategy>) => void;
|
|
26
|
-
createApi<
|
|
26
|
+
createApi<TApiClass extends SnailApi>(constructor: new (options: ApiInstanceOptions) => TApiClass): ApiProxy<TApiClass, RT, DK>;
|
|
27
27
|
private initCacheManage;
|
|
28
28
|
private initExpireSource;
|
|
29
29
|
private initAxios;
|
package/dist/decorators/api.d.ts
CHANGED
|
@@ -1,40 +1,4 @@
|
|
|
1
1
|
import "reflect-metadata";
|
|
2
2
|
import { ApiOptions } from "../typings";
|
|
3
|
-
export declare const METHOD_KEY: unique symbol;
|
|
4
3
|
export declare const API_CONFIG_KEY: unique symbol;
|
|
5
4
|
export declare const Api: (url?: string, config?: ApiOptions) => ClassDecorator;
|
|
6
|
-
/**
|
|
7
|
-
* 定义装饰的方法为Get请求
|
|
8
|
-
* @param path 字符型,请求端点,默认为空
|
|
9
|
-
*/
|
|
10
|
-
export declare const Get: (path?: string, name?: string) => (target: any, propertyKey: string | symbol) => void;
|
|
11
|
-
/**
|
|
12
|
-
* 定义装饰的方法为Post请求
|
|
13
|
-
* @param path 字符型,请求端点,默认为空
|
|
14
|
-
*/
|
|
15
|
-
export declare const Post: (path?: string, name?: string) => (target: any, propertyKey: string | symbol) => void;
|
|
16
|
-
/**
|
|
17
|
-
* 定义装饰的方法为Put请求
|
|
18
|
-
* @param path 字符型,请求端点,默认为空
|
|
19
|
-
*/
|
|
20
|
-
export declare const Put: (path?: string, name?: string) => (target: any, propertyKey: string | symbol) => void;
|
|
21
|
-
/**
|
|
22
|
-
* 定义装饰的方法为Delete请求
|
|
23
|
-
* @param path 字符型,请求端点,默认为空
|
|
24
|
-
*/
|
|
25
|
-
export declare const Delete: (path?: string, name?: string) => (target: any, propertyKey: string | symbol) => void;
|
|
26
|
-
/**
|
|
27
|
-
* 定义装饰的方法为Patch请求
|
|
28
|
-
* @param path 字符型,请求端点,默认为空
|
|
29
|
-
*/
|
|
30
|
-
export declare const Patch: (path?: string, name?: string) => (target: any, propertyKey: string | symbol) => void;
|
|
31
|
-
/**
|
|
32
|
-
* 定义装饰的方法为Options请求
|
|
33
|
-
* @param path 字符型,请求端点,默认为空
|
|
34
|
-
*/
|
|
35
|
-
export declare const Options: (path?: string, name?: string) => (target: any, propertyKey: string | symbol) => void;
|
|
36
|
-
/**
|
|
37
|
-
* 定义装饰的方法为Head请求
|
|
38
|
-
* @param path 字符型,请求端点,默认为空
|
|
39
|
-
*/
|
|
40
|
-
export declare const Head: (path?: string, name?: string) => (target: any, propertyKey: string | symbol) => void;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
import { MethodSendOptions } from "../typings";
|
|
3
|
+
export declare const METHOD_KEY: unique symbol;
|
|
4
|
+
/**
|
|
5
|
+
* 定义装饰的方法为Get请求
|
|
6
|
+
* @param path 字符型,请求端点,默认为空
|
|
7
|
+
*/
|
|
8
|
+
export declare const Get: (path?: string, options?: MethodSendOptions) => (target: any, propertyKey: string | symbol) => void;
|
|
9
|
+
/**
|
|
10
|
+
* 定义装饰的方法为Post请求
|
|
11
|
+
* @param path 字符型,请求端点,默认为空
|
|
12
|
+
*/
|
|
13
|
+
export declare const Post: (path?: string, options?: MethodSendOptions) => (target: any, propertyKey: string | symbol) => void;
|
|
14
|
+
/**
|
|
15
|
+
* 定义装饰的方法为Put请求
|
|
16
|
+
* @param path 字符型,请求端点,默认为空
|
|
17
|
+
*/
|
|
18
|
+
export declare const Put: (path?: string, options?: MethodSendOptions) => (target: any, propertyKey: string | symbol) => void;
|
|
19
|
+
/**
|
|
20
|
+
* 定义装饰的方法为Delete请求
|
|
21
|
+
* @param path 字符型,请求端点,默认为空
|
|
22
|
+
*/
|
|
23
|
+
export declare const Delete: (path?: string, options?: MethodSendOptions) => (target: any, propertyKey: string | symbol) => void;
|
|
24
|
+
/**
|
|
25
|
+
* 定义装饰的方法为Patch请求
|
|
26
|
+
* @param path 字符型,请求端点,默认为空
|
|
27
|
+
*/
|
|
28
|
+
export declare const Patch: (path?: string, options?: MethodSendOptions) => (target: any, propertyKey: string | symbol) => void;
|
|
29
|
+
/**
|
|
30
|
+
* 定义装饰的方法为Options请求
|
|
31
|
+
* @param path 字符型,请求端点,默认为空
|
|
32
|
+
*/
|
|
33
|
+
export declare const Options: (path?: string, options?: MethodSendOptions) => (target: any, propertyKey: string | symbol) => void;
|
|
34
|
+
/**
|
|
35
|
+
* 定义装饰的方法为Head请求
|
|
36
|
+
* @param path 字符型,请求端点,默认为空
|
|
37
|
+
*/
|
|
38
|
+
export declare const Head: (path?: string, options?: MethodSendOptions) => (target: any, propertyKey: string | symbol) => void;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export * from "./core";
|
|
2
2
|
export { Server } from "./decorators/server";
|
|
3
|
-
export { Api
|
|
3
|
+
export { Api } from "./decorators/api";
|
|
4
|
+
export { Get, Put, Post, Patch, Options, Head, Delete, } from "./decorators/method";
|
|
4
5
|
export { NoCache, HitSource } from "./decorators/cache";
|
|
5
6
|
export { Params, Data, Query } from "./decorators/args";
|
|
6
7
|
export { UseStrategy } from "./decorators/strategy";
|
package/dist/snail-api.js
CHANGED
|
@@ -3717,16 +3717,6 @@ class IndexDBCache {
|
|
|
3717
3717
|
});
|
|
3718
3718
|
}
|
|
3719
3719
|
}
|
|
3720
|
-
var RequestMethodEnum = /* @__PURE__ */ ((RequestMethodEnum2) => {
|
|
3721
|
-
RequestMethodEnum2["GET"] = "Get";
|
|
3722
|
-
RequestMethodEnum2["HEAD"] = "Head";
|
|
3723
|
-
RequestMethodEnum2["POST"] = "Post";
|
|
3724
|
-
RequestMethodEnum2["PUT"] = "Put";
|
|
3725
|
-
RequestMethodEnum2["DELETE"] = "delete";
|
|
3726
|
-
RequestMethodEnum2["PATCH"] = "Patch";
|
|
3727
|
-
RequestMethodEnum2["OPTIONS"] = "Options";
|
|
3728
|
-
return RequestMethodEnum2;
|
|
3729
|
-
})(RequestMethodEnum || {});
|
|
3730
3720
|
class SnailServerStatusCodeRuleOptions {
|
|
3731
3721
|
constructor() {
|
|
3732
3722
|
__publicField(this, "key");
|
|
@@ -3884,14 +3874,8 @@ function isSpecialResponse(response) {
|
|
|
3884
3874
|
return !contentType.includes("application/json");
|
|
3885
3875
|
}
|
|
3886
3876
|
const METHOD_KEY = Symbol("SNAIL_METHOD_KEY");
|
|
3887
|
-
const API_CONFIG_KEY = Symbol("SNAIL_API_CONFIG_KEY");
|
|
3888
|
-
const Api = (url = "", config) => {
|
|
3889
|
-
return (target) => {
|
|
3890
|
-
Reflect.defineMetadata(API_CONFIG_KEY, { url, ...config }, target);
|
|
3891
|
-
};
|
|
3892
|
-
};
|
|
3893
3877
|
const createMethodDecorator = (method) => {
|
|
3894
|
-
return (path = "",
|
|
3878
|
+
return (path = "", options) => {
|
|
3895
3879
|
return (target, propertyKey) => {
|
|
3896
3880
|
const methodOptions = Reflect.getMetadata(
|
|
3897
3881
|
METHOD_KEY,
|
|
@@ -3900,25 +3884,29 @@ const createMethodDecorator = (method) => {
|
|
|
3900
3884
|
);
|
|
3901
3885
|
if (methodOptions) {
|
|
3902
3886
|
console.error("only one method decorator for a request function!");
|
|
3903
|
-
console.error(
|
|
3904
|
-
|
|
3887
|
+
console.error(
|
|
3888
|
+
`you must chose only one method decorator[@${method} or @${methodOptions.method}]`
|
|
3889
|
+
);
|
|
3890
|
+
throw new TypeError(
|
|
3891
|
+
`Multiple decorators are used for the same request function`
|
|
3892
|
+
);
|
|
3905
3893
|
}
|
|
3906
3894
|
Reflect.defineMetadata(
|
|
3907
3895
|
METHOD_KEY,
|
|
3908
|
-
{ method, path,
|
|
3896
|
+
{ method, path, ...options },
|
|
3909
3897
|
target,
|
|
3910
3898
|
propertyKey
|
|
3911
3899
|
);
|
|
3912
3900
|
};
|
|
3913
3901
|
};
|
|
3914
3902
|
};
|
|
3915
|
-
const Get = createMethodDecorator(
|
|
3916
|
-
const Post = createMethodDecorator(
|
|
3917
|
-
const Put = createMethodDecorator(
|
|
3918
|
-
const Delete = createMethodDecorator(
|
|
3919
|
-
const Patch = createMethodDecorator(
|
|
3920
|
-
const Options = createMethodDecorator(
|
|
3921
|
-
const Head = createMethodDecorator(
|
|
3903
|
+
const Get = createMethodDecorator("GET");
|
|
3904
|
+
const Post = createMethodDecorator("POST");
|
|
3905
|
+
const Put = createMethodDecorator("PUT");
|
|
3906
|
+
const Delete = createMethodDecorator("DELETE");
|
|
3907
|
+
const Patch = createMethodDecorator("PATCH");
|
|
3908
|
+
const Options = createMethodDecorator("OPTIONS");
|
|
3909
|
+
const Head = createMethodDecorator("HEAD");
|
|
3922
3910
|
const SERVER_CONFIG_KEY = Symbol("SANIL_SERVER_CONFIG_KEY");
|
|
3923
3911
|
const Server = (config) => {
|
|
3924
3912
|
return (target) => {
|
|
@@ -4060,7 +4048,8 @@ function applyVersioning(version, versioning) {
|
|
|
4060
4048
|
const UPLOAD_PROGRESS_KEY = Symbol("SNAIL_UPLOAD_PROGRESS_KEY");
|
|
4061
4049
|
const DOWNLOAD_PROGRESS_KEY = Symbol("SNAIL_DOWNLOAD_PROGRESS_KEY");
|
|
4062
4050
|
class SnailMethod {
|
|
4063
|
-
|
|
4051
|
+
// private Args: any[] = [];
|
|
4052
|
+
constructor(apiInstance, target, propertyKey) {
|
|
4064
4053
|
// 私有属性
|
|
4065
4054
|
// private serverInstance: SnailServer;
|
|
4066
4055
|
__publicField(this, "Name");
|
|
@@ -4076,87 +4065,93 @@ class SnailMethod {
|
|
|
4076
4065
|
__publicField(this, "propertyKey");
|
|
4077
4066
|
__publicField(this, "Url", "");
|
|
4078
4067
|
__publicField(this, "Path", "");
|
|
4079
|
-
__publicField(this, "Method",
|
|
4068
|
+
__publicField(this, "Method", "GET");
|
|
4069
|
+
__publicField(this, "Adapter");
|
|
4080
4070
|
__publicField(this, "Version");
|
|
4081
|
-
__publicField(this, "
|
|
4082
|
-
__publicField(this, "send", async () => {
|
|
4071
|
+
__publicField(this, "send", (...args) => {
|
|
4083
4072
|
this.enableLog() && console.log("send:", this.name);
|
|
4084
4073
|
const [serverName] = this.apiInstance.name.split(".");
|
|
4085
4074
|
const axios2 = AxiosInstanceMap.get(serverName);
|
|
4086
4075
|
if (!axios2) throw new Error("AxiosInstance not created");
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
const newUrl = replacePlaceholders(this.Url, params);
|
|
4098
|
-
this.Request = {
|
|
4099
|
-
...this.Request,
|
|
4100
|
-
url: newUrl,
|
|
4101
|
-
params: {
|
|
4102
|
-
...this.Request.params,
|
|
4103
|
-
...querys
|
|
4104
|
-
},
|
|
4105
|
-
data
|
|
4106
|
-
};
|
|
4107
|
-
this.enableLog() && console.log("request:", this.Request);
|
|
4108
|
-
const isNoCache = this.isNoCache();
|
|
4109
|
-
this.enableLog() && console.log("method is noCache:", isNoCache);
|
|
4110
|
-
if (!isNoCache) {
|
|
4111
|
-
const { data: data2 } = await this.getCacheData(serverName);
|
|
4112
|
-
this.enableLog() && console.log("getCacheData:", data2);
|
|
4113
|
-
if (data2) {
|
|
4114
|
-
this.EventEmit.emit("hitCache", data2);
|
|
4115
|
-
this.EventEmit.emit("success", data2);
|
|
4116
|
-
this.EventEmit.emit("finish", data2);
|
|
4117
|
-
return data2;
|
|
4118
|
-
}
|
|
4119
|
-
}
|
|
4120
|
-
const requester = AxiosInstanceMap.get(serverName);
|
|
4121
|
-
if (!requester) throw new Error("AxiosInstance not created");
|
|
4122
|
-
try {
|
|
4123
|
-
const rawResponse = await requester.request(this.Request);
|
|
4124
|
-
const isSpecial = isSpecialResponse(rawResponse);
|
|
4125
|
-
const response = await applyStrategies(
|
|
4126
|
-
rawResponse,
|
|
4127
|
-
strategies,
|
|
4128
|
-
"response"
|
|
4076
|
+
return new Promise(async (resolve, reject) => {
|
|
4077
|
+
const serverStatusCodeRule = ServerStatusCodeRuleMap.get(serverName);
|
|
4078
|
+
const strategies = this.getStrategies();
|
|
4079
|
+
this.Request = await applyStrategies(this.Request, strategies, "request");
|
|
4080
|
+
this.Request = this.applyProgress(this.Request);
|
|
4081
|
+
const { data, querys, params } = buildRequestArgs(
|
|
4082
|
+
this.target,
|
|
4083
|
+
this.propertyKey,
|
|
4084
|
+
// this.Args
|
|
4085
|
+
args
|
|
4129
4086
|
);
|
|
4087
|
+
this.enableLog() && console.log("methodUrl:", this.Request.baseURL, this.Request.url);
|
|
4088
|
+
const newUrl = replacePlaceholders(this.Url, params);
|
|
4089
|
+
this.Request = {
|
|
4090
|
+
...this.Request,
|
|
4091
|
+
url: newUrl,
|
|
4092
|
+
params: {
|
|
4093
|
+
...this.Request.params,
|
|
4094
|
+
...querys
|
|
4095
|
+
},
|
|
4096
|
+
data
|
|
4097
|
+
};
|
|
4098
|
+
this.enableLog() && console.log("request:", this.Request);
|
|
4099
|
+
const isNoCache = this.isNoCache();
|
|
4100
|
+
this.enableLog() && console.log("method is noCache:", isNoCache);
|
|
4130
4101
|
if (!isNoCache) {
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4102
|
+
const { data: data2 } = await this.getCacheData(serverName);
|
|
4103
|
+
this.enableLog() && console.log("getCacheData:", data2);
|
|
4104
|
+
if (data2) {
|
|
4105
|
+
this.EventEmit.emit("hitCache", data2);
|
|
4106
|
+
this.EventEmit.emit("success", data2);
|
|
4107
|
+
this.EventEmit.emit("finish", data2);
|
|
4108
|
+
resolve(data2);
|
|
4109
|
+
return;
|
|
4110
|
+
}
|
|
4140
4111
|
}
|
|
4141
|
-
|
|
4142
|
-
if (
|
|
4143
|
-
|
|
4144
|
-
const
|
|
4145
|
-
const
|
|
4146
|
-
|
|
4112
|
+
const requester = AxiosInstanceMap.get(serverName);
|
|
4113
|
+
if (!requester) throw new Error("AxiosInstance not created");
|
|
4114
|
+
try {
|
|
4115
|
+
const rawResponse = await requester.request(this.Request);
|
|
4116
|
+
const isSpecial = isSpecialResponse(rawResponse);
|
|
4117
|
+
const response = await applyStrategies(
|
|
4118
|
+
rawResponse,
|
|
4119
|
+
strategies,
|
|
4120
|
+
"response"
|
|
4121
|
+
);
|
|
4122
|
+
if (!isNoCache) {
|
|
4123
|
+
!isSpecial && await this.setCacheData(serverName, response);
|
|
4124
|
+
}
|
|
4125
|
+
this.Response = response;
|
|
4126
|
+
this.applyHitSource(serverName);
|
|
4127
|
+
isSpecial && console.log("isSpecial:", isSpecial);
|
|
4128
|
+
if (isSpecial) {
|
|
4147
4129
|
this.EventEmit.emit("success", response.data);
|
|
4148
|
-
|
|
4149
|
-
|
|
4130
|
+
this.EventEmit.emit("finish", response.data);
|
|
4131
|
+
resolve(response);
|
|
4132
|
+
return;
|
|
4133
|
+
}
|
|
4134
|
+
!isSpecial && console.log("isSpecial:", isSpecial);
|
|
4135
|
+
if (serverStatusCodeRule) {
|
|
4136
|
+
const { key, rule } = serverStatusCodeRule;
|
|
4137
|
+
const statuCodeKey = key ?? "code";
|
|
4138
|
+
const data2 = response.data;
|
|
4139
|
+
if (rule(data2[statuCodeKey])) {
|
|
4140
|
+
this.EventEmit.emit("success", response.data);
|
|
4141
|
+
} else {
|
|
4142
|
+
this.EventEmit.emit("error", response.data);
|
|
4143
|
+
}
|
|
4150
4144
|
}
|
|
4145
|
+
resolve(response.data);
|
|
4146
|
+
} catch (error) {
|
|
4147
|
+
this.EventEmit.emit("error", error);
|
|
4148
|
+
this.EventEmit.emit("finish", error);
|
|
4149
|
+
console.error(error);
|
|
4150
|
+
this.Error = error;
|
|
4151
|
+
reject(error);
|
|
4152
|
+
return;
|
|
4151
4153
|
}
|
|
4152
|
-
|
|
4153
|
-
} catch (error) {
|
|
4154
|
-
this.EventEmit.emit("error", error);
|
|
4155
|
-
this.EventEmit.emit("finish", error);
|
|
4156
|
-
console.error(error);
|
|
4157
|
-
this.Error = error;
|
|
4158
|
-
return error;
|
|
4159
|
-
}
|
|
4154
|
+
});
|
|
4160
4155
|
});
|
|
4161
4156
|
__publicField(this, "onSuccess", (listener) => {
|
|
4162
4157
|
this.EventEmit.on("success", listener);
|
|
@@ -4176,7 +4171,6 @@ class SnailMethod {
|
|
|
4176
4171
|
this.apiInstance = apiInstance;
|
|
4177
4172
|
this.target = target;
|
|
4178
4173
|
this.propertyKey = propertyKey.toString();
|
|
4179
|
-
this.Args = args ?? [];
|
|
4180
4174
|
this.init();
|
|
4181
4175
|
this.enableLog() && console.log("url:", this.Url);
|
|
4182
4176
|
this.EventEmit = new SnailEvent();
|
|
@@ -4186,10 +4180,11 @@ class SnailMethod {
|
|
|
4186
4180
|
if (!methodOptions) {
|
|
4187
4181
|
throw new Error("Create SnailMethod must be used for decoration");
|
|
4188
4182
|
}
|
|
4189
|
-
const { path, method, name } = methodOptions;
|
|
4183
|
+
const { path, method, name, adapter } = methodOptions;
|
|
4190
4184
|
this.Name = name ?? this.propertyKey;
|
|
4191
4185
|
this.Path = path;
|
|
4192
4186
|
this.Method = method;
|
|
4187
|
+
this.Adapter = adapter;
|
|
4193
4188
|
this.createRequest();
|
|
4194
4189
|
this.initUrl();
|
|
4195
4190
|
this.initVersion();
|
|
@@ -4249,6 +4244,7 @@ class SnailMethod {
|
|
|
4249
4244
|
const request = {
|
|
4250
4245
|
url: this.Url,
|
|
4251
4246
|
method: this.Method,
|
|
4247
|
+
adapter: this.Adapter,
|
|
4252
4248
|
timeout: this.apiInstance.timeout,
|
|
4253
4249
|
data: {},
|
|
4254
4250
|
params: {},
|
|
@@ -4333,12 +4329,11 @@ class SnailMethod {
|
|
|
4333
4329
|
const [serverName] = this.apiInstance.name.split(".");
|
|
4334
4330
|
const cacheForMap = CacheForMap.get(serverName);
|
|
4335
4331
|
let flag = false;
|
|
4336
|
-
if (
|
|
4337
|
-
flag =
|
|
4338
|
-
}
|
|
4339
|
-
if (Array.isArray(cacheForMap)) {
|
|
4340
|
-
flag = cacheForMap.includes(this.Method);
|
|
4332
|
+
if (cacheForMap) {
|
|
4333
|
+
flag = cacheForMap.includes(this.Method.toLowerCase());
|
|
4341
4334
|
}
|
|
4335
|
+
this.enableLog() && console.log("cacheForMap:", cacheForMap);
|
|
4336
|
+
this.enableLog() && console.log("cacheMethodFlag:", flag);
|
|
4342
4337
|
const isMethodNoCache = Reflect.getMetadata(
|
|
4343
4338
|
NO_CACHE_KEY,
|
|
4344
4339
|
this.target,
|
|
@@ -4496,10 +4491,8 @@ class SnailServer {
|
|
|
4496
4491
|
propertyKey
|
|
4497
4492
|
);
|
|
4498
4493
|
if (!methodConfig) return target[propertyKey];
|
|
4499
|
-
return (
|
|
4500
|
-
const method = new SnailMethod(apiInstance, target, propertyKey
|
|
4501
|
-
...args
|
|
4502
|
-
]);
|
|
4494
|
+
return () => {
|
|
4495
|
+
const method = new SnailMethod(apiInstance, target, propertyKey);
|
|
4503
4496
|
this.initExpireSource(method, propertyKey);
|
|
4504
4497
|
return method;
|
|
4505
4498
|
};
|
|
@@ -4522,7 +4515,14 @@ class SnailServer {
|
|
|
4522
4515
|
CacheTtlMap.set(this.Name, options.ttl || 500);
|
|
4523
4516
|
}
|
|
4524
4517
|
if (cacheFor) {
|
|
4525
|
-
|
|
4518
|
+
if (Array.isArray(cacheFor)) {
|
|
4519
|
+
CacheForMap.set(
|
|
4520
|
+
this.Name,
|
|
4521
|
+
cacheFor.map((method) => method.toLowerCase())
|
|
4522
|
+
);
|
|
4523
|
+
return;
|
|
4524
|
+
}
|
|
4525
|
+
CacheForMap.set(this.Name, [cacheFor.toLowerCase()]);
|
|
4526
4526
|
}
|
|
4527
4527
|
}
|
|
4528
4528
|
initExpireSource(target, propertyKey) {
|
|
@@ -4593,6 +4593,12 @@ class SnailServer {
|
|
|
4593
4593
|
return this.BaseURL;
|
|
4594
4594
|
}
|
|
4595
4595
|
}
|
|
4596
|
+
const API_CONFIG_KEY = Symbol("SNAIL_API_CONFIG_KEY");
|
|
4597
|
+
const Api = (url = "", config) => {
|
|
4598
|
+
return (target) => {
|
|
4599
|
+
Reflect.defineMetadata(API_CONFIG_KEY, { url, ...config }, target);
|
|
4600
|
+
};
|
|
4601
|
+
};
|
|
4596
4602
|
class SnailApi {
|
|
4597
4603
|
constructor(options) {
|
|
4598
4604
|
__publicField(this, "Name");
|
|
@@ -4829,7 +4835,6 @@ export {
|
|
|
4829
4835
|
Post,
|
|
4830
4836
|
Put,
|
|
4831
4837
|
Query,
|
|
4832
|
-
RequestMethodEnum,
|
|
4833
4838
|
Server,
|
|
4834
4839
|
SnailApi,
|
|
4835
4840
|
SnailMethod,
|
package/dist/snail-api.umd.cjs
CHANGED
|
@@ -3721,16 +3721,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3721
3721
|
});
|
|
3722
3722
|
}
|
|
3723
3723
|
}
|
|
3724
|
-
var RequestMethodEnum = /* @__PURE__ */ ((RequestMethodEnum2) => {
|
|
3725
|
-
RequestMethodEnum2["GET"] = "Get";
|
|
3726
|
-
RequestMethodEnum2["HEAD"] = "Head";
|
|
3727
|
-
RequestMethodEnum2["POST"] = "Post";
|
|
3728
|
-
RequestMethodEnum2["PUT"] = "Put";
|
|
3729
|
-
RequestMethodEnum2["DELETE"] = "delete";
|
|
3730
|
-
RequestMethodEnum2["PATCH"] = "Patch";
|
|
3731
|
-
RequestMethodEnum2["OPTIONS"] = "Options";
|
|
3732
|
-
return RequestMethodEnum2;
|
|
3733
|
-
})(RequestMethodEnum || {});
|
|
3734
3724
|
class SnailServerStatusCodeRuleOptions {
|
|
3735
3725
|
constructor() {
|
|
3736
3726
|
__publicField(this, "key");
|
|
@@ -3888,14 +3878,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3888
3878
|
return !contentType.includes("application/json");
|
|
3889
3879
|
}
|
|
3890
3880
|
const METHOD_KEY = Symbol("SNAIL_METHOD_KEY");
|
|
3891
|
-
const API_CONFIG_KEY = Symbol("SNAIL_API_CONFIG_KEY");
|
|
3892
|
-
const Api = (url = "", config) => {
|
|
3893
|
-
return (target) => {
|
|
3894
|
-
Reflect.defineMetadata(API_CONFIG_KEY, { url, ...config }, target);
|
|
3895
|
-
};
|
|
3896
|
-
};
|
|
3897
3881
|
const createMethodDecorator = (method) => {
|
|
3898
|
-
return (path = "",
|
|
3882
|
+
return (path = "", options) => {
|
|
3899
3883
|
return (target, propertyKey) => {
|
|
3900
3884
|
const methodOptions = Reflect.getMetadata(
|
|
3901
3885
|
METHOD_KEY,
|
|
@@ -3904,25 +3888,29 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
3904
3888
|
);
|
|
3905
3889
|
if (methodOptions) {
|
|
3906
3890
|
console.error("only one method decorator for a request function!");
|
|
3907
|
-
console.error(
|
|
3908
|
-
|
|
3891
|
+
console.error(
|
|
3892
|
+
`you must chose only one method decorator[@${method} or @${methodOptions.method}]`
|
|
3893
|
+
);
|
|
3894
|
+
throw new TypeError(
|
|
3895
|
+
`Multiple decorators are used for the same request function`
|
|
3896
|
+
);
|
|
3909
3897
|
}
|
|
3910
3898
|
Reflect.defineMetadata(
|
|
3911
3899
|
METHOD_KEY,
|
|
3912
|
-
{ method, path,
|
|
3900
|
+
{ method, path, ...options },
|
|
3913
3901
|
target,
|
|
3914
3902
|
propertyKey
|
|
3915
3903
|
);
|
|
3916
3904
|
};
|
|
3917
3905
|
};
|
|
3918
3906
|
};
|
|
3919
|
-
const Get = createMethodDecorator(
|
|
3920
|
-
const Post = createMethodDecorator(
|
|
3921
|
-
const Put = createMethodDecorator(
|
|
3922
|
-
const Delete = createMethodDecorator(
|
|
3923
|
-
const Patch = createMethodDecorator(
|
|
3924
|
-
const Options = createMethodDecorator(
|
|
3925
|
-
const Head = createMethodDecorator(
|
|
3907
|
+
const Get = createMethodDecorator("GET");
|
|
3908
|
+
const Post = createMethodDecorator("POST");
|
|
3909
|
+
const Put = createMethodDecorator("PUT");
|
|
3910
|
+
const Delete = createMethodDecorator("DELETE");
|
|
3911
|
+
const Patch = createMethodDecorator("PATCH");
|
|
3912
|
+
const Options = createMethodDecorator("OPTIONS");
|
|
3913
|
+
const Head = createMethodDecorator("HEAD");
|
|
3926
3914
|
const SERVER_CONFIG_KEY = Symbol("SANIL_SERVER_CONFIG_KEY");
|
|
3927
3915
|
const Server = (config) => {
|
|
3928
3916
|
return (target) => {
|
|
@@ -4064,7 +4052,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4064
4052
|
const UPLOAD_PROGRESS_KEY = Symbol("SNAIL_UPLOAD_PROGRESS_KEY");
|
|
4065
4053
|
const DOWNLOAD_PROGRESS_KEY = Symbol("SNAIL_DOWNLOAD_PROGRESS_KEY");
|
|
4066
4054
|
class SnailMethod {
|
|
4067
|
-
|
|
4055
|
+
// private Args: any[] = [];
|
|
4056
|
+
constructor(apiInstance, target, propertyKey) {
|
|
4068
4057
|
// 私有属性
|
|
4069
4058
|
// private serverInstance: SnailServer;
|
|
4070
4059
|
__publicField(this, "Name");
|
|
@@ -4080,87 +4069,93 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4080
4069
|
__publicField(this, "propertyKey");
|
|
4081
4070
|
__publicField(this, "Url", "");
|
|
4082
4071
|
__publicField(this, "Path", "");
|
|
4083
|
-
__publicField(this, "Method",
|
|
4072
|
+
__publicField(this, "Method", "GET");
|
|
4073
|
+
__publicField(this, "Adapter");
|
|
4084
4074
|
__publicField(this, "Version");
|
|
4085
|
-
__publicField(this, "
|
|
4086
|
-
__publicField(this, "send", async () => {
|
|
4075
|
+
__publicField(this, "send", (...args) => {
|
|
4087
4076
|
this.enableLog() && console.log("send:", this.name);
|
|
4088
4077
|
const [serverName] = this.apiInstance.name.split(".");
|
|
4089
4078
|
const axios2 = AxiosInstanceMap.get(serverName);
|
|
4090
4079
|
if (!axios2) throw new Error("AxiosInstance not created");
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
const newUrl = replacePlaceholders(this.Url, params);
|
|
4102
|
-
this.Request = {
|
|
4103
|
-
...this.Request,
|
|
4104
|
-
url: newUrl,
|
|
4105
|
-
params: {
|
|
4106
|
-
...this.Request.params,
|
|
4107
|
-
...querys
|
|
4108
|
-
},
|
|
4109
|
-
data
|
|
4110
|
-
};
|
|
4111
|
-
this.enableLog() && console.log("request:", this.Request);
|
|
4112
|
-
const isNoCache = this.isNoCache();
|
|
4113
|
-
this.enableLog() && console.log("method is noCache:", isNoCache);
|
|
4114
|
-
if (!isNoCache) {
|
|
4115
|
-
const { data: data2 } = await this.getCacheData(serverName);
|
|
4116
|
-
this.enableLog() && console.log("getCacheData:", data2);
|
|
4117
|
-
if (data2) {
|
|
4118
|
-
this.EventEmit.emit("hitCache", data2);
|
|
4119
|
-
this.EventEmit.emit("success", data2);
|
|
4120
|
-
this.EventEmit.emit("finish", data2);
|
|
4121
|
-
return data2;
|
|
4122
|
-
}
|
|
4123
|
-
}
|
|
4124
|
-
const requester = AxiosInstanceMap.get(serverName);
|
|
4125
|
-
if (!requester) throw new Error("AxiosInstance not created");
|
|
4126
|
-
try {
|
|
4127
|
-
const rawResponse = await requester.request(this.Request);
|
|
4128
|
-
const isSpecial = isSpecialResponse(rawResponse);
|
|
4129
|
-
const response = await applyStrategies(
|
|
4130
|
-
rawResponse,
|
|
4131
|
-
strategies,
|
|
4132
|
-
"response"
|
|
4080
|
+
return new Promise(async (resolve, reject) => {
|
|
4081
|
+
const serverStatusCodeRule = ServerStatusCodeRuleMap.get(serverName);
|
|
4082
|
+
const strategies = this.getStrategies();
|
|
4083
|
+
this.Request = await applyStrategies(this.Request, strategies, "request");
|
|
4084
|
+
this.Request = this.applyProgress(this.Request);
|
|
4085
|
+
const { data, querys, params } = buildRequestArgs(
|
|
4086
|
+
this.target,
|
|
4087
|
+
this.propertyKey,
|
|
4088
|
+
// this.Args
|
|
4089
|
+
args
|
|
4133
4090
|
);
|
|
4091
|
+
this.enableLog() && console.log("methodUrl:", this.Request.baseURL, this.Request.url);
|
|
4092
|
+
const newUrl = replacePlaceholders(this.Url, params);
|
|
4093
|
+
this.Request = {
|
|
4094
|
+
...this.Request,
|
|
4095
|
+
url: newUrl,
|
|
4096
|
+
params: {
|
|
4097
|
+
...this.Request.params,
|
|
4098
|
+
...querys
|
|
4099
|
+
},
|
|
4100
|
+
data
|
|
4101
|
+
};
|
|
4102
|
+
this.enableLog() && console.log("request:", this.Request);
|
|
4103
|
+
const isNoCache = this.isNoCache();
|
|
4104
|
+
this.enableLog() && console.log("method is noCache:", isNoCache);
|
|
4134
4105
|
if (!isNoCache) {
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4106
|
+
const { data: data2 } = await this.getCacheData(serverName);
|
|
4107
|
+
this.enableLog() && console.log("getCacheData:", data2);
|
|
4108
|
+
if (data2) {
|
|
4109
|
+
this.EventEmit.emit("hitCache", data2);
|
|
4110
|
+
this.EventEmit.emit("success", data2);
|
|
4111
|
+
this.EventEmit.emit("finish", data2);
|
|
4112
|
+
resolve(data2);
|
|
4113
|
+
return;
|
|
4114
|
+
}
|
|
4144
4115
|
}
|
|
4145
|
-
|
|
4146
|
-
if (
|
|
4147
|
-
|
|
4148
|
-
const
|
|
4149
|
-
const
|
|
4150
|
-
|
|
4116
|
+
const requester = AxiosInstanceMap.get(serverName);
|
|
4117
|
+
if (!requester) throw new Error("AxiosInstance not created");
|
|
4118
|
+
try {
|
|
4119
|
+
const rawResponse = await requester.request(this.Request);
|
|
4120
|
+
const isSpecial = isSpecialResponse(rawResponse);
|
|
4121
|
+
const response = await applyStrategies(
|
|
4122
|
+
rawResponse,
|
|
4123
|
+
strategies,
|
|
4124
|
+
"response"
|
|
4125
|
+
);
|
|
4126
|
+
if (!isNoCache) {
|
|
4127
|
+
!isSpecial && await this.setCacheData(serverName, response);
|
|
4128
|
+
}
|
|
4129
|
+
this.Response = response;
|
|
4130
|
+
this.applyHitSource(serverName);
|
|
4131
|
+
isSpecial && console.log("isSpecial:", isSpecial);
|
|
4132
|
+
if (isSpecial) {
|
|
4151
4133
|
this.EventEmit.emit("success", response.data);
|
|
4152
|
-
|
|
4153
|
-
|
|
4134
|
+
this.EventEmit.emit("finish", response.data);
|
|
4135
|
+
resolve(response);
|
|
4136
|
+
return;
|
|
4137
|
+
}
|
|
4138
|
+
!isSpecial && console.log("isSpecial:", isSpecial);
|
|
4139
|
+
if (serverStatusCodeRule) {
|
|
4140
|
+
const { key, rule } = serverStatusCodeRule;
|
|
4141
|
+
const statuCodeKey = key ?? "code";
|
|
4142
|
+
const data2 = response.data;
|
|
4143
|
+
if (rule(data2[statuCodeKey])) {
|
|
4144
|
+
this.EventEmit.emit("success", response.data);
|
|
4145
|
+
} else {
|
|
4146
|
+
this.EventEmit.emit("error", response.data);
|
|
4147
|
+
}
|
|
4154
4148
|
}
|
|
4149
|
+
resolve(response.data);
|
|
4150
|
+
} catch (error) {
|
|
4151
|
+
this.EventEmit.emit("error", error);
|
|
4152
|
+
this.EventEmit.emit("finish", error);
|
|
4153
|
+
console.error(error);
|
|
4154
|
+
this.Error = error;
|
|
4155
|
+
reject(error);
|
|
4156
|
+
return;
|
|
4155
4157
|
}
|
|
4156
|
-
|
|
4157
|
-
} catch (error) {
|
|
4158
|
-
this.EventEmit.emit("error", error);
|
|
4159
|
-
this.EventEmit.emit("finish", error);
|
|
4160
|
-
console.error(error);
|
|
4161
|
-
this.Error = error;
|
|
4162
|
-
return error;
|
|
4163
|
-
}
|
|
4158
|
+
});
|
|
4164
4159
|
});
|
|
4165
4160
|
__publicField(this, "onSuccess", (listener) => {
|
|
4166
4161
|
this.EventEmit.on("success", listener);
|
|
@@ -4180,7 +4175,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4180
4175
|
this.apiInstance = apiInstance;
|
|
4181
4176
|
this.target = target;
|
|
4182
4177
|
this.propertyKey = propertyKey.toString();
|
|
4183
|
-
this.Args = args ?? [];
|
|
4184
4178
|
this.init();
|
|
4185
4179
|
this.enableLog() && console.log("url:", this.Url);
|
|
4186
4180
|
this.EventEmit = new SnailEvent();
|
|
@@ -4190,10 +4184,11 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4190
4184
|
if (!methodOptions) {
|
|
4191
4185
|
throw new Error("Create SnailMethod must be used for decoration");
|
|
4192
4186
|
}
|
|
4193
|
-
const { path, method, name } = methodOptions;
|
|
4187
|
+
const { path, method, name, adapter } = methodOptions;
|
|
4194
4188
|
this.Name = name ?? this.propertyKey;
|
|
4195
4189
|
this.Path = path;
|
|
4196
4190
|
this.Method = method;
|
|
4191
|
+
this.Adapter = adapter;
|
|
4197
4192
|
this.createRequest();
|
|
4198
4193
|
this.initUrl();
|
|
4199
4194
|
this.initVersion();
|
|
@@ -4253,6 +4248,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4253
4248
|
const request = {
|
|
4254
4249
|
url: this.Url,
|
|
4255
4250
|
method: this.Method,
|
|
4251
|
+
adapter: this.Adapter,
|
|
4256
4252
|
timeout: this.apiInstance.timeout,
|
|
4257
4253
|
data: {},
|
|
4258
4254
|
params: {},
|
|
@@ -4337,12 +4333,11 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4337
4333
|
const [serverName] = this.apiInstance.name.split(".");
|
|
4338
4334
|
const cacheForMap = CacheForMap.get(serverName);
|
|
4339
4335
|
let flag = false;
|
|
4340
|
-
if (
|
|
4341
|
-
flag =
|
|
4342
|
-
}
|
|
4343
|
-
if (Array.isArray(cacheForMap)) {
|
|
4344
|
-
flag = cacheForMap.includes(this.Method);
|
|
4336
|
+
if (cacheForMap) {
|
|
4337
|
+
flag = cacheForMap.includes(this.Method.toLowerCase());
|
|
4345
4338
|
}
|
|
4339
|
+
this.enableLog() && console.log("cacheForMap:", cacheForMap);
|
|
4340
|
+
this.enableLog() && console.log("cacheMethodFlag:", flag);
|
|
4346
4341
|
const isMethodNoCache = Reflect.getMetadata(
|
|
4347
4342
|
NO_CACHE_KEY,
|
|
4348
4343
|
this.target,
|
|
@@ -4500,10 +4495,8 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4500
4495
|
propertyKey
|
|
4501
4496
|
);
|
|
4502
4497
|
if (!methodConfig) return target[propertyKey];
|
|
4503
|
-
return (
|
|
4504
|
-
const method = new SnailMethod(apiInstance, target, propertyKey
|
|
4505
|
-
...args
|
|
4506
|
-
]);
|
|
4498
|
+
return () => {
|
|
4499
|
+
const method = new SnailMethod(apiInstance, target, propertyKey);
|
|
4507
4500
|
this.initExpireSource(method, propertyKey);
|
|
4508
4501
|
return method;
|
|
4509
4502
|
};
|
|
@@ -4526,7 +4519,14 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4526
4519
|
CacheTtlMap.set(this.Name, options.ttl || 500);
|
|
4527
4520
|
}
|
|
4528
4521
|
if (cacheFor) {
|
|
4529
|
-
|
|
4522
|
+
if (Array.isArray(cacheFor)) {
|
|
4523
|
+
CacheForMap.set(
|
|
4524
|
+
this.Name,
|
|
4525
|
+
cacheFor.map((method) => method.toLowerCase())
|
|
4526
|
+
);
|
|
4527
|
+
return;
|
|
4528
|
+
}
|
|
4529
|
+
CacheForMap.set(this.Name, [cacheFor.toLowerCase()]);
|
|
4530
4530
|
}
|
|
4531
4531
|
}
|
|
4532
4532
|
initExpireSource(target, propertyKey) {
|
|
@@ -4597,6 +4597,12 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4597
4597
|
return this.BaseURL;
|
|
4598
4598
|
}
|
|
4599
4599
|
}
|
|
4600
|
+
const API_CONFIG_KEY = Symbol("SNAIL_API_CONFIG_KEY");
|
|
4601
|
+
const Api = (url = "", config) => {
|
|
4602
|
+
return (target) => {
|
|
4603
|
+
Reflect.defineMetadata(API_CONFIG_KEY, { url, ...config }, target);
|
|
4604
|
+
};
|
|
4605
|
+
};
|
|
4600
4606
|
class SnailApi {
|
|
4601
4607
|
constructor(options) {
|
|
4602
4608
|
__publicField(this, "Name");
|
|
@@ -4832,7 +4838,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
|
|
|
4832
4838
|
exports2.Post = Post;
|
|
4833
4839
|
exports2.Put = Put;
|
|
4834
4840
|
exports2.Query = Query;
|
|
4835
|
-
exports2.RequestMethodEnum = RequestMethodEnum;
|
|
4836
4841
|
exports2.Server = Server;
|
|
4837
4842
|
exports2.SnailApi = SnailApi;
|
|
4838
4843
|
exports2.SnailMethod = SnailMethod;
|
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
import { RequestMethod } from "./request.method";
|
|
2
1
|
import { SnailServer } from "../core";
|
|
3
2
|
export interface ApiOptions {
|
|
4
3
|
name?: string;
|
|
5
4
|
timeout?: number;
|
|
6
5
|
version?: string;
|
|
7
6
|
}
|
|
8
|
-
export interface MethodOption {
|
|
9
|
-
name?: string;
|
|
10
|
-
method: RequestMethod;
|
|
11
|
-
path: string;
|
|
12
|
-
}
|
|
13
7
|
export interface ApiInstanceOptions {
|
|
14
8
|
serverInstance: SnailServer;
|
|
15
9
|
enableLog?: boolean;
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
export type
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
hitCache?: boolean;
|
|
7
|
-
}>;
|
|
8
|
-
export type ApiProxy<T extends object, RT extends ResponseData = Omit<StandardResponseData, "data">, DK extends string = "data"> = {
|
|
9
|
-
[K in keyof T]: T[K] extends (...args: infer A) => any ? RT extends SpecialResponseData ? <RD = unknown>(...args: A) => SnailMethod<RD extends SpecialResponseData ? RD : never> : <RD = unknown>(...args: A) => RD extends SpecialResponseData ? SnailMethod<RD> : SnailMethod<RT & {
|
|
1
|
+
import { SpecialResponseData, StandardResponseData, ResponseJsonData } from "./response.data";
|
|
2
|
+
import { MethodProxy } from "./snail.method";
|
|
3
|
+
export type StandardResponseWithoutData = Omit<StandardResponseData, "data">;
|
|
4
|
+
export type ApiProxy<T extends object, RT extends StandardResponseWithoutData | ResponseJsonData, DK extends string = "data"> = {
|
|
5
|
+
[K in keyof T]: T[K] extends (...args: infer A) => any ? <RD = unknown>() => MethodProxy<RD extends SpecialResponseData ? RD : RT & {
|
|
10
6
|
[KK in DK]: RD;
|
|
11
|
-
}> : T[K];
|
|
7
|
+
}, A extends any[] ? A : []> : T[K];
|
|
12
8
|
};
|
package/dist/typings/index.d.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
-
import { AxiosResponse } from "axios";
|
|
2
|
-
import { ResponseData, ResponseJsonData,
|
|
3
|
-
|
|
1
|
+
import { AxiosRequestConfig, Method, AxiosResponse } from "axios";
|
|
2
|
+
import { ResponseData, ResponseJsonData, SpecialResponseData } from "./response.data";
|
|
3
|
+
import { SnailMethod } from "../core";
|
|
4
|
+
export interface MethodSendOptions {
|
|
5
|
+
name?: string;
|
|
6
|
+
adapter?: AxiosRequestConfig["adapter"];
|
|
7
|
+
}
|
|
8
|
+
export interface MethodOption extends MethodSendOptions {
|
|
9
|
+
method: Method;
|
|
10
|
+
path: string;
|
|
11
|
+
}
|
|
12
|
+
export interface MethodProxy<RD extends ResponseData = ResponseJsonData, ArgsType extends any[] = []> extends SnailMethod<RD> {
|
|
13
|
+
send: (...args: ArgsType) => Promise<RD extends SpecialResponseData ? AxiosResponse<RD> : RD>;
|
|
14
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CacheManagementOption } from "./cache.management.option";
|
|
2
|
-
import {
|
|
3
|
-
export type CacheForType = "All" | "all" |
|
|
2
|
+
import { Method } from "axios";
|
|
3
|
+
export type CacheForType = "All" | "all" | Method | Method[];
|
|
4
4
|
export declare class SnailServerStatusCodeRuleOptions {
|
|
5
5
|
key?: string;
|
|
6
6
|
rule: (status: number) => boolean;
|
package/package.json
CHANGED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export declare enum RequestMethodEnum {
|
|
2
|
-
GET = "Get",
|
|
3
|
-
HEAD = "Head",
|
|
4
|
-
POST = "Post",
|
|
5
|
-
PUT = "Put",
|
|
6
|
-
DELETE = "delete",
|
|
7
|
-
PATCH = "Patch",
|
|
8
|
-
OPTIONS = "Options"
|
|
9
|
-
}
|
|
10
|
-
export type RequestMethod = Uppercase<`${RequestMethodEnum}`> | Lowercase<`${RequestMethodEnum}`> | `${RequestMethodEnum}` | RequestMethodEnum;
|