UNPKG

@hpcc-js/wasm-graphviz-cli

Version:
180 lines (172 loc) 5.06 kB
#!/usr/bin/env node // src/main.ts import fs from "fs"; import { Graphviz } from "@hpcc-js/wasm-graphviz"; // src/cliArgs.ts var HELP_TEXT = `Usage: dot-wasm [options] fileOrDot Options: -K, --layout <engine> Set layout engine (circo | dot | fdp | sfdp | neato | osage | patchwork | twopi | nop | nop2). Default: dot -T, --format <format> Set output format (svg | dot | json | dot_json | xdot_json | plain | plain-ext). Default: svg -n, --neato-no-op <flag> Set neato no-op flag (only valid with -K neato) -y, --invert-y Invert Y axis in plain/plain-ext formats -v Echo GraphViz version -h, --help Show this help message Examples: dot-wasm -K neato -T xdot ./input.dot https://github.com/hpcc-systems/hpcc-js-wasm`; function parseArgs(args) { const parsed = { positional: [] }; const readValue = (flag, index) => { if (index >= args.length) { throw new Error(`${flag} option requires a value.`); } return args[index]; }; for (let i = 0; i < args.length; ++i) { const token = args[i]; if (token === "--") { parsed.positional.push(...args.slice(i + 1)); break; } if (token.startsWith("--")) { const [rawName, maybeValue] = token.slice(2).split("=", 2); i = handleOption(parsed, rawName, maybeValue ?? null, i, readValue); continue; } if (token.startsWith("-") && token.length > 1) { i = handleShortFlags(parsed, token.slice(1), i, readValue); continue; } parsed.positional.push(token); } return parsed; } function handleOption(parsed, name, value, currentIndex, readValue) { switch (name) { case "layout": parsed.layout = value ?? readValue("--layout", ++currentIndex); return currentIndex; case "format": parsed.format = value ?? readValue("--format", ++currentIndex); return currentIndex; case "neato-no-op": parsed.neatoNoOp = value ?? readValue("--neato-no-op", ++currentIndex); return currentIndex; case "invert-y": parsed.invertY = true; return currentIndex; case "help": parsed.help = true; return currentIndex; case "version": parsed.version = true; return currentIndex; default: throw new Error(`Unknown option --${name}`); } } function handleShortFlags(parsed, flags, currentIndex, readValue) { for (let j = 0; j < flags.length; ++j) { const flag = flags[j]; switch (flag) { case "K": { const remaining = flags.slice(j + 1); if (remaining) { parsed.layout = remaining; return currentIndex; } parsed.layout = readValue("-K", ++currentIndex); return currentIndex; } case "T": { const remaining = flags.slice(j + 1); if (remaining) { parsed.format = remaining; return currentIndex; } parsed.format = readValue("-T", ++currentIndex); return currentIndex; } case "n": { const remaining = flags.slice(j + 1); if (remaining) { parsed.neatoNoOp = remaining; return currentIndex; } parsed.neatoNoOp = readValue("-n", ++currentIndex); return currentIndex; } case "y": parsed.invertY = true; break; case "v": parsed.version = true; break; case "h": parsed.help = true; break; default: throw new Error(`Unknown option -${flag}`); } } return currentIndex; } // src/main.ts async function main() { try { const parsed = parseArgs(process.argv.slice(2)); if (parsed.help) { console.log(HELP_TEXT); return; } if (parsed.positional.length > 1) { throw new Error("Only one 'fileOrDot' argument is allowed."); } let dot; const fileOrDot = parsed.positional[0]; if (fileOrDot) { if (fs.existsSync(fileOrDot)) { dot = fs.readFileSync(fileOrDot, "utf8"); } else { dot = fileOrDot; } } const graphviz = await Graphviz.load(); if (parsed.version) { console.log(`GraphViz version: ${graphviz.version()}`); return; } if (dot) { const layout = (parsed.layout ?? "dot").trim(); const format = (parsed.format ?? "svg").trim(); if (parsed.neatoNoOp && layout !== "neato") { throw new Error("-n option is only supported with -K neato"); } const ext = {}; if (parsed.neatoNoOp) { ext.nop = parseInt(parsed.neatoNoOp, 10); } if (parsed.invertY) { ext.yInvert = true; } const response = graphviz.layout(dot, format, layout, ext); console.log(response); } else { throw new Error("'fileOrDot' is required."); } } catch (e) { console.error(`Error: ${e?.message} `); console.error(HELP_TEXT); } } // src/index.ts await main(); export { main }; //# sourceMappingURL=index.js.map