@snail-js/api 0.1.4 → 0.1.6

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 CHANGED
@@ -335,7 +335,11 @@ class Test {
335
335
 
336
336
  ### 上传进度装饰器`@UploadProgress`
337
337
 
338
- - `@UploadProgress((progress: AxiosProgressEvent) => void)`
338
+ - `@UploadProgress((progressEvent: AxiosProgressEvent) => void)`
339
+
340
+ ### 下载进度装饰器`@DownloadProgress`
341
+
342
+ - `@DownloadProgress((progressEvent: AxiosProgressEvent) => void)`
339
343
 
340
344
  ## Server Send Event 服务端推送
341
345
 
@@ -374,33 +378,126 @@ export const Sse = Service.createSse(ServerSend);
374
378
  ```
375
379
 
376
380
  ### 服务端推送装饰器`@Sse`
381
+
377
382
  - `@Sse(path:string,options:{withCredentials: boolean})`
378
383
  - 创建一个服务端推送连接,当被装饰的方法调用时打开连接
379
384
  - 被装饰的方法调用后会返回`{eventSource:EventSource,close:function}`
380
- - eventSource: sse连接实例
381
- - close: 关闭此sse连接的方法
385
+ - eventSource: sse 连接实例
386
+ - close: 关闭此 sse 连接的方法
382
387
 
383
388
  ### 注册`onopen`装饰器`@OnSseOpen`
389
+
384
390
  - 当`@Sse`装饰的方法被调用时,将`@OnSseOpen`装饰的方法注册为`@Sse`装饰的方法返回的`EventSource`实例`onopen`处理函数
385
391
 
386
392
  ### 注册`onerror`装饰器`@OnSseError`
393
+
387
394
  - 当`@Sse`装饰的方法被调用时,将`@OnSseError`装饰的方法注册为`@Sse`装饰的方法返回的`EventSource`实例`onerror`处理函数
388
395
 
389
396
  ### 事件处理装饰器`@SseEvent`
397
+
390
398
  - `@SseEvent(eventName?:string)`
391
399
  - 未传入`eventName`,默认注册为`message`事件处理器
392
400
  - 传入`eventName`,注册为对应名称的事件处理器
393
401
 
402
+ ---
403
+
404
+ ## TypeScript 支持
405
+
406
+ ### 默认返回类型
407
+
408
+ ```typescript
409
+ export interface ResponseData<T = any> {
410
+ code: 0;
411
+ message: string;
412
+ data: T;
413
+ }
414
+ ```
415
+
416
+ ### 定义返回类型
417
+
418
+ 1. 定义后端标准数据格式
419
+
420
+ ```typescript
421
+ export class CustomResponse {
422
+ status_code: number;
423
+ msg: string;
424
+ }
425
+ ```
426
+
427
+ 2. 创建时应用格式
428
+
429
+ ```typescript
430
+ // service.ts
431
+ import { Snail, Server } from "@snail-js/api";
432
+
433
+ @Server({
434
+ baseURL: "/api",
435
+ timeout: 5000,
436
+ })
437
+ class BackEnd extends Snail<CustomResponse> {}
438
+
439
+ export const Service = new BackEnd();
440
+ ```
441
+
442
+ 3. 调用 API 时携带数据格式
443
+
444
+ ```typescript
445
+ import { userApi } from "./user";
446
+
447
+ class User {
448
+ id: number;
449
+ name: string;
450
+ tel: string;
451
+ age: number;
452
+ }
453
+
454
+ const res = await userApi.get<User>("1");
455
+ // 默认情况,以data为key存储数据
456
+ // res.data => CustomResponse & { data : User}
457
+ ```
458
+
459
+ > API 被调用的返回格式
460
+
461
+ ```typescript
462
+ const res = await userApi.get<User>("1");
463
+
464
+ // res type
465
+ {
466
+ data: T;
467
+ error: null | Error
468
+ hitCache?: boolean
469
+ }
470
+ ```
471
+
472
+ > `data: T`,后端响应数据;默认为`ResponseData<T = any>`类型;可由用户自定义修改
473
+
474
+ > `error: null | Error` ; 请求过程中的错误包含在此,可先判断 error 是否为 null 再进行数据处理
475
+
476
+ > `hitCache?: boolean`; 标识请求是否击中缓存;若从缓存获得数据,则不会发送请求。
477
+
478
+ 4. 若后端返回数据不是以 data 为 key 包含数据
479
+
480
+ ```typescript
481
+ @Server({
482
+ baseURL: "/api",
483
+ timeout: 5000,
484
+ })
485
+ class BackEnd extends Snail<CustomResponse, "record"> {}
486
+
487
+ const res = await userApi.get<User>("1");
488
+ // 自定义数据key
489
+ // res.data => CustomResponse & { record : User}
490
+ ```
394
491
 
395
492
  ### 代码仓库
396
493
 
397
494
  <p>
398
- <a src="https://gitee.com/limich/snail">
495
+ <a href="https://gitee.com/limich/snail">
399
496
  <img src="https://img.shields.io/badge/snail-js?style=flat&label=gitee&labelColor=F56C6C&link=https%3A%2F%2Fgitee.com%2Flimich%2Fsnail"></img>
400
497
  </a>
401
498
  </p>
402
499
  <p>
403
- <a src="https://github.com/limingchang/snail">
500
+ <a href="https://github.com/limingchang/snail">
404
501
  <img src="https://img.shields.io/badge/snail-js?style=flat&label=github&labelColor=F56C6C&link=https%3A%2F%2Fgihub.com%2Flimingchang%2Fsnail"></img>
405
502
  </a>
406
503
  </p>
@@ -1,8 +1,6 @@
1
1
  import "reflect-metadata";
2
2
  import { Strategy, ApiProxy, SseProxy, ResponseData } from "../typings";
3
- export declare class Snail<R extends {
4
- data: any;
5
- } = ResponseData> {
3
+ export declare class Snail<R extends {} = ResponseData, DK extends string = "data"> {
6
4
  private axiosInstance;
7
5
  private strategies;
8
6
  private cacheStorage?;
@@ -10,7 +8,7 @@ export declare class Snail<R extends {
10
8
  private sourceMap;
11
9
  private eventSource;
12
10
  registerStrategy(strategy: Strategy): void;
13
- createApi<T extends object>(constructor: new () => T): ApiProxy<T, R>;
11
+ createApi<T extends object>(constructor: new () => T): ApiProxy<T, R, DK>;
14
12
  private buildRequestArgs;
15
13
  private getStrategies;
16
14
  private applyStrategies;
@@ -1,4 +1,6 @@
1
1
  import "reflect-metadata";
2
2
  import { AxiosProgressEvent } from "axios";
3
3
  export declare const UPLOAD_PROGRESS_KEY: unique symbol;
4
- export declare const UploadProgress: (handler: (progress: AxiosProgressEvent) => void) => (target: any, propertyKey: string) => void;
4
+ export declare const UploadProgress: (handler: (progressEvent: AxiosProgressEvent) => void) => (target: any, propertyKey: string) => void;
5
+ export declare const DOWNLOAD_PROGRESS_KEY: unique symbol;
6
+ export declare const DownloadProgress: (handler: (progressEvent: AxiosProgressEvent) => void) => (target: any, propertyKey: string) => void;
package/dist/snail-api.js CHANGED
@@ -3816,6 +3816,7 @@ const Cache = (hitSource) => {
3816
3816
  };
3817
3817
  };
3818
3818
  const UPLOAD_PROGRESS_KEY = Symbol("SNAIL_UPLOAD_PROGRESS_KEY");
3819
+ const DOWNLOAD_PROGRESS_KEY = Symbol("SNAIL_DOWNLOAD_PROGRESS_KEY");
3819
3820
  const EVENT_SOURCE_OPTION_KEY = Symbol("SNAIL_EVENT_SOURCE_OPTION_KEY");
3820
3821
  const Sse = (path, options) => {
3821
3822
  return (target, propertyKey) => {
@@ -3931,15 +3932,29 @@ class Snail {
3931
3932
  target,
3932
3933
  propertyKey
3933
3934
  );
3935
+ const onDownloadProgress = Reflect.getMetadata(
3936
+ DOWNLOAD_PROGRESS_KEY,
3937
+ target,
3938
+ propertyKey
3939
+ );
3934
3940
  try {
3935
3941
  enableLog && console.log("send request:", request);
3936
3942
  const response = await this.axiosInstance({
3937
3943
  ...request,
3938
- onUploadProgress
3944
+ onUploadProgress,
3945
+ onDownloadProgress
3939
3946
  });
3947
+ const responseStrategies = strategies.filter(
3948
+ (strategy) => strategy.applyResponse
3949
+ );
3950
+ const strategyResponse = await this.applyStrategies(
3951
+ response,
3952
+ responseStrategies,
3953
+ "response"
3954
+ );
3940
3955
  hitSource !== null && this.setCache(request, response);
3941
3956
  this.expireCache(propertyKey);
3942
- return this.handleResponse(response, false);
3957
+ return this.handleResponse(strategyResponse, false);
3943
3958
  } catch (error) {
3944
3959
  return this.handleError(error);
3945
3960
  }
@@ -4017,16 +4032,9 @@ class Snail {
4017
4032
  statusText: "get response data from cache",
4018
4033
  config: { headers: new AxiosHeaders2() }
4019
4034
  };
4020
- const responseStrategies = strategies.filter(
4021
- (strategy) => strategy.applyResponse
4022
- );
4023
- const strategyResponse = await this.applyStrategies(
4024
- cacheResponse,
4025
- responseStrategies,
4026
- "response"
4027
- );
4028
- return strategyResponse;
4035
+ return cacheResponse;
4029
4036
  }
4037
+ return void 0;
4030
4038
  }
4031
4039
  initCacheManage(options) {
4032
4040
  if (!this.cacheStorage && options !== void 0) {
@@ -3820,6 +3820,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
3820
3820
  };
3821
3821
  };
3822
3822
  const UPLOAD_PROGRESS_KEY = Symbol("SNAIL_UPLOAD_PROGRESS_KEY");
3823
+ const DOWNLOAD_PROGRESS_KEY = Symbol("SNAIL_DOWNLOAD_PROGRESS_KEY");
3823
3824
  const EVENT_SOURCE_OPTION_KEY = Symbol("SNAIL_EVENT_SOURCE_OPTION_KEY");
3824
3825
  const Sse = (path, options) => {
3825
3826
  return (target, propertyKey) => {
@@ -3935,15 +3936,29 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
3935
3936
  target,
3936
3937
  propertyKey
3937
3938
  );
3939
+ const onDownloadProgress = Reflect.getMetadata(
3940
+ DOWNLOAD_PROGRESS_KEY,
3941
+ target,
3942
+ propertyKey
3943
+ );
3938
3944
  try {
3939
3945
  enableLog && console.log("send request:", request);
3940
3946
  const response = await this.axiosInstance({
3941
3947
  ...request,
3942
- onUploadProgress
3948
+ onUploadProgress,
3949
+ onDownloadProgress
3943
3950
  });
3951
+ const responseStrategies = strategies.filter(
3952
+ (strategy) => strategy.applyResponse
3953
+ );
3954
+ const strategyResponse = await this.applyStrategies(
3955
+ response,
3956
+ responseStrategies,
3957
+ "response"
3958
+ );
3944
3959
  hitSource !== null && this.setCache(request, response);
3945
3960
  this.expireCache(propertyKey);
3946
- return this.handleResponse(response, false);
3961
+ return this.handleResponse(strategyResponse, false);
3947
3962
  } catch (error) {
3948
3963
  return this.handleError(error);
3949
3964
  }
@@ -4021,16 +4036,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4021
4036
  statusText: "get response data from cache",
4022
4037
  config: { headers: new AxiosHeaders() }
4023
4038
  };
4024
- const responseStrategies = strategies.filter(
4025
- (strategy) => strategy.applyResponse
4026
- );
4027
- const strategyResponse = await this.applyStrategies(
4028
- cacheResponse,
4029
- responseStrategies,
4030
- "response"
4031
- );
4032
- return strategyResponse;
4039
+ return cacheResponse;
4033
4040
  }
4041
+ return void 0;
4034
4042
  }
4035
4043
  initCacheManage(options) {
4036
4044
  if (!this.cacheStorage && options !== void 0) {
@@ -1,11 +1,11 @@
1
+ import { ResponseData } from "./response.data";
1
2
  export type ApiResponse<T> = Promise<{
2
3
  data: T | null;
3
4
  error: Error | null;
5
+ hitCache?: boolean;
4
6
  }>;
5
- export type ApiProxy<T, R extends {
6
- data: any;
7
- }> = {
7
+ export type ApiProxy<T, R extends {} = ResponseData, DK extends string = "data"> = {
8
8
  [K in keyof T]: T[K] extends (...args: infer A) => any ? <D = any>(...args: A) => ApiResponse<R & {
9
- data: D;
9
+ [KK in DK]: D;
10
10
  }> : T[K];
11
11
  };
@@ -1,17 +1,11 @@
1
- export interface ResponseErrorData<E> {
2
- code: number;
3
- message: string;
4
- data: E;
5
- }
6
1
  export interface PaginationData<T> {
7
2
  total: number;
8
3
  page: number;
9
4
  size: number;
10
5
  record: T[];
11
6
  }
12
- export interface ResponseSuccessData<T> {
7
+ export interface ResponseData<T = any> {
13
8
  code: 0;
14
9
  message: string;
15
10
  data: T | PaginationData<T>;
16
11
  }
17
- export type ResponseData<T = any, E = any> = ResponseSuccessData<T> | ResponseErrorData<E>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snail-js/api",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "Http Request with Decorators Api, build on axios",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",