UNPKG

draig-car

Version:

Database REST API interactive generator CLI and REPL OpenAPI3 based JS generator with interactive ORM/ODM REPL

80 lines (74 loc) 2.4 kB
const vm = require('vm') const repl = require('repl') const chalk = require('chalk') const { processTopLevelAwait } = require('node-repl-await') const i = require('./init') const u = require('./util') const synErrorRex = new RegExp( '^(' + ['Unexpected end of input', 'Unexpected token'].join('|') + ')' ) async function draigEval(code, ctx, filename, callback) { if (code === '\n') return ctx.repl.displayPrompt() if(code.includes("model.") || code.includes("knex.raw(") || code.includes("knex.select(") || code.includes("knex(")) u.lastquery = code.replace(/model./g, "").replace(/\n/g, "") if(code.includes("_.")) u.lasttransform = code.replace(/\_./g, "rows.").replace(/\n/g, "") code = processTopLevelAwait(code) || code try { callback(null, await (async () => { let result = await vm.runInNewContext(code, ctx) if(result && result.rows) return result.rows return result })(code, ctx)) } catch (e) { if (e.name === 'SyntaxError' && synErrorRex.test(e.message)) callback(new repl.Recoverable(e)) else { console.log('Error', e) ctx.repl.displayPrompt() } } } async function startRepl(argv) { if (!argv.silent && argv._.includes('repl')) u.showBanner() u.testRequisites(argv) let r = repl.start({ eval: draigEval, preview: true }) r.setupHistory('.draig-console.history', () => {}) r.on('reset', ctx => { ctx.repl = r ctx.argv = argv i.initCtx(ctx) }) r.on('exit', () => { u.stopAPI(r.context) process.exit() }) process.on('unhandledRejection', reason => { console.log(chalk`{yellow Unhandled Promise Rejection}: `, reason) if (r.context.argv === undefined || r.context.argv._.includes('run')) process.exit(0) else r.displayPrompt() }) i.initRepl(r) r.context.argv = argv i.initCtx(r.context) if (argv._.includes('run')) { if (!(argv.intcmd in r.commands) || !r.commands[argv.intcmd].runnable) { console.error( chalk`Sorry, {green ${argv.intcmd}} is not a valid command` ) process.exit(1) } let msg = chalk`Running internal command {green ${argv.intcmd}}` if (argv.intargs.length) msg += chalk` with args {green ${argv.intargs}}` console.log(msg + '...\n') await r.commands[argv.intcmd].action.bind(r, argv.intargs)() console.log(chalk`Command {green ${argv.intcmd}} done.`) process.exit(0) } else { u.setPrompt(r.context, r) r.displayPrompt() } } module.exports.startRepl = startRepl