npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

rapplus

v1.2.2

Published

rapper, use http api as a function

Downloads

23

Readme

[![MIT License][license-shield]][license-url]

Rapper 是什么?

Rapper 是 TypeScript 的最佳拍档,它可以帮你生成具有类型定义的请求方案。

  • 无需自行书写请求代码,把 HTTP 接口当做函数调用
  • 请求参数/返回数据类型化,静态校验、自动补全快到飞起

RapperPlus 是什么?

基于 Rapper 开发,使配置更灵活,同时增加本地类型同步远程文档重要功能

  • ++++
  • 本地接口类型上传到rapper远程文档,本地编码驱动远程文档
  • 自定义请求函数模板,满足不同编程规范

快速开始

上传 34xx 模块 接口

$ npx rapper-plus --u --m 34xx

上下载 34xx 模块 接口

$ npx rapper-plus --d --m 34xx

文档

命令函入参会和config合并(命令行优先级更高)

  • --u 上传
  • --d 下载
  • --m xx 指定moduleId,不传默认全部

RapperPlus 配置config 有三种方案

  • 方案一(推荐)

    通过rapperPlus.config.js配置config

    <!-- rapperPlus.config.js文件 -->
    const RapperPlus = require('rapper-plus')
    <!--  使用RapperPlus 提供 defineConfig 会有类型提示 -->
    export.default = RapperPlus.defineConfig({
      upload: { xx: xx }, // 本地上传 配置
      download: { xx: xx } // 远程下载 配置
    })
  • 方案二 通过 命令行参数执行config 路径

      $ npx rapper-plus --config  ./config/index.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

    <!--package.json  文件  -->
    {
      'rapper-Plus': {
        upload: { xx: xx }, // 本地上传 配置
        download: { xx: xx } // 远程下载 配置
      }
    }

本地代码类型同步到远程raper文档

  • 解析本地文件
  • fetch 方法追加注释 (接口id 接口模块id)
  • 格式化 类型
  • 调用rapper 接口

增量更新实现

  • 每次更新会给文件头部 加一个 MD5值
  • 初始化会检查合法的文件(符合formatFunc 结构的文件) MD5值 对不住
  • 去解析当前恩建以及 依赖当前文件的文件
  • 提交变更的模块接口(文件级检查),做不到方法级检查

config 接口类型


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合并补全

    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',
      }
    }
    ```