/**
 * Scanner Plugin Types
 *
 * Defines the plugin interface for external scanners.
 * Plugins can be installed from:
 * 1. Local directory: `.vaspera/plugins/{name}/manifest.json`
 * 2. npm package: `vaspera-scanner-{name}`
 *
 * @module plugins/types
 */
import { z } from "zod";
/**
 * Plugin manifest schema
 *
 * Defines the structure of a plugin's manifest.json file.
 */
export const PluginManifestSchema = z.object({
    /** Plugin name (alphanumeric with hyphens) */
    name: z.string().regex(/^[a-z0-9-]+$/, "Name must be lowercase alphanumeric with hyphens"),
    /** Plugin version (semver) */
    version: z.string().regex(/^\d+\.\d+\.\d+/, "Version must be semver format"),
    /** Human-readable description */
    description: z.string().min(1).max(500),
    /** Plugin author */
    author: z.string().optional(),
    /** Plugin homepage/repository URL */
    homepage: z.string().url().optional(),
    /** License identifier */
    license: z.string().optional(),
    /** Minimum Vaspera version required */
    minVasperaVersion: z.string().optional(),
    /** Scanner configuration */
    scanner: z.object({
        /** Scanner type identifier */
        type: z.string(),
        /** Languages/frameworks this scanner supports */
        languages: z.array(z.string()),
        /** File patterns to include (glob) */
        include: z.array(z.string()).optional(),
        /** File patterns to exclude (glob) */
        exclude: z.array(z.string()).optional(),
        /** Whether scanner requires external binary */
        requiresBinary: z.boolean().default(false),
        /** Binary name to check for availability */
        binaryName: z.string().optional(),
        /** Default timeout in milliseconds */
        defaultTimeout: z.number().default(120000),
    }),
    /** Entry point configuration */
    entryPoint: z.object({
        /** Path to main module (relative to manifest) */
        module: z.string(),
        /** Export name for the scanner function */
        exportName: z.string().default("default"),
    }),
    /** Custom rules configuration */
    rules: z.object({
        /** Path to rules directory (relative to manifest) */
        directory: z.string().optional(),
        /** Rule file extensions */
        extensions: z.array(z.string()).default([".yaml", ".yml", ".json"]),
    }).optional(),
    /** Plugin capabilities */
    capabilities: z.object({
        /** Supports incremental scanning */
        incremental: z.boolean().default(false),
        /** Supports auto-fix */
        autofix: z.boolean().default(false),
        /** Supports custom rules */
        customRules: z.boolean().default(false),
        /** Can run in sandbox */
        sandboxable: z.boolean().default(true),
    }).default({}),
});
/**
 * Check if a value is a valid plugin manifest
 */
export function isValidManifest(value) {
    try {
        PluginManifestSchema.parse(value);
        return true;
    }
    catch {
        return false;
    }
}
/**
 * Validate a plugin manifest and return errors
 */
export function validateManifest(value) {
    const result = PluginManifestSchema.safeParse(value);
    if (result.success) {
        return { valid: true, manifest: result.data };
    }
    return {
        valid: false,
        errors: result.error.errors.map((e) => `${e.path.join(".")}: ${e.message}`),
    };
}
//# sourceMappingURL=types.js.map