Skip to content

Commit

Permalink
feat: add openapi create API services file
Browse files Browse the repository at this point in the history
  • Loading branch information
MriLiuJY committed Jun 5, 2023
1 parent 6db1947 commit 6da1dc8
Show file tree
Hide file tree
Showing 13 changed files with 242 additions and 219 deletions.
11 changes: 5 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
{
"name": "@developer-once/onecli",
"version": "1.4.4-beta.0",
"version": "1.5.0-beta.0",
"description": "developer-once onecli cli",
"main": "/lib/bin/index.js",
"files": [
"lib",
"templates",
"README.md"
],
"scripts": {
Expand Down Expand Up @@ -32,7 +33,7 @@
"@types/ora": "^3.2.0",
"@types/prettier": "^2.2.1",
"@types/reserved-words": "^0.1.0",
"@types/rimraf": "^4.0.5",
"@types/semver": "^7.5.0",
"@types/shelljs": "^0.8.11",
"@types/swagger2openapi": "^7.0.0",
"@typescript-eslint/eslint-plugin": "^5.10.2",
Expand All @@ -44,7 +45,6 @@
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.2.0",
"np": "^7.2.0",
"rimraf": "^3.0.2",
"tslib": "^2.3.1",
"typescript": "^4.5.5"
},
Expand All @@ -56,7 +56,7 @@
"@commitlint/lint": "^17.4.4",
"@commitlint/load": "^17.5.0",
"@umijs/fabric": "^2.5.6",
"axios": "^1.3.3",
"axios": "^1.4.0",
"chalk": "^4.1.2",
"commander": "^9.0.0",
"commitizen": "^4.2.5",
Expand All @@ -74,14 +74,13 @@
"minimist": "^1.2.6",
"mock.js": "^0.2.0",
"mockjs": "^1.1.0",
"node-fetch": "^3.3.1",
"node-fetch": "^2.6.11",
"npmlog": "^7.0.1",
"nunjucks": "^3.2.4",
"openapi3-ts": "^2.0.1",
"ora": "^5.4.1",
"prettier": "^2.8.8",
"reserved-words": "^0.1.2",
"rimraf": "^3.0.2",
"semver": "^7.3.8",
"simple-git": "^3.16.1",
"swagger2openapi": "^7.0.8",
Expand Down
4 changes: 2 additions & 2 deletions src/bin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Command } from 'commander';
import create from '../commands/create/index';
import cz from '../commands/cz';
import publish from '../commands/publish';
import { generateService } from '../commands/openapi/index';
import openAPI from '../commands/openapi/index';
import { checkLogin, checkVersion, log, PREFIX } from '../utils/index';

const program = new Command();
Expand Down Expand Up @@ -52,7 +52,7 @@ program
.command('openapi')
.description('openapi 自动生成 service')
.action(() => {
generateService();
openAPI();
});


Expand Down
208 changes: 43 additions & 165 deletions src/commands/openapi/index.ts
Original file line number Diff line number Diff line change
@@ -1,168 +1,46 @@
/* eslint-disable global-require */
/* eslint-disable import/no-dynamic-require */
import http from 'http';
import https from 'https';
import fetch from 'node-fetch';
import converter from 'swagger2openapi';
import type { OperationObject, SchemaObject } from 'openapi3-ts';
import type { Options as prettierOptions } from 'prettier';

import Log from './log';
import { mockGenerator } from './mockGenerator';
import { ServiceGenerator } from './serviceGenerator';

const getImportStatement = (requestLibPath: string) => {
if (requestLibPath && requestLibPath.startsWith('import')) {
return requestLibPath;
}
if (requestLibPath) {
return `import request from '${requestLibPath}'`;
}
return `import { request } from "umi"`;
};

export type GenerateServiceProps = {
requestLibPath?: string;
requestImportStatement?: string;
/**
* api 的前缀
*/
apiPrefix?:
| string
| ((params: {
path: string;
method: string;
namespace: string;
functionName: string;
autoExclude?: boolean;
}) => string);
/**
* 生成的文件夹的路径
*/
serversPath?: string;
/**
* Swagger 2.0 或 OpenAPI 3.0 的地址
*/
schemaPath?: string;
/**
* 项目名称
*/
projectName?: string;

hook?: {
/** 自定义函数名称 */
customFunctionName?: (data: OperationObject) => string;
/** 自定义类型名称 */
customTypeName?: (data: OperationObject) => string;
/** 自定义类名 */
customClassName?: (tagName: string) => string;
/** 自定义swagger ref类型 */
customRefType?: (data: {
schemaName: string;
typeName: string;
props: (SchemaObject & { name: string; type: string; desc: string; required: string })[];
}) => (SchemaObject & { name: string; type: string; desc: string; required: string })[];
};

namespace?: string;

mockFolder?: string;
/**
* 模板文件的文件路径
*/
templatesFolder?: string;

/**
* 枚举样式
*/
enumStyle?: 'string-literal' | 'enum';

/**
* 增量修改
*/
increment?: {
/** 类型增量 */
types?: boolean;

/** controller 白名单增量 */
includes?: string[];

// /** controller 黑名单 */
// excludes?: string[];
};

/** 自定义 prettier 选项 */
prettierOptions?: prettierOptions;
};

const converterSwaggerToOpenApi = (swagger: any) => {
if (!swagger.swagger) {
return swagger;
}
return new Promise((resolve, reject) => {
converter.convertObj(swagger, {}, (err, options) => {
Log(['💺 将 Swagger 转化为 openAPI']);
if (err) {
reject(err);
return;
}
resolve(options.openapi);
});
// @ts-nocheck
// --- 入口文件 ---
// --- 生成 Services ---
import inquirer from 'inquirer';
import { generateService } from './openApi';
import { log } from '../../utils/index';


async function inputSchemaPath() {
return inquirer
.prompt([
{
type: 'input',
name: 'schemaPath',
message: `请输入 OpenAPI 3.0 的地址, 默认为 https://petstore.swagger.io/v2/swagger.json`,
},
])
.then((answer) => answer.schemaPath);
}

async function inputServersPath() {
return inquirer
.prompt([
{
type: 'input',
name: 'serversPath',
message: `请输入生成的 Services 的路径, 默认为 ./src/services`,
},
])
.then((answer) => answer.serversPath);
}

const openAPI = async () => {
const schemaPath = await inputSchemaPath() || "https://petstore.swagger.io/v2/swagger.json";
log.verbose('schemaPath', schemaPath);

const serversPath = await inputServersPath() || "./src/services";
log.verbose('serversPath', serversPath);

generateService({
schemaPath,
serversPath,
});
};

export const getSchema = async (schemaPath: string) => {
if (schemaPath.startsWith('http')) {
const protocol = schemaPath.startsWith('https:') ? https : http;
try {
const agent = new protocol.Agent({
rejectUnauthorized: false,
});
const json = await fetch(schemaPath, { agent }).then((rest) => rest.json());
return json;
} catch (error) {
// eslint-disable-next-line no-console
console.log('fetch openapi error:', error);
}
return null;
}
const schema = require(schemaPath);
return schema;
};

const getOpenAPIConfig = async (schemaPath: string) => {
const schema = await getSchema(schemaPath);
if (!schema) {
return null;
}
const openAPI = await converterSwaggerToOpenApi(schema);
return openAPI;
};

// 从 appName 生成 service 数据
export const generateService = async ({
requestLibPath,
schemaPath,
mockFolder,
...rest
}: GenerateServiceProps) => {
const openAPI = await getOpenAPIConfig(schemaPath);
const requestImportStatement = getImportStatement(requestLibPath);
const serviceGenerator = new ServiceGenerator(
{
namespace: 'API',
requestImportStatement,
enumStyle: 'string-literal',
...rest,
},
openAPI,
);
serviceGenerator.genFile();

if (mockFolder) {
await mockGenerator({
openAPI,
mockFolder: mockFolder || './mocks/',
});
}
};
export default openAPI;
1 change: 1 addition & 0 deletions src/commands/openapi/log.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-nocheck
import chalk from 'chalk';

// eslint-disable-next-line no-console
Expand Down
1 change: 1 addition & 0 deletions src/commands/openapi/mockGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-nocheck
import Mock from 'mockjs';
import fs from 'fs';
import pinyin from "tiny-pinyin";
Expand Down
1 change: 1 addition & 0 deletions src/commands/openapi/openAPIParserMock/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-nocheck
/* eslint-disable no-continue */
/* eslint-disable guard-for-in */
/* eslint-disable no-restricted-syntax */
Expand Down
Loading

0 comments on commit 6da1dc8

Please sign in to comment.