@i.un/api-client 1.1.0 → 1.1.2
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/dist/index.d.mts +11 -2
- package/dist/index.d.ts +11 -2
- package/dist/index.js +10 -11
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +10 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FetchContext, $Fetch, FetchOptions } from 'ofetch';
|
|
2
|
+
import protobuf from 'protobufjs/light';
|
|
2
3
|
|
|
3
4
|
interface ApiResult<T> {
|
|
4
5
|
code: number;
|
|
@@ -141,6 +142,14 @@ declare function executeRequestChain<T>(requests: ChainRequestRule[], handlers?:
|
|
|
141
142
|
* 提供基于 Protobuf 的二进制序列化、XOR 混淆加密以及与 API Client 的无缝集成。
|
|
142
143
|
*/
|
|
143
144
|
|
|
145
|
+
interface ProtobufTypeLike {
|
|
146
|
+
create(properties?: Record<string, any>): any;
|
|
147
|
+
encode(message: any): {
|
|
148
|
+
finish(): Uint8Array;
|
|
149
|
+
};
|
|
150
|
+
decode(reader: Uint8Array | protobuf.Reader): any;
|
|
151
|
+
toObject(message: any, options?: protobuf.IConversionOptions): any;
|
|
152
|
+
}
|
|
144
153
|
/**
|
|
145
154
|
* 基础编解码配置
|
|
146
155
|
* 控制如何将数据转换为二进制,以及是否混淆
|
|
@@ -154,7 +163,7 @@ interface ProtobufCodecOptions {
|
|
|
154
163
|
*/
|
|
155
164
|
obfuscationKey?: string | Uint8Array | (() => string | Uint8Array | Promise<string | Uint8Array>);
|
|
156
165
|
/** 预编译的 Protobuf 类型对象 (推荐,性能最高) */
|
|
157
|
-
protoType?:
|
|
166
|
+
protoType?: ProtobufTypeLike;
|
|
158
167
|
/** 数据转换钩子:处理业务模型与 Proto 结构不一致的情况 */
|
|
159
168
|
transform?: {
|
|
160
169
|
beforeEncode?: (data: any) => any;
|
|
@@ -217,4 +226,4 @@ declare function createProtobufHooks(options?: ProtobufHooksOptions): {
|
|
|
217
226
|
onResponse(context: FetchContext): Promise<void>;
|
|
218
227
|
};
|
|
219
228
|
|
|
220
|
-
export { type ApiError, type ApiResult, type ChainRequestRule, type CreateApiClientOptions, type HttpRequestSpec, type NetworkAdapter, type NetworkHandler, type ProtobufCodecOptions, type ProtobufConfig, type ProtobufCustomCodec, type ProtobufHooksOptions, type TokenStorage, createApiClient, createProtobufHooks, decodeSecure, encodeSecure, executeRequestChain, getObfuscationKey, isApiError, isProtobufContentType, normalizeProtobufConfig, parseSecureRequest, secureResponse, xorTransform };
|
|
229
|
+
export { type ApiError, type ApiResult, type ChainRequestRule, type CreateApiClientOptions, type HttpRequestSpec, type NetworkAdapter, type NetworkHandler, type ProtobufCodecOptions, type ProtobufConfig, type ProtobufCustomCodec, type ProtobufHooksOptions, type ProtobufTypeLike, type TokenStorage, createApiClient, createProtobufHooks, decodeSecure, encodeSecure, executeRequestChain, getObfuscationKey, isApiError, isProtobufContentType, normalizeProtobufConfig, parseSecureRequest, secureResponse, xorTransform };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FetchContext, $Fetch, FetchOptions } from 'ofetch';
|
|
2
|
+
import protobuf from 'protobufjs/light';
|
|
2
3
|
|
|
3
4
|
interface ApiResult<T> {
|
|
4
5
|
code: number;
|
|
@@ -141,6 +142,14 @@ declare function executeRequestChain<T>(requests: ChainRequestRule[], handlers?:
|
|
|
141
142
|
* 提供基于 Protobuf 的二进制序列化、XOR 混淆加密以及与 API Client 的无缝集成。
|
|
142
143
|
*/
|
|
143
144
|
|
|
145
|
+
interface ProtobufTypeLike {
|
|
146
|
+
create(properties?: Record<string, any>): any;
|
|
147
|
+
encode(message: any): {
|
|
148
|
+
finish(): Uint8Array;
|
|
149
|
+
};
|
|
150
|
+
decode(reader: Uint8Array | protobuf.Reader): any;
|
|
151
|
+
toObject(message: any, options?: protobuf.IConversionOptions): any;
|
|
152
|
+
}
|
|
144
153
|
/**
|
|
145
154
|
* 基础编解码配置
|
|
146
155
|
* 控制如何将数据转换为二进制,以及是否混淆
|
|
@@ -154,7 +163,7 @@ interface ProtobufCodecOptions {
|
|
|
154
163
|
*/
|
|
155
164
|
obfuscationKey?: string | Uint8Array | (() => string | Uint8Array | Promise<string | Uint8Array>);
|
|
156
165
|
/** 预编译的 Protobuf 类型对象 (推荐,性能最高) */
|
|
157
|
-
protoType?:
|
|
166
|
+
protoType?: ProtobufTypeLike;
|
|
158
167
|
/** 数据转换钩子:处理业务模型与 Proto 结构不一致的情况 */
|
|
159
168
|
transform?: {
|
|
160
169
|
beforeEncode?: (data: any) => any;
|
|
@@ -217,4 +226,4 @@ declare function createProtobufHooks(options?: ProtobufHooksOptions): {
|
|
|
217
226
|
onResponse(context: FetchContext): Promise<void>;
|
|
218
227
|
};
|
|
219
228
|
|
|
220
|
-
export { type ApiError, type ApiResult, type ChainRequestRule, type CreateApiClientOptions, type HttpRequestSpec, type NetworkAdapter, type NetworkHandler, type ProtobufCodecOptions, type ProtobufConfig, type ProtobufCustomCodec, type ProtobufHooksOptions, type TokenStorage, createApiClient, createProtobufHooks, decodeSecure, encodeSecure, executeRequestChain, getObfuscationKey, isApiError, isProtobufContentType, normalizeProtobufConfig, parseSecureRequest, secureResponse, xorTransform };
|
|
229
|
+
export { type ApiError, type ApiResult, type ChainRequestRule, type CreateApiClientOptions, type HttpRequestSpec, type NetworkAdapter, type NetworkHandler, type ProtobufCodecOptions, type ProtobufConfig, type ProtobufCustomCodec, type ProtobufHooksOptions, type ProtobufTypeLike, type TokenStorage, createApiClient, createProtobufHooks, decodeSecure, encodeSecure, executeRequestChain, getObfuscationKey, isApiError, isProtobufContentType, normalizeProtobufConfig, parseSecureRequest, secureResponse, xorTransform };
|
package/dist/index.js
CHANGED
|
@@ -537,7 +537,7 @@ async function encodeSecure(data, options = {}) {
|
|
|
537
537
|
let buffer;
|
|
538
538
|
const processedData = transform?.beforeEncode ? transform.beforeEncode(data) : data;
|
|
539
539
|
if (customEncode) {
|
|
540
|
-
buffer = await customEncode(
|
|
540
|
+
buffer = await customEncode(processedData);
|
|
541
541
|
} else {
|
|
542
542
|
const type = protoType || getInternalSecureType();
|
|
543
543
|
const payload = protoType ? processedData : {
|
|
@@ -560,7 +560,7 @@ async function decodeSecure(buffer, options = {}) {
|
|
|
560
560
|
transform,
|
|
561
561
|
decode: customDecode
|
|
562
562
|
} = options;
|
|
563
|
-
let uint8 =
|
|
563
|
+
let uint8 = ArrayBuffer.isView(buffer) ? new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength) : new Uint8Array(buffer);
|
|
564
564
|
if (uint8.length > 0 && obfuscate) {
|
|
565
565
|
const finalKey = await getObfuscationKey(obfuscationKey);
|
|
566
566
|
uint8 = xorTransform(uint8, finalKey);
|
|
@@ -591,11 +591,8 @@ async function decodeSecure(buffer, options = {}) {
|
|
|
591
591
|
}
|
|
592
592
|
async function secureResponse(data, options) {
|
|
593
593
|
const buffer = await encodeSecure(data, options);
|
|
594
|
-
const
|
|
595
|
-
|
|
596
|
-
buffer.byteOffset + buffer.byteLength
|
|
597
|
-
);
|
|
598
|
-
return new Response(arrayBuffer, {
|
|
594
|
+
const cleanBuffer = buffer.slice();
|
|
595
|
+
return new Response(cleanBuffer, {
|
|
599
596
|
headers: {
|
|
600
597
|
"Content-Type": "application/x-protobuf",
|
|
601
598
|
...options?.corsHeaders
|
|
@@ -636,11 +633,13 @@ function createProtobufHooks(options = {}) {
|
|
|
636
633
|
},
|
|
637
634
|
async onResponse(context) {
|
|
638
635
|
const { response } = context;
|
|
639
|
-
if (!response?._data) return;
|
|
636
|
+
if (!response?._data || response.status === 204) return;
|
|
640
637
|
if (isProtobufContentType(response.headers.get("Content-Type"))) {
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
638
|
+
try {
|
|
639
|
+
response._data = await decode(response._data);
|
|
640
|
+
} catch (e) {
|
|
641
|
+
console.log("Error [Protobuf Decode Error]", e);
|
|
642
|
+
response._data = null;
|
|
644
643
|
}
|
|
645
644
|
} else if (response._data instanceof ArrayBuffer) {
|
|
646
645
|
const text = decoder.decode(response._data);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/client.ts","../src/chain.ts","../src/secure.js","../src/protobuf.ts"],"sourcesContent":["export * from \"./client\";\nexport * from \"./chain\";\nexport * from \"./protobuf\";\n","import {\n ofetch,\n type FetchOptions,\n type FetchContext,\n type $Fetch,\n} from \"ofetch\";\n\nexport interface ApiResult<T> {\n code: number;\n data: T;\n message: string;\n}\n\nexport interface ApiError extends Error {\n code: number; // 业务错误码\n data?: unknown; // 后端返回的 data 字段(如果有)\n status?: number; // HTTP 状态码(网络错误时)\n}\n\n// 类型守卫:判断是否是 API 业务错误\nexport const isApiError = (error: unknown): error is ApiError => {\n return error instanceof Error && \"code\" in error;\n};\n\nexport interface TokenStorage {\n getAccessToken: () => Promise<string> | string;\n setAccessToken: (token: string) => Promise<void> | void;\n}\n\nexport interface CreateApiClientOptions {\n baseURL: string;\n tokenStorage: TokenStorage;\n refreshToken?: (() => Promise<string>) | string | false;\n retry?: number; // 重试次数,默认 1\n retryDelay?: number; // 重试间隔,默认 1s\n isAuthError?: (code: number) => boolean;\n unwrapResponse?<T>(result: unknown, returnFullResponse: boolean): T;\n createErrorFromResult?(res: unknown): Error;\n /**\n * 自定义请求钩子\n * 在请求发送前执行,可用于编码请求体等\n */\n onRequest?: (context: FetchContext) => void | Promise<void>;\n /**\n * 自定义响应钩子\n * 在响应返回后执行,可用于解码响应体等\n */\n onResponse?: (context: FetchContext) => void | Promise<void>;\n}\n\ntype RequestOptions = Omit<FetchOptions<\"json\">, \"responseType\"> & {\n returnFullResponse?: boolean;\n responseType?: \"json\" | \"arrayBuffer\" | \"text\" | \"blob\";\n};\n\n// 解包后端统一响应格式(默认实现)\nconst defaultUnwrapResponse = <T>(\n result: unknown,\n returnFullResponse = false,\n): T => {\n if (result && typeof result === \"object\" && \"code\" in result) {\n const body = result as Record<string, unknown>;\n if (body.code === 0) {\n return returnFullResponse ? (body as T) : (body.data as T);\n }\n }\n return result as T;\n};\n\nconst defaultCreateErrorFromResult = (res: ApiResult<unknown>): ApiError => {\n const error = new Error(res.message || \"Request failed\") as ApiError;\n error.code = res.code;\n error.data = res.data;\n return error;\n};\n\nconst extractAccessToken = (data: unknown): string => {\n if (typeof data === \"string\" && data) {\n return data;\n }\n\n if (!data || typeof data !== \"object\") {\n throw new Error(\n \"Invalid refresh token response: data is not an object or string\",\n );\n }\n\n const anyData = data as Record<string, unknown>;\n\n const accessToken =\n anyData.access_token ?? anyData.accessToken ?? anyData.token;\n\n if (typeof accessToken === \"string\" && accessToken) {\n return accessToken;\n }\n\n throw new Error(\n \"Invalid refresh token response: no access_token or token field found\",\n );\n};\n\n// 全局共享的刷新状态,以 tokenStorage 为 Key\n// 这样即使有多个 ApiClient 实例,只要它们共用同一个 tokenStorage,刷新逻辑就是单例的\nconst refreshingPromises = new WeakMap<TokenStorage, Promise<string>>();\n\nexport function createApiClient(options: CreateApiClientOptions) {\n const {\n baseURL,\n tokenStorage,\n refreshToken = false,\n retry = 1,\n retryDelay = 1000,\n isAuthError = (code: number) => code === 401,\n unwrapResponse = defaultUnwrapResponse,\n createErrorFromResult = defaultCreateErrorFromResult,\n } = options;\n\n const refreshTokenFn: (() => Promise<string>) | null = !refreshToken\n ? null\n : typeof refreshToken === \"string\"\n ? async () => {\n const res = await ofetch<ApiResult<unknown>>(refreshToken, {\n baseURL,\n method: \"POST\",\n retry,\n retryDelay,\n });\n\n if (res.code !== 0) {\n throw createErrorFromResult(res as ApiResult<unknown>);\n }\n\n return extractAccessToken(res.data);\n }\n : refreshToken;\n\n const rawRequest = ofetch.create({\n baseURL,\n retry,\n retryDelay,\n\n async onRequest(context: FetchContext) {\n const { options: reqOptions } = context;\n const token = await tokenStorage.getAccessToken();\n\n const headers = new Headers(\n reqOptions.headers as HeadersInit | undefined,\n );\n\n if (token) {\n headers.set(\"Authorization\", `Bearer ${token}`);\n }\n\n reqOptions.headers = headers;\n\n // 执行用户自定义钩子\n if (options.onRequest) {\n await options.onRequest(context);\n }\n },\n async onResponse(context) {\n const { response } = context;\n // 不在这里处理 code,统一交给 fetchApi 层处理\n if (response.status === 204) {\n response._data = null;\n return;\n }\n\n // 执行用户自定义钩子\n if (options.onResponse) {\n await options.onResponse(context);\n }\n },\n\n async onResponseError(context: FetchContext) {\n // 后端统一返回 HTTP 200,此处只处理网络层错误(如超时、断网)\n const { response } = context;\n const message =\n (response?._data as Record<string, unknown>)?.message ||\n `HTTP ${response?.status || \"Network Error\"}`;\n\n const error = new Error(message as string) as ApiError;\n error.status = response?.status;\n error.data = response?._data;\n throw error;\n },\n }) as $Fetch;\n\n async function request<T = unknown>(\n url: string,\n options: RequestOptions & { _retry?: boolean } = {},\n ): Promise<T> {\n // 提取自定义选项,避免传递给 $fetch\n const { returnFullResponse, _retry, ...fetchOptions } = options;\n\n // const res = await rawRequest<ApiResult<T>>(url, fetchOptions);\n const res = (await rawRequest(url, fetchOptions as FetchOptions)) as ApiResult<T>;\n\n if (res.code === 0) {\n return unwrapResponse<T>(res, !!returnFullResponse);\n // if (returnFullResponse) {\n // return res as unknown as T;\n // }\n\n // return res.data;\n }\n\n if (isAuthError(res.code) && !_retry && refreshTokenFn) {\n try {\n let refreshingPromise = refreshingPromises.get(tokenStorage);\n\n if (!refreshingPromise) {\n refreshingPromise = refreshTokenFn().finally(() => {\n refreshingPromises.delete(tokenStorage);\n });\n refreshingPromises.set(tokenStorage, refreshingPromise);\n }\n\n const newToken = await refreshingPromise;\n\n if (newToken) {\n await tokenStorage.setAccessToken(newToken);\n }\n\n return await request<T>(url, {\n ...(options || {}),\n _retry: true,\n } as any);\n } catch (e) {\n await tokenStorage.setAccessToken(\"\");\n throw createErrorFromResult(res as ApiResult<unknown>);\n }\n }\n\n throw createErrorFromResult(res as ApiResult<unknown>);\n }\n\n async function get<T = unknown>(\n url: string,\n params: FetchOptions[\"query\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"GET\",\n query: params,\n } as any);\n }\n\n async function post<T = unknown>(\n url: string,\n body: FetchOptions[\"body\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"POST\",\n body,\n } as any);\n }\n\n async function put<T = unknown>(\n url: string,\n body: FetchOptions[\"body\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"PUT\",\n body,\n } as any);\n }\n\n async function patch<T = unknown>(\n url: string,\n body: FetchOptions[\"body\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"PATCH\",\n body,\n } as any);\n }\n\n async function del<T = unknown>(\n url: string,\n params: FetchOptions[\"query\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"DELETE\",\n query: params,\n } as any);\n }\n\n return {\n rawRequest,\n request,\n get,\n post,\n put,\n patch,\n del,\n };\n}\n","/**\n * Request Chain Runner\n * 负责解析和执行通用的 HTTP 请求链 (Chain Execution)\n * 适用于任何需要链式 HTTP 请求编排的场景\n */\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/** Supported HTTP Methods */\ntype HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n\n/** HTTP 请求参数 */\nexport interface HttpRequestSpec {\n method: HttpMethod;\n url: string;\n headers?: Record<string, string>;\n body?: any;\n}\n\n/**\n * 网络适配器接口\n * 定义实际发送请求的能力\n */\n/**\n * 网络适配器接口\n * 定义实际发送请求的能力\n */\nexport interface NetworkAdapter {\n get<T>(\n url: string,\n params?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n post<T>(\n url: string,\n body?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n put?<T>(\n url: string,\n body?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n delete?<T>(\n url: string,\n params?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n patch?<T>(\n url: string,\n body?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n}\n\n/**\n * 网络处理器接口 (Strategy Pattern)\n * 组合了\"匹配规则\"和\"执行能力\"\n */\nexport interface NetworkHandler {\n /** 处理器名称 (用于调试) */\n name?: string;\n\n /** 判断该 URL 是否由此适配器处理 */\n shouldHandle(url: string, method: HttpMethod): boolean;\n\n /** 具体的网络适配器 */\n adapter: NetworkAdapter;\n}\n\n/**\n * 请求链规则 (Chain Step)\n */\nexport interface ChainRequestRule {\n /**\n * 结果存储的键名 (Context Key)\n * Fetch 结果存储: context[key] = response\n */\n key?: string;\n\n /**\n * HTTP 请求详情\n */\n request: HttpRequestSpec;\n\n /**\n * 数据提取选择器\n * 用于从响应中提取特定数据, e.g., \"elements.0\"\n */\n selector?: string;\n\n /** 是否允许请求失败 (默认 false) */\n optional?: boolean;\n\n /**\n * 是否包含上下文\n * 如果为 true,请求 Body 将自动合并当前 Context 和 Payload\n */\n includeContext?: boolean;\n\n /**\n * 上下文筛选列表 (优先级高于 includeContext)\n * 指定需要合并到 Body 中的 Context Key 列表\n * e.g., [\"rawProfile\", \"rawCompany\"]\n */\n pickContext?: string[];\n\n /** 额外 Payload (仅当 includeContext 为 true 或 pickContext 存在时合并) */\n payload?: Record<string, any>;\n}\n\n// ============================================================================\n// Internal Utilities\n// ============================================================================\n\n/**\n * 执行 HTTP 请求\n * 遍历 handlers 数组,找到第一个能处理该 URL 的适配器执行\n *\n * @param spec 请求详情\n * @param handlers 网络处理器链\n */\nasync function executeChainRequest<T>(\n spec: HttpRequestSpec,\n handlers: NetworkHandler[] = []\n): Promise<T | null> {\n // Normalize method to upper case for robustness\n const method = spec.method.toUpperCase() as HttpMethod;\n\n // 1. 遍历处理器数组 (责任链)\n for (const handler of handlers) {\n if (handler.shouldHandle(spec.url, method)) {\n try {\n const { adapter } = handler;\n const headers = spec.headers;\n\n switch (method) {\n case \"GET\":\n return await adapter.get<T>(spec.url, spec.body, headers);\n case \"POST\":\n return await adapter.post<T>(spec.url, spec.body, headers);\n case \"PUT\":\n if (!adapter.put)\n throw new Error(`Adapter ${handler.name} missing PUT method`);\n return await adapter.put<T>(spec.url, spec.body, headers);\n case \"DELETE\":\n if (!adapter.delete)\n throw new Error(`Adapter ${handler.name} missing DELETE method`);\n return await adapter.delete<T>(spec.url, spec.body, headers);\n case \"PATCH\":\n if (!adapter.patch)\n throw new Error(`Adapter ${handler.name} missing PATCH method`);\n return await adapter.patch<T>(spec.url, spec.body, headers);\n default:\n throw new Error(`Unsupported method: ${method}`);\n }\n } catch (err) {\n console.warn(\n `Handler [${handler.name || \"Anonymous\"}] failed for ${spec.url}`,\n err\n );\n // 如果需要继续尝试下一个 handler,可以在这里 continue,但通常由第一个匹配者全权负责\n return null;\n }\n }\n }\n\n // 2. 默认行为 (Fallback): 绝对路径自动走标准 fetch\n if (spec.url.startsWith(\"http://\") || spec.url.startsWith(\"https://\")) {\n return await executeFallbackFetch<T>(spec);\n }\n\n console.warn(`No handler found for url: ${spec.url}`);\n return null;\n}\n\n/**\n * 标准 Fetch 回退实现\n */\nasync function executeFallbackFetch<T>(\n spec: HttpRequestSpec\n): Promise<T | null> {\n try {\n const response = await fetch(spec.url, {\n method: spec.method,\n headers: spec.headers,\n body: spec.body ? JSON.stringify(spec.body) : undefined,\n credentials: \"include\",\n });\n\n if (!response.ok) {\n console.log(`External Request failed: ${response.status} ${spec.url}`);\n return null;\n }\n\n return await response.json();\n } catch (err) {\n console.log(\"External Request error:\", err);\n return null;\n }\n}\n\n/**\n * 根据路径获取对象值\n */\nfunction getByPath(obj: any, path: string): any {\n if (!path) return obj;\n return path.split(\".\").reduce((acc, part) => acc && acc[part], obj);\n}\n\n/**\n * 变量替换 (Internal)\n * 支持字符串 {{key}} 和 {{key.prop}}\n */\nfunction substituteVariables(target: any, context: any): any {\n if (typeof target === \"string\") {\n return target.replace(/\\{\\{([\\w\\.]+)\\}\\}/g, (_, path) => {\n const val = getByPath(context, path);\n return val !== undefined ? String(val) : \"\";\n });\n }\n\n if (Array.isArray(target)) {\n return target.map((item) => substituteVariables(item, context));\n }\n\n if (target && typeof target === \"object\") {\n const result: any = {};\n for (const key in target) {\n result[key] = substituteVariables(target[key], context);\n }\n return result;\n }\n\n return target;\n}\n\n// ============================================================================\n// Main Runner\n// ============================================================================\n\n/**\n * 请求链执行器 (Request Chain Engine)\n * 支持链式请求、上下文累积、智能路由、变量替换\n *\n * @param requests 链式执行规则列表\n * @param handlers 网络适配器处理器列表 (按顺序匹配)\n */\nexport async function executeRequestChain<T>(\n requests: ChainRequestRule[],\n handlers: NetworkHandler[] = [],\n getChainRequests?: (\n context: Record<string, any>\n ) => ChainRequestRule[] | null | undefined,\n initContext?: Record<string, any>\n): Promise<T> {\n const context: Record<string, any> = initContext || {};\n let lastResult: any = null;\n\n for (const rule of requests) {\n try {\n // 1. 准备 Context Data (用于 Submit)\n let contextData: Record<string, any> = {};\n if (rule.pickContext) {\n rule.pickContext.forEach((key) => {\n if (key in context) contextData[key] = context[key];\n });\n } else if (rule.includeContext) {\n contextData = context;\n }\n const hasContextData = Object.keys(contextData).length > 0;\n\n // 2. 准备 Request Spec (合并 Payload 和 Context)\n let requestSpec = { ...rule.request };\n if (hasContextData || rule.payload) {\n requestSpec.body = {\n ...(rule.payload || {}),\n ...contextData,\n ...(requestSpec.body || {}),\n };\n }\n\n // 3. 变量替换\n requestSpec = substituteVariables(requestSpec, context);\n\n // 4. 执行请求 (传入 handlers)\n let rawData = await executeChainRequest<any>(requestSpec, handlers);\n\n if (getChainRequests) {\n const chainRequests = getChainRequests(rawData);\n if (chainRequests && chainRequests.length > 0) {\n rawData = await executeRequestChain(\n chainRequests,\n handlers,\n getChainRequests,\n JSON.parse(JSON.stringify(context))\n );\n }\n }\n\n lastResult = rawData;\n\n if (rawData) {\n // 5. 存储结果\n if (rule.key) {\n const data = rule.selector\n ? getByPath(rawData, rule.selector)\n : rawData;\n context[rule.key] = data;\n }\n } else if (!rule.optional) {\n throw new Error(\n `Failed to fetch required data for key: ${rule.key || \"unknown\"}`\n );\n }\n } catch (err) {\n if (!rule.optional) {\n throw err;\n }\n console.warn(`Optional request failed for rule:`, rule, err);\n }\n }\n\n return lastResult as T;\n}\n","/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/\nimport * as $protobuf from \"protobufjs/minimal\";\n\n// Common aliases\nconst $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;\n\n// Exported root namespace\nconst $root = $protobuf.roots[\"default\"] || ($protobuf.roots[\"default\"] = {});\n\nexport const secure = $root.secure = (() => {\n\n /**\n * Namespace secure.\n * @exports secure\n * @namespace\n */\n const secure = {};\n\n secure.SecurePayload = (function() {\n\n /**\n * Properties of a SecurePayload.\n * @memberof secure\n * @interface ISecurePayload\n * @property {number|Long|null} [ts] SecurePayload ts\n * @property {Uint8Array|null} [data] SecurePayload data\n */\n\n /**\n * Constructs a new SecurePayload.\n * @memberof secure\n * @classdesc Represents a SecurePayload.\n * @implements ISecurePayload\n * @constructor\n * @param {secure.ISecurePayload=} [properties] Properties to set\n */\n function SecurePayload(properties) {\n if (properties)\n for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null)\n this[keys[i]] = properties[keys[i]];\n }\n\n /**\n * SecurePayload ts.\n * @member {number|Long} ts\n * @memberof secure.SecurePayload\n * @instance\n */\n SecurePayload.prototype.ts = $util.Long ? $util.Long.fromBits(0,0,false) : 0;\n\n /**\n * SecurePayload data.\n * @member {Uint8Array} data\n * @memberof secure.SecurePayload\n * @instance\n */\n SecurePayload.prototype.data = $util.newBuffer([]);\n\n /**\n * Creates a new SecurePayload instance using the specified properties.\n * @function create\n * @memberof secure.SecurePayload\n * @static\n * @param {secure.ISecurePayload=} [properties] Properties to set\n * @returns {secure.SecurePayload} SecurePayload instance\n */\n SecurePayload.create = function create(properties) {\n return new SecurePayload(properties);\n };\n\n /**\n * Encodes the specified SecurePayload message. Does not implicitly {@link secure.SecurePayload.verify|verify} messages.\n * @function encode\n * @memberof secure.SecurePayload\n * @static\n * @param {secure.ISecurePayload} message SecurePayload message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n SecurePayload.encode = function encode(message, writer) {\n if (!writer)\n writer = $Writer.create();\n if (message.ts != null && Object.hasOwnProperty.call(message, \"ts\"))\n writer.uint32(/* id 1, wireType 0 =*/8).int64(message.ts);\n if (message.data != null && Object.hasOwnProperty.call(message, \"data\"))\n writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.data);\n return writer;\n };\n\n /**\n * Encodes the specified SecurePayload message, length delimited. Does not implicitly {@link secure.SecurePayload.verify|verify} messages.\n * @function encodeDelimited\n * @memberof secure.SecurePayload\n * @static\n * @param {secure.ISecurePayload} message SecurePayload message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n SecurePayload.encodeDelimited = function encodeDelimited(message, writer) {\n return this.encode(message, writer).ldelim();\n };\n\n /**\n * Decodes a SecurePayload message from the specified reader or buffer.\n * @function decode\n * @memberof secure.SecurePayload\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {secure.SecurePayload} SecurePayload\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n SecurePayload.decode = function decode(reader, length, error) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n let end = length === undefined ? reader.len : reader.pos + length, message = new $root.secure.SecurePayload();\n while (reader.pos < end) {\n let tag = reader.uint32();\n if (tag === error)\n break;\n switch (tag >>> 3) {\n case 1: {\n message.ts = reader.int64();\n break;\n }\n case 2: {\n message.data = reader.bytes();\n break;\n }\n default:\n reader.skipType(tag & 7);\n break;\n }\n }\n return message;\n };\n\n /**\n * Decodes a SecurePayload message from the specified reader or buffer, length delimited.\n * @function decodeDelimited\n * @memberof secure.SecurePayload\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @returns {secure.SecurePayload} SecurePayload\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n SecurePayload.decodeDelimited = function decodeDelimited(reader) {\n if (!(reader instanceof $Reader))\n reader = new $Reader(reader);\n return this.decode(reader, reader.uint32());\n };\n\n /**\n * Verifies a SecurePayload message.\n * @function verify\n * @memberof secure.SecurePayload\n * @static\n * @param {Object.<string,*>} message Plain object to verify\n * @returns {string|null} `null` if valid, otherwise the reason why it is not\n */\n SecurePayload.verify = function verify(message) {\n if (typeof message !== \"object\" || message === null)\n return \"object expected\";\n if (message.ts != null && message.hasOwnProperty(\"ts\"))\n if (!$util.isInteger(message.ts) && !(message.ts && $util.isInteger(message.ts.low) && $util.isInteger(message.ts.high)))\n return \"ts: integer|Long expected\";\n if (message.data != null && message.hasOwnProperty(\"data\"))\n if (!(message.data && typeof message.data.length === \"number\" || $util.isString(message.data)))\n return \"data: buffer expected\";\n return null;\n };\n\n /**\n * Creates a SecurePayload message from a plain object. Also converts values to their respective internal types.\n * @function fromObject\n * @memberof secure.SecurePayload\n * @static\n * @param {Object.<string,*>} object Plain object\n * @returns {secure.SecurePayload} SecurePayload\n */\n SecurePayload.fromObject = function fromObject(object) {\n if (object instanceof $root.secure.SecurePayload)\n return object;\n let message = new $root.secure.SecurePayload();\n if (object.ts != null)\n if ($util.Long)\n (message.ts = $util.Long.fromValue(object.ts)).unsigned = false;\n else if (typeof object.ts === \"string\")\n message.ts = parseInt(object.ts, 10);\n else if (typeof object.ts === \"number\")\n message.ts = object.ts;\n else if (typeof object.ts === \"object\")\n message.ts = new $util.LongBits(object.ts.low >>> 0, object.ts.high >>> 0).toNumber();\n if (object.data != null)\n if (typeof object.data === \"string\")\n $util.base64.decode(object.data, message.data = $util.newBuffer($util.base64.length(object.data)), 0);\n else if (object.data.length >= 0)\n message.data = object.data;\n return message;\n };\n\n /**\n * Creates a plain object from a SecurePayload message. Also converts values to other types if specified.\n * @function toObject\n * @memberof secure.SecurePayload\n * @static\n * @param {secure.SecurePayload} message SecurePayload\n * @param {$protobuf.IConversionOptions} [options] Conversion options\n * @returns {Object.<string,*>} Plain object\n */\n SecurePayload.toObject = function toObject(message, options) {\n if (!options)\n options = {};\n let object = {};\n if (options.defaults) {\n if ($util.Long) {\n let long = new $util.Long(0, 0, false);\n object.ts = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;\n } else\n object.ts = options.longs === String ? \"0\" : 0;\n if (options.bytes === String)\n object.data = \"\";\n else {\n object.data = [];\n if (options.bytes !== Array)\n object.data = $util.newBuffer(object.data);\n }\n }\n if (message.ts != null && message.hasOwnProperty(\"ts\"))\n if (typeof message.ts === \"number\")\n object.ts = options.longs === String ? String(message.ts) : message.ts;\n else\n object.ts = options.longs === String ? $util.Long.prototype.toString.call(message.ts) : options.longs === Number ? new $util.LongBits(message.ts.low >>> 0, message.ts.high >>> 0).toNumber() : message.ts;\n if (message.data != null && message.hasOwnProperty(\"data\"))\n object.data = options.bytes === String ? $util.base64.encode(message.data, 0, message.data.length) : options.bytes === Array ? Array.prototype.slice.call(message.data) : message.data;\n return object;\n };\n\n /**\n * Converts this SecurePayload to JSON.\n * @function toJSON\n * @memberof secure.SecurePayload\n * @instance\n * @returns {Object.<string,*>} JSON object\n */\n SecurePayload.prototype.toJSON = function toJSON() {\n return this.constructor.toObject(this, $protobuf.util.toJSONOptions);\n };\n\n /**\n * Gets the default type url for SecurePayload\n * @function getTypeUrl\n * @memberof secure.SecurePayload\n * @static\n * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default \"type.googleapis.com\")\n * @returns {string} The default type url\n */\n SecurePayload.getTypeUrl = function getTypeUrl(typeUrlPrefix) {\n if (typeUrlPrefix === undefined) {\n typeUrlPrefix = \"type.googleapis.com\";\n }\n return typeUrlPrefix + \"/secure.SecurePayload\";\n };\n\n return SecurePayload;\n })();\n\n return secure;\n})();\n\nexport { $root as default };\n","/**\n * Protobuf 安全通信模块\n *\n * 提供基于 Protobuf 的二进制序列化、XOR 混淆加密以及与 API Client 的无缝集成。\n */\n\nimport protobuf from \"protobufjs/light\";\nimport { secure } from \"./secure.js\";\nimport type { FetchContext } from \"ofetch\";\n\n// ============================================================================\n// 1. 类型定义 (Types)\n// ============================================================================\n\n/**\n * 基础编解码配置\n * 控制如何将数据转换为二进制,以及是否混淆\n */\nexport interface ProtobufCodecOptions {\n /** 是否启用二进制 XOR 混淆 (默认 true) */\n obfuscate?: boolean;\n /**\n * 混淆密钥\n * 可以是静态字符串/字节数组,也可以是动态获取密钥的同步或异步函数\n */\n obfuscationKey?:\n | string\n | Uint8Array\n | (() => string | Uint8Array | Promise<string | Uint8Array>);\n /** 预编译的 Protobuf 类型对象 (推荐,性能最高) */\n protoType?: any;\n /** 数据转换钩子:处理业务模型与 Proto 结构不一致的情况 */\n transform?: {\n beforeEncode?: (data: any) => any;\n afterDecode?: (payload: any) => any;\n };\n}\n\n/**\n * 完全自定义编解码接口\n * 用于外部项目完全接管序列化过程,同时复用基础库的混淆外壳\n */\nexport interface ProtobufCustomCodec {\n /** 外部定义的编码逻辑 (返回原始二进制) */\n encode?: (data: any) => Uint8Array | Promise<Uint8Array>;\n /** 外部定义的解码逻辑 (返回原始对象) */\n decode?: <T>(buffer: Uint8Array) => T | Promise<T>;\n}\n\n/**\n * 集成配置项\n * 用于 createProtobufHooks 或 API Client 全局配置\n */\nexport interface ProtobufHooksOptions\n extends ProtobufCodecOptions, ProtobufCustomCodec {}\n\n/**\n * API Client 内部使用的标准化配置\n */\nexport interface ProtobufConfig {\n encode: (data: any) => Uint8Array | Promise<Uint8Array>;\n decode: <T>(buffer: Uint8Array) => T | Promise<T>;\n options?: ProtobufCodecOptions;\n}\n\n// ============================================================================\n// 2. 内部工具函数 (Internal Utilities)\n// ============================================================================\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/** 简单的二进制异或混淆转换 */\nexport function xorTransform(\n data: Uint8Array,\n key: string | Uint8Array,\n): Uint8Array {\n const keyBytes = typeof key === \"string\" ? encoder.encode(key) : key;\n if (keyBytes.length === 0) return data;\n\n for (let i = 0; i < data.length; i++) {\n data[i] ^= keyBytes[i % keyBytes.length];\n }\n return data;\n}\n\n/** 获取混淆密钥(支持异步/函数) */\nexport async function getObfuscationKey(\n keyOption?: ProtobufCodecOptions[\"obfuscationKey\"],\n): Promise<string | Uint8Array> {\n const defaultKey = \"api-client-default-key\";\n if (!keyOption) return defaultKey;\n if (typeof keyOption === \"function\") {\n return await keyOption();\n }\n return keyOption;\n}\n\n/** 获取内置的 SecurePayload 类型(使用预编译代码) */\nfunction getInternalSecureType(): protobuf.Type {\n return secure.SecurePayload as unknown as protobuf.Type;\n}\n\n// ============================================================================\n// 3. 核心编解码逻辑 (Core Codecs)\n// ============================================================================\n\n/**\n * 编码安全载荷\n *\n * 流程:业务数据 -> (自定义编码 / Proto 序列化) -> 二进制混淆\n */\nexport async function encodeSecure<T>(\n data: T,\n options: ProtobufHooksOptions = {},\n): Promise<Uint8Array> {\n const {\n obfuscate = true,\n obfuscationKey,\n protoType,\n transform,\n encode: customEncode,\n } = options;\n\n let buffer: Uint8Array;\n\n // 1. 预处理阶段:无论后续走哪条路径,只要定义了 beforeEncode 就先执行\n const processedData = transform?.beforeEncode\n ? transform.beforeEncode(data)\n : data;\n\n // 1. 序列化阶段\n if (customEncode) {\n buffer = await customEncode(data);\n } else {\n const type = protoType || getInternalSecureType();\n\n // 构造最终要交给 Protobuf 序列化的对象\n const payload = protoType\n ? processedData // 自定义模式:直接使用预处理后的数据\n : {\n // 默认容器模式:将预处理后的数据封装进信封\n ts: Date.now(),\n data:\n processedData instanceof Uint8Array\n ? processedData\n : encoder.encode(JSON.stringify(processedData)),\n };\n\n const message = type.create(payload);\n buffer = type.encode(message).finish();\n }\n\n // 2. 混淆阶段\n if (!obfuscate) return buffer;\n const finalKey = await getObfuscationKey(obfuscationKey);\n return xorTransform(buffer, finalKey);\n}\n\n/**\n * 解码安全载荷\n *\n * 流程:二进制流 -> 二进制反混淆 -> (自定义解码 / Proto 反序列化) -> 业务数据\n */\nexport async function decodeSecure<T>(\n buffer: Uint8Array | ArrayBuffer,\n options: ProtobufHooksOptions = {},\n): Promise<T> {\n const {\n obfuscate = true,\n obfuscationKey,\n protoType,\n transform,\n decode: customDecode,\n } = options;\n\n // let uint8 = buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : buffer;\n let uint8 =\n buffer instanceof ArrayBuffer\n ? new Uint8Array(buffer)\n : new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n\n // 1. 反混淆阶段\n if (uint8.length > 0 && obfuscate) {\n const finalKey = await getObfuscationKey(obfuscationKey);\n uint8 = xorTransform(uint8, finalKey);\n }\n\n // 2. 反序列化阶段\n if (customDecode) {\n return await customDecode<T>(uint8);\n }\n\n const type = protoType || getInternalSecureType();\n const decoded = type.decode(uint8);\n const plainObj = type.toObject(decoded, {\n longs: String,\n enums: String,\n bytes: Uint8Array as any,\n defaults: true,\n });\n\n // 3. 转换阶段\n if (transform?.afterDecode) {\n return transform.afterDecode(plainObj);\n }\n\n // 内置容器模式的额外还原逻辑\n if (!protoType && plainObj.data) {\n const jsonString = decoder.decode(plainObj.data as Uint8Array);\n try {\n return JSON.parse(jsonString) as T;\n } catch {\n return jsonString as unknown as T;\n }\n }\n\n return plainObj as T;\n}\n\n// ============================================================================\n// 4. HTTP/环境适配工具 (HTTP Tools)\n// ============================================================================\n\n/** 创建安全响应 (Worker/Server 端使用) */\nexport async function secureResponse<T>(\n data: T,\n options?: ProtobufCodecOptions & { corsHeaders?: Record<string, string> },\n): Promise<Response> {\n const buffer = await encodeSecure(data, options);\n const arrayBuffer = buffer.buffer.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength,\n ) as ArrayBuffer;\n\n return new Response(arrayBuffer, {\n headers: {\n \"Content-Type\": \"application/x-protobuf\",\n ...options?.corsHeaders,\n },\n });\n}\n\n/** 解析安全请求体 (Worker/Server 端使用) */\nexport async function parseSecureRequest<T>(\n request: Request,\n customDecode?: ProtobufCustomCodec[\"decode\"],\n): Promise<T> {\n const buffer = await request.arrayBuffer();\n return decodeSecure<T>(buffer, { decode: customDecode });\n}\n\n/** 检查是否为 Protobuf 响应头 */\nexport function isProtobufContentType(contentType: string | null): boolean {\n return !!contentType?.includes(\"application/x-protobuf\");\n}\n\n/** 标准化配置对象 */\nexport function normalizeProtobufConfig(\n config: boolean | ProtobufConfig | undefined,\n options?: ProtobufHooksOptions, // 接收全局配置\n): ProtobufConfig | null {\n if (!config) return null;\n if (config === true) {\n return {\n encode: (data) => encodeSecure(data, options),\n decode: <T>(buffer: Uint8Array) => decodeSecure<T>(buffer, options),\n };\n }\n return config;\n}\n\n// ============================================================================\n// 5. API Client 钩子逻辑 (Integration Hooks)\n// ============================================================================\n\n/** 创建 Protobuf 编解码钩子 (用于与 createApiClient 配合使用) */\nexport function createProtobufHooks(options: ProtobufHooksOptions = {}) {\n const encode = (data: any) => encodeSecure(data, options);\n const decode = <T>(buffer: Uint8Array) => decodeSecure<T>(buffer, options);\n\n return {\n async onRequest(context: FetchContext) {\n const { options: reqOptions } = context;\n const headers =\n reqOptions.headers instanceof Headers\n ? reqOptions.headers\n : new Headers(reqOptions.headers as HeadersInit | undefined);\n\n // 自动编码请求体\n if (\n isProtobufContentType(headers.get(\"Content-Type\")) &&\n reqOptions.body &&\n !(reqOptions.body instanceof Uint8Array)\n ) {\n reqOptions.body = await encode(reqOptions.body);\n }\n\n // 自动设置期望响应类型\n if (\n isProtobufContentType(headers.get(\"Accept\")) &&\n !reqOptions.responseType\n ) {\n reqOptions.responseType = \"arrayBuffer\";\n }\n\n reqOptions.headers = headers;\n },\n\n async onResponse(context: FetchContext) {\n const { response } = context;\n if (!response?._data) return;\n\n if (isProtobufContentType(response.headers.get(\"Content-Type\"))) {\n const buffer = response._data as ArrayBuffer;\n if (buffer && buffer.byteLength > 0) {\n response._data = await decode(new Uint8Array(buffer));\n }\n } else if (response._data instanceof ArrayBuffer) {\n const text = decoder.decode(response._data);\n try {\n response._data = JSON.parse(text);\n } catch {\n response._data = text;\n }\n }\n },\n };\n}\n"],"mappings":"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","names":["options","secure"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/client.ts","../src/chain.ts","../src/secure.js","../src/protobuf.ts"],"sourcesContent":["export * from \"./client\";\nexport * from \"./chain\";\nexport * from \"./protobuf\";\n","import {\n ofetch,\n type FetchOptions,\n type FetchContext,\n type $Fetch,\n} from \"ofetch\";\n\nexport interface ApiResult<T> {\n code: number;\n data: T;\n message: string;\n}\n\nexport interface ApiError extends Error {\n code: number; // 业务错误码\n data?: unknown; // 后端返回的 data 字段(如果有)\n status?: number; // HTTP 状态码(网络错误时)\n}\n\n// 类型守卫:判断是否是 API 业务错误\nexport const isApiError = (error: unknown): error is ApiError => {\n return error instanceof Error && \"code\" in error;\n};\n\nexport interface TokenStorage {\n getAccessToken: () => Promise<string> | string;\n setAccessToken: (token: string) => Promise<void> | void;\n}\n\nexport interface CreateApiClientOptions {\n baseURL: string;\n tokenStorage: TokenStorage;\n refreshToken?: (() => Promise<string>) | string | false;\n retry?: number; // 重试次数,默认 1\n retryDelay?: number; // 重试间隔,默认 1s\n isAuthError?: (code: number) => boolean;\n unwrapResponse?<T>(result: unknown, returnFullResponse: boolean): T;\n createErrorFromResult?(res: unknown): Error;\n /**\n * 自定义请求钩子\n * 在请求发送前执行,可用于编码请求体等\n */\n onRequest?: (context: FetchContext) => void | Promise<void>;\n /**\n * 自定义响应钩子\n * 在响应返回后执行,可用于解码响应体等\n */\n onResponse?: (context: FetchContext) => void | Promise<void>;\n}\n\ntype RequestOptions = Omit<FetchOptions<\"json\">, \"responseType\"> & {\n returnFullResponse?: boolean;\n responseType?: \"json\" | \"arrayBuffer\" | \"text\" | \"blob\";\n};\n\n// 解包后端统一响应格式(默认实现)\nconst defaultUnwrapResponse = <T>(\n result: unknown,\n returnFullResponse = false,\n): T => {\n if (result && typeof result === \"object\" && \"code\" in result) {\n const body = result as Record<string, unknown>;\n if (body.code === 0) {\n return returnFullResponse ? (body as T) : (body.data as T);\n }\n }\n return result as T;\n};\n\nconst defaultCreateErrorFromResult = (res: ApiResult<unknown>): ApiError => {\n const error = new Error(res.message || \"Request failed\") as ApiError;\n error.code = res.code;\n error.data = res.data;\n return error;\n};\n\nconst extractAccessToken = (data: unknown): string => {\n if (typeof data === \"string\" && data) {\n return data;\n }\n\n if (!data || typeof data !== \"object\") {\n throw new Error(\n \"Invalid refresh token response: data is not an object or string\",\n );\n }\n\n const anyData = data as Record<string, unknown>;\n\n const accessToken =\n anyData.access_token ?? anyData.accessToken ?? anyData.token;\n\n if (typeof accessToken === \"string\" && accessToken) {\n return accessToken;\n }\n\n throw new Error(\n \"Invalid refresh token response: no access_token or token field found\",\n );\n};\n\n// 全局共享的刷新状态,以 tokenStorage 为 Key\n// 这样即使有多个 ApiClient 实例,只要它们共用同一个 tokenStorage,刷新逻辑就是单例的\nconst refreshingPromises = new WeakMap<TokenStorage, Promise<string>>();\n\nexport function createApiClient(options: CreateApiClientOptions) {\n const {\n baseURL,\n tokenStorage,\n refreshToken = false,\n retry = 1,\n retryDelay = 1000,\n isAuthError = (code: number) => code === 401,\n unwrapResponse = defaultUnwrapResponse,\n createErrorFromResult = defaultCreateErrorFromResult,\n } = options;\n\n const refreshTokenFn: (() => Promise<string>) | null = !refreshToken\n ? null\n : typeof refreshToken === \"string\"\n ? async () => {\n const res = await ofetch<ApiResult<unknown>>(refreshToken, {\n baseURL,\n method: \"POST\",\n retry,\n retryDelay,\n });\n\n if (res.code !== 0) {\n throw createErrorFromResult(res as ApiResult<unknown>);\n }\n\n return extractAccessToken(res.data);\n }\n : refreshToken;\n\n const rawRequest = ofetch.create({\n baseURL,\n retry,\n retryDelay,\n\n async onRequest(context: FetchContext) {\n const { options: reqOptions } = context;\n const token = await tokenStorage.getAccessToken();\n\n const headers = new Headers(\n reqOptions.headers as HeadersInit | undefined,\n );\n\n if (token) {\n headers.set(\"Authorization\", `Bearer ${token}`);\n }\n\n reqOptions.headers = headers;\n\n // 执行用户自定义钩子\n if (options.onRequest) {\n await options.onRequest(context);\n }\n },\n async onResponse(context) {\n const { response } = context;\n // 不在这里处理 code,统一交给 fetchApi 层处理\n if (response.status === 204) {\n response._data = null;\n return;\n }\n\n // 执行用户自定义钩子\n if (options.onResponse) {\n await options.onResponse(context);\n }\n },\n\n async onResponseError(context: FetchContext) {\n // 后端统一返回 HTTP 200,此处只处理网络层错误(如超时、断网)\n const { response } = context;\n const message =\n (response?._data as Record<string, unknown>)?.message ||\n `HTTP ${response?.status || \"Network Error\"}`;\n\n const error = new Error(message as string) as ApiError;\n error.status = response?.status;\n error.data = response?._data;\n throw error;\n },\n }) as $Fetch;\n\n async function request<T = unknown>(\n url: string,\n options: RequestOptions & { _retry?: boolean } = {},\n ): Promise<T> {\n // 提取自定义选项,避免传递给 $fetch\n const { returnFullResponse, _retry, ...fetchOptions } = options;\n\n // const res = await rawRequest<ApiResult<T>>(url, fetchOptions);\n const res = (await rawRequest(url, fetchOptions as FetchOptions)) as ApiResult<T>;\n\n if (res.code === 0) {\n return unwrapResponse<T>(res, !!returnFullResponse);\n // if (returnFullResponse) {\n // return res as unknown as T;\n // }\n\n // return res.data;\n }\n\n if (isAuthError(res.code) && !_retry && refreshTokenFn) {\n try {\n let refreshingPromise = refreshingPromises.get(tokenStorage);\n\n if (!refreshingPromise) {\n refreshingPromise = refreshTokenFn().finally(() => {\n refreshingPromises.delete(tokenStorage);\n });\n refreshingPromises.set(tokenStorage, refreshingPromise);\n }\n\n const newToken = await refreshingPromise;\n\n if (newToken) {\n await tokenStorage.setAccessToken(newToken);\n }\n\n return await request<T>(url, {\n ...(options || {}),\n _retry: true,\n } as any);\n } catch (e) {\n await tokenStorage.setAccessToken(\"\");\n throw createErrorFromResult(res as ApiResult<unknown>);\n }\n }\n\n throw createErrorFromResult(res as ApiResult<unknown>);\n }\n\n async function get<T = unknown>(\n url: string,\n params: FetchOptions[\"query\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"GET\",\n query: params,\n } as any);\n }\n\n async function post<T = unknown>(\n url: string,\n body: FetchOptions[\"body\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"POST\",\n body,\n } as any);\n }\n\n async function put<T = unknown>(\n url: string,\n body: FetchOptions[\"body\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"PUT\",\n body,\n } as any);\n }\n\n async function patch<T = unknown>(\n url: string,\n body: FetchOptions[\"body\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"PATCH\",\n body,\n } as any);\n }\n\n async function del<T = unknown>(\n url: string,\n params: FetchOptions[\"query\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"DELETE\",\n query: params,\n } as any);\n }\n\n return {\n rawRequest,\n request,\n get,\n post,\n put,\n patch,\n del,\n };\n}\n","/**\n * Request Chain Runner\n * 负责解析和执行通用的 HTTP 请求链 (Chain Execution)\n * 适用于任何需要链式 HTTP 请求编排的场景\n */\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/** Supported HTTP Methods */\ntype HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n\n/** HTTP 请求参数 */\nexport interface HttpRequestSpec {\n method: HttpMethod;\n url: string;\n headers?: Record<string, string>;\n body?: any;\n}\n\n/**\n * 网络适配器接口\n * 定义实际发送请求的能力\n */\n/**\n * 网络适配器接口\n * 定义实际发送请求的能力\n */\nexport interface NetworkAdapter {\n get<T>(\n url: string,\n params?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n post<T>(\n url: string,\n body?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n put?<T>(\n url: string,\n body?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n delete?<T>(\n url: string,\n params?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n patch?<T>(\n url: string,\n body?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n}\n\n/**\n * 网络处理器接口 (Strategy Pattern)\n * 组合了\"匹配规则\"和\"执行能力\"\n */\nexport interface NetworkHandler {\n /** 处理器名称 (用于调试) */\n name?: string;\n\n /** 判断该 URL 是否由此适配器处理 */\n shouldHandle(url: string, method: HttpMethod): boolean;\n\n /** 具体的网络适配器 */\n adapter: NetworkAdapter;\n}\n\n/**\n * 请求链规则 (Chain Step)\n */\nexport interface ChainRequestRule {\n /**\n * 结果存储的键名 (Context Key)\n * Fetch 结果存储: context[key] = response\n */\n key?: string;\n\n /**\n * HTTP 请求详情\n */\n request: HttpRequestSpec;\n\n /**\n * 数据提取选择器\n * 用于从响应中提取特定数据, e.g., \"elements.0\"\n */\n selector?: string;\n\n /** 是否允许请求失败 (默认 false) */\n optional?: boolean;\n\n /**\n * 是否包含上下文\n * 如果为 true,请求 Body 将自动合并当前 Context 和 Payload\n */\n includeContext?: boolean;\n\n /**\n * 上下文筛选列表 (优先级高于 includeContext)\n * 指定需要合并到 Body 中的 Context Key 列表\n * e.g., [\"rawProfile\", \"rawCompany\"]\n */\n pickContext?: string[];\n\n /** 额外 Payload (仅当 includeContext 为 true 或 pickContext 存在时合并) */\n payload?: Record<string, any>;\n}\n\n// ============================================================================\n// Internal Utilities\n// ============================================================================\n\n/**\n * 执行 HTTP 请求\n * 遍历 handlers 数组,找到第一个能处理该 URL 的适配器执行\n *\n * @param spec 请求详情\n * @param handlers 网络处理器链\n */\nasync function executeChainRequest<T>(\n spec: HttpRequestSpec,\n handlers: NetworkHandler[] = []\n): Promise<T | null> {\n // Normalize method to upper case for robustness\n const method = spec.method.toUpperCase() as HttpMethod;\n\n // 1. 遍历处理器数组 (责任链)\n for (const handler of handlers) {\n if (handler.shouldHandle(spec.url, method)) {\n try {\n const { adapter } = handler;\n const headers = spec.headers;\n\n switch (method) {\n case \"GET\":\n return await adapter.get<T>(spec.url, spec.body, headers);\n case \"POST\":\n return await adapter.post<T>(spec.url, spec.body, headers);\n case \"PUT\":\n if (!adapter.put)\n throw new Error(`Adapter ${handler.name} missing PUT method`);\n return await adapter.put<T>(spec.url, spec.body, headers);\n case \"DELETE\":\n if (!adapter.delete)\n throw new Error(`Adapter ${handler.name} missing DELETE method`);\n return await adapter.delete<T>(spec.url, spec.body, headers);\n case \"PATCH\":\n if (!adapter.patch)\n throw new Error(`Adapter ${handler.name} missing PATCH method`);\n return await adapter.patch<T>(spec.url, spec.body, headers);\n default:\n throw new Error(`Unsupported method: ${method}`);\n }\n } catch (err) {\n console.warn(\n `Handler [${handler.name || \"Anonymous\"}] failed for ${spec.url}`,\n err\n );\n // 如果需要继续尝试下一个 handler,可以在这里 continue,但通常由第一个匹配者全权负责\n return null;\n }\n }\n }\n\n // 2. 默认行为 (Fallback): 绝对路径自动走标准 fetch\n if (spec.url.startsWith(\"http://\") || spec.url.startsWith(\"https://\")) {\n return await executeFallbackFetch<T>(spec);\n }\n\n console.warn(`No handler found for url: ${spec.url}`);\n return null;\n}\n\n/**\n * 标准 Fetch 回退实现\n */\nasync function executeFallbackFetch<T>(\n spec: HttpRequestSpec\n): Promise<T | null> {\n try {\n const response = await fetch(spec.url, {\n method: spec.method,\n headers: spec.headers,\n body: spec.body ? JSON.stringify(spec.body) : undefined,\n credentials: \"include\",\n });\n\n if (!response.ok) {\n console.log(`External Request failed: ${response.status} ${spec.url}`);\n return null;\n }\n\n return await response.json();\n } catch (err) {\n console.log(\"External Request error:\", err);\n return null;\n }\n}\n\n/**\n * 根据路径获取对象值\n */\nfunction getByPath(obj: any, path: string): any {\n if (!path) return obj;\n return path.split(\".\").reduce((acc, part) => acc && acc[part], obj);\n}\n\n/**\n * 变量替换 (Internal)\n * 支持字符串 {{key}} 和 {{key.prop}}\n */\nfunction substituteVariables(target: any, context: any): any {\n if (typeof target === \"string\") {\n return target.replace(/\\{\\{([\\w\\.]+)\\}\\}/g, (_, path) => {\n const val = getByPath(context, path);\n return val !== undefined ? String(val) : \"\";\n });\n }\n\n if (Array.isArray(target)) {\n return target.map((item) => substituteVariables(item, context));\n }\n\n if (target && typeof target === \"object\") {\n const result: any = {};\n for (const key in target) {\n result[key] = substituteVariables(target[key], context);\n }\n return result;\n }\n\n return target;\n}\n\n// ============================================================================\n// Main Runner\n// ============================================================================\n\n/**\n * 请求链执行器 (Request Chain Engine)\n * 支持链式请求、上下文累积、智能路由、变量替换\n *\n * @param requests 链式执行规则列表\n * @param handlers 网络适配器处理器列表 (按顺序匹配)\n */\nexport async function executeRequestChain<T>(\n requests: ChainRequestRule[],\n handlers: NetworkHandler[] = [],\n getChainRequests?: (\n context: Record<string, any>\n ) => ChainRequestRule[] | null | undefined,\n initContext?: Record<string, any>\n): Promise<T> {\n const context: Record<string, any> = initContext || {};\n let lastResult: any = null;\n\n for (const rule of requests) {\n try {\n // 1. 准备 Context Data (用于 Submit)\n let contextData: Record<string, any> = {};\n if (rule.pickContext) {\n rule.pickContext.forEach((key) => {\n if (key in context) contextData[key] = context[key];\n });\n } else if (rule.includeContext) {\n contextData = context;\n }\n const hasContextData = Object.keys(contextData).length > 0;\n\n // 2. 准备 Request Spec (合并 Payload 和 Context)\n let requestSpec = { ...rule.request };\n if (hasContextData || rule.payload) {\n requestSpec.body = {\n ...(rule.payload || {}),\n ...contextData,\n ...(requestSpec.body || {}),\n };\n }\n\n // 3. 变量替换\n requestSpec = substituteVariables(requestSpec, context);\n\n // 4. 执行请求 (传入 handlers)\n let rawData = await executeChainRequest<any>(requestSpec, handlers);\n\n if (getChainRequests) {\n const chainRequests = getChainRequests(rawData);\n if (chainRequests && chainRequests.length > 0) {\n rawData = await executeRequestChain(\n chainRequests,\n handlers,\n getChainRequests,\n JSON.parse(JSON.stringify(context))\n );\n }\n }\n\n lastResult = rawData;\n\n if (rawData) {\n // 5. 存储结果\n if (rule.key) {\n const data = rule.selector\n ? getByPath(rawData, rule.selector)\n : rawData;\n context[rule.key] = data;\n }\n } else if (!rule.optional) {\n throw new Error(\n `Failed to fetch required data for key: ${rule.key || \"unknown\"}`\n );\n }\n } catch (err) {\n if (!rule.optional) {\n throw err;\n }\n console.warn(`Optional request failed for rule:`, rule, err);\n }\n }\n\n return lastResult as T;\n}\n","/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/\nimport * as $protobuf from \"protobufjs/minimal\";\n\n// Common aliases\nconst $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;\n\n// Exported root namespace\nconst $root = $protobuf.roots[\"default\"] || ($protobuf.roots[\"default\"] = {});\n\nexport const secure = $root.secure = (() => {\n\n /**\n * Namespace secure.\n * @exports secure\n * @namespace\n */\n const secure = {};\n\n secure.SecurePayload = (function() {\n\n /**\n * Properties of a SecurePayload.\n * @memberof secure\n * @interface ISecurePayload\n * @property {number|Long|null} [ts] SecurePayload ts\n * @property {Uint8Array|null} [data] SecurePayload data\n */\n\n /**\n * Constructs a new SecurePayload.\n * @memberof secure\n * @classdesc Represents a SecurePayload.\n * @implements ISecurePayload\n * @constructor\n * @param {secure.ISecurePayload=} [properties] Properties to set\n */\n function SecurePayload(properties) {\n if (properties)\n for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null)\n this[keys[i]] = properties[keys[i]];\n }\n\n /**\n * SecurePayload ts.\n * @member {number|Long} ts\n * @memberof secure.SecurePayload\n * @instance\n */\n SecurePayload.prototype.ts = $util.Long ? $util.Long.fromBits(0,0,false) : 0;\n\n /**\n * SecurePayload data.\n * @member {Uint8Array} data\n * @memberof secure.SecurePayload\n * @instance\n */\n SecurePayload.prototype.data = $util.newBuffer([]);\n\n /**\n * Creates a new SecurePayload instance using the specified properties.\n * @function create\n * @memberof secure.SecurePayload\n * @static\n * @param {secure.ISecurePayload=} [properties] Properties to set\n * @returns {secure.SecurePayload} SecurePayload instance\n */\n SecurePayload.create = function create(properties) {\n return new SecurePayload(properties);\n };\n\n /**\n * Encodes the specified SecurePayload message. Does not implicitly {@link secure.SecurePayload.verify|verify} messages.\n * @function encode\n * @memberof secure.SecurePayload\n * @static\n * @param {secure.ISecurePayload} message SecurePayload message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n SecurePayload.encode = function encode(message, writer) {\n if (!writer)\n writer = $Writer.create();\n if (message.ts != null && Object.hasOwnProperty.call(message, \"ts\"))\n writer.uint32(/* id 1, wireType 0 =*/8).int64(message.ts);\n if (message.data != null && Object.hasOwnProperty.call(message, \"data\"))\n writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.data);\n return writer;\n };\n\n /**\n * Encodes the specified SecurePayload message, length delimited. Does not implicitly {@link secure.SecurePayload.verify|verify} messages.\n * @function encodeDelimited\n * @memberof secure.SecurePayload\n * @static\n * @param {secure.ISecurePayload} message SecurePayload message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n SecurePayload.encodeDelimited = function encodeDelimited(message, writer) {\n return this.encode(message, writer).ldelim();\n };\n\n /**\n * Decodes a SecurePayload message from the specified reader or buffer.\n * @function decode\n * @memberof secure.SecurePayload\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {secure.SecurePayload} SecurePayload\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n SecurePayload.decode = function decode(reader, length, error) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n let end = length === undefined ? reader.len : reader.pos + length, message = new $root.secure.SecurePayload();\n while (reader.pos < end) {\n let tag = reader.uint32();\n if (tag === error)\n break;\n switch (tag >>> 3) {\n case 1: {\n message.ts = reader.int64();\n break;\n }\n case 2: {\n message.data = reader.bytes();\n break;\n }\n default:\n reader.skipType(tag & 7);\n break;\n }\n }\n return message;\n };\n\n /**\n * Decodes a SecurePayload message from the specified reader or buffer, length delimited.\n * @function decodeDelimited\n * @memberof secure.SecurePayload\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @returns {secure.SecurePayload} SecurePayload\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n SecurePayload.decodeDelimited = function decodeDelimited(reader) {\n if (!(reader instanceof $Reader))\n reader = new $Reader(reader);\n return this.decode(reader, reader.uint32());\n };\n\n /**\n * Verifies a SecurePayload message.\n * @function verify\n * @memberof secure.SecurePayload\n * @static\n * @param {Object.<string,*>} message Plain object to verify\n * @returns {string|null} `null` if valid, otherwise the reason why it is not\n */\n SecurePayload.verify = function verify(message) {\n if (typeof message !== \"object\" || message === null)\n return \"object expected\";\n if (message.ts != null && message.hasOwnProperty(\"ts\"))\n if (!$util.isInteger(message.ts) && !(message.ts && $util.isInteger(message.ts.low) && $util.isInteger(message.ts.high)))\n return \"ts: integer|Long expected\";\n if (message.data != null && message.hasOwnProperty(\"data\"))\n if (!(message.data && typeof message.data.length === \"number\" || $util.isString(message.data)))\n return \"data: buffer expected\";\n return null;\n };\n\n /**\n * Creates a SecurePayload message from a plain object. Also converts values to their respective internal types.\n * @function fromObject\n * @memberof secure.SecurePayload\n * @static\n * @param {Object.<string,*>} object Plain object\n * @returns {secure.SecurePayload} SecurePayload\n */\n SecurePayload.fromObject = function fromObject(object) {\n if (object instanceof $root.secure.SecurePayload)\n return object;\n let message = new $root.secure.SecurePayload();\n if (object.ts != null)\n if ($util.Long)\n (message.ts = $util.Long.fromValue(object.ts)).unsigned = false;\n else if (typeof object.ts === \"string\")\n message.ts = parseInt(object.ts, 10);\n else if (typeof object.ts === \"number\")\n message.ts = object.ts;\n else if (typeof object.ts === \"object\")\n message.ts = new $util.LongBits(object.ts.low >>> 0, object.ts.high >>> 0).toNumber();\n if (object.data != null)\n if (typeof object.data === \"string\")\n $util.base64.decode(object.data, message.data = $util.newBuffer($util.base64.length(object.data)), 0);\n else if (object.data.length >= 0)\n message.data = object.data;\n return message;\n };\n\n /**\n * Creates a plain object from a SecurePayload message. Also converts values to other types if specified.\n * @function toObject\n * @memberof secure.SecurePayload\n * @static\n * @param {secure.SecurePayload} message SecurePayload\n * @param {$protobuf.IConversionOptions} [options] Conversion options\n * @returns {Object.<string,*>} Plain object\n */\n SecurePayload.toObject = function toObject(message, options) {\n if (!options)\n options = {};\n let object = {};\n if (options.defaults) {\n if ($util.Long) {\n let long = new $util.Long(0, 0, false);\n object.ts = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;\n } else\n object.ts = options.longs === String ? \"0\" : 0;\n if (options.bytes === String)\n object.data = \"\";\n else {\n object.data = [];\n if (options.bytes !== Array)\n object.data = $util.newBuffer(object.data);\n }\n }\n if (message.ts != null && message.hasOwnProperty(\"ts\"))\n if (typeof message.ts === \"number\")\n object.ts = options.longs === String ? String(message.ts) : message.ts;\n else\n object.ts = options.longs === String ? $util.Long.prototype.toString.call(message.ts) : options.longs === Number ? new $util.LongBits(message.ts.low >>> 0, message.ts.high >>> 0).toNumber() : message.ts;\n if (message.data != null && message.hasOwnProperty(\"data\"))\n object.data = options.bytes === String ? $util.base64.encode(message.data, 0, message.data.length) : options.bytes === Array ? Array.prototype.slice.call(message.data) : message.data;\n return object;\n };\n\n /**\n * Converts this SecurePayload to JSON.\n * @function toJSON\n * @memberof secure.SecurePayload\n * @instance\n * @returns {Object.<string,*>} JSON object\n */\n SecurePayload.prototype.toJSON = function toJSON() {\n return this.constructor.toObject(this, $protobuf.util.toJSONOptions);\n };\n\n /**\n * Gets the default type url for SecurePayload\n * @function getTypeUrl\n * @memberof secure.SecurePayload\n * @static\n * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default \"type.googleapis.com\")\n * @returns {string} The default type url\n */\n SecurePayload.getTypeUrl = function getTypeUrl(typeUrlPrefix) {\n if (typeUrlPrefix === undefined) {\n typeUrlPrefix = \"type.googleapis.com\";\n }\n return typeUrlPrefix + \"/secure.SecurePayload\";\n };\n\n return SecurePayload;\n })();\n\n return secure;\n})();\n\nexport { $root as default };\n","/**\n * Protobuf 安全通信模块\n *\n * 提供基于 Protobuf 的二进制序列化、XOR 混淆加密以及与 API Client 的无缝集成。\n */\n\nimport protobuf from \"protobufjs/light\";\nimport { secure } from \"./secure.js\";\nimport type { FetchContext } from \"ofetch\";\n\n// ============================================================================\n// 1. 类型定义 (Types)\n// ============================================================================\n// export type ProtobufTypeLike = Pick<protobuf.Type, \"create\" | \"encode\" | \"decode\" | \"toObject\">;\nexport interface ProtobufTypeLike {\n // 1. 允许 properties 为任何对象,返回结果不再强制要求 $type\n create(properties?: Record<string, any>): any;\n // 2. 借用原生的参数类型约束,但手动简化返回类型\n encode(message: any): { finish(): Uint8Array };\n // 3. 借用原生的 decode 签名(支持 Uint8Array 和 Reader)\n decode(reader: Uint8Array | protobuf.Reader): any;\n // 4. 借用原生的 toObject 签名,保留 IConversionOptions 的类型检查\n toObject(message: any, options?: protobuf.IConversionOptions): any;\n}\n/**\n * 基础编解码配置\n * 控制如何将数据转换为二进制,以及是否混淆\n */\nexport interface ProtobufCodecOptions {\n /** 是否启用二进制 XOR 混淆 (默认 true) */\n obfuscate?: boolean;\n /**\n * 混淆密钥\n * 可以是静态字符串/字节数组,也可以是动态获取密钥的同步或异步函数\n */\n obfuscationKey?:\n | string\n | Uint8Array\n | (() => string | Uint8Array | Promise<string | Uint8Array>);\n /** 预编译的 Protobuf 类型对象 (推荐,性能最高) */\n protoType?: ProtobufTypeLike;\n /** 数据转换钩子:处理业务模型与 Proto 结构不一致的情况 */\n transform?: {\n beforeEncode?: (data: any) => any;\n afterDecode?: (payload: any) => any;\n };\n}\n\n/**\n * 完全自定义编解码接口\n * 用于外部项目完全接管序列化过程,同时复用基础库的混淆外壳\n */\nexport interface ProtobufCustomCodec {\n /** 外部定义的编码逻辑 (返回原始二进制) */\n encode?: (data: any) => Uint8Array | Promise<Uint8Array>;\n /** 外部定义的解码逻辑 (返回原始对象) */\n decode?: <T>(buffer: Uint8Array) => T | Promise<T>;\n}\n\n/**\n * 集成配置项\n * 用于 createProtobufHooks 或 API Client 全局配置\n */\nexport interface ProtobufHooksOptions\n extends ProtobufCodecOptions, ProtobufCustomCodec {}\n\n/**\n * API Client 内部使用的标准化配置\n */\nexport interface ProtobufConfig {\n encode: (data: any) => Uint8Array | Promise<Uint8Array>;\n decode: <T>(buffer: Uint8Array) => T | Promise<T>;\n options?: ProtobufCodecOptions;\n}\n\n// ============================================================================\n// 2. 内部工具函数 (Internal Utilities)\n// ============================================================================\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/** 简单的二进制异或混淆转换 */\nexport function xorTransform(\n data: Uint8Array,\n key: string | Uint8Array,\n): Uint8Array {\n const keyBytes = typeof key === \"string\" ? encoder.encode(key) : key;\n if (keyBytes.length === 0) return data;\n\n for (let i = 0; i < data.length; i++) {\n data[i] ^= keyBytes[i % keyBytes.length];\n }\n return data;\n}\n\n/** 获取混淆密钥(支持异步/函数) */\nexport async function getObfuscationKey(\n keyOption?: ProtobufCodecOptions[\"obfuscationKey\"],\n): Promise<string | Uint8Array> {\n const defaultKey = \"api-client-default-key\";\n if (!keyOption) return defaultKey;\n if (typeof keyOption === \"function\") {\n return await keyOption();\n }\n return keyOption;\n}\n\n/** 获取内置的 SecurePayload 类型(使用预编译代码) */\nfunction getInternalSecureType(): protobuf.Type {\n return secure.SecurePayload as unknown as protobuf.Type;\n}\n\n// ============================================================================\n// 3. 核心编解码逻辑 (Core Codecs)\n// ============================================================================\n\n/**\n * 编码安全载荷\n *\n * 流程:业务数据 -> (自定义编码 / Proto 序列化) -> 二进制混淆\n */\nexport async function encodeSecure<T>(\n data: T,\n options: ProtobufHooksOptions = {},\n): Promise<Uint8Array> {\n const {\n obfuscate = true,\n obfuscationKey,\n protoType,\n transform,\n encode: customEncode,\n } = options;\n\n let buffer: Uint8Array;\n\n // 1. 预处理阶段:无论后续走哪条路径,只要定义了 beforeEncode 就先执行\n const processedData = transform?.beforeEncode\n ? transform.beforeEncode(data)\n : data;\n\n // 1. 序列化阶段\n if (customEncode) {\n buffer = await customEncode(processedData);\n } else {\n const type = protoType || getInternalSecureType();\n\n // 构造最终要交给 Protobuf 序列化的对象\n const payload = protoType\n ? processedData // 自定义模式:直接使用预处理后的数据\n : {\n // 默认容器模式:将预处理后的数据封装进信封\n ts: Date.now(),\n data:\n processedData instanceof Uint8Array\n ? processedData\n : encoder.encode(JSON.stringify(processedData)),\n };\n\n const message = type.create(payload);\n buffer = type.encode(message).finish();\n }\n\n // 2. 混淆阶段\n if (!obfuscate) return buffer;\n const finalKey = await getObfuscationKey(obfuscationKey);\n return xorTransform(buffer, finalKey);\n}\n\n/**\n * 解码安全载荷\n *\n * 流程:二进制流 -> 二进制反混淆 -> (自定义解码 / Proto 反序列化) -> 业务数据\n */\nexport async function decodeSecure<T>(\n buffer: Uint8Array | ArrayBuffer,\n options: ProtobufHooksOptions = {},\n): Promise<T> {\n const {\n obfuscate = true,\n obfuscationKey,\n protoType,\n transform,\n decode: customDecode,\n } = options;\n\n // let uint8 = buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : buffer;\n // let uint8 =\n // buffer instanceof ArrayBuffer\n // ? new Uint8Array(buffer)\n // : new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n\n // 1. 标准化为 Uint8Array 视图 (跨环境最稳写法)\n let uint8 = ArrayBuffer.isView(buffer)\n ? new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength)\n : new Uint8Array(buffer);\n\n // 1. 反混淆阶段\n if (uint8.length > 0 && obfuscate) {\n const finalKey = await getObfuscationKey(obfuscationKey);\n uint8 = xorTransform(uint8, finalKey);\n }\n\n // 2. 反序列化阶段\n if (customDecode) {\n return await customDecode<T>(uint8);\n }\n\n const type = protoType || getInternalSecureType();\n const decoded = type.decode(uint8);\n const plainObj = type.toObject(decoded, {\n longs: String,\n enums: String,\n bytes: Uint8Array as any,\n defaults: true,\n });\n\n // 3. 转换阶段\n if (transform?.afterDecode) {\n return transform.afterDecode(plainObj);\n }\n\n // 内置容器模式的额外还原逻辑\n if (!protoType && plainObj.data) {\n const jsonString = decoder.decode(plainObj.data as Uint8Array);\n try {\n return JSON.parse(jsonString) as T;\n } catch {\n return jsonString as unknown as T;\n }\n }\n\n return plainObj as T;\n}\n\n// ============================================================================\n// 4. HTTP/环境适配工具 (HTTP Tools)\n// ============================================================================\n\n/** 创建安全响应 (Worker/Server 端使用) */\nexport async function secureResponse<T>(\n data: T,\n options?: ProtobufCodecOptions & { corsHeaders?: Record<string, string> },\n): Promise<Response> {\n const buffer = await encodeSecure(data, options);\n // const arrayBuffer = buffer.buffer.slice(\n // buffer.byteOffset,\n // buffer.byteOffset + buffer.byteLength,\n // ) as ArrayBuffer;\n const cleanBuffer = buffer.slice();\n\n return new Response(cleanBuffer, {\n headers: {\n \"Content-Type\": \"application/x-protobuf\",\n ...options?.corsHeaders,\n },\n });\n}\n\n/** 解析安全请求体 (Worker/Server 端使用) */\nexport async function parseSecureRequest<T>(\n request: Request,\n customDecode?: ProtobufCustomCodec[\"decode\"],\n): Promise<T> {\n const buffer = await request.arrayBuffer();\n return decodeSecure<T>(buffer, { decode: customDecode });\n}\n\n/** 检查是否为 Protobuf 响应头 */\nexport function isProtobufContentType(contentType: string | null): boolean {\n return !!contentType?.includes(\"application/x-protobuf\");\n}\n\n/** 标准化配置对象 */\nexport function normalizeProtobufConfig(\n config: boolean | ProtobufConfig | undefined,\n options?: ProtobufHooksOptions, // 接收全局配置\n): ProtobufConfig | null {\n if (!config) return null;\n if (config === true) {\n return {\n encode: (data) => encodeSecure(data, options),\n decode: <T>(buffer: Uint8Array) => decodeSecure<T>(buffer, options),\n };\n }\n return config;\n}\n\n// ============================================================================\n// 5. API Client 钩子逻辑 (Integration Hooks)\n// ============================================================================\n\n/** 创建 Protobuf 编解码钩子 (用于与 createApiClient 配合使用) */\nexport function createProtobufHooks(options: ProtobufHooksOptions = {}) {\n const encode = (data: any) => encodeSecure(data, options);\n const decode = <T>(buffer: Uint8Array) => decodeSecure<T>(buffer, options);\n\n return {\n async onRequest(context: FetchContext) {\n const { options: reqOptions } = context;\n const headers =\n reqOptions.headers instanceof Headers\n ? reqOptions.headers\n : new Headers(reqOptions.headers as HeadersInit | undefined);\n\n // 自动编码请求体\n if (\n isProtobufContentType(headers.get(\"Content-Type\")) &&\n reqOptions.body &&\n !(reqOptions.body instanceof Uint8Array)\n ) {\n reqOptions.body = await encode(reqOptions.body);\n }\n\n // 自动设置期望响应类型\n if (\n isProtobufContentType(headers.get(\"Accept\")) &&\n !reqOptions.responseType\n ) {\n reqOptions.responseType = \"arrayBuffer\";\n }\n\n reqOptions.headers = headers;\n },\n\n async onResponse(context: FetchContext) {\n const { response } = context;\n if (!response?._data || response.status === 204) return;\n\n if (isProtobufContentType(response.headers.get(\"Content-Type\"))) {\n try {\n // 这里的 _data 可能是 ArrayBuffer (浏览器) 或 Buffer (Node)\n // decodeSecure 内部已处理好兼容性\n response._data = await decode(response._data);\n // const buffer = response._data as ArrayBuffer;\n // if (buffer && buffer.byteLength > 0) {\n // response._data = await decode(new Uint8Array(buffer));\n // }\n } catch (e) {\n console.log(\"Error [Protobuf Decode Error]\", e);\n response._data = null;\n }\n } else if (response._data instanceof ArrayBuffer) {\n const text = decoder.decode(response._data);\n try {\n response._data = JSON.parse(text);\n } catch {\n response._data = text;\n }\n }\n },\n };\n}\n"],"mappings":"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","names":["options","secure"]}
|
package/dist/index.mjs
CHANGED
|
@@ -492,7 +492,7 @@ async function encodeSecure(data, options = {}) {
|
|
|
492
492
|
let buffer;
|
|
493
493
|
const processedData = transform?.beforeEncode ? transform.beforeEncode(data) : data;
|
|
494
494
|
if (customEncode) {
|
|
495
|
-
buffer = await customEncode(
|
|
495
|
+
buffer = await customEncode(processedData);
|
|
496
496
|
} else {
|
|
497
497
|
const type = protoType || getInternalSecureType();
|
|
498
498
|
const payload = protoType ? processedData : {
|
|
@@ -515,7 +515,7 @@ async function decodeSecure(buffer, options = {}) {
|
|
|
515
515
|
transform,
|
|
516
516
|
decode: customDecode
|
|
517
517
|
} = options;
|
|
518
|
-
let uint8 =
|
|
518
|
+
let uint8 = ArrayBuffer.isView(buffer) ? new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength) : new Uint8Array(buffer);
|
|
519
519
|
if (uint8.length > 0 && obfuscate) {
|
|
520
520
|
const finalKey = await getObfuscationKey(obfuscationKey);
|
|
521
521
|
uint8 = xorTransform(uint8, finalKey);
|
|
@@ -546,11 +546,8 @@ async function decodeSecure(buffer, options = {}) {
|
|
|
546
546
|
}
|
|
547
547
|
async function secureResponse(data, options) {
|
|
548
548
|
const buffer = await encodeSecure(data, options);
|
|
549
|
-
const
|
|
550
|
-
|
|
551
|
-
buffer.byteOffset + buffer.byteLength
|
|
552
|
-
);
|
|
553
|
-
return new Response(arrayBuffer, {
|
|
549
|
+
const cleanBuffer = buffer.slice();
|
|
550
|
+
return new Response(cleanBuffer, {
|
|
554
551
|
headers: {
|
|
555
552
|
"Content-Type": "application/x-protobuf",
|
|
556
553
|
...options?.corsHeaders
|
|
@@ -591,11 +588,13 @@ function createProtobufHooks(options = {}) {
|
|
|
591
588
|
},
|
|
592
589
|
async onResponse(context) {
|
|
593
590
|
const { response } = context;
|
|
594
|
-
if (!response?._data) return;
|
|
591
|
+
if (!response?._data || response.status === 204) return;
|
|
595
592
|
if (isProtobufContentType(response.headers.get("Content-Type"))) {
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
593
|
+
try {
|
|
594
|
+
response._data = await decode(response._data);
|
|
595
|
+
} catch (e) {
|
|
596
|
+
console.log("Error [Protobuf Decode Error]", e);
|
|
597
|
+
response._data = null;
|
|
599
598
|
}
|
|
600
599
|
} else if (response._data instanceof ArrayBuffer) {
|
|
601
600
|
const text = decoder.decode(response._data);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/chain.ts","../src/secure.js","../src/protobuf.ts"],"sourcesContent":["import {\n ofetch,\n type FetchOptions,\n type FetchContext,\n type $Fetch,\n} from \"ofetch\";\n\nexport interface ApiResult<T> {\n code: number;\n data: T;\n message: string;\n}\n\nexport interface ApiError extends Error {\n code: number; // 业务错误码\n data?: unknown; // 后端返回的 data 字段(如果有)\n status?: number; // HTTP 状态码(网络错误时)\n}\n\n// 类型守卫:判断是否是 API 业务错误\nexport const isApiError = (error: unknown): error is ApiError => {\n return error instanceof Error && \"code\" in error;\n};\n\nexport interface TokenStorage {\n getAccessToken: () => Promise<string> | string;\n setAccessToken: (token: string) => Promise<void> | void;\n}\n\nexport interface CreateApiClientOptions {\n baseURL: string;\n tokenStorage: TokenStorage;\n refreshToken?: (() => Promise<string>) | string | false;\n retry?: number; // 重试次数,默认 1\n retryDelay?: number; // 重试间隔,默认 1s\n isAuthError?: (code: number) => boolean;\n unwrapResponse?<T>(result: unknown, returnFullResponse: boolean): T;\n createErrorFromResult?(res: unknown): Error;\n /**\n * 自定义请求钩子\n * 在请求发送前执行,可用于编码请求体等\n */\n onRequest?: (context: FetchContext) => void | Promise<void>;\n /**\n * 自定义响应钩子\n * 在响应返回后执行,可用于解码响应体等\n */\n onResponse?: (context: FetchContext) => void | Promise<void>;\n}\n\ntype RequestOptions = Omit<FetchOptions<\"json\">, \"responseType\"> & {\n returnFullResponse?: boolean;\n responseType?: \"json\" | \"arrayBuffer\" | \"text\" | \"blob\";\n};\n\n// 解包后端统一响应格式(默认实现)\nconst defaultUnwrapResponse = <T>(\n result: unknown,\n returnFullResponse = false,\n): T => {\n if (result && typeof result === \"object\" && \"code\" in result) {\n const body = result as Record<string, unknown>;\n if (body.code === 0) {\n return returnFullResponse ? (body as T) : (body.data as T);\n }\n }\n return result as T;\n};\n\nconst defaultCreateErrorFromResult = (res: ApiResult<unknown>): ApiError => {\n const error = new Error(res.message || \"Request failed\") as ApiError;\n error.code = res.code;\n error.data = res.data;\n return error;\n};\n\nconst extractAccessToken = (data: unknown): string => {\n if (typeof data === \"string\" && data) {\n return data;\n }\n\n if (!data || typeof data !== \"object\") {\n throw new Error(\n \"Invalid refresh token response: data is not an object or string\",\n );\n }\n\n const anyData = data as Record<string, unknown>;\n\n const accessToken =\n anyData.access_token ?? anyData.accessToken ?? anyData.token;\n\n if (typeof accessToken === \"string\" && accessToken) {\n return accessToken;\n }\n\n throw new Error(\n \"Invalid refresh token response: no access_token or token field found\",\n );\n};\n\n// 全局共享的刷新状态,以 tokenStorage 为 Key\n// 这样即使有多个 ApiClient 实例,只要它们共用同一个 tokenStorage,刷新逻辑就是单例的\nconst refreshingPromises = new WeakMap<TokenStorage, Promise<string>>();\n\nexport function createApiClient(options: CreateApiClientOptions) {\n const {\n baseURL,\n tokenStorage,\n refreshToken = false,\n retry = 1,\n retryDelay = 1000,\n isAuthError = (code: number) => code === 401,\n unwrapResponse = defaultUnwrapResponse,\n createErrorFromResult = defaultCreateErrorFromResult,\n } = options;\n\n const refreshTokenFn: (() => Promise<string>) | null = !refreshToken\n ? null\n : typeof refreshToken === \"string\"\n ? async () => {\n const res = await ofetch<ApiResult<unknown>>(refreshToken, {\n baseURL,\n method: \"POST\",\n retry,\n retryDelay,\n });\n\n if (res.code !== 0) {\n throw createErrorFromResult(res as ApiResult<unknown>);\n }\n\n return extractAccessToken(res.data);\n }\n : refreshToken;\n\n const rawRequest = ofetch.create({\n baseURL,\n retry,\n retryDelay,\n\n async onRequest(context: FetchContext) {\n const { options: reqOptions } = context;\n const token = await tokenStorage.getAccessToken();\n\n const headers = new Headers(\n reqOptions.headers as HeadersInit | undefined,\n );\n\n if (token) {\n headers.set(\"Authorization\", `Bearer ${token}`);\n }\n\n reqOptions.headers = headers;\n\n // 执行用户自定义钩子\n if (options.onRequest) {\n await options.onRequest(context);\n }\n },\n async onResponse(context) {\n const { response } = context;\n // 不在这里处理 code,统一交给 fetchApi 层处理\n if (response.status === 204) {\n response._data = null;\n return;\n }\n\n // 执行用户自定义钩子\n if (options.onResponse) {\n await options.onResponse(context);\n }\n },\n\n async onResponseError(context: FetchContext) {\n // 后端统一返回 HTTP 200,此处只处理网络层错误(如超时、断网)\n const { response } = context;\n const message =\n (response?._data as Record<string, unknown>)?.message ||\n `HTTP ${response?.status || \"Network Error\"}`;\n\n const error = new Error(message as string) as ApiError;\n error.status = response?.status;\n error.data = response?._data;\n throw error;\n },\n }) as $Fetch;\n\n async function request<T = unknown>(\n url: string,\n options: RequestOptions & { _retry?: boolean } = {},\n ): Promise<T> {\n // 提取自定义选项,避免传递给 $fetch\n const { returnFullResponse, _retry, ...fetchOptions } = options;\n\n // const res = await rawRequest<ApiResult<T>>(url, fetchOptions);\n const res = (await rawRequest(url, fetchOptions as FetchOptions)) as ApiResult<T>;\n\n if (res.code === 0) {\n return unwrapResponse<T>(res, !!returnFullResponse);\n // if (returnFullResponse) {\n // return res as unknown as T;\n // }\n\n // return res.data;\n }\n\n if (isAuthError(res.code) && !_retry && refreshTokenFn) {\n try {\n let refreshingPromise = refreshingPromises.get(tokenStorage);\n\n if (!refreshingPromise) {\n refreshingPromise = refreshTokenFn().finally(() => {\n refreshingPromises.delete(tokenStorage);\n });\n refreshingPromises.set(tokenStorage, refreshingPromise);\n }\n\n const newToken = await refreshingPromise;\n\n if (newToken) {\n await tokenStorage.setAccessToken(newToken);\n }\n\n return await request<T>(url, {\n ...(options || {}),\n _retry: true,\n } as any);\n } catch (e) {\n await tokenStorage.setAccessToken(\"\");\n throw createErrorFromResult(res as ApiResult<unknown>);\n }\n }\n\n throw createErrorFromResult(res as ApiResult<unknown>);\n }\n\n async function get<T = unknown>(\n url: string,\n params: FetchOptions[\"query\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"GET\",\n query: params,\n } as any);\n }\n\n async function post<T = unknown>(\n url: string,\n body: FetchOptions[\"body\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"POST\",\n body,\n } as any);\n }\n\n async function put<T = unknown>(\n url: string,\n body: FetchOptions[\"body\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"PUT\",\n body,\n } as any);\n }\n\n async function patch<T = unknown>(\n url: string,\n body: FetchOptions[\"body\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"PATCH\",\n body,\n } as any);\n }\n\n async function del<T = unknown>(\n url: string,\n params: FetchOptions[\"query\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"DELETE\",\n query: params,\n } as any);\n }\n\n return {\n rawRequest,\n request,\n get,\n post,\n put,\n patch,\n del,\n };\n}\n","/**\n * Request Chain Runner\n * 负责解析和执行通用的 HTTP 请求链 (Chain Execution)\n * 适用于任何需要链式 HTTP 请求编排的场景\n */\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/** Supported HTTP Methods */\ntype HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n\n/** HTTP 请求参数 */\nexport interface HttpRequestSpec {\n method: HttpMethod;\n url: string;\n headers?: Record<string, string>;\n body?: any;\n}\n\n/**\n * 网络适配器接口\n * 定义实际发送请求的能力\n */\n/**\n * 网络适配器接口\n * 定义实际发送请求的能力\n */\nexport interface NetworkAdapter {\n get<T>(\n url: string,\n params?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n post<T>(\n url: string,\n body?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n put?<T>(\n url: string,\n body?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n delete?<T>(\n url: string,\n params?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n patch?<T>(\n url: string,\n body?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n}\n\n/**\n * 网络处理器接口 (Strategy Pattern)\n * 组合了\"匹配规则\"和\"执行能力\"\n */\nexport interface NetworkHandler {\n /** 处理器名称 (用于调试) */\n name?: string;\n\n /** 判断该 URL 是否由此适配器处理 */\n shouldHandle(url: string, method: HttpMethod): boolean;\n\n /** 具体的网络适配器 */\n adapter: NetworkAdapter;\n}\n\n/**\n * 请求链规则 (Chain Step)\n */\nexport interface ChainRequestRule {\n /**\n * 结果存储的键名 (Context Key)\n * Fetch 结果存储: context[key] = response\n */\n key?: string;\n\n /**\n * HTTP 请求详情\n */\n request: HttpRequestSpec;\n\n /**\n * 数据提取选择器\n * 用于从响应中提取特定数据, e.g., \"elements.0\"\n */\n selector?: string;\n\n /** 是否允许请求失败 (默认 false) */\n optional?: boolean;\n\n /**\n * 是否包含上下文\n * 如果为 true,请求 Body 将自动合并当前 Context 和 Payload\n */\n includeContext?: boolean;\n\n /**\n * 上下文筛选列表 (优先级高于 includeContext)\n * 指定需要合并到 Body 中的 Context Key 列表\n * e.g., [\"rawProfile\", \"rawCompany\"]\n */\n pickContext?: string[];\n\n /** 额外 Payload (仅当 includeContext 为 true 或 pickContext 存在时合并) */\n payload?: Record<string, any>;\n}\n\n// ============================================================================\n// Internal Utilities\n// ============================================================================\n\n/**\n * 执行 HTTP 请求\n * 遍历 handlers 数组,找到第一个能处理该 URL 的适配器执行\n *\n * @param spec 请求详情\n * @param handlers 网络处理器链\n */\nasync function executeChainRequest<T>(\n spec: HttpRequestSpec,\n handlers: NetworkHandler[] = []\n): Promise<T | null> {\n // Normalize method to upper case for robustness\n const method = spec.method.toUpperCase() as HttpMethod;\n\n // 1. 遍历处理器数组 (责任链)\n for (const handler of handlers) {\n if (handler.shouldHandle(spec.url, method)) {\n try {\n const { adapter } = handler;\n const headers = spec.headers;\n\n switch (method) {\n case \"GET\":\n return await adapter.get<T>(spec.url, spec.body, headers);\n case \"POST\":\n return await adapter.post<T>(spec.url, spec.body, headers);\n case \"PUT\":\n if (!adapter.put)\n throw new Error(`Adapter ${handler.name} missing PUT method`);\n return await adapter.put<T>(spec.url, spec.body, headers);\n case \"DELETE\":\n if (!adapter.delete)\n throw new Error(`Adapter ${handler.name} missing DELETE method`);\n return await adapter.delete<T>(spec.url, spec.body, headers);\n case \"PATCH\":\n if (!adapter.patch)\n throw new Error(`Adapter ${handler.name} missing PATCH method`);\n return await adapter.patch<T>(spec.url, spec.body, headers);\n default:\n throw new Error(`Unsupported method: ${method}`);\n }\n } catch (err) {\n console.warn(\n `Handler [${handler.name || \"Anonymous\"}] failed for ${spec.url}`,\n err\n );\n // 如果需要继续尝试下一个 handler,可以在这里 continue,但通常由第一个匹配者全权负责\n return null;\n }\n }\n }\n\n // 2. 默认行为 (Fallback): 绝对路径自动走标准 fetch\n if (spec.url.startsWith(\"http://\") || spec.url.startsWith(\"https://\")) {\n return await executeFallbackFetch<T>(spec);\n }\n\n console.warn(`No handler found for url: ${spec.url}`);\n return null;\n}\n\n/**\n * 标准 Fetch 回退实现\n */\nasync function executeFallbackFetch<T>(\n spec: HttpRequestSpec\n): Promise<T | null> {\n try {\n const response = await fetch(spec.url, {\n method: spec.method,\n headers: spec.headers,\n body: spec.body ? JSON.stringify(spec.body) : undefined,\n credentials: \"include\",\n });\n\n if (!response.ok) {\n console.log(`External Request failed: ${response.status} ${spec.url}`);\n return null;\n }\n\n return await response.json();\n } catch (err) {\n console.log(\"External Request error:\", err);\n return null;\n }\n}\n\n/**\n * 根据路径获取对象值\n */\nfunction getByPath(obj: any, path: string): any {\n if (!path) return obj;\n return path.split(\".\").reduce((acc, part) => acc && acc[part], obj);\n}\n\n/**\n * 变量替换 (Internal)\n * 支持字符串 {{key}} 和 {{key.prop}}\n */\nfunction substituteVariables(target: any, context: any): any {\n if (typeof target === \"string\") {\n return target.replace(/\\{\\{([\\w\\.]+)\\}\\}/g, (_, path) => {\n const val = getByPath(context, path);\n return val !== undefined ? String(val) : \"\";\n });\n }\n\n if (Array.isArray(target)) {\n return target.map((item) => substituteVariables(item, context));\n }\n\n if (target && typeof target === \"object\") {\n const result: any = {};\n for (const key in target) {\n result[key] = substituteVariables(target[key], context);\n }\n return result;\n }\n\n return target;\n}\n\n// ============================================================================\n// Main Runner\n// ============================================================================\n\n/**\n * 请求链执行器 (Request Chain Engine)\n * 支持链式请求、上下文累积、智能路由、变量替换\n *\n * @param requests 链式执行规则列表\n * @param handlers 网络适配器处理器列表 (按顺序匹配)\n */\nexport async function executeRequestChain<T>(\n requests: ChainRequestRule[],\n handlers: NetworkHandler[] = [],\n getChainRequests?: (\n context: Record<string, any>\n ) => ChainRequestRule[] | null | undefined,\n initContext?: Record<string, any>\n): Promise<T> {\n const context: Record<string, any> = initContext || {};\n let lastResult: any = null;\n\n for (const rule of requests) {\n try {\n // 1. 准备 Context Data (用于 Submit)\n let contextData: Record<string, any> = {};\n if (rule.pickContext) {\n rule.pickContext.forEach((key) => {\n if (key in context) contextData[key] = context[key];\n });\n } else if (rule.includeContext) {\n contextData = context;\n }\n const hasContextData = Object.keys(contextData).length > 0;\n\n // 2. 准备 Request Spec (合并 Payload 和 Context)\n let requestSpec = { ...rule.request };\n if (hasContextData || rule.payload) {\n requestSpec.body = {\n ...(rule.payload || {}),\n ...contextData,\n ...(requestSpec.body || {}),\n };\n }\n\n // 3. 变量替换\n requestSpec = substituteVariables(requestSpec, context);\n\n // 4. 执行请求 (传入 handlers)\n let rawData = await executeChainRequest<any>(requestSpec, handlers);\n\n if (getChainRequests) {\n const chainRequests = getChainRequests(rawData);\n if (chainRequests && chainRequests.length > 0) {\n rawData = await executeRequestChain(\n chainRequests,\n handlers,\n getChainRequests,\n JSON.parse(JSON.stringify(context))\n );\n }\n }\n\n lastResult = rawData;\n\n if (rawData) {\n // 5. 存储结果\n if (rule.key) {\n const data = rule.selector\n ? getByPath(rawData, rule.selector)\n : rawData;\n context[rule.key] = data;\n }\n } else if (!rule.optional) {\n throw new Error(\n `Failed to fetch required data for key: ${rule.key || \"unknown\"}`\n );\n }\n } catch (err) {\n if (!rule.optional) {\n throw err;\n }\n console.warn(`Optional request failed for rule:`, rule, err);\n }\n }\n\n return lastResult as T;\n}\n","/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/\nimport * as $protobuf from \"protobufjs/minimal\";\n\n// Common aliases\nconst $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;\n\n// Exported root namespace\nconst $root = $protobuf.roots[\"default\"] || ($protobuf.roots[\"default\"] = {});\n\nexport const secure = $root.secure = (() => {\n\n /**\n * Namespace secure.\n * @exports secure\n * @namespace\n */\n const secure = {};\n\n secure.SecurePayload = (function() {\n\n /**\n * Properties of a SecurePayload.\n * @memberof secure\n * @interface ISecurePayload\n * @property {number|Long|null} [ts] SecurePayload ts\n * @property {Uint8Array|null} [data] SecurePayload data\n */\n\n /**\n * Constructs a new SecurePayload.\n * @memberof secure\n * @classdesc Represents a SecurePayload.\n * @implements ISecurePayload\n * @constructor\n * @param {secure.ISecurePayload=} [properties] Properties to set\n */\n function SecurePayload(properties) {\n if (properties)\n for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null)\n this[keys[i]] = properties[keys[i]];\n }\n\n /**\n * SecurePayload ts.\n * @member {number|Long} ts\n * @memberof secure.SecurePayload\n * @instance\n */\n SecurePayload.prototype.ts = $util.Long ? $util.Long.fromBits(0,0,false) : 0;\n\n /**\n * SecurePayload data.\n * @member {Uint8Array} data\n * @memberof secure.SecurePayload\n * @instance\n */\n SecurePayload.prototype.data = $util.newBuffer([]);\n\n /**\n * Creates a new SecurePayload instance using the specified properties.\n * @function create\n * @memberof secure.SecurePayload\n * @static\n * @param {secure.ISecurePayload=} [properties] Properties to set\n * @returns {secure.SecurePayload} SecurePayload instance\n */\n SecurePayload.create = function create(properties) {\n return new SecurePayload(properties);\n };\n\n /**\n * Encodes the specified SecurePayload message. Does not implicitly {@link secure.SecurePayload.verify|verify} messages.\n * @function encode\n * @memberof secure.SecurePayload\n * @static\n * @param {secure.ISecurePayload} message SecurePayload message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n SecurePayload.encode = function encode(message, writer) {\n if (!writer)\n writer = $Writer.create();\n if (message.ts != null && Object.hasOwnProperty.call(message, \"ts\"))\n writer.uint32(/* id 1, wireType 0 =*/8).int64(message.ts);\n if (message.data != null && Object.hasOwnProperty.call(message, \"data\"))\n writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.data);\n return writer;\n };\n\n /**\n * Encodes the specified SecurePayload message, length delimited. Does not implicitly {@link secure.SecurePayload.verify|verify} messages.\n * @function encodeDelimited\n * @memberof secure.SecurePayload\n * @static\n * @param {secure.ISecurePayload} message SecurePayload message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n SecurePayload.encodeDelimited = function encodeDelimited(message, writer) {\n return this.encode(message, writer).ldelim();\n };\n\n /**\n * Decodes a SecurePayload message from the specified reader or buffer.\n * @function decode\n * @memberof secure.SecurePayload\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {secure.SecurePayload} SecurePayload\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n SecurePayload.decode = function decode(reader, length, error) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n let end = length === undefined ? reader.len : reader.pos + length, message = new $root.secure.SecurePayload();\n while (reader.pos < end) {\n let tag = reader.uint32();\n if (tag === error)\n break;\n switch (tag >>> 3) {\n case 1: {\n message.ts = reader.int64();\n break;\n }\n case 2: {\n message.data = reader.bytes();\n break;\n }\n default:\n reader.skipType(tag & 7);\n break;\n }\n }\n return message;\n };\n\n /**\n * Decodes a SecurePayload message from the specified reader or buffer, length delimited.\n * @function decodeDelimited\n * @memberof secure.SecurePayload\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @returns {secure.SecurePayload} SecurePayload\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n SecurePayload.decodeDelimited = function decodeDelimited(reader) {\n if (!(reader instanceof $Reader))\n reader = new $Reader(reader);\n return this.decode(reader, reader.uint32());\n };\n\n /**\n * Verifies a SecurePayload message.\n * @function verify\n * @memberof secure.SecurePayload\n * @static\n * @param {Object.<string,*>} message Plain object to verify\n * @returns {string|null} `null` if valid, otherwise the reason why it is not\n */\n SecurePayload.verify = function verify(message) {\n if (typeof message !== \"object\" || message === null)\n return \"object expected\";\n if (message.ts != null && message.hasOwnProperty(\"ts\"))\n if (!$util.isInteger(message.ts) && !(message.ts && $util.isInteger(message.ts.low) && $util.isInteger(message.ts.high)))\n return \"ts: integer|Long expected\";\n if (message.data != null && message.hasOwnProperty(\"data\"))\n if (!(message.data && typeof message.data.length === \"number\" || $util.isString(message.data)))\n return \"data: buffer expected\";\n return null;\n };\n\n /**\n * Creates a SecurePayload message from a plain object. Also converts values to their respective internal types.\n * @function fromObject\n * @memberof secure.SecurePayload\n * @static\n * @param {Object.<string,*>} object Plain object\n * @returns {secure.SecurePayload} SecurePayload\n */\n SecurePayload.fromObject = function fromObject(object) {\n if (object instanceof $root.secure.SecurePayload)\n return object;\n let message = new $root.secure.SecurePayload();\n if (object.ts != null)\n if ($util.Long)\n (message.ts = $util.Long.fromValue(object.ts)).unsigned = false;\n else if (typeof object.ts === \"string\")\n message.ts = parseInt(object.ts, 10);\n else if (typeof object.ts === \"number\")\n message.ts = object.ts;\n else if (typeof object.ts === \"object\")\n message.ts = new $util.LongBits(object.ts.low >>> 0, object.ts.high >>> 0).toNumber();\n if (object.data != null)\n if (typeof object.data === \"string\")\n $util.base64.decode(object.data, message.data = $util.newBuffer($util.base64.length(object.data)), 0);\n else if (object.data.length >= 0)\n message.data = object.data;\n return message;\n };\n\n /**\n * Creates a plain object from a SecurePayload message. Also converts values to other types if specified.\n * @function toObject\n * @memberof secure.SecurePayload\n * @static\n * @param {secure.SecurePayload} message SecurePayload\n * @param {$protobuf.IConversionOptions} [options] Conversion options\n * @returns {Object.<string,*>} Plain object\n */\n SecurePayload.toObject = function toObject(message, options) {\n if (!options)\n options = {};\n let object = {};\n if (options.defaults) {\n if ($util.Long) {\n let long = new $util.Long(0, 0, false);\n object.ts = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;\n } else\n object.ts = options.longs === String ? \"0\" : 0;\n if (options.bytes === String)\n object.data = \"\";\n else {\n object.data = [];\n if (options.bytes !== Array)\n object.data = $util.newBuffer(object.data);\n }\n }\n if (message.ts != null && message.hasOwnProperty(\"ts\"))\n if (typeof message.ts === \"number\")\n object.ts = options.longs === String ? String(message.ts) : message.ts;\n else\n object.ts = options.longs === String ? $util.Long.prototype.toString.call(message.ts) : options.longs === Number ? new $util.LongBits(message.ts.low >>> 0, message.ts.high >>> 0).toNumber() : message.ts;\n if (message.data != null && message.hasOwnProperty(\"data\"))\n object.data = options.bytes === String ? $util.base64.encode(message.data, 0, message.data.length) : options.bytes === Array ? Array.prototype.slice.call(message.data) : message.data;\n return object;\n };\n\n /**\n * Converts this SecurePayload to JSON.\n * @function toJSON\n * @memberof secure.SecurePayload\n * @instance\n * @returns {Object.<string,*>} JSON object\n */\n SecurePayload.prototype.toJSON = function toJSON() {\n return this.constructor.toObject(this, $protobuf.util.toJSONOptions);\n };\n\n /**\n * Gets the default type url for SecurePayload\n * @function getTypeUrl\n * @memberof secure.SecurePayload\n * @static\n * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default \"type.googleapis.com\")\n * @returns {string} The default type url\n */\n SecurePayload.getTypeUrl = function getTypeUrl(typeUrlPrefix) {\n if (typeUrlPrefix === undefined) {\n typeUrlPrefix = \"type.googleapis.com\";\n }\n return typeUrlPrefix + \"/secure.SecurePayload\";\n };\n\n return SecurePayload;\n })();\n\n return secure;\n})();\n\nexport { $root as default };\n","/**\n * Protobuf 安全通信模块\n *\n * 提供基于 Protobuf 的二进制序列化、XOR 混淆加密以及与 API Client 的无缝集成。\n */\n\nimport protobuf from \"protobufjs/light\";\nimport { secure } from \"./secure.js\";\nimport type { FetchContext } from \"ofetch\";\n\n// ============================================================================\n// 1. 类型定义 (Types)\n// ============================================================================\n\n/**\n * 基础编解码配置\n * 控制如何将数据转换为二进制,以及是否混淆\n */\nexport interface ProtobufCodecOptions {\n /** 是否启用二进制 XOR 混淆 (默认 true) */\n obfuscate?: boolean;\n /**\n * 混淆密钥\n * 可以是静态字符串/字节数组,也可以是动态获取密钥的同步或异步函数\n */\n obfuscationKey?:\n | string\n | Uint8Array\n | (() => string | Uint8Array | Promise<string | Uint8Array>);\n /** 预编译的 Protobuf 类型对象 (推荐,性能最高) */\n protoType?: any;\n /** 数据转换钩子:处理业务模型与 Proto 结构不一致的情况 */\n transform?: {\n beforeEncode?: (data: any) => any;\n afterDecode?: (payload: any) => any;\n };\n}\n\n/**\n * 完全自定义编解码接口\n * 用于外部项目完全接管序列化过程,同时复用基础库的混淆外壳\n */\nexport interface ProtobufCustomCodec {\n /** 外部定义的编码逻辑 (返回原始二进制) */\n encode?: (data: any) => Uint8Array | Promise<Uint8Array>;\n /** 外部定义的解码逻辑 (返回原始对象) */\n decode?: <T>(buffer: Uint8Array) => T | Promise<T>;\n}\n\n/**\n * 集成配置项\n * 用于 createProtobufHooks 或 API Client 全局配置\n */\nexport interface ProtobufHooksOptions\n extends ProtobufCodecOptions, ProtobufCustomCodec {}\n\n/**\n * API Client 内部使用的标准化配置\n */\nexport interface ProtobufConfig {\n encode: (data: any) => Uint8Array | Promise<Uint8Array>;\n decode: <T>(buffer: Uint8Array) => T | Promise<T>;\n options?: ProtobufCodecOptions;\n}\n\n// ============================================================================\n// 2. 内部工具函数 (Internal Utilities)\n// ============================================================================\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/** 简单的二进制异或混淆转换 */\nexport function xorTransform(\n data: Uint8Array,\n key: string | Uint8Array,\n): Uint8Array {\n const keyBytes = typeof key === \"string\" ? encoder.encode(key) : key;\n if (keyBytes.length === 0) return data;\n\n for (let i = 0; i < data.length; i++) {\n data[i] ^= keyBytes[i % keyBytes.length];\n }\n return data;\n}\n\n/** 获取混淆密钥(支持异步/函数) */\nexport async function getObfuscationKey(\n keyOption?: ProtobufCodecOptions[\"obfuscationKey\"],\n): Promise<string | Uint8Array> {\n const defaultKey = \"api-client-default-key\";\n if (!keyOption) return defaultKey;\n if (typeof keyOption === \"function\") {\n return await keyOption();\n }\n return keyOption;\n}\n\n/** 获取内置的 SecurePayload 类型(使用预编译代码) */\nfunction getInternalSecureType(): protobuf.Type {\n return secure.SecurePayload as unknown as protobuf.Type;\n}\n\n// ============================================================================\n// 3. 核心编解码逻辑 (Core Codecs)\n// ============================================================================\n\n/**\n * 编码安全载荷\n *\n * 流程:业务数据 -> (自定义编码 / Proto 序列化) -> 二进制混淆\n */\nexport async function encodeSecure<T>(\n data: T,\n options: ProtobufHooksOptions = {},\n): Promise<Uint8Array> {\n const {\n obfuscate = true,\n obfuscationKey,\n protoType,\n transform,\n encode: customEncode,\n } = options;\n\n let buffer: Uint8Array;\n\n // 1. 预处理阶段:无论后续走哪条路径,只要定义了 beforeEncode 就先执行\n const processedData = transform?.beforeEncode\n ? transform.beforeEncode(data)\n : data;\n\n // 1. 序列化阶段\n if (customEncode) {\n buffer = await customEncode(data);\n } else {\n const type = protoType || getInternalSecureType();\n\n // 构造最终要交给 Protobuf 序列化的对象\n const payload = protoType\n ? processedData // 自定义模式:直接使用预处理后的数据\n : {\n // 默认容器模式:将预处理后的数据封装进信封\n ts: Date.now(),\n data:\n processedData instanceof Uint8Array\n ? processedData\n : encoder.encode(JSON.stringify(processedData)),\n };\n\n const message = type.create(payload);\n buffer = type.encode(message).finish();\n }\n\n // 2. 混淆阶段\n if (!obfuscate) return buffer;\n const finalKey = await getObfuscationKey(obfuscationKey);\n return xorTransform(buffer, finalKey);\n}\n\n/**\n * 解码安全载荷\n *\n * 流程:二进制流 -> 二进制反混淆 -> (自定义解码 / Proto 反序列化) -> 业务数据\n */\nexport async function decodeSecure<T>(\n buffer: Uint8Array | ArrayBuffer,\n options: ProtobufHooksOptions = {},\n): Promise<T> {\n const {\n obfuscate = true,\n obfuscationKey,\n protoType,\n transform,\n decode: customDecode,\n } = options;\n\n // let uint8 = buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : buffer;\n let uint8 =\n buffer instanceof ArrayBuffer\n ? new Uint8Array(buffer)\n : new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n\n // 1. 反混淆阶段\n if (uint8.length > 0 && obfuscate) {\n const finalKey = await getObfuscationKey(obfuscationKey);\n uint8 = xorTransform(uint8, finalKey);\n }\n\n // 2. 反序列化阶段\n if (customDecode) {\n return await customDecode<T>(uint8);\n }\n\n const type = protoType || getInternalSecureType();\n const decoded = type.decode(uint8);\n const plainObj = type.toObject(decoded, {\n longs: String,\n enums: String,\n bytes: Uint8Array as any,\n defaults: true,\n });\n\n // 3. 转换阶段\n if (transform?.afterDecode) {\n return transform.afterDecode(plainObj);\n }\n\n // 内置容器模式的额外还原逻辑\n if (!protoType && plainObj.data) {\n const jsonString = decoder.decode(plainObj.data as Uint8Array);\n try {\n return JSON.parse(jsonString) as T;\n } catch {\n return jsonString as unknown as T;\n }\n }\n\n return plainObj as T;\n}\n\n// ============================================================================\n// 4. HTTP/环境适配工具 (HTTP Tools)\n// ============================================================================\n\n/** 创建安全响应 (Worker/Server 端使用) */\nexport async function secureResponse<T>(\n data: T,\n options?: ProtobufCodecOptions & { corsHeaders?: Record<string, string> },\n): Promise<Response> {\n const buffer = await encodeSecure(data, options);\n const arrayBuffer = buffer.buffer.slice(\n buffer.byteOffset,\n buffer.byteOffset + buffer.byteLength,\n ) as ArrayBuffer;\n\n return new Response(arrayBuffer, {\n headers: {\n \"Content-Type\": \"application/x-protobuf\",\n ...options?.corsHeaders,\n },\n });\n}\n\n/** 解析安全请求体 (Worker/Server 端使用) */\nexport async function parseSecureRequest<T>(\n request: Request,\n customDecode?: ProtobufCustomCodec[\"decode\"],\n): Promise<T> {\n const buffer = await request.arrayBuffer();\n return decodeSecure<T>(buffer, { decode: customDecode });\n}\n\n/** 检查是否为 Protobuf 响应头 */\nexport function isProtobufContentType(contentType: string | null): boolean {\n return !!contentType?.includes(\"application/x-protobuf\");\n}\n\n/** 标准化配置对象 */\nexport function normalizeProtobufConfig(\n config: boolean | ProtobufConfig | undefined,\n options?: ProtobufHooksOptions, // 接收全局配置\n): ProtobufConfig | null {\n if (!config) return null;\n if (config === true) {\n return {\n encode: (data) => encodeSecure(data, options),\n decode: <T>(buffer: Uint8Array) => decodeSecure<T>(buffer, options),\n };\n }\n return config;\n}\n\n// ============================================================================\n// 5. API Client 钩子逻辑 (Integration Hooks)\n// ============================================================================\n\n/** 创建 Protobuf 编解码钩子 (用于与 createApiClient 配合使用) */\nexport function createProtobufHooks(options: ProtobufHooksOptions = {}) {\n const encode = (data: any) => encodeSecure(data, options);\n const decode = <T>(buffer: Uint8Array) => decodeSecure<T>(buffer, options);\n\n return {\n async onRequest(context: FetchContext) {\n const { options: reqOptions } = context;\n const headers =\n reqOptions.headers instanceof Headers\n ? reqOptions.headers\n : new Headers(reqOptions.headers as HeadersInit | undefined);\n\n // 自动编码请求体\n if (\n isProtobufContentType(headers.get(\"Content-Type\")) &&\n reqOptions.body &&\n !(reqOptions.body instanceof Uint8Array)\n ) {\n reqOptions.body = await encode(reqOptions.body);\n }\n\n // 自动设置期望响应类型\n if (\n isProtobufContentType(headers.get(\"Accept\")) &&\n !reqOptions.responseType\n ) {\n reqOptions.responseType = \"arrayBuffer\";\n }\n\n reqOptions.headers = headers;\n },\n\n async onResponse(context: FetchContext) {\n const { response } = context;\n if (!response?._data) return;\n\n if (isProtobufContentType(response.headers.get(\"Content-Type\"))) {\n const buffer = response._data as ArrayBuffer;\n if (buffer && buffer.byteLength > 0) {\n response._data = await decode(new Uint8Array(buffer));\n }\n } else if (response._data instanceof ArrayBuffer) {\n const text = decoder.decode(response._data);\n try {\n response._data = JSON.parse(text);\n } catch {\n response._data = text;\n }\n }\n },\n };\n}\n"],"mappings":"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","names":["options","secure"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/chain.ts","../src/secure.js","../src/protobuf.ts"],"sourcesContent":["import {\n ofetch,\n type FetchOptions,\n type FetchContext,\n type $Fetch,\n} from \"ofetch\";\n\nexport interface ApiResult<T> {\n code: number;\n data: T;\n message: string;\n}\n\nexport interface ApiError extends Error {\n code: number; // 业务错误码\n data?: unknown; // 后端返回的 data 字段(如果有)\n status?: number; // HTTP 状态码(网络错误时)\n}\n\n// 类型守卫:判断是否是 API 业务错误\nexport const isApiError = (error: unknown): error is ApiError => {\n return error instanceof Error && \"code\" in error;\n};\n\nexport interface TokenStorage {\n getAccessToken: () => Promise<string> | string;\n setAccessToken: (token: string) => Promise<void> | void;\n}\n\nexport interface CreateApiClientOptions {\n baseURL: string;\n tokenStorage: TokenStorage;\n refreshToken?: (() => Promise<string>) | string | false;\n retry?: number; // 重试次数,默认 1\n retryDelay?: number; // 重试间隔,默认 1s\n isAuthError?: (code: number) => boolean;\n unwrapResponse?<T>(result: unknown, returnFullResponse: boolean): T;\n createErrorFromResult?(res: unknown): Error;\n /**\n * 自定义请求钩子\n * 在请求发送前执行,可用于编码请求体等\n */\n onRequest?: (context: FetchContext) => void | Promise<void>;\n /**\n * 自定义响应钩子\n * 在响应返回后执行,可用于解码响应体等\n */\n onResponse?: (context: FetchContext) => void | Promise<void>;\n}\n\ntype RequestOptions = Omit<FetchOptions<\"json\">, \"responseType\"> & {\n returnFullResponse?: boolean;\n responseType?: \"json\" | \"arrayBuffer\" | \"text\" | \"blob\";\n};\n\n// 解包后端统一响应格式(默认实现)\nconst defaultUnwrapResponse = <T>(\n result: unknown,\n returnFullResponse = false,\n): T => {\n if (result && typeof result === \"object\" && \"code\" in result) {\n const body = result as Record<string, unknown>;\n if (body.code === 0) {\n return returnFullResponse ? (body as T) : (body.data as T);\n }\n }\n return result as T;\n};\n\nconst defaultCreateErrorFromResult = (res: ApiResult<unknown>): ApiError => {\n const error = new Error(res.message || \"Request failed\") as ApiError;\n error.code = res.code;\n error.data = res.data;\n return error;\n};\n\nconst extractAccessToken = (data: unknown): string => {\n if (typeof data === \"string\" && data) {\n return data;\n }\n\n if (!data || typeof data !== \"object\") {\n throw new Error(\n \"Invalid refresh token response: data is not an object or string\",\n );\n }\n\n const anyData = data as Record<string, unknown>;\n\n const accessToken =\n anyData.access_token ?? anyData.accessToken ?? anyData.token;\n\n if (typeof accessToken === \"string\" && accessToken) {\n return accessToken;\n }\n\n throw new Error(\n \"Invalid refresh token response: no access_token or token field found\",\n );\n};\n\n// 全局共享的刷新状态,以 tokenStorage 为 Key\n// 这样即使有多个 ApiClient 实例,只要它们共用同一个 tokenStorage,刷新逻辑就是单例的\nconst refreshingPromises = new WeakMap<TokenStorage, Promise<string>>();\n\nexport function createApiClient(options: CreateApiClientOptions) {\n const {\n baseURL,\n tokenStorage,\n refreshToken = false,\n retry = 1,\n retryDelay = 1000,\n isAuthError = (code: number) => code === 401,\n unwrapResponse = defaultUnwrapResponse,\n createErrorFromResult = defaultCreateErrorFromResult,\n } = options;\n\n const refreshTokenFn: (() => Promise<string>) | null = !refreshToken\n ? null\n : typeof refreshToken === \"string\"\n ? async () => {\n const res = await ofetch<ApiResult<unknown>>(refreshToken, {\n baseURL,\n method: \"POST\",\n retry,\n retryDelay,\n });\n\n if (res.code !== 0) {\n throw createErrorFromResult(res as ApiResult<unknown>);\n }\n\n return extractAccessToken(res.data);\n }\n : refreshToken;\n\n const rawRequest = ofetch.create({\n baseURL,\n retry,\n retryDelay,\n\n async onRequest(context: FetchContext) {\n const { options: reqOptions } = context;\n const token = await tokenStorage.getAccessToken();\n\n const headers = new Headers(\n reqOptions.headers as HeadersInit | undefined,\n );\n\n if (token) {\n headers.set(\"Authorization\", `Bearer ${token}`);\n }\n\n reqOptions.headers = headers;\n\n // 执行用户自定义钩子\n if (options.onRequest) {\n await options.onRequest(context);\n }\n },\n async onResponse(context) {\n const { response } = context;\n // 不在这里处理 code,统一交给 fetchApi 层处理\n if (response.status === 204) {\n response._data = null;\n return;\n }\n\n // 执行用户自定义钩子\n if (options.onResponse) {\n await options.onResponse(context);\n }\n },\n\n async onResponseError(context: FetchContext) {\n // 后端统一返回 HTTP 200,此处只处理网络层错误(如超时、断网)\n const { response } = context;\n const message =\n (response?._data as Record<string, unknown>)?.message ||\n `HTTP ${response?.status || \"Network Error\"}`;\n\n const error = new Error(message as string) as ApiError;\n error.status = response?.status;\n error.data = response?._data;\n throw error;\n },\n }) as $Fetch;\n\n async function request<T = unknown>(\n url: string,\n options: RequestOptions & { _retry?: boolean } = {},\n ): Promise<T> {\n // 提取自定义选项,避免传递给 $fetch\n const { returnFullResponse, _retry, ...fetchOptions } = options;\n\n // const res = await rawRequest<ApiResult<T>>(url, fetchOptions);\n const res = (await rawRequest(url, fetchOptions as FetchOptions)) as ApiResult<T>;\n\n if (res.code === 0) {\n return unwrapResponse<T>(res, !!returnFullResponse);\n // if (returnFullResponse) {\n // return res as unknown as T;\n // }\n\n // return res.data;\n }\n\n if (isAuthError(res.code) && !_retry && refreshTokenFn) {\n try {\n let refreshingPromise = refreshingPromises.get(tokenStorage);\n\n if (!refreshingPromise) {\n refreshingPromise = refreshTokenFn().finally(() => {\n refreshingPromises.delete(tokenStorage);\n });\n refreshingPromises.set(tokenStorage, refreshingPromise);\n }\n\n const newToken = await refreshingPromise;\n\n if (newToken) {\n await tokenStorage.setAccessToken(newToken);\n }\n\n return await request<T>(url, {\n ...(options || {}),\n _retry: true,\n } as any);\n } catch (e) {\n await tokenStorage.setAccessToken(\"\");\n throw createErrorFromResult(res as ApiResult<unknown>);\n }\n }\n\n throw createErrorFromResult(res as ApiResult<unknown>);\n }\n\n async function get<T = unknown>(\n url: string,\n params: FetchOptions[\"query\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"GET\",\n query: params,\n } as any);\n }\n\n async function post<T = unknown>(\n url: string,\n body: FetchOptions[\"body\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"POST\",\n body,\n } as any);\n }\n\n async function put<T = unknown>(\n url: string,\n body: FetchOptions[\"body\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"PUT\",\n body,\n } as any);\n }\n\n async function patch<T = unknown>(\n url: string,\n body: FetchOptions[\"body\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"PATCH\",\n body,\n } as any);\n }\n\n async function del<T = unknown>(\n url: string,\n params: FetchOptions[\"query\"] = {},\n options?: RequestOptions,\n ) {\n return request<T>(url, {\n ...options,\n method: \"DELETE\",\n query: params,\n } as any);\n }\n\n return {\n rawRequest,\n request,\n get,\n post,\n put,\n patch,\n del,\n };\n}\n","/**\n * Request Chain Runner\n * 负责解析和执行通用的 HTTP 请求链 (Chain Execution)\n * 适用于任何需要链式 HTTP 请求编排的场景\n */\n\n// ============================================================================\n// Type Definitions\n// ============================================================================\n\n/** Supported HTTP Methods */\ntype HttpMethod = \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n\n/** HTTP 请求参数 */\nexport interface HttpRequestSpec {\n method: HttpMethod;\n url: string;\n headers?: Record<string, string>;\n body?: any;\n}\n\n/**\n * 网络适配器接口\n * 定义实际发送请求的能力\n */\n/**\n * 网络适配器接口\n * 定义实际发送请求的能力\n */\nexport interface NetworkAdapter {\n get<T>(\n url: string,\n params?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n post<T>(\n url: string,\n body?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n put?<T>(\n url: string,\n body?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n delete?<T>(\n url: string,\n params?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n patch?<T>(\n url: string,\n body?: any,\n headers?: Record<string, string>\n ): Promise<T>;\n}\n\n/**\n * 网络处理器接口 (Strategy Pattern)\n * 组合了\"匹配规则\"和\"执行能力\"\n */\nexport interface NetworkHandler {\n /** 处理器名称 (用于调试) */\n name?: string;\n\n /** 判断该 URL 是否由此适配器处理 */\n shouldHandle(url: string, method: HttpMethod): boolean;\n\n /** 具体的网络适配器 */\n adapter: NetworkAdapter;\n}\n\n/**\n * 请求链规则 (Chain Step)\n */\nexport interface ChainRequestRule {\n /**\n * 结果存储的键名 (Context Key)\n * Fetch 结果存储: context[key] = response\n */\n key?: string;\n\n /**\n * HTTP 请求详情\n */\n request: HttpRequestSpec;\n\n /**\n * 数据提取选择器\n * 用于从响应中提取特定数据, e.g., \"elements.0\"\n */\n selector?: string;\n\n /** 是否允许请求失败 (默认 false) */\n optional?: boolean;\n\n /**\n * 是否包含上下文\n * 如果为 true,请求 Body 将自动合并当前 Context 和 Payload\n */\n includeContext?: boolean;\n\n /**\n * 上下文筛选列表 (优先级高于 includeContext)\n * 指定需要合并到 Body 中的 Context Key 列表\n * e.g., [\"rawProfile\", \"rawCompany\"]\n */\n pickContext?: string[];\n\n /** 额外 Payload (仅当 includeContext 为 true 或 pickContext 存在时合并) */\n payload?: Record<string, any>;\n}\n\n// ============================================================================\n// Internal Utilities\n// ============================================================================\n\n/**\n * 执行 HTTP 请求\n * 遍历 handlers 数组,找到第一个能处理该 URL 的适配器执行\n *\n * @param spec 请求详情\n * @param handlers 网络处理器链\n */\nasync function executeChainRequest<T>(\n spec: HttpRequestSpec,\n handlers: NetworkHandler[] = []\n): Promise<T | null> {\n // Normalize method to upper case for robustness\n const method = spec.method.toUpperCase() as HttpMethod;\n\n // 1. 遍历处理器数组 (责任链)\n for (const handler of handlers) {\n if (handler.shouldHandle(spec.url, method)) {\n try {\n const { adapter } = handler;\n const headers = spec.headers;\n\n switch (method) {\n case \"GET\":\n return await adapter.get<T>(spec.url, spec.body, headers);\n case \"POST\":\n return await adapter.post<T>(spec.url, spec.body, headers);\n case \"PUT\":\n if (!adapter.put)\n throw new Error(`Adapter ${handler.name} missing PUT method`);\n return await adapter.put<T>(spec.url, spec.body, headers);\n case \"DELETE\":\n if (!adapter.delete)\n throw new Error(`Adapter ${handler.name} missing DELETE method`);\n return await adapter.delete<T>(spec.url, spec.body, headers);\n case \"PATCH\":\n if (!adapter.patch)\n throw new Error(`Adapter ${handler.name} missing PATCH method`);\n return await adapter.patch<T>(spec.url, spec.body, headers);\n default:\n throw new Error(`Unsupported method: ${method}`);\n }\n } catch (err) {\n console.warn(\n `Handler [${handler.name || \"Anonymous\"}] failed for ${spec.url}`,\n err\n );\n // 如果需要继续尝试下一个 handler,可以在这里 continue,但通常由第一个匹配者全权负责\n return null;\n }\n }\n }\n\n // 2. 默认行为 (Fallback): 绝对路径自动走标准 fetch\n if (spec.url.startsWith(\"http://\") || spec.url.startsWith(\"https://\")) {\n return await executeFallbackFetch<T>(spec);\n }\n\n console.warn(`No handler found for url: ${spec.url}`);\n return null;\n}\n\n/**\n * 标准 Fetch 回退实现\n */\nasync function executeFallbackFetch<T>(\n spec: HttpRequestSpec\n): Promise<T | null> {\n try {\n const response = await fetch(spec.url, {\n method: spec.method,\n headers: spec.headers,\n body: spec.body ? JSON.stringify(spec.body) : undefined,\n credentials: \"include\",\n });\n\n if (!response.ok) {\n console.log(`External Request failed: ${response.status} ${spec.url}`);\n return null;\n }\n\n return await response.json();\n } catch (err) {\n console.log(\"External Request error:\", err);\n return null;\n }\n}\n\n/**\n * 根据路径获取对象值\n */\nfunction getByPath(obj: any, path: string): any {\n if (!path) return obj;\n return path.split(\".\").reduce((acc, part) => acc && acc[part], obj);\n}\n\n/**\n * 变量替换 (Internal)\n * 支持字符串 {{key}} 和 {{key.prop}}\n */\nfunction substituteVariables(target: any, context: any): any {\n if (typeof target === \"string\") {\n return target.replace(/\\{\\{([\\w\\.]+)\\}\\}/g, (_, path) => {\n const val = getByPath(context, path);\n return val !== undefined ? String(val) : \"\";\n });\n }\n\n if (Array.isArray(target)) {\n return target.map((item) => substituteVariables(item, context));\n }\n\n if (target && typeof target === \"object\") {\n const result: any = {};\n for (const key in target) {\n result[key] = substituteVariables(target[key], context);\n }\n return result;\n }\n\n return target;\n}\n\n// ============================================================================\n// Main Runner\n// ============================================================================\n\n/**\n * 请求链执行器 (Request Chain Engine)\n * 支持链式请求、上下文累积、智能路由、变量替换\n *\n * @param requests 链式执行规则列表\n * @param handlers 网络适配器处理器列表 (按顺序匹配)\n */\nexport async function executeRequestChain<T>(\n requests: ChainRequestRule[],\n handlers: NetworkHandler[] = [],\n getChainRequests?: (\n context: Record<string, any>\n ) => ChainRequestRule[] | null | undefined,\n initContext?: Record<string, any>\n): Promise<T> {\n const context: Record<string, any> = initContext || {};\n let lastResult: any = null;\n\n for (const rule of requests) {\n try {\n // 1. 准备 Context Data (用于 Submit)\n let contextData: Record<string, any> = {};\n if (rule.pickContext) {\n rule.pickContext.forEach((key) => {\n if (key in context) contextData[key] = context[key];\n });\n } else if (rule.includeContext) {\n contextData = context;\n }\n const hasContextData = Object.keys(contextData).length > 0;\n\n // 2. 准备 Request Spec (合并 Payload 和 Context)\n let requestSpec = { ...rule.request };\n if (hasContextData || rule.payload) {\n requestSpec.body = {\n ...(rule.payload || {}),\n ...contextData,\n ...(requestSpec.body || {}),\n };\n }\n\n // 3. 变量替换\n requestSpec = substituteVariables(requestSpec, context);\n\n // 4. 执行请求 (传入 handlers)\n let rawData = await executeChainRequest<any>(requestSpec, handlers);\n\n if (getChainRequests) {\n const chainRequests = getChainRequests(rawData);\n if (chainRequests && chainRequests.length > 0) {\n rawData = await executeRequestChain(\n chainRequests,\n handlers,\n getChainRequests,\n JSON.parse(JSON.stringify(context))\n );\n }\n }\n\n lastResult = rawData;\n\n if (rawData) {\n // 5. 存储结果\n if (rule.key) {\n const data = rule.selector\n ? getByPath(rawData, rule.selector)\n : rawData;\n context[rule.key] = data;\n }\n } else if (!rule.optional) {\n throw new Error(\n `Failed to fetch required data for key: ${rule.key || \"unknown\"}`\n );\n }\n } catch (err) {\n if (!rule.optional) {\n throw err;\n }\n console.warn(`Optional request failed for rule:`, rule, err);\n }\n }\n\n return lastResult as T;\n}\n","/*eslint-disable block-scoped-var, id-length, no-control-regex, no-magic-numbers, no-prototype-builtins, no-redeclare, no-shadow, no-var, sort-vars*/\nimport * as $protobuf from \"protobufjs/minimal\";\n\n// Common aliases\nconst $Reader = $protobuf.Reader, $Writer = $protobuf.Writer, $util = $protobuf.util;\n\n// Exported root namespace\nconst $root = $protobuf.roots[\"default\"] || ($protobuf.roots[\"default\"] = {});\n\nexport const secure = $root.secure = (() => {\n\n /**\n * Namespace secure.\n * @exports secure\n * @namespace\n */\n const secure = {};\n\n secure.SecurePayload = (function() {\n\n /**\n * Properties of a SecurePayload.\n * @memberof secure\n * @interface ISecurePayload\n * @property {number|Long|null} [ts] SecurePayload ts\n * @property {Uint8Array|null} [data] SecurePayload data\n */\n\n /**\n * Constructs a new SecurePayload.\n * @memberof secure\n * @classdesc Represents a SecurePayload.\n * @implements ISecurePayload\n * @constructor\n * @param {secure.ISecurePayload=} [properties] Properties to set\n */\n function SecurePayload(properties) {\n if (properties)\n for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i)\n if (properties[keys[i]] != null)\n this[keys[i]] = properties[keys[i]];\n }\n\n /**\n * SecurePayload ts.\n * @member {number|Long} ts\n * @memberof secure.SecurePayload\n * @instance\n */\n SecurePayload.prototype.ts = $util.Long ? $util.Long.fromBits(0,0,false) : 0;\n\n /**\n * SecurePayload data.\n * @member {Uint8Array} data\n * @memberof secure.SecurePayload\n * @instance\n */\n SecurePayload.prototype.data = $util.newBuffer([]);\n\n /**\n * Creates a new SecurePayload instance using the specified properties.\n * @function create\n * @memberof secure.SecurePayload\n * @static\n * @param {secure.ISecurePayload=} [properties] Properties to set\n * @returns {secure.SecurePayload} SecurePayload instance\n */\n SecurePayload.create = function create(properties) {\n return new SecurePayload(properties);\n };\n\n /**\n * Encodes the specified SecurePayload message. Does not implicitly {@link secure.SecurePayload.verify|verify} messages.\n * @function encode\n * @memberof secure.SecurePayload\n * @static\n * @param {secure.ISecurePayload} message SecurePayload message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n SecurePayload.encode = function encode(message, writer) {\n if (!writer)\n writer = $Writer.create();\n if (message.ts != null && Object.hasOwnProperty.call(message, \"ts\"))\n writer.uint32(/* id 1, wireType 0 =*/8).int64(message.ts);\n if (message.data != null && Object.hasOwnProperty.call(message, \"data\"))\n writer.uint32(/* id 2, wireType 2 =*/18).bytes(message.data);\n return writer;\n };\n\n /**\n * Encodes the specified SecurePayload message, length delimited. Does not implicitly {@link secure.SecurePayload.verify|verify} messages.\n * @function encodeDelimited\n * @memberof secure.SecurePayload\n * @static\n * @param {secure.ISecurePayload} message SecurePayload message or plain object to encode\n * @param {$protobuf.Writer} [writer] Writer to encode to\n * @returns {$protobuf.Writer} Writer\n */\n SecurePayload.encodeDelimited = function encodeDelimited(message, writer) {\n return this.encode(message, writer).ldelim();\n };\n\n /**\n * Decodes a SecurePayload message from the specified reader or buffer.\n * @function decode\n * @memberof secure.SecurePayload\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @param {number} [length] Message length if known beforehand\n * @returns {secure.SecurePayload} SecurePayload\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n SecurePayload.decode = function decode(reader, length, error) {\n if (!(reader instanceof $Reader))\n reader = $Reader.create(reader);\n let end = length === undefined ? reader.len : reader.pos + length, message = new $root.secure.SecurePayload();\n while (reader.pos < end) {\n let tag = reader.uint32();\n if (tag === error)\n break;\n switch (tag >>> 3) {\n case 1: {\n message.ts = reader.int64();\n break;\n }\n case 2: {\n message.data = reader.bytes();\n break;\n }\n default:\n reader.skipType(tag & 7);\n break;\n }\n }\n return message;\n };\n\n /**\n * Decodes a SecurePayload message from the specified reader or buffer, length delimited.\n * @function decodeDelimited\n * @memberof secure.SecurePayload\n * @static\n * @param {$protobuf.Reader|Uint8Array} reader Reader or buffer to decode from\n * @returns {secure.SecurePayload} SecurePayload\n * @throws {Error} If the payload is not a reader or valid buffer\n * @throws {$protobuf.util.ProtocolError} If required fields are missing\n */\n SecurePayload.decodeDelimited = function decodeDelimited(reader) {\n if (!(reader instanceof $Reader))\n reader = new $Reader(reader);\n return this.decode(reader, reader.uint32());\n };\n\n /**\n * Verifies a SecurePayload message.\n * @function verify\n * @memberof secure.SecurePayload\n * @static\n * @param {Object.<string,*>} message Plain object to verify\n * @returns {string|null} `null` if valid, otherwise the reason why it is not\n */\n SecurePayload.verify = function verify(message) {\n if (typeof message !== \"object\" || message === null)\n return \"object expected\";\n if (message.ts != null && message.hasOwnProperty(\"ts\"))\n if (!$util.isInteger(message.ts) && !(message.ts && $util.isInteger(message.ts.low) && $util.isInteger(message.ts.high)))\n return \"ts: integer|Long expected\";\n if (message.data != null && message.hasOwnProperty(\"data\"))\n if (!(message.data && typeof message.data.length === \"number\" || $util.isString(message.data)))\n return \"data: buffer expected\";\n return null;\n };\n\n /**\n * Creates a SecurePayload message from a plain object. Also converts values to their respective internal types.\n * @function fromObject\n * @memberof secure.SecurePayload\n * @static\n * @param {Object.<string,*>} object Plain object\n * @returns {secure.SecurePayload} SecurePayload\n */\n SecurePayload.fromObject = function fromObject(object) {\n if (object instanceof $root.secure.SecurePayload)\n return object;\n let message = new $root.secure.SecurePayload();\n if (object.ts != null)\n if ($util.Long)\n (message.ts = $util.Long.fromValue(object.ts)).unsigned = false;\n else if (typeof object.ts === \"string\")\n message.ts = parseInt(object.ts, 10);\n else if (typeof object.ts === \"number\")\n message.ts = object.ts;\n else if (typeof object.ts === \"object\")\n message.ts = new $util.LongBits(object.ts.low >>> 0, object.ts.high >>> 0).toNumber();\n if (object.data != null)\n if (typeof object.data === \"string\")\n $util.base64.decode(object.data, message.data = $util.newBuffer($util.base64.length(object.data)), 0);\n else if (object.data.length >= 0)\n message.data = object.data;\n return message;\n };\n\n /**\n * Creates a plain object from a SecurePayload message. Also converts values to other types if specified.\n * @function toObject\n * @memberof secure.SecurePayload\n * @static\n * @param {secure.SecurePayload} message SecurePayload\n * @param {$protobuf.IConversionOptions} [options] Conversion options\n * @returns {Object.<string,*>} Plain object\n */\n SecurePayload.toObject = function toObject(message, options) {\n if (!options)\n options = {};\n let object = {};\n if (options.defaults) {\n if ($util.Long) {\n let long = new $util.Long(0, 0, false);\n object.ts = options.longs === String ? long.toString() : options.longs === Number ? long.toNumber() : long;\n } else\n object.ts = options.longs === String ? \"0\" : 0;\n if (options.bytes === String)\n object.data = \"\";\n else {\n object.data = [];\n if (options.bytes !== Array)\n object.data = $util.newBuffer(object.data);\n }\n }\n if (message.ts != null && message.hasOwnProperty(\"ts\"))\n if (typeof message.ts === \"number\")\n object.ts = options.longs === String ? String(message.ts) : message.ts;\n else\n object.ts = options.longs === String ? $util.Long.prototype.toString.call(message.ts) : options.longs === Number ? new $util.LongBits(message.ts.low >>> 0, message.ts.high >>> 0).toNumber() : message.ts;\n if (message.data != null && message.hasOwnProperty(\"data\"))\n object.data = options.bytes === String ? $util.base64.encode(message.data, 0, message.data.length) : options.bytes === Array ? Array.prototype.slice.call(message.data) : message.data;\n return object;\n };\n\n /**\n * Converts this SecurePayload to JSON.\n * @function toJSON\n * @memberof secure.SecurePayload\n * @instance\n * @returns {Object.<string,*>} JSON object\n */\n SecurePayload.prototype.toJSON = function toJSON() {\n return this.constructor.toObject(this, $protobuf.util.toJSONOptions);\n };\n\n /**\n * Gets the default type url for SecurePayload\n * @function getTypeUrl\n * @memberof secure.SecurePayload\n * @static\n * @param {string} [typeUrlPrefix] your custom typeUrlPrefix(default \"type.googleapis.com\")\n * @returns {string} The default type url\n */\n SecurePayload.getTypeUrl = function getTypeUrl(typeUrlPrefix) {\n if (typeUrlPrefix === undefined) {\n typeUrlPrefix = \"type.googleapis.com\";\n }\n return typeUrlPrefix + \"/secure.SecurePayload\";\n };\n\n return SecurePayload;\n })();\n\n return secure;\n})();\n\nexport { $root as default };\n","/**\n * Protobuf 安全通信模块\n *\n * 提供基于 Protobuf 的二进制序列化、XOR 混淆加密以及与 API Client 的无缝集成。\n */\n\nimport protobuf from \"protobufjs/light\";\nimport { secure } from \"./secure.js\";\nimport type { FetchContext } from \"ofetch\";\n\n// ============================================================================\n// 1. 类型定义 (Types)\n// ============================================================================\n// export type ProtobufTypeLike = Pick<protobuf.Type, \"create\" | \"encode\" | \"decode\" | \"toObject\">;\nexport interface ProtobufTypeLike {\n // 1. 允许 properties 为任何对象,返回结果不再强制要求 $type\n create(properties?: Record<string, any>): any;\n // 2. 借用原生的参数类型约束,但手动简化返回类型\n encode(message: any): { finish(): Uint8Array };\n // 3. 借用原生的 decode 签名(支持 Uint8Array 和 Reader)\n decode(reader: Uint8Array | protobuf.Reader): any;\n // 4. 借用原生的 toObject 签名,保留 IConversionOptions 的类型检查\n toObject(message: any, options?: protobuf.IConversionOptions): any;\n}\n/**\n * 基础编解码配置\n * 控制如何将数据转换为二进制,以及是否混淆\n */\nexport interface ProtobufCodecOptions {\n /** 是否启用二进制 XOR 混淆 (默认 true) */\n obfuscate?: boolean;\n /**\n * 混淆密钥\n * 可以是静态字符串/字节数组,也可以是动态获取密钥的同步或异步函数\n */\n obfuscationKey?:\n | string\n | Uint8Array\n | (() => string | Uint8Array | Promise<string | Uint8Array>);\n /** 预编译的 Protobuf 类型对象 (推荐,性能最高) */\n protoType?: ProtobufTypeLike;\n /** 数据转换钩子:处理业务模型与 Proto 结构不一致的情况 */\n transform?: {\n beforeEncode?: (data: any) => any;\n afterDecode?: (payload: any) => any;\n };\n}\n\n/**\n * 完全自定义编解码接口\n * 用于外部项目完全接管序列化过程,同时复用基础库的混淆外壳\n */\nexport interface ProtobufCustomCodec {\n /** 外部定义的编码逻辑 (返回原始二进制) */\n encode?: (data: any) => Uint8Array | Promise<Uint8Array>;\n /** 外部定义的解码逻辑 (返回原始对象) */\n decode?: <T>(buffer: Uint8Array) => T | Promise<T>;\n}\n\n/**\n * 集成配置项\n * 用于 createProtobufHooks 或 API Client 全局配置\n */\nexport interface ProtobufHooksOptions\n extends ProtobufCodecOptions, ProtobufCustomCodec {}\n\n/**\n * API Client 内部使用的标准化配置\n */\nexport interface ProtobufConfig {\n encode: (data: any) => Uint8Array | Promise<Uint8Array>;\n decode: <T>(buffer: Uint8Array) => T | Promise<T>;\n options?: ProtobufCodecOptions;\n}\n\n// ============================================================================\n// 2. 内部工具函数 (Internal Utilities)\n// ============================================================================\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/** 简单的二进制异或混淆转换 */\nexport function xorTransform(\n data: Uint8Array,\n key: string | Uint8Array,\n): Uint8Array {\n const keyBytes = typeof key === \"string\" ? encoder.encode(key) : key;\n if (keyBytes.length === 0) return data;\n\n for (let i = 0; i < data.length; i++) {\n data[i] ^= keyBytes[i % keyBytes.length];\n }\n return data;\n}\n\n/** 获取混淆密钥(支持异步/函数) */\nexport async function getObfuscationKey(\n keyOption?: ProtobufCodecOptions[\"obfuscationKey\"],\n): Promise<string | Uint8Array> {\n const defaultKey = \"api-client-default-key\";\n if (!keyOption) return defaultKey;\n if (typeof keyOption === \"function\") {\n return await keyOption();\n }\n return keyOption;\n}\n\n/** 获取内置的 SecurePayload 类型(使用预编译代码) */\nfunction getInternalSecureType(): protobuf.Type {\n return secure.SecurePayload as unknown as protobuf.Type;\n}\n\n// ============================================================================\n// 3. 核心编解码逻辑 (Core Codecs)\n// ============================================================================\n\n/**\n * 编码安全载荷\n *\n * 流程:业务数据 -> (自定义编码 / Proto 序列化) -> 二进制混淆\n */\nexport async function encodeSecure<T>(\n data: T,\n options: ProtobufHooksOptions = {},\n): Promise<Uint8Array> {\n const {\n obfuscate = true,\n obfuscationKey,\n protoType,\n transform,\n encode: customEncode,\n } = options;\n\n let buffer: Uint8Array;\n\n // 1. 预处理阶段:无论后续走哪条路径,只要定义了 beforeEncode 就先执行\n const processedData = transform?.beforeEncode\n ? transform.beforeEncode(data)\n : data;\n\n // 1. 序列化阶段\n if (customEncode) {\n buffer = await customEncode(processedData);\n } else {\n const type = protoType || getInternalSecureType();\n\n // 构造最终要交给 Protobuf 序列化的对象\n const payload = protoType\n ? processedData // 自定义模式:直接使用预处理后的数据\n : {\n // 默认容器模式:将预处理后的数据封装进信封\n ts: Date.now(),\n data:\n processedData instanceof Uint8Array\n ? processedData\n : encoder.encode(JSON.stringify(processedData)),\n };\n\n const message = type.create(payload);\n buffer = type.encode(message).finish();\n }\n\n // 2. 混淆阶段\n if (!obfuscate) return buffer;\n const finalKey = await getObfuscationKey(obfuscationKey);\n return xorTransform(buffer, finalKey);\n}\n\n/**\n * 解码安全载荷\n *\n * 流程:二进制流 -> 二进制反混淆 -> (自定义解码 / Proto 反序列化) -> 业务数据\n */\nexport async function decodeSecure<T>(\n buffer: Uint8Array | ArrayBuffer,\n options: ProtobufHooksOptions = {},\n): Promise<T> {\n const {\n obfuscate = true,\n obfuscationKey,\n protoType,\n transform,\n decode: customDecode,\n } = options;\n\n // let uint8 = buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : buffer;\n // let uint8 =\n // buffer instanceof ArrayBuffer\n // ? new Uint8Array(buffer)\n // : new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n\n // 1. 标准化为 Uint8Array 视图 (跨环境最稳写法)\n let uint8 = ArrayBuffer.isView(buffer)\n ? new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength)\n : new Uint8Array(buffer);\n\n // 1. 反混淆阶段\n if (uint8.length > 0 && obfuscate) {\n const finalKey = await getObfuscationKey(obfuscationKey);\n uint8 = xorTransform(uint8, finalKey);\n }\n\n // 2. 反序列化阶段\n if (customDecode) {\n return await customDecode<T>(uint8);\n }\n\n const type = protoType || getInternalSecureType();\n const decoded = type.decode(uint8);\n const plainObj = type.toObject(decoded, {\n longs: String,\n enums: String,\n bytes: Uint8Array as any,\n defaults: true,\n });\n\n // 3. 转换阶段\n if (transform?.afterDecode) {\n return transform.afterDecode(plainObj);\n }\n\n // 内置容器模式的额外还原逻辑\n if (!protoType && plainObj.data) {\n const jsonString = decoder.decode(plainObj.data as Uint8Array);\n try {\n return JSON.parse(jsonString) as T;\n } catch {\n return jsonString as unknown as T;\n }\n }\n\n return plainObj as T;\n}\n\n// ============================================================================\n// 4. HTTP/环境适配工具 (HTTP Tools)\n// ============================================================================\n\n/** 创建安全响应 (Worker/Server 端使用) */\nexport async function secureResponse<T>(\n data: T,\n options?: ProtobufCodecOptions & { corsHeaders?: Record<string, string> },\n): Promise<Response> {\n const buffer = await encodeSecure(data, options);\n // const arrayBuffer = buffer.buffer.slice(\n // buffer.byteOffset,\n // buffer.byteOffset + buffer.byteLength,\n // ) as ArrayBuffer;\n const cleanBuffer = buffer.slice();\n\n return new Response(cleanBuffer, {\n headers: {\n \"Content-Type\": \"application/x-protobuf\",\n ...options?.corsHeaders,\n },\n });\n}\n\n/** 解析安全请求体 (Worker/Server 端使用) */\nexport async function parseSecureRequest<T>(\n request: Request,\n customDecode?: ProtobufCustomCodec[\"decode\"],\n): Promise<T> {\n const buffer = await request.arrayBuffer();\n return decodeSecure<T>(buffer, { decode: customDecode });\n}\n\n/** 检查是否为 Protobuf 响应头 */\nexport function isProtobufContentType(contentType: string | null): boolean {\n return !!contentType?.includes(\"application/x-protobuf\");\n}\n\n/** 标准化配置对象 */\nexport function normalizeProtobufConfig(\n config: boolean | ProtobufConfig | undefined,\n options?: ProtobufHooksOptions, // 接收全局配置\n): ProtobufConfig | null {\n if (!config) return null;\n if (config === true) {\n return {\n encode: (data) => encodeSecure(data, options),\n decode: <T>(buffer: Uint8Array) => decodeSecure<T>(buffer, options),\n };\n }\n return config;\n}\n\n// ============================================================================\n// 5. API Client 钩子逻辑 (Integration Hooks)\n// ============================================================================\n\n/** 创建 Protobuf 编解码钩子 (用于与 createApiClient 配合使用) */\nexport function createProtobufHooks(options: ProtobufHooksOptions = {}) {\n const encode = (data: any) => encodeSecure(data, options);\n const decode = <T>(buffer: Uint8Array) => decodeSecure<T>(buffer, options);\n\n return {\n async onRequest(context: FetchContext) {\n const { options: reqOptions } = context;\n const headers =\n reqOptions.headers instanceof Headers\n ? reqOptions.headers\n : new Headers(reqOptions.headers as HeadersInit | undefined);\n\n // 自动编码请求体\n if (\n isProtobufContentType(headers.get(\"Content-Type\")) &&\n reqOptions.body &&\n !(reqOptions.body instanceof Uint8Array)\n ) {\n reqOptions.body = await encode(reqOptions.body);\n }\n\n // 自动设置期望响应类型\n if (\n isProtobufContentType(headers.get(\"Accept\")) &&\n !reqOptions.responseType\n ) {\n reqOptions.responseType = \"arrayBuffer\";\n }\n\n reqOptions.headers = headers;\n },\n\n async onResponse(context: FetchContext) {\n const { response } = context;\n if (!response?._data || response.status === 204) return;\n\n if (isProtobufContentType(response.headers.get(\"Content-Type\"))) {\n try {\n // 这里的 _data 可能是 ArrayBuffer (浏览器) 或 Buffer (Node)\n // decodeSecure 内部已处理好兼容性\n response._data = await decode(response._data);\n // const buffer = response._data as ArrayBuffer;\n // if (buffer && buffer.byteLength > 0) {\n // response._data = await decode(new Uint8Array(buffer));\n // }\n } catch (e) {\n console.log(\"Error [Protobuf Decode Error]\", e);\n response._data = null;\n }\n } else if (response._data instanceof ArrayBuffer) {\n const text = decoder.decode(response._data);\n try {\n response._data = JSON.parse(text);\n } catch {\n response._data = text;\n }\n }\n },\n };\n}\n"],"mappings":"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","names":["options","secure"]}
|