@wapri/ghermes 0.0.0-stage → 3.0.0-beta.0
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 +16 -3
- package/dist/base.d.ts +46 -0
- package/dist/base.js +165 -0
- package/dist/constants/domain.d.ts +44 -0
- package/dist/constants/domain.js +80 -0
- package/dist/constants/index.d.ts +2 -0
- package/dist/constants/index.js +2 -0
- package/dist/constants/resultCode.d.ts +13 -0
- package/dist/constants/resultCode.js +14 -0
- package/dist/demo/custom-interceptor.d.ts +3 -0
- package/dist/demo/custom-interceptor.js +69 -0
- package/dist/demo/index.d.ts +3 -0
- package/dist/demo/index.js +65 -0
- package/dist/hermes.d.ts +25 -0
- package/dist/hermes.js +107 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/interceptors/index.d.ts +4 -0
- package/dist/interceptors/index.js +298 -0
- package/dist/interceptors/interceptorAddSnowflake.d.ts +7 -0
- package/dist/interceptors/interceptorAddSnowflake.js +35 -0
- package/dist/interceptors/interceptorAddToken.d.ts +7 -0
- package/dist/interceptors/interceptorAddToken.js +46 -0
- package/dist/interceptors/interceptorAddTrace.d.ts +8 -0
- package/dist/interceptors/interceptorAddTrace.js +34 -0
- package/dist/interceptors/interceptorRepeatSubmit.d.ts +8 -0
- package/dist/interceptors/interceptorRepeatSubmit.js +78 -0
- package/dist/modules/auth/dto/account.d.ts +56 -0
- package/dist/modules/auth/dto/account.js +1 -0
- package/dist/modules/auth/dto/ticket.d.ts +13 -0
- package/dist/modules/auth/dto/ticket.js +1 -0
- package/dist/modules/auth/index.d.ts +36 -0
- package/dist/modules/auth/index.js +121 -0
- package/dist/modules/file/dto/tos.d.ts +6 -0
- package/dist/modules/file/dto/tos.js +1 -0
- package/dist/modules/file/index.d.ts +8 -0
- package/dist/modules/file/index.js +28 -0
- package/dist/types/common.d.ts +170 -0
- package/dist/types/common.js +38 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/interceptor.d.ts +13 -0
- package/dist/types/interceptor.js +1 -0
- package/dist/utils/error.d.ts +40 -0
- package/dist/utils/error.js +66 -0
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.js +2 -0
- package/dist/utils/snowflake.d.ts +26 -0
- package/dist/utils/snowflake.js +79 -0
- package/package.json +25 -3
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { InternalAxiosRequestConfig } from 'axios';
|
|
2
|
+
export type HermesCustomizeInterceptor = (config: InternalAxiosRequestConfig<unknown>) => void;
|
|
3
|
+
export type CustomizeInterceptor = {
|
|
4
|
+
request?: HermesCustomizeInterceptor;
|
|
5
|
+
};
|
|
6
|
+
/** 请求统一响应格式 */
|
|
7
|
+
export type HermesResponse<T> = {
|
|
8
|
+
code: number;
|
|
9
|
+
message: string;
|
|
10
|
+
data: T;
|
|
11
|
+
/** 部分网关以 success 标记替代 code 判定 */
|
|
12
|
+
success?: boolean;
|
|
13
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file error
|
|
3
|
+
* @description 请求错误处理纯函数
|
|
4
|
+
* - 保持 hermes「不绑定 UI 库」的设计:只负责提取文案与打标记
|
|
5
|
+
* - 提示由业务层自行决定(element-plus / antd / 自研组件均可)
|
|
6
|
+
*/
|
|
7
|
+
/** 请求层抛出的错误:带通知标记与追踪信息,业务 catch 可据此避免重复提示 */
|
|
8
|
+
export type HermesRequestError = Error & {
|
|
9
|
+
/** 是否已在请求层提示过(用于避免业务 catch 再弹一遍) */
|
|
10
|
+
__notified?: boolean;
|
|
11
|
+
/** 业务错误码 */
|
|
12
|
+
code?: string | number;
|
|
13
|
+
/** 链路追踪 ID */
|
|
14
|
+
traceId?: string;
|
|
15
|
+
/** 原始响应体(可选) */
|
|
16
|
+
response?: unknown;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* 解析错误响应体,兼容「对象」与「JSON 字符串」两种形态。
|
|
20
|
+
*/
|
|
21
|
+
export declare function normalizeErrorPayload(data: unknown): Record<string, unknown> | null;
|
|
22
|
+
/**
|
|
23
|
+
* 标记「请求层已提示」的错误,附带 code / traceId。
|
|
24
|
+
*/
|
|
25
|
+
export declare function markNotifiedError(message: string, extra?: {
|
|
26
|
+
code?: string | number;
|
|
27
|
+
traceId?: string;
|
|
28
|
+
}): HermesRequestError;
|
|
29
|
+
/**
|
|
30
|
+
* 提取可展示的请求错误文案。
|
|
31
|
+
* 过滤 `error` / `cancel` / `invalid` 及 `Request failed with status code` 等泛化文案。
|
|
32
|
+
*
|
|
33
|
+
* @param error 任意错误对象
|
|
34
|
+
* @param fallback 无法提取时的兜底文案
|
|
35
|
+
*/
|
|
36
|
+
export declare function resolveRequestErrorMessage(error: unknown, fallback?: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* 判断错误是否已在请求层提示过(业务 catch 可直接据此跳过重复提示)。
|
|
39
|
+
*/
|
|
40
|
+
export declare function isNotifiedError(error: unknown): boolean;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
/**
|
|
3
|
+
* @file error
|
|
4
|
+
* @description 请求错误处理纯函数
|
|
5
|
+
* - 保持 hermes「不绑定 UI 库」的设计:只负责提取文案与打标记
|
|
6
|
+
* - 提示由业务层自行决定(element-plus / antd / 自研组件均可)
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/** 请求层抛出的错误:带通知标记与追踪信息,业务 catch 可据此避免重复提示 */
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* 解析错误响应体,兼容「对象」与「JSON 字符串」两种形态。
|
|
13
|
+
*/
|
|
14
|
+
export function normalizeErrorPayload(data) {
|
|
15
|
+
if (!data) return null;
|
|
16
|
+
if (_typeof(data) === 'object') return data;
|
|
17
|
+
if (typeof data === 'string' && data) {
|
|
18
|
+
try {
|
|
19
|
+
var parsed = JSON.parse(data);
|
|
20
|
+
return parsed && _typeof(parsed) === 'object' ? parsed : null;
|
|
21
|
+
} catch (_unused) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* 标记「请求层已提示」的错误,附带 code / traceId。
|
|
30
|
+
*/
|
|
31
|
+
export function markNotifiedError(message) {
|
|
32
|
+
var extra = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
33
|
+
var err = new Error(message);
|
|
34
|
+
err.__notified = true;
|
|
35
|
+
if (extra.code !== undefined) err.code = extra.code;
|
|
36
|
+
if (extra.traceId !== undefined) err.traceId = extra.traceId;
|
|
37
|
+
return err;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* 提取可展示的请求错误文案。
|
|
42
|
+
* 过滤 `error` / `cancel` / `invalid` 及 `Request failed with status code` 等泛化文案。
|
|
43
|
+
*
|
|
44
|
+
* @param error 任意错误对象
|
|
45
|
+
* @param fallback 无法提取时的兜底文案
|
|
46
|
+
*/
|
|
47
|
+
export function resolveRequestErrorMessage(error) {
|
|
48
|
+
var _err$response;
|
|
49
|
+
var fallback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '操作失败';
|
|
50
|
+
if (!error || error === 'error' || error === 'cancel') return fallback;
|
|
51
|
+
var err = error;
|
|
52
|
+
if (err.message === 'invalid') return '';
|
|
53
|
+
var payload = normalizeErrorPayload((_err$response = err.response) === null || _err$response === void 0 ? void 0 : _err$response.data);
|
|
54
|
+
var biz = payload && (payload.message || payload.msg) || err.message;
|
|
55
|
+
if (biz && typeof biz === 'string' && biz !== 'error' && !biz.includes('Request failed with status code')) {
|
|
56
|
+
return biz;
|
|
57
|
+
}
|
|
58
|
+
return fallback;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* 判断错误是否已在请求层提示过(业务 catch 可直接据此跳过重复提示)。
|
|
63
|
+
*/
|
|
64
|
+
export function isNotifiedError(error) {
|
|
65
|
+
return Boolean(error && error.__notified);
|
|
66
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file snowflake
|
|
3
|
+
* @description 雪花 Long 精度保护
|
|
4
|
+
* - 后端雪花 ID 通常为 19 位,超出 JS Number.MAX_SAFE_INTEGER(2^53-1)
|
|
5
|
+
* - 若以 JSON 数字返回,会在 JSON.parse 阶段丢精度
|
|
6
|
+
* - 因此:响应侧在 parse 前改写为字符串;请求侧把 ID 字段收成字符串
|
|
7
|
+
*/
|
|
8
|
+
/** 视为长整型的最小位数 */
|
|
9
|
+
export declare const LONG_DIGIT_MIN = 16;
|
|
10
|
+
/**
|
|
11
|
+
* 将 JSON 文本中「未加引号」的超长整数改为字符串,再 parse。
|
|
12
|
+
* 已在引号内的内容(含 URL)不会被改写。
|
|
13
|
+
*/
|
|
14
|
+
export declare function parseJsonSafeLong(text: string): unknown;
|
|
15
|
+
/**
|
|
16
|
+
* axios transformResponse:安全解析 JSON,解析失败或其他类型原样返回。
|
|
17
|
+
*/
|
|
18
|
+
export declare function axiosTransformSafeLong(data: unknown): unknown;
|
|
19
|
+
/**
|
|
20
|
+
* 递归处理请求 payload:把可能丢精度的 ID 字段强制转为字符串。
|
|
21
|
+
* - null/undefined 原样返回
|
|
22
|
+
* - 数组逐项递归
|
|
23
|
+
* - 对象递归每个字段;FormData / Blob / File 直接跳过
|
|
24
|
+
* - 叶子字段命中 ID 规则且为 16 位及以上数字时转字符串
|
|
25
|
+
*/
|
|
26
|
+
export declare function stringifySnowflakeFields(value: unknown, key?: string): unknown;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2
|
+
/**
|
|
3
|
+
* @file snowflake
|
|
4
|
+
* @description 雪花 Long 精度保护
|
|
5
|
+
* - 后端雪花 ID 通常为 19 位,超出 JS Number.MAX_SAFE_INTEGER(2^53-1)
|
|
6
|
+
* - 若以 JSON 数字返回,会在 JSON.parse 阶段丢精度
|
|
7
|
+
* - 因此:响应侧在 parse 前改写为字符串;请求侧把 ID 字段收成字符串
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** 视为长整型的最小位数 */
|
|
11
|
+
export var LONG_DIGIT_MIN = 16;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* 将 JSON 文本中「未加引号」的超长整数改为字符串,再 parse。
|
|
15
|
+
* 已在引号内的内容(含 URL)不会被改写。
|
|
16
|
+
*/
|
|
17
|
+
export function parseJsonSafeLong(text) {
|
|
18
|
+
if (typeof text !== 'string') return text;
|
|
19
|
+
var trimmed = text.trim();
|
|
20
|
+
if (!trimmed || trimmed[0] !== '{' && trimmed[0] !== '[') {
|
|
21
|
+
return text;
|
|
22
|
+
}
|
|
23
|
+
var quoted = trimmed.replace(/"(?:\\.|[^"\\])*"|(-?\d{16,})/g, function (match, num) {
|
|
24
|
+
return num != null ? "\"".concat(num, "\"") : match;
|
|
25
|
+
});
|
|
26
|
+
return JSON.parse(quoted);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* axios transformResponse:安全解析 JSON,解析失败或其他类型原样返回。
|
|
31
|
+
*/
|
|
32
|
+
export function axiosTransformSafeLong(data) {
|
|
33
|
+
if (typeof data !== 'string' || !data) return data;
|
|
34
|
+
try {
|
|
35
|
+
return parseJsonSafeLong(data);
|
|
36
|
+
} catch (_unused) {
|
|
37
|
+
return data;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** 命中 ID 语义的字段名(首尾 Id/ID,或 fileId/id) */
|
|
42
|
+
function looksLikeIdField(key) {
|
|
43
|
+
return /(?:^|Id|ID)$/.test(key) || key === 'fileId' || key === 'id';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* 递归处理请求 payload:把可能丢精度的 ID 字段强制转为字符串。
|
|
48
|
+
* - null/undefined 原样返回
|
|
49
|
+
* - 数组逐项递归
|
|
50
|
+
* - 对象递归每个字段;FormData / Blob / File 直接跳过
|
|
51
|
+
* - 叶子字段命中 ID 规则且为 16 位及以上数字时转字符串
|
|
52
|
+
*/
|
|
53
|
+
export function stringifySnowflakeFields(value, key) {
|
|
54
|
+
if (value == null) return value;
|
|
55
|
+
if (Array.isArray(value)) {
|
|
56
|
+
return value.map(function (item) {
|
|
57
|
+
return stringifySnowflakeFields(item);
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
if (_typeof(value) === 'object') {
|
|
61
|
+
if (value instanceof FormData || value instanceof Blob || value instanceof File) {
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
var out = {};
|
|
65
|
+
Object.keys(value).forEach(function (k) {
|
|
66
|
+
out[k] = stringifySnowflakeFields(value[k], k);
|
|
67
|
+
});
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
// 叶子值:命中 ID 规则且为超长数字时转字符串
|
|
71
|
+
if (key && looksLikeIdField(key) && (typeof value === 'number' || typeof value === 'string')) {
|
|
72
|
+
// 已丢精度的 Number 再 String 也无法恢复,只能告警
|
|
73
|
+
if (typeof value === 'number' && !Number.isSafeInteger(value)) {
|
|
74
|
+
console.error('[hermes:snowflake] 请求字段已丢精度,无法恢复:', key, value);
|
|
75
|
+
}
|
|
76
|
+
if (/^\d{16,}$/.test(String(value))) return String(value);
|
|
77
|
+
}
|
|
78
|
+
return value;
|
|
79
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wapri/ghermes",
|
|
3
|
-
"version": "0.0.0
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "3.0.0-beta.0",
|
|
4
|
+
"description": "公共请求库,维护了统一请求与不同模块的请求",
|
|
5
|
+
"keywords": [],
|
|
6
|
+
"license": "UNLICENSED",
|
|
7
|
+
"author": "wa",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"type": "module",
|
|
10
|
+
"module": "dist/index.js",
|
|
11
|
+
"types": "dist/index.d.ts",
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"dependencies": {
|
|
16
|
+
"axios": "^1.16.1",
|
|
17
|
+
"@wapri/gbase": "^1.0.1-beta.0"
|
|
18
|
+
},
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public",
|
|
21
|
+
"registry": "https://registry.npmjs.org/"
|
|
22
|
+
},
|
|
23
|
+
"peerDependenciesMeta": {},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "father build",
|
|
26
|
+
"dev": "father dev"
|
|
27
|
+
}
|
|
6
28
|
}
|