Skip to content

Commit 080c42a

Browse files
committed
Initial commit
0 parents  commit 080c42a

File tree

7 files changed

+390
-0
lines changed

7 files changed

+390
-0
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/.idea
2+
/node_modules
3+
4+
# Project exclude paths
5+
/src/build-map.js
6+
/src/index.js

bin/lint-css-duplicates.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import lint from '../src/index.js';
2+
3+
lint(process.argv[2] || process.cwd());

package-lock.json

Lines changed: 274 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "@idrinth/duplicate-style-check",
3+
"version": "1.0.0",
4+
"description": "",
5+
"type": "module",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1",
8+
"tsc": "tsc -p tsconfig.json"
9+
},
10+
"private": false,
11+
"dependencies": {
12+
"css": "^3.0.0"
13+
},
14+
"devDependencies": {
15+
"@types/css": "^0.0.37",
16+
"@types/node": "^20.10.6",
17+
"typescript": "^5.3.3",
18+
"ts-node": "^10.9.2"
19+
}
20+
}

src/build-map.ts

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import css from 'css';
2+
import {readFileSync} from 'fs';
3+
4+
interface Rules {
5+
[selector:string]: {
6+
[media:string]: {
7+
[property:string]: string
8+
}
9+
}
10+
}
11+
const handleDeclaration = (selector: string, declaration: css.Declaration, position: css.Position|undefined, media: string, rules: Rules) => {
12+
if (rules[selector]) {
13+
if (rules[selector][media]) {
14+
if (rules[selector][media][declaration.property || '']) {
15+
console.error(`${declaration.property} of ${selector} overwrites a previous definition in line ${position?.line} for media ${media}.`);
16+
}
17+
}
18+
if (media !== '' && rules[selector]['']) {
19+
if (rules[selector][''][declaration.property || ''] && rules[selector][''][declaration.property || ''] === declaration.value || '') {
20+
console.error(`${declaration.property} of ${selector} overwrites a previous definition in line ${position?.line} general with the same value.`);
21+
}
22+
}
23+
}
24+
rules[selector] = rules[selector] || {};
25+
rules[selector][media] = rules[selector][media] || {};
26+
rules[selector][media][declaration.property || ''] = declaration.value || '';
27+
}
28+
const handleRule = (rule: css.Rule, rules: Rules, media: string = '') => {
29+
for (const selector of rule.selectors || []) {
30+
for (const declaration of rule.declarations || []) {
31+
if (declaration.type === 'declaration') {
32+
handleDeclaration(selector, declaration, rule.position?.start, media, rules);
33+
}
34+
}
35+
}
36+
};
37+
const handleAtRule = (rule: css.Media, rules: Rules) => {
38+
for (const rul of rule.rules || []) {
39+
handleRule(rul, rules, rule.media)
40+
}
41+
};
42+
export default(file: string): void => {
43+
const rules: Rules = {};
44+
console.log(file);
45+
const code = css.parse(readFileSync(file, 'utf8'));
46+
for (const rule of (code.stylesheet?.rules || [])) {
47+
if (rule.type === 'rule') {
48+
handleRule(rule, rules)
49+
} else if(rule.type === 'media') {
50+
handleAtRule(rule, rules);
51+
}
52+
}
53+
};

src/index.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import {readdirSync} from 'node:fs';
2+
import buildMap from './build-map.js';
3+
4+
export default (cwd: string) => {
5+
for (const file of readdirSync(cwd, {recursive: true, encoding: 'utf8'})) {
6+
if (file.endsWith('.css') && !file.includes('node_modules') && !file.includes('coverage') && !file.includes('dist')) {
7+
buildMap(cwd + '/' + file);
8+
}
9+
}
10+
}

tsconfig.json

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"compilerOptions": {
3+
"experimentalDecorators": true,
4+
"module": "NodeNext",
5+
"lib": [],
6+
"target": "ESNext",
7+
"esModuleInterop": true,
8+
"moduleResolution": "NodeNext",
9+
"resolveJsonModule": true
10+
},
11+
"typeRoots" : [
12+
"./typings",
13+
"@types"
14+
],
15+
"include": [
16+
"src/**/*.ts",
17+
],
18+
"ts-node": {
19+
"transpileOnly": true,
20+
"moduleTypes": {
21+
"*.ts": "cjs"
22+
}
23+
}
24+
}

0 commit comments

Comments
 (0)