Skip to content

Commit

Permalink
Merge pull request #87 from long-woo/dev
Browse files Browse the repository at this point in the history
release: v2.4.1
  • Loading branch information
long-woo authored Nov 22, 2024
2 parents f7169e0 + 1b2e5c5 commit 595cebc
Show file tree
Hide file tree
Showing 19 changed files with 182 additions and 47 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ Create a `myPlugin.ts` file:

```ts
// 引用模块
// import { start } from 'https://deno.land/x/stc@2.4.0/mod.ts'
import { start } from 'jsr:@loongwoo/stc@^2.4.0'
// import { start } from 'https://deno.land/x/stc@2.4.1/mod.ts'
import { start } from 'jsr:@loongwoo/stc@^2.4.1'

// Defining plugins
const myPlugin: IPlugin = {
Expand Down
6 changes: 3 additions & 3 deletions deno.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"name": "@loongwoo/stc",
"version": "2.4.0",
"version": "2.4.1",
"exports": "./mod.ts",
"tasks": {
"pack": "deno run -A src/pack.ts",
"dev": "deno task pack && deno run -A --watch=src src/main.ts --url='https://petstore3.swagger.io/api/v3/openapi.json' --lang=js",
"dev": "deno task pack && deno run -A --watch=src src/main.ts --url='https://petstore3.swagger.io/api/v3/openapi.json' --lang=ts",
"serve": "deno run -A --watch=src src/service.ts",
"version": "echo '2.4.0' > release/version",
"version": "echo '2.4.1' > release/version",
"build:npm": "deno run -A src/npm/build.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
2 changes: 1 addition & 1 deletion src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export const createFile = async (
*
* https://github.com/long-woo/stc
* ${dateFormat(new Date(), "yyyy-MM-dd HH:mm:ss")}
*/\n`
*/\n\n`
: ""
}${content}`,
),
Expand Down
27 changes: 22 additions & 5 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,17 @@ const getDefinitionNameMapping = (
const getVirtualProperties = (
defItem: ISwaggerResultDefinition,
defMapping: IDefinitionNameMapping,
defData: Map<string, IDefinitionVirtualProperty[]>,
defData: Map<
string,
IDefinitionVirtualProperty[] | IDefinitionVirtualProperty
>,
): IDefinitionVirtualProperty[] => {
if (!defItem.type.includes("object")) {
Logs.error(getT("$t(def.parserTypeError)", { type: defItem.type }));
return [];
}

const props = defItem.properties;
const props = defItem.properties ?? {};
const mappings = defMapping.mappings ?? {};

const vProps = Object.keys(props).reduce(
Expand Down Expand Up @@ -163,8 +166,11 @@ const getVirtualProperties = (
*/
export const getDefinition = (
definitions: IDefaultObject<ISwaggerResultDefinition>,
): Map<string, IDefinitionVirtualProperty[]> => {
const defMap = new Map<string, IDefinitionVirtualProperty[]>();
): Map<string, IDefinitionVirtualProperty[] | IDefinitionVirtualProperty> => {
const defMap = new Map<
string,
IDefinitionVirtualProperty[] | IDefinitionVirtualProperty
>();

Object.keys(definitions).forEach((key) => {
const def = getDefinitionNameMapping(key, true);
Expand All @@ -177,7 +183,18 @@ export const getDefinition = (
});
if (defKeys.includes(name)) return;

const props = getVirtualProperties(definitions[key], def, defMap);
const defItem = definitions[key];
let props: IDefinitionVirtualProperty | IDefinitionVirtualProperty[] = [];

// 处理枚举
if (defItem.enum) {
props = {
type: defItem.type,
enumOption: defItem.enum,
} as IDefinitionVirtualProperty;
} else {
props = getVirtualProperties(defItem, def, defMap);
}

defMap.set(name, props);
});
Expand Down
2 changes: 1 addition & 1 deletion src/npm/pkg.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@loongwoo/stc",
"version": "2.4.0",
"version": "2.4.1",
"description": "A tool for converting OpenApi/Swagger/Apifox into code.",
"type": "module",
"module": "esm/mod.js",
Expand Down
23 changes: 18 additions & 5 deletions src/plugins/defintion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,25 @@ export const parserDefinition = (
options: IPluginOptions,
) => {
const _definitions: string[] = [];

Logs.info(`${getT("$t(plugin.parserDef)")}...`);

data.forEach((props, key) => {
const _definition: string[] = [`// #region ${key}`];
const _definition: string[] = [];

// 枚举处理
if (!Array.isArray(props)) {
const _enumOption = (props as IDefinitionVirtualProperty).enumOption;

if (_enumOption?.length) {
const _enumData = renderEtaString(
options.template.enum,
{ name: key, data: _enumOption, convertValue },
);

_definitions.push(_enumData);
}
return;
}

props.forEach((prop, index) => {
const _type = convertType(
Expand All @@ -40,7 +55,7 @@ export const parserDefinition = (
options.template.enum,
{ name: _type, data: _enumOption, convertValue },
);
_definition.splice(1, 0, `${_enumData}\n`);
_definition.unshift(`${_enumData}`);
}

// 定义头
Expand All @@ -62,12 +77,10 @@ export const parserDefinition = (
// 定义尾
if (index === props.length - 1) {
_definition.push(
"",
renderEtaString(options.template.definitionFooter, {
defName: key,
props,
}),
"// #endregion\n",
);
}
});
Expand Down
24 changes: 12 additions & 12 deletions src/plugins/typescript/shared/axios/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,17 +114,17 @@ export const createAxios = (
};

/**
* Sends a request using the provided WebClientConfig instance. If formData is included in the instance parameters, it is processed and sent as FormData.
* Makes a request using the provided configuration.
*
* @param {ApiClientConfig} instance - the configuration object for the request
* @return {Promise<T>} a Promise that resolves with the response data
* @param {ApiClientConfig} config - The configuration object for the request.
* @return {Promise<T>} A promise that resolves with the response data.
*/
export const request = <T>(
instance: ApiClientConfig,
config: ApiClientConfig,
): Promise<T> => {
const _formData: IDefaultObject = instance.params?.formData as IDefaultObject;
const _formData: IDefaultObject = config.params?.formData as IDefaultObject;

let _data: IDefaultObject | FormData | unknown = instance.params?.body;
let _data: IDefaultObject | FormData | unknown = config.params?.body;

// 处理 FormData 数据
if (_formData) {
Expand All @@ -138,12 +138,12 @@ export const request = <T>(
}

return axiosInstance.request<T, T>({
url: instance.url,
method: instance.method,
url: config.url,
method: config.method,
data: _data,
params: instance.params?.query,
headers: instance.params?.header,
timeout: instance.config?.timeout,
signal: instance.config?.signal,
params: config.params?.query,
headers: config.params?.header,
timeout: config.config?.timeout,
signal: config.config?.signal,
});
};
14 changes: 7 additions & 7 deletions src/plugins/typescript/shared/fetchRuntime.eta
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import type {
import { generateURL } from "./apiClientBase";
import { <% if (it.client === 'axios') { %> createAxios, <% } %>request } from "./<%= it.client %>";

let apiClientInstance: ApiClientConfig = {};
let apiClientConfig: ApiClientConfig = {};

export const createApiClient = (
config: Omit<ApiClientConfig, "url" | "signal" | "config">,
): void => {
apiClientInstance = config;
apiClientConfig = config;
<% if (it.client === "axios") { %>
createAxios(config);
<% } %>
Expand All @@ -26,12 +26,12 @@ export const fetchRuntime = <T>(
): Promise<T> => {
const _url = generateURL(url, req?.path as unknown as IDefaultObject);

apiClientInstance.url = _url;
apiClientInstance.method = method;
apiClientInstance.params = req;
apiClientInstance.config = config;
apiClientConfig.url = _url;
apiClientConfig.method = method;
apiClientConfig.params = req;
apiClientConfig.config = config;

return request<T>(apiClientInstance);
return request<T>(apiClientConfig);
};

/**
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/typescript/shared/index.ts

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/plugins/typescript/template/definitionFooter.eta
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
}
// #endregion
2 changes: 2 additions & 0 deletions src/plugins/typescript/template/definitionHeader.eta
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
// #region <%= it.defName %>

export interface <%= it.defName %> {
5 changes: 4 additions & 1 deletion src/plugins/typescript/template/enum.eta
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
export type <%= it.name %> = '<%~ it.data.map(it.convertValue).join("' | '") %>';
// #region <%= it.name %>

export type <%= it.name %> = '<%~ it.data.map(it.convertValue).join("' | '") %>';
// #endregion
2 changes: 1 addition & 1 deletion src/plugins/typescript/template/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// this file is auto generated.
export default {"actionImport":"import { fetchRuntime } from '<%= it.importPath %>shared/fetchRuntime'\n<% if (it.imports.length) { %>\nimport type { <%= it.imports.join(', ') %> } from '<%= it.importPath %><%= it.typeFileName %>'\n<% } %>","actionMethod":"<% /* API 方法注释 */ %>\n/**\n<% if (it.summary) { %>\n * <%~ it.summary %>\n<% } %>\n<% if (it.summary !== it.description) { %>\n<% if (it.summary && it.description) { %>\n\n *\n<% } %>\n<% if (it.description) { %>\n * @description <%~ it.description %>\n<% } %>\n<% } %>\n<% if (it.params.length) { %>\n\n *\n<% it.params.forEach(param => { %>\n * @param {<%~ param.type %>} <% if (!param.required) { %>[<% } %><%= param.name %><% if (!param.required) { %>]<% } %> - <%~ param.description || param.type %>\n\n<% }) %>\n<% } %>\n * @returns {Promise<<%~ it.responseType %>>} Promise<<%~ it.responseType %>>\n */\n<% /* API 方法 */ %>\nexport const <%= it.methodName %> = (<% it.params.forEach((param, index) => { %>\n<%= param.name %><% if (!param.required) { %>?<% } %>: <%~ param.type %><% if (index < it.params.length - 1) { %>, <% } %>\n<% }) %>): Promise<<%~ it.responseType %>> => fetchRuntime<<%~ it.responseType %>>('<%= it.url %>', '<%= it.method.toUpperCase() %>'<% if (it.params.length) { %>, {\n<% it.params.forEach((param, index) => { %>\n <%= param.category %><% if (param.category === param.name) { %>\n<% } else { %>: <% if (param.category === 'body') { %><%= param.name %><% } else { %>{\n\t\t<%= param.name %>\n\n\t}<% } %>\n<% } %><% if (index < it.params.length - 1) { %>, <% } %>\n\n<% }) %>\n}<% } %>)\n","definitionBody":"<% if (it.propCommit) { %>\n /**\n * <%~ it.propCommit %>\n\n */\n<% } %>\n <%= it.prop.name %><% if (!it.prop.required) { %>?<% } %>: <%~ it.propType %>;","definitionFooter":"}\n","definitionHeader":"export interface <%= it.defName %> {","enum":"export type <%= it.name %> = '<%~ it.data.map(it.convertValue).join(\"' | '\") %>';"}
export default {"actionImport":"import { fetchRuntime } from '<%= it.importPath %>shared/fetchRuntime'\n<% if (it.imports.length) { %>\nimport type { <%= it.imports.join(', ') %> } from '<%= it.importPath %><%= it.typeFileName %>'\n<% } %>","actionMethod":"<% /* API 方法注释 */ %>\n/**\n<% if (it.summary) { %>\n * <%~ it.summary %>\n<% } %>\n<% if (it.summary !== it.description) { %>\n<% if (it.summary && it.description) { %>\n\n *\n<% } %>\n<% if (it.description) { %>\n * @description <%~ it.description %>\n<% } %>\n<% } %>\n<% if (it.params.length) { %>\n\n *\n<% it.params.forEach(param => { %>\n * @param {<%~ param.type %>} <% if (!param.required) { %>[<% } %><%= param.name %><% if (!param.required) { %>]<% } %> - <%~ param.description || param.type %>\n\n<% }) %>\n<% } %>\n * @returns {Promise<<%~ it.responseType %>>} Promise<<%~ it.responseType %>>\n */\n<% /* API 方法 */ %>\nexport const <%= it.methodName %> = (<% it.params.forEach((param, index) => { %>\n<%= param.name %><% if (!param.required) { %>?<% } %>: <%~ param.type %><% if (index < it.params.length - 1) { %>, <% } %>\n<% }) %>): Promise<<%~ it.responseType %>> => fetchRuntime<<%~ it.responseType %>>('<%= it.url %>', '<%= it.method.toUpperCase() %>'<% if (it.params.length) { %>, {\n<% it.params.forEach((param, index) => { %>\n <%= param.category %><% if (param.category === param.name) { %>\n<% } else { %>: <% if (param.category === 'body') { %><%= param.name %><% } else { %>{\n\t\t<%= param.name %>\n\n\t}<% } %>\n<% } %><% if (index < it.params.length - 1) { %>, <% } %>\n\n<% }) %>\n}<% } %>)\n","definitionBody":"<% if (it.propCommit) { %>\n /**\n * <%~ it.propCommit %>\n\n */\n<% } %>\n <%= it.prop.name %><% if (!it.prop.required) { %>?<% } %>: <%~ it.propType %>;","definitionFooter":"}\n// #endregion\n","definitionHeader":"// #region <%= it.defName %>\n\nexport interface <%= it.defName %> {","enum":"// #region <%= it.name %>\n\nexport type <%= it.name %> = '<%~ it.data.map(it.convertValue).join(\"' | '\") %>';\n// #endregion\n"}
3 changes: 2 additions & 1 deletion src/swagger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ export interface ISwaggerComponents {

export interface ISwaggerResultDefinition {
type: string;
enum?: (number | string)[];
required?: string[];
properties: IDefaultObject<ISwaggerDefinitionProperties>;
}
Expand Down Expand Up @@ -188,7 +189,7 @@ export interface IDefinitionVirtualProperty {
/**
* 枚举选项
*/
enumOption?: string[];
enumOption?: (string | number)[];
/**
* 自定义类型
*/
Expand Down
9 changes: 4 additions & 5 deletions test/cli.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { assertEquals } from "@std/assert";

Deno.test("测试-输出版本信息", async () => {
Deno.test("version", async () => {
const command = new Deno.Command("deno", {
args: [
"run",
Expand All @@ -15,7 +15,7 @@ Deno.test("测试-输出版本信息", async () => {
assertEquals(0, code);
});

Deno.test("测试-输出帮助信息", async () => {
Deno.test("help", async () => {
const command = new Deno.Command("deno", {
args: [
"run",
Expand All @@ -30,7 +30,7 @@ Deno.test("测试-输出帮助信息", async () => {
assertEquals(0, code);
});

Deno.test("测试 filter", async () => {
Deno.test("filter", async () => {
const command = new Deno.Command("deno", {
args: [
"run",
Expand All @@ -47,7 +47,7 @@ Deno.test("测试 filter", async () => {
assertEquals(0, code);
});

Deno.test("测试 con", async () => {
Deno.test("conjunction", async () => {
const command = new Deno.Command("deno", {
args: [
"run",
Expand All @@ -59,6 +59,5 @@ Deno.test("测试 con", async () => {
});
const { code } = await command.output();

// console.log(new TextDecoder().decode(stdout));
assertEquals(0, code);
});
82 changes: 82 additions & 0 deletions test/demo1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"openapi": "3.0.1",
"info": {
"title": "Api",
"version": "1.0"
},
"paths": {
},
"components": {
"schemas": {
"ConnectionInfoModel": {
"required": [
"connectionType"
],
"type": "object",
"properties": {
"name": {
"maxLength": 50,
"minLength": 4,
"type": "string",
"nullable": true
},
"connectionType": {
"maxLength": 50,
"minLength": 1,
"type": "string"
},
"description": {
"maxLength": 300,
"type": "string",
"nullable": true
},
"properties": {
"type": "object",
"additionalProperties": {},
"nullable": true
},
"id": {
"type": "integer",
"format": "int32"
},
"createBy": {
"type": "integer",
"format": "int32"
},
"createUserName": {
"type": "string",
"nullable": true
},
"createTime": {
"type": "string",
"format": "date-time"
},
"updateBy": {
"type": "integer",
"format": "int32"
},
"updateUserName": {
"type": "string",
"nullable": true
},
"updateTime": {
"type": "string",
"format": "date-time"
},
"status": {
"$ref": "#/components/schemas/ConnectionStatus"
}
},
"additionalProperties": false
},
"ConnectionStatus": {
"enum": [
0,
1
],
"type": "integer",
"format": "int32"
}
}
}
}
Loading

0 comments on commit 595cebc

Please sign in to comment.