UNPKG

dependency-guardian

Version:

A powerful dependency management and analysis tool for Node.js projects

138 lines (113 loc) 4.09 kB
const axios = require('axios'); const logger = require('./logger'); const cache = require('./cache'); class LicenseUtils { constructor() { this.cache = cache; this.spdxLicenses = null; this.customMappings = new Map(); } async init() { if (!this.spdxLicenses) { await this.loadSPDXLicenses(); } } async loadSPDXLicenses() { const cacheKey = 'spdx-licenses'; const cached = this.cache.get(cacheKey); if (cached) { this.spdxLicenses = cached; return; } try { const response = await axios.get('https://raw.githubusercontent.com/spdx/license-list-data/master/json/licenses.json'); this.spdxLicenses = response.data.licenses.reduce((acc, license) => { acc[license.licenseId] = { ...license, aliases: this.generateLicenseAliases(license.licenseId) }; return acc; }, {}); this.cache.set(cacheKey, this.spdxLicenses, 86400); // Cache for 24 hours } catch (error) { logger.error('Failed to load SPDX licenses:', error); this.spdxLicenses = {}; } } generateLicenseAliases(licenseId) { const aliases = new Set([licenseId]); // Add common variations aliases.add(licenseId.toLowerCase()); aliases.add(licenseId.replace(/-/g, '')); aliases.add(licenseId.replace(/\s/g, '')); // Add specific known aliases const knownAliases = { 'MIT': ['MIT License', 'MIT-0', 'MIT No Attribution'], 'Apache-2.0': ['Apache 2', 'Apache2', 'Apache License 2.0'], 'GPL-3.0': ['GPL3', 'GPLv3', 'GNU GPL v3'], 'ISC': ['ISC License', 'ISC Public License'] }; knownAliases[licenseId]?.forEach(alias => aliases.add(alias)); return Array.from(aliases); } addCustomMapping(customLicense, spdxLicense) { this.customMappings.set(customLicense.toLowerCase(), spdxLicense); } async detectLicense(packageInfo) { const licenses = new Set(); // Check package.json license field if (typeof packageInfo.license === 'string') { licenses.add(this.normalizeLicense(packageInfo.license)); } else if (typeof packageInfo.license === 'object') { licenses.add(this.normalizeLicense(packageInfo.license.type)); } // Check licenses array if present if (Array.isArray(packageInfo.licenses)) { packageInfo.licenses.forEach(license => { const normalized = this.normalizeLicense( typeof license === 'string' ? license : license.type ); if (normalized) licenses.add(normalized); }); } // Check license file content if available if (packageInfo.licenseFile) { const detectedFromFile = await this.detectLicenseFromContent(packageInfo.licenseFile); if (detectedFromFile) licenses.add(detectedFromFile); } return Array.from(licenses); } normalizeLicense(license) { if (!license) return null; // Convert to uppercase for consistent matching const normalized = license.toUpperCase(); // MIT variations if (normalized.includes('MIT')) { return 'MIT'; } // Apache variations if (normalized.includes('APACHE')) { const version = normalized.match(/2\.0|2|20/); return version ? 'Apache-2.0' : 'Apache'; } // BSD variations if (normalized.includes('BSD')) { if (normalized.includes('3')) return 'BSD-3-Clause'; if (normalized.includes('2')) return 'BSD-2-Clause'; return 'BSD'; } // Return original if no matches return license; } async detectLicenseFromContent(content) { // Implement license detection from file content // This would require natural language processing or pattern matching // Return the most likely SPDX identifier return null; } validateLicense(license) { if (!license) return false; return !!this.spdxLicenses[this.normalizeLicense(license)]; } } module.exports = new LicenseUtils();