@cnbcool/cnb-api-generate
v1.0.2
Published
`cnb-api-generate`是一款基于`swagger2.0`标准协议生成基于`@cnb/request`和`@reduxjs/toolkit`的`Typescript`代码的工具。将`Typescript`中的`Interface`和`Enum`与`swagger.json`强绑定。并自动对请求函数的依赖分析并引入。
Downloads
308
Keywords
Readme
cnb-api-generate
cnb-api-generate是一款基于swagger2.0标准协议生成基于@cnb/request和@reduxjs/toolkit的Typescript代码的工具。将Typescript中的Interface和Enum与swagger.json强绑定。并自动对请求函数的依赖分析并引入。
解决了什么问题?
长期以来,前后端开发都是两套代码甚至多套代码各自维护。前端基于后端提供的接口定义,例如swagger.json中定义的接口入参出参,自行编写Typescript代码,用Typescript重新定义一遍接口的入参出参(Interface和Enum)。然后自行引用这些定义的入参出参(Interface和Enum)。
看似一切都很正常,实际上这里有一个致命问题,当后端接口主动或被动发生变更时,前端无感知。但是代码却能正常编译通过,当进入到运行时时,就会出现错误。问题核心就在于前端自行维护入参出参(Interface和Enum)和swargger.json中的定义是脱钩的。当后端代码发生变化,通过编译重新生成了swargger.json,但是新的swargger.json的变化并不能触达到前端。
- ❎ 与
swargger.json脱钩,swargger.json变化无法触发前端,编译通过,运行报错。 - ❎ 手动定义
Interface和Enum,可能存在认为失误写错代码。 - ❎ 可能存在多个重复定义的
Interface和Enum。
当使用cnb-api-generate后,Interface和Enum完全基于swargger.json中的定义自动生成标准的Typescript代码。并根据前端CNB的前端技术栈,完全自动生成多态化的网络函数调用,并自动完成对Interface和Enum的依赖注入。
- 💯
swargger.json与所有的前端网络调用函数代码强绑定,当swargger.json变化后,重新生成前端代码,实现Typescript代码重新生成,从而在编译时就能发现类型错误的问题。 - 💯
Interface和Enum的定义完全自动化,完全基于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 cagcnb-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中定义的类型生成三类型代码,Interface、Enum和Api。其中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生成调用代码,并且自动完成对生成的interface和enum的引用依赖。
"/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)
