validate static method
Validates that a command doesn't mix incompatible properties
Critical rules:
- Cannot have both 'script' AND 'switch' at the same level
- Cannot have both 'params' AND 'switch' at the same level
- If 'default' is a string reference, it must point to an existing switch
- Switch names must be valid identifiers
Implementation
static ValidationResult validate(String commandName, Map<String, dynamic> commandData) {
final hasScript = commandData.containsKey('script');
final hasSwitch = commandData.containsKey('switch');
final hasParams = commandData.containsKey('params');
// Rule 1: Script + Switch conflict
if (hasScript && hasSwitch) {
return ValidationResult.error(
'Cannot use both $bold${red}script$reset and $bold${red}switch$reset at the same time',
hint: 'Move your script content into a \'default\' switch case',
);
}
// Rule 2: Params + Switch conflict
if (hasParams && hasSwitch) {
return ValidationResult.error(
'Cannot use \'params\' and \'switch\' at the same level in command: $commandName',
hint: 'Parameters should be defined within individual switch cases, not at the switch level',
);
}
// Rule 3: Validate default reference if it exists
if (hasSwitch && commandData['switch'] is Map) {
final switches = commandData['switch'] as Map<String, dynamic>;
final defaultValue = switches['default'];
if (defaultValue is String) {
// Default references another switch by name
if (!switches.containsKey(defaultValue)) {
return ValidationResult.error(
'Default switch \'$defaultValue\' does not exist in command: $commandName',
hint: 'Available switches: ${switches.keys.where((k) => k != 'default').join(', ')}',
);
}
// Check for self-reference
if (defaultValue == 'default') {
return ValidationResult.error(
'Default switch cannot reference itself in command: $commandName',
hint: 'Point default to an existing switch name or define default as a command',
);
}
}
// Rule 4: Validate switch names
for (final switchName in switches.keys) {
if (switchName == 'default') continue; // 'default' is allowed reserved word
if (!_isValidSwitchName(switchName)) {
return ValidationResult.error(
'Invalid switch name \'$switchName\' in command: $commandName',
hint: 'Switch names must be valid identifiers (letters, numbers, hyphens, underscores)',
);
}
}
// Recursively validate nested switches
for (final entry in switches.entries) {
if (entry.key == 'default' && entry.value is String) continue;
final switchData = entry.value;
if (switchData is Map<String, dynamic>) {
final nestedResult = validate('$commandName > ${entry.key}', switchData);
if (!nestedResult.isValid) {
return nestedResult;
}
}
}
}
return ValidationResult.success();
}