openapi-ts-request
Version:
Swagger2/OpenAPI3/Apifox to TypeScript/JavaScript, request client(support any client), request mock service, enum and enum translation, react-query/vue-query, type field label, JSON Schemas
224 lines (223 loc) • 8.45 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const lodash_1 = require("lodash");
const memoizee_1 = tslib_1.__importDefault(require("memoizee"));
const util_1 = require("../generator/util");
const primitives_1 = require("./primitives");
const util_2 = require("./util");
function getDateByName(name, parentsKey) {
if (!name || name.length < 1) {
return 'string';
}
if (Array.isArray(name)) {
return getDateByName([...name].pop(), name);
}
if (['nickname', 'name'].includes(name)) {
return 'cname';
}
if (['owner', 'firstName', 'lastName', 'username'].includes(name)) {
return 'name';
}
if (['avatar'].includes(name)) {
return 'avatar';
}
if (['group'].includes(name)) {
return 'group';
}
if (name.toLocaleLowerCase().endsWith('id')) {
return 'uuid';
}
if (name.toLocaleLowerCase().endsWith('type') ||
name.toLocaleLowerCase().endsWith('key') ||
['key'].includes(name)) {
return 'id';
}
if (name.toLocaleLowerCase().endsWith('label') || ['label'].includes(name)) {
const newParents = [...parentsKey];
newParents.pop();
const newType = getDateByName(newParents);
if (newType !== 'string' && newType !== 'csentence') {
return newType;
}
return 'label';
}
if (['email'].includes(name)) {
return 'email';
}
if (['password'].includes(name)) {
return 'string(16)';
}
if (['phone'].includes(name)) {
return 'phone';
}
if (['province'].includes(name)) {
return 'province';
}
if (['city'].includes(name)) {
return 'city';
}
if (['addr', 'address'].includes(name)) {
return 'county';
}
if (['country'].includes(name)) {
return 'country';
}
if (['url', 'imageUrl', 'href'].includes(name) ||
name.toLocaleLowerCase().endsWith('url') ||
name.toLocaleLowerCase().endsWith('urls') ||
name.toLocaleLowerCase().endsWith('image') ||
name.toLocaleLowerCase().endsWith('link')) {
return 'href';
}
if (name.toLocaleLowerCase().endsWith('errorcode')) {
return 'errorCode';
}
if (['type', 'status'].includes(name) ||
name.toLocaleLowerCase().endsWith('status') ||
name.toLocaleLowerCase().endsWith('type')) {
return 'status';
}
if (name.toLocaleLowerCase().endsWith('authority')) {
return 'authority';
}
return 'csentence';
}
function primitive(schemaParams, propsName) {
const schema = (0, util_2.objectify)(schemaParams);
const { type, format } = schema;
const value = primitives_1.primitives[`${type}_${format || getDateByName(propsName)}`] ||
primitives_1.primitives[type];
if ((0, lodash_1.isUndefined)(schema.example)) {
return value || `Unknown Type: ${schema.type}`;
}
return schema.example;
}
class OpenAPIGeneratorMockJs {
constructor(openAPI) {
this.sampleFromSchema = (schema, propsName, schemaSet = new Set()) => {
const schemaRef = (0, util_1.isReferenceObject)(schema) ? schema.$ref : null;
if (schemaRef) {
// 如果之前已经使用过该引用结构,直接返回null,不然会陷入无限递归的情况
if (schemaSet.has(schemaRef)) {
return null;
}
else {
schemaSet.add(schemaRef);
}
}
const localSchema = (schemaRef ? (0, util_2.get)(this.openAPI, schemaRef) : (0, util_2.objectify)(schema));
let type = localSchema.type;
const { properties, additionalProperties, items, anyOf, oneOf, allOf } = localSchema;
if (allOf) {
let obj = {};
allOf.forEach((item) => {
const newObj = this.sampleFromSchema(item, propsName, new Set(schemaSet));
if ((0, lodash_1.isObject)(newObj)) {
obj = Object.assign(Object.assign({}, obj), newObj);
}
});
return obj;
}
if (!type) {
if (properties) {
type = 'object';
}
else if (items) {
type = 'array';
}
else if (anyOf || oneOf) {
type = 'union';
}
else {
return null;
}
}
if (type === 'null') {
return null;
}
if (type === 'object') {
const props = (0, util_2.objectify)(properties);
const obj = {};
for (const name in props) {
obj[name] = this.sampleFromSchema(props[name], [...(propsName || []), name], new Set(schemaSet));
}
if (additionalProperties === true) {
obj.additionalProp1 = {};
return obj;
}
if (additionalProperties) {
const additionalProps = (0, util_2.objectify)(additionalProperties);
const additionalPropVal = this.sampleFromSchema(additionalProps, propsName, new Set(schemaSet));
for (let i = 1; i < 4; i += 1) {
obj[`additionalProp${i}`] = additionalPropVal;
}
}
return obj;
}
if (type === 'array') {
const item = this.sampleFromSchema(items, propsName, new Set(schemaSet));
return new Array(parseInt((Math.random() * 20).toFixed(0), 10)).fill(item);
}
if (type === 'union') {
const subschemas = anyOf || oneOf;
const subschemas_length = (subschemas && subschemas.length) || 0;
if (subschemas_length) {
const index = (0, util_2.getRandomInt)(0, subschemas_length);
const obj = this.sampleFromSchema(subschemas[index], propsName, new Set(schemaSet));
return obj;
}
}
if (localSchema.enum) {
if (localSchema.default) {
return localSchema.default;
}
return (0, util_2.normalizeArray)(localSchema.enum)[0];
}
if (type === 'file') {
return null;
}
return primitive(localSchema, propsName);
};
this.openAPI = openAPI;
this.sampleFromSchema = (0, memoizee_1.default)(this.sampleFromSchema);
}
parser() {
const openAPI = Object.assign({}, this.openAPI);
for (const path in openAPI.paths) {
for (const method in openAPI.paths[path]) {
const api = openAPI.paths[path][method];
for (const code in api.responses) {
const response = api.responses[code];
const mediaTypeKeys = (0, lodash_1.keys)(response.content);
if (mediaTypeKeys.length) {
let key;
if (mediaTypeKeys.includes('application/json')) {
key = 'application/json';
}
else if (mediaTypeKeys.includes('*/*')) {
key = '*/*';
}
else {
key = mediaTypeKeys[0];
}
const schema = (0, util_2.inferSchema)(response.content[key]);
if (schema) {
response.example = this.sampleFromSchema(schema);
}
}
}
if (!api.parameters)
continue;
for (const parameter of api.parameters) {
const schema = (0, util_2.inferSchema)(parameter);
parameter.example = schema
? this.sampleFromSchema(schema)
: null;
}
}
}
return openAPI;
}
}
exports.default = OpenAPIGeneratorMockJs;