diff --git a/bin/index.js b/bin/index.js index 1c49755c0..b06e941f1 100755 --- a/bin/index.js +++ b/bin/index.js @@ -1,4 +1,6 @@ #!/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') @@ -11,7 +13,7 @@ updateNotifier({packageName: pkg.name, packageVersion: pkg.version}).notify() // Parse arguments var argv = yargs - .usage('$0 ') + .usage('$0 [options] ') .help('help').alias('help', 'h') .version(pkg.version, 'version').alias('version', 'v') .options({ @@ -24,29 +26,38 @@ var argv = yargs alias: 'H', description: 'Set host', default: '0.0.0.0' + }, + watch: { + alias: 'w', + description: 'Reload database on JSON file change' } }) + .boolean('w') .example('$0 db.json', '') .example('$0 file.js', '') .example('$0 http://example.com/db.json', '') .require(1, 'Missing argument') .argv -// Start server function -function start (object, filename) { - var port = process.env.PORT || argv.port - var hostname = argv.host === '0.0.0.0' ? 'localhost' : argv.host - +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( - '\nYou can now go to ' + chalk.gray('http://' + hostname + ':' + port + '/\n') + '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\n' + 'Enter ' + chalk.cyan('s') + ' at any time to create a snapshot of the db' ) process.stdin.resume() @@ -55,7 +66,7 @@ function start (object, filename) { if (chunk.trim().toLowerCase() === 's') { var file = 'db-' + Date.now() + '.json' _db.save(object, file) - console.log('\nSaved snapshot to ' + chalk.cyan(file) + '\n') + console.log('Saved snapshot to ' + chalk.cyan(file) + '\n') } }) @@ -66,6 +77,34 @@ function start (object, filename) { router = jsonServer.router(object) } + if (filename && 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' && changedFile === watchedFile) { + console.log(chalk.cyan(source), 'has changed, reloading database') + + try { + var watchedFileObject = JSON.parse(fs.readFileSync(filename)) + db.object = watchedFileObject + 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) server.use(router) @@ -76,24 +115,26 @@ function start (object, filename) { var source = argv._[0] // Say hi, load file and start server -console.log(chalk.cyan('{^_^} Hi!\n')) +console.log(chalk.cyan(' {^_^} Hi!\n')) console.log('Loading database from ' + chalk.cyan(source)) -if (/\.json$/.test(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) -} - -if (/\.js$/.test(source)) { +// JS file +} else if (/\.js$/.test(source)) { var object = require(process.cwd() + '/' + source)() start(object) } - -if (/^http/.test(source)) { - got(source, function (err, data) { - if (err) throw err - var object = JSON.parse(data) - start(object) - }) -} diff --git a/package.json b/package.json index 780275168..28dccd16d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "json-server", - "version": "0.7.6", + "version": "0.7.8", "description": "Serves JSON files through REST routes.", "main": "./src/index.js", "bin": "./bin/index.js", diff --git a/src/utils.js b/src/utils.js index 807eb426c..a954acfdf 100644 --- a/src/utils.js +++ b/src/utils.js @@ -9,7 +9,9 @@ _.mixin(_inflections) // '1' -> 1 function toNative (value) { if (typeof value === 'string') { - if (value === '' || value.trim() !== value) { + if (value === '' + || value.trim() !== value + || (value.length > 1 && value[0] === '0')) { return value } else if (value === 'true' || value === 'false') { return value === 'true' diff --git a/test/utils.js b/test/utils.js index 111dc93ab..0e7bfdd3b 100644 --- a/test/utils.js +++ b/test/utils.js @@ -36,11 +36,13 @@ describe('utils', function () { it('should convert string to native type', function () { // should convert assert.strictEqual(utils.toNative('1'), 1) + assert.strictEqual(utils.toNative('0'), 0) assert.strictEqual(utils.toNative('true'), true) // should not convert assert.strictEqual(utils.toNative(''), '') assert.strictEqual(utils.toNative('\t\n'), '\t\n') assert.strictEqual(utils.toNative('1 '), '1 ') + assert.strictEqual(utils.toNative('01'), '01') assert.strictEqual(utils.toNative(' 1'), ' 1') assert.strictEqual(utils.toNative('string'), 'string') assert.strictEqual(utils.toNative(1), 1)