UNPKG

eslint-plugin-sonarjs

Version:
154 lines (153 loc) 5.79 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getManifests = exports.PACKAGE_JSON = void 0; exports.getAllDependencies = getAllDependencies; exports.getDependencies = getDependencies; exports.clearDependenciesCache = clearDependenciesCache; exports.getDependenciesFromPackageJson = getDependenciesFromPackageJson; /* * SonarQube JavaScript Plugin * Copyright (C) 2011-2025 SonarSource SA * mailto:info AT sonarsource DOT com * * This program is free software; you can redistribute it and/or * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the Sonar Source-Available License for more details. * * You should have received a copy of the Sonar Source-Available License * along with this program; if not, see https://sonarsource.com/license/ssal/ */ const posix_1 = __importDefault(require("path/posix")); const files_js_1 = require("./files.js"); const minimatch_1 = require("minimatch"); const find_up_js_1 = require("./find-up.js"); const fs_1 = __importDefault(require("fs")); exports.PACKAGE_JSON = 'package.json'; /** * The {@link FindUp} instance dedicated to retrieving `package.json` files */ const findPackageJsons = (0, find_up_js_1.createFindUp)(exports.PACKAGE_JSON); const DefinitelyTyped = '@types/'; /** * Cache for the available dependencies by dirname. */ const cache = new Map(); /** * Returns the dependencies of the root package.json file collected in the cache. * As the cache is populated lazily, it could be null in case no rule execution has touched it. * This removes duplicate dependencies and keeps the last occurrence. */ function getAllDependencies() { const dependencies = [...cache.values()] .flatMap(dependencies => [...dependencies]) .filter((dependency) => typeof dependency.name === 'string'); return Object.values(dependencies.reduce((result, dependency) => ({ ...result, [dependency.name]: dependency, }), {})); } /** * Retrieve the dependencies of all the package.json files available for the given file. * * @param filename context.filename * @param cwd working dir, will search up to that root * @returns */ function getDependencies(filename, cwd) { const dirname = posix_1.default.dirname((0, files_js_1.toUnixPath)(filename)); const cached = cache.get(dirname); if (cached) { return new Set([...cached].map(item => item.name)); } const result = new Set(); cache.set(dirname, result); (0, exports.getManifests)(dirname, cwd, fs_1.default).forEach(manifest => { const manifestDependencies = getDependenciesFromPackageJson(manifest); manifestDependencies.forEach(dependency => { result.add(dependency); }); }); return new Set([...result].map(item => item.name)); } /** * In the case of SonarIDE, when a package.json file changes, the cache can become obsolete. */ function clearDependenciesCache() { console.debug('Clearing dependencies cache'); cache.clear(); } function getDependenciesFromPackageJson(content) { const result = new Set(); if (content.name) { addDependencies(result, { [content.name]: '*' }); } if (content.dependencies !== undefined) { addDependencies(result, content.dependencies); } if (content.devDependencies !== undefined) { addDependencies(result, content.devDependencies); } if (content.peerDependencies !== undefined) { addDependencies(result, content.peerDependencies); } if (content.optionalDependencies !== undefined) { addDependencies(result, content.optionalDependencies); } if (content._moduleAliases !== undefined) { addDependencies(result, content._moduleAliases); } if (Array.isArray(content.workspaces)) { addDependenciesArray(result, content.workspaces); } else if (content.workspaces?.packages) { addDependenciesArray(result, content.workspaces?.packages); } return result; } function addDependencies(result, dependencies, isGlob = false) { Object.keys(dependencies).forEach(name => addDependency(result, name, isGlob, dependencies[name])); } function addDependenciesArray(result, dependencies, isGlob = true) { dependencies.forEach(name => addDependency(result, name, isGlob)); } function addDependency(result, dependency, isGlob, version) { if (isGlob) { result.add({ name: new minimatch_1.Minimatch(dependency, { nocase: true, matchBase: true }), version, }); } else { result.add({ name: dependency.startsWith(DefinitelyTyped) ? dependency.substring(DefinitelyTyped.length) : dependency, version, }); } } /** * Returns the project manifests that are used to resolve the dependencies imported by * the module named `filename`, up to the passed working directory. */ const getManifests = (dir, workingDirectory, fileSystem) => { const files = findPackageJsons(dir, workingDirectory, fileSystem); return files.map(file => { const content = file.content; try { return JSON.parse((0, files_js_1.stripBOM)(content.toString())); } catch (error) { console.debug(`Error parsing file ${file.path}: ${error}`); return {}; } }); }; exports.getManifests = getManifests;