mirror of
https://github.com/typicode/json-server.git
synced 2025-07-27 20:23:34 +08:00
Remove automatic type conversion
This commit is contained in:
@ -25,7 +25,7 @@
|
|||||||
"pluralize": "^3.0.0",
|
"pluralize": "^3.0.0",
|
||||||
"request": "^2.72.0",
|
"request": "^2.72.0",
|
||||||
"server-destroy": "^1.0.1",
|
"server-destroy": "^1.0.1",
|
||||||
"underscore-db": "^0.10.0",
|
"underscore-db": "^0.12.0",
|
||||||
"update-notifier": "^1.0.2",
|
"update-notifier": "^1.0.2",
|
||||||
"yargs": "^4.2.0"
|
"yargs": "^4.2.0"
|
||||||
},
|
},
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
var express = require('express')
|
var express = require('express')
|
||||||
var pluralize = require('pluralize')
|
var pluralize = require('pluralize')
|
||||||
var utils = require('../utils')
|
|
||||||
|
|
||||||
module.exports = function () {
|
module.exports = function () {
|
||||||
var router = express.Router()
|
var router = express.Router()
|
||||||
@ -8,7 +7,7 @@ module.exports = function () {
|
|||||||
// Rewrite URL (/:resource/:id/:nested -> /:nested) and request query
|
// Rewrite URL (/:resource/:id/:nested -> /:nested) and request query
|
||||||
function get (req, res, next) {
|
function get (req, res, next) {
|
||||||
var prop = pluralize.singular(req.params.resource)
|
var prop = pluralize.singular(req.params.resource)
|
||||||
req.query[prop + 'Id'] = utils.toNative(req.params.id)
|
req.query[prop + 'Id'] = req.params.id
|
||||||
req.url = '/' + req.params.nested
|
req.url = '/' + req.params.nested
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
@ -16,7 +15,7 @@ module.exports = function () {
|
|||||||
// Rewrite URL (/:resource/:id/:nested -> /:nested) and request body
|
// Rewrite URL (/:resource/:id/:nested -> /:nested) and request body
|
||||||
function post (req, res, next) {
|
function post (req, res, next) {
|
||||||
var prop = pluralize.singular(req.params.resource)
|
var prop = pluralize.singular(req.params.resource)
|
||||||
req.body[prop + 'Id'] = utils.toNative(req.params.id)
|
req.body[prop + 'Id'] = req.params.id
|
||||||
req.url = '/' + req.params.nested
|
req.url = '/' + req.params.nested
|
||||||
next()
|
next()
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,6 @@ module.exports = function (db, name) {
|
|||||||
|
|
||||||
chain = chain.filter(function (element) {
|
chain = chain.filter(function (element) {
|
||||||
return arr
|
return arr
|
||||||
.map(utils.toNative)
|
|
||||||
.map(function (value) {
|
.map(function (value) {
|
||||||
var isDifferent = key.indexOf('_ne') !== -1
|
var isDifferent = key.indexOf('_ne') !== -1
|
||||||
var isRange = key.indexOf('_lte') !== -1 || key.indexOf('_gte') !== -1
|
var isRange = key.indexOf('_lte') !== -1 || key.indexOf('_gte') !== -1
|
||||||
@ -115,6 +114,10 @@ module.exports = function (db, name) {
|
|||||||
var path = key.replace(/(_lte|_gte|_ne|_like)$/, '')
|
var path = key.replace(/(_lte|_gte|_ne|_like)$/, '')
|
||||||
var elementValue = _.get(element, path)
|
var elementValue = _.get(element, path)
|
||||||
|
|
||||||
|
if (!elementValue) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if (isRange) {
|
if (isRange) {
|
||||||
var isLowerThan = key.indexOf('_gte') !== -1
|
var isLowerThan = key.indexOf('_gte') !== -1
|
||||||
|
|
||||||
@ -124,11 +127,11 @@ module.exports = function (db, name) {
|
|||||||
return value >= elementValue
|
return value >= elementValue
|
||||||
}
|
}
|
||||||
} else if (isDifferent) {
|
} else if (isDifferent) {
|
||||||
return value !== elementValue
|
return value !== elementValue.toString()
|
||||||
} else if (isLike) {
|
} else if (isLike) {
|
||||||
return new RegExp(value, 'i').test(elementValue)
|
return new RegExp(value, 'i').test(elementValue.toString())
|
||||||
} else {
|
} else {
|
||||||
return _.matchesProperty(key, value)(element)
|
return value === elementValue.toString()
|
||||||
}
|
}
|
||||||
}).reduce(function (a, b) {
|
}).reduce(function (a, b) {
|
||||||
return a || b
|
return a || b
|
||||||
@ -209,8 +212,7 @@ module.exports = function (db, name) {
|
|||||||
function show (req, res, next) {
|
function show (req, res, next) {
|
||||||
var _embed = req.query._embed
|
var _embed = req.query._embed
|
||||||
var _expand = req.query._expand
|
var _expand = req.query._expand
|
||||||
var id = utils.toNative(req.params.id)
|
var resource = db.get(name).getById(req.params.id).value()
|
||||||
var resource = db.get(name).getById(id).value()
|
|
||||||
|
|
||||||
if (resource) {
|
if (resource) {
|
||||||
// Clone resource to avoid making changes to the underlying object
|
// Clone resource to avoid making changes to the underlying object
|
||||||
@ -232,10 +234,6 @@ module.exports = function (db, name) {
|
|||||||
|
|
||||||
// POST /name
|
// POST /name
|
||||||
function create (req, res, next) {
|
function create (req, res, next) {
|
||||||
for (var key in req.body) {
|
|
||||||
req.body[key] = utils.toNative(req.body[key])
|
|
||||||
}
|
|
||||||
|
|
||||||
var resource = db.get(name)
|
var resource = db.get(name)
|
||||||
.insert(req.body)
|
.insert(req.body)
|
||||||
.value()
|
.value()
|
||||||
@ -248,11 +246,7 @@ module.exports = function (db, name) {
|
|||||||
// PUT /name/:id
|
// PUT /name/:id
|
||||||
// PATCH /name/:id
|
// PATCH /name/:id
|
||||||
function update (req, res, next) {
|
function update (req, res, next) {
|
||||||
for (var key in req.body) {
|
var id = req.params.id
|
||||||
req.body[key] = utils.toNative(req.body[key])
|
|
||||||
}
|
|
||||||
|
|
||||||
var id = utils.toNative(req.params.id)
|
|
||||||
var chain = db.get(name)
|
var chain = db.get(name)
|
||||||
|
|
||||||
chain = req.method === 'PATCH'
|
chain = req.method === 'PATCH'
|
||||||
@ -270,7 +264,7 @@ module.exports = function (db, name) {
|
|||||||
|
|
||||||
// DELETE /name/:id
|
// DELETE /name/:id
|
||||||
function destroy (req, res, next) {
|
function destroy (req, res, next) {
|
||||||
var resource = db.get(name).removeById(utils.toNative(req.params.id)).value()
|
var resource = db.get(name).removeById(req.params.id).value()
|
||||||
|
|
||||||
// Remove dependents documents
|
// Remove dependents documents
|
||||||
var removable = db._.getRemovable(db.getState())
|
var removable = db._.getRemovable(db.getState())
|
||||||
|
@ -1,29 +1,7 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
toNative: toNative,
|
|
||||||
getPage: getPage
|
getPage: getPage
|
||||||
}
|
}
|
||||||
|
|
||||||
// Turns string to native.
|
|
||||||
// Example:
|
|
||||||
// 'true' -> true
|
|
||||||
// '1' -> 1
|
|
||||||
function toNative (value) {
|
|
||||||
if (typeof value === 'string') {
|
|
||||||
if (
|
|
||||||
value === '' ||
|
|
||||||
value.trim() !== value ||
|
|
||||||
(value.length > 1 && value[0] === '0')
|
|
||||||
) {
|
|
||||||
return value
|
|
||||||
} else if (value === 'true' || value === 'false') {
|
|
||||||
return value === 'true'
|
|
||||||
} else if (!isNaN(+value)) {
|
|
||||||
return +value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPage (array, page, perPage) {
|
function getPage (array, page, perPage) {
|
||||||
var obj = {}
|
var obj = {}
|
||||||
var start = (page - 1) * perPage
|
var start = (page - 1) * perPage
|
||||||
|
@ -24,8 +24,8 @@ describe('Server', function () {
|
|||||||
]
|
]
|
||||||
|
|
||||||
db.users = [
|
db.users = [
|
||||||
{id: 1, username: 'Jim'},
|
{id: 1, username: 'Jim', tel: '0123'},
|
||||||
{id: 2, username: 'George'}
|
{id: 2, username: 'George', tel: '123'}
|
||||||
]
|
]
|
||||||
|
|
||||||
db.comments = [
|
db.comments = [
|
||||||
@ -40,6 +40,10 @@ describe('Server', function () {
|
|||||||
{id: 'abcd-1234', url: 'http://example.com', postId: 1, userId: 1}
|
{id: 'abcd-1234', url: 'http://example.com', postId: 1, userId: 1}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
db.stringIds = [
|
||||||
|
{id: '1234'}
|
||||||
|
]
|
||||||
|
|
||||||
db.deep = [
|
db.deep = [
|
||||||
{ a: { b: 1 } },
|
{ a: { b: 1 } },
|
||||||
{ a: 1 }
|
{ a: 1 }
|
||||||
@ -117,6 +121,14 @@ describe('Server', function () {
|
|||||||
.expect(200, done)
|
.expect(200, done)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should be strict', function (done) {
|
||||||
|
request(server)
|
||||||
|
.get('/users?tel=123')
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect([db.users[1]])
|
||||||
|
.expect(200, done)
|
||||||
|
})
|
||||||
|
|
||||||
it('should support multiple filters', function (done) {
|
it('should support multiple filters', function (done) {
|
||||||
request(server)
|
request(server)
|
||||||
.get('/comments?id=1&id=2')
|
.get('/comments?id=1&id=2')
|
||||||
@ -349,6 +361,14 @@ describe('Server', function () {
|
|||||||
.expect(200, done)
|
.expect(200, done)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should support integer id as string', function (done) {
|
||||||
|
request(server)
|
||||||
|
.get('/stringIds/1234')
|
||||||
|
.expect('Content-Type', /json/)
|
||||||
|
.expect(db.stringIds[0])
|
||||||
|
.expect(200, done)
|
||||||
|
})
|
||||||
|
|
||||||
it('should respond with 404 if resource is not found', function (done) {
|
it('should respond with 404 if resource is not found', function (done) {
|
||||||
request(server)
|
request(server)
|
||||||
.get('/posts/9001')
|
.get('/posts/9001')
|
||||||
@ -388,25 +408,25 @@ describe('Server', function () {
|
|||||||
|
|
||||||
describe('GET /:resource/:id?_embed=', function () {
|
describe('GET /:resource/:id?_embed=', function () {
|
||||||
it('should respond with corresponding resources and embedded resources', function (done) {
|
it('should respond with corresponding resources and embedded resources', function (done) {
|
||||||
var posts = db.posts[0]
|
var post = _.cloneDeep(db.posts[0])
|
||||||
posts.comments = [db.comments[0], db.comments[1]]
|
post.comments = [db.comments[0], db.comments[1]]
|
||||||
request(server)
|
request(server)
|
||||||
.get('/posts/1?_embed=comments')
|
.get('/posts/1?_embed=comments')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(posts)
|
.expect(post)
|
||||||
.expect(200, done)
|
.expect(200, done)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('GET /:resource/:id?_embed=&_embed=', function () {
|
describe('GET /:resource/:id?_embed=&_embed=', function () {
|
||||||
it('should respond with corresponding resource and embedded resources', function (done) {
|
it('should respond with corresponding resource and embedded resources', function (done) {
|
||||||
var posts = db.posts[0]
|
var post = _.cloneDeep(db.posts[0])
|
||||||
posts.comments = [db.comments[0], db.comments[1]]
|
post.comments = [db.comments[0], db.comments[1]]
|
||||||
posts.refs = [db.refs[0]]
|
post.refs = [db.refs[0]]
|
||||||
request(server)
|
request(server)
|
||||||
.get('/posts/1?_embed=comments&_embed=refs')
|
.get('/posts/1?_embed=comments&_embed=refs')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(posts)
|
.expect(post)
|
||||||
.expect(200, done)
|
.expect(200, done)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -425,12 +445,12 @@ describe('Server', function () {
|
|||||||
|
|
||||||
describe('GET /:resource/:id?_expand=', function () {
|
describe('GET /:resource/:id?_expand=', function () {
|
||||||
it('should respond with corresponding resource and expanded inner resources', function (done) {
|
it('should respond with corresponding resource and expanded inner resources', function (done) {
|
||||||
var comments = db.comments[0]
|
var comment = _.cloneDeep(db.comments[0])
|
||||||
comments.post = db.posts[0]
|
comment.post = db.posts[0]
|
||||||
request(server)
|
request(server)
|
||||||
.get('/comments/1?_expand=post')
|
.get('/comments/1?_expand=post')
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(comments)
|
.expect(comment)
|
||||||
.expect(200, done)
|
.expect(200, done)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -466,7 +486,7 @@ describe('Server', function () {
|
|||||||
function (done) {
|
function (done) {
|
||||||
request(server)
|
request(server)
|
||||||
.post('/posts')
|
.post('/posts')
|
||||||
.send({body: 'foo', booleanValue: 'true', integerValue: '1'})
|
.send({body: 'foo', booleanValue: true, integerValue: 1})
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect({id: 3, body: 'foo', booleanValue: true, integerValue: 1})
|
.expect({id: 3, body: 'foo', booleanValue: true, integerValue: 1})
|
||||||
.expect(201)
|
.expect(201)
|
||||||
@ -475,23 +495,26 @@ describe('Server', function () {
|
|||||||
assert.equal(db.posts.length, 3)
|
assert.equal(db.posts.length, 3)
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
it('should support x-www-form-urlencoded',
|
it('should support x-www-form-urlencoded',
|
||||||
function (done) {
|
function (done) {
|
||||||
request(server)
|
request(server)
|
||||||
.post('/posts')
|
.post('/posts')
|
||||||
.type('form')
|
.type('form')
|
||||||
.send({body: 'foo'})
|
.send({body: 'foo', booleanValue: true, integerValue: 1})
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect({id: 3, body: 'foo'})
|
// x-www-form-urlencoded will convert to string
|
||||||
|
.expect({id: 3, body: 'foo', booleanValue: 'true', integerValue: '1'})
|
||||||
.expect(201)
|
.expect(201)
|
||||||
.end(function (err, res) {
|
.end(function (err, res) {
|
||||||
if (err) return done(err)
|
if (err) return done(err)
|
||||||
assert.equal(db.posts.length, 3)
|
assert.equal(db.posts.length, 3)
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
}
|
||||||
|
)
|
||||||
|
|
||||||
it('should respond with json, create a resource and generate string id',
|
it('should respond with json, create a resource and generate string id',
|
||||||
function (done) {
|
function (done) {
|
||||||
@ -525,7 +548,7 @@ describe('Server', function () {
|
|||||||
request(server)
|
request(server)
|
||||||
.put('/posts/1')
|
.put('/posts/1')
|
||||||
// body property omitted to test that the resource is replaced
|
// body property omitted to test that the resource is replaced
|
||||||
.send({id: 1, booleanValue: 'true', integerValue: '1'})
|
.send(post)
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect(post)
|
.expect(post)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
@ -540,7 +563,7 @@ describe('Server', function () {
|
|||||||
it('should respond with 404 if resource is not found', function (done) {
|
it('should respond with 404 if resource is not found', function (done) {
|
||||||
request(server)
|
request(server)
|
||||||
.put('/posts/9001')
|
.put('/posts/9001')
|
||||||
.send({id: 1, body: 'bar', booleanValue: 'true', integerValue: '1'})
|
.send({id: 1, body: 'bar'})
|
||||||
.expect('Content-Type', /json/)
|
.expect('Content-Type', /json/)
|
||||||
.expect({})
|
.expect({})
|
||||||
.expect(404, done)
|
.expect(404, done)
|
||||||
|
@ -4,24 +4,6 @@ var utils = require('../../src/server/utils')
|
|||||||
/* global describe, it */
|
/* global describe, it */
|
||||||
|
|
||||||
describe('utils', function () {
|
describe('utils', function () {
|
||||||
describe('toNative', 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)
|
|
||||||
assert.strictEqual(utils.toNative(true), true)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('getPage', function () {
|
describe('getPage', function () {
|
||||||
var array = [1, 2, 3, 4, 5]
|
var array = [1, 2, 3, 4, 5]
|
||||||
var perPage = 2
|
var perPage = 2
|
||||||
|
Reference in New Issue
Block a user