cli.js (1793B)
1 #!/usr/bin/env node 2 /** Explicit export and result format; positional application arguments are text. */ 3 import { readFileSync } from 'node:fs'; 4 import { Library } from './lib.js'; 5 6 const [command, bundle, name, ...args] = process.argv.slice(2); 7 if (command !== 'run' || !bundle || !name) { 8 console.error('Usage: arboricx-run run BUNDLE EXPORT [--io] [--format string|number|bool|bytes] [--] [text arguments...]'); 9 process.exitCode = 1; 10 } else { 11 let ctx; 12 try { 13 ctx = new Library().context(); 14 let term = ctx.loadBundle(readFileSync(bundle), name), io = false, format = 'string', options = true; 15 for (let i = 0; i < args.length; i++) { 16 if (options && args[i] === '--') { options = false; continue; } 17 if (options && args[i] === '--io') { io = true; continue; } 18 if (options && args[i] === '--format') { format = args[++i]; continue; } 19 if (options && args[i].startsWith('--')) throw new Error(`unknown option: ${args[i]}`); 20 const argument = ctx.string(args[i]); 21 const next = ctx.apply(term, argument); 22 ctx.release(term); ctx.release(argument); term = next; 23 } 24 if (!['string', 'number', 'bool', 'bytes'].includes(format)) throw new Error('invalid result format'); 25 if (io) { 26 const result = ctx.runIO(term); 27 if (result.outcome !== 0) throw new Error(`IO task ${result.outcome === 1 ? 'failed' : 'cancelled'} (reason left opaque)`); 28 term = result.value; 29 } 30 const result = {string: () => ctx.toString(term), number: () => ctx.toNumber(term).toString(), 31 bool: () => String(ctx.toBool(term)), bytes: () => ctx.toBytes(term).toString('hex')}[format](); 32 console.log(result); 33 } catch (error) { 34 console.error(`Error: ${error.message}`); 35 process.exitCode = 1; 36 } finally { ctx?.close(); } 37 }