Files
json-server/bin/index.js
2015-06-30 14:26:55 +02:00

166 lines
4.3 KiB
JavaScript
Executable File

#!/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] <source>')
.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 <source> 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)
}