Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

css-conflict-inspector

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

css-conflict-inspector - npm Package Compare versions

Comparing version 0.1.0 to 0.1.1

esm/analyze.d.ts

24

lib/index.d.ts

@@ -1,22 +0,2 @@

export interface CssInspectorOptions {
universalPenalty?: number;
elementPenalty?: number;
customElementPenalty?: number;
simpleClassPenalty?: number;
simplerClassPenalty?: number;
simplestClassPenalty?: number;
idPenalty?: number;
attributePenalty?: number;
}
export interface CssConflict {
penalty: number;
message: string;
}
export declare function analyzeCss(content: string, options?: CssInspectorOptions): {
selectors: string[];
conflicts: CssConflict[];
warnings: import("lightningcss").Warning[];
dependencies: void | import("lightningcss").Dependency[];
totalPenalty: number;
score: number;
};
export * from './analyze';
export type * from './types';
"use strict";
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.analyzeCss = void 0;
var lightningcss_1 = require("lightningcss");
function getPenalty(options, name, defaultValue) {
if (name in options) {
var value = options[name];
if (typeof value === 'number') {
return value;
}
}
return defaultValue;
}
function inspect(selectors, violations, options, scale) {
if (scale === void 0) { scale = 1; }
selectors.forEach(function (sel) {
switch (sel.type) {
case 'combinator': {
// e.g., ">"
switch (sel.value) {
case 'descendant':
scale *= 0.4;
break;
case 'child':
scale *= 0.2;
break;
case 'next-sibling':
case 'later-sibling':
scale *= 0.1;
break;
}
break;
}
case 'universal': {
// e.g., "*"
var penalty = getPenalty(options, 'universalPenalty', 50) * scale;
if (penalty) {
violations.push({
message: 'Detected use of an universal selector ("*")',
penalty: penalty,
});
}
break;
}
case 'type': {
// e.g., "p"
var elementPenalty = getPenalty(options, 'elementPenalty', 20) * scale;
var customElementPenalty = getPenalty(options, 'customElementPenalty', 10) * scale;
var isCustomElement = sel.name.includes('-');
if (isCustomElement && customElementPenalty) {
violations.push({
message: "Detected use of a type selector (custom element \"".concat(sel.name, "\")"),
penalty: customElementPenalty,
});
}
else if (!isCustomElement && elementPenalty) {
violations.push({
message: "Detected use of a type selector (element \"".concat(sel.name, "\")"),
penalty: elementPenalty,
});
}
break;
}
case 'class': {
// e.g., ".foo"
var numHyphens = sel.name.replace(/[^\_\-]/g, '').length;
var simplePenalty = getPenalty(options, 'simpleClassPenalty', 5) * scale;
var simplerPenalty = getPenalty(options, 'simplerClassPenalty', 3) * scale;
var simplestPenalty = getPenalty(options, 'simplestClassPenalty', 2) * scale;
if (numHyphens < 1 && sel.name.length < 8 && simplePenalty) {
violations.push({
message: "Detected use of a simple class selector (\"".concat(sel.name, "\")"),
penalty: simplePenalty,
});
}
else if (numHyphens < 1 && sel.name.length < 20 && simplerPenalty) {
violations.push({
message: "Detected use of an almost simple class selector (\"".concat(sel.name, "\")"),
penalty: simplerPenalty,
});
}
else if (numHyphens < 2 && sel.name.length < 10 && simplestPenalty) {
violations.push({
message: "Detected use of an almost simple class selector (\"".concat(sel.name, "\")"),
penalty: simplestPenalty,
});
}
else {
scale = 0;
}
break;
}
case 'id': {
// e.g., "#foo"
var penalty = getPenalty(options, 'idPenalty', 0) * scale;
if (penalty) {
violations.push({
message: "Detected use of an ID selector (\"".concat(sel.name, "\")"),
penalty: penalty,
});
}
break;
}
case 'attribute': {
// e.g., "hidden"
var penalty = getPenalty(options, 'attributePenalty', 0) * scale;
if (penalty) {
violations.push({
message: "Detected use of an attribute selector (\"".concat(sel.name, "\")"),
penalty: penalty,
});
}
break;
}
case 'pseudo-class': {
// e.g., ":where"
if (sel.kind === 'not') {
inspect(sel.selectors, violations, options, 0.5);
}
else if (sel.kind === 'where') {
inspect(sel.selectors, violations, options, 0.5);
}
else if (sel.kind === 'has') {
inspect(sel.selectors, violations, options, 0.2);
}
else if (sel.kind === 'is') {
inspect(sel.selectors, violations, options, 0.1);
}
else {
//
}
break;
}
case 'pseudo-element': {
break;
}
default: {
if (Array.isArray(sel)) {
inspect(sel, violations, options);
}
else {
console.log('Got unknown type', sel.type, sel);
}
break;
}
}
});
}
function serializeOperation(op) {
if (op) {
var mapping = {
equal: '=',
includes: '~=',
'dash-match': '|=',
prefix: '^=',
substring: '*=',
suffix: '$=',
};
var o = mapping[op.operator];
return "".concat(o).concat(op.value);
}
return '';
}
function serializeNamespace(ns) {
if (ns) {
if (ns.type === 'specific') {
return "".concat(ns.prefix, "\\:");
}
else if (ns.type === 'any') {
return '*\\:';
}
}
return '';
}
function stringify(selectors) {
return selectors
.map(function (sel) {
switch (sel.type) {
case 'combinator':
// e.g., ">"
switch (sel.value) {
case 'descendant':
return ' ';
case 'child':
return '>';
case 'next-sibling':
return '+';
case 'later-sibling':
return '~';
}
return '';
case 'universal':
// e.g., "*"
return '*';
case 'type':
// e.g., "p"
return sel.name;
case 'class':
// e.g., ".foo"
return ".".concat(sel.name);
case 'id':
// e.g., "#foo"
return "#".concat(sel.name);
case 'attribute':
// e.g., "hidden"
return "[".concat(serializeNamespace(sel.namespace)).concat(sel.name).concat(serializeOperation(sel.operation), "]");
case 'pseudo-class':
// e.g., ":where"
if (Array.isArray(sel.selectors)) {
var inner = stringify(sel.selectors);
return ":".concat(sel.kind, "(").concat(inner, ")");
}
return ":".concat(sel.kind);
case 'pseudo-element':
return "::".concat(sel.kind);
default: {
if (Array.isArray(sel)) {
return stringify(sel);
}
return '';
}
}
})
.join('');
}
function analyzeCss(content, options) {
if (options === void 0) { options = {}; }
var conflicts = [];
var selectors = [];
var result = (0, lightningcss_1.transform)({
code: Buffer.from(content, 'utf8'),
filename: 'style.css',
analyzeDependencies: true,
errorRecovery: true,
visitor: {
Selector: function (selector) {
var violations = [];
inspect(selector, violations, options);
var conflict = violations
.filter(function (v) { return v.penalty; })
.reduce(function (p, c) {
if (p && p.penalty < c.penalty) {
return __assign(__assign({}, c), { penalty: p.penalty });
}
return c;
}, undefined);
if (conflict) {
conflicts.push(conflict);
}
selectors.push(stringify(selector));
},
},
});
return {
selectors: selectors,
conflicts: conflicts,
warnings: result.warnings,
dependencies: result.dependencies,
totalPenalty: Math.ceil(conflicts.reduce(function (p, c) { return p + c.penalty; }, 0)),
score: 100 - Math.ceil(conflicts.reduce(function (p, c) { return Math.max(p, c.penalty); }, 0)),
};
}
exports.analyzeCss = analyzeCss;
__exportStar(require("./analyze"), exports);
//# sourceMappingURL=index.js.map
{
"name": "css-conflict-inspector",
"version": "0.1.0",
"version": "0.1.1",
"description": "Find potential conflict in your CSS files - to avoid surprises when used in the context of Micro Frontends.",

@@ -15,2 +15,7 @@ "main": "lib/index.js",

},
"files": [
"esm",
"lib",
"src"
],
"repository": {

@@ -17,0 +22,0 @@ "type": "git",

@@ -1,295 +0,2 @@

import { transform, Selector, AttrOperation, NamespaceConstraint } from 'lightningcss';
export interface CssInspectorOptions {
universalPenalty?: number;
elementPenalty?: number;
customElementPenalty?: number;
simpleClassPenalty?: number;
simplerClassPenalty?: number;
simplestClassPenalty?: number;
idPenalty?: number;
attributePenalty?: number;
}
export interface CssConflict {
penalty: number;
message: string;
}
function getPenalty(options: CssInspectorOptions, name: keyof CssInspectorOptions, defaultValue: number) {
if (name in options) {
const value = options[name];
if (typeof value === 'number') {
return value;
}
}
return defaultValue;
}
function inspect(selectors: Selector | Array<Selector>, violations: Array<CssConflict>, options: CssInspectorOptions, scale = 1) {
selectors.forEach((sel) => {
switch (sel.type) {
case 'combinator': {
// e.g., ">"
switch (sel.value) {
case 'descendant':
scale *= 0.4;
break;
case 'child':
scale *= 0.2;
break;
case 'next-sibling':
case 'later-sibling':
scale *= 0.1;
break;
}
break;
}
case 'universal': {
// e.g., "*"
const penalty = getPenalty(options, 'universalPenalty', 50) * scale;
if (penalty) {
violations.push({
message: 'Detected use of an universal selector ("*")',
penalty,
});
}
break;
}
case 'type': {
// e.g., "p"
const elementPenalty = getPenalty(options, 'elementPenalty', 20) * scale;
const customElementPenalty = getPenalty(options, 'customElementPenalty', 10) * scale;
const isCustomElement = sel.name.includes('-');
if (isCustomElement && customElementPenalty) {
violations.push({
message: `Detected use of a type selector (custom element "${sel.name}")`,
penalty: customElementPenalty,
});
} else if (!isCustomElement && elementPenalty) {
violations.push({
message: `Detected use of a type selector (element "${sel.name}")`,
penalty: elementPenalty,
});
}
break;
}
case 'class': {
// e.g., ".foo"
const numHyphens = sel.name.replace(/[^\_\-]/g, '').length;
const simplePenalty = getPenalty(options, 'simpleClassPenalty', 5) * scale;
const simplerPenalty = getPenalty(options, 'simplerClassPenalty', 3) * scale;
const simplestPenalty = getPenalty(options, 'simplestClassPenalty', 2) * scale;
if (numHyphens < 1 && sel.name.length < 8 && simplePenalty) {
violations.push({
message: `Detected use of a simple class selector ("${sel.name}")`,
penalty: simplePenalty,
});
} else if (numHyphens < 1 && sel.name.length < 20 && simplerPenalty) {
violations.push({
message: `Detected use of an almost simple class selector ("${sel.name}")`,
penalty: simplerPenalty,
});
} else if (numHyphens < 2 && sel.name.length < 10 && simplestPenalty) {
violations.push({
message: `Detected use of an almost simple class selector ("${sel.name}")`,
penalty: simplestPenalty,
});
} else {
scale = 0;
}
break;
}
case 'id': {
// e.g., "#foo"
const penalty = getPenalty(options, 'idPenalty', 0) * scale;
if (penalty) {
violations.push({
message: `Detected use of an ID selector ("${sel.name}")`,
penalty,
});
}
break;
}
case 'attribute': {
// e.g., "hidden"
const penalty = getPenalty(options, 'attributePenalty', 0) * scale;
if (penalty) {
violations.push({
message: `Detected use of an attribute selector ("${sel.name}")`,
penalty,
});
}
break;
}
case 'pseudo-class': {
// e.g., ":where"
if (sel.kind === 'not') {
inspect(sel.selectors, violations, options, 0.5);
} else if (sel.kind === 'where') {
inspect(sel.selectors, violations, options, 0.5);
} else if (sel.kind === 'has') {
inspect(sel.selectors, violations, options, 0.2);
} else if (sel.kind === 'is') {
inspect(sel.selectors, violations, options, 0.1);
} else {
//
}
break;
}
case 'pseudo-element': {
break;
}
default: {
if (Array.isArray(sel)) {
inspect(sel, violations, options);
} else {
console.log('Got unknown type', sel.type, sel);
}
break;
}
}
});
}
function serializeOperation(op: AttrOperation | undefined) {
if (op) {
const mapping = {
equal: '=',
includes: '~=',
'dash-match': '|=',
prefix: '^=',
substring: '*=',
suffix: '$=',
};
const o = mapping[op.operator];
return `${o}${op.value}`;
}
return '';
}
function serializeNamespace(ns: NamespaceConstraint | undefined) {
if (ns) {
if (ns.type === 'specific') {
return `${ns.prefix}\\:`;
} else if (ns.type === 'any') {
return '*\\:';
}
}
return '';
}
function stringify(selectors: Selector | Array<Selector>) {
return selectors
.map((sel) => {
switch (sel.type) {
case 'combinator':
// e.g., ">"
switch (sel.value) {
case 'descendant':
return ' ';
case 'child':
return '>';
case 'next-sibling':
return '+';
case 'later-sibling':
return '~';
}
return '';
case 'universal':
// e.g., "*"
return '*';
case 'type':
// e.g., "p"
return sel.name;
case 'class':
// e.g., ".foo"
return `.${sel.name}`;
case 'id':
// e.g., "#foo"
return `#${sel.name}`;
case 'attribute':
// e.g., "hidden"
return `[${serializeNamespace(sel.namespace)}${sel.name}${serializeOperation(sel.operation)}]`;
case 'pseudo-class':
// e.g., ":where"
if (Array.isArray(sel.selectors)) {
const inner = stringify(sel.selectors);
return `:${sel.kind}(${inner})`;
}
return `:${sel.kind}`;
case 'pseudo-element':
return `::${sel.kind}`;
default: {
if (Array.isArray(sel)) {
return stringify(sel);
}
return '';
}
}
})
.join('');
}
export function analyzeCss(content: string, options: CssInspectorOptions = {}) {
const conflicts: Array<CssConflict> = [];
const selectors: Array<string> = [];
const result = transform({
code: Buffer.from(content, 'utf8'),
filename: 'style.css',
analyzeDependencies: true,
errorRecovery: true,
visitor: {
Selector(selector) {
const violations: Array<CssConflict> = [];
inspect(selector, violations, options);
const conflict = violations
.filter((v) => v.penalty)
.reduce((p, c) => {
if (p && p.penalty < c.penalty) {
return {
...c,
penalty: p.penalty,
};
}
return c;
}, undefined as CssConflict | undefined);
if (conflict) {
conflicts.push(conflict);
}
selectors.push(stringify(selector));
},
},
});
return {
selectors,
conflicts,
warnings: result.warnings,
dependencies: result.dependencies,
totalPenalty: Math.ceil(conflicts.reduce((p, c) => p + c.penalty, 0)),
score: 100 - Math.ceil(conflicts.reduce((p, c) => Math.max(p, c.penalty), 0)),
};
}
export * from './analyze';
export type * from './types';

Sorry, the diff of this file is not supported yet

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