Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v1.5.0 #55

Merged
merged 10 commits into from
Mar 27, 2024
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,15 @@ App<IAppOption>({

### Options 选项

| 参数名 | 类型 | 默认值 | 说明 |
| -------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------- |
| url | string | | Swagger 文档地址,或者本地路径 |
| outDir | string | stc_out | 输出目录 |
| platform | string | axios | 平台,可选值:`axios`、`wechat` |
| lang | string | ts | 语言,用于输出文件的后缀名 |
| tag | number | | 从接口 url 指定标签,默认读取 tags 的第一个用于文件名 |
| 参数名 | 类型 | 默认值 | 说明 |
| -------- | -------- | ------- | ------------------------------------------------------------------------------------------------ |
| url | string | | Swagger 文档地址,或者本地路径 |
| outDir | string | stc_out | 输出目录 |
| platform | string | axios | 平台,可选值:`axios`、`wechat` |
| lang | string | ts | 语言,用于输出文件的后缀名 |
| tag | number | | 从接口 url 指定标签,默认读取 tags 的第一个用于文件名 |
| filter | string[] | | 过滤接口,符合过滤条件的接口会被生成。eg: `--filter "/pet/*"`,生成 `/pet` 的接口,同时支持多个 `--filter` |
| conjunction | string | By | 方法的连接词,默认值为 `By` |

## Plug-in development 插件开发

Expand All @@ -141,7 +142,7 @@ For convenience, STC can not only develop plugins in Deno, but also provides `@l

```ts
// 引用模块
import { start } from 'https://deno.land/x/stc@1.4.2/mod.ts'
import { start } from 'https://deno.land/x/stc@1.5.0/mod.ts'

// 定义插件
const myPlugin: IPlugin = {
Expand Down
4 changes: 2 additions & 2 deletions deno.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "@loongwoo/stc",
"version": "1.4.2",
"version": "1.5.0",
"exports": "./mod.ts",
"tasks": {
"dev": "deno run -A --watch=src src/main.ts --url 'https://petstore3.swagger.io/api/v3/openapi.json' --outDir=out",
"version": "echo '1.4.2' > release/version",
"version": "echo '1.5.0' > release/version",
"build:npm": "deno run -A src/npm/index.ts",
"build:mac": "deno compile -A --target x86_64-apple-darwin --output release/stc src/main.ts",
"build:mac-m": "deno compile -A --target aarch64-apple-darwin --output release/stc-m src/main.ts",
Expand Down
12 changes: 7 additions & 5 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const start = async (options: ISwaggerOptions) => {
const transformData = await context.onTransform?.(defData, actionData);

// 写入类型定义文件
if (transformData?.definition) {
if (transformData?.definition?.content) {
createFile(
`${options.outDir}/${transformData.definition.filename}`,
transformData.definition.content,
Expand All @@ -99,10 +99,12 @@ export const start = async (options: ISwaggerOptions) => {
// 写入 API 文件
if (transformData?.action) {
transformData.action.forEach((content, filename) => {
createFile(
`${options.outDir}/${filename}.${options.lang}`,
content,
);
if (content) {
createFile(
`${options.outDir}/${filename}.${options.lang}`,
content,
);
}
});
}

Expand Down
19 changes: 7 additions & 12 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,7 @@ ${getT("$t(cli.option)")}
-l, --lang ${getT("$t(cli.option_lang)")}
-f, --filter ${getT("$t(cli.option_filter)")}
--tag ${getT("$t(cli.option_tag)")}
-c, --con ${getT("$t(cli.option_con)")}
-a, --addMethod ${getT("$t(cli.option_addMethod)")}
-c, --conjunction ${getT("$t(cli.option_conjunction)")}
-v, --version ${getT("$t(cli.option_version)")}

${getT("$t(cli.example)")}
Expand All @@ -184,8 +183,7 @@ export const main = async (): Promise<ISwaggerOptions> => {
"lang",
"tag",
"filter",
"con",
"addMethod",
"conjunction",
],
alias: {
h: "help",
Expand All @@ -194,13 +192,13 @@ export const main = async (): Promise<ISwaggerOptions> => {
l: "lang",
v: "version",
f: "filter",
c: "con",
a: "addMethod",
c: "conjunction",
},
collect: ["filter"],
default: {
lang: "ts",
platform: "axios",
conjunction: "By",
},
unknown: (arg: string) => {
Logs.error(getT("$t(cli.unknownOption)", { arg }));
Expand Down Expand Up @@ -243,10 +241,8 @@ export const main = async (): Promise<ISwaggerOptions> => {
const platform = args.platform ?? "axios";
// 语言,用于输出文件的后缀名。默认:ts
const lang = args.lang ?? "ts";
// 动态路径方法的连接词,默认值为 by
const con = args.con ?? "by";
// 方法名是否添加请求方法,默认值为 true
const addMethod = args.addMethod !== "false";
// 动态路径方法的连接词,默认: By
const conjunction = args.conjunction ?? "By";

return {
url: args.url,
Expand All @@ -255,7 +251,6 @@ export const main = async (): Promise<ISwaggerOptions> => {
lang,
tag: args.tag,
filter: args.filter,
con,
addMethod
conjunction,
};
};
44 changes: 37 additions & 7 deletions src/definition.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
IDefinitionVirtualProperty,
ISwaggerResultDefinition,
} from "./swagger.ts";
import { getObjectKeyByValue, getRefType, upperCase } from "./util.ts";
import { camelCase, getObjectKeyByValue, getRefType, hasKey } from "./util.ts";
import { getT } from "./i18n/index.ts";

/**
Expand Down Expand Up @@ -60,15 +60,17 @@ const getDefinitionNameMapping = (

/**
* 原始定义对象转换为虚拟定义对象
*
* @param defItem - 定义名的属性
* @param defMapping - 定义
* @returns
*/
const getVirtualProperties = (
defItem: ISwaggerResultDefinition,
defMapping: IDefinitionNameMapping,
defData: Map<string, IDefinitionVirtualProperty[]>,
): IDefinitionVirtualProperty[] => {
if (defItem.type !== "object") {
if (!defItem.type.includes("object")) {
Logs.error(getT("$t(def.parserTypeError)", { type: defItem.type }));
return [];
}
Expand All @@ -94,18 +96,45 @@ const getVirtualProperties = (

// 属性类型。若存在枚举选项,则需要声明一个“定义名 + 属性名”的枚举类型
const type = enumOption.length
? defMapping.name + upperCase(current)
? camelCase(`${defMapping.name}_${current}`, true)
: (getObjectKeyByValue(mappings, refName) || prop.type);

prev.push({
name: current,
const _defItem: IDefinitionVirtualProperty = {
name: camelCase(current),
type,
description: prop.description ?? "",
required,
enumOption,
ref: refName,
format: prop.format ?? "",
});
};

// 处理当前属性的子属性
if (hasKey(prop as unknown as Record<string, unknown>, "properties")) {
const _childDef = getDefinitionNameMapping(current, true);
const _childProps = getVirtualProperties(
prop as ISwaggerResultDefinition,
_childDef,
defData,
);

// 将 type 中存在 object,替换为新名字
if (_defItem.type.includes("object") && _childProps.length) {
const _objTypeName = defMapping.name + _childDef.name;

if (Array.isArray(_defItem.type)) {
const _objIndex = _defItem.type.indexOf("object");

_defItem.type.splice(_objIndex, 1, _objTypeName);
} else {
_defItem.type = _objTypeName;
}

defData.set(_objTypeName, _childProps);
}
}

prev.push(_defItem);
return prev;
},
[],
Expand Down Expand Up @@ -135,7 +164,8 @@ export const getDefinition = (
});
if (defKeys.includes(name)) return;

const props = getVirtualProperties(definitions[key], def);
const props = getVirtualProperties(definitions[key], def, defMap);

defMap.set(name, props);
});

Expand Down
3 changes: 1 addition & 2 deletions src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@
"option_filter": "Filter interfaces, and the interfaces that meet the filter conditions will be generated.",
"option_tag": "Specify tags from the interface url for filenames, the first one of tags is read by default.",
"option_version": "View version information.",
"option_con": "Conjunctions for dynamic path methods.",
"option_addMethod": "Specifies whether to add the request method to the method name."
"option_conjunction": "Conjunction of method name."
},
"plugin": {
"name": "Load plugin {{name}}",
Expand Down
3 changes: 1 addition & 2 deletions src/i18n/locales/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@
"option_filter": "过滤接口,符合过滤条件的接口会被生成。",
"option_tag": "从接口 url 中指定标签,用于文件名,默认读取 tags 的第一个。",
"option_version": "显示版本信息。",
"option_con": "动态路径方法的连接词。",
"option_addMethod": "方法名是否添加请求方法。"
"option_conjunction": "方法名的连接词。"
},
"plugin": {
"name": "加载插件 {{name}}",
Expand Down
2 changes: 1 addition & 1 deletion src/npm/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@loongwoo/stc",
"version": "1.4.2",
"version": "1.5.0",
"description": "Converting OpenAPI (Swagger) and Apifox documents to interface files.\nOpenAPI(Swagger)、Apifox 文档转换为接口文件",
"type": "module",
"module": "esm/mod.js",
Expand Down
Loading