draig-car
Version:
Database REST API interactive generator CLI and REPL OpenAPI3 based JS generator with interactive ORM/ODM REPL
119 lines (115 loc) • 4.07 kB
JavaScript
const fs = require('fs')
const path = require('path')
const chalk = require('chalk')
const yaml = require('js-yaml')
const clearModule = require('clear-module')
const u = require('./util')
const a = require('./actions/common')
// Initialization
module.exports = {
initRepl: repl => {
let ctx = repl.context
let oldCompleter = repl.completer
ctx.repl = repl
repl.writer.options.depth = null
repl.completer = (line, callback) => {
let comp = [],
last,
rest
if (line.startsWith('.newop ')) {
comp = u.templateList(ctx.argv, 'op', 'all')
last = line.split(' ')[1]
} else if (line.startsWith('.newsch ')) {
comp = u.templateList(ctx.argv, 'schema', 'all')
last = line.split(' ')[1]
} else if (line.startsWith('.addprop ')) {
comp = Object.keys(ctx.api.components.schemas)
last = line.split(' ')[1]
} else if (
line.startsWith('.edit ') ||
line.startsWith('.rm ') ||
line.startsWith('.cd ') ||
line.startsWith('.ls ') ||
line.startsWith('.print ') ||
line.startsWith('.addelem ') ||
line.startsWith('.annotate ')
) {
let args = line
.split(' ')
.slice(1)
.filter(e => e !== '')
last = line.endsWith(' ') ? '' : args[args.length - 1]
rest = line.endsWith(' ') ? args : args.slice(0, args.length - 1)
let [value] = a.apiValue(ctx, rest)
if (typeof value !== 'undefined') comp = Object.keys(value)
} else if (
line.startsWith('.migrate up ') ||
line.startsWith('.migrate down ')
) {
comp = fs.readdirSync(path.resolve(ctx.argv.projectDir, 'migrations'))
last = line.split(' ')[2]
} else if (line.startsWith('.migrate ')) {
comp = ['up', 'down']
last = line.split(' ')[1]
} else if (line.startsWith('.seed ')) {
comp = fs.readdirSync(path.resolve(ctx.argv.projectDir, 'seeds'))
last = line.split(' ')[1]
} else if (line.startsWith('.desc ')) {
comp = Object.keys(ctx.model).map(e => ctx.model[e].tableName)
last = line.split(' ')[1]
} else return oldCompleter(line, callback)
const hits = comp.filter(c => c && c.startsWith(last))
const ret = [last !== undefined ? hits : comp, last || '']
callback(null, ret)
}
},
initCtx: (ctx) => {
if (!ctx.argv.silent) console.log('Context (re)initialized')
// Read api definition (again)
if (ctx.argv && ctx.argv.api) {
ctx.apiPath = []
ctx.api = yaml.safeLoad(fs.readFileSync(ctx.argv.api))
u.setPrompt(ctx)
if (!ctx.argv.silent)
console.log(chalk`> API from {italic ${ctx.argv.api}} (re)loaded`)
const commands = require('./commands')
for (c in commands) ctx.repl.defineCommand(c, commands[c])
} else if (!ctx.argv.silent) console.log(`No API loaded`)
let projPath = path.resolve(ctx.argv.projectDir)
if (fs.existsSync(path.join(projPath, 'utils', 'orm.js'))) {
try {
// May have been changed after an schema uddate
clearModule(path.join(projPath, 'models.js'))
ctx.knex = require(path.join(projPath, 'utils', 'orm.js')).knex()
const c = ctx.knex.client.config
const cc = c.connection
if (!ctx.argv.silent)
console.log(
chalk`> Connection with {dim ${c.client}} to {dim ${
cc.database
? cc.database
: path.relative(process.cwd(), cc.filename)
}}`
)
if (c.connection.host && c.connection.user && !ctx.argv.silent)
console.log(chalk`> at {dim ${cc.host}} as {dim ${cc.user}} user`)
if (c.debug && !ctx.argv.silent)
console.log(' DB debug is: ' + c.debug ? c.debug : false)
if (fs.existsSync(path.join(projPath, 'models.js'))) {
ctx.model = require(path.join(projPath, 'models.js'))
if (!ctx.argv.silent)
console.log(
chalk`> {dim ${Object.keys(ctx.model).length}} models loaded\n`
)
}
} catch (e) {
console.error(
'%s\nPlease check your API files for typos and required deps' +
' - Did you forget to make "yarn install" ( or .install)?',
e
)
}
} else if (!ctx.argv.silent)
console.log('> No orm.js file found - Is the project generated?')
}
}