@snail-js/api 0.1.20 → 0.1.22

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
@@ -171,6 +171,13 @@ const data = await send();
171
171
  <td>Get</td>
172
172
  <td>要启用缓存的方法,默认仅开启Get缓存</td>
173
173
  </tr>
174
+ <tr>
175
+ <td>serverStatusCodeRule</td>
176
+ <td><a href="#SnailServerStatusCodeRuleOptions">SnailServerStatusCodeRuleOptions</a></td>
177
+ <td>否</td>
178
+ <td>undefined</td>
179
+ <td>服务端状态码规则,若配置此项,rule函数返回false时会触发错误</td>
180
+ </tr>
174
181
  <tr>
175
182
  <td>enableLog</td>
176
183
  <td>boolean</td>
@@ -426,6 +433,19 @@ export type VersioningOption =
426
433
  | VersioningCustomOption;
427
434
  ```
428
435
 
436
+ ### <a id="SnailServerStatusCodeRuleOptions">SnailServerStatusCodeRuleOptions</a> 类型
437
+
438
+ ```typescript
439
+ export class SnailServerStatusCodeRuleOptions {
440
+ // 通常服务端会返回一个状态码,当状态码不符合预期时,会抛出错误
441
+ // 可以使用此选项来定义服务端状态码的规则
442
+ // 当rule函数返回false时,会触发错误
443
+ rule: (statusCode: number) => boolean;
444
+ // response.data中服务端状态码的key,默认为code
445
+ key?: string;
446
+ }
447
+ ```
448
+
429
449
  ### 临时版本修改器`@Version`
430
450
 
431
451
  - 临时改变方法请求的版本
@@ -1,5 +1,5 @@
1
1
  import { AxiosResponse, AxiosRequestConfig } from "axios";
2
- import { EventHandler, Strategy, ResponseData, SendRequest, StandardResponseData, SnailMethodEventType } from "../typings";
2
+ import { Strategy, ResponseData, SendRequest, StandardResponseData, SnailSuccessListener, SnailErrorListener, SnailHitCacheListener, SnailFinishListener } from "../typings";
3
3
  import { SnailApi } from "./snailApi";
4
4
  /**
5
5
  * SnailMethod
@@ -14,8 +14,7 @@ export declare class SnailMethod<RT extends ResponseData = StandardResponseData>
14
14
  private Request;
15
15
  private Response;
16
16
  private Error;
17
- private eventMap;
18
- private onceWrapperMap;
17
+ private EventEmit;
19
18
  private propertyKey;
20
19
  private Url;
21
20
  private Path;
@@ -29,14 +28,10 @@ export declare class SnailMethod<RT extends ResponseData = StandardResponseData>
29
28
  private initVersion;
30
29
  private getExpireSources;
31
30
  private createRequest;
32
- onSuccess: (handler: EventHandler<RT>) => void;
33
- onError: (handler: EventHandler<RT>) => void;
34
- onHitCache: (handler: EventHandler<RT>) => void;
35
- onFinish: (handler: EventHandler<RT>) => void;
36
- on: (eventName: SnailMethodEventType, handler: EventHandler<RT>) => void;
37
- once: (eventName: SnailMethodEventType, handler: EventHandler<RT>) => void;
38
- emit: (eventName: SnailMethodEventType, ...args: any) => boolean;
39
- off: (eventName: SnailMethodEventType, handler: EventHandler<RT>) => void;
31
+ onSuccess: (listener: SnailSuccessListener<RT>) => void;
32
+ onError: <ErrorData = any>(listener: SnailErrorListener<RT, ErrorData>) => void;
33
+ onHitCache: (listener: SnailHitCacheListener<RT>) => void;
34
+ onFinish: (listener: SnailFinishListener<RT>) => void;
40
35
  private getCacheData;
41
36
  private setCacheData;
42
37
  get response(): AxiosResponse<RT, any>;
@@ -1,6 +1,6 @@
1
1
  import "reflect-metadata";
2
2
  import { AxiosInstance } from "axios";
3
- import { Strategy, ApiInstanceOptions, VersioningOption, CacheStorage, ApiProxy, ResponseData, StandardResponseData, CacheForType } from "../typings";
3
+ import { Strategy, ApiInstanceOptions, VersioningOption, CacheStorage, ApiProxy, ResponseData, StandardResponseData, CacheForType, SnailServerStatusCodeRuleOptions } from "../typings";
4
4
  import { SnailApi } from "./snailApi";
5
5
  import { SnailSse } from "./snailSse";
6
6
  export declare const CacheStorageMap: Map<string, CacheStorage>;
@@ -10,6 +10,7 @@ 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
+ export declare const ServerStatusCodeRuleMap: Map<string, SnailServerStatusCodeRuleOptions>;
13
14
  export declare class SnailServer<RT extends ResponseData = Omit<StandardResponseData, "data">, DK extends string = "data"> {
14
15
  private Name;
15
16
  private BaseURL;
@@ -17,6 +18,7 @@ export declare class SnailServer<RT extends ResponseData = Omit<StandardResponse
17
18
  private EnableLog;
18
19
  constructor();
19
20
  private init;
21
+ private initServerStatusCodeRule;
20
22
  private initLog;
21
23
  private initStrategy;
22
24
  private initVersioning;
@@ -0,0 +1 @@
1
+ export * from "./snail.event";
@@ -0,0 +1,10 @@
1
+ import { SnailEventListener } from "../typings";
2
+ export declare class SnailEvent<DT = any> {
3
+ private eventMap;
4
+ private onceWrapperMap;
5
+ constructor();
6
+ on: <ErrorData = any>(eventName: string, listener: SnailEventListener<DT, ErrorData>) => void;
7
+ off: (eventName: string, listener: SnailEventListener<DT>) => void;
8
+ once: (eventName: string, listener: SnailEventListener<DT>) => void;
9
+ emit: (eventName: string, ...args: any) => boolean;
10
+ }
package/dist/snail-api.js CHANGED
@@ -3727,6 +3727,12 @@ var RequestMethodEnum = /* @__PURE__ */ ((RequestMethodEnum2) => {
3727
3727
  RequestMethodEnum2["OPTIONS"] = "Options";
3728
3728
  return RequestMethodEnum2;
3729
3729
  })(RequestMethodEnum || {});
3730
+ class SnailServerStatusCodeRuleOptions {
3731
+ constructor() {
3732
+ __publicField(this, "key");
3733
+ __publicField(this, "rule");
3734
+ }
3735
+ }
3730
3736
  var VersioningType = /* @__PURE__ */ ((VersioningType2) => {
3731
3737
  VersioningType2[VersioningType2["Uri"] = 0] = "Uri";
3732
3738
  VersioningType2[VersioningType2["Header"] = 1] = "Header";
@@ -3758,13 +3764,6 @@ class SseOptions {
3758
3764
  __publicField(this, "version");
3759
3765
  }
3760
3766
  }
3761
- var EventType = /* @__PURE__ */ ((EventType2) => {
3762
- EventType2["Success"] = "success";
3763
- EventType2["Error"] = "error";
3764
- EventType2["hitCache"] = "hitCache";
3765
- EventType2["Finish"] = "finish";
3766
- return EventType2;
3767
- })(EventType || {});
3768
3767
  function createCache(optios) {
3769
3768
  const { type } = optios;
3770
3769
  if (type === CacheType.Custom) {
@@ -3970,6 +3969,54 @@ const HitSource = (...sources) => {
3970
3969
  Reflect.defineMetadata(CACHE_EXPIRE_SOURCE_KEY, sources, target);
3971
3970
  };
3972
3971
  };
3972
+ class SnailEvent {
3973
+ constructor() {
3974
+ __publicField(this, "eventMap");
3975
+ __publicField(this, "onceWrapperMap");
3976
+ __publicField(this, "on", (eventName, listener) => {
3977
+ if (typeof listener !== "function") {
3978
+ throw new TypeError("Handler must be a function");
3979
+ }
3980
+ const listeners = this.eventMap.get(eventName) || /* @__PURE__ */ new Set();
3981
+ listeners.add(listener);
3982
+ this.eventMap.set(eventName, listeners);
3983
+ });
3984
+ __publicField(this, "off", (eventName, listener) => {
3985
+ const listeners = this.eventMap.get(eventName);
3986
+ if (!listeners) return;
3987
+ if (this.onceWrapperMap.has(listener)) {
3988
+ this.onceWrapperMap.delete(listener);
3989
+ }
3990
+ if (listeners.size === 0) {
3991
+ this.eventMap.delete(eventName);
3992
+ }
3993
+ });
3994
+ __publicField(this, "once", (eventName, listener) => {
3995
+ const onceHandler = (data) => {
3996
+ try {
3997
+ listener.apply(this, [data]);
3998
+ } finally {
3999
+ this.off(eventName, onceHandler);
4000
+ this.onceWrapperMap.delete(listener);
4001
+ }
4002
+ };
4003
+ this.onceWrapperMap.set(listener, onceHandler);
4004
+ this.on(eventName, onceHandler);
4005
+ });
4006
+ __publicField(this, "emit", (eventName, ...args) => {
4007
+ const listeners = this.eventMap.get(eventName);
4008
+ if (!listeners || listeners.size === 0) return false;
4009
+ listeners.forEach((listener) => {
4010
+ Promise.resolve().then(() => {
4011
+ listener.apply(this, args);
4012
+ });
4013
+ });
4014
+ return true;
4015
+ });
4016
+ this.eventMap = /* @__PURE__ */ new Map();
4017
+ this.onceWrapperMap = /* @__PURE__ */ new Map();
4018
+ }
4019
+ }
3973
4020
  const versionHandlers = {
3974
4021
  [VersioningType.Uri]: (version, versioning) => {
3975
4022
  const prefix = versioning.prefix || "v";
@@ -4023,8 +4070,9 @@ class SnailMethod {
4023
4070
  __publicField(this, "Request");
4024
4071
  __publicField(this, "Response");
4025
4072
  __publicField(this, "Error");
4026
- __publicField(this, "eventMap");
4027
- __publicField(this, "onceWrapperMap");
4073
+ __publicField(this, "EventEmit");
4074
+ // private eventMap: Map<string, Set<EventHandler>>;
4075
+ // private onceWrapperMap: Map<EventHandler, EventHandler>;
4028
4076
  __publicField(this, "propertyKey");
4029
4077
  __publicField(this, "Url", "");
4030
4078
  __publicField(this, "Path", "");
@@ -4036,6 +4084,7 @@ class SnailMethod {
4036
4084
  const [serverName] = this.apiInstance.name.split(".");
4037
4085
  const axios2 = AxiosInstanceMap.get(serverName);
4038
4086
  if (!axios2) throw new Error("AxiosInstance not created");
4087
+ const serverStatusCodeRule = ServerStatusCodeRuleMap.get(serverName);
4039
4088
  const strategies = this.getStrategies();
4040
4089
  this.Request = await applyStrategies(this.Request, strategies, "request");
4041
4090
  this.Request = this.applyProgress(this.Request);
@@ -4062,9 +4111,9 @@ class SnailMethod {
4062
4111
  const { data: data2 } = await this.getCacheData(serverName);
4063
4112
  this.enableLog() && console.log("getCacheData:", data2);
4064
4113
  if (data2) {
4065
- this.emit("hitCache", data2);
4066
- this.emit("success", data2);
4067
- this.emit("finish", data2);
4114
+ this.EventEmit.emit("hitCache", data2);
4115
+ this.EventEmit.emit("success", data2);
4116
+ this.EventEmit.emit("finish", data2);
4068
4117
  return data2;
4069
4118
  }
4070
4119
  }
@@ -4083,71 +4132,43 @@ class SnailMethod {
4083
4132
  }
4084
4133
  this.Response = response;
4085
4134
  this.applyHitSource(serverName);
4086
- this.emit("success", response.data);
4087
- this.emit("finish", response.data);
4088
4135
  isSpecial && console.log("isSpecial:", isSpecial);
4089
- if (isSpecial) return response;
4136
+ if (isSpecial) {
4137
+ this.EventEmit.emit("success", response.data);
4138
+ this.EventEmit.emit("finish", response.data);
4139
+ return response;
4140
+ }
4090
4141
  !isSpecial && console.log("isSpecial:", isSpecial);
4142
+ if (serverStatusCodeRule) {
4143
+ const { key, rule } = serverStatusCodeRule;
4144
+ const statuCodeKey = key ?? "code";
4145
+ const data2 = response.data;
4146
+ if (rule(data2[statuCodeKey])) {
4147
+ this.EventEmit.emit("success", response.data);
4148
+ } else {
4149
+ this.EventEmit.emit("error", response.data);
4150
+ }
4151
+ }
4091
4152
  return response.data;
4092
4153
  } catch (error) {
4093
- this.emit("error", error);
4094
- this.emit("finish", error);
4154
+ this.EventEmit.emit("error", error);
4155
+ this.EventEmit.emit("finish", error);
4095
4156
  console.error(error);
4096
4157
  this.Error = error;
4097
4158
  return error;
4098
4159
  }
4099
4160
  });
4100
- __publicField(this, "onSuccess", (handler) => {
4101
- this.on("success", handler);
4161
+ __publicField(this, "onSuccess", (listener) => {
4162
+ this.EventEmit.on("success", listener);
4102
4163
  });
4103
- __publicField(this, "onError", (handler) => {
4104
- this.on("error", handler);
4164
+ __publicField(this, "onError", (listener) => {
4165
+ this.EventEmit.on("error", listener);
4105
4166
  });
4106
- __publicField(this, "onHitCache", (handler) => {
4107
- this.on("hitCache", handler);
4167
+ __publicField(this, "onHitCache", (listener) => {
4168
+ this.EventEmit.on("hitCache", listener);
4108
4169
  });
4109
- __publicField(this, "onFinish", (handler) => {
4110
- this.on("finish", handler);
4111
- });
4112
- __publicField(this, "on", (eventName, handler) => {
4113
- if (typeof handler !== "function") {
4114
- throw new TypeError("Handler must be a function");
4115
- }
4116
- const handlers = this.eventMap.get(eventName) || /* @__PURE__ */ new Set();
4117
- handlers.add(handler);
4118
- this.eventMap.set(eventName, handlers);
4119
- });
4120
- __publicField(this, "once", (eventName, handler) => {
4121
- const onceHandler = (data) => {
4122
- try {
4123
- handler.apply(this, [data]);
4124
- } finally {
4125
- this.off(eventName, onceHandler);
4126
- this.onceWrapperMap.delete(handler);
4127
- }
4128
- };
4129
- this.onceWrapperMap.set(handler, onceHandler);
4130
- this.on(eventName, onceHandler);
4131
- });
4132
- __publicField(this, "emit", (eventName, ...args) => {
4133
- const handlers = this.eventMap.get(eventName);
4134
- if (!handlers || handlers.size === 0) return false;
4135
- handlers.forEach((handler) => {
4136
- Promise.resolve().then(() => {
4137
- handler.apply(this, args);
4138
- });
4139
- });
4140
- return true;
4141
- });
4142
- __publicField(this, "off", (eventName, handler) => {
4143
- const handlers = this.eventMap.get(eventName);
4144
- if (!handlers) return;
4145
- if (handlers.has(handler)) {
4146
- handlers.delete(handler);
4147
- }
4148
- if (handlers.size === 0) {
4149
- this.eventMap.delete(eventName);
4150
- }
4170
+ __publicField(this, "onFinish", (listener) => {
4171
+ this.EventEmit.on("finish", listener);
4151
4172
  });
4152
4173
  __publicField(this, "registerStrategies", (...strategys) => {
4153
4174
  this.strategies.push(...strategys);
@@ -4158,12 +4179,7 @@ class SnailMethod {
4158
4179
  this.Args = args ?? [];
4159
4180
  this.init();
4160
4181
  this.enableLog() && console.log("url:", this.Url);
4161
- this.eventMap = /* @__PURE__ */ new Map();
4162
- this.onceWrapperMap = /* @__PURE__ */ new Map();
4163
- this.eventMap.set("success", /* @__PURE__ */ new Set());
4164
- this.eventMap.set("hitCache", /* @__PURE__ */ new Set());
4165
- this.eventMap.set("error", /* @__PURE__ */ new Set());
4166
- this.eventMap.set("finish", /* @__PURE__ */ new Set());
4182
+ this.EventEmit = new SnailEvent();
4167
4183
  }
4168
4184
  init() {
4169
4185
  const methodOptions = this.getMethodOptions();
@@ -4378,6 +4394,7 @@ const ExpireSourceMap = /* @__PURE__ */ new Map();
4378
4394
  const AxiosInstanceMap = /* @__PURE__ */ new Map();
4379
4395
  const StrategyMap = /* @__PURE__ */ new Map();
4380
4396
  const VersioningMap = /* @__PURE__ */ new Map();
4397
+ const ServerStatusCodeRuleMap = /* @__PURE__ */ new Map();
4381
4398
  const defaultCacheManageOptions = {
4382
4399
  type: CacheType.Memory,
4383
4400
  ttl: 500
@@ -4406,9 +4423,19 @@ class SnailServer {
4406
4423
  }
4407
4424
  init() {
4408
4425
  const options = this.getServerOptions();
4409
- const { baseURL, timeout, cacheManage, enableLog, cacheFor } = options;
4426
+ const {
4427
+ baseURL,
4428
+ timeout,
4429
+ cacheManage,
4430
+ enableLog,
4431
+ cacheFor,
4432
+ serverStatusCodeRule
4433
+ } = options;
4410
4434
  this.BaseURL = baseURL ?? resolveUrl("");
4411
4435
  this.initAxios({ baseURL, timeout });
4436
+ if (serverStatusCodeRule) {
4437
+ this.initServerStatusCodeRule(serverStatusCodeRule);
4438
+ }
4412
4439
  this.initStrategy();
4413
4440
  this.initCacheManage(cacheManage, cacheFor);
4414
4441
  this.initVersioning();
@@ -4416,6 +4443,9 @@ class SnailServer {
4416
4443
  this.EnableLog = enableLog ?? false;
4417
4444
  this.initLog(enableLog);
4418
4445
  }
4446
+ initServerStatusCodeRule(ruleOptions) {
4447
+ ServerStatusCodeRuleMap.set(this.name, ruleOptions);
4448
+ }
4419
4449
  initLog(enableLog) {
4420
4450
  if (enableLog) {
4421
4451
  const axiosInstance = AxiosInstanceMap.get(this.Name);
@@ -4787,7 +4817,6 @@ export {
4787
4817
  CacheType,
4788
4818
  Data,
4789
4819
  Delete,
4790
- EventType,
4791
4820
  Get,
4792
4821
  Head,
4793
4822
  HitSource,
@@ -4806,6 +4835,7 @@ export {
4806
4835
  SnailMethod,
4807
4836
  SnailPass,
4808
4837
  SnailServer,
4838
+ SnailServerStatusCodeRuleOptions,
4809
4839
  SnailSse,
4810
4840
  Sse,
4811
4841
  SseEvent,
@@ -3731,6 +3731,12 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
3731
3731
  RequestMethodEnum2["OPTIONS"] = "Options";
3732
3732
  return RequestMethodEnum2;
3733
3733
  })(RequestMethodEnum || {});
3734
+ class SnailServerStatusCodeRuleOptions {
3735
+ constructor() {
3736
+ __publicField(this, "key");
3737
+ __publicField(this, "rule");
3738
+ }
3739
+ }
3734
3740
  var VersioningType = /* @__PURE__ */ ((VersioningType2) => {
3735
3741
  VersioningType2[VersioningType2["Uri"] = 0] = "Uri";
3736
3742
  VersioningType2[VersioningType2["Header"] = 1] = "Header";
@@ -3762,13 +3768,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
3762
3768
  __publicField(this, "version");
3763
3769
  }
3764
3770
  }
3765
- var EventType = /* @__PURE__ */ ((EventType2) => {
3766
- EventType2["Success"] = "success";
3767
- EventType2["Error"] = "error";
3768
- EventType2["hitCache"] = "hitCache";
3769
- EventType2["Finish"] = "finish";
3770
- return EventType2;
3771
- })(EventType || {});
3772
3771
  function createCache(optios) {
3773
3772
  const { type } = optios;
3774
3773
  if (type === CacheType.Custom) {
@@ -3974,6 +3973,54 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
3974
3973
  Reflect.defineMetadata(CACHE_EXPIRE_SOURCE_KEY, sources, target);
3975
3974
  };
3976
3975
  };
3976
+ class SnailEvent {
3977
+ constructor() {
3978
+ __publicField(this, "eventMap");
3979
+ __publicField(this, "onceWrapperMap");
3980
+ __publicField(this, "on", (eventName, listener) => {
3981
+ if (typeof listener !== "function") {
3982
+ throw new TypeError("Handler must be a function");
3983
+ }
3984
+ const listeners = this.eventMap.get(eventName) || /* @__PURE__ */ new Set();
3985
+ listeners.add(listener);
3986
+ this.eventMap.set(eventName, listeners);
3987
+ });
3988
+ __publicField(this, "off", (eventName, listener) => {
3989
+ const listeners = this.eventMap.get(eventName);
3990
+ if (!listeners) return;
3991
+ if (this.onceWrapperMap.has(listener)) {
3992
+ this.onceWrapperMap.delete(listener);
3993
+ }
3994
+ if (listeners.size === 0) {
3995
+ this.eventMap.delete(eventName);
3996
+ }
3997
+ });
3998
+ __publicField(this, "once", (eventName, listener) => {
3999
+ const onceHandler = (data) => {
4000
+ try {
4001
+ listener.apply(this, [data]);
4002
+ } finally {
4003
+ this.off(eventName, onceHandler);
4004
+ this.onceWrapperMap.delete(listener);
4005
+ }
4006
+ };
4007
+ this.onceWrapperMap.set(listener, onceHandler);
4008
+ this.on(eventName, onceHandler);
4009
+ });
4010
+ __publicField(this, "emit", (eventName, ...args) => {
4011
+ const listeners = this.eventMap.get(eventName);
4012
+ if (!listeners || listeners.size === 0) return false;
4013
+ listeners.forEach((listener) => {
4014
+ Promise.resolve().then(() => {
4015
+ listener.apply(this, args);
4016
+ });
4017
+ });
4018
+ return true;
4019
+ });
4020
+ this.eventMap = /* @__PURE__ */ new Map();
4021
+ this.onceWrapperMap = /* @__PURE__ */ new Map();
4022
+ }
4023
+ }
3977
4024
  const versionHandlers = {
3978
4025
  [VersioningType.Uri]: (version, versioning) => {
3979
4026
  const prefix = versioning.prefix || "v";
@@ -4027,8 +4074,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4027
4074
  __publicField(this, "Request");
4028
4075
  __publicField(this, "Response");
4029
4076
  __publicField(this, "Error");
4030
- __publicField(this, "eventMap");
4031
- __publicField(this, "onceWrapperMap");
4077
+ __publicField(this, "EventEmit");
4078
+ // private eventMap: Map<string, Set<EventHandler>>;
4079
+ // private onceWrapperMap: Map<EventHandler, EventHandler>;
4032
4080
  __publicField(this, "propertyKey");
4033
4081
  __publicField(this, "Url", "");
4034
4082
  __publicField(this, "Path", "");
@@ -4040,6 +4088,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4040
4088
  const [serverName] = this.apiInstance.name.split(".");
4041
4089
  const axios2 = AxiosInstanceMap.get(serverName);
4042
4090
  if (!axios2) throw new Error("AxiosInstance not created");
4091
+ const serverStatusCodeRule = ServerStatusCodeRuleMap.get(serverName);
4043
4092
  const strategies = this.getStrategies();
4044
4093
  this.Request = await applyStrategies(this.Request, strategies, "request");
4045
4094
  this.Request = this.applyProgress(this.Request);
@@ -4066,9 +4115,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4066
4115
  const { data: data2 } = await this.getCacheData(serverName);
4067
4116
  this.enableLog() && console.log("getCacheData:", data2);
4068
4117
  if (data2) {
4069
- this.emit("hitCache", data2);
4070
- this.emit("success", data2);
4071
- this.emit("finish", data2);
4118
+ this.EventEmit.emit("hitCache", data2);
4119
+ this.EventEmit.emit("success", data2);
4120
+ this.EventEmit.emit("finish", data2);
4072
4121
  return data2;
4073
4122
  }
4074
4123
  }
@@ -4087,71 +4136,43 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4087
4136
  }
4088
4137
  this.Response = response;
4089
4138
  this.applyHitSource(serverName);
4090
- this.emit("success", response.data);
4091
- this.emit("finish", response.data);
4092
4139
  isSpecial && console.log("isSpecial:", isSpecial);
4093
- if (isSpecial) return response;
4140
+ if (isSpecial) {
4141
+ this.EventEmit.emit("success", response.data);
4142
+ this.EventEmit.emit("finish", response.data);
4143
+ return response;
4144
+ }
4094
4145
  !isSpecial && console.log("isSpecial:", isSpecial);
4146
+ if (serverStatusCodeRule) {
4147
+ const { key, rule } = serverStatusCodeRule;
4148
+ const statuCodeKey = key ?? "code";
4149
+ const data2 = response.data;
4150
+ if (rule(data2[statuCodeKey])) {
4151
+ this.EventEmit.emit("success", response.data);
4152
+ } else {
4153
+ this.EventEmit.emit("error", response.data);
4154
+ }
4155
+ }
4095
4156
  return response.data;
4096
4157
  } catch (error) {
4097
- this.emit("error", error);
4098
- this.emit("finish", error);
4158
+ this.EventEmit.emit("error", error);
4159
+ this.EventEmit.emit("finish", error);
4099
4160
  console.error(error);
4100
4161
  this.Error = error;
4101
4162
  return error;
4102
4163
  }
4103
4164
  });
4104
- __publicField(this, "onSuccess", (handler) => {
4105
- this.on("success", handler);
4165
+ __publicField(this, "onSuccess", (listener) => {
4166
+ this.EventEmit.on("success", listener);
4106
4167
  });
4107
- __publicField(this, "onError", (handler) => {
4108
- this.on("error", handler);
4168
+ __publicField(this, "onError", (listener) => {
4169
+ this.EventEmit.on("error", listener);
4109
4170
  });
4110
- __publicField(this, "onHitCache", (handler) => {
4111
- this.on("hitCache", handler);
4171
+ __publicField(this, "onHitCache", (listener) => {
4172
+ this.EventEmit.on("hitCache", listener);
4112
4173
  });
4113
- __publicField(this, "onFinish", (handler) => {
4114
- this.on("finish", handler);
4115
- });
4116
- __publicField(this, "on", (eventName, handler) => {
4117
- if (typeof handler !== "function") {
4118
- throw new TypeError("Handler must be a function");
4119
- }
4120
- const handlers = this.eventMap.get(eventName) || /* @__PURE__ */ new Set();
4121
- handlers.add(handler);
4122
- this.eventMap.set(eventName, handlers);
4123
- });
4124
- __publicField(this, "once", (eventName, handler) => {
4125
- const onceHandler = (data) => {
4126
- try {
4127
- handler.apply(this, [data]);
4128
- } finally {
4129
- this.off(eventName, onceHandler);
4130
- this.onceWrapperMap.delete(handler);
4131
- }
4132
- };
4133
- this.onceWrapperMap.set(handler, onceHandler);
4134
- this.on(eventName, onceHandler);
4135
- });
4136
- __publicField(this, "emit", (eventName, ...args) => {
4137
- const handlers = this.eventMap.get(eventName);
4138
- if (!handlers || handlers.size === 0) return false;
4139
- handlers.forEach((handler) => {
4140
- Promise.resolve().then(() => {
4141
- handler.apply(this, args);
4142
- });
4143
- });
4144
- return true;
4145
- });
4146
- __publicField(this, "off", (eventName, handler) => {
4147
- const handlers = this.eventMap.get(eventName);
4148
- if (!handlers) return;
4149
- if (handlers.has(handler)) {
4150
- handlers.delete(handler);
4151
- }
4152
- if (handlers.size === 0) {
4153
- this.eventMap.delete(eventName);
4154
- }
4174
+ __publicField(this, "onFinish", (listener) => {
4175
+ this.EventEmit.on("finish", listener);
4155
4176
  });
4156
4177
  __publicField(this, "registerStrategies", (...strategys) => {
4157
4178
  this.strategies.push(...strategys);
@@ -4162,12 +4183,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4162
4183
  this.Args = args ?? [];
4163
4184
  this.init();
4164
4185
  this.enableLog() && console.log("url:", this.Url);
4165
- this.eventMap = /* @__PURE__ */ new Map();
4166
- this.onceWrapperMap = /* @__PURE__ */ new Map();
4167
- this.eventMap.set("success", /* @__PURE__ */ new Set());
4168
- this.eventMap.set("hitCache", /* @__PURE__ */ new Set());
4169
- this.eventMap.set("error", /* @__PURE__ */ new Set());
4170
- this.eventMap.set("finish", /* @__PURE__ */ new Set());
4186
+ this.EventEmit = new SnailEvent();
4171
4187
  }
4172
4188
  init() {
4173
4189
  const methodOptions = this.getMethodOptions();
@@ -4382,6 +4398,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4382
4398
  const AxiosInstanceMap = /* @__PURE__ */ new Map();
4383
4399
  const StrategyMap = /* @__PURE__ */ new Map();
4384
4400
  const VersioningMap = /* @__PURE__ */ new Map();
4401
+ const ServerStatusCodeRuleMap = /* @__PURE__ */ new Map();
4385
4402
  const defaultCacheManageOptions = {
4386
4403
  type: CacheType.Memory,
4387
4404
  ttl: 500
@@ -4410,9 +4427,19 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4410
4427
  }
4411
4428
  init() {
4412
4429
  const options = this.getServerOptions();
4413
- const { baseURL, timeout, cacheManage, enableLog, cacheFor } = options;
4430
+ const {
4431
+ baseURL,
4432
+ timeout,
4433
+ cacheManage,
4434
+ enableLog,
4435
+ cacheFor,
4436
+ serverStatusCodeRule
4437
+ } = options;
4414
4438
  this.BaseURL = baseURL ?? resolveUrl("");
4415
4439
  this.initAxios({ baseURL, timeout });
4440
+ if (serverStatusCodeRule) {
4441
+ this.initServerStatusCodeRule(serverStatusCodeRule);
4442
+ }
4416
4443
  this.initStrategy();
4417
4444
  this.initCacheManage(cacheManage, cacheFor);
4418
4445
  this.initVersioning();
@@ -4420,6 +4447,9 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4420
4447
  this.EnableLog = enableLog ?? false;
4421
4448
  this.initLog(enableLog);
4422
4449
  }
4450
+ initServerStatusCodeRule(ruleOptions) {
4451
+ ServerStatusCodeRuleMap.set(this.name, ruleOptions);
4452
+ }
4423
4453
  initLog(enableLog) {
4424
4454
  if (enableLog) {
4425
4455
  const axiosInstance = AxiosInstanceMap.get(this.Name);
@@ -4790,7 +4820,6 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4790
4820
  exports2.CacheType = CacheType;
4791
4821
  exports2.Data = Data;
4792
4822
  exports2.Delete = Delete;
4793
- exports2.EventType = EventType;
4794
4823
  exports2.Get = Get;
4795
4824
  exports2.Head = Head;
4796
4825
  exports2.HitSource = HitSource;
@@ -4809,6 +4838,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
4809
4838
  exports2.SnailMethod = SnailMethod;
4810
4839
  exports2.SnailPass = SnailPass;
4811
4840
  exports2.SnailServer = SnailServer;
4841
+ exports2.SnailServerStatusCodeRuleOptions = SnailServerStatusCodeRuleOptions;
4812
4842
  exports2.SnailSse = SnailSse;
4813
4843
  exports2.Sse = Sse;
4814
4844
  exports2.SseEvent = SseEvent;
@@ -6,7 +6,7 @@ export type ApiResponse<T> = Promise<{
6
6
  hitCache?: boolean;
7
7
  }>;
8
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>(...args: A) => SnailMethod<RD extends SpecialResponseData ? RD : never> : <RD>(...args: A) => RD extends SpecialResponseData ? SnailMethod<RD> : SnailMethod<RT & {
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 & {
10
10
  [KK in DK]: RD;
11
11
  }> : T[K];
12
12
  };
@@ -10,3 +10,4 @@ export * from "./strategy";
10
10
  export * from "./apiProxy";
11
11
  export * from "./sse";
12
12
  export * from "./snail.method";
13
+ export * from "./snail.event";
@@ -0,0 +1,6 @@
1
+ import { AxiosResponse } from "axios";
2
+ export type SnailSuccessListener<T = any> = (data?: T) => void;
3
+ export type SnailErrorListener<T = any, ErrorData = any> = (response?: AxiosResponse<T> | Error | ErrorData) => void;
4
+ export type SnailHitCacheListener<T = any> = (cacheData?: T) => void;
5
+ export type SnailFinishListener<T = any> = (data?: T) => void;
6
+ export type SnailEventListener<T = any, ErrorData = any> = SnailSuccessListener<T> | SnailErrorListener<T, ErrorData> | SnailHitCacheListener<T> | SnailFinishListener<T>;
@@ -1,11 +1,3 @@
1
1
  import { AxiosResponse } from "axios";
2
2
  import { ResponseData, ResponseJsonData, StandardResponseData, SpecialResponseData } from "./response.data";
3
- export type EventHandler<T = any> = (data?: T) => void;
4
- export declare enum EventType {
5
- Success = "success",
6
- Error = "error",
7
- hitCache = "hitCache",
8
- Finish = "finish"
9
- }
10
- export type SnailMethodEventType = `${EventType}` | EventType | string;
11
3
  export type SendRequest<RD extends ResponseData = StandardResponseData<ResponseJsonData>> = () => Promise<RD extends SpecialResponseData ? AxiosResponse<RD> : RD>;
@@ -1,6 +1,10 @@
1
1
  import { CacheManagementOption } from "./cache.management.option";
2
2
  import { RequestMethod } from "./request.method";
3
3
  export type CacheForType = "All" | "all" | RequestMethod | RequestMethod[];
4
+ export declare class SnailServerStatusCodeRuleOptions {
5
+ key?: string;
6
+ rule: (status: number) => boolean;
7
+ }
4
8
  export interface SnailOption {
5
9
  name?: string;
6
10
  baseURL?: string;
@@ -8,4 +12,5 @@ export interface SnailOption {
8
12
  cacheFor?: CacheForType;
9
13
  enableLog?: boolean;
10
14
  timeout?: number;
15
+ serverStatusCodeRule?: SnailServerStatusCodeRuleOptions;
11
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@snail-js/api",
3
- "version": "0.1.20",
3
+ "version": "0.1.22",
4
4
  "description": "Http Request with Decorators Api, build on axios",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",