@code-pushup/js-packages-plugin
Version:
Code PushUp plugin for JavaScript packages 🛡️
105 lines • 4.55 kB
JavaScript
import ansis from 'ansis';
import { createRequire } from 'node:module';
import { logger, pluralizeToken } from '@code-pushup/utils';
import { dependencyGroups, } from './config.js';
import { JS_PACKAGES_PLUGIN_SLUG, JS_PACKAGES_PLUGIN_TITLE, dependencyDocs, dependencyGroupWeights, } from './constants.js';
import { formatMetaLog } from './format.js';
import { packageManagers } from './package-managers/package-managers.js';
import { createRunnerFunction } from './runner/runner.js';
import { normalizeConfig } from './utils.js';
/**
* Instantiates Code PushUp JS packages plugin for core config.
*
* @example
* import jsPackagesPlugin from '@code-pushup/js-packages-plugin'
*
* export default {
* // ... core config ...
* plugins: [
* // ... other plugins ...
* await jsPackagesPlugin({ packageManager: 'npm' })
* ]
* }
*
* @returns Plugin configuration.
*/
export async function jsPackagesPlugin(config) {
const { packageManager, checks, depGroups, scoreTargets, ...jsPackagesPluginConfigRest } = await normalizeConfig(config);
const packageJson = createRequire(import.meta.url)('../../package.json');
const audits = createAudits(packageManager.slug, checks, depGroups);
const groups = createGroups(packageManager.slug, checks, depGroups);
logger.info(formatMetaLog(`Created ${pluralizeToken('audit', audits.length)} and ${pluralizeToken('group', groups.length)} for ${ansis.bold(packageManager.name)} package manager`));
return {
slug: JS_PACKAGES_PLUGIN_SLUG,
title: JS_PACKAGES_PLUGIN_TITLE,
icon: packageManager.icon,
description: 'This plugin runs audit to uncover vulnerabilities and lists outdated dependencies. It supports npm, yarn classic, yarn modern, and pnpm package managers.',
docsUrl: packageManager.docs.homepage,
packageName: packageJson.name,
version: packageJson.version,
audits,
groups,
runner: createRunnerFunction({
...jsPackagesPluginConfigRest,
checks,
packageManager: packageManager.slug,
dependencyGroups: depGroups,
}),
...(scoreTargets && { scoreTargets }),
};
}
function createGroups(id, checks, depGroups) {
const pm = packageManagers[id];
const supportedAuditDepGroups = pm.audit.supportedDepGroups ?? dependencyGroups;
const compatibleAuditDepGroups = depGroups.filter(group => supportedAuditDepGroups.includes(group));
const groups = {
audit: {
slug: `${pm.slug}-audit`,
title: `${pm.name} audit`,
description: `Group containing ${pm.name} vulnerabilities.`,
docsUrl: pm.docs.audit,
refs: compatibleAuditDepGroups.map(depGroup => ({
slug: `${pm.slug}-audit-${depGroup}`,
weight: dependencyGroupWeights[depGroup],
})),
},
outdated: {
slug: `${pm.slug}-outdated`,
title: `${pm.name} outdated dependencies`,
description: `Group containing outdated ${pm.name} dependencies.`,
docsUrl: pm.docs.outdated,
refs: depGroups.map(depGroup => ({
slug: `${pm.slug}-outdated-${depGroup}`,
weight: dependencyGroupWeights[depGroup],
})),
},
};
return checks.map(check => groups[check]);
}
function createAudits(id, checks, depGroups) {
const { slug } = packageManagers[id];
return checks.flatMap(check => {
const supportedAuditDepGroups = packageManagers[id].audit.supportedDepGroups ?? dependencyGroups;
const compatibleDepGroups = check === 'audit'
? depGroups.filter(group => supportedAuditDepGroups.includes(group))
: depGroups;
return compatibleDepGroups.map(depGroup => ({
slug: `${slug}-${check}-${depGroup}`,
title: getAuditTitle(slug, check, depGroup),
description: getAuditDescription(check, depGroup),
docsUrl: dependencyDocs[depGroup],
}));
});
}
function getAuditTitle(id, check, depGroup) {
const pm = packageManagers[id];
return check === 'audit'
? `Vulnerabilities for ${pm.name} ${depGroup} dependencies.`
: `Outdated ${pm.name} ${depGroup} dependencies.`;
}
function getAuditDescription(check, depGroup) {
return check === 'audit'
? `Runs security audit on ${depGroup} dependencies.`
: `Checks for outdated ${depGroup} dependencies`;
}
//# sourceMappingURL=js-packages-plugin.js.map