mirror of
https://github.com/typicode/json-server.git
synced 2025-07-27 12:12:41 +08:00
Merge branch 'ruifortes-master'
This commit is contained in:
10550
package-lock.json
generated
10550
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -30,7 +30,7 @@
|
|||||||
"json-parse-helpfulerror": "^1.0.3",
|
"json-parse-helpfulerror": "^1.0.3",
|
||||||
"lodash": "^4.17.10",
|
"lodash": "^4.17.10",
|
||||||
"lodash-id": "^0.14.0",
|
"lodash-id": "^0.14.0",
|
||||||
"lowdb": "^0.15.0",
|
"lowdb": "^1.0.0",
|
||||||
"method-override": "^2.3.10",
|
"method-override": "^2.3.10",
|
||||||
"morgan": "^1.9.0",
|
"morgan": "^1.9.0",
|
||||||
"nanoid": "^1.1.1",
|
"nanoid": "^1.1.1",
|
||||||
|
@ -9,12 +9,6 @@ const is = require('./utils/is')
|
|||||||
const load = require('./utils/load')
|
const load = require('./utils/load')
|
||||||
const jsonServer = require('../server')
|
const jsonServer = require('../server')
|
||||||
|
|
||||||
const example = {
|
|
||||||
posts: [{ id: 1, title: 'json-server', author: 'typicode' }],
|
|
||||||
comments: [{ id: 1, body: 'some comment', postId: 1 }],
|
|
||||||
profile: { name: 'typicode' }
|
|
||||||
}
|
|
||||||
|
|
||||||
function prettyPrint(argv, object, rules) {
|
function prettyPrint(argv, object, rules) {
|
||||||
const root = `http://${argv.host}:${argv.port}`
|
const root = `http://${argv.host}:${argv.port}`
|
||||||
|
|
||||||
@ -38,22 +32,15 @@ function prettyPrint(argv, object, rules) {
|
|||||||
console.log()
|
console.log()
|
||||||
}
|
}
|
||||||
|
|
||||||
function createApp(source, object, routes, middlewares, argv) {
|
function createApp(db, routes, middlewares, argv) {
|
||||||
const app = jsonServer.create()
|
const app = jsonServer.create()
|
||||||
|
|
||||||
let router
|
|
||||||
|
|
||||||
const { foreignKeySuffix } = argv
|
const { foreignKeySuffix } = argv
|
||||||
try {
|
|
||||||
router = jsonServer.router(
|
let router = jsonServer.router(
|
||||||
is.JSON(source) ? source : object,
|
db,
|
||||||
foreignKeySuffix ? { foreignKeySuffix } : undefined
|
foreignKeySuffix ? { foreignKeySuffix } : undefined
|
||||||
)
|
)
|
||||||
} catch (e) {
|
|
||||||
console.log()
|
|
||||||
console.error(chalk.red(e.message.replace(/^/gm, ' ')))
|
|
||||||
process.exit(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
const defaultsOpts = {
|
const defaultsOpts = {
|
||||||
logger: !argv.quiet,
|
logger: !argv.quiet,
|
||||||
@ -111,20 +98,12 @@ module.exports = function(argv) {
|
|||||||
function start(cb) {
|
function start(cb) {
|
||||||
console.log()
|
console.log()
|
||||||
|
|
||||||
// Be nice and create a default db.json if it doesn't exist
|
|
||||||
if (is.JSON(source) && !fs.existsSync(source)) {
|
|
||||||
console.log(chalk.yellow(` Oops, ${source} doesn't seem to exist`))
|
|
||||||
console.log(chalk.yellow(` Creating ${source} with some default data`))
|
|
||||||
console.log()
|
|
||||||
fs.writeFileSync(source, JSON.stringify(example, null, 2))
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(chalk.gray(' Loading', source))
|
console.log(chalk.gray(' Loading', source))
|
||||||
|
|
||||||
// Load JSON, JS or HTTP database
|
server = undefined
|
||||||
load(source, (err, data) => {
|
|
||||||
if (err) throw err
|
|
||||||
|
|
||||||
|
// create db and load object, JSON file, JS or HTTP database
|
||||||
|
return load(source).then(db => {
|
||||||
// Load additional routes
|
// Load additional routes
|
||||||
let routes
|
let routes
|
||||||
if (argv.routes) {
|
if (argv.routes) {
|
||||||
@ -145,21 +124,20 @@ module.exports = function(argv) {
|
|||||||
console.log(chalk.gray(' Done'))
|
console.log(chalk.gray(' Done'))
|
||||||
|
|
||||||
// Create app and server
|
// Create app and server
|
||||||
app = createApp(source, data, routes, middlewares, argv)
|
app = createApp(db, routes, middlewares, argv)
|
||||||
server = app.listen(argv.port, argv.host)
|
server = app.listen(argv.port, argv.host)
|
||||||
|
|
||||||
// Enhance with a destroy function
|
// Enhance with a destroy function
|
||||||
enableDestroy(server)
|
enableDestroy(server)
|
||||||
|
|
||||||
// Display server informations
|
// Display server informations
|
||||||
prettyPrint(argv, data, routes)
|
prettyPrint(argv, db.getState(), routes)
|
||||||
|
|
||||||
cb && cb()
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start server
|
// Start server
|
||||||
start(() => {
|
start()
|
||||||
|
.then(() => {
|
||||||
// Snapshot
|
// Snapshot
|
||||||
console.log(
|
console.log(
|
||||||
chalk.gray(
|
chalk.gray(
|
||||||
@ -205,7 +183,7 @@ module.exports = function(argv) {
|
|||||||
if (file) {
|
if (file) {
|
||||||
const watchedFile = path.resolve(watchedDir, file)
|
const watchedFile = path.resolve(watchedDir, file)
|
||||||
if (watchedFile === path.resolve(source)) {
|
if (watchedFile === path.resolve(source)) {
|
||||||
if (is.JSON(watchedFile)) {
|
if (is.FILE(watchedFile)) {
|
||||||
let obj
|
let obj
|
||||||
try {
|
try {
|
||||||
obj = jph.parse(fs.readFileSync(watchedFile))
|
obj = jph.parse(fs.readFileSync(watchedFile))
|
||||||
@ -223,9 +201,10 @@ module.exports = function(argv) {
|
|||||||
// Compare .json file content with in memory database
|
// Compare .json file content with in memory database
|
||||||
const isDatabaseDifferent = !_.isEqual(obj, app.db.getState())
|
const isDatabaseDifferent = !_.isEqual(obj, app.db.getState())
|
||||||
if (isDatabaseDifferent) {
|
if (isDatabaseDifferent) {
|
||||||
console.log(chalk.gray(` ${source} has changed, reloading...`))
|
console.log(
|
||||||
server && server.destroy()
|
chalk.gray(` ${source} has changed, reloading...`)
|
||||||
start()
|
)
|
||||||
|
server && server.destroy(() => start())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -242,12 +221,15 @@ module.exports = function(argv) {
|
|||||||
console.log(
|
console.log(
|
||||||
chalk.gray(` ${argv.routes} has changed, reloading...`)
|
chalk.gray(` ${argv.routes} has changed, reloading...`)
|
||||||
)
|
)
|
||||||
server && server.destroy()
|
server && server.destroy(() => start())
|
||||||
start()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err)
|
||||||
|
process.exit(1)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
JSON,
|
FILE,
|
||||||
JS,
|
JS,
|
||||||
URL
|
URL
|
||||||
}
|
}
|
||||||
|
|
||||||
function JSON(s) {
|
function FILE(s) {
|
||||||
return !URL(s) && /\.json$/.test(s)
|
return !URL(s) && /\.json$/.test(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,30 @@
|
|||||||
|
const fs = require('fs')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const request = require('request')
|
const request = require('request')
|
||||||
const low = require('lowdb')
|
const low = require('lowdb')
|
||||||
const fileAsync = require('lowdb/lib/storages/file-async')
|
const FileAsync = require('lowdb/adapters/FileAsync')
|
||||||
|
const Memory = require('lowdb/adapters/Memory')
|
||||||
const is = require('./is')
|
const is = require('./is')
|
||||||
|
const chalk = require('chalk')
|
||||||
|
|
||||||
module.exports = function(source, cb) {
|
const example = {
|
||||||
if (is.URL(source)) {
|
posts: [{ id: 1, title: 'json-server', author: 'typicode' }],
|
||||||
|
comments: [{ id: 1, body: 'some comment', postId: 1 }],
|
||||||
|
profile: { name: 'typicode' }
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function(source) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
if (is.FILE(source)) {
|
||||||
|
if (!fs.existsSync(source)) {
|
||||||
|
console.log(chalk.yellow(` Oops, ${source} doesn't seem to exist`))
|
||||||
|
console.log(chalk.yellow(` Creating ${source} with some default data`))
|
||||||
|
console.log()
|
||||||
|
fs.writeFileSync(source, JSON.stringify(example, null, 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
resolve(low(new FileAsync(source)))
|
||||||
|
} else if (is.URL(source)) {
|
||||||
// Load remote data
|
// Load remote data
|
||||||
const opts = {
|
const opts = {
|
||||||
url: source,
|
url: source,
|
||||||
@ -13,8 +32,8 @@ module.exports = function(source, cb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
request(opts, (err, response) => {
|
request(opts, (err, response) => {
|
||||||
if (err) return cb(err)
|
if (err) return reject(err)
|
||||||
cb(null, response.body)
|
resolve(low(new Memory()).setState(response.body))
|
||||||
})
|
})
|
||||||
} else if (is.JS(source)) {
|
} else if (is.JS(source)) {
|
||||||
// Clear cache
|
// Clear cache
|
||||||
@ -30,12 +49,9 @@ module.exports = function(source, cb) {
|
|||||||
|
|
||||||
// Run dataFn to generate data
|
// Run dataFn to generate data
|
||||||
const data = dataFn()
|
const data = dataFn()
|
||||||
cb(null, data)
|
resolve(low(new Memory()).setState(data))
|
||||||
} else if (is.JSON(source)) {
|
|
||||||
// Load JSON using lowdb
|
|
||||||
const data = low(source, { storage: fileAsync }).getState()
|
|
||||||
cb(null, data)
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error(`Unsupported source ${source}`)
|
throw new Error(`Unsupported source ${source}`)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,8 @@ const methodOverride = require('method-override')
|
|||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
const lodashId = require('lodash-id')
|
const lodashId = require('lodash-id')
|
||||||
const low = require('lowdb')
|
const low = require('lowdb')
|
||||||
const fileAsync = require('lowdb/lib/storages/file-async')
|
const Memory = require('lowdb/adapters/Memory')
|
||||||
|
const FileSync = require('lowdb/adapters/FileSync')
|
||||||
const bodyParser = require('../body-parser')
|
const bodyParser = require('../body-parser')
|
||||||
const validateData = require('./validate-data')
|
const validateData = require('./validate-data')
|
||||||
const plural = require('./plural')
|
const plural = require('./plural')
|
||||||
@ -11,7 +12,13 @@ const nested = require('./nested')
|
|||||||
const singular = require('./singular')
|
const singular = require('./singular')
|
||||||
const mixins = require('../mixins')
|
const mixins = require('../mixins')
|
||||||
|
|
||||||
module.exports = (source, opts = { foreignKeySuffix: 'Id' }) => {
|
module.exports = (db, opts = { foreignKeySuffix: 'Id' }) => {
|
||||||
|
if (typeof db === 'string') {
|
||||||
|
db = low(new FileSync(db))
|
||||||
|
} else if (!_.has(db, '__chain__') || !_.has(db, '__wrapped__')) {
|
||||||
|
db = low(new Memory()).setState(db)
|
||||||
|
}
|
||||||
|
|
||||||
// Create router
|
// Create router
|
||||||
const router = express.Router()
|
const router = express.Router()
|
||||||
|
|
||||||
@ -19,15 +26,6 @@ module.exports = (source, opts = { foreignKeySuffix: 'Id' }) => {
|
|||||||
router.use(methodOverride())
|
router.use(methodOverride())
|
||||||
router.use(bodyParser)
|
router.use(bodyParser)
|
||||||
|
|
||||||
// Create database
|
|
||||||
let db
|
|
||||||
if (_.isObject(source)) {
|
|
||||||
db = low()
|
|
||||||
db.setState(source)
|
|
||||||
} else {
|
|
||||||
db = low(source, { storage: fileAsync })
|
|
||||||
}
|
|
||||||
|
|
||||||
validateData(db.getState())
|
validateData(db.getState())
|
||||||
|
|
||||||
// Add lodash-id methods to db
|
// Add lodash-id methods to db
|
||||||
@ -65,9 +63,9 @@ module.exports = (source, opts = { foreignKeySuffix: 'Id' }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var sourceMessage = ''
|
var sourceMessage = ''
|
||||||
if (!_.isObject(source)) {
|
// if (!_.isObject(source)) {
|
||||||
sourceMessage = `in ${source}`
|
// sourceMessage = `in ${source}`
|
||||||
}
|
// }
|
||||||
|
|
||||||
const msg =
|
const msg =
|
||||||
`Type of "${key}" (${typeof value}) ${sourceMessage} is not supported. ` +
|
`Type of "${key}" (${typeof value}) ${sourceMessage} is not supported. ` +
|
||||||
|
Reference in New Issue
Block a user