t-comm
Version:
专业、稳定、纯粹的工具库
207 lines (206 loc) • 8.16 kB
TypeScript
import { type EnvDomainMap, type IEnvSwitcher } from '../env';
import { NetworkEngine } from './engine';
import { type ICocosFangshuaCrypto } from './interceptors/request/cocos-fangshua-interceptor';
import { type IAegisReportInfo } from './interceptors/response/aegis-report-interceptor';
import type { ICocosLoginInfoStorage, IResponseInterceptorParam, LoginInfo } from './types';
/** aegisReport 选项:透传到 AegisReportInterceptor */
export interface IAegisReportOption {
/**
* 业务注入的上报回调。
*
* 形如:
* ```ts
* aegisReport: {
* report: (info) => aegis.infoAll({
* msg: `${info.method} ${info.url} ret=${info.ret} dur=${info.duration}ms`,
* ext1: info.requestBody,
* ext2: info.responseData,
* ext3: `${info.status} | ${info.responseHeader}`,
* duration: info.duration,
* }),
* truncateSize: 1000,
* }
* ```
*/
report: (info: IAegisReportInfo) => void;
/**
* 单项 JSON 序列化后最大字符数,默认 1000。<=0 不截断。
* 超过会在末尾追加 `...(truncated, total N)` 标记。
*/
truncateSize?: number;
}
export interface IInitCocosNetworkOptions {
/**
* 多环境域名配置(必填,breaking change)。
*
* 例:
* ```ts
* network: {
* svrdomain: {
* test: 'atest.igame.qq.com',
* prod: 'igame.qq.com',
* },
* }
* ```
* 域名不要带协议,也不要带末尾斜杠。
*/
network: {
svrdomain: EnvDomainMap;
};
/**
* 登录接口路径(必填,breaking change)。
* 内部会拼接为 `https://{svrdomain[env]}{loginPath}`。
* 例如 '/v2/login/code'。
*/
loginPath?: string;
/**
* 登录接口路径
* 优先级更高,防止 loginPath 的 domain 与 network.svrdomain 不一致
* 如 https://atest.igame.qq.com/pmdtrpc.commcgi.user.user/QueryUserInfo
*/
loginUrl?: string;
/**
* 环境持久化存储 key,默认 'pmd_api_cocos_env'。
*/
envStorageKey?: string;
/**
* 切换环境后是否自动重启(restartMiniProgram / location.reload),默认 true。
*/
envAutoRestart?: boolean;
/**
* 全局调试函数名(挂到 globalThis 上)。
* - 默认 '__pmdSetEnv__' / '__pmdGetEnv__'
* - 传 false 可关闭挂载
*/
globalSetEnvName?: string | false;
globalGetEnvName?: string | false;
/** 小游戏 appid(必填) */
appid: string;
/** 登录平台类型,默认 3(微信小游戏) */
platform?: number;
/** 登录类型 _ltype,默认 tiploginwxproc */
ltype?: string;
/**
* 登录态存储(可选)
* 默认使用 Cocos 的 `sys.localStorage`(getItem/setItem/removeItem)封装,
* 业务如需自定义(如真机用 wx.getStorageSync)可自行传入。
*/
storage?: ICocosLoginInfoStorage;
/** 存储 key,默认 cocos_login_info */
storageKey?: string;
/**
* 无登录态时获取 wx.code 的方法(可选)
* 默认使用 `wx.login`;在 `wx` 不存在的环境下返回空 code。
*/
getLoginCode?: () => Promise<{
code: string;
}>;
/** loginInfo 更新回调(可选,便于业务侧刷新 UI 或同步到 AuthService 等) */
onLoginInfo?: (info: LoginInfo) => void;
/**
* 「访问被拒」回调(可选,强烈推荐注入)
*
* 触发时机:后端返回 `r=100006`(ACCESS_DENIED_RET)时由 `NormalizeResponseRetInterceptor` 调用。
* 常见场景:测试环境白名单 / 黑名单 / 风控等。
*
* 框架层会同时把响应 `msg` 置空(避免兜底 toast 抢先弹),由业务方决定后续动作:
* - 打开 H5 申请页(推荐,通过 `wx.openUrl` / `wx.navigateTo` 等)
* - 弹 `wx.showModal` 告知用户
* - 直接 `wx.restartMiniProgram()` 重启小游戏
*
* 实现要求:
* - 可同步可异步;框架层不阻塞响应链
* - 内部异常由框架 try/catch 兜住,不会影响业务方后续业务流
* - **不要在这里再次 throw 出 ret=100006**,上层(AccountService / PlayerService 等)
* 仍会按正常失败路径派发 `LoginFail` 等事件,由业务方在 `catch` 中识别
* `r === 100006` 后跳过对应的「切号失败 / 网络异常」toast
*/
onAccessDenied?: (info: IResponseInterceptorParam) => void | Promise<void>;
/**
* 防刷配置(可选)
* 传入后会在请求拦截器链末尾自动加上防刷签名拦截器。
* 需要业务方提前调用 GetTs 接口获取加密参数。
*/
fangshua?: {
/** 获取防刷时间戳(后台 GetTs 接口返回的 ts) */
getTs: () => string | undefined;
/** 获取防刷加密数据(后台 GetTs 接口返回的 encryptData) */
getEncryptData: () => string | undefined;
/** 加密能力注入(MD5 + AES 解密),业务方基于 crypto-js 实现 */
crypto: ICocosFangshuaCrypto;
};
/**
* 接入 aegis(伽利略)监控:自动把每个请求的 url / method / 请求体 / 响应 data / 响应 header / 耗时
* 上报到注入的回调。
*
* 接入后框架层会:
* 1. 在请求拦截器链最前加 `AegisStartTimeInterceptor`(打点)
* 2. 在响应拦截器链 NormalizeResponseRet 之后、GetData 之前加 `AegisReportInterceptor`
*
* 注意:
* - 上报是**附加**行为,不会影响主响应链;回调内部异常被框架吞掉
* - 响应 data / header 都会做 JSON 序列化 + 截断(默认 1000 字符),避免 aegis 单条日志过大
* - doRequest 网络层失败(wx.request fail)**不会**进响应拦截器,需要业务自己再补一层;
* 本接口当前只覆盖 HTTP 拿到响应的情况
*
* @example
* ```ts
* aegisReport: {
* report: (info) => {
* aegis.infoAll({
* msg: `${info.method} ${info.url} ret=${info.ret} dur=${info.duration}ms`,
* ext1: info.requestBody,
* ext2: info.responseData,
* ext3: `${info.status} | ${info.responseHeader}`,
* duration: info.duration,
* });
* },
* }
* ```
*/
aegisReport?: IAegisReportOption;
}
/**
* 一键初始化 Cocos 微信小游戏网络层
*
* 等价于 pmd-npm `business/src/network-v2/application/cocos/index-mp.ts`
* 的 initNetworkManager,但适配到本包自带的 NetworkManager 和 wx.request。
*
* 调用一次后,所有通过 pmd-api-cocos 的 NetworkManager 发出的请求
* 都会:
* - 自动拼 baseUrl + host
* - 无登录态时带 code → 触发后台换登录态
* - 有登录态时 body.login_info + cookie 透传
* - 响应 header logininfo 自动入库
* - ret=100000 自动清态重试一次
*
* 使用示例(见 README):
* ```ts
* import { initCocosNetwork } from '@tencent/pmd-api-cocos/network';
*
* initCocosNetwork({
* network: {
* svrdomain: {
* test: 'atest.igame.qq.com',
* prod: 'igame.qq.com',
* },
* },
* loginPath: '/v2/login/code',
* appid: 'wx14f5bb5ae9a067f8',
* // storage / getLoginCode 可不传,默认走 sys.localStorage + wx.login
* onLoginInfo: (info) => {
* // 可选:同步到 AuthService / 刷新 UI 等
* },
* });
*
* // 控制台可执行(微信小游戏 / 开发者工具):
* wx.__pmdSetEnv__('prod') // → 切到正式环境并自动重启
* wx.__pmdSetEnv__('test') // → 切回测试环境
* wx.__pmdGetEnv__() // → 查看当前环境
* // (非微信环境会回退挂到 globalThis 上)
* ```
*/
export declare function initCocosNetwork(options: IInitCocosNetworkOptions): NetworkEngine & {
envSwitcher: IEnvSwitcher;
};
export type { ICocosLoginInfoStorage, LoginInfo };