/** * 强类型命令工厂 * * 提供类型安全的命令创建和验证功能 */ import type { CommandTypeMap, SpecificCommand } from './command-types'; import type { CommandMessage, Priority } from './index'; import { MessageFactory, OperationType, CommandType } from './index'; /** * 强类型命令消息工厂 */ export class TypedCommandFactory { /** * 创建强类型命令消息 */ static createTypedCommandMessage( requestRef: string, targetClientId: string, commandCode: T, commandProps: Omit, options?: { priority?: Priority; timeout?: number; callback?: string; } ): CommandMessage { const command: CommandTypeMap[T] = { commandCode, ...commandProps } as CommandTypeMap[T]; return MessageFactory.createCommandMessage( requestRef, targetClientId, command, options?.callback || '', // callback 是必需的,如果未提供则使用空字符串 { priority: options?.priority, timeout: options?.timeout } ); } /** * 示例:创建命令的工厂方法 * * 实际使用时,应该为每个从 C# 生成的命令创建对应的工厂方法 * 例如: createLedSwitchCommand, createBlockPlayCommand 等 */ static createExampleCommand( requestRef: string, targetClientId: string, deviceId: number, exampleField: string, exampleValue: number, operationType: OperationType = OperationType.WRITE, options?: { priority?: Priority; timeout?: number; callback?: string; } ): CommandMessage { return this.createTypedCommandMessage( requestRef, targetClientId, 'ExampleCommand', { commandType: CommandType.SIMPLE, deviceType: 'example', deviceId, operationType, parameters: { exampleField, exampleValue } }, options ); } } /** * 命令类型验证器 */ export class CommandTypeValidator { /** * 验证命令是否符合强类型定义 */ static validateCommand(command: any): { valid: boolean; errors: string[] } { const errors: string[] = []; if (!command) { errors.push('Command is null or undefined'); return { valid: false, errors }; } if (!command.commandCode || typeof command.commandCode !== 'string') { errors.push('commandCode is required and must be a string'); } if (!command.deviceType || typeof command.deviceType !== 'string') { errors.push('deviceType is required and must be a string'); } if (!command.operationType || !Object.values(OperationType).includes(command.operationType as OperationType)) { errors.push('operationType must be READ or WRITE'); } // 根据具体的 commandCode 进行详细验证 switch (command.commandCode) { case 'ExampleCommand': this.validateExampleCommand(command, errors); break; // TODO: 实际使用时,为每个真实命令添加验证 // case 'LedSwitch': // this.validateLedSwitchCommand(command, errors); // break; default: // 对于未知的命令类型,只做基本验证 break; } return { valid: errors.length === 0, errors }; } private static validateExampleCommand(command: any, errors: string[]): void { if (command.deviceType !== 'example') { errors.push('ExampleCommand requires deviceType to be "example"'); } if (command.parameters) { if (typeof command.parameters.exampleField !== 'string') { errors.push('ExampleCommand parameters.exampleField must be a string'); } if (typeof command.parameters.exampleValue !== 'number') { errors.push('ExampleCommand parameters.exampleValue must be a number'); } } } } /** * 命令类型转换器 */ export class CommandTypeConverter { /** * 将通用命令转换为强类型命令 */ static toTypedCommand(genericCommand: any): SpecificCommand | null { const validation = CommandTypeValidator.validateCommand(genericCommand); if (!validation.valid) { console.warn('Command validation failed:', validation.errors); return null; } // 根据 commandCode 转换为具体的强类型 switch (genericCommand.commandCode) { case 'ExampleCommand': return genericCommand as import('./command-types').ExampleCommand; // TODO: 实际使用时,为每个真实命令添加转换 // case 'LedSwitch': // return genericCommand as import('./command-types').LedSwitchCommand; default: return null; } } /** * 检查命令是否为强类型命令 */ static isTypedCommand(command: any): command is SpecificCommand { return command && this.toTypedCommand(command) !== null; } } // 导出便捷的工厂函数 export const createExampleCommand = TypedCommandFactory.createExampleCommand.bind(TypedCommandFactory); // TODO: 实际使用时,导出真实的命令工厂函数 // export const createLedSwitchCommand = TypedCommandFactory.createLedSwitchCommand.bind(TypedCommandFactory); // export const createBlockPlayCommand = TypedCommandFactory.createBlockPlayCommand.bind(TypedCommandFactory); // 导出验证函数 export const validateCommand = CommandTypeValidator.validateCommand.bind(CommandTypeValidator); export const toTypedCommand = CommandTypeConverter.toTypedCommand.bind(CommandTypeConverter);