logo
0
0
WeChat Login
Forkfromcnb/skills/cnb-api-generate, aheadmain21 commits

cnb-api-generate

cnb-api-generate是一款基于swagger2.0标准协议生成基于@cnb/request@reduxjs/toolkitTypescript代码的工具。将Typescript中的InterfaceEnumswagger.json强绑定。并自动对请求函数的依赖分析并引入。

解决了什么问题?

长期以来,前后端开发都是两套代码甚至多套代码各自维护。前端基于后端提供的接口定义,例如swagger.json中定义的接口入参出参,自行编写Typescript代码,用Typescript重新定义一遍接口的入参出参(InterfaceEnum)。然后自行引用这些定义的入参出参(InterfaceEnum)。

看似一切都很正常,实际上这里有一个致命问题,当后端接口主动或被动发生变更时,前端无感知。但是代码却能正常编译通过,当进入到运行时时,就会出现错误。问题核心就在于前端自行维护入参出参(InterfaceEnum)和swargger.json中的定义是脱钩的。当后端代码发生变化,通过编译重新生成了swargger.json,但是新的swargger.json的变化并不能触达到前端。

  • ❎ 与swargger.json脱钩,swargger.json变化无法触发前端,编译通过,运行报错。
  • ❎ 手动定义InterfaceEnum,可能存在认为失误写错代码。
  • ❎ 可能存在多个重复定义的InterfaceEnum

当使用cnb-api-generate后,InterfaceEnum完全基于swargger.json中的定义自动生成标准的Typescript代码。并根据前端CNB的前端技术栈,完全自动生成多态化的网络函数调用,并自动完成对InterfaceEnum的依赖注入。

  • 💯 swargger.json与所有的前端网络调用函数代码强绑定,当swargger.json变化后,重新生成前端代码,实现Typescript代码重新生成,从而在编译时就能发现类型错误的问题。
  • 💯 InterfaceEnum的定义完全自动化,完全基于swargger.json,无需人为干预。
  • 💯 生成的代码更规范,抹除因开发人员水平差异导致编写的Typescript代码质量参差不齐。
  • 💯 完善的jsDos定义,除了生成Typescript代码外,还会根据swargger.json定义每个参数的说明,自动生成jsDos的注释。
  • 💯 从生成的代码和注释质量倒推接口的文档规范。

安装

npm install @cnbcool/cnb-api-generate -D
# or
yarn add @cnbcool/cnb-api-generate -D

快速使用

在运行cag目录下创建cag.config.js文件。

module.exports = {
  target: '<swargger.json文件地址>',
}
npx cag
# or
yarn cag

cnb-api-generate必须搭配@cnb/request使用!!!

cag.config.js

cnb-api-generate基本不需要任何配置,为了灵活支持输入输出文件的位置和引用代码的自定义位置,提供一些简单的配置。

target

指定swagger.json的文件位置,路径为相对cag.config.js的路径。

outputDir

指定输出的生成代码的目录,路径为相对cag.config.js的路径。

printeReduxAction

是否输出Redux Action代码,默认为true

requestDependencyMap

用于定义请求模块中依赖的函数与Typescript的定义

  • path -> 模块所在路径
  • isDefault -> 是否default导出
[key in string]: {
  path: string;
  isDefault: boolean;
}

基于@cnb/request,已内置,无需配置

Example

cnb-api-generate基于swargger中定义的类型生成三类型代码,InterfaceEnumApi。其中Api会基于swargger中对接口的分类进行目录级归类输出。

Interface

swagger中定义的definitions处理,生成Interface

"dto.AiAutoPrResult": {
    "type": "object",
    "properties": {
        "buildLogUrl": {
            "description": "构建链接",
            "type": "string"
        },
        "message": {
            "description": "message",
            "type": "string"
        },
        "sn": {
            "description": "构建号",
            "type": "string"
        }
    }
}

interfaces/dto.aiautoprresult.ts

export interface DtoAiAutoPrResult {
  /**
   * 构建链接
   */
  buildLogUrl?: string;
  /**
   * message
   */
  message?: string;
  /**
   * 构建号
   */
  sn?: string;
}

依赖其他Interface

swagger的定义中,definitions是可以互相依赖的。cnb-api-generate会自动处理好所有依赖的文件引入,确保代码正常使用。

"api.CommitObject": {
    "type": "object",
    "properties": {
        "author": {
            "$ref": "#/definitions/api.Signature"
        },
        "comment_count": {
            "type": "integer"
        },
        "committer": {
            "$ref": "#/definitions/api.Signature"
        },
        "message": {
            "type": "string"
        },
        "tree": {
            "$ref": "#/definitions/api.CommitObjectTree"
        },
        "verification": {
            "$ref": "#/definitions/api.CommitObjectVerification"
        }
    }
}

interfaces/api.commitobject.ts

import { ApiSignature } from "./api.signature";
import { ApiCommitObjectTree } from "./api.commitobjecttree";
import { ApiCommitObjectVerification } from "./api.commitobjectverification";
export interface ApiCommitObject {
  author?: ApiSignature;
  comment_count?: number;
  committer?: ApiSignature;
  message?: string;
  tree?: ApiCommitObjectTree;
  verification?: ApiCommitObjectVerification;
}

Enum

swagger中定义的definitions处理,生成Interface

"constant.ActivityType": {
    "type": "string",
    "enum": [
        "mine",
        "fork",
        "follow",
        "star",
        "join_group",
        "create_repo",
        "user_create_release",
        "repo_create_release",
        "user_deploy_success",
        "repo_deploy_success",
        "at_user",
        "comment"
    ],
    "x-enum-comments": {
        "AtUser": "AtUser @用户",
        "Comment": "Comment pr,issue 评论",
        "CreateRepo": "CreateRepo 创建仓库",
        "Follow": "Follow 用户 follow",
        "Fork": "Fork 仓库 fork",
        "JoinGroup": "JoinGroup 加入组织",
        "Mine": "Mine 与我相关的动态",
        "RepoCreateRelease": "RepoCreateRelease 仓库发布版本",
        "RepoDeploySuccess": "RepoDeploySuccess 仓库部署版本",
        "Star": "Star 仓库 star",
        "UserCreateRelease": "UserCreateRelease 用户发布版本",
        "UserDeploySuccess": "UserDeploySuccess 用户部署版本"
    },
    "x-enum-descriptions": [
        "Mine 与我相关的动态",
        "Fork 仓库 fork",
        "Follow 用户 follow",
        "Star 仓库 star",
        "JoinGroup 加入组织",
        "CreateRepo 创建仓库",
        "UserCreateRelease 用户发布版本",
        "RepoCreateRelease 仓库发布版本",
        "UserDeploySuccess 用户部署版本",
        "RepoDeploySuccess 仓库部署版本",
        "AtUser @用户",
        "Comment pr,issue 评论"
    ],
    "x-enum-varnames": [
        "Mine",
        "Fork",
        "Follow",
        "Star",
        "JoinGroup",
        "CreateRepo",
        "UserCreateRelease",
        "RepoCreateRelease",
        "UserDeploySuccess",
        "RepoDeploySuccess",
        "AtUser",
        "Comment"
    ]
}

enums/constant.activitytype.ts

export enum ConstantActivityType {
  /* Mine 与我相关的动态 */
  Mine = "mine",
  /* Fork 仓库 fork */
  Fork = "fork",
  /* Follow 用户 follow */
  Follow = "follow",
  /* Star 仓库 star */
  Star = "star",
  /* JoinGroup 加入组织 */
  JoinGroup = "join_group",
  /* CreateRepo 创建仓库 */
  CreateRepo = "create_repo",
  /* UserCreateRelease 用户发布版本 */
  UserCreateRelease = "user_create_release",
  /* RepoCreateRelease 仓库发布版本 */
  RepoCreateRelease = "repo_create_release",
  /* UserDeploySuccess 用户部署版本 */
  UserDeploySuccess = "user_deploy_success",
  /* RepoDeploySuccess 仓库部署版本 */
  RepoDeploySuccess = "repo_deploy_success",
  /* AtUser @用户 */
  AtUser = "at_user",
  /* Comment pr,issue 评论 */
  Comment = "comment",
}

Api

cnb-api-generate是为cnb量身定做的代码生成工具,所以基于@cnb/request@reduxjs/toolkit生成调用代码,并且自动完成对生成的interfaceenum的引用依赖。

"/user/gpg-keys/{id}": {
    "delete": {
        "security": [
            {
                "BearerAuth": []
            }
        ],
        "consumes": [
            "application/json"
        ],
        "produces": [
            "application/json",
            "application/vnd.cnb.web+json"
        ],
        "tags": [
            "Users"
        ],
        "summary": "删除用户 GPG key",
        "operationId": "DeleteGPGKey",
        "parameters": [
            {
                "type": "string",
                "description": "gpg id",
                "name": "id",
                "in": "path",
                "required": true
            }
        ],
        "responses": {
            "200": {
                "description": "OK"
            },
            "404": {
                "description": "Not Found",
                "schema": {
                    "$ref": "#/definitions/die.WebError"
                }
            },
            "500": {
                "description": "Internal Server Error",
                "schema": {
                    "$ref": "#/definitions/die.WebError"
                }
            }
        }
    }
}

apis/users/delete-gpg-key.ts

import type { IncomingMessage } from "http";
import { createAsyncThunk } from "@reduxjs/toolkit";
import fetch from "@/request";
import { CnbRequestOptions, CnbRequestResult } from "@cnb/request";
import { AxiosRequestConfig } from "axios";
import { DieWebError } from "../../interfaces/die.weberror";

/**
 * @description Other reuqest params
 */
type RequestConfig<DataType = any> = AxiosRequestConfig<DataType> & {
  options?: CnbRequestOptions;
  req?: IncomingMessage;
};

/**
 * @description DeleteGPGKeyRes Success Response Type
 */
export type DeleteGPGKeyRes = unknown;

/**
 * @description DeleteGPGKeyError Error Response Type
 */
export type DeleteGPGKeyError = DieWebError;

/**
* @description No description
* @tags Users
* @name deleteGPGKey
* @summary 删除用户 GPG key
* @request delete:/user/gpg-keys/{id}

----------------------------------
* @param {string} arg0
* @param {RequestConfig} arg1 - Other reuqest params
*/
export async function deleteGPGKey(
  id: string,
  {req, options, ...axiosConfig}: RequestConfig = {},
): Promise<CnbRequestResult<DeleteGPGKeyRes, DeleteGPGKeyError>> {
  return await fetch.request<DeleteGPGKeyRes, DeleteGPGKeyError>({
    ...axiosConfig,
    _next_req: req,
    options: options,
    url: `/user/gpg-keys/${id}`,
    _apiTag: "/user/gpg-keys/{id}",
    method: "delete",
  });
}

生成SKILL

基于swagger生成Agent Skill。

文件配置

cag.config.js

module.exports = {
  target: './template/swagger.json',
  skillsOutputDir: `./`,
}

执行命令

npx csg

生成如下目录结构:

| SKILL.md
| scripts/
| - core/
| - modules/

环境变量依赖

skills运行需要依赖以下环境变量

  • CNB_API_ENDPOINT: 可选:自定义 API 地址(默认为 https://api.cnb.cool
  • CNB_TOKEN: openapi令牌
  • CNB_WEB_ENDPOINT: 与CNB_API_ENDPOINT相对应的根域名(默认为 https://cnb.cool

About

No description, topics, or website provided.
Language
TypeScript99%
JavaScript0.7%
Shell0.2%
Dockerfile0.1%