#!/usr/bin/env node var fs = require('fs') var path = require('path') var updateNotifier = require('update-notifier') var _db = require('underscore-db') var yargs = require('yargs') var chalk = require('chalk') var got = require('got') var pkg = require('../package.json') var jsonServer = require('../src') var jsMockGenerator = null updateNotifier({packageName: pkg.name, packageVersion: pkg.version}).notify() // Parse arguments var argv = yargs .usage('$0 [options] ') .options({ port: { alias: 'p', description: 'Set port', default: 3000 }, host: { alias: 'H', description: 'Set host', default: '0.0.0.0' }, watch: { alias: 'w', description: 'Reload database on JSON file change' }, routes: { alias: 'r', description: 'Load routes file' }, id: { description: 'Set database id property (e.g. _id)', default: 'id' } }) .boolean('watch') .help('help').alias('help', 'h') .version(pkg.version).alias('version', 'v') .example('$0 db.json', '') .example('$0 file.js', '') .example('$0 http://example.com/db.json', '') .epilog('https://github.com/typicode/json-server') .require(1, 'Missing argument') .argv function showResources (hostname, port, object) { for (var prop in object) { console.log(chalk.gray(' http://' + hostname + ':' + port + '/') + chalk.cyan(prop)) } } function start (object, filename) { var port = process.env.PORT || argv.port var hostname = argv.host === '0.0.0.0' ? 'localhost' : argv.host console.log() showResources(hostname, port, object) console.log() console.log( 'You can now go to ' + chalk.gray('http://' + hostname + ':' + port) ) console.log() console.log( 'Enter ' + chalk.cyan('s') + ' at any time to create a snapshot of the db' ) // Snapshot process.stdin.resume() process.stdin.setEncoding('utf8') process.stdin.on('data', function (chunk) { if (chunk.trim().toLowerCase() === 's') { var file = 'db-' + Date.now() + '.json' _db.save(object, file) console.log('Saved snapshot to ' + chalk.cyan(file) + '\n') } }) // Router var router = jsonServer.router(filename ? filename : object) // Watcher if (argv.watch) { console.log('Watching', chalk.cyan(source)) var db = router.db var watchedDir = path.dirname(filename) var watchedFile = path.basename(filename) fs.watch(watchedDir, function (event, changedFile) { // lowdb generates 'rename' event on watchedFile // using it to know if file has been modified by the user if ((event === 'change' || event === 'rename') && (changedFile === watchedFile || changedFile === source)) { console.log(chalk.cyan(source), 'has changed, reloading database') try { if (filename) { db.object = JSON.parse(fs.readFileSync(filename)) } else { require.cache[jsMockGenerator] = null db.object = require(jsMockGenerator)() } showResources(hostname, port, db.object) } catch (e) { console.log('Can\'t parse', chalk.cyan(source)) console.log(e.message) } console.log() } }) } console.log() var server = jsonServer.create() server.use(jsonServer.defaults) // Rewriter if (argv.routes) { var routes = JSON.parse(fs.readFileSync(process.cwd() + '/' + argv.routes)) var rewriter = jsonServer.rewriter(routes) server.use(rewriter) } server.use(router) // Custom id router.db._.id = argv.id server.listen(port, argv.host) } // Set file and port var source = argv._[0] // Say hi, load file and start server console.log(chalk.cyan(' {^_^} Hi!\n')) console.log('Loading database from ' + chalk.cyan(source)) // Remote source if (/^(http|https):/.test(source)) { got(source, function (err, data) { if (err) { console.log('Error', err) process.exit(1) } var object = JSON.parse(data) start(object) }) // JSON file } else if (/\.json$/.test(source)) { var filename = process.cwd() + '/' + source var object = require(filename) start(object, filename) // JS file } else if (/\.js$/.test(source)) { jsMockGenerator = process.cwd() + '/' + source var object = require(jsMockGenerator)() start(object) }