Skip to main content
Glama

Poker Task Management MCP

by Hirao-Y
ManifestValidator.js8.08 kB
// validators/ManifestValidator.js // 最終的なエラー処理は呈出先で実装(循環依存解消のため) import { MaterialAlternatives } from '../utils/MaterialAlternatives.js'; /** * マニフェスト仕様準拠バリデーター(循環依存解消版) * マニフェストで定義されたパラメータ制約を厳密に実装 */ export class ManifestValidator { // オブジェクト名の検証(英数字とアンダースコアのみ、50文字以内) static validateObjectName(name, fieldName = 'name') { if (!name || typeof name !== 'string') { const error = new Error(`${fieldName} is required and must be a string`); error.field = fieldName; error.value = name; error.code = 'VALIDATION_ERROR'; throw error; } // ATMOSPHERE予約語チェック if (name === 'ATMOSPHERE') { const error = new Error(`ATMOSPHERE is reserved - cannot be used as ${fieldName}`); error.field = fieldName; error.value = name; error.code = 'ATMOSPHERE_RESERVED'; throw error; } // ハイフンチェック if (name.includes('-')) { const error = new Error(`Invalid name format - hyphens not allowed: ${name}`); error.field = 'name'; error.value = name; error.code = 'INVALID_NAME_FORMAT_HYPHENS'; throw error; } // パターンチェック: 英数字とアンダースコアのみ if (!/^[a-zA-Z0-9_]+$/.test(name)) { const invalidChars = name.match(/[^a-zA-Z0-9_]/g) || []; const error = new Error(`Name contains forbidden characters: ${name} (invalid: ${invalidChars.join(', ')})`); error.field = 'name'; error.value = name; error.code = 'NAME_FORBIDDEN_CHARACTERS'; throw error; } // 長さチェック if (name.length > 50) { const error = new Error(`${fieldName} must be 50 characters or less`); error.field = fieldName; error.value = name; error.code = 'VALIDATION_ERROR'; throw error; } return true; } // 座標文字列の検証(x y z形式) static validateCoordinateString(coordString, fieldName) { if (!coordString || typeof coordString !== 'string') { const error = new Error(`${fieldName} must be a coordinate string`); error.field = fieldName; error.value = coordString; error.code = 'VALIDATION_ERROR'; throw error; } const pattern = /^-?\d+(\.\d+)?\s+-?\d+(\.\d+)?\s+-?\d+(\.\d+)?$/; if (!pattern.test(coordString.trim())) { const error = new Error(`${fieldName} must be in "x y z" format with numeric values`); error.field = fieldName; error.value = coordString; error.code = 'VALIDATION_ERROR'; throw error; } return true; } // 正の半径値検証 static validatePositiveRadius(radius, fieldName) { if (typeof radius !== 'number' || radius <= 0) { const error = new Error(`${fieldName} must be a positive number`); error.field = fieldName; error.value = radius; error.code = 'VALIDATION_ERROR'; throw error; } if (radius < 0.001 || radius > 10000) { const error = new Error(`${fieldName} must be between 0.001 and 10000`); error.field = fieldName; error.value = radius; error.code = 'VALIDATION_ERROR'; throw error; } return true; } // 密度値検証 static validateDensityValue(density, fieldName) { if (typeof density !== 'number' || density <= 0) { const error = new Error(`${fieldName} must be a positive number`); error.field = fieldName; error.value = density; error.code = 'VALIDATION_ERROR'; throw error; } if (density < 0.001 || density > 30.0) { const error = new Error(`${fieldName} must be between 0.001 and 30.0 g/cm³`); error.field = fieldName; error.value = density; error.code = 'VALIDATION_ERROR'; throw error; } return true; } // 放射能値検証 static validateRadioactivityValue(radioactivity, fieldName) { if (typeof radioactivity !== 'number' || radioactivity <= 0) { throw PokerMcpError.validationError(`${fieldName} must be a positive number`, fieldName, radioactivity); } if (radioactivity < 0.001 || radioactivity > 1e15) { throw PokerMcpError.validationError(`${fieldName} must be between 0.001 and 1e15 Bq`, fieldName, radioactivity); } return true; } // 回転角度検証 static validateRotationAngle(angle, fieldName) { if (typeof angle !== 'number') { throw PokerMcpError.validationError(`${fieldName} must be a number`, fieldName, angle); } if (angle < -360 || angle > 360) { throw PokerMcpError.validationError(`${fieldName} must be between -360 and 360 degrees`, fieldName, angle); } return true; } // カットオフ率検証 static validateCutoffRate(rate, fieldName) { if (typeof rate !== 'number') { throw PokerMcpError.validationError(`${fieldName} must be a number`, fieldName, rate); } if (rate < 0.0001 || rate > 1.0) { throw PokerMcpError.validationError(`${fieldName} must be between 0.0001 and 1.0`, fieldName, rate); } return true; } // ビルドアップ係数インデックス検証 static validateBuildupIndex(index, fieldName) { if (!Number.isInteger(index) || index < 0 || index > 100) { throw PokerMcpError.validationError(`${fieldName} must be an integer between 0 and 100`, fieldName, index); } return true; } // グリッド分割数検証 static validateGridDivision(number, fieldName) { if (!Number.isInteger(number) || number < 1 || number > 1000) { throw PokerMcpError.validationError(`${fieldName} must be an integer between 1 and 1000`, fieldName, number); } return true; } // サポートされる材料の検証(代替提案機能付き) static validateSupportedMaterial(material, fieldName) { // MaterialAlternativesクラスを使用して包括的なチェック try { return MaterialAlternatives.validateMaterialWithSuggestion(material, fieldName); } catch (error) { // エラーをそのまま再スロー(代替提案付きエラー含む) throw error; } } // 単位検証 static validateSupportedLengthUnit(unit, fieldName) { const supportedUnits = ['m', 'cm', 'mm']; if (!supportedUnits.includes(unit)) { throw PokerMcpError.unitInvalidValue(fieldName, unit, supportedUnits); } return true; } static validateSupportedAngleUnit(unit, fieldName) { const supportedUnits = ['radian', 'degree']; if (!supportedUnits.includes(unit)) { throw PokerMcpError.unitInvalidValue(fieldName, unit, supportedUnits); } return true; } static validateSupportedDensityUnit(unit, fieldName) { const supportedUnits = ['g/cm3']; if (!supportedUnits.includes(unit)) { throw PokerMcpError.unitInvalidValue(fieldName, unit, supportedUnits); } return true; } static validateSupportedRadioactivityUnit(unit, fieldName) { const supportedUnits = ['Bq']; if (!supportedUnits.includes(unit)) { throw PokerMcpError.unitInvalidValue(fieldName, unit, supportedUnits); } return true; } // 立体タイプ検証 static validateBodyType(type, fieldName) { const supportedTypes = ['SPH', 'RCC', 'RPP', 'BOX', 'CMB', 'TOR', 'ELL', 'REC', 'TRC', 'WED']; if (!supportedTypes.includes(type)) { throw PokerMcpError.invalidBodyType(type); } return true; } // コメント長検証 static validateCommentLength(comment, fieldName) { if (typeof comment !== 'string') { throw PokerMcpError.validationError(`${fieldName} must be a string`, fieldName, comment); } if (comment.length > 200) { throw PokerMcpError.validationError(`${fieldName} must be 200 characters or less`, fieldName, comment); } return true; } }

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/Hirao-Y/poker_mcp'

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