mirror of
https://github.com/typicode/json-server.git
synced 2025-07-29 21:23:41 +08:00
Refactor CLI and add tests
This commit is contained in:
48
src/cli/index.js
Normal file
48
src/cli/index.js
Normal file
@ -0,0 +1,48 @@
|
||||
var updateNotifier = require('update-notifier')
|
||||
var yargs = require('yargs')
|
||||
var run = require('./run')
|
||||
var pkg = require('../../package.json')
|
||||
|
||||
module.exports = function () {
|
||||
|
||||
updateNotifier({ pkg: pkg }).notify()
|
||||
|
||||
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: 'Watch file(s)'
|
||||
},
|
||||
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
|
||||
|
||||
run(argv)
|
||||
|
||||
}
|
102
src/cli/run.js
Normal file
102
src/cli/run.js
Normal file
@ -0,0 +1,102 @@
|
||||
var fs = require('fs')
|
||||
var chalk = require('chalk')
|
||||
var is = require('./utils/is')
|
||||
var load = require('./utils/load')
|
||||
var watch = require('./watch')
|
||||
var jsonServer = require('../server')
|
||||
|
||||
function prettyPrint (argv, object, rules) {
|
||||
var host = argv.host === '0.0.0.0' ? 'localhost' : argv.host
|
||||
var port = argv.port
|
||||
var root = 'http://' + host + ':' + port
|
||||
|
||||
console.log()
|
||||
console.log(chalk.bold(' Resources'))
|
||||
for (var prop in object) {
|
||||
console.log(' ' + root + '/' + prop)
|
||||
}
|
||||
|
||||
if (rules) {
|
||||
console.log()
|
||||
console.log(chalk.bold(' Other routes'))
|
||||
for (var rule in rules) {
|
||||
console.log(' ' + rule + ' -> ' + rules[rule])
|
||||
}
|
||||
}
|
||||
|
||||
console.log()
|
||||
console.log(chalk.bold(' Home'))
|
||||
console.log(' ' + root)
|
||||
console.log()
|
||||
}
|
||||
|
||||
function createServer (source, object, routes) {
|
||||
var server = jsonServer.create()
|
||||
|
||||
var router = jsonServer.router(
|
||||
is.JSON(source) ?
|
||||
source :
|
||||
object
|
||||
)
|
||||
|
||||
server.use(jsonServer.defaults)
|
||||
|
||||
if (routes) {
|
||||
var rewriter = jsonServer.rewriter(routes)
|
||||
server.use(rewriter)
|
||||
}
|
||||
|
||||
server.use(router)
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
module.exports = function (argv) {
|
||||
|
||||
var source = argv._[0]
|
||||
var server
|
||||
|
||||
console.log()
|
||||
console.log(chalk.cyan(' \\{^_^}/ hi!'))
|
||||
|
||||
function start () {
|
||||
console.log()
|
||||
console.log(chalk.gray(' Loading', source))
|
||||
|
||||
// Load JSON, JS or HTTP database
|
||||
load(source, function (err, data) {
|
||||
|
||||
if (err) throw err
|
||||
|
||||
// Load additional routes
|
||||
if (argv.routes) {
|
||||
console.log(chalk.gray(' Loading', argv.routes))
|
||||
var routes = JSON.parse(fs.readFileSync(argv.routes))
|
||||
}
|
||||
|
||||
console.log(chalk.gray(' Done'))
|
||||
|
||||
// Create server and listen
|
||||
server = createServer(source, data, routes).listen(argv.port, argv.host)
|
||||
|
||||
// Display server informations
|
||||
prettyPrint(argv, data, routes)
|
||||
})
|
||||
}
|
||||
|
||||
// Start server
|
||||
start()
|
||||
|
||||
// Watch files
|
||||
if (argv.watch) {
|
||||
console.log(chalk.gray(' Watching...'))
|
||||
console.log()
|
||||
watch(argv, function (file) {
|
||||
console.log(chalk.gray(' ' + file + ' has changed, reloading...'))
|
||||
// Restart server
|
||||
server && server.close()
|
||||
start()
|
||||
})
|
||||
}
|
||||
|
||||
}
|
17
src/cli/utils/is.js
Normal file
17
src/cli/utils/is.js
Normal file
@ -0,0 +1,17 @@
|
||||
module.exports = {
|
||||
JSON: isJSON,
|
||||
JS: isJS,
|
||||
URL: isURL
|
||||
}
|
||||
|
||||
function isJSON (s) {
|
||||
return /\.json$/.test(s)
|
||||
}
|
||||
|
||||
function isJS (s) {
|
||||
return /\.js$/.test(s)
|
||||
}
|
||||
|
||||
function isURL (s) {
|
||||
return /^(http|https):/.test(s)
|
||||
}
|
18
src/cli/utils/load.js
Normal file
18
src/cli/utils/load.js
Normal file
@ -0,0 +1,18 @@
|
||||
var path = require('path')
|
||||
var got = require('got')
|
||||
var is = require('./is')
|
||||
|
||||
module.exports = function (source, cb) {
|
||||
if (is.URL(source)) {
|
||||
// Load URL
|
||||
got(source, { json: true }, function (err, data) {
|
||||
cb(err, data)
|
||||
})
|
||||
} else {
|
||||
// Load JS or JSON
|
||||
var filename = path.resolve(source)
|
||||
delete require.cache[filename]
|
||||
var data = is.JSON(source) ? require(filename) : require(filename)()
|
||||
cb(null, data)
|
||||
}
|
||||
}
|
44
src/cli/watch.js
Normal file
44
src/cli/watch.js
Normal file
@ -0,0 +1,44 @@
|
||||
var fs = require('fs')
|
||||
var path = require('path')
|
||||
var is = require('./utils/is')
|
||||
|
||||
module.exports = watch
|
||||
|
||||
// Because JSON file can be modified by the server, we need to be able to
|
||||
// distinguish between user modification vs server modification.
|
||||
// When the server modifies the JSON file, it generates a rename event.
|
||||
// When the user modifies the JSON file, it generate a change event.
|
||||
function watchDB (file, cb) {
|
||||
var watchedDir = path.dirname(file)
|
||||
var watchedFile = path.basename(file)
|
||||
|
||||
fs.watch(watchedDir, function (event, changedFile) {
|
||||
if (event === 'change' && changedFile === watchedFile) cb()
|
||||
})
|
||||
}
|
||||
|
||||
function watchJS (file, cb) {
|
||||
fs.watchFile(file, cb)
|
||||
}
|
||||
|
||||
function watchSource (source, cb) {
|
||||
if (is.JSON(source)) {
|
||||
return watchDB(source, cb)
|
||||
}
|
||||
if (is.JS(source)) return watchJS(source, cb)
|
||||
if (is.URL(source)) throw new Error('Can\'t watch URL')
|
||||
}
|
||||
|
||||
function watch (argv, cb) {
|
||||
var source = argv._[0]
|
||||
|
||||
watchSource(source, function () {
|
||||
cb(source)
|
||||
})
|
||||
|
||||
if (argv.routes) {
|
||||
fs.watchFile(argv.routes, function () {
|
||||
cb(argv.routes)
|
||||
})
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user