@snail-js/api 0.1.14 → 0.1.16

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.
Files changed (36) hide show
  1. package/README.md +223 -73
  2. package/README_EN.md +592 -0
  3. package/dist/cache/index.d.ts +6 -2
  4. package/dist/cache/indexDBCache.d.ts +7 -22
  5. package/dist/cache/localstorageCache.d.ts +7 -22
  6. package/dist/cache/memoryCache.d.ts +8 -23
  7. package/dist/core/index.d.ts +4 -1
  8. package/dist/core/snailApi.d.ts +22 -0
  9. package/dist/core/snailMethod.d.ts +54 -0
  10. package/dist/core/snailServer.d.ts +34 -0
  11. package/dist/core/snailSse.d.ts +20 -0
  12. package/dist/decorators/api.d.ts +9 -9
  13. package/dist/decorators/{param.d.ts → args.d.ts} +6 -0
  14. package/dist/decorators/cache.d.ts +11 -6
  15. package/dist/decorators/sse.d.ts +2 -3
  16. package/dist/decorators/strategy.d.ts +1 -1
  17. package/dist/index.d.ts +2 -2
  18. package/dist/snail-api.js +1125 -531
  19. package/dist/snail-api.umd.cjs +1126 -532
  20. package/dist/typings/api.option.d.ts +16 -0
  21. package/dist/typings/apiProxy.d.ts +5 -4
  22. package/dist/typings/cache.management.option.d.ts +16 -10
  23. package/dist/typings/cache.type.d.ts +17 -2
  24. package/dist/typings/index.d.ts +2 -1
  25. package/dist/typings/request.method.d.ts +9 -8
  26. package/dist/typings/response.data.d.ts +7 -3
  27. package/dist/typings/snail.method.d.ts +11 -0
  28. package/dist/typings/snail.option.d.ts +5 -1
  29. package/dist/typings/sse.d.ts +5 -1
  30. package/dist/typings/versioning.option.d.ts +2 -2
  31. package/dist/utils/function.d.ts +29 -8
  32. package/dist/versioning/index.d.ts +1 -0
  33. package/dist/versioning/versioning.d.ts +10 -5
  34. package/package.json +2 -1
  35. package/dist/core/snail.d.ts +0 -32
  36. package/dist/typings/api.config.d.ts +0 -9
package/dist/snail-api.js CHANGED
@@ -1461,7 +1461,7 @@ const utils$1 = {
1461
1461
  setImmediate: _setImmediate,
1462
1462
  asap
1463
1463
  };
1464
- function AxiosError$1(message, code, config, request, response) {
1464
+ function AxiosError(message, code, config, request, response) {
1465
1465
  Error.call(this);
1466
1466
  if (Error.captureStackTrace) {
1467
1467
  Error.captureStackTrace(this, this.constructor);
@@ -1478,7 +1478,7 @@ function AxiosError$1(message, code, config, request, response) {
1478
1478
  this.status = response.status ? response.status : null;
1479
1479
  }
1480
1480
  }
1481
- utils$1.inherits(AxiosError$1, Error, {
1481
+ utils$1.inherits(AxiosError, Error, {
1482
1482
  toJSON: function toJSON() {
1483
1483
  return {
1484
1484
  // Standard
@@ -1499,7 +1499,7 @@ utils$1.inherits(AxiosError$1, Error, {
1499
1499
  };
1500
1500
  }
1501
1501
  });
1502
- const prototype$1 = AxiosError$1.prototype;
1502
+ const prototype$1 = AxiosError.prototype;
1503
1503
  const descriptors = {};
1504
1504
  [
1505
1505
  "ERR_BAD_OPTION_VALUE",
@@ -1518,16 +1518,16 @@ const descriptors = {};
1518
1518
  ].forEach((code) => {
1519
1519
  descriptors[code] = { value: code };
1520
1520
  });
1521
- Object.defineProperties(AxiosError$1, descriptors);
1521
+ Object.defineProperties(AxiosError, descriptors);
1522
1522
  Object.defineProperty(prototype$1, "isAxiosError", { value: true });
1523
- AxiosError$1.from = (error, code, config, request, response, customProps) => {
1523
+ AxiosError.from = (error, code, config, request, response, customProps) => {
1524
1524
  const axiosError = Object.create(prototype$1);
1525
1525
  utils$1.toFlatObject(error, axiosError, function filter2(obj) {
1526
1526
  return obj !== Error.prototype;
1527
1527
  }, (prop) => {
1528
1528
  return prop !== "isAxiosError";
1529
1529
  });
1530
- AxiosError$1.call(axiosError, error.message, code, config, request, response);
1530
+ AxiosError.call(axiosError, error.message, code, config, request, response);
1531
1531
  axiosError.cause = error;
1532
1532
  axiosError.name = error.name;
1533
1533
  customProps && Object.assign(axiosError, customProps);
@@ -1553,7 +1553,7 @@ function isFlatArray(arr) {
1553
1553
  const predicates = utils$1.toFlatObject(utils$1, {}, null, function filter(prop) {
1554
1554
  return /^is[A-Z]/.test(prop);
1555
1555
  });
1556
- function toFormData$1(obj, formData, options) {
1556
+ function toFormData(obj, formData, options) {
1557
1557
  if (!utils$1.isObject(obj)) {
1558
1558
  throw new TypeError("target must be an object");
1559
1559
  }
@@ -1580,7 +1580,7 @@ function toFormData$1(obj, formData, options) {
1580
1580
  return value.toISOString();
1581
1581
  }
1582
1582
  if (!useBlob && utils$1.isBlob(value)) {
1583
- throw new AxiosError$1("Blob is not supported. Use a Buffer instead.");
1583
+ throw new AxiosError("Blob is not supported. Use a Buffer instead.");
1584
1584
  }
1585
1585
  if (utils$1.isArrayBuffer(value) || utils$1.isTypedArray(value)) {
1586
1586
  return useBlob && typeof Blob === "function" ? new Blob([value]) : Buffer.from(value);
@@ -1659,7 +1659,7 @@ function encode$1(str) {
1659
1659
  }
1660
1660
  function AxiosURLSearchParams(params, options) {
1661
1661
  this._pairs = [];
1662
- params && toFormData$1(params, this, options);
1662
+ params && toFormData(params, this, options);
1663
1663
  }
1664
1664
  const prototype = AxiosURLSearchParams.prototype;
1665
1665
  prototype.append = function append(name, value) {
@@ -1801,7 +1801,7 @@ const platform = {
1801
1801
  ...platform$1
1802
1802
  };
1803
1803
  function toURLEncodedForm(data, options) {
1804
- return toFormData$1(data, new platform.classes.URLSearchParams(), Object.assign({
1804
+ return toFormData(data, new platform.classes.URLSearchParams(), Object.assign({
1805
1805
  visitor: function(value, key, path, helpers) {
1806
1806
  if (platform.isNode && utils$1.isBuffer(value)) {
1807
1807
  this.append(key, value.toString("base64"));
@@ -1905,7 +1905,7 @@ const defaults = {
1905
1905
  }
1906
1906
  if ((isFileList2 = utils$1.isFileList(data)) || contentType.indexOf("multipart/form-data") > -1) {
1907
1907
  const _FormData = this.env && this.env.FormData;
1908
- return toFormData$1(
1908
+ return toFormData(
1909
1909
  isFileList2 ? { "files[]": data } : data,
1910
1910
  _FormData && new _FormData(),
1911
1911
  this.formSerializer
@@ -1933,7 +1933,7 @@ const defaults = {
1933
1933
  } catch (e) {
1934
1934
  if (strictJSONParsing) {
1935
1935
  if (e.name === "SyntaxError") {
1936
- throw AxiosError$1.from(e, AxiosError$1.ERR_BAD_RESPONSE, this, null, this.response);
1936
+ throw AxiosError.from(e, AxiosError.ERR_BAD_RESPONSE, this, null, this.response);
1937
1937
  }
1938
1938
  throw e;
1939
1939
  }
@@ -2061,7 +2061,7 @@ function buildAccessors(obj, header) {
2061
2061
  });
2062
2062
  });
2063
2063
  }
2064
- let AxiosHeaders$1 = class AxiosHeaders {
2064
+ class AxiosHeaders {
2065
2065
  constructor(headers) {
2066
2066
  headers && this.set(headers);
2067
2067
  }
@@ -2216,9 +2216,9 @@ let AxiosHeaders$1 = class AxiosHeaders {
2216
2216
  utils$1.isArray(header) ? header.forEach(defineAccessor) : defineAccessor(header);
2217
2217
  return this;
2218
2218
  }
2219
- };
2220
- AxiosHeaders$1.accessor(["Content-Type", "Content-Length", "Accept", "Accept-Encoding", "User-Agent", "Authorization"]);
2221
- utils$1.reduceDescriptors(AxiosHeaders$1.prototype, ({ value }, key) => {
2219
+ }
2220
+ AxiosHeaders.accessor(["Content-Type", "Content-Length", "Accept", "Accept-Encoding", "User-Agent", "Authorization"]);
2221
+ utils$1.reduceDescriptors(AxiosHeaders.prototype, ({ value }, key) => {
2222
2222
  let mapped = key[0].toUpperCase() + key.slice(1);
2223
2223
  return {
2224
2224
  get: () => value,
@@ -2227,11 +2227,11 @@ utils$1.reduceDescriptors(AxiosHeaders$1.prototype, ({ value }, key) => {
2227
2227
  }
2228
2228
  };
2229
2229
  });
2230
- utils$1.freezeMethods(AxiosHeaders$1);
2230
+ utils$1.freezeMethods(AxiosHeaders);
2231
2231
  function transformData(fns, response) {
2232
2232
  const config = this || defaults;
2233
2233
  const context = response || config;
2234
- const headers = AxiosHeaders$1.from(context.headers);
2234
+ const headers = AxiosHeaders.from(context.headers);
2235
2235
  let data = context.data;
2236
2236
  utils$1.forEach(fns, function transform(fn) {
2237
2237
  data = fn.call(config, data, headers.normalize(), response ? response.status : void 0);
@@ -2239,14 +2239,14 @@ function transformData(fns, response) {
2239
2239
  headers.normalize();
2240
2240
  return data;
2241
2241
  }
2242
- function isCancel$1(value) {
2242
+ function isCancel(value) {
2243
2243
  return !!(value && value.__CANCEL__);
2244
2244
  }
2245
- function CanceledError$1(message, config, request) {
2246
- AxiosError$1.call(this, message == null ? "canceled" : message, AxiosError$1.ERR_CANCELED, config, request);
2245
+ function CanceledError(message, config, request) {
2246
+ AxiosError.call(this, message == null ? "canceled" : message, AxiosError.ERR_CANCELED, config, request);
2247
2247
  this.name = "CanceledError";
2248
2248
  }
2249
- utils$1.inherits(CanceledError$1, AxiosError$1, {
2249
+ utils$1.inherits(CanceledError, AxiosError, {
2250
2250
  __CANCEL__: true
2251
2251
  });
2252
2252
  function settle(resolve, reject, response) {
@@ -2254,9 +2254,9 @@ function settle(resolve, reject, response) {
2254
2254
  if (!response.status || !validateStatus2 || validateStatus2(response.status)) {
2255
2255
  resolve(response);
2256
2256
  } else {
2257
- reject(new AxiosError$1(
2257
+ reject(new AxiosError(
2258
2258
  "Request failed with status code " + response.status,
2259
- [AxiosError$1.ERR_BAD_REQUEST, AxiosError$1.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],
2259
+ [AxiosError.ERR_BAD_REQUEST, AxiosError.ERR_BAD_RESPONSE][Math.floor(response.status / 100) - 4],
2260
2260
  response.config,
2261
2261
  response.request,
2262
2262
  response
@@ -2415,8 +2415,8 @@ function buildFullPath(baseURL, requestedURL) {
2415
2415
  }
2416
2416
  return requestedURL;
2417
2417
  }
2418
- const headersToObject = (thing) => thing instanceof AxiosHeaders$1 ? { ...thing } : thing;
2419
- function mergeConfig$1(config1, config2) {
2418
+ const headersToObject = (thing) => thing instanceof AxiosHeaders ? { ...thing } : thing;
2419
+ function mergeConfig(config1, config2) {
2420
2420
  config2 = config2 || {};
2421
2421
  const config = {};
2422
2422
  function getMergedValue(target, source, prop, caseless) {
@@ -2494,9 +2494,9 @@ function mergeConfig$1(config1, config2) {
2494
2494
  return config;
2495
2495
  }
2496
2496
  const resolveConfig = (config) => {
2497
- const newConfig = mergeConfig$1({}, config);
2497
+ const newConfig = mergeConfig({}, config);
2498
2498
  let { data, withXSRFToken, xsrfHeaderName, xsrfCookieName, headers, auth } = newConfig;
2499
- newConfig.headers = headers = AxiosHeaders$1.from(headers);
2499
+ newConfig.headers = headers = AxiosHeaders.from(headers);
2500
2500
  newConfig.url = buildURL(buildFullPath(newConfig.baseURL, newConfig.url), config.params, config.paramsSerializer);
2501
2501
  if (auth) {
2502
2502
  headers.set(
@@ -2529,7 +2529,7 @@ const xhrAdapter = isXHRAdapterSupported && function(config) {
2529
2529
  return new Promise(function dispatchXhrRequest(resolve, reject) {
2530
2530
  const _config = resolveConfig(config);
2531
2531
  let requestData = _config.data;
2532
- const requestHeaders = AxiosHeaders$1.from(_config.headers).normalize();
2532
+ const requestHeaders = AxiosHeaders.from(_config.headers).normalize();
2533
2533
  let { responseType, onUploadProgress, onDownloadProgress } = _config;
2534
2534
  let onCanceled;
2535
2535
  let uploadThrottled, downloadThrottled;
@@ -2547,7 +2547,7 @@ const xhrAdapter = isXHRAdapterSupported && function(config) {
2547
2547
  if (!request) {
2548
2548
  return;
2549
2549
  }
2550
- const responseHeaders = AxiosHeaders$1.from(
2550
+ const responseHeaders = AxiosHeaders.from(
2551
2551
  "getAllResponseHeaders" in request && request.getAllResponseHeaders()
2552
2552
  );
2553
2553
  const responseData = !responseType || responseType === "text" || responseType === "json" ? request.responseText : request.response;
@@ -2585,11 +2585,11 @@ const xhrAdapter = isXHRAdapterSupported && function(config) {
2585
2585
  if (!request) {
2586
2586
  return;
2587
2587
  }
2588
- reject(new AxiosError$1("Request aborted", AxiosError$1.ECONNABORTED, config, request));
2588
+ reject(new AxiosError("Request aborted", AxiosError.ECONNABORTED, config, request));
2589
2589
  request = null;
2590
2590
  };
2591
2591
  request.onerror = function handleError() {
2592
- reject(new AxiosError$1("Network Error", AxiosError$1.ERR_NETWORK, config, request));
2592
+ reject(new AxiosError("Network Error", AxiosError.ERR_NETWORK, config, request));
2593
2593
  request = null;
2594
2594
  };
2595
2595
  request.ontimeout = function handleTimeout() {
@@ -2598,9 +2598,9 @@ const xhrAdapter = isXHRAdapterSupported && function(config) {
2598
2598
  if (_config.timeoutErrorMessage) {
2599
2599
  timeoutErrorMessage = _config.timeoutErrorMessage;
2600
2600
  }
2601
- reject(new AxiosError$1(
2601
+ reject(new AxiosError(
2602
2602
  timeoutErrorMessage,
2603
- transitional2.clarifyTimeoutError ? AxiosError$1.ETIMEDOUT : AxiosError$1.ECONNABORTED,
2603
+ transitional2.clarifyTimeoutError ? AxiosError.ETIMEDOUT : AxiosError.ECONNABORTED,
2604
2604
  config,
2605
2605
  request
2606
2606
  ));
@@ -2632,7 +2632,7 @@ const xhrAdapter = isXHRAdapterSupported && function(config) {
2632
2632
  if (!request) {
2633
2633
  return;
2634
2634
  }
2635
- reject(!cancel || cancel.type ? new CanceledError$1(null, config, request) : cancel);
2635
+ reject(!cancel || cancel.type ? new CanceledError(null, config, request) : cancel);
2636
2636
  request.abort();
2637
2637
  request = null;
2638
2638
  };
@@ -2643,7 +2643,7 @@ const xhrAdapter = isXHRAdapterSupported && function(config) {
2643
2643
  }
2644
2644
  const protocol = parseProtocol(_config.url);
2645
2645
  if (protocol && platform.protocols.indexOf(protocol) === -1) {
2646
- reject(new AxiosError$1("Unsupported protocol " + protocol + ":", AxiosError$1.ERR_BAD_REQUEST, config));
2646
+ reject(new AxiosError("Unsupported protocol " + protocol + ":", AxiosError.ERR_BAD_REQUEST, config));
2647
2647
  return;
2648
2648
  }
2649
2649
  request.send(requestData || null);
@@ -2659,12 +2659,12 @@ const composeSignals = (signals, timeout) => {
2659
2659
  aborted = true;
2660
2660
  unsubscribe();
2661
2661
  const err = reason instanceof Error ? reason : this.reason;
2662
- controller.abort(err instanceof AxiosError$1 ? err : new CanceledError$1(err instanceof Error ? err.message : err));
2662
+ controller.abort(err instanceof AxiosError ? err : new CanceledError(err instanceof Error ? err.message : err));
2663
2663
  }
2664
2664
  };
2665
2665
  let timer = timeout && setTimeout(() => {
2666
2666
  timer = null;
2667
- onabort(new AxiosError$1(`timeout ${timeout} of ms exceeded`, AxiosError$1.ETIMEDOUT));
2667
+ onabort(new AxiosError(`timeout ${timeout} of ms exceeded`, AxiosError.ETIMEDOUT));
2668
2668
  }, timeout);
2669
2669
  const unsubscribe = () => {
2670
2670
  if (signals) {
@@ -2787,7 +2787,7 @@ const resolvers = {
2787
2787
  isFetchSupported && ((res) => {
2788
2788
  ["text", "arrayBuffer", "blob", "formData", "stream"].forEach((type) => {
2789
2789
  !resolvers[type] && (resolvers[type] = utils$1.isFunction(res[type]) ? (res2) => res2[type]() : (_, config) => {
2790
- throw new AxiosError$1(`Response type '${type}' is not supported`, AxiosError$1.ERR_NOT_SUPPORT, config);
2790
+ throw new AxiosError(`Response type '${type}' is not supported`, AxiosError.ERR_NOT_SUPPORT, config);
2791
2791
  });
2792
2792
  });
2793
2793
  })(new Response());
@@ -2899,7 +2899,7 @@ const fetchAdapter = isFetchSupported && (async (config) => {
2899
2899
  return await new Promise((resolve, reject) => {
2900
2900
  settle(resolve, reject, {
2901
2901
  data: responseData,
2902
- headers: AxiosHeaders$1.from(response.headers),
2902
+ headers: AxiosHeaders.from(response.headers),
2903
2903
  status: response.status,
2904
2904
  statusText: response.statusText,
2905
2905
  config,
@@ -2910,13 +2910,13 @@ const fetchAdapter = isFetchSupported && (async (config) => {
2910
2910
  unsubscribe && unsubscribe();
2911
2911
  if (err && err.name === "TypeError" && /fetch/i.test(err.message)) {
2912
2912
  throw Object.assign(
2913
- new AxiosError$1("Network Error", AxiosError$1.ERR_NETWORK, config, request),
2913
+ new AxiosError("Network Error", AxiosError.ERR_NETWORK, config, request),
2914
2914
  {
2915
2915
  cause: err.cause || err
2916
2916
  }
2917
2917
  );
2918
2918
  }
2919
- throw AxiosError$1.from(err, err && err.code, config, request);
2919
+ throw AxiosError.from(err, err && err.code, config, request);
2920
2920
  }
2921
2921
  });
2922
2922
  const knownAdapters = {
@@ -2949,7 +2949,7 @@ const adapters = {
2949
2949
  if (!isResolvedHandle(nameOrAdapter)) {
2950
2950
  adapter = knownAdapters[(id = String(nameOrAdapter)).toLowerCase()];
2951
2951
  if (adapter === void 0) {
2952
- throw new AxiosError$1(`Unknown adapter '${id}'`);
2952
+ throw new AxiosError(`Unknown adapter '${id}'`);
2953
2953
  }
2954
2954
  }
2955
2955
  if (adapter) {
@@ -2962,7 +2962,7 @@ const adapters = {
2962
2962
  ([id, state]) => `adapter ${id} ` + (state === false ? "is not supported by the environment" : "is not available in the build")
2963
2963
  );
2964
2964
  let s = length ? reasons.length > 1 ? "since :\n" + reasons.map(renderReason).join("\n") : " " + renderReason(reasons[0]) : "as no adapter specified";
2965
- throw new AxiosError$1(
2965
+ throw new AxiosError(
2966
2966
  `There is no suitable adapter to dispatch the request ` + s,
2967
2967
  "ERR_NOT_SUPPORT"
2968
2968
  );
@@ -2976,12 +2976,12 @@ function throwIfCancellationRequested(config) {
2976
2976
  config.cancelToken.throwIfRequested();
2977
2977
  }
2978
2978
  if (config.signal && config.signal.aborted) {
2979
- throw new CanceledError$1(null, config);
2979
+ throw new CanceledError(null, config);
2980
2980
  }
2981
2981
  }
2982
2982
  function dispatchRequest(config) {
2983
2983
  throwIfCancellationRequested(config);
2984
- config.headers = AxiosHeaders$1.from(config.headers);
2984
+ config.headers = AxiosHeaders.from(config.headers);
2985
2985
  config.data = transformData.call(
2986
2986
  config,
2987
2987
  config.transformRequest
@@ -2997,10 +2997,10 @@ function dispatchRequest(config) {
2997
2997
  config.transformResponse,
2998
2998
  response
2999
2999
  );
3000
- response.headers = AxiosHeaders$1.from(response.headers);
3000
+ response.headers = AxiosHeaders.from(response.headers);
3001
3001
  return response;
3002
3002
  }, function onAdapterRejection(reason) {
3003
- if (!isCancel$1(reason)) {
3003
+ if (!isCancel(reason)) {
3004
3004
  throwIfCancellationRequested(config);
3005
3005
  if (reason && reason.response) {
3006
3006
  reason.response.data = transformData.call(
@@ -3008,13 +3008,13 @@ function dispatchRequest(config) {
3008
3008
  config.transformResponse,
3009
3009
  reason.response
3010
3010
  );
3011
- reason.response.headers = AxiosHeaders$1.from(reason.response.headers);
3011
+ reason.response.headers = AxiosHeaders.from(reason.response.headers);
3012
3012
  }
3013
3013
  }
3014
3014
  return Promise.reject(reason);
3015
3015
  });
3016
3016
  }
3017
- const VERSION$1 = "1.7.9";
3017
+ const VERSION = "1.7.9";
3018
3018
  const validators$1 = {};
3019
3019
  ["object", "boolean", "number", "function", "string", "symbol"].forEach((type, i) => {
3020
3020
  validators$1[type] = function validator2(thing) {
@@ -3024,13 +3024,13 @@ const validators$1 = {};
3024
3024
  const deprecatedWarnings = {};
3025
3025
  validators$1.transitional = function transitional(validator2, version, message) {
3026
3026
  function formatMessage(opt, desc) {
3027
- return "[Axios v" + VERSION$1 + "] Transitional option '" + opt + "'" + desc + (message ? ". " + message : "");
3027
+ return "[Axios v" + VERSION + "] Transitional option '" + opt + "'" + desc + (message ? ". " + message : "");
3028
3028
  }
3029
3029
  return (value, opt, opts) => {
3030
3030
  if (validator2 === false) {
3031
- throw new AxiosError$1(
3031
+ throw new AxiosError(
3032
3032
  formatMessage(opt, " has been removed" + (version ? " in " + version : "")),
3033
- AxiosError$1.ERR_DEPRECATED
3033
+ AxiosError.ERR_DEPRECATED
3034
3034
  );
3035
3035
  }
3036
3036
  if (version && !deprecatedWarnings[opt]) {
@@ -3053,7 +3053,7 @@ validators$1.spelling = function spelling(correctSpelling) {
3053
3053
  };
3054
3054
  function assertOptions(options, schema, allowUnknown) {
3055
3055
  if (typeof options !== "object") {
3056
- throw new AxiosError$1("options must be an object", AxiosError$1.ERR_BAD_OPTION_VALUE);
3056
+ throw new AxiosError("options must be an object", AxiosError.ERR_BAD_OPTION_VALUE);
3057
3057
  }
3058
3058
  const keys = Object.keys(options);
3059
3059
  let i = keys.length;
@@ -3064,12 +3064,12 @@ function assertOptions(options, schema, allowUnknown) {
3064
3064
  const value = options[opt];
3065
3065
  const result = value === void 0 || validator2(value, opt, options);
3066
3066
  if (result !== true) {
3067
- throw new AxiosError$1("option " + opt + " must be " + result, AxiosError$1.ERR_BAD_OPTION_VALUE);
3067
+ throw new AxiosError("option " + opt + " must be " + result, AxiosError.ERR_BAD_OPTION_VALUE);
3068
3068
  }
3069
3069
  continue;
3070
3070
  }
3071
3071
  if (allowUnknown !== true) {
3072
- throw new AxiosError$1("Unknown option " + opt, AxiosError$1.ERR_BAD_OPTION);
3072
+ throw new AxiosError("Unknown option " + opt, AxiosError.ERR_BAD_OPTION);
3073
3073
  }
3074
3074
  }
3075
3075
  }
@@ -3078,7 +3078,7 @@ const validator = {
3078
3078
  validators: validators$1
3079
3079
  };
3080
3080
  const validators = validator.validators;
3081
- let Axios$1 = class Axios {
3081
+ class Axios {
3082
3082
  constructor(instanceConfig) {
3083
3083
  this.defaults = instanceConfig;
3084
3084
  this.interceptors = {
@@ -3121,7 +3121,7 @@ let Axios$1 = class Axios {
3121
3121
  } else {
3122
3122
  config = configOrUrl || {};
3123
3123
  }
3124
- config = mergeConfig$1(this.defaults, config);
3124
+ config = mergeConfig(this.defaults, config);
3125
3125
  const { transitional: transitional2, paramsSerializer, headers } = config;
3126
3126
  if (transitional2 !== void 0) {
3127
3127
  validator.assertOptions(transitional2, {
@@ -3157,7 +3157,7 @@ let Axios$1 = class Axios {
3157
3157
  delete headers[method];
3158
3158
  }
3159
3159
  );
3160
- config.headers = AxiosHeaders$1.concat(contextHeaders, headers);
3160
+ config.headers = AxiosHeaders.concat(contextHeaders, headers);
3161
3161
  const requestInterceptorChain = [];
3162
3162
  let synchronousRequestInterceptors = true;
3163
3163
  this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {
@@ -3211,14 +3211,14 @@ let Axios$1 = class Axios {
3211
3211
  return promise;
3212
3212
  }
3213
3213
  getUri(config) {
3214
- config = mergeConfig$1(this.defaults, config);
3214
+ config = mergeConfig(this.defaults, config);
3215
3215
  const fullPath = buildFullPath(config.baseURL, config.url);
3216
3216
  return buildURL(fullPath, config.params, config.paramsSerializer);
3217
3217
  }
3218
- };
3218
+ }
3219
3219
  utils$1.forEach(["delete", "get", "head", "options"], function forEachMethodNoData(method) {
3220
- Axios$1.prototype[method] = function(url, config) {
3221
- return this.request(mergeConfig$1(config || {}, {
3220
+ Axios.prototype[method] = function(url, config) {
3221
+ return this.request(mergeConfig(config || {}, {
3222
3222
  method,
3223
3223
  url,
3224
3224
  data: (config || {}).data
@@ -3228,7 +3228,7 @@ utils$1.forEach(["delete", "get", "head", "options"], function forEachMethodNoDa
3228
3228
  utils$1.forEach(["post", "put", "patch"], function forEachMethodWithData(method) {
3229
3229
  function generateHTTPMethod(isForm) {
3230
3230
  return function httpMethod(url, data, config) {
3231
- return this.request(mergeConfig$1(config || {}, {
3231
+ return this.request(mergeConfig(config || {}, {
3232
3232
  method,
3233
3233
  headers: isForm ? {
3234
3234
  "Content-Type": "multipart/form-data"
@@ -3238,10 +3238,10 @@ utils$1.forEach(["post", "put", "patch"], function forEachMethodWithData(method)
3238
3238
  }));
3239
3239
  };
3240
3240
  }
3241
- Axios$1.prototype[method] = generateHTTPMethod();
3242
- Axios$1.prototype[method + "Form"] = generateHTTPMethod(true);
3241
+ Axios.prototype[method] = generateHTTPMethod();
3242
+ Axios.prototype[method + "Form"] = generateHTTPMethod(true);
3243
3243
  });
3244
- let CancelToken$1 = class CancelToken {
3244
+ class CancelToken {
3245
3245
  constructor(executor) {
3246
3246
  if (typeof executor !== "function") {
3247
3247
  throw new TypeError("executor must be a function.");
@@ -3274,7 +3274,7 @@ let CancelToken$1 = class CancelToken {
3274
3274
  if (token.reason) {
3275
3275
  return;
3276
3276
  }
3277
- token.reason = new CanceledError$1(message, config, request);
3277
+ token.reason = new CanceledError(message, config, request);
3278
3278
  resolvePromise(token.reason);
3279
3279
  });
3280
3280
  }
@@ -3335,16 +3335,16 @@ let CancelToken$1 = class CancelToken {
3335
3335
  cancel
3336
3336
  };
3337
3337
  }
3338
- };
3339
- function spread$1(callback) {
3338
+ }
3339
+ function spread(callback) {
3340
3340
  return function wrap(arr) {
3341
3341
  return callback.apply(null, arr);
3342
3342
  };
3343
3343
  }
3344
- function isAxiosError$1(payload) {
3344
+ function isAxiosError(payload) {
3345
3345
  return utils$1.isObject(payload) && payload.isAxiosError === true;
3346
3346
  }
3347
- const HttpStatusCode$1 = {
3347
+ const HttpStatusCode = {
3348
3348
  Continue: 100,
3349
3349
  SwitchingProtocols: 101,
3350
3350
  Processing: 102,
@@ -3409,102 +3409,115 @@ const HttpStatusCode$1 = {
3409
3409
  NotExtended: 510,
3410
3410
  NetworkAuthenticationRequired: 511
3411
3411
  };
3412
- Object.entries(HttpStatusCode$1).forEach(([key, value]) => {
3413
- HttpStatusCode$1[value] = key;
3412
+ Object.entries(HttpStatusCode).forEach(([key, value]) => {
3413
+ HttpStatusCode[value] = key;
3414
3414
  });
3415
3415
  function createInstance(defaultConfig) {
3416
- const context = new Axios$1(defaultConfig);
3417
- const instance = bind(Axios$1.prototype.request, context);
3418
- utils$1.extend(instance, Axios$1.prototype, context, { allOwnKeys: true });
3416
+ const context = new Axios(defaultConfig);
3417
+ const instance = bind(Axios.prototype.request, context);
3418
+ utils$1.extend(instance, Axios.prototype, context, { allOwnKeys: true });
3419
3419
  utils$1.extend(instance, context, null, { allOwnKeys: true });
3420
3420
  instance.create = function create(instanceConfig) {
3421
- return createInstance(mergeConfig$1(defaultConfig, instanceConfig));
3421
+ return createInstance(mergeConfig(defaultConfig, instanceConfig));
3422
3422
  };
3423
3423
  return instance;
3424
3424
  }
3425
3425
  const axios = createInstance(defaults);
3426
- axios.Axios = Axios$1;
3427
- axios.CanceledError = CanceledError$1;
3428
- axios.CancelToken = CancelToken$1;
3429
- axios.isCancel = isCancel$1;
3430
- axios.VERSION = VERSION$1;
3431
- axios.toFormData = toFormData$1;
3432
- axios.AxiosError = AxiosError$1;
3426
+ axios.Axios = Axios;
3427
+ axios.CanceledError = CanceledError;
3428
+ axios.CancelToken = CancelToken;
3429
+ axios.isCancel = isCancel;
3430
+ axios.VERSION = VERSION;
3431
+ axios.toFormData = toFormData;
3432
+ axios.AxiosError = AxiosError;
3433
3433
  axios.Cancel = axios.CanceledError;
3434
3434
  axios.all = function all(promises) {
3435
3435
  return Promise.all(promises);
3436
3436
  };
3437
- axios.spread = spread$1;
3438
- axios.isAxiosError = isAxiosError$1;
3439
- axios.mergeConfig = mergeConfig$1;
3440
- axios.AxiosHeaders = AxiosHeaders$1;
3437
+ axios.spread = spread;
3438
+ axios.isAxiosError = isAxiosError;
3439
+ axios.mergeConfig = mergeConfig;
3440
+ axios.AxiosHeaders = AxiosHeaders;
3441
3441
  axios.formToJSON = (thing) => formDataToJSON(utils$1.isHTMLForm(thing) ? new FormData(thing) : thing);
3442
3442
  axios.getAdapter = adapters.getAdapter;
3443
- axios.HttpStatusCode = HttpStatusCode$1;
3443
+ axios.HttpStatusCode = HttpStatusCode;
3444
3444
  axios.default = axios;
3445
- const {
3446
- Axios: Axios2,
3447
- AxiosError,
3448
- CanceledError,
3449
- isCancel,
3450
- CancelToken: CancelToken2,
3451
- VERSION,
3452
- all: all2,
3453
- Cancel,
3454
- isAxiosError,
3455
- spread,
3456
- toFormData,
3457
- AxiosHeaders: AxiosHeaders2,
3458
- HttpStatusCode,
3459
- formToJSON,
3460
- getAdapter,
3461
- mergeConfig
3462
- } = axios;
3463
3445
  class MemoryCache {
3464
3446
  constructor(ttl) {
3465
- __publicField(this, "cache", {});
3447
+ // private cache: Record<string, CacheSetData> = {};
3448
+ __publicField(this, "CacheMap", /* @__PURE__ */ new Map());
3466
3449
  __publicField(this, "ttl");
3467
3450
  this.ttl = ttl;
3468
3451
  }
3469
3452
  async get(key) {
3470
- const cacheRecord = this.cache;
3471
3453
  return new Promise((resolve, reject) => {
3472
3454
  try {
3473
- const cacheItem = cacheRecord[key];
3455
+ const cacheItem = this.CacheMap.get(key);
3474
3456
  if (!cacheItem) {
3475
- return resolve({ error: "[MemoryCache]未找到缓存,将执行请求", data: null });
3457
+ return resolve({
3458
+ error: new Error("[MemoryCache]未找到缓存,将执行请求"),
3459
+ data: null
3460
+ });
3476
3461
  }
3477
3462
  const { data, exp } = cacheItem;
3478
3463
  if (exp < Math.ceil((/* @__PURE__ */ new Date()).getTime() / 1e3)) {
3479
3464
  this.delete(key);
3480
- return resolve({ error: "[MemoryCache]缓存已过期,将执行请求", data: null });
3465
+ return resolve({
3466
+ error: new Error("[MemoryCache]缓存已过期,将执行请求"),
3467
+ data: null
3468
+ });
3481
3469
  }
3482
3470
  resolve({ error: null, data });
3483
3471
  } catch (error) {
3484
- reject({ error, data: null });
3472
+ console.error("[MemoryCache]获取缓存错误:", error);
3473
+ reject(error);
3485
3474
  }
3486
3475
  });
3487
3476
  }
3488
3477
  async set(key, value) {
3489
3478
  return new Promise((resolve, reject) => {
3490
3479
  try {
3491
- this.cache[key] = {
3480
+ this.CacheMap.set(key, {
3492
3481
  data: value,
3493
3482
  exp: Math.ceil((/* @__PURE__ */ new Date()).getTime() / 1e3) + this.ttl
3494
- };
3495
- resolve({ error: null, data: true });
3483
+ });
3484
+ resolve(true);
3496
3485
  } catch (error) {
3497
- reject({ error, data: null });
3486
+ console.error("[MemoryCache]设置缓存错误:", error);
3487
+ reject(error);
3498
3488
  }
3499
3489
  });
3500
3490
  }
3501
3491
  async delete(key) {
3502
3492
  return new Promise((resolve, reject) => {
3503
3493
  try {
3504
- delete this.cache[key];
3505
- resolve({ error: null, data: true });
3494
+ this.CacheMap.delete(key);
3495
+ resolve(true);
3506
3496
  } catch (error) {
3507
- reject({ error, data: null });
3497
+ console.error("[MemoryCache]删除缓存错误:", error);
3498
+ reject(error);
3499
+ }
3500
+ });
3501
+ }
3502
+ async clear() {
3503
+ return new Promise((resolve, reject) => {
3504
+ try {
3505
+ this.CacheMap.clear();
3506
+ resolve(true);
3507
+ } catch (error) {
3508
+ console.error("[MemoryCache]清空缓存错误:", error);
3509
+ reject(error);
3510
+ }
3511
+ });
3512
+ }
3513
+ async keys() {
3514
+ return new Promise((resolve, reject) => {
3515
+ try {
3516
+ const keys = Array.from(this.CacheMap.keys());
3517
+ resolve(keys);
3518
+ } catch (error) {
3519
+ console.error("[MemoryCache]获取缓存键错误:", error);
3520
+ reject(error);
3508
3521
  }
3509
3522
  });
3510
3523
  }
@@ -3519,12 +3532,18 @@ class LocalStorageCache {
3519
3532
  try {
3520
3533
  const cacheItem = localStorage.getItem(key);
3521
3534
  if (!cacheItem) {
3522
- return resolve({ error: `未找到${key}的缓存`, data: null });
3535
+ return resolve({
3536
+ error: new Error(`未找到${key}的缓存`),
3537
+ data: null
3538
+ });
3523
3539
  }
3524
3540
  const { data, exp } = JSON.parse(cacheItem);
3525
3541
  if (exp < Math.ceil((/* @__PURE__ */ new Date()).getTime() / 1e3)) {
3526
3542
  this.delete(key);
3527
- return resolve({ error: `${key}的缓存已过期`, data: null });
3543
+ return resolve({
3544
+ error: new Error(`${key}的缓存已过期`),
3545
+ data: null
3546
+ });
3528
3547
  }
3529
3548
  resolve({ error: null, data });
3530
3549
  } catch (error) {
@@ -3542,8 +3561,9 @@ class LocalStorageCache {
3542
3561
  exp: Math.ceil((/* @__PURE__ */ new Date()).getTime() / 1e3) + this.ttl
3543
3562
  })
3544
3563
  );
3545
- resolve({ error: null, data: true });
3564
+ resolve(true);
3546
3565
  } catch (error) {
3566
+ console.error("[LocalStorage]插入数据错误:", error);
3547
3567
  reject({ error, data: null });
3548
3568
  }
3549
3569
  });
@@ -3552,12 +3572,34 @@ class LocalStorageCache {
3552
3572
  return new Promise((resolve, reject) => {
3553
3573
  try {
3554
3574
  localStorage.removeItem(key);
3555
- resolve({ error: null, data: true });
3575
+ resolve(true);
3556
3576
  } catch (error) {
3557
- reject({ error, data: null });
3577
+ console.error("[LocalStorage]删除数据错误:", error);
3578
+ reject(error);
3558
3579
  }
3559
3580
  });
3560
3581
  }
3582
+ async clear() {
3583
+ return new Promise((resolve, reject) => {
3584
+ try {
3585
+ localStorage.clear();
3586
+ resolve(true);
3587
+ } catch (error) {
3588
+ console.error("[LocalStorage]清空数据错误:", error);
3589
+ reject(false);
3590
+ }
3591
+ });
3592
+ }
3593
+ async keys() {
3594
+ return new Promise((resolve) => {
3595
+ const keys = [];
3596
+ for (let i = 0; i < localStorage.length; i++) {
3597
+ const key = localStorage.key(i);
3598
+ if (key) keys.push(key);
3599
+ }
3600
+ resolve(keys);
3601
+ });
3602
+ }
3561
3603
  }
3562
3604
  const INDEXDB_DATABASE_NAME = "SNAIL_CACHE";
3563
3605
  const INDEXDB_VERSION = 3;
@@ -3627,13 +3669,11 @@ class IndexDBCache {
3627
3669
  key
3628
3670
  });
3629
3671
  select.onsuccess = () => {
3630
- resolve({ error: null, data: true });
3672
+ resolve(true);
3631
3673
  };
3632
3674
  select.onerror = (event) => {
3633
- reject({
3634
- error: new Error(`插入数据错误:${event.target}`),
3635
- data: null
3636
- });
3675
+ console.error(`[indexDB]插入数据错误:${event.target}`);
3676
+ reject(event);
3637
3677
  };
3638
3678
  });
3639
3679
  }
@@ -3644,27 +3684,49 @@ class IndexDBCache {
3644
3684
  }
3645
3685
  const select = this.db.transaction(INDEXDB_OBJECT_STORE_NAME, "readwrite").objectStore(INDEXDB_OBJECT_STORE_NAME).delete(key);
3646
3686
  select.onsuccess = () => {
3647
- resolve({ error: null, data: true });
3687
+ resolve(true);
3648
3688
  };
3649
3689
  select.onerror = (event) => {
3650
- reject({
3651
- error: new Error(`删除数据错误:${event.target}`),
3652
- data: null
3653
- });
3690
+ console.error(`[indexDB]删除数据错误:${event.target}`);
3691
+ reject(event);
3692
+ };
3693
+ });
3694
+ }
3695
+ async clear() {
3696
+ return new Promise(async (resolve, reject) => {
3697
+ if (!this.db) await this.init();
3698
+ const transaction = this.db.transaction(INDEXDB_OBJECT_STORE_NAME, "readwrite");
3699
+ const request = transaction.objectStore(INDEXDB_OBJECT_STORE_NAME).clear();
3700
+ request.onsuccess = () => resolve(true);
3701
+ request.onerror = (event) => {
3702
+ console.error(`[indexDB]清空数据错误:${event.target}`);
3703
+ reject(false);
3704
+ };
3705
+ });
3706
+ }
3707
+ async keys() {
3708
+ return new Promise(async (resolve, reject) => {
3709
+ if (!this.db) await this.init();
3710
+ const transaction = this.db.transaction(INDEXDB_OBJECT_STORE_NAME, "readonly");
3711
+ const request = transaction.objectStore(INDEXDB_OBJECT_STORE_NAME).getAllKeys();
3712
+ request.onsuccess = () => resolve(request.result.map((key) => key.toString()));
3713
+ request.onerror = (event) => {
3714
+ console.error(`[indexDB]获取键名错误:${event.target}`);
3715
+ reject([]);
3654
3716
  };
3655
3717
  });
3656
3718
  }
3657
3719
  }
3658
- var RequestMethod = /* @__PURE__ */ ((RequestMethod2) => {
3659
- RequestMethod2["GET"] = "GET";
3660
- RequestMethod2["HEAD"] = "HEAD";
3661
- RequestMethod2["POST"] = "POST";
3662
- RequestMethod2["PUT"] = "PUT";
3663
- RequestMethod2["DELETE"] = "DELETE";
3664
- RequestMethod2["PATCH"] = "PATCH";
3665
- RequestMethod2["OPTIONS"] = "OPTIONS";
3666
- return RequestMethod2;
3667
- })(RequestMethod || {});
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 || {});
3668
3730
  var VersioningType = /* @__PURE__ */ ((VersioningType2) => {
3669
3731
  VersioningType2[VersioningType2["Uri"] = 0] = "Uri";
3670
3732
  VersioningType2[VersioningType2["Header"] = 1] = "Header";
@@ -3676,36 +3738,70 @@ var CacheType = /* @__PURE__ */ ((CacheType2) => {
3676
3738
  CacheType2[CacheType2["Memory"] = 0] = "Memory";
3677
3739
  CacheType2[CacheType2["IndexDB"] = 1] = "IndexDB";
3678
3740
  CacheType2[CacheType2["LocalStorage"] = 2] = "LocalStorage";
3741
+ CacheType2[CacheType2["Custom"] = 3] = "Custom";
3679
3742
  return CacheType2;
3680
3743
  })(CacheType || {});
3744
+ class CacheStorageAdapter {
3745
+ }
3681
3746
  class Strategy {
3682
3747
  }
3683
- class RegisterSseEvent {
3748
+ class SseEventListener {
3684
3749
  constructor() {
3685
3750
  __publicField(this, "eventName");
3686
3751
  __publicField(this, "emit");
3687
3752
  __publicField(this, "options");
3688
3753
  }
3689
3754
  }
3690
- function createCache(type, ttl) {
3691
- if (type === CacheType.Memory) {
3692
- return new MemoryCache(ttl);
3755
+ class SseOptions {
3756
+ constructor() {
3757
+ __publicField(this, "withCredentials");
3758
+ __publicField(this, "version");
3759
+ }
3760
+ }
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
+ function createCache(optios) {
3769
+ const { type } = optios;
3770
+ if (type === CacheType.Custom) {
3771
+ const adapter = optios.adapter;
3772
+ return new adapter(optios.options);
3693
3773
  }
3694
3774
  if (type === CacheType.LocalStorage) {
3695
- return new LocalStorageCache(ttl);
3775
+ const { ttl: ttl2 } = optios;
3776
+ return new LocalStorageCache(ttl2);
3696
3777
  }
3697
3778
  if (type === CacheType.IndexDB) {
3698
- const db = new IndexDBCache(ttl);
3779
+ const { ttl: ttl2 } = optios;
3780
+ const db = new IndexDBCache(ttl2);
3699
3781
  db.init();
3700
3782
  return db;
3701
3783
  }
3702
- return void 0;
3784
+ const { ttl } = optios;
3785
+ return new MemoryCache(ttl);
3703
3786
  }
3704
- const apiKey = async (apiInstance) => {
3705
- const { version, method, url, params, headers } = apiInstance;
3706
- const str = `${params ? `-${recordToString(params)}` : ""}${headers ? `-${recordToString(headers)}` : ""}`;
3707
- return `[${method}]${version ? `-v${version}` : ""}-${url}-${await generateShortUniqueHash(str)}`;
3787
+ const REQUEST_ARGS_KEY = Symbol("SNAIL_REQUEST_ARGS_KEY");
3788
+ const Params = (key) => createArgsDecorator("params", key);
3789
+ const Query = (key) => createArgsDecorator("querys", key);
3790
+ const Data = (key) => createArgsDecorator("data", key);
3791
+ const createArgsDecorator = (type, key) => {
3792
+ return (target, propertyKey, parameterIndex) => {
3793
+ const args = Reflect.getMetadata(REQUEST_ARGS_KEY, target, propertyKey) || [];
3794
+ args.push({ index: parameterIndex, type, key });
3795
+ Reflect.defineMetadata(REQUEST_ARGS_KEY, args, target, propertyKey);
3796
+ };
3708
3797
  };
3798
+ async function generateCacheKey(methodName, version, request) {
3799
+ const { method, url, params, headers } = request;
3800
+ const hash = await generateShortUniqueHash(
3801
+ `${params ? `-${recordToString(params)}` : ""}${headers ? `-${recordToString(headers)}` : ""}`
3802
+ );
3803
+ return `${methodName}${version ? `[v${version}]` : ""}[${method}]${url}-${hash}`;
3804
+ }
3709
3805
  async function generateShortUniqueHash(str) {
3710
3806
  const encoder = new TextEncoder();
3711
3807
  const data = encoder.encode(str);
@@ -3720,42 +3816,73 @@ function recordToString(record) {
3720
3816
  return `${key}=${record[key]}`;
3721
3817
  }).sort((a, b) => a.localeCompare(b)).join("&");
3722
3818
  }
3723
- const versionHandlers = {
3724
- [VersioningType.Uri]: (version, versioning) => {
3725
- const prefix = versioning.prefix || "v";
3726
- return {
3727
- url: `${prefix}${version}`
3728
- };
3729
- },
3730
- [VersioningType.Header]: (version, versioning) => {
3731
- const headers = {
3732
- [versioning.header || "version"]: version
3733
- };
3734
- return {
3735
- headers
3736
- };
3737
- },
3738
- [VersioningType.Query]: (version, versioning) => {
3739
- const key = versioning.key || "version";
3740
- return {
3741
- params: {
3742
- [key]: version
3743
- }
3744
- };
3745
- },
3746
- [VersioningType.Custom]: (version, versioning) => {
3747
- return versioning.extractor({
3748
- version
3749
- });
3750
- }
3819
+ function replacePlaceholders(route, values) {
3820
+ const placeholderRegex = /:([a-zA-Z0-9_]+)/g;
3821
+ const newRoute = route.replace(placeholderRegex, (match, key) => {
3822
+ if (values.hasOwnProperty(key)) {
3823
+ return values[key];
3824
+ } else {
3825
+ console.error(`路由[${route}]中的占位符${match},没有对应的值`);
3826
+ console.error(`请在该路由对应的方法中添加@Params('${key}')装饰器`);
3827
+ throw new TypeError(`route params error in ${route}`);
3828
+ }
3829
+ });
3830
+ return newRoute;
3831
+ }
3832
+ const resolveUrl = (url) => {
3833
+ if (!url) return "";
3834
+ if (url.startsWith("/")) return url;
3835
+ return `/${url}`;
3751
3836
  };
3752
- function applyVersioning(version, versioning) {
3753
- const handler = versionHandlers[versioning.type];
3754
- return handler(
3755
- version,
3756
- versioning
3837
+ async function applyStrategies(data, strategies, type = "request") {
3838
+ return await strategies.reduce(
3839
+ async (result, strategy) => {
3840
+ let handler;
3841
+ const instance = new strategy();
3842
+ if (type == "response") {
3843
+ handler = instance.applyResponse;
3844
+ }
3845
+ handler = instance.applyRequest;
3846
+ const currentResult = handler(await result);
3847
+ if (!currentResult) return result;
3848
+ return currentResult;
3849
+ },
3850
+ Promise.resolve(data)
3757
3851
  );
3758
3852
  }
3853
+ const SnailPass = (...args) => {
3854
+ };
3855
+ const buildRequestArgs = (target, propertyKey, args) => {
3856
+ const requestArgs = { params: {}, data: {}, querys: {} };
3857
+ const argsConfigs = Reflect.getMetadata(REQUEST_ARGS_KEY, target, propertyKey) || [];
3858
+ console.log("argsConfigs:", argsConfigs);
3859
+ argsConfigs.forEach(({ index, type, key }) => {
3860
+ const value = args[index];
3861
+ if (type === "params" && !key && typeof value === "object") {
3862
+ requestArgs.params = { ...requestArgs.params, ...value };
3863
+ }
3864
+ if (type === "params" && key) {
3865
+ requestArgs.params[key] = value;
3866
+ }
3867
+ if (type === "querys" && !key && typeof value === "object") {
3868
+ requestArgs.querys = { ...requestArgs.params, ...value };
3869
+ }
3870
+ if (type === "querys" && key) {
3871
+ requestArgs.querys[key] = value;
3872
+ }
3873
+ if (type === "data" && !key && typeof value === "object") {
3874
+ requestArgs.data = { ...requestArgs.data, ...value };
3875
+ }
3876
+ if (type === "data" && key) {
3877
+ requestArgs.data[key] = value;
3878
+ }
3879
+ });
3880
+ return requestArgs;
3881
+ };
3882
+ function isSpecialResponse(response) {
3883
+ const contentType = response.headers["content-type"];
3884
+ return contentType && contentType.includes("application/json");
3885
+ }
3759
3886
  const METHOD_KEY = Symbol("SNAIL_METHOD_KEY");
3760
3887
  const API_CONFIG_KEY = Symbol("SNAIL_API_CONFIG_KEY");
3761
3888
  const Api = (url = "", config) => {
@@ -3764,23 +3891,34 @@ const Api = (url = "", config) => {
3764
3891
  };
3765
3892
  };
3766
3893
  const createMethodDecorator = (method) => {
3767
- return (path = "") => {
3894
+ return (path = "", name) => {
3768
3895
  return (target, propertyKey) => {
3769
- if (target) {
3770
- Reflect.defineMetadata(METHOD_KEY, { method, path }, target, propertyKey);
3771
- return;
3896
+ const methodOptions = Reflect.getMetadata(
3897
+ METHOD_KEY,
3898
+ target,
3899
+ propertyKey
3900
+ );
3901
+ if (methodOptions) {
3902
+ console.error("only one method decorator for a request function!");
3903
+ console.error(`you must chose only one method decorator[@${method} or @${methodOptions.method}]`);
3904
+ throw new TypeError(`Multiple decorators are used for the same request function`);
3772
3905
  }
3773
- Reflect.metadata(METHOD_KEY, { method, path });
3906
+ Reflect.defineMetadata(
3907
+ METHOD_KEY,
3908
+ { method, path, name },
3909
+ target,
3910
+ propertyKey
3911
+ );
3774
3912
  };
3775
3913
  };
3776
3914
  };
3777
- const Get = createMethodDecorator(RequestMethod.GET);
3778
- const Post = createMethodDecorator(RequestMethod.POST);
3779
- const Put = createMethodDecorator(RequestMethod.PUT);
3780
- const Delete = createMethodDecorator(RequestMethod.DELETE);
3781
- const Patch = createMethodDecorator(RequestMethod.PATCH);
3782
- const Options = createMethodDecorator(RequestMethod.OPTIONS);
3783
- const Head = createMethodDecorator(RequestMethod.HEAD);
3915
+ const Get = createMethodDecorator(RequestMethodEnum.GET);
3916
+ const Post = createMethodDecorator(RequestMethodEnum.POST);
3917
+ const Put = createMethodDecorator(RequestMethodEnum.PUT);
3918
+ const Delete = createMethodDecorator(RequestMethodEnum.DELETE);
3919
+ const Patch = createMethodDecorator(RequestMethodEnum.PATCH);
3920
+ const Options = createMethodDecorator(RequestMethodEnum.OPTIONS);
3921
+ const Head = createMethodDecorator(RequestMethodEnum.HEAD);
3784
3922
  const SERVER_CONFIG_KEY = Symbol("SANIL_SERVER_CONFIG_KEY");
3785
3923
  const Server = (config) => {
3786
3924
  return (target) => {
@@ -3794,16 +3932,6 @@ const UseStrategy = (...strategies) => {
3794
3932
  Reflect.defineMetadata(key, strategies, target);
3795
3933
  };
3796
3934
  };
3797
- const REQUEST_ARGS_KEY = Symbol("SNAIL_REQUEST_ARGS_KEY");
3798
- const Params = (key) => createArgsDecorator("params", key);
3799
- const Data = (key) => createArgsDecorator("data", key);
3800
- const createArgsDecorator = (type, key) => {
3801
- return (target, propertyKey, parameterIndex) => {
3802
- const args = Reflect.getMetadata(REQUEST_ARGS_KEY, target, propertyKey) || [];
3803
- args.push({ index: parameterIndex, type, key });
3804
- Reflect.defineMetadata(REQUEST_ARGS_KEY, args, target, propertyKey);
3805
- };
3806
- };
3807
3935
  const VERSIONING_KEY = Symbol("SNAIL_VERSIONING_KEY");
3808
3936
  const VERSION_KEY = Symbol("SNAIL_VERSION_KEY");
3809
3937
  const Versioning = (options) => {
@@ -3816,390 +3944,845 @@ const Version = (version) => {
3816
3944
  Reflect.defineMetadata(VERSION_KEY, version, target, propertyKey);
3817
3945
  };
3818
3946
  };
3819
- const CACHE_OPTIONS_KEY = Symbol("SNALI_CACHE_OPTIONS_KEY");
3820
- const Cache = (hitSource) => {
3947
+ const NO_CACHE_KEY = Symbol("SNALI_NO_CACHE_KEY");
3948
+ const CACHE_EXPIRE_SOURCE_KEY = Symbol("SNALI_CACHE_EXPIRE_SOURCE_KEY");
3949
+ const NoCache = () => {
3821
3950
  return (target, propertyKey) => {
3822
- const key = propertyKey ? `${CACHE_OPTIONS_KEY.toString()}_${propertyKey}` : CACHE_OPTIONS_KEY;
3823
- Reflect.defineMetadata(key, hitSource, target);
3951
+ if (propertyKey) {
3952
+ Reflect.defineMetadata(NO_CACHE_KEY, true, target, propertyKey);
3953
+ return;
3954
+ }
3955
+ Reflect.defineMetadata(NO_CACHE_KEY, true, target);
3824
3956
  };
3825
3957
  };
3826
- const UPLOAD_PROGRESS_KEY = Symbol("SNAIL_UPLOAD_PROGRESS_KEY");
3827
- const DOWNLOAD_PROGRESS_KEY = Symbol("SNAIL_DOWNLOAD_PROGRESS_KEY");
3828
- const EVENT_SOURCE_OPTION_KEY = Symbol("SNAIL_EVENT_SOURCE_OPTION_KEY");
3829
- const Sse = (path, options) => {
3958
+ const HitSource = (...sources) => {
3830
3959
  return (target, propertyKey) => {
3831
- Reflect.defineMetadata(
3832
- EVENT_SOURCE_OPTION_KEY,
3833
- {
3834
- path,
3835
- withCredentials: options == null ? void 0 : options.withCredentials
3836
- },
3837
- target,
3838
- propertyKey
3839
- );
3960
+ if (propertyKey) {
3961
+ Reflect.defineMetadata(
3962
+ CACHE_EXPIRE_SOURCE_KEY,
3963
+ sources,
3964
+ target,
3965
+ propertyKey
3966
+ );
3967
+ return;
3968
+ }
3969
+ Reflect.defineMetadata(CACHE_EXPIRE_SOURCE_KEY, sources, target);
3840
3970
  };
3841
3971
  };
3842
- const EVENT_SOURCE_EVENTS_KEY = Symbol("EVENT_SOURCE_EVENTS_KEY");
3843
- const SseEvent = (eventName, options) => {
3844
- return (target, propertyKey) => {
3845
- const events = Reflect.getMetadata(EVENT_SOURCE_EVENTS_KEY, target) || [];
3846
- events.push({
3847
- eventName: eventName ? eventName : "message",
3848
- emit: target[propertyKey],
3849
- options
3972
+ const versionHandlers = {
3973
+ [VersioningType.Uri]: (version, versioning) => {
3974
+ const prefix = versioning.prefix || "v";
3975
+ return {
3976
+ type: VersioningType.Uri,
3977
+ result: `${prefix}${version}`
3978
+ };
3979
+ },
3980
+ [VersioningType.Header]: (version, versioning) => {
3981
+ const headers = {
3982
+ [versioning.header || "version"]: version
3983
+ };
3984
+ return {
3985
+ type: VersioningType.Header,
3986
+ result: headers
3987
+ };
3988
+ },
3989
+ [VersioningType.Query]: (version, versioning) => {
3990
+ const key = versioning.key || "v";
3991
+ return {
3992
+ type: VersioningType.Query,
3993
+ result: {
3994
+ [key]: version
3995
+ }
3996
+ };
3997
+ },
3998
+ [VersioningType.Custom]: (version, versioning) => {
3999
+ return versioning.extractor({
4000
+ version
3850
4001
  });
3851
- Reflect.defineMetadata(EVENT_SOURCE_EVENTS_KEY, events, target);
3852
- };
3853
- };
3854
- const EVENT_SOURCE_OPEN_KEY = Symbol("EVENT_SOURCE_OPEN_KEY");
3855
- const OnSseOpen = () => {
3856
- return (target, propertyKey) => {
3857
- Reflect.defineMetadata(EVENT_SOURCE_OPEN_KEY, target[propertyKey], target);
3858
- };
3859
- };
3860
- const EVENT_SOURCE_ERROR_KEY = Symbol("EVENT_SOURCE_ERROR_KEY");
3861
- const OnSseError = () => {
3862
- return (target, propertyKey) => {
3863
- Reflect.defineMetadata(EVENT_SOURCE_ERROR_KEY, target[propertyKey], target);
3864
- };
4002
+ }
3865
4003
  };
3866
- class Snail {
3867
- constructor() {
3868
- __publicField(this, "axiosInstance");
3869
- // private config: SnailConfig;
4004
+ function applyVersioning(version, versioning) {
4005
+ if (!versioning) return void 0;
4006
+ const handler = versionHandlers[versioning.type];
4007
+ return handler(
4008
+ version,
4009
+ versioning
4010
+ );
4011
+ }
4012
+ const UPLOAD_PROGRESS_KEY = Symbol("SNAIL_UPLOAD_PROGRESS_KEY");
4013
+ const DOWNLOAD_PROGRESS_KEY = Symbol("SNAIL_DOWNLOAD_PROGRESS_KEY");
4014
+ class SnailMethod {
4015
+ constructor(apiInstance, target, propertyKey, args) {
4016
+ // 私有属性
4017
+ // private serverInstance: SnailServer;
4018
+ __publicField(this, "Name");
4019
+ __publicField(this, "apiInstance");
4020
+ __publicField(this, "target");
3870
4021
  __publicField(this, "strategies", []);
3871
- __publicField(this, "cacheStorage");
3872
- __publicField(this, "version");
3873
- __publicField(this, "sourceMap", /* @__PURE__ */ new Map());
3874
- __publicField(this, "eventSource");
3875
- }
3876
- registerStrategy(strategy) {
3877
- this.strategies.push(strategy);
3878
- }
3879
- createApi(constructor) {
3880
- const instance = new constructor();
3881
- const serverConfig = this.getServerConfig();
3882
- const { baseURL, timeout, CacheManage, enableLog } = serverConfig;
3883
- enableLog && console.log("serverConfig:", serverConfig);
3884
- this.initAxios({ baseURL, timeout });
3885
- enableLog && console.log("CacheManage:", CacheManage);
3886
- this.initCacheManage(CacheManage);
3887
- const apiConfig = this.getApiConfig(constructor);
3888
- enableLog && console.log("ApiConfig:", apiConfig);
3889
- this.version = apiConfig.version;
3890
- return new Proxy(instance, {
3891
- get: (target, propertyKey) => {
3892
- enableLog && console.log("proxy:", target, "|", propertyKey);
3893
- if (typeof propertyKey !== "string") return;
3894
- const methodConfig = Reflect.getMetadata(
3895
- METHOD_KEY,
3896
- target,
3897
- propertyKey
4022
+ __publicField(this, "Request");
4023
+ __publicField(this, "Response");
4024
+ __publicField(this, "Error");
4025
+ __publicField(this, "eventMap");
4026
+ __publicField(this, "onceWrapperMap");
4027
+ __publicField(this, "propertyKey");
4028
+ __publicField(this, "Url", "");
4029
+ __publicField(this, "Path", "");
4030
+ __publicField(this, "Method", RequestMethodEnum.GET);
4031
+ __publicField(this, "Version");
4032
+ __publicField(this, "Args", []);
4033
+ __publicField(this, "send", async () => {
4034
+ this.enableLog() && console.log("send:", this.name);
4035
+ const [serverName] = this.apiInstance.name.split(".");
4036
+ const axios2 = AxiosInstanceMap.get(serverName);
4037
+ if (!axios2) throw new Error("AxiosInstance not created");
4038
+ const strategies = this.getStrategies();
4039
+ this.Request = await applyStrategies(this.Request, strategies, "request");
4040
+ this.Request = this.applyProgress(this.Request);
4041
+ const { data, querys, params } = buildRequestArgs(
4042
+ this.target,
4043
+ this.propertyKey,
4044
+ this.Args
4045
+ );
4046
+ console.log("apiurl:", this.apiInstance.url);
4047
+ const newUrl = replacePlaceholders(this.Url, params);
4048
+ this.Request = {
4049
+ ...this.Request,
4050
+ url: newUrl,
4051
+ params: {
4052
+ ...this.Request.params,
4053
+ ...querys
4054
+ },
4055
+ data
4056
+ };
4057
+ this.enableLog() && console.log("request:", this.Request);
4058
+ const isNoCache = this.isNoCache();
4059
+ this.enableLog() && console.log("method is noCache:", isNoCache);
4060
+ if (!isNoCache) {
4061
+ const { data: data2 } = await this.getCacheData(serverName);
4062
+ this.enableLog() && console.log("getCacheData:", data2);
4063
+ if (data2) {
4064
+ this.emit("hitCache", data2);
4065
+ this.emit("success", data2);
4066
+ this.emit("finish", data2);
4067
+ return data2;
4068
+ }
4069
+ }
4070
+ const requester = AxiosInstanceMap.get(serverName);
4071
+ if (!requester) throw new Error("AxiosInstance not created");
4072
+ try {
4073
+ const rawResponse = await requester.request(this.Request);
4074
+ const isSpecial = isSpecialResponse(rawResponse);
4075
+ const response = await applyStrategies(
4076
+ rawResponse,
4077
+ strategies,
4078
+ "response"
3898
4079
  );
3899
- if (!methodConfig) return target[propertyKey];
3900
- return async (...args) => {
3901
- const url = methodConfig.path == "" ? apiConfig.url : apiConfig.url + `/${methodConfig.path}`;
3902
- enableLog && console.log("url:", url);
3903
- let request = {
3904
- // baseURL: serverConfig.baseURL,
3905
- url,
3906
- method: methodConfig.method,
3907
- timeout: apiConfig.timeout ? apiConfig.timeout : serverConfig.timeout
3908
- };
3909
- request = {
3910
- ...request,
3911
- ...this.applyVersion(request, target, propertyKey)
3912
- };
3913
- enableLog && console.log("版本管理参数:", request);
3914
- const strategies = this.getStrategies(target, propertyKey);
3915
- const params = this.buildRequestArgs(target, propertyKey, args);
3916
- request = { ...request, ...params };
3917
- enableLog && console.log("构建请求参数:", request);
3918
- const requestStrategies = strategies.filter(
3919
- (strategy) => strategy.applyRequest
3920
- );
3921
- request = await this.applyStrategies(
3922
- request,
3923
- requestStrategies,
3924
- "request"
3925
- );
3926
- const hitSource = this.getHitSource(target, propertyKey);
3927
- enableLog && console.log("hitSource:", hitSource);
3928
- if (typeof hitSource == "string") {
3929
- await this.setHitSource(request, hitSource);
3930
- }
3931
- if (hitSource !== null) {
3932
- const cachedResponse = await this.getCache(request, strategies);
3933
- if (cachedResponse) {
3934
- enableLog && console.warn("数据从缓存获取");
3935
- return this.handleResponse(cachedResponse, true);
3936
- }
3937
- }
3938
- const onUploadProgress = Reflect.getMetadata(
3939
- UPLOAD_PROGRESS_KEY,
3940
- target,
3941
- propertyKey
3942
- );
3943
- const onDownloadProgress = Reflect.getMetadata(
3944
- DOWNLOAD_PROGRESS_KEY,
3945
- target,
3946
- propertyKey
3947
- );
3948
- try {
3949
- enableLog && console.log("send request:", request);
3950
- const response = await this.axiosInstance({
3951
- ...request,
3952
- onUploadProgress,
3953
- onDownloadProgress
3954
- });
3955
- const responseStrategies = strategies.filter(
3956
- (strategy) => strategy.applyResponse
3957
- );
3958
- const strategyResponse = await this.applyStrategies(
3959
- response,
3960
- responseStrategies,
3961
- "response"
3962
- );
3963
- hitSource !== null && this.setCache(request, response);
3964
- this.expireCache(propertyKey);
3965
- return this.handleResponse(strategyResponse, false);
3966
- } catch (error) {
3967
- return this.handleError(error);
3968
- }
3969
- };
4080
+ if (!isNoCache) {
4081
+ !isSpecial && await this.setCacheData(serverName, response);
4082
+ }
4083
+ this.Response = response;
4084
+ this.applyHitSource(serverName);
4085
+ this.emit("success", response.data);
4086
+ this.emit("finish", response.data);
4087
+ if (isSpecial) return response;
4088
+ return response.data;
4089
+ } catch (error) {
4090
+ this.emit("error", error);
4091
+ this.emit("finish", error);
4092
+ console.error(error);
4093
+ this.Error = error;
4094
+ return error;
3970
4095
  }
3971
4096
  });
4097
+ this.apiInstance = apiInstance;
4098
+ this.target = target;
4099
+ this.propertyKey = propertyKey.toString();
4100
+ this.Args = args ?? [];
4101
+ this.init();
4102
+ console.log("url:", this.Url);
4103
+ this.eventMap = /* @__PURE__ */ new Map();
4104
+ this.onceWrapperMap = /* @__PURE__ */ new Map();
4105
+ this.eventMap.set("success", /* @__PURE__ */ new Set());
4106
+ this.eventMap.set("hitCache", /* @__PURE__ */ new Set());
4107
+ this.eventMap.set("error", /* @__PURE__ */ new Set());
4108
+ this.eventMap.set("finish", /* @__PURE__ */ new Set());
4109
+ }
4110
+ init() {
4111
+ const methodOptions = this.getMethodOptions();
4112
+ if (!methodOptions) {
4113
+ throw new Error("Create SnailMethod must be used for decoration");
4114
+ }
4115
+ const { path, method, name } = methodOptions;
4116
+ this.Name = name ?? this.propertyKey;
4117
+ this.Path = path;
4118
+ this.Method = method;
4119
+ this.createRequest();
4120
+ this.initUrl();
4121
+ this.initVersion();
4122
+ }
4123
+ initUrl() {
4124
+ const url = this.Path == "" ? this.apiInstance.url || "" : `${this.apiInstance.url || ""}${resolveUrl(this.Path)}`;
4125
+ this.Url = url;
4126
+ }
4127
+ initVersion() {
4128
+ const version = Reflect.getMetadata(
4129
+ VERSION_KEY,
4130
+ this.target,
4131
+ this.propertyKey
4132
+ );
4133
+ this.Version = version ?? this.apiInstance.version;
4134
+ if (!this.Version) return;
4135
+ const [serverName] = this.apiInstance.name.split(".");
4136
+ const versioningOptions = VersioningMap.get(serverName);
4137
+ if (!versioningOptions) {
4138
+ console.warn("Version Manager not configured");
4139
+ console.log(
4140
+ "Please use @Versioning() to configure the version manager on the ` SnailServer ` class"
4141
+ );
4142
+ return;
4143
+ }
4144
+ const versioningResult = applyVersioning(this.Version, versioningOptions);
4145
+ if (!versioningResult) {
4146
+ console.warn("Apply Versioning error");
4147
+ return;
4148
+ }
4149
+ const { type, result } = versioningResult;
4150
+ if (type === VersioningType.Uri) {
4151
+ this.Url = `${resolveUrl(result)}${resolveUrl(this.Url)}`;
4152
+ }
4153
+ if (type === VersioningType.Header) {
4154
+ this.Request.headers = {
4155
+ ...this.Request.headers,
4156
+ ...result
4157
+ };
4158
+ }
4159
+ if (type === VersioningType.Query) {
4160
+ this.Request.params = {
4161
+ ...this.Request.params,
4162
+ ...result
4163
+ };
4164
+ }
3972
4165
  }
3973
- buildRequestArgs(target, propertyKey, args) {
3974
- const requestArgs = { params: {}, data: {} };
3975
- const paramConfigs = Reflect.getMetadata(REQUEST_ARGS_KEY, target, propertyKey) || [];
3976
- paramConfigs.forEach(({ index, type, key }) => {
3977
- const value = args[index];
3978
- if (type === "params" && !key && typeof value === "object") {
3979
- requestArgs.params = { ...requestArgs.params, ...value };
3980
- }
3981
- if (type === "params" && key) {
3982
- requestArgs.params[key] = value;
3983
- }
3984
- if (type === "data" && !key && typeof value === "object") {
3985
- requestArgs.data = { ...requestArgs.data, ...value };
3986
- }
3987
- if (type === "data" && key) {
3988
- requestArgs.data[key] = value;
4166
+ getExpireSources() {
4167
+ const invalidSources = ExpireSourceMap.get(this.name) ?? /* @__PURE__ */ new Set();
4168
+ if (invalidSources.size === 0) return [];
4169
+ return Array.from(invalidSources);
4170
+ }
4171
+ createRequest() {
4172
+ const request = {
4173
+ url: this.Url,
4174
+ method: this.Method,
4175
+ timeout: this.apiInstance.timeout,
4176
+ data: {},
4177
+ params: {},
4178
+ headers: {}
4179
+ };
4180
+ this.Request = request;
4181
+ return request;
4182
+ }
4183
+ onSuccess(handler) {
4184
+ this.on("success", handler);
4185
+ }
4186
+ onError(handler) {
4187
+ this.on("error", handler);
4188
+ }
4189
+ onHitCache(handler) {
4190
+ this.on("hitCache", handler);
4191
+ }
4192
+ onFinish(handler) {
4193
+ this.on("finish", handler);
4194
+ }
4195
+ on(eventName, handler) {
4196
+ if (typeof handler !== "function") {
4197
+ throw new TypeError("Handler must be a function");
4198
+ }
4199
+ const handlers = this.eventMap.get(eventName) || /* @__PURE__ */ new Set();
4200
+ handlers.add(handler);
4201
+ this.eventMap.set(eventName, handlers);
4202
+ }
4203
+ once(eventName, handler) {
4204
+ const onceHandler = (data) => {
4205
+ try {
4206
+ handler.apply(this, [data]);
4207
+ } finally {
4208
+ this.off(eventName, onceHandler);
4209
+ this.onceWrapperMap.delete(handler);
3989
4210
  }
4211
+ };
4212
+ this.onceWrapperMap.set(handler, onceHandler);
4213
+ this.on(eventName, onceHandler);
4214
+ }
4215
+ emit(eventName, ...args) {
4216
+ const handlers = this.eventMap.get(eventName);
4217
+ if (!handlers || handlers.size === 0) return false;
4218
+ handlers.forEach((handler) => {
4219
+ Promise.resolve().then(() => {
4220
+ handler.apply(this, args);
4221
+ });
3990
4222
  });
3991
- return requestArgs;
4223
+ return true;
3992
4224
  }
3993
- getStrategies(target, propertyKey) {
3994
- const serverStrategies = Reflect.getMetadata(STRATEGY_KEY, this.constructor) || [];
3995
- const classStrategies = Reflect.getMetadata(STRATEGY_KEY, target.constructor) || [];
4225
+ off(eventName, handler) {
4226
+ const handlers = this.eventMap.get(eventName);
4227
+ if (!handlers) return;
4228
+ if (handlers.has(handler)) {
4229
+ handlers.delete(handler);
4230
+ }
4231
+ if (handlers.size === 0) {
4232
+ this.eventMap.delete(eventName);
4233
+ }
4234
+ }
4235
+ async getCacheData(serverName) {
4236
+ const methodKey = await generateCacheKey(
4237
+ this.name,
4238
+ this.version,
4239
+ this.Request
4240
+ );
4241
+ const cacheStorage = CacheStorageMap.get(serverName);
4242
+ if (!cacheStorage) {
4243
+ throw new Error("CacheStorage not created");
4244
+ }
4245
+ const cacheData = await cacheStorage.get(methodKey);
4246
+ const { error } = cacheData;
4247
+ if (!error) {
4248
+ this.enableLog() && console.warn(`[${this.Name}]`, "Cache hit");
4249
+ }
4250
+ return cacheData;
4251
+ }
4252
+ async setCacheData(serverName, responseData) {
4253
+ const methodKey = await generateCacheKey(
4254
+ this.name,
4255
+ this.version,
4256
+ this.Request
4257
+ );
4258
+ this.enableLog() && console.log("setCacheData:", methodKey);
4259
+ const cacheStorage = CacheStorageMap.get(serverName);
4260
+ if (!cacheStorage) throw new Error("CacheStorage not created");
4261
+ const ttl = CacheTtlMap.get(serverName);
4262
+ const cacheData = {
4263
+ data: responseData.data,
4264
+ exp: Date.now() + ttl * 1e3
4265
+ };
4266
+ cacheStorage.set(methodKey, cacheData);
4267
+ }
4268
+ get response() {
4269
+ return this.Response;
4270
+ }
4271
+ get request() {
4272
+ return this.Request;
4273
+ }
4274
+ get version() {
4275
+ return this.Version;
4276
+ }
4277
+ get name() {
4278
+ return `${this.apiInstance.name}.${this.Name}`;
4279
+ }
4280
+ get error() {
4281
+ if (this.Error) return this.Error;
4282
+ return null;
4283
+ }
4284
+ registerStrategies(...strategys) {
4285
+ this.strategies.push(...strategys);
4286
+ }
4287
+ getStrategies() {
4288
+ const [serverName, apiName] = this.apiInstance.name.split(".");
4289
+ const serverStrategies = StrategyMap.get(serverName) ?? [];
4290
+ const apiStrategies = StrategyMap.get(apiName) ?? [];
3996
4291
  const methodStrategies = Reflect.getMetadata(
3997
- `${STRATEGY_KEY.toString()}_${propertyKey}`,
3998
- target
4292
+ `${STRATEGY_KEY.toString()}_${this.propertyKey}`,
4293
+ this.target
3999
4294
  ) || [];
4000
4295
  const allStrategies = [
4001
- ...this.strategies,
4002
4296
  ...serverStrategies,
4003
- ...classStrategies,
4297
+ ...apiStrategies,
4004
4298
  ...methodStrategies
4005
4299
  ];
4006
4300
  return allStrategies;
4007
4301
  }
4008
- async applyStrategies(data, strategies, type = "request") {
4009
- return await strategies.reduce(async (result, strategy) => {
4010
- if (type == "response")
4011
- return await strategy.applyResponse(await result);
4012
- return await strategy.applyRequest(await result);
4013
- }, Promise.resolve(data));
4302
+ getMethodOptions() {
4303
+ const methodConfig = Reflect.getMetadata(
4304
+ METHOD_KEY,
4305
+ this.target,
4306
+ this.propertyKey
4307
+ );
4308
+ return methodConfig;
4309
+ }
4310
+ isNoCache() {
4311
+ const [serverName] = this.apiInstance.name.split(".");
4312
+ const cacheForMap = CacheForMap.get(serverName);
4313
+ let flag = false;
4314
+ if (typeof cacheForMap === "string" && (cacheForMap.toLowerCase() === "all" || cacheForMap === this.Method)) {
4315
+ flag = true;
4316
+ }
4317
+ if (Array.isArray(cacheForMap)) {
4318
+ flag = cacheForMap.includes(this.Method);
4319
+ }
4320
+ const isMethodNoCache = Reflect.getMetadata(
4321
+ NO_CACHE_KEY,
4322
+ this.target,
4323
+ this.propertyKey
4324
+ );
4325
+ const isApiNoCache = this.apiInstance.noCache;
4326
+ const noCacheFlag = isMethodNoCache ? true : isApiNoCache ? true : false;
4327
+ return flag ? noCacheFlag : true;
4328
+ }
4329
+ enableLog() {
4330
+ return this.apiInstance.enableLog;
4331
+ }
4332
+ async applyHitSource(serverName) {
4333
+ const sources = this.getExpireSources();
4334
+ const cacheStorage = CacheStorageMap.get(serverName);
4335
+ if (cacheStorage) {
4336
+ const cacheKeys = await cacheStorage.keys();
4337
+ sources.map((source) => {
4338
+ cacheKeys.map((key) => {
4339
+ if (key.startsWith(source)) {
4340
+ this.enableLog() && console.warn(`[${this.name}]请求成功,触发清除缓存:${source}`);
4341
+ cacheStorage.delete(key);
4342
+ }
4343
+ });
4344
+ });
4345
+ }
4346
+ }
4347
+ applyProgress(request) {
4348
+ const onUploadProgress = Reflect.getMetadata(
4349
+ UPLOAD_PROGRESS_KEY,
4350
+ this.target,
4351
+ this.propertyKey
4352
+ );
4353
+ const onDownloadProgress = Reflect.getMetadata(
4354
+ DOWNLOAD_PROGRESS_KEY,
4355
+ this.target,
4356
+ this.propertyKey
4357
+ );
4358
+ return {
4359
+ ...request,
4360
+ onUploadProgress,
4361
+ onDownloadProgress
4362
+ };
4363
+ }
4364
+ }
4365
+ const CacheStorageMap = /* @__PURE__ */ new Map();
4366
+ const CacheTtlMap = /* @__PURE__ */ new Map();
4367
+ const CacheForMap = /* @__PURE__ */ new Map();
4368
+ const ExpireSourceMap = /* @__PURE__ */ new Map();
4369
+ const AxiosInstanceMap = /* @__PURE__ */ new Map();
4370
+ const StrategyMap = /* @__PURE__ */ new Map();
4371
+ const VersioningMap = /* @__PURE__ */ new Map();
4372
+ const defaultCacheManageOptions = {
4373
+ type: CacheType.Memory,
4374
+ ttl: 500
4375
+ };
4376
+ const defaultServerOptions = {
4377
+ baseURL: "",
4378
+ timeout: 5e3,
4379
+ cacheManage: defaultCacheManageOptions,
4380
+ cacheFor: "get",
4381
+ enableLog: false
4382
+ };
4383
+ class SnailServer {
4384
+ constructor() {
4385
+ __publicField(this, "Name");
4386
+ __publicField(this, "BaseURL");
4387
+ __publicField(this, "Version");
4388
+ __publicField(this, "EnableLog", false);
4389
+ const options = this.getServerOptions();
4390
+ this.Name = options.name ?? this.constructor.name;
4391
+ this.init();
4392
+ }
4393
+ init() {
4394
+ const options = this.getServerOptions();
4395
+ const { baseURL, timeout, cacheManage, enableLog, cacheFor } = options;
4396
+ this.BaseURL = baseURL ?? resolveUrl("");
4397
+ this.initAxios({ baseURL, timeout });
4398
+ this.initStrategy();
4399
+ this.initCacheManage(cacheManage, cacheFor);
4400
+ this.initVersioning();
4401
+ this.initExpireSource(this);
4402
+ this.EnableLog = enableLog ?? false;
4403
+ this.initLog(enableLog);
4404
+ }
4405
+ initLog(enableLog) {
4406
+ if (enableLog) {
4407
+ const axiosInstance = AxiosInstanceMap.get(this.Name);
4408
+ axiosInstance.interceptors.request.use((config) => {
4409
+ console.log("Request:", config);
4410
+ return config;
4411
+ });
4412
+ axiosInstance.interceptors.response.use((response) => {
4413
+ console.log("Response:", response);
4414
+ return response;
4415
+ });
4416
+ }
4417
+ }
4418
+ initStrategy() {
4419
+ const serverStrategies = Reflect.getMetadata(STRATEGY_KEY, this.constructor) || [];
4420
+ StrategyMap.set(this.Name, serverStrategies);
4014
4421
  }
4015
- applyVersion(request, target, propertyKey) {
4422
+ initVersioning() {
4016
4423
  const versioning = Reflect.getMetadata(
4017
4424
  VERSIONING_KEY,
4018
4425
  this.constructor
4019
4426
  );
4020
- if (!versioning) return request;
4021
- const version = Reflect.getMetadata(VERSION_KEY, target, propertyKey);
4022
- const currentVersion = version || this.version || versioning.defaultVersion;
4023
- const { url, headers, params } = applyVersioning(
4024
- currentVersion,
4025
- versioning
4026
- );
4027
- const versionUrl = url ? `${url}/${request.url}` : request.url;
4028
- return { ...request, url: versionUrl, headers, params };
4029
- }
4030
- async getCache(request, strategies) {
4031
- var _a;
4032
- if (!this.cacheStorage) return void 0;
4033
- const cacheKey = await apiKey(request);
4034
- const cached = await ((_a = this.cacheStorage) == null ? void 0 : _a.get(cacheKey));
4035
- if (cached && cached.error === null) {
4036
- let cacheResponse = {
4037
- data: cached.data,
4038
- status: 304,
4039
- headers: {},
4040
- statusText: "get response data from cache",
4041
- config: { headers: new AxiosHeaders2() }
4042
- };
4043
- return cacheResponse;
4427
+ if (versioning) {
4428
+ VersioningMap.set(this.Name, versioning);
4044
4429
  }
4045
- return void 0;
4046
4430
  }
4047
- initCacheManage(options) {
4048
- if (!this.cacheStorage && options !== void 0) {
4049
- this.cacheStorage = createCache(options.type, options.ttl || 300);
4050
- }
4431
+ registerStrategies(...strategys) {
4432
+ const serverStrategies = StrategyMap.get(this.Name) ?? [];
4433
+ serverStrategies.push(...strategys);
4434
+ StrategyMap.set(this.Name, serverStrategies);
4051
4435
  }
4052
- getHitSource(target, propertyKey) {
4053
- const methodHitSource = Reflect.getMetadata(
4054
- `${CACHE_OPTIONS_KEY.toString()}_${propertyKey}`,
4055
- target
4056
- );
4057
- if (methodHitSource !== void 0) return methodHitSource;
4058
- const apiHitSource = Reflect.getMetadata(
4059
- CACHE_OPTIONS_KEY,
4060
- target.constructor
4436
+ createApi(constructor) {
4437
+ const serverVersioning = Reflect.getMetadata(
4438
+ VERSIONING_KEY,
4439
+ this.constructor
4061
4440
  );
4062
- return apiHitSource;
4063
- }
4064
- async setHitSource(request, hitSource) {
4065
- const cacheKeys = this.sourceMap.get(hitSource);
4066
- const currentCacheKey = await apiKey(request);
4067
- if (cacheKeys) {
4068
- cacheKeys.push(currentCacheKey);
4069
- this.sourceMap.set(hitSource, cacheKeys);
4070
- } else {
4071
- this.sourceMap.set(hitSource, [currentCacheKey]);
4072
- }
4073
- }
4074
- async setCache(request, response) {
4075
- var _a;
4076
- const cacheKey = await apiKey(request);
4077
- await ((_a = this.cacheStorage) == null ? void 0 : _a.set(cacheKey, response.data));
4078
- }
4079
- async expireCache(hitSource) {
4080
- const keys = this.sourceMap.get(hitSource);
4081
- if (keys) {
4082
- Promise.all(
4083
- keys.map(async (key) => {
4084
- var _a;
4085
- await ((_a = this.cacheStorage) == null ? void 0 : _a.delete(key));
4086
- })
4087
- );
4441
+ if (serverVersioning) {
4442
+ this.Version = serverVersioning.defaultVersion || "";
4088
4443
  }
4444
+ const apiInstanceOptions = {
4445
+ serverInstance: this,
4446
+ enableLog: this.EnableLog
4447
+ };
4448
+ const apiInstance = new constructor(apiInstanceOptions);
4449
+ this.initExpireSource(apiInstance);
4450
+ return new Proxy(apiInstance, {
4451
+ get: (target, propertyKey) => {
4452
+ if (typeof propertyKey !== "string")
4453
+ return target[propertyKey];
4454
+ const methodConfig = Reflect.getMetadata(
4455
+ METHOD_KEY,
4456
+ target,
4457
+ propertyKey
4458
+ );
4459
+ if (!methodConfig) return target[propertyKey];
4460
+ return (...args) => {
4461
+ const method = new SnailMethod(apiInstance, target, propertyKey, [
4462
+ ...args
4463
+ ]);
4464
+ this.initExpireSource(method, propertyKey);
4465
+ return method;
4466
+ };
4467
+ }
4468
+ });
4089
4469
  }
4090
- getServerConfig() {
4091
- return Reflect.getMetadata(
4092
- SERVER_CONFIG_KEY,
4470
+ initCacheManage(options, cacheFor) {
4471
+ const noCache = Reflect.getMetadata(
4472
+ NO_CACHE_KEY,
4093
4473
  this.constructor
4094
4474
  );
4475
+ if (noCache && options !== defaultCacheManageOptions) {
4476
+ console.warn("you configured cache manage, but you set noCache");
4477
+ return;
4478
+ }
4479
+ const cacheStorage = CacheStorageMap.get(this.Name);
4480
+ if (!cacheStorage && options !== void 0) {
4481
+ const storage = createCache(options);
4482
+ CacheStorageMap.set(this.Name, storage);
4483
+ CacheTtlMap.set(this.Name, options.ttl || 500);
4484
+ }
4485
+ if (cacheFor) {
4486
+ CacheForMap.set(this.Name, cacheFor);
4487
+ }
4095
4488
  }
4096
- getApiConfig(constructor) {
4097
- return Reflect.getMetadata(API_CONFIG_KEY, constructor);
4489
+ initExpireSource(target, propertyKey) {
4490
+ if (propertyKey) {
4491
+ const expireSource = Reflect.getMetadata(
4492
+ CACHE_EXPIRE_SOURCE_KEY,
4493
+ target.target,
4494
+ propertyKey
4495
+ );
4496
+ if (expireSource && expireSource.length > 0) {
4497
+ expireSource.map((source) => {
4498
+ const invalidSources = ExpireSourceMap.get(source) ?? /* @__PURE__ */ new Set();
4499
+ invalidSources.add(target.name);
4500
+ ExpireSourceMap.set(source, invalidSources);
4501
+ });
4502
+ }
4503
+ return;
4504
+ }
4505
+ const expireSources = Reflect.getMetadata(
4506
+ CACHE_EXPIRE_SOURCE_KEY,
4507
+ target.constructor
4508
+ ) ?? [];
4509
+ if (expireSources.length > 0) {
4510
+ expireSources.map((source) => {
4511
+ const invalidSources = ExpireSourceMap.get(source) ?? /* @__PURE__ */ new Set();
4512
+ invalidSources.add(target.name);
4513
+ ExpireSourceMap.set(source, invalidSources);
4514
+ });
4515
+ }
4098
4516
  }
4099
4517
  initAxios(config) {
4100
- if (!this.axiosInstance) {
4101
- this.axiosInstance = axios.create({
4102
- baseURL: config.baseURL,
4518
+ const axiosInstance = AxiosInstanceMap.get(this.Name);
4519
+ if (!axiosInstance) {
4520
+ const axiosInstance2 = axios.create({
4521
+ baseURL: resolveUrl(config.baseURL),
4103
4522
  timeout: config.timeout
4104
4523
  });
4524
+ AxiosInstanceMap.set(this.Name, axiosInstance2);
4105
4525
  }
4106
4526
  }
4107
- generateSseUrl(baseURL, url) {
4108
- if (!baseURL && !url) {
4109
- return "/";
4110
- }
4111
- if (!baseURL && url) {
4112
- return `/${url}`;
4527
+ getServerOptions() {
4528
+ const serverOptions = Reflect.getMetadata(
4529
+ SERVER_CONFIG_KEY,
4530
+ this.constructor
4531
+ );
4532
+ if (!serverOptions) {
4533
+ throw new Error(
4534
+ "Create SnailServer must be used for @Server() decoration"
4535
+ );
4113
4536
  }
4114
- return `${baseURL}/${url}`;
4537
+ const options = Object.assign({}, defaultServerOptions, serverOptions);
4538
+ return options;
4115
4539
  }
4116
- handleResponse(response, hitCache) {
4117
- return {
4118
- data: response.data,
4119
- error: null,
4120
- hitCache
4121
- };
4540
+ createSse(constructor) {
4541
+ const sseInstance = new constructor(this);
4542
+ return sseInstance;
4122
4543
  }
4123
- handleError(error) {
4124
- return {
4125
- data: null,
4126
- error
4127
- };
4544
+ get version() {
4545
+ return this.Version;
4128
4546
  }
4129
- createSse(constructor) {
4130
- const instance = new constructor();
4131
- const serverConfig = this.getServerConfig();
4132
- const { baseURL, enableLog } = serverConfig;
4133
- const apiConfig = this.getApiConfig(constructor);
4134
- enableLog && console.log("ApiConfig:", apiConfig);
4135
- this.version = apiConfig.version;
4136
- return new Proxy(instance, {
4137
- get: (target, propertyKey) => {
4138
- enableLog && console.log("proxy:", target, "|", propertyKey);
4139
- if (typeof propertyKey !== "string") return;
4140
- const sseOption = Reflect.getMetadata(
4141
- EVENT_SOURCE_OPTION_KEY,
4142
- target,
4143
- propertyKey
4144
- );
4145
- if (sseOption) {
4146
- const url = sseOption.path == "" ? apiConfig.url : apiConfig.url + `/${sseOption.path}`;
4147
- const { url: versionUrl } = this.applyVersion(
4148
- { url },
4149
- target,
4150
- propertyKey
4151
- );
4152
- const sseUrl = this.generateSseUrl(baseURL, versionUrl || url);
4153
- enableLog && console.log("sse-url:", sseUrl);
4154
- return () => this.initSse(sseUrl, sseOption, target);
4155
- }
4156
- }
4157
- });
4547
+ get name() {
4548
+ return this.Name;
4158
4549
  }
4159
- initSse(url, options, target) {
4160
- return () => {
4161
- const eventSource = new EventSource(url, {
4162
- withCredentials: options.withCredentials ? options.withCredentials : false
4163
- });
4164
- this.eventSource = eventSource;
4165
- this.setSse(target);
4166
- this.registerSseEvent(target);
4167
- return {
4168
- eventSource,
4169
- close: eventSource.close
4170
- };
4171
- };
4550
+ get enableLog() {
4551
+ return this.EnableLog;
4172
4552
  }
4173
- setSse(target) {
4174
- const onOpenFunc = Reflect.getMetadata(EVENT_SOURCE_OPEN_KEY, target);
4175
- if (typeof onOpenFunc == "function") {
4176
- this.eventSource && (this.eventSource.onopen = onOpenFunc);
4553
+ get baseUrl() {
4554
+ return this.BaseURL;
4555
+ }
4556
+ }
4557
+ class SnailApi {
4558
+ constructor(options) {
4559
+ __publicField(this, "Name");
4560
+ __publicField(this, "serverInstance");
4561
+ __publicField(this, "Version");
4562
+ __publicField(this, "Url");
4563
+ __publicField(this, "Timeout");
4564
+ __publicField(this, "EnableLog");
4565
+ const apiConfig = this.getApiConfig();
4566
+ if (!apiConfig) {
4567
+ throw new Error("Create SnailApi must be used for @Api() decoration");
4568
+ }
4569
+ const { serverInstance, enableLog } = options;
4570
+ this.serverInstance = serverInstance;
4571
+ this.EnableLog = enableLog ? true : false;
4572
+ this.init();
4573
+ }
4574
+ init() {
4575
+ const apiConfig = this.getApiConfig();
4576
+ this.initName();
4577
+ this.initStrategy();
4578
+ this.Version = apiConfig.version ?? this.serverInstance.version;
4579
+ this.Url = apiConfig.url;
4580
+ this.Timeout = apiConfig.timeout;
4581
+ }
4582
+ initStrategy() {
4583
+ const serverStrategies = Reflect.getMetadata(STRATEGY_KEY, this.constructor) || [];
4584
+ StrategyMap.set(this.Name, serverStrategies);
4585
+ }
4586
+ registerStrategies(...strategys) {
4587
+ const serverStrategies = StrategyMap.get(this.Name) ?? [];
4588
+ serverStrategies.push(...strategys);
4589
+ StrategyMap.set(this.Name, serverStrategies);
4590
+ }
4591
+ initName() {
4592
+ const { name } = this.getApiConfig();
4593
+ const apiName = name ?? this.constructor.name;
4594
+ this.Name = `${this.serverInstance.name}.${apiName}`;
4595
+ }
4596
+ getApiConfig() {
4597
+ return Reflect.getMetadata(
4598
+ API_CONFIG_KEY,
4599
+ this.constructor
4600
+ );
4601
+ }
4602
+ isNoCache() {
4603
+ const isServerNoCache = Reflect.getMetadata(
4604
+ NO_CACHE_KEY,
4605
+ this.serverInstance.constructor
4606
+ );
4607
+ const isApiNoCache = Reflect.getMetadata(
4608
+ NO_CACHE_KEY,
4609
+ this.constructor
4610
+ );
4611
+ return isServerNoCache || isApiNoCache;
4612
+ }
4613
+ get version() {
4614
+ return this.Version;
4615
+ }
4616
+ get url() {
4617
+ return this.Url;
4618
+ }
4619
+ get name() {
4620
+ return this.Name;
4621
+ }
4622
+ get noCache() {
4623
+ return this.isNoCache();
4624
+ }
4625
+ get enableLog() {
4626
+ return this.EnableLog;
4627
+ }
4628
+ get timeout() {
4629
+ return this.Timeout;
4630
+ }
4631
+ }
4632
+ const EVENT_SOURCE_OPTION_KEY = Symbol("SNAIL_EVENT_SOURCE_OPTION_KEY");
4633
+ const Sse = (path, options) => {
4634
+ return (target) => {
4635
+ Reflect.defineMetadata(
4636
+ EVENT_SOURCE_OPTION_KEY,
4637
+ {
4638
+ path,
4639
+ ...options
4640
+ },
4641
+ target
4642
+ );
4643
+ };
4644
+ };
4645
+ const EVENT_SOURCE_EVENTS_KEY = Symbol("EVENT_SOURCE_EVENTS_KEY");
4646
+ const SseEvent = (eventName, options) => {
4647
+ return (target, propertyKey) => {
4648
+ const events = Reflect.getMetadata(EVENT_SOURCE_EVENTS_KEY, target) || [];
4649
+ events.push({
4650
+ eventName: eventName ? eventName : "message",
4651
+ emit: target[propertyKey],
4652
+ options
4653
+ });
4654
+ Reflect.defineMetadata(EVENT_SOURCE_EVENTS_KEY, events, target);
4655
+ };
4656
+ };
4657
+ const EVENT_SOURCE_OPEN_KEY = Symbol("EVENT_SOURCE_OPEN_KEY");
4658
+ const OnSseOpen = () => {
4659
+ return (target, propertyKey) => {
4660
+ Reflect.defineMetadata(EVENT_SOURCE_OPEN_KEY, target[propertyKey], target);
4661
+ };
4662
+ };
4663
+ const EVENT_SOURCE_ERROR_KEY = Symbol("EVENT_SOURCE_ERROR_KEY");
4664
+ const OnSseError = () => {
4665
+ return (target, propertyKey) => {
4666
+ Reflect.defineMetadata(EVENT_SOURCE_ERROR_KEY, target[propertyKey], target);
4667
+ };
4668
+ };
4669
+ const defaultSseOptions = {
4670
+ path: "",
4671
+ withCredentials: false
4672
+ };
4673
+ class SnailSse {
4674
+ constructor(server) {
4675
+ __publicField(this, "_serverInstance");
4676
+ __publicField(this, "_baseUrl");
4677
+ __publicField(this, "_url");
4678
+ __publicField(this, "_version");
4679
+ __publicField(this, "_withCredentials");
4680
+ __publicField(this, "_eventSource");
4681
+ this._serverInstance = server;
4682
+ this._baseUrl = server.baseUrl;
4683
+ const options = this.getSseOptions();
4684
+ const { path, withCredentials, version } = options;
4685
+ this._url = resolveUrl(path);
4686
+ this._version = version;
4687
+ this._withCredentials = withCredentials ? withCredentials : false;
4688
+ this.initVersion();
4689
+ }
4690
+ getSseOptions() {
4691
+ const sseOptions = Reflect.getMetadata(
4692
+ EVENT_SOURCE_OPTION_KEY,
4693
+ this.constructor
4694
+ );
4695
+ if (!sseOptions) {
4696
+ throw new Error(
4697
+ "you need to use @Sse() decorator to decorate your class"
4698
+ );
4177
4699
  }
4178
- const onErrorFunc = Reflect.getMetadata(EVENT_SOURCE_ERROR_KEY, target);
4179
- if (typeof onErrorFunc == "function") {
4180
- this.eventSource && (this.eventSource.onerror = onErrorFunc);
4700
+ const options = Object.assign({}, defaultSseOptions, sseOptions);
4701
+ return options;
4702
+ }
4703
+ initVersion() {
4704
+ const versioningOptions = VersioningMap.get(this._serverInstance.name);
4705
+ if (!versioningOptions || !this._version) return;
4706
+ const versioningResult = applyVersioning(this._version, versioningOptions);
4707
+ if (!versioningResult) return;
4708
+ const { type, result } = versioningResult;
4709
+ if (type === VersioningType.Uri) {
4710
+ const url = `${resolveUrl(result)}${this._url}`;
4711
+ this._url = url;
4712
+ return;
4713
+ }
4714
+ if (type === VersioningType.Query) {
4715
+ const k = Object.keys(result)[0];
4716
+ const v = result[k];
4717
+ this._url = `resolveUrl(${this._url}?${k}=${v})`;
4718
+ return;
4181
4719
  }
4182
4720
  }
4183
- registerSseEvent(target) {
4721
+ open() {
4722
+ const url = `${this._baseUrl}${this._url}`;
4723
+ const eventSource = new EventSource(url, {
4724
+ withCredentials: this._withCredentials
4725
+ });
4726
+ this._eventSource = eventSource;
4727
+ this.setEvent();
4728
+ this.registerSseEvent();
4729
+ }
4730
+ close() {
4184
4731
  const eventSource = this.eventSource;
4185
4732
  if (!eventSource) return;
4733
+ eventSource.close();
4734
+ }
4735
+ registerSseEvent() {
4736
+ const eventSource = this._eventSource;
4737
+ if (!eventSource) return;
4186
4738
  const events = Reflect.getMetadata(
4187
4739
  EVENT_SOURCE_EVENTS_KEY,
4188
- target
4740
+ this.constructor
4189
4741
  );
4190
4742
  events.map((event) => {
4191
4743
  eventSource.addEventListener(event.eventName, event.emit, event.options);
4192
4744
  });
4193
4745
  }
4746
+ setEvent() {
4747
+ const onOpenFunc = Reflect.getMetadata(
4748
+ EVENT_SOURCE_OPEN_KEY,
4749
+ this.constructor
4750
+ );
4751
+ if (typeof onOpenFunc == "function") {
4752
+ this._eventSource && (this._eventSource.onopen = onOpenFunc);
4753
+ }
4754
+ const onErrorFunc = Reflect.getMetadata(
4755
+ EVENT_SOURCE_ERROR_KEY,
4756
+ this.constructor
4757
+ );
4758
+ if (typeof onErrorFunc == "function") {
4759
+ this._eventSource && (this._eventSource.onerror = onErrorFunc);
4760
+ }
4761
+ }
4762
+ on(eventName, callback, options) {
4763
+ this._eventSource && this._eventSource.addEventListener(eventName, callback, options);
4764
+ }
4765
+ off(eventName, callback, options) {
4766
+ this._eventSource && this._eventSource.removeEventListener(eventName, callback, options);
4767
+ }
4768
+ get url() {
4769
+ return this._url;
4770
+ }
4771
+ get eventSource() {
4772
+ return this._eventSource;
4773
+ }
4194
4774
  }
4195
4775
  export {
4196
4776
  Api,
4197
- Cache,
4777
+ CacheStorageAdapter,
4198
4778
  CacheType,
4199
4779
  Data,
4200
4780
  Delete,
4781
+ EventType,
4201
4782
  Get,
4202
4783
  Head,
4784
+ HitSource,
4785
+ NoCache,
4203
4786
  OnSseError,
4204
4787
  OnSseOpen,
4205
4788
  Options,
@@ -4207,18 +4790,29 @@ export {
4207
4790
  Patch,
4208
4791
  Post,
4209
4792
  Put,
4210
- RegisterSseEvent,
4211
- RequestMethod,
4793
+ Query,
4794
+ RequestMethodEnum,
4212
4795
  Server,
4213
- Snail,
4796
+ SnailApi,
4797
+ SnailMethod,
4798
+ SnailPass,
4799
+ SnailServer,
4800
+ SnailSse,
4214
4801
  Sse,
4215
4802
  SseEvent,
4803
+ SseEventListener,
4804
+ SseOptions,
4216
4805
  Strategy,
4217
4806
  UseStrategy,
4218
4807
  Version,
4219
4808
  Versioning,
4220
4809
  VersioningType,
4221
- apiKey,
4810
+ applyStrategies,
4811
+ buildRequestArgs,
4812
+ generateCacheKey,
4222
4813
  generateShortUniqueHash,
4223
- recordToString
4814
+ isSpecialResponse,
4815
+ recordToString,
4816
+ replacePlaceholders,
4817
+ resolveUrl
4224
4818
  };