discoverCustomCommands static method

Future<List<NyCommand>> discoverCustomCommands()

Discovers custom commands from a JSON file.

Implementation

static Future<List<NyCommand>> discoverCustomCommands() async {
  try {
    final configFile = File('lib/app/commands/custom_commands.json');
    if (await configFile.exists()) {
      final jsonStr = await configFile.readAsString();
      final List<dynamic> commandConfigs = jsonDecode(jsonStr);

      // Remove any duplicate commands from commandConfigs
      final Set<String> commandNames = {};
      commandConfigs.removeWhere((config) {
        final name = config['name'];
        if (commandNames.contains(name)) {
          return true; // Remove duplicate
        } else {
          commandNames.add(name);
          return false; // Keep unique
        }
      });

      // List of commands
      List<NyCommand> allCommands = commandConfigs.map<NyCommand>((config) {
        assert(config['name'] != null,
            'Command "name" is required in custom_commands.json');
        assert(config['script'] != null,
            'Command "script" is required in custom_commands.json');
        return NyCommand(
          name: config['name'],
          category:
              config.containsKey('category') ? config['category'] : "app",
          action: (args) => _executeCommandScript(config['script'], args),
        );
      }).toList();

      // Sort commands by category
      allCommands.sort((a, b) {
        if (a.category == b.category) {
          return (a.name ?? "").compareTo(b.name ?? "");
        }
        return (a.category ?? "").compareTo(b.category ?? "");
      });

      return allCommands;
    }
  } catch (e) {
    MetroConsole.writeInRed(
        'Error loading custom commands: $e\n\nMake sure to create a custom_commands.json file in the lib/app/commands directory.');
  }
  return [];
}