depsweep
Version:
🌱 Automated intelligent dependency cleanup with environmental impact reporting
364 lines (363 loc) • 9.74 kB
JavaScript
export const MESSAGES = {
title: "DepSweep 🧹",
noPackageJson: "No package.json found",
monorepoDetected: "\nMonorepo detected, using root package.json",
monorepoWorkspaceDetected: "\nMonorepo workspace package detected",
analyzingDependencies: "Analyzing dependencies...",
fatalError: "\nFatal error:",
noUnusedDependencies: "No unused dependencies found",
unusedFound: "Detected unused dependencies:",
noChangesMade: "No changes made",
promptRemove: "Do you want to remove these unused dependencies? (y/N) ",
dependenciesRemoved: "Dependencies:",
diskSpace: "Unpacked Disk Space:",
carbonFootprint: "Carbon Footprint:",
measuringImpact: "Impact Analysis",
measureComplete: "Measurement complete",
installTime: "Total Install Time:",
signalCleanup: "\n{0} received, cleaning up...",
unexpected: "\nUnexpected error:",
environmentalImpact: "🌱 Environmental Impact Analysis",
carbonSavings: "Carbon Savings",
energyEfficiency: "Energy Efficiency",
waterSavings: "Water Savings",
treesEquivalent: "Trees Equivalent",
carMilesEquivalent: "Car Miles Equivalent",
environmentalHero: "Environmental Hero",
impactSummary: "Impact Summary",
savingsBreakdown: "Savings Breakdown",
};
export const CLI_STRINGS = {
PROGRESS_FORMAT: "Dependency Analysis |{bar}| [{currentDeps}/{totalDeps}] {dep}",
BAR_COMPLETE: "\u2588",
BAR_INCOMPLETE: "\u2591",
CLI_NAME: "depsweep",
CLI_DESCRIPTION: "Automated intelligent dependency cleanup and impact analysis report",
EXAMPLE_TEXT: "\nExample:\n $ depsweep -v --measure-impact",
};
export const PROTECTED_DEPENDENCIES = {
CORE_RUNTIME: [
"node",
"npm",
"yarn",
"pnpm",
"npx",
"nvm",
"nodemon",
"ts-node",
"tsx",
"esbuild",
"swc",
],
BUILD_TOOLS: [
"typescript",
"webpack",
"vite",
"rollup",
"esbuild",
"swc",
"babel",
"@babel/core",
"@babel/cli",
"@babel/preset-env",
"@babel/preset-typescript",
"@babel/preset-react",
"tsc",
"tsc-alias",
],
FRAMEWORK_CORE: [
"react",
"react-dom",
"vue",
"@vue/runtime-core",
"@angular/core",
"@angular/common",
"@angular/platform-browser",
"next",
"nuxt",
"svelte",
"solid-js",
"preact",
"inferno",
],
TESTING: [
"jest",
"vitest",
"mocha",
"chai",
"sinon",
"cypress",
"playwright",
"@testing-library/react",
"@testing-library/vue",
"@testing-library/jest-dom",
"enzyme",
"karma",
"ava",
"tap",
],
CODE_QUALITY: [
"eslint",
"@eslint/js",
"prettier",
"stylelint",
"husky",
"lint-staged",
"commitlint",
"semantic-release",
"conventional-changelog",
"standard",
"xo",
],
DEV_SERVER: [
"webpack-dev-server",
"vite",
"rollup-plugin-serve",
"live-server",
"browser-sync",
"concurrently",
"cross-env",
"dotenv",
"dotenv-expand",
],
PACKAGE_MANAGEMENT: [
"webpack-cli",
"webpack-merge",
"webpack-bundle-analyzer",
"vite-plugin-*",
"rollup-plugin-*",
"esbuild-plugin-*",
"parcel-bundler",
"metro",
"fusebox",
],
TYPE_DEFINITIONS: [
"@types/node",
"@types/react",
"@types/react-dom",
"@types/vue",
"@types/angular",
"@types/jest",
"@types/mocha",
"@types/chai",
"@types/sinon",
"@types/cypress",
],
CONFIGURATION: [
"tsconfig-paths",
"tsconfig-paths-webpack-plugin",
"dotenv-webpack",
"webpack-define-plugin",
"vite-plugin-env",
"rollup-plugin-replace",
"esbuild-define",
],
STYLING: [
"css-loader",
"style-loader",
"sass-loader",
"less-loader",
"postcss-loader",
"autoprefixer",
"tailwindcss",
"styled-components",
"emotion",
"linaria",
],
ASSET_HANDLING: [
"file-loader",
"url-loader",
"raw-loader",
"html-webpack-plugin",
"copy-webpack-plugin",
"vite-plugin-static-copy",
"rollup-plugin-copy",
],
DEV_UTILITIES: [
"rimraf",
"del",
"chalk",
"ora",
"cli-progress",
"commander",
"yargs",
"inquirer",
"enquirer",
],
SECURITY: [
"helmet",
"cors",
"express-rate-limit",
"express-validator",
"joi",
"yup",
"zod",
"ajv",
"json-schema",
],
DATABASE: [
"mongoose",
"sequelize",
"prisma",
"typeorm",
"knex",
"bookshelf",
"objection",
"drizzle-orm",
],
HTTP_API: [
"express",
"koa",
"fastify",
"hapi",
"axios",
"fetch",
"node-fetch",
"got",
"request",
"superagent",
],
STATE_MANAGEMENT: [
"redux",
"mobx",
"zustand",
"recoil",
"jotai",
"valtio",
"pinia",
"vuex",
"ngrx",
"akita",
],
ROUTING: [
"react-router",
"vue-router",
"@angular/router",
"next/router",
"nuxt/router",
"svelte-routing",
"solid-router",
],
I18N: [
"react-i18next",
"vue-i18n",
"ngx-translate",
"next-i18next",
"nuxt-i18n",
"i18next",
"intl",
],
};
export function isProtectedDependency(dependency) {
const allProtected = Object.values(PROTECTED_DEPENDENCIES).flat();
return allProtected.some((protectedDep) => {
if (protectedDep === dependency)
return true;
if (protectedDep.includes("*")) {
const pattern = protectedDep.replaceAll("*", ".*");
return new RegExp(`^${pattern}$`).test(dependency);
}
if (protectedDep.startsWith("@") && dependency.startsWith("@")) {
const protectedScope = protectedDep.split("/")[0];
const dependencyScope = dependency.split("/")[0];
if (protectedScope === dependencyScope)
return true;
}
return false;
});
}
export function getProtectionReason(dependency) {
for (const [category, deps] of Object.entries(PROTECTED_DEPENDENCIES)) {
if (deps.some((dep) => {
if (dep === dependency)
return true;
if (dep.includes("*")) {
const pattern = dep.replaceAll("*", ".*");
return new RegExp(`^${pattern}$`).test(dependency);
}
return false;
})) {
return category.replaceAll("_", " ").toLowerCase();
}
}
return null;
}
export const FRAMEWORK_PATTERNS = {
ANGULAR: {
CORE: "@angular/core",
PATTERNS: ["@angular/*", "@angular-*", "@webcomponents/*"],
DEV_DEPS: ["@angular-builders/*", "@angular-devkit/*", "@angular/cli"],
},
REACT: {
CORE: "react",
PATTERNS: ["react-*", "@testing-library/react*", "@types/react*"],
DEV_DEPS: ["react-scripts", "react-app-rewired"],
},
VUE: {
CORE: "vue",
PATTERNS: ["vue-*", "@vue/*", "@nuxt/*"],
DEV_DEPS: ["@vue/cli-service", "@vue/cli-plugin-*"],
},
};
export const RAW_CONTENT_PATTERNS = new Map([
["webpack", ["webpack.*", "webpack-*"]],
["babel", ["babel.*", "@babel/*"]],
["eslint", ["eslint.*", "@eslint/*"]],
["jest", ["jest.*", "@jest/*"]],
["typescript", ["ts-*", "@typescript-*"]],
[
"bundler",
["rollup.*", "rollup-*", "esbuild.*", "@esbuild/*", "vite.*", "@vitejs/*"],
],
]);
export const DEPENDENCY_PATTERNS = {
TYPES_PREFIX: "@types/",
DYNAMIC_IMPORT_BASE: String.raw `import\s*\(\s*['"]`,
DYNAMIC_IMPORT_END: String.raw `['"]\s*\)`,
};
export const FILE_PATTERNS = {
PACKAGE_JSON: "package.json",
YARN_LOCK: "yarn.lock",
PNPM_LOCK: "pnpm-lock.yaml",
NODE_MODULES: "node_modules",
CONFIG_REGEX: /\.(config|rc)(\.|\b)/,
PACKAGE_NAME_REGEX: /^[\w./@-]+$/,
};
export const PACKAGE_MANAGERS = {
NPM: "npm",
YARN: "yarn",
PNPM: "pnpm",
};
export const COMMANDS = {
INSTALL: "install",
UNINSTALL: "uninstall",
REMOVE: "remove",
};
export const ENVIRONMENTAL_CONSTANTS = {
ENERGY_PER_GB: 0.072,
CARBON_INTENSITY: 0.456,
WATER_PER_KWH: 1.92,
TREES_PER_KG_CO2: 0.042,
CO2_PER_CAR_MILE: 0.387,
EFFICIENCY_IMPROVEMENT: 18.5,
NETWORK_ENERGY_PER_MB: 0.000_12,
STORAGE_ENERGY_PER_GB_YEAR: 0.000_28,
EWASTE_IMPACT_PER_GB: 0.000_15,
SERVER_UTILIZATION_IMPROVEMENT: 12.3,
BUILD_TIME_PRODUCTIVITY_GAIN: 0.8,
CPU_ENERGY_PER_GB: 0.015,
MEMORY_ENERGY_PER_GB: 0.008,
LATENCY_ENERGY_PER_MB: 0.000_08,
BUILD_SYSTEM_ENERGY_PER_HOUR: 0.25,
CI_CD_ENERGY_PER_BUILD: 0.12,
REGISTRY_ENERGY_PER_DOWNLOAD: 0.000_05,
CARBON_OFFSET_COST_PER_KG: 0.85,
WATER_TREATMENT_COST_PER_LITER: 0.0025,
RENEWABLE_ENERGY_PERCENTAGE: 0.32,
LIFECYCLE_ENERGY_MULTIPLIER: 2.1,
CARBON_INTENSITY_NA: 0.387,
CARBON_INTENSITY_EU: 0.298,
CARBON_INTENSITY_AP: 0.521,
PEAK_ENERGY_MULTIPLIER: 1.45,
OFF_PEAK_ENERGY_MULTIPLIER: 0.78,
};