UNPKG

t-comm

Version:

专业、稳定、纯粹的工具库

207 lines (206 loc) 8.16 kB
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 };