fortify2-js
Version:
MOST POWERFUL JavaScript Security Library! Military-grade cryptography + 19 enhanced object methods + quantum-resistant algorithms + perfect TypeScript support. More powerful than Lodash with built-in security.
201 lines (170 loc) • 6.39 kB
JavaScript
/**
* TSR - TypeScript Runner
*/
const { readFileSync, writeFileSync, existsSync, mkdirSync } = require('fs');
const { spawn } = require('child_process');
const { join, dirname, extname, basename } = require('path');
class TSR {
constructor() {
this.tempDir = join(process.cwd(), '.tsr-temp');
this.ensureTempDir();
}
ensureTempDir() {
if (!existsSync(this.tempDir)) {
mkdirSync(this.tempDir, { recursive: true });
}
}
async run(scriptPath, args = []) {
if (!existsSync(scriptPath)) {
throw new Error(`Script file not found: ${scriptPath}`);
}
// For TypeScript files, use runtime compilation (most reliable)
if (this.isTypeScriptFile(scriptPath)) {
try {
console.log('Compiling TypeScript...');
const compiledPath = await this.compileTypeScript(scriptPath);
return {
runtime: 'node',
args: [compiledPath, ...args]
};
} catch (error) {
console.warn('Runtime compilation failed, trying external runners...');
}
}
// Try external runners as fallback
const runners = ['ts-node', 'tsx', 'bun'];
for (const runner of runners) {
const runnerPath = this.findRunner(runner);
if (runnerPath) {
console.log(`Using external runner: ${runner}`);
return {
runtime: runnerPath,
args: runner === 'bun' ? ['run', scriptPath, ...args] : [scriptPath, ...args]
};
}
}
// Final fallback to node
console.warn('No TypeScript support available, using node directly');
return {
runtime: 'node',
args: [scriptPath, ...args]
};
}
findRunner(runner) {
const paths = [
join(process.cwd(), 'node_modules', '.bin', runner),
join(process.cwd(), 'node_modules', '.bin', `${runner}.cmd`),
join(process.cwd(), 'node_modules', '.bin', `${runner}.exe`),
];
for (const path of paths) {
if (existsSync(path)) {
return path;
}
}
return null;
}
async compileTypeScript(scriptPath) {
try {
// Try to use TypeScript compiler
const ts = require('typescript');
const sourceCode = readFileSync(scriptPath, 'utf8');
const result = ts.transpileModule(sourceCode, {
compilerOptions: {
target: ts.ScriptTarget.ES2020,
module: ts.ModuleKind.CommonJS,
moduleResolution: ts.ModuleResolutionKind.NodeJs,
allowSyntheticDefaultImports: true,
esModuleInterop: true,
skipLibCheck: true,
strict: false,
},
fileName: scriptPath,
});
const compiledPath = join(this.tempDir, `${basename(scriptPath, '.ts')}.js`);
writeFileSync(compiledPath, result.outputText);
return compiledPath;
} catch (error) {
// Simple fallback transpilation
return this.simpleTranspile(scriptPath);
}
}
simpleTranspile(scriptPath) {
const sourceCode = readFileSync(scriptPath, 'utf8');
// Basic TypeScript to JavaScript conversion
let jsCode = sourceCode
.replace(/:\s*[A-Za-z_$][A-Za-z0-9_$<>[\]|&\s]*(?=\s*[=,;)\n])/g, '')
.replace(/interface\s+[A-Za-z_$][A-Za-z0-9_$]*\s*{[^}]*}/g, '')
.replace(/import\s+type\s+{[^}]*}\s+from\s+['"][^'"]*['"];?/g, '')
.replace(/<[A-Za-z_$][A-Za-z0-9_$<>[\]|&\s]*>/g, '')
.replace(/\s+as\s+[A-Za-z_$][A-Za-z0-9_$<>[\]|&\s]*/g, '');
const compiledPath = join(this.tempDir, `${basename(scriptPath, '.ts')}.js`);
writeFileSync(compiledPath, jsCode);
return compiledPath;
}
isTypeScriptFile(filePath) {
const ext = extname(filePath).toLowerCase();
return ext === '.ts' || ext === '.tsx';
}
cleanup() {
try {
const fs = require('fs');
if (existsSync(this.tempDir)) {
fs.rmSync(this.tempDir, { recursive: true, force: true });
}
} catch (error) {
// Ignore cleanup errors
}
}
}
async function main() {
const args = process.argv.slice(2);
if (args.length === 0) {
console.error('Usage: tsr <script.ts> [args...]');
console.error(' npx tsr <script.ts> [args...]');
console.error('');
console.error('Examples:');
console.error(' tsr server.ts');
console.error(' tsr app.ts --port 3000');
console.error(' npx tsr test.ts arg1 arg2');
console.error('');
console.error('Installation:');
console.error(' npm install -g fortify2-js # Global install');
console.error(' npm install fortify2-js # Local install (use with npx)');
process.exit(1);
}
const scriptPath = args[0];
const scriptArgs = args.slice(1);
const tsr = new TSR();
try {
const result = await tsr.run(scriptPath, scriptArgs);
console.log(`Executing: ${result.runtime} ${result.args.join(' ')}`);
const childProcess = spawn(result.runtime, result.args, {
stdio: 'inherit',
detached: false,
});
childProcess.on('exit', (code, signal) => {
tsr.cleanup();
process.exit(code || 0);
});
childProcess.on('error', (error) => {
console.error('Process error:', error.message);
tsr.cleanup();
process.exit(1);
});
// Handle process termination
process.on('SIGINT', () => {
childProcess.kill('SIGINT');
});
process.on('SIGTERM', () => {
childProcess.kill('SIGTERM');
});
} catch (error) {
console.error('TSR error:', error.message);
process.exit(1);
}
}
main().catch(error => {
console.error('Fatal error:', error.message);
process.exit(1);
});