node-web-mvc
Version:
node spring mvc
120 lines (119 loc) • 6.06 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const metadata_1 = require("../../servlets/annotations/annotation/metadata");
const RuntimeAnnotation_1 = __importDefault(require("../../servlets/annotations/annotation/RuntimeAnnotation"));
const ApiModel_1 = __importDefault(require("../annotations/ApiModel"));
const ApiModelProperty_1 = __importDefault(require("../annotations/ApiModelProperty"));
const typemappings_1 = __importDefault(require("./typemappings"));
class Schemas {
constructor() {
this.typemappings = new typemappings_1.default();
}
makeRef(name) {
return `#/components/schemas/${name}`;
}
/**
* 获取最后可用的定义数据
* @param dataType
*/
build() {
const schemas = {};
const models = RuntimeAnnotation_1.default.getAnnotations(ApiModel_1.default);
for (const model of models) {
this.buildApiModel(model.ctor.name, model.ctor, model.nativeAnnotation, schemas);
}
// 处理引用类型
this.buildApiModelRefrerences(schemas);
// 返回定义
return schemas;
}
buildApiModel(modelName, clazzType, anno, schemas, fillRuntimeType = false) {
// 构建属性
const properties = this.buildApiModelProperties(clazzType, fillRuntimeType);
return schemas[modelName] = {
title: anno.value,
description: anno.description,
properties: properties,
// allOf: parentModel && [
// {
// title: anno.value,
// description: anno.description,
// properties: properties
// },
// { $ref: this.makeRef(parentModel.ctor.name) },
// ]
};
}
buildApiModelProperties(clazzType, fillRuntimeType = false) {
var _a;
const modelProperties = {};
const keys = RuntimeAnnotation_1.default.getClazzPropertyKeys(clazzType);
for (const key of keys) {
if (modelProperties[key])
continue;
const basicProperty = RuntimeAnnotation_1.default.getPropertyAnnotations(clazzType, key)[0];
const property = RuntimeAnnotation_1.default.getPropertyAnnotation(clazzType, key, ApiModelProperty_1.default);
const anno = property === null || property === void 0 ? void 0 : property.nativeAnnotation;
const dataType = (basicProperty === null || basicProperty === void 0 ? void 0 : basicProperty.dataType) || (0, metadata_1.buildRuntimeType)((_a = anno.example) === null || _a === void 0 ? void 0 : _a.constructor, null);
const name = (property === null || property === void 0 ? void 0 : property.name) || (basicProperty === null || basicProperty === void 0 ? void 0 : basicProperty.name);
const typeInfo = this.typemappings.make(dataType);
modelProperties[name] = Object.assign({ description: anno === null || anno === void 0 ? void 0 : anno.value, example: anno === null || anno === void 0 ? void 0 : anno.example, runtimeType: fillRuntimeType ? dataType : undefined, enum: !(anno === null || anno === void 0 ? void 0 : anno.enum) ? undefined : Object.keys(anno.enum).filter((m) => isNaN(m)) }, typeInfo);
}
return modelProperties;
}
buildApiModelRefrerences(schemas) {
for (const genericType of this.typemappings.referenceTypes) {
this.buildApiGenericModel(schemas, genericType);
}
}
buildApiGenericModel(schemas, genericTypeRef) {
const refType = genericTypeRef.refType;
const name = genericTypeRef.name;
const runtimeType = genericTypeRef.runtimeType;
if (!refType.$ref || schemas[name]) {
// 如果当前泛型已构建过,则跳过
return;
}
const anno = { value: runtimeType.fullName, description: '' };
const model = this.buildApiModel(name, runtimeType.clazz, anno, schemas, true);
const properties = {};
// if (!baseModel && !genericTypeRef.clazzType) {
// // 如果没有baseModel,无法生成,跳过
// console.warn('OpenApi: Cannot found ref:' + type2.name);
// return;
// }
Object.keys(model.properties).map((key) => {
var _a;
const item = model.properties[key];
const itemRuntimeType = item.runtimeType;
if (itemRuntimeType.tp) {
// 如果是泛型填充类型
const fillType = runtimeType.args.find((m) => m.at == itemRuntimeType.name);
const newFillType = Object.assign(Object.assign({}, fillType), { fullName: fillType === null || fillType === void 0 ? void 0 : fillType.name });
properties[key] = fillType ? this.typemappings.make(newFillType) : item;
}
else if (((_a = itemRuntimeType.args) === null || _a === void 0 ? void 0 : _a.length) > 0) {
const newArgs = itemRuntimeType.args.map((m, i) => {
if (!m.tp) {
return m;
}
return runtimeType.args.find((r) => r.at == m.name) || m;
});
// 如果当前属性为泛型
const newRuntimeType = Object.assign(Object.assign({}, itemRuntimeType), { args: newArgs, fullName: itemRuntimeType.name + `<${newArgs.map((m) => `${m.name}${m.array ? '[]' : ''}`).join(',')}>`, tp: false });
const info = this.typemappings.make(newRuntimeType);
properties[key] = info;
}
else {
properties[key] = item;
}
// 删除runtimeType属性
delete item.runtimeType;
});
schemas[name] = Object.assign(Object.assign({}, model), { properties: properties });
}
}
exports.default = Schemas;