UNPKG

erest

Version:

Easy to build api server depend on @leizm/web and express.

309 lines (308 loc) 14.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = schemaDocs; const params_1 = require("../../params"); const utils_1 = require("./utils"); function schemaDocs(data) { function _parseType(type) { return !type || data.typeManager.has(type) ? (0, utils_1.stringOrEmpty)(type) : `[${type}](#${type.replace("[]", "").toLocaleLowerCase()})`; } function typeDocString(typeDoc) { return (0, utils_1.fieldString)([ (0, utils_1.stringOrEmpty)(typeDoc.name), _parseType(typeDoc.tsType || "unknown"), (0, utils_1.stringOrEmpty)(typeDoc.description), (0, utils_1.itemTF)(typeDoc.isDefaultFormat), (0, utils_1.stringOrEmpty)(""), // 默认值暂时为空 (0, utils_1.itemTF)(!typeDoc.isParamsRequired), // 非必填参数表示可选 (0, utils_1.stringOrEmpty)(""), // 参数暂时为空 ]); } function generateZodSchemaInfo(schemaName, zodSchema) { const res = []; res.push(`## ${schemaName}`); if ((0, params_1.isZodSchema)(zodSchema) && zodSchema._def) { const tableHead = (0, utils_1.tableHeader)(["字段", "类型", "备注", "格式化", "默认值", "必填", "参数"]); res.push(tableHead); const typeName = zodSchema._def .typeName || zodSchema._def .type; // 处理lazy类型 const typeValue = zodSchema._def.type; if (typeName === "ZodLazy" || typeName === "lazy" || typeValue === "lazy") { const getter = zodSchema._def.getter; if (getter) { try { const innerSchema = getter(); const innerTypeName = innerSchema._def.typeName || innerSchema._def.type; if ((innerTypeName === "ZodObject" || innerTypeName === "object") && innerSchema ._def.shape) { let shape = innerSchema._def.shape; // 如果shape是函数,调用它获取实际的shape if (typeof shape === "function") { shape = shape(); } for (const [fieldName, fieldSchema] of Object.entries(shape)) { const fieldInfo = extractZodFieldInfo(fieldName, fieldSchema); res.push((0, utils_1.fieldString)([ (0, utils_1.stringOrEmpty)(fieldName), (0, utils_1.stringOrEmpty)(fieldInfo.type), (0, utils_1.stringOrEmpty)(fieldInfo.description), (0, utils_1.itemTF)(true), (0, utils_1.stringOrEmpty)(fieldInfo.defaultValue), (0, utils_1.itemTF)(fieldInfo.required), (0, utils_1.stringOrEmpty)(fieldInfo.params), ])); } } else { // 非对象的lazy类型 const fieldInfo = extractZodFieldInfo(schemaName, innerSchema); res.push((0, utils_1.fieldString)([ (0, utils_1.stringOrEmpty)(schemaName), (0, utils_1.stringOrEmpty)(fieldInfo.type), (0, utils_1.stringOrEmpty)(fieldInfo.description), (0, utils_1.itemTF)(true), (0, utils_1.stringOrEmpty)(fieldInfo.defaultValue), (0, utils_1.itemTF)(fieldInfo.required), (0, utils_1.stringOrEmpty)(fieldInfo.params), ])); } } catch (_e) { // 如果无法解析lazy类型,显示为lazy类型 const fieldInfo = extractZodFieldInfo(schemaName, zodSchema); res.push((0, utils_1.fieldString)([ (0, utils_1.stringOrEmpty)(schemaName), (0, utils_1.stringOrEmpty)(fieldInfo.type), (0, utils_1.stringOrEmpty)(fieldInfo.description), (0, utils_1.itemTF)(true), (0, utils_1.stringOrEmpty)(fieldInfo.defaultValue), (0, utils_1.itemTF)(fieldInfo.required), (0, utils_1.stringOrEmpty)(fieldInfo.params), ])); } } } else if ((typeName === "ZodObject" || typeName === "object") && zodSchema._def.shape) { const shape = zodSchema._def.shape; for (const [fieldName, fieldSchema] of Object.entries(shape)) { const fieldInfo = extractZodFieldInfo(fieldName, fieldSchema); res.push((0, utils_1.fieldString)([ (0, utils_1.stringOrEmpty)(fieldName), (0, utils_1.stringOrEmpty)(fieldInfo.type), (0, utils_1.stringOrEmpty)(fieldInfo.description), (0, utils_1.itemTF)(true), // 默认格式化 (0, utils_1.stringOrEmpty)(fieldInfo.defaultValue), (0, utils_1.itemTF)(fieldInfo.required), (0, utils_1.stringOrEmpty)(fieldInfo.params), ])); } } else { // 非对象类型的schema const fieldInfo = extractZodFieldInfo(schemaName, zodSchema); res.push((0, utils_1.fieldString)([ (0, utils_1.stringOrEmpty)(schemaName), (0, utils_1.stringOrEmpty)(fieldInfo.type), (0, utils_1.stringOrEmpty)(fieldInfo.description), (0, utils_1.itemTF)(true), (0, utils_1.stringOrEmpty)(fieldInfo.defaultValue), (0, utils_1.itemTF)(fieldInfo.required), (0, utils_1.stringOrEmpty)(fieldInfo.params), ])); } } return res.join("\n"); } function extractZodFieldInfo(fieldName, zodSchema) { const info = { type: "unknown", description: "", required: true, defaultValue: "", params: "", }; if (!zodSchema || !zodSchema._def) { return info; } // 首先尝试获取describe信息 const zodSchemaWithDescription = zodSchema; if (zodSchemaWithDescription.description) { info.description = zodSchemaWithDescription.description; } const typeName = zodSchema._def.typeName || zodSchema._def.type; const typeValue = zodSchema.def.type; switch (typeName) { case "ZodString": case "string": info.type = "string"; if (!info.description) info.description = "字符串类型"; break; case "ZodNumber": case "number": info.type = "number"; if (!info.description) info.description = "数字类型"; break; case "ZodBoolean": case "boolean": info.type = "boolean"; if (!info.description) info.description = "布尔类型"; break; case "ZodDate": case "date": info.type = "Date"; if (!info.description) info.description = "日期类型"; break; case "ZodArray": case "array": { const typeField = zodSchema._def.type; const innerType = typeField ? extractZodFieldInfo("", typeField) : { type: "unknown" }; info.type = `${innerType.type}[]`; if (!info.description) info.description = "数组类型"; break; } case "ZodObject": case "object": info.type = "object"; if (!info.description) info.description = "对象类型"; break; case "ZodEnum": case "enum": info.type = "enum"; if (!info.description) info.description = "枚举类型"; if (zodSchema._def.values) { const values = zodSchema._def.values; info.params = Array.isArray(values) ? values.join(", ") : String(values); } break; case "ZodOptional": case "optional": { const innerInfo = extractZodFieldInfo(fieldName, zodSchema._def.innerType); info.type = innerInfo.type; info.description = info.description || innerInfo.description; info.required = false; info.params = innerInfo.params; break; } case "ZodDefault": case "default": { const defaultInnerInfo = extractZodFieldInfo(fieldName, zodSchema._def.innerType); info.type = defaultInnerInfo.type; info.description = info.description || defaultInnerInfo.description; info.required = false; const defValue = zodSchema._def.defaultValue; if (typeof defValue === "function") { try { info.defaultValue = String(defValue()); } catch (_e) { info.defaultValue = "[default value]"; } } else { info.defaultValue = String(defValue || ""); } info.params = defaultInnerInfo.params; break; } case "ZodUnion": case "union": { const options = zodSchema._def.options; if (options && options.length > 0) { const types = options.map((opt) => extractZodFieldInfo("", opt).type); info.type = types.join(" | "); } else { info.type = "union"; } if (!info.description) info.description = "联合类型"; break; } case "ZodLazy": case "lazy": { // 检查是否为lazy类型 if (typeValue === "lazy" || typeName === "ZodLazy" || typeName === "lazy") { // 对于lazy类型,尝试获取内部的getter函数返回的schema const getter = zodSchema.def.getter; if (getter) { try { const innerSchema = getter(); const innerInfo = extractZodFieldInfo(fieldName, innerSchema); info.type = innerInfo.type; info.description = info.description || innerInfo.description; info.params = innerInfo.params; } catch (_e) { info.type = "lazy"; if (!info.description) info.description = "延迟类型"; } } else { info.type = "lazy"; if (!info.description) info.description = "延迟类型"; } } break; } default: info.type = typeName ? typeName.replace("Zod", "").toLowerCase() : "unknown"; if (!info.description) info.description = `${typeName} 类型`; } return info; } const schemaList = []; schemaList.push("# 数据类型"); // 生成注册的类型文档 if (data.types && Object.keys(data.types).length > 0) { schemaList.push("\n## 注册类型"); const tableHead = (0, utils_1.tableHeader)(["类型名", "TypeScript类型", "描述", "格式化", "默认值", "可选", "参数"]); schemaList.push(tableHead); for (const typeDoc of Object.values(data.types)) { schemaList.push(typeDocString(typeDoc)); } } // 生成Schema文档 const schemaManager = data.schema; if (schemaManager) { // 从erest实例中获取schemaRegistry let schemaRegistry = null; if (data.erest && data.erest.schemaRegistry instanceof Map) { schemaRegistry = data.erest.schemaRegistry; } else { // 尝试从schemaManager的属性中找到Map实例 for (const prop in schemaManager) { if (schemaManager[prop] instanceof Map) { schemaRegistry = schemaManager[prop]; break; } } } if (schemaRegistry instanceof Map && schemaRegistry.size > 0) { schemaList.push("\n## Schema定义"); for (const [schemaName, zodSchema] of schemaRegistry.entries()) { schemaList.push(generateZodSchemaInfo(schemaName, zodSchema)); } } } return schemaList.join("\n"); }