import { coerce, satisfies } from 'semver';
import { JsonRule } from '../../JsonRule.js';
export class DependencyRule extends JsonRule {
    constructor(options) {
        super();
        this.packageName = options.packageName;
        this.supportedRange = options.supportedRange;
        this.isDevDep = options.isDevDep ?? false;
    }
    get title() {
        return this.packageName;
    }
    get description() {
        return '';
    }
    get resolution() {
        return `${(this.isDevDep ? 'installDev' : 'install')} ${this.packageName}@${this.supportedRange.includes(' ') ? `"${this.supportedRange}"` : this.supportedRange}`;
    }
    get resolutionType() {
        return 'cmd';
    }
    get severity() {
        return 'Required';
    }
    get file() {
        return './package.json';
    }
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    customCondition(project) {
        return true;
    }
    visit(project, findings) {
        if (!project.packageJson || !this.customCondition(project)) {
            return;
        }
        // if the project has no dependencies, then we assume the package is missing
        let packageNotFound = (this.isDevDep && !project.packageJson.devDependencies) ||
            (!this.isDevDep && !project.packageJson.dependencies);
        let minSemVer = null;
        if (!packageNotFound) {
            // try to get the current version of the dependency installed in the
            // project. If not possible, we assume the dependency is missing
            const packageVersionFromProject = this.isDevDep ? project.packageJson.devDependencies[this.packageName] : project.packageJson.dependencies[this.packageName];
            if (!packageVersionFromProject) {
                packageNotFound = true;
            }
            else {
                minSemVer = coerce(packageVersionFromProject);
                if (!minSemVer) {
                    packageNotFound = true;
                }
            }
        }
        if (packageNotFound) {
            return this.addFindingWithCustomInfo(this.title, `Install missing package ${this.packageName}`, [{
                    file: this.file,
                    resolution: this.resolution
                }], findings);
        }
        if (satisfies(minSemVer, this.supportedRange)) {
            return;
        }
        const node = this.getAstNodeFromFile(project.packageJson, `${(this.isDevDep ? 'devDependencies' : 'dependencies')}.${this.packageName}`);
        this.addFindingWithCustomInfo(this.title, `Install supported version of the ${this.packageName} package`, [{
                file: this.file,
                resolution: this.resolution,
                position: this.getPositionFromNode(node)
            }], findings);
    }
}
//# sourceMappingURL=DependencyRule.js.map