UNPKG

node-web-mvc

Version:
120 lines (119 loc) 6.06 kB
"use strict"; 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;