auto-request
Version:
通过Yapi JSON Schema生成接口Axios或Taro接口
967 lines (897 loc) • 33.3 kB
JavaScript
;
var fs$1 = require('fs');
var prettier = require('prettier');
var jsonSchemaToTypescript = require('json-schema-to-typescript');
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n["default"] = e;
return Object.freeze(n);
}
var fs__namespace = /*#__PURE__*/_interopNamespace(fs$1);
var prettier__namespace = /*#__PURE__*/_interopNamespace(prettier);
const UPPERCASE = /[\p{Lu}]/u;
const LOWERCASE = /[\p{Ll}]/u;
const LEADING_CAPITAL = /^[\p{Lu}](?![\p{Lu}])/gu;
const IDENTIFIER = /([\p{Alpha}\p{N}_]|$)/u;
const SEPARATORS = /[_.\- ]+/;
const LEADING_SEPARATORS = new RegExp('^' + SEPARATORS.source);
const SEPARATORS_AND_IDENTIFIER = new RegExp(
SEPARATORS.source + IDENTIFIER.source,
'gu'
);
const NUMBERS_AND_IDENTIFIER = new RegExp('\\d+' + IDENTIFIER.source, 'gu');
const preserveCamelCase = (string, toLowerCase, toUpperCase) => {
let isLastCharLower = false;
let isLastCharUpper = false;
let isLastLastCharUpper = false;
for (let i = 0; i < string.length; i++) {
const character = string[i];
if (isLastCharLower && UPPERCASE.test(character)) {
string = string.slice(0, i) + '-' + string.slice(i);
isLastCharLower = false;
isLastLastCharUpper = isLastCharUpper;
isLastCharUpper = true;
i++;
} else if (
isLastCharUpper &&
isLastLastCharUpper &&
LOWERCASE.test(character)
) {
string = string.slice(0, i - 1) + '-' + string.slice(i - 1);
isLastLastCharUpper = isLastCharUpper;
isLastCharUpper = false;
isLastCharLower = true;
} else {
isLastCharLower =
toLowerCase(character) === character &&
toUpperCase(character) !== character;
isLastLastCharUpper = isLastCharUpper;
isLastCharUpper =
toUpperCase(character) === character &&
toLowerCase(character) !== character;
}
}
return string;
};
const preserveConsecutiveUppercase = (input, toLowerCase) => {
LEADING_CAPITAL.lastIndex = 0;
return input.replace(LEADING_CAPITAL, (m1) => toLowerCase(m1));
};
const postProcess = (input, toUpperCase) => {
SEPARATORS_AND_IDENTIFIER.lastIndex = 0;
NUMBERS_AND_IDENTIFIER.lastIndex = 0;
return input
.replace(SEPARATORS_AND_IDENTIFIER, (_, identifier) =>
toUpperCase(identifier)
)
.replace(NUMBERS_AND_IDENTIFIER, (m) => toUpperCase(m));
};
const camelCase = (input, options) => {
if (!(typeof input === 'string' || Array.isArray(input))) {
throw new TypeError('Expected the input to be `string | string[]`');
}
options = {
pascalCase: false,
preserveConsecutiveUppercase: false,
...options,
};
if (Array.isArray(input)) {
input = input
.map((x) => x.trim())
.filter((x) => x.length)
.join('-');
} else {
input = input.trim();
}
if (input.length === 0) {
return '';
}
const toLowerCase =
options.locale === false
? (string) => string.toLowerCase()
: (string) => string.toLocaleLowerCase(options.locale);
const toUpperCase =
options.locale === false
? (string) => string.toUpperCase()
: (string) => string.toLocaleUpperCase(options.locale);
if (input.length === 1) {
return options.pascalCase ? toUpperCase(input) : toLowerCase(input);
}
const hasUpperCase = input !== toLowerCase(input);
if (hasUpperCase) {
input = preserveCamelCase(input, toLowerCase, toUpperCase);
}
input = input.replace(LEADING_SEPARATORS, '');
if (options.preserveConsecutiveUppercase) {
input = preserveConsecutiveUppercase(input, toLowerCase);
} else {
input = toLowerCase(input);
}
if (options.pascalCase) {
input = toUpperCase(input.charAt(0)) + input.slice(1);
}
return postProcess(input, toUpperCase);
};
function getDefaultExportFromCjs (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
var clone$1 = {exports: {}};
clone$1.exports;
(function (module) {
var clone = (function() {
function _instanceof(obj, type) {
return type != null && obj instanceof type;
}
var nativeMap;
try {
nativeMap = Map;
} catch(_) {
// maybe a reference error because no `Map`. Give it a dummy value that no
// value will ever be an instanceof.
nativeMap = function() {};
}
var nativeSet;
try {
nativeSet = Set;
} catch(_) {
nativeSet = function() {};
}
var nativePromise;
try {
nativePromise = Promise;
} catch(_) {
nativePromise = function() {};
}
/**
* Clones (copies) an Object using deep copying.
*
* This function supports circular references by default, but if you are certain
* there are no circular references in your object, you can save some CPU time
* by calling clone(obj, false).
*
* Caution: if `circular` is false and `parent` contains circular references,
* your program may enter an infinite loop and crash.
*
* @param `parent` - the object to be cloned
* @param `circular` - set to true if the object to be cloned may contain
* circular references. (optional - true by default)
* @param `depth` - set to a number if the object is only to be cloned to
* a particular depth. (optional - defaults to Infinity)
* @param `prototype` - sets the prototype to be used when cloning an object.
* (optional - defaults to parent prototype).
* @param `includeNonEnumerable` - set to true if the non-enumerable properties
* should be cloned as well. Non-enumerable properties on the prototype
* chain will be ignored. (optional - false by default)
*/
function clone(parent, circular, depth, prototype, includeNonEnumerable) {
if (typeof circular === 'object') {
depth = circular.depth;
prototype = circular.prototype;
includeNonEnumerable = circular.includeNonEnumerable;
circular = circular.circular;
}
// maintain two arrays for circular references, where corresponding parents
// and children have the same index
var allParents = [];
var allChildren = [];
var useBuffer = typeof Buffer != 'undefined';
if (typeof circular == 'undefined')
circular = true;
if (typeof depth == 'undefined')
depth = Infinity;
// recurse this function so we don't reset allParents and allChildren
function _clone(parent, depth) {
// cloning null always returns null
if (parent === null)
return null;
if (depth === 0)
return parent;
var child;
var proto;
if (typeof parent != 'object') {
return parent;
}
if (_instanceof(parent, nativeMap)) {
child = new nativeMap();
} else if (_instanceof(parent, nativeSet)) {
child = new nativeSet();
} else if (_instanceof(parent, nativePromise)) {
child = new nativePromise(function (resolve, reject) {
parent.then(function(value) {
resolve(_clone(value, depth - 1));
}, function(err) {
reject(_clone(err, depth - 1));
});
});
} else if (clone.__isArray(parent)) {
child = [];
} else if (clone.__isRegExp(parent)) {
child = new RegExp(parent.source, __getRegExpFlags(parent));
if (parent.lastIndex) child.lastIndex = parent.lastIndex;
} else if (clone.__isDate(parent)) {
child = new Date(parent.getTime());
} else if (useBuffer && Buffer.isBuffer(parent)) {
if (Buffer.allocUnsafe) {
// Node.js >= 4.5.0
child = Buffer.allocUnsafe(parent.length);
} else {
// Older Node.js versions
child = new Buffer(parent.length);
}
parent.copy(child);
return child;
} else if (_instanceof(parent, Error)) {
child = Object.create(parent);
} else {
if (typeof prototype == 'undefined') {
proto = Object.getPrototypeOf(parent);
child = Object.create(proto);
}
else {
child = Object.create(prototype);
proto = prototype;
}
}
if (circular) {
var index = allParents.indexOf(parent);
if (index != -1) {
return allChildren[index];
}
allParents.push(parent);
allChildren.push(child);
}
if (_instanceof(parent, nativeMap)) {
parent.forEach(function(value, key) {
var keyChild = _clone(key, depth - 1);
var valueChild = _clone(value, depth - 1);
child.set(keyChild, valueChild);
});
}
if (_instanceof(parent, nativeSet)) {
parent.forEach(function(value) {
var entryChild = _clone(value, depth - 1);
child.add(entryChild);
});
}
for (var i in parent) {
var attrs;
if (proto) {
attrs = Object.getOwnPropertyDescriptor(proto, i);
}
if (attrs && attrs.set == null) {
continue;
}
child[i] = _clone(parent[i], depth - 1);
}
if (Object.getOwnPropertySymbols) {
var symbols = Object.getOwnPropertySymbols(parent);
for (var i = 0; i < symbols.length; i++) {
// Don't need to worry about cloning a symbol because it is a primitive,
// like a number or string.
var symbol = symbols[i];
var descriptor = Object.getOwnPropertyDescriptor(parent, symbol);
if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {
continue;
}
child[symbol] = _clone(parent[symbol], depth - 1);
if (!descriptor.enumerable) {
Object.defineProperty(child, symbol, {
enumerable: false
});
}
}
}
if (includeNonEnumerable) {
var allPropertyNames = Object.getOwnPropertyNames(parent);
for (var i = 0; i < allPropertyNames.length; i++) {
var propertyName = allPropertyNames[i];
var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName);
if (descriptor && descriptor.enumerable) {
continue;
}
child[propertyName] = _clone(parent[propertyName], depth - 1);
Object.defineProperty(child, propertyName, {
enumerable: false
});
}
}
return child;
}
return _clone(parent, depth);
}
/**
* Simple flat clone using prototype, accepts only objects, usefull for property
* override on FLAT configuration object (no nested props).
*
* USE WITH CAUTION! This may not behave as you wish if you do not know how this
* works.
*/
clone.clonePrototype = function clonePrototype(parent) {
if (parent === null)
return null;
var c = function () {};
c.prototype = parent;
return new c();
};
// private utility functions
function __objToStr(o) {
return Object.prototype.toString.call(o);
}
clone.__objToStr = __objToStr;
function __isDate(o) {
return typeof o === 'object' && __objToStr(o) === '[object Date]';
}
clone.__isDate = __isDate;
function __isArray(o) {
return typeof o === 'object' && __objToStr(o) === '[object Array]';
}
clone.__isArray = __isArray;
function __isRegExp(o) {
return typeof o === 'object' && __objToStr(o) === '[object RegExp]';
}
clone.__isRegExp = __isRegExp;
function __getRegExpFlags(re) {
var flags = '';
if (re.global) flags += 'g';
if (re.ignoreCase) flags += 'i';
if (re.multiline) flags += 'm';
return flags;
}
clone.__getRegExpFlags = __getRegExpFlags;
return clone;
})();
if (module.exports) {
module.exports = clone;
}
} (clone$1));
var cloneExports = clone$1.exports;
var clone = /*@__PURE__*/getDefaultExportFromCjs(cloneExports);
// 读取入口文件
const readFileSync = (source) => {
try {
return fs__namespace.readFileSync(source, 'utf8');
}
catch (err) {
console.error(err, `${source}读取出错`);
throw err;
}
};
const parseJSON = (json) => {
try {
return JSON.parse(json);
}
catch (err) {
return json;
}
};
const analysRequstMap = (stream) => {
const apiQueue = [];
for (let [url, urlValue] of Object.entries(stream)) {
for (let [method, schema] of Object.entries(urlValue)) {
apiQueue.push({ method, url, schema });
}
}
return apiQueue;
};
const analysiAxiosRules = (stream) => {
const jsonStream = analysRequstMap(parseJSON(stream).paths);
return jsonStream;
};
const analysiYapiRules = (stream) => {
const jsonStream = analysRequstMap(parseJSON(stream).paths);
return jsonStream;
};
const pascalCase = (str) => {
return camelCase(str, { pascalCase: true });
};
const pascalCaseReplaceString = (str) => {
return camelCase(str.replace(/[\/|\{|\}|\?\$]/g, ''), { pascalCase: true });
};
const formatUrl = (parameters = [], url) => {
const pathParams = parameters.filter((paramsItem) => paramsItem.in === 'path');
return pathParams.reduce((pre, { name }) => {
const reg = new RegExp(`{${name}}`);
pre = pre.replace(reg, '${' + pascalCase(name) + '}');
return pre;
}, url);
};
const createMethodsName = (url, method, parameters = []) => {
return pascalCaseReplaceString(`${formatUrl(parameters, url)}${pascalCase(method)}`);
};
const filterPathParams = (parameters = [], type) => {
const urlPathParams = parameters.filter((paramsItem) => ['path'].includes(paramsItem.in));
if (type === 'ts') {
return (urlPathParams.reduce((pre, next) => {
pre = `${pascalCase(next.name)}:any,` + pre;
return pre;
}, '') + 'params: P, options?:any');
}
return (urlPathParams.reduce((pre, next) => {
pre = `${pascalCase(next.name)},` + pre;
return pre;
}, '') + 'params, options');
};
const rendeFetchPre = (type, fetchType) => {
if (type === 'taro') {
if (fetchType === 'js') {
return `import Taro from '@tarojs/taro';\n`;
}
return `import Taro, { RequestTask } from '@tarojs/taro';\n`;
}
if (fetchType === 'js') {
return `import axios from 'axios';\n`;
}
return `import axios, {AxiosResponse} from 'axios';\n`;
};
const formatTsRequest = (name) => {
return `${name}Requset`;
};
const formatTsResponse = (name) => {
return `${name}Response`;
};
const formatRequireds = (reqParams = []) => {
return reqParams.filter((params) => params.required === true).map((params) => params.name);
};
const formatProperties = (reqParams = []) => {
return reqParams.reduce((pre, next) => {
pre[next.name] = next;
return pre;
}, {});
};
const renderTsPreImport = (prePath, preDefine) => {
return `import {
${preDefine}
} from '${prePath}'; \n
`;
};
const deepCopy = (json) => clone(json);
const createTypeDefineObj = (title, properties, type, required) => {
return {
key: title,
propertiesKey: {
$ref: `#/definitions/${title}`
},
definitionsKey: {
title: title,
type: type,
additionalProperties: false,
properties: properties,
required: required,
}
};
};
// 处理response的properties
const deepFormatResponse = (preProperties, schemas = [], createTypeDefineObjParams) => {
const { title, type } = createTypeDefineObjParams;
if (!preProperties.properties) {
return;
}
for (const [key, value] of Object.entries(preProperties.properties)) {
const pascalCaseKey = pascalCase(key);
const refTitle = `${title}${pascalCaseKey}`;
const paramsProperties = Object.assign(createTypeDefineObjParams, { title: refTitle });
if (value.type === 'string') {
continue;
}
if (value.type === 'object') {
const schemaItem = createTypeDefineObj(refTitle, deepCopy(value.properties), type, value.required);
schemas.push(schemaItem);
Object.assign(value, {
$ref: `#/definitions/${refTitle}`
});
deepFormatResponse(value, schemas, paramsProperties);
}
if (value.type === 'array') {
const schemaItem = createTypeDefineObj(refTitle, deepCopy(value.items.properties), type, value.items.required);
schemas.push(schemaItem);
delete value.items.properties;
Object.assign(value.items, {
$ref: `#/definitions/${refTitle}`
});
deepFormatResponse(value.items, schemas, paramsProperties);
}
}
};
class BaseRequest {
state;
constructor(method, url, schema, fetchType, host) {
this.state = {
methodName: createMethodsName(url, method, schema.parameters),
url: formatUrl(schema.parameters, url),
fetchType: fetchType,
method: method,
schema: schema,
host: host,
tsReq: {},
tsRes: {},
};
this.state.tsReq = this.renderTsDefineReq();
}
renderAxiosRes(title) {
try {
const isArray = this.state.schema.responses['200'].schema.type === 'array' ? '[]' : '';
if (this.state.fetchType === 'axios') {
return `AxiosResponse <${title}${isArray}>`;
}
return `${title}${isArray}`;
}
catch (err) {
return `any`;
}
}
renderPromiseType() {
if (this.state.fetchType === 'axios') {
return 'Promise<T>';
}
return `RequestTask <T>`;
}
renderMethod(type) {
const responseTsList = this.renderTsDefineResFeature();
const requestTsList = this.renderTsDefineReqFeature();
const ReqTsTitle = (requestTsList[0] && requestTsList[0].key) || 'any';
const ResTsTitle = (responseTsList[0] && responseTsList[0].key) || 'any';
if (type === 'ts') {
return `\n
export const ${this.state.methodName} =
<P extends ${ReqTsTitle}, T = ${this.renderAxiosRes(ResTsTitle)}>
(${filterPathParams(this.state.schema.parameters, type)}): ${this.renderPromiseType()} => {
${this.renderFetchRequest()}
}
`;
}
return `\n
export const ${this.state.methodName} =
(${filterPathParams(this.state.schema.parameters, type)}) => {
${this.renderFetchRequest()}
}
`;
}
}
class RequestGet extends BaseRequest {
constructor(method, url, schema, fetchType, host) {
super(method, url, schema, fetchType, host);
}
renderTsDefineReq() {
const { parameters = [] } = this.state.schema;
const reqParams = parameters.filter((params) => params.in === 'query');
return {
title: formatTsRequest(this.state.methodName),
properties: formatProperties(reqParams),
required: formatRequireds(reqParams),
additionalProperties: false,
};
}
renderTsDefineReqFeature() {
const { parameters = [] } = this.state.schema;
const reqParams = parameters.filter((params) => params.in === 'query');
const title = formatTsRequest(this.state.methodName);
const properties = formatProperties(reqParams);
const required = formatRequireds(reqParams);
const reqList = [];
const req = createTypeDefineObj(title, properties, 'object', required);
reqList.push(req);
return reqList;
}
renderTsDefineResFeature() {
try {
const schema = deepCopy(this.state.schema.responses['200'].schema);
const properties = [];
const title = formatTsResponse(this.state.methodName);
if (['object'].includes(schema.type)) {
properties.push(createTypeDefineObj(title, schema.properties, schema.type, schema.required));
deepFormatResponse(schema, properties, { title: title, properties: schema.properties, type: schema.type });
}
if (['array'].includes(schema.type)) {
const schemaArray = schema.items;
properties.push(createTypeDefineObj(title, schemaArray.properties, schemaArray.type, schemaArray.required));
deepFormatResponse(schemaArray, properties, { title: title, properties: schemaArray.properties, type: schemaArray.type });
}
return properties;
}
catch (err) {
console.log(`解析错误:${this.state.url} response schema`);
return [];
}
}
renderFetchRequest() {
const { schema, host, url, method } = this.state;
const { summary } = schema;
if (this.state.fetchType === 'axios') {
return `
// ${summary}
return axios.request({
url: \`${host}${url}\`,
method: '${method}',
params: params,
...options,
})
`;
}
return `
// ${summary}
return Taro.request({
url: \`${host}${url}\`,
method: '${method}',
data: params,
...options,
})
`;
}
}
class RequestPost extends BaseRequest {
constructor(method, url, schema, fetchType, host) {
super(method, url, schema, fetchType, host);
}
renderTsDefineReqFeature() {
try {
const { parameters = [] } = this.state.schema;
const reqParams = parameters.filter((params) => params.in === 'body');
if (reqParams.length === 0) {
return [];
}
const [firstParams] = reqParams;
const title = formatTsRequest(this.state.methodName);
const properties = firstParams.schema.properties;
const required = firstParams.schema.required;
const reqList = [];
const req = createTypeDefineObj(title, properties, 'object', required);
reqList.push(req);
for (let [key, value] of Object.entries(firstParams.schema.properties)) {
const pascalCaseKey = pascalCase(key);
if (value.type === 'array') {
reqList.push(createTypeDefineObj(`${title}${pascalCaseKey}`, deepCopy(value.items.properties), value.items.type));
delete value.items.properties;
Object.assign(value.items, {
$ref: `#/definitions/${title}${pascalCaseKey}`
});
}
// if (value.type === 'object') {
// reqList.push(createTypeDefineObj(`${title}${pascalCaseKey}`, deepCopy(value.properties), value.type));
// }
}
return reqList;
}
catch (err) {
console.log(`解析错误:${this.state.url} request schema`);
return [];
}
}
renderTsDefineReq() {
const { parameters = [] } = this.state.schema;
const reqParams = parameters.filter((params) => params.in === 'body');
if (reqParams.length > 0) {
const [firstParams] = reqParams;
return {
title: formatTsRequest(this.state.methodName),
properties: firstParams.schema.properties,
required: firstParams.schema.required,
additionalProperties: false,
};
}
return {
title: formatTsRequest(this.state.methodName),
properties: formatProperties(reqParams),
required: formatRequireds(reqParams),
additionalProperties: true,
};
}
renderTsDefineResFeature() {
// const schema = deepCopy(this.state.schema.responses['200'].schema) as SwaggerParamsPathsMethodsSchema;
// const properties = [];
// const title = formatTsResponse(this.state.methodName);
// if (schema.type === 'object') {
// properties.push(createTypeDefineObj(title, schema.properties, schema.type));
// }
// if (schema.properties === undefined) { return properties; }
// for (const [key, value] of Object.entries(schema.properties)) {
// const pascalCaseKey = pascalCase(key);
// if (value.type === 'array') {
// // properties.push(deepCopy(value));
// properties.push(createTypeDefineObj(`${title}${pascalCaseKey}`, deepCopy(value.items.properties), value.items.type));
// delete value.items.properties;
// Object.assign(value.items, {
// $ref: `#/definitions/${title}${pascalCaseKey}`
// })
// }
// if (value.type === 'object') {
// properties.push(createTypeDefineObj(`${title}${pascalCaseKey}`, deepCopy(value.properties), value.type));
// }
// }
// return properties;
try {
const schema = deepCopy(this.state.schema.responses['200'].schema);
const properties = [];
const title = formatTsResponse(this.state.methodName);
// if (schema.type === 'object') {
// properties.push(createTypeDefineObj(title, schema.properties, schema.type, schema.required));
// }
// deepFormatResponse(schema, properties, { title: title, properties: schema.properties, type: schema.type });
if (['object'].includes(schema.type)) {
properties.push(createTypeDefineObj(title, schema.properties, schema.type, schema.required));
if (schema.properties === undefined) {
return properties;
}
deepFormatResponse(schema, properties, { title: title, properties: schema.properties, type: schema.type });
}
if (['array'].includes(schema.type)) {
const schemaArray = schema.items;
properties.push(createTypeDefineObj(title, schemaArray.properties, schemaArray.type, schemaArray.required));
deepFormatResponse(schemaArray, properties, { title: title, properties: schemaArray.properties, type: schemaArray.type });
}
return properties;
}
catch (err) {
console.log(`解析错误:${this.state.url} response schema`);
return [];
}
}
renderFetchRequest() {
const { schema, host, url, method } = this.state;
const { summary } = schema;
if (this.state.fetchType === 'axios') {
return `
// ${summary}
return axios.request({
url: \`${host}${url}\`,
method: '${method}',
data: params,
...options,
})
`;
}
return `
// ${summary}
return Taro.request({
url: \`${host}${url}\`,
method: '${method}',
data: params,
...options,
})
`;
}
}
const fs = require('fs');
// export const checkHasFile = async (filePath: string) => {
// try {
// await access(filePath, constants.R_OK | constants.W_OK);
// console.log('can access');
// } catch {
// console.error('cannot access');
// }
// };
const createDir = (dirPath) => {
return new Promise((resolve, reject) => {
fs.mkdir(dirPath, function (err) {
if (err) {
console.log('目录创建失败,可能已存在');
}
else {
console.log(`接口目录路径:【${dirPath}】`);
}
resolve('');
});
});
};
class CreateApi {
state = {
input: '',
fetchType: 'axios',
templateType: 'ts',
inputStream: '',
options: { host: '', preFix: '' },
methodsQueue: [],
resultQueue: [],
createCount: 0,
};
constructor(input, fetchType = 'axios', options = { host: '', preFix: '', templateType: 'ts' }) {
if (!['axios', 'taro'].includes(fetchType)) {
throw `${fetchType}字段出错, 必须是${'axios'}|${'taro'}`;
}
this.state = {
input: input,
templateType: options.templateType || 'ts',
fetchType: fetchType,
inputStream: '',
options: options,
methodsQueue: [],
resultQueue: [],
createCount: 0,
};
this.state.inputStream = readFileSync(this.state.input);
this.state.options.host = this.state.options.host + this.state.options.preFix || '';
console.log(`=====host:[${this.state.options.host}]=====\n`);
this.state.methodsQueue = this.analysiRules(this.state.inputStream);
this.state.resultQueue = this.generateMethod(this.state.methodsQueue);
}
// 生成接口类型
generateMethod(queue) {
return queue.map(({ method, url, schema }) => {
this.state.createCount++;
if (['post', 'put'].includes(method)) {
return new RequestPost(method, url, schema, this.state.fetchType, this.state.options.host);
}
return new RequestGet(method, url, schema, this.state.fetchType, this.state.options.host);
});
}
// 解析规则
analysiRules(stream) {
if (this.state.fetchType === 'axios') {
return analysiAxiosRules(stream);
}
return analysiYapiRules(stream);
}
// 生成接口文件
handleRenderApiFile() {
return this.state.resultQueue.reduce((pre, next) => {
pre =
pre +
`
${next.renderMethod(this.state.templateType)}
`;
return pre;
}, '');
}
handleRenderApiTsFileFeature() {
const init = {
title: 'Api',
type: 'object',
properties: {},
definitions: {},
additionalProperties: false,
preDefine: '',
};
return this.state.resultQueue.reduce((pre, next) => {
const tsQueue = next.renderTsDefineResFeature();
tsQueue.forEach((item) => {
const { key, propertiesKey, definitionsKey } = item;
pre.properties[key] = propertiesKey;
pre.definitions[key] = definitionsKey;
pre.preDefine = pre.preDefine + `${key},`;
});
const tsQueueReq = next.renderTsDefineReqFeature();
tsQueueReq.forEach((item) => {
const { key, propertiesKey, definitionsKey } = item;
pre.properties[key] = propertiesKey;
pre.definitions[key] = definitionsKey;
pre.preDefine = pre.preDefine + `${key},`;
});
return pre;
}, init);
}
// 生成接口
generateFile(outputPath = '') {
const apiDefineStream = this.handleRenderApiTsFileFeature();
// console.log(JSON.stringify(mock));
// const apiDefineStream = this.handleRenderApiTsFile();
const tsDefine = apiDefineStream.preDefine;
delete apiDefineStream.preDefine;
const definePath = './index.define';
const tsPreDefineStream = renderTsPreImport(definePath, tsDefine);
const apiStream = this.state.templateType === 'ts' ?
rendeFetchPre(this.state.fetchType, this.state.templateType) +
tsPreDefineStream +
this.handleRenderApiFile() : rendeFetchPre(this.state.fetchType, this.state.templateType) + this.handleRenderApiFile();
createDir(outputPath).then(() => {
fs__namespace.writeFileSync(`${outputPath}/index.${this.state.templateType}`, prettier__namespace.format(apiStream, { semi: false, parser: 'typescript' }));
// fs.writeFileSync(`${outputPath}/index.test.json`, prettier.format(JSON.stringify(apiDefineStream), { semi: false, parser: "json" }));
jsonSchemaToTypescript.compile(apiDefineStream, 'Api').then((ts) => {
fs__namespace.writeFileSync(outputPath + `${definePath}.ts`, ts);
});
console.log(`成功生成【${this.state.createCount}】个接口`);
console.log('文件生成成功~');
});
}
}
module.exports = CreateApi;