UNPKG

rapplus

Version:
236 lines (206 loc) 7.09 kB
[![MIT License][license-shield]][license-url] ## Rapper 是什么? Rapper 是 TypeScript 的最佳拍档,它可以帮你生成具有类型定义的请求方案。 - 无需自行书写请求代码,把 HTTP 接口当做函数调用 - 请求参数/返回数据类型化,静态校验、自动补全快到飞起 ## RapperPlus 是什么? 基于 Rapper 开发,使配置更灵活,同时增加本地类型同步远程文档重要功能 - ++++ - 本地接口类型上传到rapper远程文档,本地编码驱动远程文档 - 自定义请求函数模板,满足不同编程规范 ## 快速开始 上传 34xx 模块 接口 ```bash $ npx rapper-plus --u --m 34xx ``` 上下载 34xx 模块 接口 ```bash $ npx rapper-plus --d --m 34xx ``` ## 文档 ### 命令函入参会和config合并(命令行优先级更高) * --u 上传 * --d 下载 * --m xx 指定moduleId,不传默认全部 ### RapperPlus 配置config 有三种方案 * 方案一(推荐) 通过rapperPlus.config.js配置config ```js <!-- rapperPlus.config.js文件 --> const RapperPlus = require('rapper-plus') <!-- 使用RapperPlus 提供 defineConfig 会有类型提示 --> export.default = RapperPlus.defineConfig({ upload: { xx: xx }, // 本地上传 配置 download: { xx: xx } // 远程下载 配置 }) ``` * 方案二 通过 命令行参数执行config 路径 ```bash $ npx rapper-plus --config ./config/index.js ``` ```js <!-- ./config/index.js文件 --> const RapperPlus = require('rapper-plus') <!-- 使用RapperPlus 提供 defineConfig 会有类型提示 --> export.default = RapperPlus.defineConfig({ upload: { xx: xx }, // 本地上传 配置 download: { xx: xx } // 远程下载 配置 }) ``` * 方案三 通过 package.json 配置 rapper-Plus ```js <!--package.json 文件 --> { 'rapper-Plus': { upload: { xx: xx }, // 本地上传 配置 download: { xx: xx } // 远程下载 配置 } } ``` ## 本地代码类型同步到远程raper文档 * 解析本地文件 * fetch 方法追加注释 (接口id 接口模块id) * 格式化 类型 * 调用rapper 接口 ## 增量更新实现 * 每次更新会给文件头部 加一个 MD5值 * 初始化会检查合法的文件(符合formatFunc 结构的文件) MD5值 对不住 * 去解析当前恩建以及 依赖当前文件的文件 * 提交变更的模块接口(文件级检查),做不到方法级检查 ## config 接口类型 ```ts interface IConfig { download: { requestFunc?: (params: { funcDescription: string; repositoryId: number; moduleId: number; interfaceId: number; requestUrl: string; requestMethod: string; rapUrl: string; }) => { reqTypeName: string; resTypeName: string; funcMain: string }; requestModule?: (params: { repositoryId: number; moduleId: number; moduleRapUrl: string; moduleDescription: string }) => { fileName: string; moduleHeader: string; }; moduleId?: number; } rapper: { // 拉取接口地址 apiUrl?: string; /** rap 前端地址,默认是 http://rap2.taobao.org */ rapUrl?: string; matchDir?: string; tokenCookie?:string; repositoryId?: number, }, upload: { formatFunc?: (params: IFuncInfo) => ITypeName; moduleId?: number; alias?: Record<string, string>; } __completion?: boolean } export type IOptions = Partial<IConfig> ``` ## defaultConfig 会和传进来的config合并补全 ```js const defaultOptions = { download: { //请求 function 模板 requestFunc(params) { function getFnName(url: string): null | string { const fnName = url.match(/\/([.a-z0-9_-]+)\/([a-z0-9_-]+$)/i); if (fnName && fnName.length === 3) { if (/^\d+\.\d+$/.test(fnName[1])) { return fnName[2]; } return fnName[1] + fnName[2].charAt(0).toUpperCase() + fnName[2].slice(1); } return null; } const fnName = getFnName(params.requestUrl); if (!fnName) { throw new TypeError('接口路径不对,请修改合规'); } const camelCaseName = `${fnName.charAt(0).toUpperCase()}${fnName.slice(1)}`; const paramsType = `IReq${camelCaseName}`; const returnType = `IRes${camelCaseName}`; return { paramsType, returnType, funcMain: ` /** * 接口名:${params.funcDescription} * Rap 地址: ${params.rapUrl}?id=${params.repositoryId}&mod=${params.moduleId}&itf=${params.interfaceId} */ export const ${fnName} = <T extends boolean = false>( data: ${paramsType}, options?: { proxy?: T pageError?: boolean } ): Promise<IResType<T, ${returnType}>> => { return instance( { url: '${params.requestUrl}', method: '${params.requestMethod}', data, }, options ) as Promise<any> } `, }; }, //请求 函数共工头(用于引入函数 requestModule(params) { return { fileName: params.moduleDescription, moduleHeader: ` import instance from '@/utils/request' type IResType<T extends boolean, U extends {data: any}> = T extends true ? U['data'] : U `, }; }, rap: { apiUrl: 'http://rap2api.taobao.org/repository/get?id=284428&token=TTDNJ7gvXgy9R-9axC-7_mbi4ZxEPlp6', /** rap 前端地址,默认是 http://rap2.taobao.org */ rapUrl: 'http://rap2.taobao.org', rapperPath: './src/actions', }, }, upload: { // 根据函数信息 过滤出 有用信息 formatFunc(params) { return { returnType: params.returnType.match(/T,\s*(\w+)>>$/)[1], paramsType: params.paramsType[0].data, fetchUrl: params.comment.match(/http:\/\/rap2\.tao[\s\S]+&itf=\d+/)[0], }; }, // webpack 别名 alias 绝对路径 alias: { '@': './src', }, // 上传 token tokenCookie: 'aliyungf_tc=ed5eefe153b8cd6d7a9b0ea3f4aaaa92eaf022825c19857a2b435978264d17d8; koa.sid=MzB5TnJaGWkQK6DL7MAFt_qp18DfQ41Q; koa.sid.sig=ujNSfud5538kuHWTx0zYRHXnDSU', //会递归遍历啊所有附和 当前文件的 文件 matchDir: './src/actions', } } ```