crapifyme
Version:
Ultra-fast developer productivity CLI tools - remove comments, logs, and more
173 lines • 6.99 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CharacterDetector = void 0;
const any_ascii_1 = __importDefault(require("any-ascii"));
const types_1 = require("./types");
class CharacterDetector {
constructor(logger, options = {}) {
this.logger = logger;
this.options = {
strict: false,
interactive: false,
showContext: 40,
ignoreStrings: false,
ignoreComments: false,
...options
};
}
detectCharacters(content, filePath) {
const issues = [];
const lines = content.split('\n');
for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {
const line = lines[lineIndex];
for (let charIndex = 0; charIndex < line.length; charIndex++) {
const char = line[charIndex];
const codePoint = char.codePointAt(0) || 0;
if (this.shouldIgnoreCharacter(char, codePoint, line, charIndex)) {
continue;
}
const scriptInfo = this.getScriptInfo(codePoint);
if (scriptInfo || (this.options.strict && codePoint > 127)) {
const context = this.getContext(line, charIndex, this.options.showContext || 40);
const replacement = (0, any_ascii_1.default)(char);
issues.push({
character: char,
codePoint,
line: lineIndex + 1,
column: charIndex + 1,
context,
script: scriptInfo?.script || types_1.ScriptType.OTHER,
severity: scriptInfo?.severity || types_1.IssueSeverity.MEDIUM,
replacement: replacement !== char ? replacement : undefined
});
}
}
}
return {
content,
modified: false,
issues,
fixed: 0
};
}
fixCharacters(content, filePath) {
const result = this.detectCharacters(content, filePath);
let modifiedContent = content;
let fixed = 0;
const sortedIssues = result.issues
.filter(issue => issue.replacement !== undefined)
.sort((a, b) => {
if (a.line !== b.line)
return b.line - a.line;
return b.column - a.column;
});
for (const issue of sortedIssues) {
const lines = modifiedContent.split('\n');
if (lines[issue.line - 1]) {
const line = lines[issue.line - 1];
const before = line.substring(0, issue.column - 1);
const after = line.substring(issue.column);
lines[issue.line - 1] = before + (issue.replacement || '') + after;
modifiedContent = lines.join('\n');
fixed++;
}
}
return {
content: modifiedContent,
modified: fixed > 0,
issues: result.issues,
fixed
};
}
shouldIgnoreCharacter(char, codePoint, line, charIndex) {
if (codePoint <= 127 && !this.options.strict) {
return true;
}
if (this.options.ignoreStrings && this.isInString(line, charIndex)) {
return true;
}
if (this.options.ignoreComments && this.isInComment(line, charIndex)) {
return true;
}
return false;
}
getScriptInfo(codePoint) {
for (const range of CharacterDetector.CHARACTER_RANGES) {
if (codePoint >= range.start && codePoint <= range.end) {
return { script: range.script, severity: range.severity };
}
}
return null;
}
getContext(line, charIndex, contextLength) {
const start = Math.max(0, charIndex - Math.floor(contextLength / 2));
const end = Math.min(line.length, charIndex + Math.floor(contextLength / 2));
const context = line.substring(start, end);
const prefix = start > 0 ? '...' : '';
const suffix = end < line.length ? '...' : '';
return prefix + context + suffix;
}
isInString(line, charIndex) {
let inString = false;
let quote = '';
let escaped = false;
for (let i = 0; i < charIndex; i++) {
const char = line[i];
if (escaped) {
escaped = false;
continue;
}
if (char === '\\') {
escaped = true;
continue;
}
if (!inString && (char === '"' || char === "'" || char === '`')) {
inString = true;
quote = char;
}
else if (inString && char === quote) {
inString = false;
quote = '';
}
}
return inString;
}
isInComment(line, charIndex) {
const beforeChar = line.substring(0, charIndex);
const singleLineComment = beforeChar.indexOf('//');
const blockCommentStart = beforeChar.indexOf('/*');
return singleLineComment !== -1 || blockCommentStart !== -1;
}
getScriptTypeStats(issues) {
const stats = {};
for (const scriptType of Object.values(types_1.ScriptType)) {
stats[scriptType] = 0;
}
for (const issue of issues) {
stats[issue.script]++;
}
return stats;
}
}
exports.CharacterDetector = CharacterDetector;
CharacterDetector.CHARACTER_RANGES = [
{
start: 0x0080,
end: 0x00ff,
script: types_1.ScriptType.LATIN_EXTENDED,
severity: types_1.IssueSeverity.MEDIUM
},
{ start: 0x0100, end: 0x024f, script: types_1.ScriptType.LATIN_EXTENDED, severity: types_1.IssueSeverity.LOW },
{ start: 0x1e00, end: 0x1eff, script: types_1.ScriptType.LATIN_EXTENDED, severity: types_1.IssueSeverity.LOW },
{ start: 0x0370, end: 0x03ff, script: types_1.ScriptType.GREEK, severity: types_1.IssueSeverity.MEDIUM },
{ start: 0x0400, end: 0x04ff, script: types_1.ScriptType.CYRILLIC, severity: types_1.IssueSeverity.HIGH },
{ start: 0x4e00, end: 0x9fff, script: types_1.ScriptType.CJK, severity: types_1.IssueSeverity.HIGH },
{ start: 0x3400, end: 0x4dbf, script: types_1.ScriptType.CJK, severity: types_1.IssueSeverity.HIGH },
{ start: 0x0600, end: 0x06ff, script: types_1.ScriptType.ARABIC, severity: types_1.IssueSeverity.HIGH },
{ start: 0x200b, end: 0x200d, script: types_1.ScriptType.INVISIBLE, severity: types_1.IssueSeverity.CRITICAL },
{ start: 0xfeff, end: 0xfeff, script: types_1.ScriptType.INVISIBLE, severity: types_1.IssueSeverity.CRITICAL }
];
//# sourceMappingURL=logic.js.map