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

proto2tsapi

v1.1.8

Published

Convert proto file to api file

Downloads

17

Readme

用于把 proto 文件转换成 Typescript 的 api 文件

  1. 先把需要转换的 proto 文件确定好
  2. 依次遍历 proto 文件,然后转换成 ts 文件

注意事项:目前仅支持单个 proto 文件内存在单个 service,如单个 proto 文件存在多个 service,输出的 service 名称将会是最后一个 service 的名称

基于proto2api修改的 npm 包,在 proto2api 基础上拆分类型文件和 api 文件,将格式修改为自己需要的内容。

新版本特性

2024-03-14 v1.1.8: 更新了 config 文件对 depPath 和 protoDir 的支持

{
  "files": {
    ...
  },
  "output": "./src/api",
  "ignore": "google|swagger",
  "protoDir": "./proto/", // 设置读取proto的根路径
  "depPath": "./proto/" // 设置读取proto时依赖包的路径
}

2023-10-13 v1.1.7:customVariate 新增了文件名入参

interface ICustomVariateParams {
  name: string;
  comment?: string;
  url: string;
  redirectUrl?: string;
  method: "get" | "post" | "put" | "patch" | "delete";
  res: string;
  req: string;
  pkgName: string;
  srvName: string;
  fileName: string; // new!
}

const METHOD_NAME = (params: ICustomVariateParams) => {
  const { pkgName, srvName, name, fileName } = params;
  return `${fileName}/${pkgName}.${srvName}/${name}`;
};
module.exports = { METHOD_NAME };

2023-10-09 v1.1.6:修复互相依赖情况下的报错导致的中断

2023-7-28 v1.1.5:导出的 apiName 会自动带/

2023-7-28 v1.1.4:新增 excel 导出 API 的功能,如有需要请配置 config.expApiPath 路径


{
  "files": {
    "./": [
      "example.proto"
    ]
  },
  ...
  "expApiPath":"./apiExport/apiExport.xlsx",
  ...
}

2023-3-10 v1.1.3:删除多余的 console.log

2023-3-10 v1.1.2:

  1. 更改了 enum 的转换方式,现在能正常转换成对应的数值,支持 proto 内断连的 enum 数值了。参考如下:
// 现在默认不会转换成旧版本的字符串值了,如有需要请在配置文件内设置 transEnum2String:true
export enum YesOrNo {
  // 否
  No = 0,
  // 是
  Yes = 1,
}

export enum Status {
  // 草稿
  Draft = 0,
  // 已完成
  Done = 3,
  // 未提交
  Todo = 4,
}
  1. 新增了自定义变量的功能,现在可以通过自定义变量插入模板代码中的任意部位。注意!!!模板代码使用自定义变量时需以$符号开始和结尾。 参考如下:
// proto2tsapi.json 在配置文件内新增了customVariate配置,接收自定义变量的文件路径
{
  "files": {
    "./": [
      "example.proto"
    ]
  },
  "output": "./src/api/example",
  "ignore": "google|swagger",
  "FORMAT_URL_METHOD": "./formatUrlMethod.ts", // 此变量依然保留,以兼容旧版本
  "customVariate": "./customVariate.ts", // 现在可以通过使用自定义变量来实现FORMAT_URL_METHOD的功能
  "transEnum2String":false, // 如需转换成key值字符串的enum请设置成true
  "defaultTemplate": [
    "$COMMENT",
    "export const $API_NAME = ($REQ_KEY: Types.$REQ_TYPE) => {",
    "return request<RspStructure<Types.$RSP_TYPE>>({",
    "url:'$FORMAT_URL_METHOD',",
    "method: '$API_METHOD',",
    "$REQ_KEY,",
    "} as AxiosConfig<Types.$REQ_TYPE, Types.$REQ_TYPE>);",
    "};"
    "// $METHOD_NAME1$" // 使用自定义变量请以$开头和结尾,根据下面的文件内容配置,这里的结果会转换成 // 13
  ],
  ...
}
// customVariate.ts 新增的[自定义变量格式化函数]文件内

interface ApiFunction {
  name: string;
  comment?: string;
  req: PropertyType;
  url: string;
  redirectUrl?: string;
  res: PropertyType;
  method: "get" | "post" | "put" | "patch" | "delete";
}

interface ICustomVariateParams extends Omit<ApiFunction, "req" | "res"> {
  res: string;
  req: string;
  pkgName: string;
  srvName: string;
}
interface ICustomVariate {
  [k: string]: (parms: ICustomVariateParams) => string;
}

const METHOD_NAME = (p: ICustomVariate) => {
  return p.req;
};
const METHOD_NAME1 = () => {
  return "13";
};
const request = () => {
  return "6666";
};

// 自定义变量名可以自己取,但是建议与模板内其他变量和代码段字符区分开来,推荐全大写的下划线写法

module.exports = { METHOD_NAME, METHOD_NAME1, request };

2022-11-29 v1.1.1:

  1. 修复了 customTemplate 和 templateConfig 匹配不上的问题,现在可以正常使用 customTemplate 了。

2022-9-02 v1.1.0:

  1. 新增了 printRoot 配置项,值为 Boolean,可在项目根目录输出解析 proto 文件生成的 root 对象的 json 文件,非必填;

  2. 新增了预处理规则,pretreatRules 配置项,可用于替换 proto 文件内的部分内容,解决一些不兼容的语法问题

  3. 新增了 proto3 中配置了 validate 规则的类型输出支持,现在可以在配置了 validate 规则的 proto 文件中区分是否必填项;※默认所有字段均为可选※,只有配置了 validate 选项的字段会输出必填项的类型;参考如下:

    config 文件:

 "pretreatRules": { // 用于替换proto文件内的部分匹配内容,如配置了此项,会使用此项规则修改后的proto文件进行转换;不会修改原proto文件; 非必填项
        "./proto/example/example.proto": [  // key名是配置的路径,可配置多个规则,均会应用到该文件上
            {
                "searchValue": "{ in: [ \\\"未处理\\\", \\\"已处理\\\" ] }",  // 被替代的内容,注意:此内容是匹配JSON.stringify后的文本信息,按照json的规则,对特殊的符号匹配需进行转义,例如 "" 和 \ 等等;
                "replaceValue": "0"  // 需要替换成的内容
            }
        ],
     	"./proto/hello.proto":[] // 可为多个文件配置多个规则
    }

proto 文件:

import "validate.proto";

message Example {
    uint64 id       	 = 1; // 这种默认会转换成可选项的类型
    string username      = 1 [(validate.rules).string.min_len = 2]; // 这种配置了validate.rules的会转换成必填项的类型
    string status        = 4 [(validate.rules).string = { in: [ "未处理", "已处理" ] }]; // 这种配合插件使用的情况无法解析,会报错,需配合新增的pretreatRules配置使用
}

转换后的 types 文件:

export interface Example {
  todo_id?: string;
  username: string;
  status: string; // 需配置pretreatRules解决语法问题,否则会报错,后面的内容都不会被转换
}

2022-8-31 v1.0.6:

  1. 修复了生产多个文件的 api 时,$API_URL变量中自动拼接的serviceName只为最后一个的bug,现在已废弃$API_URL 变量;
  2. 新增了$PKG_NAME和$SRV_NAME 两个变量,用于在 FORMAT_URL_METHOD 的格式化函数中使用
  3. 修复了配置 files 里的*全选项时,默认生成根目录下所有 proto 文件的 bug,现在能正常按 files 配置里的文件夹路径单个文件夹生效了
  4. 修复了部分非必填配置项如不存在仍然报错的 bug,修复的配置项如下:REQ_KEY、templateConfig、customTemplate

快速开始

npm install -g proto2tsapi

cd proto2api

proto2tsapi -c examples/config.json

命令行说明

Usage: proto2tsapi [options]

Convert proto file to api file

Options:
Options:
  -V, --version         output the version number
  --debug               load code with ts-node for debug
  -c, --config <path>   config.json path
  --depPath <type>      the address of the external dependency proto library.
                        eq: /common/proto3 (default: "")
  -h, --help            display help for command

配置文件

参考配置项如下

{
  "files": {
    // 此处配置需转换的proto文件的路径,key是路径,value是文件名的数组集合;**必填项**
    "./proto/examples": ["hello.proto"],
    "./proto": [
      "*" // 如果数组的首项是 * ,则会转换该文件夹下的所有proto文件
    ]
  },
  "output": "./dist", // 输出文件的路径; **必填项**
  "printRoot": false, // 可在项目根目录输出解析proto文件生成的root对象的json文件; 非必填
  "ignore": "google|swagger", // proto文件可被忽略的部分,例如"google|swagger" , 可参考proto2api; 非必填
  "FORMAT_URL_METHOD": "./formatUrlMethod.ts", // 配置格式化函数的文件路径,需返回字符串;非必填
  "REQ_KEY": {
    // 配置不同请求方式下,请求参数的key名,将会作为变量用在生成api代码的片段上;默认值为data; 非必填
    "get": "params",
    "post": "data",
    "put": "put",
    "delete": "del"
  },
  "templateConfig": {
    // 配置接口与代码片段模板的对应关系,非必填;通过这个可以配置不同接口使用不同模板生成
    "pageLoading": [
      "hello/GetGame" // 匹配规则是 `${文件名}/${service里的rpc方法名}`
    ],
    "unPageLoading": ["hello/BatchGetGame"]
  },
  "defaultTemplate": [
    // 默认代码片段的模板; **必填项**
    "$COMMENT",
    "export const $API_NAME = ($REQ_KEY: $REQ_TYPE) => {",
    "return request<ResponseStructure<$RSP_TYPE>>({",
    "url:'$FORMAT_URL_METHOD',",
    "method: '$API_METHOD',",
    "$REQ_KEY,",
    "} as AxiosConfig<$REQ_TYPE, $REQ_TYPE>);",
    "};"
  ],
  "customTemplate": {
    // 自定义不同代码片段的模板,非必填; 需搭配templateConfig项使用
    "pageLoading": [
      "$COMMENT",
      "export const $API_NAME = ($REQ_KEY: $REQ_TYPE) => {",
      "return request<ResponseStructure<$RSP_TYPE>>({",
      "url:'$PKG_NAME.$SRV_NAME/$API_NAME',",
      "method: '$API_METHOD',",
      "$REQ_KEY,",
      "pageLoading:'pageLoading'",
      "} as AxiosConfig<$REQ_TYPE, $REQ_TYPE>);",
      "};"
    ],
    "unPageLoading": [
      "$COMMENT",
      "export const $API_NAME = ($REQ_KEY: $REQ_TYPE) => {",
      "return request<ResponseStructure<$RSP_TYPE>>({",
      "url:'$PKG_NAME.$SRV_NAME/$API_NAME',",
      "method: '$API_METHOD',",
      "$REQ_KEY,",
      "pageLoading:'none'",
      "} as AxiosConfig<$REQ_TYPE, $REQ_TYPE>);",
      "};"
    ]
  },
  "importTemplate": [
    // 导入依赖相关的代码片段模板,可根据自己需求定义,非必填
    "import * as Types from './types';",
    "const { request } = useAxios();"
  ],
  "pretreatRules": {
    // 用于替换proto文件内的部分匹配内容,如配置了此项,会使用此项规则修改后的proto文件进行转换;不会修改原proto文件; 非必填项
    "./proto/example/example.proto": [
      // key名是配置的路径,可配置多个规则,均会应用到该文件上
      {
        "searchValue": "{ in: [ \\\"未处理\\\", \\\"已处理\\\" ] }", // 被替代的内容,注意:此内容是匹配JSON.stringify后的文本信息,按照json的规则,对特殊的符号匹配需进行转义,例如 "" 和 \ 等等;
        "replaceValue": "0" // 需要替换成的内容
      }
    ],
    "./proto/hello.proto": [] // 可为多个文件配置多个规则
  },
  "printRoot": false // 可在项目根目录输出解析proto文件生成的root对象的json文件,调试用,非必填;
}

代码片段变量说明

"$COMMENT": proto文件的注释,
"$API_NAME": proto文件的api名称,
"$REQ_KEY": 不同请求方式下,请求参数的key名; 默认值是:'data',
"$REQ_TYPE": proto文件的请求参数类型,
"$RSP_TYPE": proto文件的相应数据类型,
"$PKG_NAME": proto文件的package名称,
"$SRV_NAME": proto文件接口的service名称,
"$API_METHOD": proto文件接口的方法名称,
"$FORMAT_URL_METHOD": 格式化函数的返回结果

格式化函数示例

const formatUrlMethod = (PKG_NAME, SRV_NAME, API_NAME) => {
  // 参数1可以取到$PKG_NAME的值,参数2可以取到$SRV_NAME的值,参数3可以取到$API_NAME的值
  return `prefix ${PKG_NAME}.${SRV_NAME} conjunctions ${API_NAME} suffix`; // 可以根据入参自由拼接,返回的结果会体现到模板的$FORMAT_URL_METHOD变量上
};

exports.FORMAT_URL_METHOD = formatUrlMethod; // 此处导出的时候必须使用FORMAT_URL_METHOD命名

转换示例

proto 文件


syntax = "proto3";
package hello;

import "google/protobuf/empty.proto";
import "google/api/annotations.proto";

enum Status {
    UNKNOWN = 0;
    // 新创建
    NEW = 1;
  }

message InfoReq {
    int32 id = 1 [proto3_optional = true]; // id
    string user_name = 2 ; //  optional
}
message InfoResp {
    int32 ret_code = 1 [json_name = "retCode"];
    string ret_msg = 2  [json_name = "retMsg"];
    Status status = 3;
}

service API {
   rpc GetDemo(google.protobuf.Empty) returns (google.protobuf.Empty) {
       option (google.api.http) = {
           get: "/get"
           body: "*"
         };
   }
   rpc PostDemo(InfoReq) returns (InfoResp) {
       option (google.api.http) = {
           post: "/post"
       };
   }

}


message GetRequest {
    int64 id = 1;
    int64 external_id = 2;
    int32 external_type = 3;
  }

service API2 {
    // @method get
    // @redirect api/get-game
    rpc GetGame(GetRequest) returns (InfoResp);
    rpc BatchGetGame(GetRequest) returns (InfoResp);
}

转换后的 api 文件

/* eslint-disable */
/** @format */

// This is code generated automatically by the proto2api, please do not modify

import * as Types from "./types";
const { request } = useAxios();

// null
// API

export const GetDemo = (params: {}) => {
  return request<ResponseStructure<{}>>({
    url: "prefix /hello.API2 conjunctions GetDemo suffix",
    method: "get",
    params,
  } as AxiosConfig<{}, {}>);
};

export const PostDemo = (data: InfoReq) => {
  return request<ResponseStructure<InfoResp>>({
    url: "prefix /hello.API2 conjunctions PostDemo suffix",
    method: "post",
    data,
  } as AxiosConfig<InfoReq, InfoResp>);
};

// null
// API2

// @method get
// @originUrl:

export const GetGame = (params: GetRequest) => {
  return request<ResponseStructure<InfoResp>>({
    url: "prefix /hello.API2 conjunctions GetGame suffix",
    method: "get",
    params,
  } as AxiosConfig<GetRequest, InfoResp>);
};

export const BatchGetGame = (data: GetRequest) => {
  return request<ResponseStructure<InfoResp>>({
    url: "/hello.API2/BatchGetGame",
    method: "post",
    data,
    pageLoading: "none",
  } as AxiosConfig<GetRequest, InfoResp>);
};

转换后的 types 文件

/* eslint-disable */
/** @format */

// This is code generated automatically by the proto2api, please do not modify

export enum Status {
  UNKNOWN = "UNKNOWN",
  // 新创建
  NEW = "NEW",
}
export interface InfoReq {
  // id @int32
  id?: number;
  // optional
  user_name?: string;
}

export interface InfoResp {
  //  @int32
  retCode: number;
  retMsg: string;
  status: Status;
}

export interface GetRequest {
  //  @int64
  id: string;
  //  @int64
  external_id: string;
  //  @int32
  external_type: number;
}

参考文档

Google Protobuf 语法指南 https://developers.google.com/protocol-buffers/docs/proto3

proto2api 参考链接https://www.npmjs.com/package/proto2api