Files
rspade_system/bin/js-sanitizer.js
root f6fac6c4bc Fix bin/publish: copy docs.dist from project root
Fix bin/publish: use correct .env path for rspade_system
Fix bin/publish script: prevent grep exit code 1 from terminating script

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-21 02:08:33 +00:00

136 lines
4.3 KiB
JavaScript
Executable File

#!/usr/bin/env node
/**
* JavaScript Sanitizer for Code Quality Checks
*
* This script removes comments and replaces string contents with spaces
* while preserving line numbers and column positions for accurate violation reporting.
*
* Usage: node js-sanitizer.js <input-file>
* Output: Sanitized JavaScript to stdout
*/
const fs = require('fs');
const decomment = require('decomment');
const acorn = require('acorn');
// Get input file from command line arguments
const inputFile = process.argv[2];
if (!inputFile) {
console.error('Usage: node js-sanitizer.js <input-file>');
process.exit(1);
}
// Read the input file
let code;
try {
code = fs.readFileSync(inputFile, 'utf8');
} catch (error) {
console.error(`Error reading file: ${error.message}`);
process.exit(1);
}
// Step 1: Remove comments while preserving spaces
let sanitized;
try {
sanitized = decomment(code, {
space: true, // Replace comments with spaces to preserve line numbers
tolerant: true // Handle potential syntax issues
});
} catch (error) {
// If decomment fails, continue with original code
sanitized = code;
}
// Step 2: Parse the code to find string literals and replace their contents
try {
// Parse with location tracking
const ast = acorn.parse(sanitized, {
ecmaVersion: 'latest',
sourceType: 'module',
locations: true,
ranges: true,
allowReturnOutsideFunction: true,
allowImportExportEverywhere: true,
allowAwaitOutsideFunction: true,
allowSuperOutsideMethod: true,
allowHashBang: true,
onComment: () => {} // Ignore comments (already removed)
});
// Convert code to array of characters for manipulation
const chars = sanitized.split('');
// Function to replace string content with spaces
function replaceStringContent(node) {
if (node.type === 'Literal' && typeof node.value === 'string') {
// For string literals, replace the content (but keep the quotes)
const start = node.range[0];
const end = node.range[1];
// Find the quote character (first non-whitespace character)
let quoteChar = chars[start];
let quoteEnd = chars[end - 1];
// Replace everything between quotes with spaces
for (let i = start + 1; i < end - 1; i++) {
if (chars[i] !== '\n') { // Preserve newlines for line counting
chars[i] = ' ';
}
}
} else if (node.type === 'TemplateLiteral') {
// For template literals, replace the raw text parts
for (let quasi of node.quasis) {
const start = quasi.range[0];
const end = quasi.range[1];
// Replace content between backticks or ${...}
for (let i = start + 1; i < end - 1; i++) {
if (chars[i] !== '\n' && chars[i] !== '$' && chars[i] !== '{' && chars[i] !== '}') {
chars[i] = ' ';
}
}
}
}
}
// Walk the AST to find all string literals
function walk(node) {
if (!node) return;
// Process current node
replaceStringContent(node);
// Recursively process all child nodes
for (let key in node) {
if (key === 'range' || key === 'loc' || key === 'start' || key === 'end') {
continue; // Skip location properties
}
const value = node[key];
if (Array.isArray(value)) {
for (let item of value) {
if (typeof item === 'object' && item !== null) {
walk(item);
}
}
} else if (typeof value === 'object' && value !== null) {
walk(value);
}
}
}
// Walk the AST to process all strings
walk(ast);
// Convert back to string
sanitized = chars.join('');
} catch (error) {
// If parsing fails (e.g., syntax error), we still have comments removed
// Just continue with the decommented version
}
// Output the sanitized code
process.stdout.write(sanitized);