validateManifest function

Future<ValidationResult> validateManifest(
  1. String filePath
)

Validate a manifest file or directory (auto-detects type).

Implementation

Future<ValidationResult> validateManifest(String filePath) async {
  final absolutePath = path.absolute(filePath);

  // Check if it's a directory
  final entityType = await FileSystemEntity.type(absolutePath);
  if (entityType == FileSystemEntityType.directory) {
    // Look for manifest files in .neomage-plugin directory
    final marketplacePath = path.join(
      absolutePath,
      '.neomage-plugin',
      'marketplace.json',
    );
    final marketplaceResult = await validateMarketplaceManifest(
      marketplacePath,
    );
    if (marketplaceResult.errors.isEmpty ||
        marketplaceResult.errors.first.code != 'ENOENT') {
      return marketplaceResult;
    }

    final pluginPath = path.join(
      absolutePath,
      '.neomage-plugin',
      'plugin.json',
    );
    final pluginResult = await validatePluginManifest(pluginPath);
    if (pluginResult.errors.isEmpty ||
        pluginResult.errors.first.code != 'ENOENT') {
      return pluginResult;
    }

    return ValidationResult(
      success: false,
      errors: [
        const ValidationError(
          path: 'directory',
          message:
              'No manifest found in directory. Expected .neomage-plugin/marketplace.json or .neomage-plugin/plugin.json',
        ),
      ],
      warnings: const [],
      filePath: absolutePath,
      fileType: PluginFileType.plugin,
    );
  }

  final manifestType = _detectManifestType(filePath);

  switch (manifestType) {
    case 'plugin':
      return validatePluginManifest(filePath);
    case 'marketplace':
      return validateMarketplaceManifest(filePath);
    case 'unknown':
    default:
      // Try to parse and guess based on content
      try {
        final content = await File(absolutePath).readAsString();
        final parsed = _jsonDecode(content);
        if (parsed is Map<String, dynamic> && parsed['plugins'] is List) {
          return validateMarketplaceManifest(filePath);
        }
      } on FileSystemException catch (e) {
        if (e.osError?.errorCode == 2) {
          return ValidationResult(
            success: false,
            errors: [
              ValidationError(
                path: 'file',
                message: 'File not found: $absolutePath',
              ),
            ],
            warnings: const [],
            filePath: absolutePath,
            fileType: PluginFileType.plugin,
          );
        }
      } catch (_) {
        // Fall through to default
      }
      return validatePluginManifest(filePath);
  }
}