Skip to main content
Glama

Feishu MCP Server

paramUtils.ts7.09 kB
import { normalizeDocumentId, normalizeWikiToken } from './document.js'; import { Logger } from './logger.js'; import { formatErrorMessage } from './error.js'; /** * 参数验证错误 */ export class ParamValidationError extends Error { public readonly param: string; constructor(param: string, message: string) { super(message); this.name = 'ParamValidationError'; this.param = param; } } /** * 通用参数配置接口 */ export interface CommonParams { documentId?: string; blockId?: string; parentBlockId?: string; index?: number; startIndex?: number; [key: string]: any; } /** * 参数处理工具类 * 提供参数验证、转换和处理功能 */ export class ParamUtils { /** * 处理文档ID参数 * 验证并规范化文档ID * * @param documentId 文档ID或URL * @returns 规范化的文档ID * @throws 如果文档ID无效则抛出错误 */ public static processDocumentId(documentId: string): string { 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无效则抛出错误 */ public static processWikiToken(wikiUrl: string): string { 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无效则抛出错误 */ public static processBlockId(blockId: string): string { 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无效则抛出错误 */ public static processParentBlockId(parentBlockId: string): string { 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 如果索引无效则抛出错误 */ public static processIndex(index: number): number { if (index === undefined || index === null) { return 0; // 默认值 } if (!Number.isInteger(index) || index < 0) { throw new ParamValidationError('index', '索引必须是非负整数'); } return index; } /** * 处理对齐方式参数 * 验证并规范化对齐方式值 * * @param align 对齐方式 * @returns 验证后的对齐方式值 */ public static processAlign(align: number): number { if (align === undefined || align === null) { return 1; // 默认左对齐 } if (![1, 2, 3].includes(align)) { Logger.warn(`对齐方式值 ${align} 无效,使用默认值1(左对齐)`); return 1; } return align; } /** * 处理语言类型参数 * 验证并规范化语言类型值 * * @param language 语言类型 * @returns 验证后的语言类型值 */ public static processLanguage(language: number): number { 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 验证后的标题级别值 */ public static processHeadingLevel(level: number): number { 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无效则抛出错误 */ public static processWhiteboardId(whiteboardId: string): string { 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)); } } /** * 批量处理通用参数 * 验证并规范化常用参数集 * * @param params 通用参数对象 * @returns 处理后的参数对象 */ public static processCommonParams(params: CommonParams): CommonParams { const result: CommonParams = { ...params }; // 处理文档ID if (params.documentId) { result.documentId = ParamUtils.processDocumentId(params.documentId); } // 处理块ID if (params.blockId) { result.blockId = ParamUtils.processBlockId(params.blockId); } // 处理父块ID if (params.parentBlockId) { result.parentBlockId = ParamUtils.processParentBlockId(params.parentBlockId); } // 处理索引 if (params.index !== undefined) { result.index = ParamUtils.processIndex(params.index); } // 处理起始索引 if (params.startIndex !== undefined) { result.startIndex = ParamUtils.processIndex(params.startIndex); } return result; } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/cso1z/Feishu-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server