New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

cleanstyles

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

cleanstyles - npm Package Compare versions

Comparing version 1.0.8 to 1.0.9

README.md

10

package.json
{
"name": "cleanstyles",
"version": "1.0.8",
"description": "project to detect unused stylesheet in react-native codebase(coded by jasbirrana)",
"version": "1.0.9",
"description": "project to detect unused stylesheet in react-native codebase",
"main": "src/index.js",

@@ -12,3 +12,3 @@ "type": "module",

"lint:fix": "eslint --fix",
"cleanit":"node src/index.js"
"cleanit": "node src/index.js"
},

@@ -23,4 +23,6 @@ "bin": "./src/index.js",

"chalk": "^5.2.0",
"figlet": "^1.5.2",
"inquirer": "^9.1.4",
"lodash-contrib": "^4.1200.1"
"lodash": "^4.17.21",
"shelljs": "^0.8.5"
},

@@ -27,0 +29,0 @@ "devDependencies": {

159

src/index.js
#!/usr/bin/env node
import chalk from "chalk";
import fs from "fs";
import path from "path";
import chalk from "chalk";
import { strContains } from "lodash-contrib";
import inquirer from "inquirer";
import { fromDir, getObjectStyleFromFile,removeNullFromAray } from "./utils.js";
import { logUnusedProperty } from "./logger.js";
import figlet from "figlet";
import {
getFilesInDir,
getUsedStyles,
isStyleImported,
searchForStyles,
} from "./utils.js";
import { askQuestions } from "./logger.js";
const dirname_ =
"/Users/jasbirrana/Desktop/Jasbirrana/HRx_portal/app/containers/health-pay/components/payment-summary-drawer";
const checkAllUnusedStyle = () => {
// const questions = [
// {
// type: "input",
// name: "path",
// message: "Your starting path? (eg ./app/containers/health-pay)",
// },
// ];
// let START_PATH;
// inquirer.prompt(questions).then((answers) => {
// START_PATH = answers.path;
// });
// console.log("script is running?")
const values = [];
fromDir("./app/containers/health-pay", "styles.ts", values);
const styles = getUnusedStyle(values);
if (styles.length > 0) {
const countError = styles.reduce((sum, item) => sum + item.length, 0);
console.log(chalk.red.bold(`\n ✖ Encontrado -->${countError} problem \n`));
process.exit(500);
} else {
console.log(chalk.green.bold("All good"));
}
};
const getUnusedStyle = (pathStyles) =>
pathStyles
.map((pathStyle) => {
const data = fs.readFileSync(pathStyle, "utf-8");
const values = getObjectStyleFromFile(data);
if (!values) {
return;
const findUnusedStyles = (dir) => {
const styles = searchForStyles(dir);
Object.keys(styles).forEach((stylePath) => {
let importName;
getFilesInDir(dir).forEach((file) => {
if (file !== stylePath) {
const fileContents = fs.readFileSync(file, "utf8");
if (
isStyleImported(
stylePath,
path.basename(stylePath),
file,
fileContents
)
) {
importName = path.basename(stylePath).split(".")[0];
}
}
});
const styles = values.map((item) => `styles.${item}`);
if (importName) {
let usedStyles;
getFilesInDir(dir).forEach((file) => {
if (file !== stylePath) {
const fileContents = fs.readFileSync(file, "utf8");
usedStyles = getUsedStyles(
importName,
styles[stylePath],
fileContents
);
}
});
const currentStyleDir = path.dirname(pathStyle);
const unusedStyles = styles[stylePath].filter(
(styleKey) => !usedStyles.has(styleKey)
);
const filesInCwd = fs.readdirSync(currentStyleDir);
let correspondingIndexFilePath;
if (
filesInCwd.indexOf("styles.ts") !== -1 &&
filesInCwd.indexOf("index.tsx") !== -1
) {
correspondingIndexFilePath = pathStyle.replace(
"styles.ts",
"index.tsx"
if (unusedStyles.length > 0) {
console.log(
chalk.bold.italic.magentaBright(`Unused styles in ${stylePath}`)
);
unusedStyles.forEach((unusedStyle) => {
console.log(chalk.bold.red(`-> styles.${unusedStyle}`));
});
}
}
});
};
if (
filesInCwd.indexOf("styles.js") !== -1 &&
filesInCwd.indexOf("index.js") !== -1
) {
correspondingIndexFilePath = pathStyle.replace(
"styles.ts",
"index.tsx"
);
}
const init = async () => {
console.log(
chalk.green(
figlet.textSync("CLEAN IT UP", {
font: "Ghost",
horizontalLayout: "default",
verticalLayout: "default",
whitespaceBreak: false,
})
)
);
const { path } = await askQuestions();
if (correspondingIndexFilePath) {
const indexData = fs.readFileSync(correspondingIndexFilePath, "utf-8");
let unusedStyles = styles.map((item) =>
indexData.indexOf(item) === -1 ? item : null
);
unusedStyles = removeNullFromAray(unusedStyles);
console.log(chalk.white.bgGreen.bold(`Your Starting Path is:${path}`));
console.log(
chalk.red.bold(
`\n -> ${correspondingIndexFilePath} (${unusedStyles?.length}) \n`
)
);
unusedStyles.forEach((item) => {
logUnusedProperty(item);
});
return unusedStyles;
}
return null;
})
.filter((item) => item);
findUnusedStyles(
"/Users/jasbirrana/Desktop/Jasbirrana/HRx_portal/app/containers/health-pay/screens"
);
};
checkAllUnusedStyle();
init();

@@ -1,16 +0,13 @@

import chalk from "chalk";
import { strContains } from "lodash-contrib";
export const logUnusedProperty = (item) => {
if (item) {
if (strContains(item, "create")) {
const splitedUnusedStyle = item?.split(".create({");
console.log(
chalk.bold.underline(
` -> styles.${splitedUnusedStyle[splitedUnusedStyle?.length - 1]}`
)
);
} else {
console.log(chalk.bold.underline(` -> ${item}`));
}
}
import inquirer from "inquirer";
export const askQuestions = () => {
const questions = [
{
type: "input",
name: "path",
message: "Your starting path? (eg ./app/containers/health-pay)",
},
];
return inquirer.prompt(questions);
};
import path from "path";
import fs from "fs";
export const getFilesInDir = (dir) => {
const files = [];
fs.readdirSync(dir).forEach((file) => {
if (file !== ".DS_Store") {
const filePath = path.join(dir, file);
if (fs.lstatSync(filePath).isDirectory()) {
files.push(...getFilesInDir(filePath));
} else {
files.push(filePath);
}
}
});
return files;
};
const TAG_START = "{";
const TAG_END = "}";
const TAG_IGNORE = "//check-style disable";
export const fromDir = (startPath, filter, values) => {
if (startPath.indexOf("node_modules") >= 0 || !fs.existsSync(startPath)) {
return;
}
const files = fs.readdirSync(startPath);
for (let index = 0; index < files.length; index++) {
const filename = path.join(startPath, files[index]);
const stat = fs.lstatSync(filename);
if (stat.isDirectory()) {
fromDir(filename, filter, values);
} else if (filename.indexOf(filter) >= 0) {
values.push(filename);
export const extractStyleObject = (data) => {
const temp = data.split("StyleSheet.create({")?.[1]?.split("});")?.[0];
const keys = temp.split(": {").map((text) => {
const k = text.split(" ");
const t = text.split(",");
if (t.length) {
const l = t[t.length - 2];
if (l && !l?.includes?.("}")) return undefined;
}
}
return k[k.length - 1];
});
return keys.filter((s) => !!s).slice(0, -1);
};
export const getObjectStyleFromFile = (file) => {
if (file.includes(TAG_IGNORE)) {
return [];
}
let valueWithoutHeader;
if (file.indexOf("export const styles = ") !== -1) {
valueWithoutHeader = file
.slice(file.indexOf("export const styles = ") + 21)
.replace(/;/g, "")
.replace(/ /g, "");
}
if (file.indexOf("export default") !== -1) {
valueWithoutHeader = file
.slice(file.indexOf("export default") + 14)
.replace(/;/g, "")
.replace(/ /g, "");
}
valueWithoutHeader = valueWithoutHeader.slice(
0,
valueWithoutHeader.lastIndexOf("}")
);
let index = null;
const gotIndex = [];
for (let i = valueWithoutHeader.length; i > 0; i--) {
const letter = valueWithoutHeader[i - 1];
if (letter === TAG_START) {
if (index) {
if (gotIndex.length > 0) {
gotIndex.pop();
} else {
const value = valueWithoutHeader.substring(i - 2, index);
valueWithoutHeader = valueWithoutHeader.replace(value, "");
index = null;
}
export const searchForStyles = (pathString) => {
let styles = {};
const files = fs.readdirSync(pathString);
files.forEach((file) => {
if (file.startsWith(".")) {
return;
}
const filePath = path.resolve(pathString, file);
const isDir = fs.lstatSync(filePath).isDirectory();
if (isDir) {
styles = { ...styles, ...searchForStyles(filePath) };
} else {
const fileContents = fs.readFileSync(filePath, {
encoding: "utf8",
flag: "r",
});
if (fileContents.includes("StyleSheet.create({")) {
styles[filePath] = extractStyleObject(fileContents);
}
} else if (letter === TAG_END) {
if (index) {
gotIndex.push(i);
} else {
index = i;
}
}
});
return styles;
};
export const isStyleImported = (
stylePath,
styleName,
filePath,
fileContents
) => {
const styleExtension = `.${styleName.split(".")[1]}`;
const importStatements =
fileContents.match(/import\s.+from\s(?:'|")(.+)(?:'|");/g) || [];
for (const statement of importStatements) {
let importPath = statement.split("from")[1].trim().slice(1, -2);
if (!path.isAbsolute(importPath)) {
importPath = path.join(path.dirname(filePath), importPath);
}
if (importPath + styleExtension === stylePath) {
return true;
}
}
return false;
};
let stringObject = valueWithoutHeader.replace(/\r?\n|\r/g, "");
export const getUsedStyles = (importName, styleKeys, fileContents) => {
const usedStyles = new Set();
const temp = styleKeys.filter((key) => {
return fileContents.includes(`${importName}.${key}`);
});
if (stringObject && stringObject[stringObject.length - 1] === ",") {
stringObject = stringObject.substring(0, stringObject.length - 1);
for (const key of temp) {
usedStyles.add(key);
}
return stringObject.split(",");
};
export const removeNullFromAray = (array) => {
return array.filter((ele) => ele !== null);
};
return usedStyles;
};
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc