Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

reversa

Package Overview
Dependencies
Maintainers
1
Versions
50
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

reversa - npm Package Compare versions

Comparing version
1.2.37
to
1.2.38
+66
-12
lib/commands/export-diagrams.js
import { readFileSync, existsSync, mkdirSync, writeFileSync, readdirSync, statSync, unlinkSync } from 'fs';
import { join } from 'path';
import { execSync } from 'child_process';
import { join, resolve, isAbsolute, relative } from 'path';
import { execFileSync } from 'child_process';
import { tmpdir } from 'os';
import { readJsonSafe } from '../utils/json-safe.js';
const MMDC_TIMEOUT_MS = 60_000;
export default async function exportDiagrams(args) {

@@ -44,5 +46,11 @@ const { default: chalk } = await import('chalk');

const diagramsDir = customOutput
? join(process.cwd(), customOutput)
: join(sddPath, 'diagrams');
let diagramsDir;
try {
diagramsDir = customOutput
? resolveOutputDir(customOutput)
: join(sddPath, 'diagrams');
} catch (err) {
console.error(chalk.red(`\n ${err.message}\n`));
process.exit(1);
}

@@ -90,7 +98,8 @@ mkdirSync(diagramsDir, { recursive: true });

writeFileSync(tmpFile, diagram, 'utf8');
execSync(`${mmdc} -i "${tmpFile}" -o "${outPath}"`, { stdio: 'pipe' });
runMmdc(mmdc, ['-i', tmpFile, '-o', outPath]);
spin.succeed(chalk.hex('#ffa203')(` ✓ ${outName}`));
success++;
} catch (err) {
spin.fail(chalk.red(` ✗ ${outName} — ${err.stderr?.toString().split('\n')[0] || err.message}`));
const detail = err.stderr?.toString().split('\n')[0] || err.message;
spin.fail(chalk.red(` ✗ ${outName}: ${detail}`));
failed++;

@@ -108,11 +117,56 @@ } finally {

function resolveOutputDir(customOutput) {
if (/[\n\r\0]/.test(customOutput)) {
throw new Error('Invalid --output: contains control characters');
}
const target = isAbsolute(customOutput)
? resolve(customOutput)
: resolve(process.cwd(), customOutput);
const rel = relative(process.cwd(), target);
if (rel.startsWith('..') || isAbsolute(rel)) {
throw new Error(`Invalid --output: path must stay inside the project (${target})`);
}
return target;
}
function runMmdc(mmdc, extraArgs) {
execFileSync(mmdc.command, [...mmdc.prefixArgs, ...extraArgs], {
stdio: 'pipe',
shell: mmdc.shell,
timeout: MMDC_TIMEOUT_MS,
cwd: process.cwd(),
windowsHide: true,
});
}
function findMmdc() {
const localJs = join(process.cwd(), 'node_modules', '@mermaid-js', 'mermaid-cli', 'src', 'cli.js');
if (existsSync(localJs)) {
return { command: process.execPath, prefixArgs: [localJs], shell: false };
}
const localBin = join(process.cwd(), 'node_modules', '.bin', 'mmdc');
if (process.platform === 'win32') {
const localCmd = localBin + '.cmd';
if (existsSync(localCmd)) {
return { command: localCmd, prefixArgs: [], shell: true };
}
}
if (existsSync(localBin)) {
return { command: localBin, prefixArgs: [], shell: false };
}
try {
execSync('mmdc --version', { stdio: 'pipe' });
return 'mmdc';
const finder = process.platform === 'win32' ? 'where' : 'which';
const out = execFileSync(finder, ['mmdc'], { stdio: ['ignore', 'pipe', 'ignore'] })
.toString().trim().split(/\r?\n/)[0];
if (out && existsSync(out)) {
const isWinScript = process.platform === 'win32' && /\.(cmd|bat)$/i.test(out);
return { command: out, prefixArgs: [], shell: isWinScript };
}
} catch {}
const local = join(process.cwd(), 'node_modules', '.bin', 'mmdc');
if (existsSync(local)) return `"${local}"`;
return null;

@@ -119,0 +173,0 @@ }

+4
-5
import { existsSync } from 'fs';
import { join } from 'path';
import { execSync } from 'child_process';
import { execFileSync } from 'child_process';

@@ -126,7 +126,6 @@ export const ENGINES = [

function commandExists(cmd) {
if (!/^[a-zA-Z0-9_-]+$/.test(cmd)) return false;
try {
execSync(
process.platform === 'win32' ? `where ${cmd}` : `which ${cmd}`,
{ stdio: 'pipe' }
);
const finder = process.platform === 'win32' ? 'where' : 'which';
execFileSync(finder, [cmd], { stdio: 'pipe' });
return true;

@@ -133,0 +132,0 @@ } catch {

{
"name": "reversa",
"version": "1.2.37",
"version": "1.2.38",
"description": "Transform legacy systems into executable specifications for AI coding agents",

@@ -39,3 +39,3 @@ "bin": {

"engines": {
"node": ">=18.0.0"
"node": ">=18.20.2"
},

@@ -42,0 +42,0 @@ "dependencies": {