Add prettier

This commit is contained in:
typicode
2017-07-02 15:09:32 +02:00
parent 9fd9c3134a
commit 13a231d794
31 changed files with 1041 additions and 1206 deletions

View File

@ -3,7 +3,7 @@ const yargs = require('yargs')
const run = require('./run')
const pkg = require('../../package.json')
module.exports = function () {
module.exports = function() {
updateNotifier({ pkg }).notify()
const argv = yargs
@ -83,14 +83,15 @@ module.exports = function () {
.boolean('quiet')
.boolean('no-cors')
.boolean('no-gzip')
.help('help').alias('help', 'h')
.version(pkg.version).alias('version', 'v')
.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
.require(1, 'Missing <source> argument').argv
run(argv)
}

View File

@ -10,7 +10,7 @@ const load = require('./utils/load')
const example = require('./example.json')
const jsonServer = require('../server')
function prettyPrint (argv, object, rules) {
function prettyPrint(argv, object, rules) {
const host = argv.host === '0.0.0.0' ? 'localhost' : argv.host
const port = argv.port
const root = `http://${host}:${port}`
@ -35,7 +35,7 @@ function prettyPrint (argv, object, rules) {
console.log()
}
function createApp (source, object, routes, middlewares, argv) {
function createApp(source, object, routes, middlewares, argv) {
const app = jsonServer.create()
let router
@ -86,7 +86,7 @@ function createApp (source, object, routes, middlewares, argv) {
return app
}
module.exports = function (argv) {
module.exports = function(argv) {
const source = argv._[0]
let app
let server
@ -104,7 +104,7 @@ module.exports = function (argv) {
console.log()
console.log(chalk.cyan(' \\{^_^}/ hi!'))
function start (cb) {
function start(cb) {
console.log()
// Be nice and create a default db.json if it doesn't exist
@ -131,7 +131,7 @@ module.exports = function (argv) {
// Load middlewares
let middlewares
if (argv.middlewares) {
middlewares = argv.middlewares.map(function (m) {
middlewares = argv.middlewares.map(function(m) {
console.log(chalk.gray(' Loading', m))
return require(path.resolve(m))
})
@ -158,7 +158,9 @@ module.exports = function (argv) {
start(() => {
// Snapshot
console.log(
chalk.gray(' Type s + enter at any time to create a snapshot of the database')
chalk.gray(
' Type s + enter at any time to create a snapshot of the database'
)
)
// Support nohup
@ -168,13 +170,15 @@ module.exports = function (argv) {
console.log(` Creating a snapshot from the CLI won't be possible`)
})
process.stdin.setEncoding('utf8')
process.stdin.on('data', (chunk) => {
process.stdin.on('data', chunk => {
if (chunk.trim().toLowerCase() === 's') {
const filename = 'db-' + Date.now() + '.json'
const file = path.join(argv.snapshots, filename)
const state = app.db.getState()
fs.writeFileSync(file, JSON.stringify(state, null, 2), 'utf-8')
console.log(` Saved snapshot to ${path.relative(process.cwd(), file)}\n`)
console.log(
` Saved snapshot to ${path.relative(process.cwd(), file)}\n`
)
}
})
@ -185,7 +189,7 @@ module.exports = function (argv) {
const source = argv._[0]
// Can't watch URL
if (is.URL(source)) throw new Error('Can\'t watch URL')
if (is.URL(source)) throw new Error("Can't watch URL")
// Watch .js or .json file
// Since lowdb uses atomic writing, directory is watched instead of file
@ -231,7 +235,9 @@ module.exports = function (argv) {
if (file) {
const watchedFile = path.resolve(watchedDir, file)
if (watchedFile === path.resolve(argv.routes)) {
console.log(chalk.gray(` ${argv.routes} has changed, reloading...`))
console.log(
chalk.gray(` ${argv.routes} has changed, reloading...`)
)
server && server.destroy()
start()
}

View File

@ -4,14 +4,14 @@ module.exports = {
URL
}
function JSON (s) {
function JSON(s) {
return !URL(s) && /\.json$/.test(s)
}
function JS (s) {
function JS(s) {
return !URL(s) && /\.js$/.test(s)
}
function URL (s) {
function URL(s) {
return /^(http|https):/.test(s)
}

View File

@ -4,7 +4,7 @@ const low = require('lowdb')
const fileAsync = require('lowdb/lib/storages/file-async')
const is = require('./is')
module.exports = function (source, cb) {
module.exports = function(source, cb) {
if (is.URL(source)) {
// Load remote data
const opts = {
@ -23,7 +23,9 @@ module.exports = function (source, cb) {
const dataFn = require(filename)
if (typeof dataFn !== 'function') {
throw new Error('The database is a JavaScript file but the export is not a function.')
throw new Error(
'The database is a JavaScript file but the export is not a function.'
)
}
// Run dataFn to generate data

View File

@ -1,6 +1,6 @@
const bodyParser = require('body-parser')
module.exports = [
bodyParser.json({limit: '10mb', extended: false}),
bodyParser.urlencoded({extended: false})
bodyParser.json({ limit: '10mb', extended: false }),
bodyParser.urlencoded({ extended: false })
]

View File

@ -7,12 +7,10 @@ const compression = require('compression')
const errorhandler = require('errorhandler')
const objectAssign = require('object-assign')
module.exports = function (opts) {
module.exports = function(opts) {
const userDir = path.join(process.cwd(), 'public')
const defaultDir = path.join(__dirname, 'public')
const staticDir = fs.existsSync(userDir)
? userDir
: defaultDir
const staticDir = fs.existsSync(userDir) ? userDir : defaultDir
opts = objectAssign({ logger: true, static: staticDir }, opts)
@ -27,10 +25,8 @@ module.exports = function (opts) {
if (opts.logger) {
arr.push(
logger('dev', {
skip: (req) => (
process.env.NODE_ENV === 'test' ||
req.path === '/favicon.ico'
)
skip: req =>
process.env.NODE_ENV === 'test' || req.path === '/favicon.ico'
})
)
}

View File

@ -9,16 +9,18 @@ module.exports = {
// Returns document ids that have unsatisfied relations
// Example: a comment that references a post that doesn't exist
function getRemovable (db, opts) {
function getRemovable(db, opts) {
const _ = this
const removable = []
_.each(db, (coll, collName) => {
_.each(coll, (doc) => {
_.each(coll, doc => {
_.each(doc, (value, key) => {
if (new RegExp(`${opts.foreignKeySuffix}$`).test(key)) {
// Remove foreign key suffix and pluralize it
// Example postId -> posts
const refName = pluralize.plural(key.replace(new RegExp(`${opts.foreignKeySuffix}$`), ''))
const refName = pluralize.plural(
key.replace(new RegExp(`${opts.foreignKeySuffix}$`), '')
)
// Test if table exists
if (db[refName]) {
// Test if references is defined in table
@ -37,7 +39,7 @@ function getRemovable (db, opts) {
// Return incremented id or uuid
// Used to override lodash-id's createId with utils.createId
function createId (coll) {
function createId(coll) {
const _ = this
const idProperty = _.__id()
if (_.isEmpty(coll)) {
@ -46,13 +48,11 @@ function createId (coll) {
let id = _(coll).maxBy(idProperty)[idProperty]
// Increment integer id or generate string id
return _.isFinite(id)
? ++id
: shortid.generate()
return _.isFinite(id) ? ++id : shortid.generate()
}
}
function deepQuery (value, q) {
function deepQuery(value, q) {
const _ = this
if (value && q) {
if (_.isArray(value)) {

View File

@ -3,68 +3,55 @@
// Resource list
var db = {}
m.request('db').then(function (data) {
m.request('db').then(function(data) {
db = data
})
m.mount(
document.getElementById('resources'),
{
view: function () {
var keys = Object.keys(db)
var resourceList = (
m(
'ul',
keys
.map(function (key) {
return m('li', [
m('a', { href: key }, '/' + key),
m('sup', Array.isArray(db[key])
? ' ' + db[key].length + 'x'
: ' object'
)
])
})
.concat([
m('a', { href: 'db' }, '/db'),
m('sup', m('em', ' state'))
])
)
)
m.mount(document.getElementById('resources'), {
view: function() {
var keys = Object.keys(db)
var resourceList = m(
'ul',
keys
.map(function(key) {
return m('li', [
m('a', { href: key }, '/' + key),
m(
'sup',
Array.isArray(db[key]) ? ' ' + db[key].length + 'x' : ' object'
)
])
})
.concat([m('a', { href: 'db' }, '/db'), m('sup', m('em', ' state'))])
)
return [
m('h4', 'Resources'),
keys.length
? resourceList
: m('p', 'No resources found')
]
}
return [
m('h4', 'Resources'),
keys.length ? resourceList : m('p', 'No resources found')
]
}
)
})
// Custom routes
var customRoutes = {}
m.request('__rules').then(function (data) {
m.request('__rules').then(function(data) {
customRoutes = data
})
m.mount(
document.getElementById('custom-routes'),
{
view: function () {
var rules = Object.keys(customRoutes)
if (rules.length) {
return [
m('h4', 'Custom routes'),
m('table', rules.map(function (rule) {
return m('tr', [
m('td', rule),
m('td', '⇢ ' + customRoutes[rule])
])
}))
]
}
m.mount(document.getElementById('custom-routes'), {
view: function() {
var rules = Object.keys(customRoutes)
if (rules.length) {
return [
m('h4', 'Custom routes'),
m(
'table',
rules.map(function(rule) {
return m('tr', [m('td', rule), m('td', '⇢ ' + customRoutes[rule])])
})
)
]
}
}
)
})

View File

@ -1,17 +1,19 @@
const express = require('express')
const url = require('url')
const _ = require('lodash')
function updateQueryString (target, sourceUrl) {
return ~sourceUrl.indexOf('?') ? _.assign(target, url.parse(sourceUrl, true).query) : {}
function updateQueryString(target, sourceUrl) {
return ~sourceUrl.indexOf('?')
? _.assign(target, url.parse(sourceUrl, true).query)
: {}
}
module.exports = (routes) => {
module.exports = routes => {
const router = express.Router()
router.get('/__rules', (req, res) => {
res.json(routes)
})
Object.keys(routes).forEach((route) => {
Object.keys(routes).forEach(route => {
if (route.indexOf(':') !== -1) {
router.all(route, (req, res, next) => {
// Rewrite target url using params

View File

@ -1,6 +1,6 @@
const url = require('url')
module.exports = function getFullURL (req) {
module.exports = function getFullURL(req) {
const root = url.format({
protocol: req.protocol,
host: req.get('host')

View File

@ -53,24 +53,27 @@ module.exports = (source, opts = { foreignKeySuffix: 'Id' }) => {
router.use(nested(opts))
// Create routes
db.forEach((value, key) => {
if (_.isPlainObject(value)) {
router.use(`/${key}`, singular(db, key))
return
}
db
.forEach((value, key) => {
if (_.isPlainObject(value)) {
router.use(`/${key}`, singular(db, key))
return
}
if (_.isArray(value)) {
router.use(`/${key}`, plural(db, key, opts))
return
}
if (_.isArray(value)) {
router.use(`/${key}`, plural(db, key, opts))
return
}
const msg =
`Type of "${key}" (${typeof value}) ` +
(_.isObject(source) ? '' : `in ${source}`) + ' is not supported. ' +
'Use objects or arrays of objects.'
const msg =
`Type of "${key}" (${typeof value}) ` +
(_.isObject(source) ? '' : `in ${source}`) +
' is not supported. ' +
'Use objects or arrays of objects.'
throw new Error(msg)
}).value()
throw new Error(msg)
})
.value()
router.use((req, res) => {
if (!res.locals.data) {

View File

@ -1,11 +1,11 @@
const express = require('express')
const pluralize = require('pluralize')
module.exports = (opts) => {
module.exports = opts => {
const router = express.Router()
// Rewrite URL (/:resource/:id/:nested -> /:nested) and request query
function get (req, res, next) {
function get(req, res, next) {
const prop = pluralize.singular(req.params.resource)
req.query[`${prop}${opts.foreignKeySuffix}`] = req.params.id
req.url = `/${req.params.nested}`
@ -13,7 +13,7 @@ module.exports = (opts) => {
}
// Rewrite URL (/:resource/:id/:nested -> /:nested) and request body
function post (req, res, next) {
function post(req, res, next) {
const prop = pluralize.singular(req.params.resource)
req.body[`${prop}${opts.foreignKeySuffix}`] = req.params.id
req.url = `/${req.params.nested}`

View File

@ -10,26 +10,32 @@ module.exports = (db, name, opts) => {
const router = express.Router()
// Embed function used in GET /name and GET /name/id
function embed (resource, e) {
e && [].concat(e)
.forEach((externalResource) => {
function embed(resource, e) {
e &&
[].concat(e).forEach(externalResource => {
if (db.get(externalResource).value) {
const query = {}
const singularResource = pluralize.singular(name)
query[`${singularResource}${opts.foreignKeySuffix}`] = resource.id
resource[externalResource] = db.get(externalResource).filter(query).value()
resource[externalResource] = db
.get(externalResource)
.filter(query)
.value()
}
})
}
// Expand function used in GET /name and GET /name/id
function expand (resource, e) {
e && [].concat(e)
.forEach((innerResource) => {
function expand(resource, e) {
e &&
[].concat(e).forEach(innerResource => {
const plural = pluralize(innerResource)
if (db.get(plural).value()) {
const prop = `${innerResource}${opts.foreignKeySuffix}`
resource[innerResource] = db.get(plural).getById(resource[prop]).value()
resource[innerResource] = db
.get(plural)
.getById(resource[prop])
.value()
}
})
}
@ -40,7 +46,7 @@ module.exports = (db, name, opts) => {
// GET /name?_end=&
// GET /name?_start=&_end=&
// GET /name?_embed=&_expand=
function list (req, res, next) {
function list(req, res, next) {
// Resource chain
let chain = db.get(name)
@ -66,7 +72,7 @@ module.exports = (db, name, opts) => {
// Automatically delete query parameters that can't be found
// in the database
Object.keys(req.query).forEach((query) => {
Object.keys(req.query).forEach(query => {
const arr = db.get(name).value()
for (let i in arr) {
if (
@ -77,7 +83,8 @@ module.exports = (db, name, opts) => {
/_gte$/.test(query) ||
/_ne$/.test(query) ||
/_like$/.test(query)
) return
)
return
}
delete req.query[query]
})
@ -90,7 +97,7 @@ module.exports = (db, name, opts) => {
q = q.toLowerCase()
chain = chain.filter((obj) => {
chain = chain.filter(obj => {
for (let key in obj) {
const value = obj[key]
if (db._.deepQuery(value, q)) {
@ -100,16 +107,16 @@ module.exports = (db, name, opts) => {
})
}
Object.keys(req.query).forEach((key) => {
Object.keys(req.query).forEach(key => {
// Don't take into account JSONP query parameters
// jQuery adds a '_' query parameter too
if (key !== 'callback' && key !== '_') {
// Always use an array, in case req.query is an array
const arr = [].concat(req.query[key])
chain = chain.filter((element) => {
chain = chain.filter(element => {
return arr
.map(function (value) {
.map(function(value) {
const isDifferent = /_ne$/.test(key)
const isRange = /_lte$/.test(key) || /_gte$/.test(key)
const isLike = /_like$/.test(key)
@ -152,7 +159,10 @@ module.exports = (db, name, opts) => {
// Slice result
if (_end || _limit || _page) {
res.setHeader('X-Total-Count', chain.size())
res.setHeader('Access-Control-Expose-Headers', 'X-Total-Count' + (_page ? ', Link' : ''))
res.setHeader(
'Access-Control-Expose-Headers',
'X-Total-Count' + (_page ? ', Link' : '')
)
}
if (_page) {
@ -164,19 +174,31 @@ module.exports = (db, name, opts) => {
const fullURL = getFullURL(req)
if (page.first) {
links.first = fullURL.replace('page=' + page.current, 'page=' + page.first)
links.first = fullURL.replace(
'page=' + page.current,
'page=' + page.first
)
}
if (page.prev) {
links.prev = fullURL.replace('page=' + page.current, 'page=' + page.prev)
links.prev = fullURL.replace(
'page=' + page.current,
'page=' + page.prev
)
}
if (page.next) {
links.next = fullURL.replace('page=' + page.current, 'page=' + page.next)
links.next = fullURL.replace(
'page=' + page.current,
'page=' + page.next
)
}
if (page.last) {
links.last = fullURL.replace('page=' + page.current, 'page=' + page.last)
links.last = fullURL.replace(
'page=' + page.current,
'page=' + page.last
)
}
res.links(links)
@ -192,12 +214,10 @@ module.exports = (db, name, opts) => {
}
// embed and expand
chain = chain
.cloneDeep()
.forEach(function (element) {
embed(element, _embed)
expand(element, _expand)
})
chain = chain.cloneDeep().forEach(function(element) {
embed(element, _embed)
expand(element, _expand)
})
res.locals.data = chain.value()
next()
@ -205,12 +225,10 @@ module.exports = (db, name, opts) => {
// GET /name/:id
// GET /name/:id?_embed=&_expand
function show (req, res, next) {
function show(req, res, next) {
const _embed = req.query._embed
const _expand = req.query._expand
const resource = db.get(name)
.getById(req.params.id)
.value()
const resource = db.get(name).getById(req.params.id).value()
if (resource) {
// Clone resource to avoid making changes to the underlying object
@ -231,11 +249,8 @@ module.exports = (db, name, opts) => {
}
// POST /name
function create (req, res, next) {
const resource = db
.get(name)
.insert(req.body)
.value()
function create(req, res, next) {
const resource = db.get(name).insert(req.body).value()
res.setHeader('Access-Control-Expose-Headers', 'Location')
res.location(`${getFullURL(req)}/${resource.id}`)
@ -248,13 +263,14 @@ module.exports = (db, name, opts) => {
// PUT /name/:id
// PATCH /name/:id
function update (req, res, next) {
function update(req, res, next) {
const id = req.params.id
let chain = db.get(name)
chain = req.method === 'PATCH'
? chain.updateById(id, req.body)
: chain.replaceById(id, req.body)
chain =
req.method === 'PATCH'
? chain.updateById(id, req.body)
: chain.replaceById(id, req.body)
const resource = chain.value()
@ -266,19 +282,15 @@ module.exports = (db, name, opts) => {
}
// DELETE /name/:id
function destroy (req, res, next) {
const resource = db.get(name)
.removeById(req.params.id)
.value()
function destroy(req, res, next) {
const resource = db.get(name).removeById(req.params.id).value()
// Remove dependents documents
console.log({opts})
console.log({ opts })
const removable = db._.getRemovable(db.getState(), opts)
console.log(removable)
removable.forEach((item) => {
db.get(item.name)
.removeById(item.id)
.value()
removable.forEach(item => {
db.get(item.name).removeById(item.id).value()
})
if (resource) {
@ -290,11 +302,10 @@ module.exports = (db, name, opts) => {
const w = write(db)
router.route('/')
.get(list)
.post(create, w)
router.route('/').get(list).post(create, w)
router.route('/:id')
router
.route('/:id')
.get(show)
.put(update, w)
.patch(update, w)

View File

@ -5,12 +5,12 @@ const getFullURL = require('./get-full-url')
module.exports = (db, name) => {
const router = express.Router()
function show (req, res, next) {
function show(req, res, next) {
res.locals.data = db.get(name).value()
next()
}
function create (req, res, next) {
function create(req, res, next) {
db.set(name, req.body).value()
res.locals.data = db.get(name).value()
@ -21,14 +21,11 @@ module.exports = (db, name) => {
next()
}
function update (req, res, next) {
function update(req, res, next) {
if (req.method === 'PUT') {
db.set(name, req.body)
.value()
db.set(name, req.body).value()
} else {
db.get(name)
.assign(req.body)
.value()
db.get(name).assign(req.body).value()
}
res.locals.data = db.get(name).value()
@ -37,11 +34,7 @@ module.exports = (db, name) => {
const w = write(db)
router.route('/')
.get(show)
.post(create, w)
.put(update, w)
.patch(update, w)
router.route('/').get(show).post(create, w).put(update, w).patch(update, w)
return router
}

View File

@ -1,26 +1,24 @@
const _ = require('lodash')
function validateKey (key) {
function validateKey(key) {
if (key.indexOf('/') !== -1) {
const msg = [
`Oops, found / character in database property '${key}'.`,
'',
'/ aren\'t supported, if you want to tweak default routes, see',
"/ aren't supported, if you want to tweak default routes, see",
'https://github.com/typicode/json-server/#add-custom-routes'
].join('\n')
throw new Error(msg)
}
}
module.exports = (obj) => {
module.exports = obj => {
if (_.isPlainObject(obj)) {
Object
.keys(obj)
.forEach(validateKey)
Object.keys(obj).forEach(validateKey)
} else {
throw new Error(
`Data must be an object. Found ${typeof obj}.` +
'See https://github.com/typicode/json-server for example.'
'See https://github.com/typicode/json-server for example.'
)
}
}

View File

@ -1,4 +1,4 @@
module.exports = function write (db) {
module.exports = function write(db) {
return (req, res, next) => {
db.write()
next()

View File

@ -2,7 +2,7 @@ module.exports = {
getPage
}
function getPage (array, page, perPage) {
function getPage(array, page, perPage) {
var obj = {}
var start = (page - 1) * perPage
var end = page * perPage