mirror of
https://github.com/typicode/json-server.git
synced 2025-07-28 12:43:18 +08:00
Refactor and update to LowDB 0.4
This commit is contained in:
34
README.md
34
README.md
@ -33,13 +33,11 @@ $ curl -i http://localhost:3000/posts/1
|
||||
```javascript
|
||||
var server = require('json-server');
|
||||
|
||||
server.low.db = {
|
||||
server({
|
||||
posts: [
|
||||
{ id: 1, body: 'foo' }
|
||||
]
|
||||
}
|
||||
|
||||
server.listen(3000);
|
||||
}).listen(3000);
|
||||
```
|
||||
|
||||
You can find a running demo here: http://jsonplaceholder.typicode.com.
|
||||
@ -62,20 +60,18 @@ $ npm install -g json-server
|
||||
## CLI usage
|
||||
|
||||
```bash
|
||||
json-server <source>
|
||||
|
||||
Usage: json-server <source> [options]
|
||||
Examples:
|
||||
json-server db.json
|
||||
json-server file.js
|
||||
json-server http://example.com/db.json
|
||||
|
||||
Options:
|
||||
|
||||
--version output version
|
||||
--port <port> set port
|
||||
|
||||
Exemples:
|
||||
|
||||
json-server db.json
|
||||
json-server seed.js
|
||||
json-server http://example.com/db.json
|
||||
|
||||
Options:
|
||||
--help, -h Show help
|
||||
--version, -v Show version number
|
||||
--port, -p Set port [default: 3000]
|
||||
```
|
||||
|
||||
#### Input
|
||||
@ -97,10 +93,10 @@ Here's 2 examples showing how to format JSON or JS seed file:
|
||||
}
|
||||
```
|
||||
|
||||
* __seed.js__
|
||||
* __file.js__
|
||||
|
||||
```javascript
|
||||
exports.run = function() {
|
||||
module.exports = function() {
|
||||
var data = {};
|
||||
|
||||
data.posts = [];
|
||||
@ -111,7 +107,7 @@ exports.run = function() {
|
||||
}
|
||||
```
|
||||
|
||||
JSON Server expects JS files to export a ```run``` method that returns an object.
|
||||
JSON Server expects JS files to export a function that returns an object.
|
||||
|
||||
Seed files are useful if you need to programmaticaly create a lot of data.
|
||||
|
||||
@ -159,4 +155,4 @@ Returns default index file or content of ./public/index.html (useful if you need
|
||||
## Links
|
||||
|
||||
* [Fast prototyping using Restangular and Json-server](http://bahmutov.calepin.co/fast-prototyping-using-restangular-and-json-server.html)
|
||||
* [Grunt plugin](https://github.com/tfiwm/grunt-json-server)
|
||||
* [grunt plugin](https://github.com/tfiwm/grunt-json-server)
|
82
bin/index.js
82
bin/index.js
@ -1,20 +1,74 @@
|
||||
#!/usr/bin/env node
|
||||
var minimist = require('minimist')
|
||||
var updateNotifier = require('update-notifier')
|
||||
var cli = require('../src/cli')
|
||||
var _db = require('underscore-db')
|
||||
var yargs = require('yargs')
|
||||
var chalk = require('chalk')
|
||||
var got = require('got')
|
||||
var pkg = require('../package.json')
|
||||
var server = require('../src')
|
||||
|
||||
var notifier = updateNotifier({packagePath: '../package'})
|
||||
if (notifier.update) notifier.notify()
|
||||
updateNotifier({packageName: pkg.name, packageVersion: pkg.version}).notify()
|
||||
|
||||
var argv = minimist(process.argv.slice(2), {
|
||||
boolean: ["silent"],
|
||||
alias: {
|
||||
'p': 'port',
|
||||
's': 'silent'
|
||||
},
|
||||
default: {
|
||||
silent: false
|
||||
var argv = yargs
|
||||
.usage('$0 <source>')
|
||||
.help('help').alias('help', 'h')
|
||||
.version(pkg.version, 'version').alias('version', 'v')
|
||||
.options({
|
||||
port: {
|
||||
alias: 'p',
|
||||
description: 'Set port',
|
||||
default: 3000
|
||||
}
|
||||
})
|
||||
})
|
||||
.example('$0 db.json', '')
|
||||
.example('$0 file.js', '')
|
||||
.example('$0 http://example.com/db.json', '')
|
||||
.require(1, 'Missing <source> argument')
|
||||
.argv
|
||||
|
||||
cli.run(argv)
|
||||
function start(object, filename) {
|
||||
for (var prop in object) {
|
||||
console.log('http://localhost:' + port + '/' + chalk.green(prop))
|
||||
}
|
||||
|
||||
console.log(
|
||||
'\nEnter ' + chalk.green('`s`') + ' at any time to create a snapshot of the db\n'
|
||||
)
|
||||
|
||||
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, filename)
|
||||
console.log('\nSaved snapshot to ' + chalk.green(file) + '\n')
|
||||
}
|
||||
})
|
||||
|
||||
server(object, filename).listen(port)
|
||||
}
|
||||
|
||||
var source = argv._[0]
|
||||
var port = process.env.PORT || argv.port
|
||||
|
||||
console.log(chalk.green('\n{^ ^} Yo!\n'))
|
||||
console.log('Loading database from ' + source + '\n')
|
||||
|
||||
if (/\.json$/.test(source)) {
|
||||
var filename = process.cwd() + '/' + source
|
||||
var object = require(filename)
|
||||
start(object, filename)
|
||||
}
|
||||
|
||||
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)
|
||||
})
|
||||
}
|
15
package.json
15
package.json
@ -12,17 +12,18 @@
|
||||
"chalk": "^0.4.0",
|
||||
"cors": "^2.3.0",
|
||||
"errorhandler": "^1.2.0",
|
||||
"express": "^4.9.0",
|
||||
"lowdb": "^0.3.0",
|
||||
"express": "^4.9.5",
|
||||
"got": "^1.2.2",
|
||||
"lowdb": "^0.4.2",
|
||||
"method-override": "^2.1.2",
|
||||
"minimist": "0.0.8",
|
||||
"morgan": "^1.3.1",
|
||||
"serve-static": "^1.6.1",
|
||||
"superagent": "~0.15.7",
|
||||
"underscore": "~1.5.2",
|
||||
"superagent": "^0.15.7",
|
||||
"underscore": "^1.5.2",
|
||||
"underscore-db": "^0.8.0",
|
||||
"underscore.inflections": "~0.2.1",
|
||||
"update-notifier": "^0.1.8",
|
||||
"yargs": "^1.2.1"
|
||||
"update-notifier": "^0.2.2",
|
||||
"yargs": "^1.3.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"supertest": "~0.8.1",
|
||||
|
90
src/cli.js
90
src/cli.js
@ -1,90 +0,0 @@
|
||||
var fs = require('fs')
|
||||
var chalk = require('chalk')
|
||||
var minimist = require('minimist')
|
||||
var request = require('superagent')
|
||||
var low = require('lowdb')
|
||||
var server = require('./server')
|
||||
|
||||
// Output version
|
||||
function version() {
|
||||
var pkg = require('../package.json')
|
||||
console.log(pkg.version)
|
||||
}
|
||||
|
||||
// Output help.txt with some colors
|
||||
function help() {
|
||||
var txt = fs.readFileSync(__dirname + '/help.txt').toString()
|
||||
txt = txt.replace(/json-server/g, chalk.green('json-server'))
|
||||
console.log(txt)
|
||||
}
|
||||
|
||||
// Start server
|
||||
function start(port, silent) {
|
||||
for (var prop in low.db) {
|
||||
console.log('http://localhost:' + port + '/' + chalk.green(prop))
|
||||
}
|
||||
|
||||
if(!silent) {
|
||||
console.log(
|
||||
'\nEnter ' + chalk.green('`s`') + ' at any time to create a snapshot of the db\n'
|
||||
)
|
||||
process.stdin.resume()
|
||||
process.stdin.setEncoding('utf8')
|
||||
process.stdin.on('data', function (chunk) {
|
||||
if (chunk.trim().toLowerCase() === 's') {
|
||||
var file = 'db-' + Date.now() + '.json'
|
||||
low.save(file)
|
||||
console.log('\nSaved snapshot to ' + chalk.green(file) + '\n')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
server.listen(port)
|
||||
}
|
||||
|
||||
// Load source
|
||||
function load(source, port, silent) {
|
||||
console.log(chalk.green('\n{^ ^} Heya!\n'))
|
||||
|
||||
console.log('Loading database from ' + source + '\n')
|
||||
|
||||
if (/\.json$/.test(source)) {
|
||||
var path = process.cwd() + '/' + source
|
||||
low.path = path
|
||||
low.db = require(path);
|
||||
start(port, silent)
|
||||
}
|
||||
|
||||
if (/\.js$/.test(source)) {
|
||||
var path = process.cwd() + '/' + source
|
||||
low.db = require(path).run();
|
||||
start(port, silent)
|
||||
}
|
||||
|
||||
if (/^http/.test(source)) {
|
||||
request
|
||||
.get(source)
|
||||
.end(function(err, res) {
|
||||
if (err) {
|
||||
console.error(err)
|
||||
} else {
|
||||
low.db = JSON.parse(res.text)
|
||||
start(port, silent)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Uses minimist parsed argv
|
||||
function run(argv) {
|
||||
var source = argv._[0]
|
||||
var port = argv.port || 3000
|
||||
var silent = argv.silent
|
||||
|
||||
if (argv.version) return version()
|
||||
if (source) return load(source, port, silent)
|
||||
|
||||
help()
|
||||
}
|
||||
|
||||
module.exports.run = run
|
169
src/create-routes.js
Normal file
169
src/create-routes.js
Normal file
@ -0,0 +1,169 @@
|
||||
var _ = require('underscore')
|
||||
var low = require('lowdb')
|
||||
var _db = require('underscore-db')
|
||||
var _inflections = require('underscore.inflections')
|
||||
var utils = require('./utils')
|
||||
|
||||
low.mixin(_db)
|
||||
low.mixin(_inflections)
|
||||
|
||||
module.exports = function(object, filename) {
|
||||
if (filename) {
|
||||
var db = low(filename)
|
||||
} else {
|
||||
var db = low()
|
||||
_.extend(db.object, object)
|
||||
}
|
||||
|
||||
return {
|
||||
// GET /db
|
||||
showDatabase: function(req, res, next) {
|
||||
res.jsonp(db.object)
|
||||
},
|
||||
|
||||
// GET /:resource
|
||||
// GET /:resource?q=
|
||||
// GET /:resource?attr=&attr=
|
||||
// GET /:parent/:parentId/:resource?attr=&attr=
|
||||
// GET /*?*&_end=
|
||||
// GET /*?*&_start=&_end=
|
||||
list: function(req, res, next) {
|
||||
// Filters list
|
||||
var filters = {}
|
||||
|
||||
// Result array
|
||||
var array
|
||||
|
||||
// Remove _start and _end from req.query to avoid filtering using those
|
||||
// parameters
|
||||
var _start = req.query._start
|
||||
var _end = req.query._end
|
||||
var _sort = req.query._sort
|
||||
var _sortDir = req.query._sortDir
|
||||
|
||||
delete req.query._start
|
||||
delete req.query._end
|
||||
delete req.query._sort
|
||||
delete req.query._sortDir
|
||||
|
||||
if (req.query.q) {
|
||||
|
||||
// Full-text search
|
||||
var q = req.query.q.toLowerCase()
|
||||
|
||||
array = db(req.params.resource).where(function(obj) {
|
||||
for (var key in obj) {
|
||||
var value = obj[key]
|
||||
if (_.isString(value) && value.toLowerCase().indexOf(q) !== -1) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}).value()
|
||||
|
||||
} else {
|
||||
|
||||
// Add :parentId filter in case URL is like /:parent/:parentId/:resource
|
||||
if (req.params.parent) {
|
||||
filters[req.params.parent.slice(0, - 1) + 'Id'] = +req.params.parentId
|
||||
}
|
||||
|
||||
// Add query parameters filters
|
||||
// Convert query parameters to their native counterparts
|
||||
for (var key in req.query) {
|
||||
if (key !== 'callback') {
|
||||
filters[key] = utils.toNative(req.query[key])
|
||||
}
|
||||
}
|
||||
|
||||
// Filter
|
||||
if (_(filters).isEmpty()) {
|
||||
array = db(req.params.resource).value()
|
||||
} else {
|
||||
array = db(req.params.resource).where(filters).value()
|
||||
}
|
||||
}
|
||||
|
||||
if(_sort) {
|
||||
_sortDir = _sortDir || 'ASC'
|
||||
|
||||
array = _.sortBy(array, function(element) {
|
||||
return element[_sort];
|
||||
})
|
||||
|
||||
if (_sortDir === 'DESC') {
|
||||
array.reverse();
|
||||
}
|
||||
}
|
||||
|
||||
// Slice result
|
||||
if (_end) {
|
||||
res.setHeader('X-Total-Count', array.length)
|
||||
res.setHeader('Access-Control-Expose-Headers', 'X-Total-Count')
|
||||
|
||||
_start = _start || 0
|
||||
|
||||
array = array.slice(_start, _end)
|
||||
}
|
||||
|
||||
res.jsonp(array)
|
||||
},
|
||||
|
||||
// GET /:resource/:id
|
||||
show: function(req, res, next) {
|
||||
var resource = db(req.params.resource)
|
||||
.get(+req.params.id)
|
||||
.value()
|
||||
|
||||
if (resource) {
|
||||
res.jsonp(resource)
|
||||
} else {
|
||||
res.status(404).jsonp({})
|
||||
}
|
||||
},
|
||||
|
||||
// POST /:resource
|
||||
create: function(req, res, next) {
|
||||
for (var key in req.body) {
|
||||
req.body[key] = utils.toNative(req.body[key])
|
||||
}
|
||||
|
||||
var resource = db(req.params.resource)
|
||||
.insert(req.body)
|
||||
.value()
|
||||
|
||||
res.jsonp(resource)
|
||||
},
|
||||
|
||||
// PUT /:resource/:id
|
||||
// PATCH /:resource/:id
|
||||
update: function(req, res, next) {
|
||||
for (var key in req.body) {
|
||||
req.body[key] = utils.toNative(req.body[key])
|
||||
}
|
||||
|
||||
var resource = db(req.params.resource)
|
||||
.update(+req.params.id, req.body)
|
||||
.value()
|
||||
|
||||
if (resource) {
|
||||
res.jsonp(resource)
|
||||
} else {
|
||||
res.status(404).jsonp({})
|
||||
}
|
||||
},
|
||||
|
||||
// DELETE /:resource/:id
|
||||
destroy: function(req, res, next) {
|
||||
db(req.params.resource).remove(+req.params.id)
|
||||
|
||||
// Remove dependents documents
|
||||
var removable = utils.getRemovable(db.object)
|
||||
|
||||
_(removable).each(function(item) {
|
||||
db(item.name).remove(item.id)
|
||||
})
|
||||
|
||||
res.status(204).end()
|
||||
}
|
||||
}
|
||||
}
|
14
src/help.txt
14
src/help.txt
@ -1,14 +0,0 @@
|
||||
|
||||
Usage: json-server <source> [options]
|
||||
|
||||
Options:
|
||||
|
||||
--version output version
|
||||
--port <port> set port
|
||||
|
||||
Exemples:
|
||||
|
||||
json-server db.json
|
||||
json-server seed.js
|
||||
json-server http://example.com/db.json
|
||||
|
69
src/index.js
Normal file
69
src/index.js
Normal file
@ -0,0 +1,69 @@
|
||||
var fs = require('fs')
|
||||
var path = require('path')
|
||||
|
||||
// LowDB
|
||||
var low = require('lowdb')
|
||||
var _db = require('underscore-db')
|
||||
var _inflections = require('underscore.inflections')
|
||||
|
||||
low.mixin('_db')
|
||||
low.mixin('_inflections')
|
||||
|
||||
// Express
|
||||
var http = require('http')
|
||||
var express = require('express')
|
||||
var logger = require('morgan')
|
||||
var cors = require('cors')
|
||||
var methodOverride = require('method-override')
|
||||
var bodyParser = require('body-parser')
|
||||
var serveStatic = require('serve-static')
|
||||
var errorhandler = require('errorhandler')
|
||||
|
||||
// json-server
|
||||
var utils = require('./utils')
|
||||
var createRoutes = require('./create-routes')
|
||||
|
||||
low.mixin({ createId: utils.createId })
|
||||
|
||||
module.exports = function(object, filename) {
|
||||
var server = express()
|
||||
var routes = createRoutes(object, filename)
|
||||
|
||||
// Don't use logger if json-server is mounted
|
||||
if (!module.parent) {
|
||||
server.use(logger('dev'))
|
||||
}
|
||||
|
||||
server.use(bodyParser.json())
|
||||
server.use(bodyParser.urlencoded({ extended: false }))
|
||||
server.use(methodOverride())
|
||||
|
||||
if (fs.existsSync(process.cwd() + '/public')) {
|
||||
server.use(serveStatic(process.cwd() + '/public'));
|
||||
} else {
|
||||
server.use(serveStatic(path.join(__dirname, './public')));
|
||||
}
|
||||
|
||||
server.use(cors({ origin: true, credentials: true }))
|
||||
|
||||
server.get('/db', routes.showDatabase)
|
||||
|
||||
server.route('/:resource')
|
||||
.get(routes.list)
|
||||
.post(routes.create)
|
||||
|
||||
server.route('/:resource/:id')
|
||||
.get(routes.show)
|
||||
.put(routes.update)
|
||||
.patch(routes.update)
|
||||
.delete(routes.destroy)
|
||||
|
||||
server.get('/:parent/:parentId/:resource', routes.list)
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// only use in development
|
||||
server.use(errorhandler())
|
||||
}
|
||||
|
||||
return server
|
||||
}
|
158
src/routes.js
158
src/routes.js
@ -1,158 +0,0 @@
|
||||
var _ = require('underscore')
|
||||
var low = require('lowdb')
|
||||
var utils = require('./utils')
|
||||
|
||||
var routes = {}
|
||||
|
||||
// GET /db
|
||||
routes.db = function(req, res, next) {
|
||||
res.jsonp(low.db)
|
||||
}
|
||||
|
||||
// GET /:resource
|
||||
// GET /:resource?q=
|
||||
// GET /:resource?attr=&attr=
|
||||
// GET /:parent/:parentId/:resource?attr=&attr=
|
||||
// GET /*?*&_end=
|
||||
// GET /*?*&_start=&_end=
|
||||
routes.list = function(req, res, next) {
|
||||
|
||||
// Filters list
|
||||
var filters = {}
|
||||
|
||||
// Result array
|
||||
var array
|
||||
|
||||
// Remove _start and _end from req.query to avoid filtering using those
|
||||
// parameters
|
||||
var _start = req.query._start
|
||||
var _end = req.query._end
|
||||
var _sort = req.query._sort
|
||||
var _sortDir = req.query._sortDir
|
||||
|
||||
delete req.query._start
|
||||
delete req.query._end
|
||||
delete req.query._sort
|
||||
delete req.query._sortDir
|
||||
|
||||
if (req.query.q) {
|
||||
|
||||
// Full-text search
|
||||
var q = req.query.q.toLowerCase()
|
||||
|
||||
array = low(req.params.resource).where(function(obj) {
|
||||
for (var key in obj) {
|
||||
var value = obj[key]
|
||||
if (_.isString(value) && value.toLowerCase().indexOf(q) !== -1) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}).value()
|
||||
|
||||
} else {
|
||||
|
||||
// Add :parentId filter in case URL is like /:parent/:parentId/:resource
|
||||
if (req.params.parent) {
|
||||
filters[req.params.parent.slice(0, - 1) + 'Id'] = +req.params.parentId
|
||||
}
|
||||
|
||||
// Add query parameters filters
|
||||
// Convert query parameters to their native counterparts
|
||||
for (var key in req.query) {
|
||||
if (key !== 'callback') {
|
||||
filters[key] = utils.toNative(req.query[key])
|
||||
}
|
||||
}
|
||||
|
||||
// Filter
|
||||
if (_(filters).isEmpty()) {
|
||||
array = low(req.params.resource).value()
|
||||
} else {
|
||||
array = low(req.params.resource).where(filters).value()
|
||||
}
|
||||
}
|
||||
|
||||
if(_sort) {
|
||||
_sortDir = _sortDir || 'ASC'
|
||||
|
||||
array = _.sortBy(array, function(element) {
|
||||
return element[_sort];
|
||||
})
|
||||
|
||||
if (_sortDir === 'DESC') {
|
||||
array.reverse();
|
||||
}
|
||||
}
|
||||
|
||||
// Slice result
|
||||
if (_end) {
|
||||
res.setHeader('X-Total-Count', array.length)
|
||||
res.setHeader('Access-Control-Expose-Headers', 'X-Total-Count')
|
||||
|
||||
_start = _start || 0
|
||||
|
||||
array = array.slice(_start, _end)
|
||||
}
|
||||
|
||||
res.jsonp(array)
|
||||
}
|
||||
|
||||
// GET /:resource/:id
|
||||
routes.show = function(req, res, next) {
|
||||
var resource = low(req.params.resource)
|
||||
.get(+req.params.id)
|
||||
.value()
|
||||
|
||||
if (resource) {
|
||||
res.jsonp(resource)
|
||||
} else {
|
||||
res.status(404).jsonp({})
|
||||
}
|
||||
}
|
||||
|
||||
// POST /:resource
|
||||
routes.create = function(req, res, next) {
|
||||
for (var key in req.body) {
|
||||
req.body[key] = utils.toNative(req.body[key])
|
||||
}
|
||||
|
||||
var resource = low(req.params.resource)
|
||||
.insert(req.body)
|
||||
.value()
|
||||
|
||||
res.jsonp(resource)
|
||||
}
|
||||
|
||||
// PUT /:resource/:id
|
||||
// PATCH /:resource/:id
|
||||
routes.update = function(req, res, next) {
|
||||
for (var key in req.body) {
|
||||
req.body[key] = utils.toNative(req.body[key])
|
||||
}
|
||||
|
||||
var resource = low(req.params.resource)
|
||||
.update(+req.params.id, req.body)
|
||||
.value()
|
||||
|
||||
if (resource) {
|
||||
res.jsonp(resource)
|
||||
} else {
|
||||
res.status(404).jsonp({})
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /:resource/:id
|
||||
routes.destroy = function(req, res, next) {
|
||||
low(req.params.resource).remove(+req.params.id)
|
||||
|
||||
// Remove dependents documents
|
||||
var removable = utils.getRemovable(low.db)
|
||||
|
||||
_(removable).each(function(item) {
|
||||
low(item[0]).remove(item[1]);
|
||||
})
|
||||
|
||||
res.status(204).end()
|
||||
}
|
||||
|
||||
module.exports = routes
|
@ -1,60 +0,0 @@
|
||||
var fs = require('fs')
|
||||
var path = require('path')
|
||||
var http = require('http')
|
||||
var express = require('express')
|
||||
var logger = require('morgan')
|
||||
var cors = require('cors')
|
||||
var methodOverride = require('method-override')
|
||||
var bodyParser = require('body-parser')
|
||||
var serveStatic = require('serve-static')
|
||||
var errorhandler = require('errorhandler')
|
||||
var low = require('lowdb')
|
||||
|
||||
var utils = require('./utils')
|
||||
var routes = require('./routes')
|
||||
|
||||
low._.createId = utils.createId
|
||||
|
||||
var server = express()
|
||||
|
||||
server.set('port', process.env.PORT || 3000)
|
||||
|
||||
// Don't use logger if json-server is mounted
|
||||
if (!module.parent) {
|
||||
server.use(logger('dev'))
|
||||
}
|
||||
|
||||
server.use(bodyParser.json())
|
||||
server.use(bodyParser.urlencoded({ extended: false }))
|
||||
server.use(methodOverride())
|
||||
|
||||
if (fs.existsSync(process.cwd() + '/public')) {
|
||||
server.use(serveStatic(process.cwd() + '/public'));
|
||||
} else {
|
||||
server.use(serveStatic(path.join(__dirname, './public')));
|
||||
}
|
||||
|
||||
server.use(cors({ origin: true, credentials: true }))
|
||||
|
||||
server.get('/db', routes.db)
|
||||
|
||||
server.route('/:resource')
|
||||
.get(routes.list)
|
||||
.post(routes.create)
|
||||
|
||||
server.route('/:resource/:id')
|
||||
.get(routes.show)
|
||||
.put(routes.update)
|
||||
.patch(routes.update)
|
||||
.delete(routes.destroy)
|
||||
|
||||
server.get('/:parent/:parentId/:resource', routes.list)
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// only use in development
|
||||
server.use(errorhandler())
|
||||
}
|
||||
|
||||
server.low = low
|
||||
|
||||
module.exports = server
|
@ -1,7 +1,6 @@
|
||||
var low = require('lowdb')
|
||||
var _ = require('underscore')
|
||||
_.mixin(require('underscore.inflections'))
|
||||
|
||||
var _inflections = require('underscore.inflections')
|
||||
_.mixin(_inflections)
|
||||
|
||||
// Turns string to native.
|
||||
// Example:
|
||||
@ -42,7 +41,7 @@ function getRemovable(db) {
|
||||
var refName = _.pluralize(key.slice(0, - 2))
|
||||
var ref = _.findWhere(db[refName], {id: value})
|
||||
if (_.isUndefined(ref)) {
|
||||
removable.push([collName, doc.id])
|
||||
removable.push({ name: collName, id: doc.id })
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -1,31 +1,35 @@
|
||||
var request = require('supertest')
|
||||
var assert = require('assert')
|
||||
var low = require('lowdb')
|
||||
var server = require('../src/server')
|
||||
var jsonServer = require('../src/')
|
||||
|
||||
describe('Server', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
low.db = {}
|
||||
var server
|
||||
var db
|
||||
|
||||
low.db.posts = [
|
||||
beforeEach(function() {
|
||||
db = {}
|
||||
|
||||
db.posts = [
|
||||
{id: 1, body: 'foo'},
|
||||
{id: 2, body: 'bar'}
|
||||
]
|
||||
|
||||
low.db.tags = [
|
||||
db.tags = [
|
||||
{id: 1, body: 'Technology'},
|
||||
{id: 2, body: 'Photography'},
|
||||
{id: 3, body: 'photo'}
|
||||
]
|
||||
|
||||
low.db.comments = [
|
||||
db.comments = [
|
||||
{id: 1, published: true, postId: 1},
|
||||
{id: 2, published: false, postId: 1},
|
||||
{id: 3, published: false, postId: 2},
|
||||
{id: 4, published: false, postId: 2},
|
||||
{id: 5, published: false, postId: 2},
|
||||
]
|
||||
|
||||
server = jsonServer(db)
|
||||
})
|
||||
|
||||
describe('GET /db', function() {
|
||||
@ -33,7 +37,7 @@ describe('Server', function() {
|
||||
request(server)
|
||||
.get('/db')
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(low.db)
|
||||
.expect(db)
|
||||
.expect(200, done)
|
||||
})
|
||||
})
|
||||
@ -46,7 +50,7 @@ describe('Server', function() {
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('Access-Control-Allow-Credentials', 'true')
|
||||
.expect('Access-Control-Allow-Origin', 'http://example.com')
|
||||
.expect(low.db.posts)
|
||||
.expect(db.posts)
|
||||
.expect(200, done)
|
||||
})
|
||||
})
|
||||
@ -56,7 +60,7 @@ describe('Server', function() {
|
||||
request(server)
|
||||
.get('/comments?postId=1&published=true')
|
||||
.expect('Content-Type', /json/)
|
||||
.expect([low.db.comments[0]])
|
||||
.expect([db.comments[0]])
|
||||
.expect(200, done)
|
||||
})
|
||||
})
|
||||
@ -66,7 +70,7 @@ describe('Server', function() {
|
||||
request(server)
|
||||
.get('/tags?q=pho')
|
||||
.expect('Content-Type', /json/)
|
||||
.expect([low.db.tags[1], low.db.tags[2]])
|
||||
.expect([db.tags[1], db.tags[2]])
|
||||
.expect(200, done)
|
||||
})
|
||||
|
||||
@ -84,9 +88,9 @@ describe('Server', function() {
|
||||
request(server)
|
||||
.get('/comments?_end=2')
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('x-total-count', low.db.comments.length.toString())
|
||||
.expect('x-total-count', db.comments.length.toString())
|
||||
.expect('Access-Control-Expose-Headers', 'X-Total-Count')
|
||||
.expect(low.db.comments.slice(0, 2))
|
||||
.expect(db.comments.slice(0, 2))
|
||||
.expect(200, done)
|
||||
})
|
||||
})
|
||||
@ -96,7 +100,7 @@ describe('Server', function() {
|
||||
request(server)
|
||||
.get('/tags?_sort=body')
|
||||
.expect('Content-Type', /json/)
|
||||
.expect([low.db.tags[1], low.db.tags[0], low.db.tags[2]])
|
||||
.expect([db.tags[1], db.tags[0], db.tags[2]])
|
||||
.expect(200, done)
|
||||
})
|
||||
|
||||
@ -104,7 +108,7 @@ describe('Server', function() {
|
||||
request(server)
|
||||
.get('/tags?_sort=body&_sortDir=DESC')
|
||||
.expect('Content-Type', /json/)
|
||||
.expect([low.db.tags[2], low.db.tags[0], low.db.tags[1]])
|
||||
.expect([db.tags[2], db.tags[0], db.tags[1]])
|
||||
.expect(200, done)
|
||||
})
|
||||
|
||||
@ -112,7 +116,7 @@ describe('Server', function() {
|
||||
request(server)
|
||||
.get('/posts?_sort=id&_sortDir=DESC')
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(low.db.posts.reverse())
|
||||
.expect(db.posts.reverse())
|
||||
.expect(200, done)
|
||||
})
|
||||
})
|
||||
@ -122,9 +126,9 @@ describe('Server', function() {
|
||||
request(server)
|
||||
.get('/comments?_start=1&_end=2')
|
||||
.expect('Content-Type', /json/)
|
||||
.expect('x-total-count', low.db.comments.length.toString())
|
||||
.expect('x-total-count', db.comments.length.toString())
|
||||
.expect('Access-Control-Expose-Headers', 'X-Total-Count')
|
||||
.expect(low.db.comments.slice(1, 2))
|
||||
.expect(db.comments.slice(1, 2))
|
||||
.expect(200, done)
|
||||
})
|
||||
})
|
||||
@ -135,8 +139,8 @@ describe('Server', function() {
|
||||
.get('/posts/1/comments')
|
||||
.expect('Content-Type', /json/)
|
||||
.expect([
|
||||
low.db.comments[0],
|
||||
low.db.comments[1]
|
||||
db.comments[0],
|
||||
db.comments[1]
|
||||
])
|
||||
.expect(200, done)
|
||||
})
|
||||
@ -147,7 +151,7 @@ describe('Server', function() {
|
||||
request(server)
|
||||
.get('/posts/1')
|
||||
.expect('Content-Type', /json/)
|
||||
.expect(low.db.posts[0])
|
||||
.expect(db.posts[0])
|
||||
.expect(200, done)
|
||||
})
|
||||
|
||||
@ -171,7 +175,7 @@ describe('Server', function() {
|
||||
.expect(200)
|
||||
.end(function(err, res){
|
||||
if (err) return done(err)
|
||||
assert.equal(low.db.posts.length, 3)
|
||||
assert.equal(db.posts.length, 3)
|
||||
done()
|
||||
})
|
||||
})
|
||||
@ -188,7 +192,7 @@ describe('Server', function() {
|
||||
.end(function(err, res){
|
||||
if (err) return done(err)
|
||||
// assert it was created in database too
|
||||
assert.deepEqual(low.db.posts[0], {id: 1, body: 'bar', booleanValue: true, integerValue: 1})
|
||||
assert.deepEqual(db.posts[0], {id: 1, body: 'bar', booleanValue: true, integerValue: 1})
|
||||
done()
|
||||
})
|
||||
})
|
||||
@ -214,7 +218,7 @@ describe('Server', function() {
|
||||
.end(function(err, res){
|
||||
if (err) return done(err)
|
||||
// assert it was created in database too
|
||||
assert.deepEqual(low.db.posts[0], {id: 1, body: 'bar'})
|
||||
assert.deepEqual(db.posts[0], {id: 1, body: 'bar'})
|
||||
done()
|
||||
})
|
||||
})
|
||||
@ -236,8 +240,8 @@ describe('Server', function() {
|
||||
.expect(204)
|
||||
.end(function(err, res){
|
||||
if (err) return done(err)
|
||||
assert.equal(low.db.posts.length, 1)
|
||||
assert.equal(low.db.comments.length, 3)
|
||||
assert.equal(db.posts.length, 1)
|
||||
assert.equal(db.comments.length, 3)
|
||||
done()
|
||||
})
|
||||
})
|
@ -20,8 +20,8 @@ describe('utils', function() {
|
||||
}
|
||||
|
||||
var expected = [
|
||||
['comments', 2],
|
||||
['comments', 3]
|
||||
{ name: 'comments', id: 2 },
|
||||
{ name: 'comments', id: 3 }
|
||||
]
|
||||
|
||||
assert.deepEqual(expected, utils.getRemovable(db))
|
||||
|
Reference in New Issue
Block a user