UNPKG

feishu-mcp

Version:

Model Context Protocol server for Feishu integration

201 lines (200 loc) 6.35 kB
import { normalizeDocumentId, normalizeWikiToken } from './document.js'; import { Logger } from './logger.js'; import { formatErrorMessage } from './error.js'; /** * 参数验证错误 */ export class ParamValidationError extends Error { constructor(param, message) { super(message); Object.defineProperty(this, "param", { enumerable: true, configurable: true, writable: true, value: void 0 }); this.name = 'ParamValidationError'; this.param = param; } } /** * 参数处理工具类 * 提供参数验证、转换和处理功能 */ export class ParamUtils { /** * 处理文档ID参数 * 验证并规范化文档ID * * @param documentId 文档ID或URL * @returns 规范化的文档ID * @throws 如果文档ID无效则抛出错误 */ static processDocumentId(documentId) { if (!documentId) { throw new ParamValidationError('documentId', '文档ID不能为空'); } try { return normalizeDocumentId(documentId); } catch (error) { throw new ParamValidationError('documentId', formatErrorMessage(error)); } } /** * 处理Wiki Token参数 * 验证并规范化Wiki Token * * @param wikiUrl Wiki URL或Token * @returns 规范化的Wiki Token * @throws 如果Wiki Token无效则抛出错误 */ static processWikiToken(wikiUrl) { if (!wikiUrl) { throw new ParamValidationError('wikiUrl', 'Wiki URL不能为空'); } try { return normalizeWikiToken(wikiUrl); } catch (error) { throw new ParamValidationError('wikiUrl', formatErrorMessage(error)); } } /** * 处理块ID参数 * 验证块ID是否有效 * * @param blockId 块ID * @returns 验证后的块ID * @throws 如果块ID无效则抛出错误 */ static processBlockId(blockId) { if (!blockId) { throw new ParamValidationError('blockId', '块ID不能为空'); } if (!/^[a-zA-Z0-9_-]{5,}$/.test(blockId)) { throw new ParamValidationError('blockId', '块ID格式无效'); } return blockId; } /** * 处理父块ID参数 * 验证父块ID是否有效 * * @param parentBlockId 父块ID * @returns 验证后的父块ID * @throws 如果父块ID无效则抛出错误 */ static processParentBlockId(parentBlockId) { if (!parentBlockId) { throw new ParamValidationError('parentBlockId', '父块ID不能为空'); } if (!/^[a-zA-Z0-9_-]{5,}$/.test(parentBlockId)) { throw new ParamValidationError('parentBlockId', '父块ID格式无效'); } return parentBlockId; } /** * 处理插入位置索引参数 * 验证并规范化索引值 * * @param index 插入位置索引 * @returns 验证后的索引值 * @throws 如果索引无效则抛出错误 */ static processIndex(index) { if (index === undefined || index === null) { return 0; // 默认值 } if (!Number.isInteger(index) || index < 0) { throw new ParamValidationError('index', '索引必须是非负整数'); } return index; } /** * 处理对齐方式参数 * 验证并规范化对齐方式值 * * @param align 对齐方式 * @returns 验证后的对齐方式值 */ static processAlign(align) { if (align === undefined || align === null) { return 1; // 默认左对齐 } if (![1, 2, 3].includes(align)) { Logger.warn(`对齐方式值 ${align} 无效,使用默认值1(左对齐)`); return 1; } return align; } /** * 处理语言类型参数 * 验证并规范化语言类型值 * * @param language 语言类型 * @returns 验证后的语言类型值 */ static processLanguage(language) { if (language === undefined || language === null) { return 1; // 默认纯文本 } if (!Number.isInteger(language) || language < 1 || language > 71) { Logger.warn(`语言类型值 ${language} 无效,使用默认值1(纯文本)`); return 1; } return language; } /** * 处理标题级别参数 * 验证并规范化标题级别值 * * @param level 标题级别 * @returns 验证后的标题级别值 */ static processHeadingLevel(level) { if (level === undefined || level === null) { return 1; // 默认一级标题 } // 限制在1-9范围内 return Math.max(1, Math.min(9, level)); } /** * 处理画板ID参数 * 验证并规范化画板ID,支持从URL中提取 * * @param whiteboardId 画板ID或URL * @returns 规范化的画板ID * @throws 如果画板ID无效则抛出错误 */ static processWhiteboardId(whiteboardId) { if (!whiteboardId) { throw new ParamValidationError('whiteboardId', '画板ID不能为空'); } try { // 从URL中提取画板ID let normalizedWhiteboardId = whiteboardId; if (whiteboardId.includes('feishu.cn/board/')) { // 从URL中提取画板ID const matches = whiteboardId.match(/board\/([^\/\?]+)/); if (matches) { normalizedWhiteboardId = matches[1]; } else { throw new ParamValidationError('whiteboardId', '无法从URL中提取画板ID'); } } // 验证画板ID格式(基本格式检查) if (!/^[a-zA-Z0-9_-]{5,}$/.test(normalizedWhiteboardId)) { throw new ParamValidationError('whiteboardId', '画板ID格式无效'); } return normalizedWhiteboardId; } catch (error) { if (error instanceof ParamValidationError) { throw error; } throw new ParamValidationError('whiteboardId', formatErrorMessage(error)); } } }