[release]4.1.0 (#211)
This commit is contained in:
		@@ -1,26 +1,66 @@
 | 
			
		||||
import Mock from 'mockjs'
 | 
			
		||||
import userAPI from './user'
 | 
			
		||||
import tableAPI from './table'
 | 
			
		||||
import { param2Obj } from '../src/utils'
 | 
			
		||||
 | 
			
		||||
// Fix an issue with setting withCredentials = true, cross-domain request lost cookies
 | 
			
		||||
// https://github.com/nuysoft/Mock/issues/300
 | 
			
		||||
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
 | 
			
		||||
Mock.XHR.prototype.send = function() {
 | 
			
		||||
  if (this.custom.xhr) {
 | 
			
		||||
    this.custom.xhr.withCredentials = this.withCredentials || false
 | 
			
		||||
import user from './user'
 | 
			
		||||
import table from './table'
 | 
			
		||||
 | 
			
		||||
const mocks = [
 | 
			
		||||
  ...user,
 | 
			
		||||
  ...table
 | 
			
		||||
]
 | 
			
		||||
 | 
			
		||||
// for front mock
 | 
			
		||||
// please use it cautiously, it will redefine XMLHttpRequest,
 | 
			
		||||
// which will cause many of your third-party libraries to be invalidated(like progress event).
 | 
			
		||||
export function mockXHR() {
 | 
			
		||||
  // mock patch
 | 
			
		||||
  // https://github.com/nuysoft/Mock/issues/300
 | 
			
		||||
  Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
 | 
			
		||||
  Mock.XHR.prototype.send = function() {
 | 
			
		||||
    if (this.custom.xhr) {
 | 
			
		||||
      this.custom.xhr.withCredentials = this.withCredentials || false
 | 
			
		||||
 | 
			
		||||
      if (this.responseType) {
 | 
			
		||||
        this.custom.xhr.responseType = this.responseType
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    this.proxy_send(...arguments)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function XHR2ExpressReqWrap(respond) {
 | 
			
		||||
    return function(options) {
 | 
			
		||||
      let result = null
 | 
			
		||||
      if (respond instanceof Function) {
 | 
			
		||||
        const { body, type, url } = options
 | 
			
		||||
        // https://expressjs.com/en/4x/api.html#req
 | 
			
		||||
        result = respond({
 | 
			
		||||
          method: type,
 | 
			
		||||
          body: JSON.parse(body),
 | 
			
		||||
          query: param2Obj(url)
 | 
			
		||||
        })
 | 
			
		||||
      } else {
 | 
			
		||||
        result = respond
 | 
			
		||||
      }
 | 
			
		||||
      return Mock.mock(result)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (const i of mocks) {
 | 
			
		||||
    Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))
 | 
			
		||||
  }
 | 
			
		||||
  this.proxy_send(...arguments)
 | 
			
		||||
}
 | 
			
		||||
// Mock.setup({
 | 
			
		||||
//   timeout: '350-600'
 | 
			
		||||
// })
 | 
			
		||||
 | 
			
		||||
// User
 | 
			
		||||
Mock.mock(/\/user\/login/, 'post', userAPI.login)
 | 
			
		||||
Mock.mock(/\/user\/info/, 'get', userAPI.getInfo)
 | 
			
		||||
Mock.mock(/\/user\/logout/, 'post', userAPI.logout)
 | 
			
		||||
// for mock server
 | 
			
		||||
const responseFake = (url, type, respond) => {
 | 
			
		||||
  return {
 | 
			
		||||
    url: new RegExp(`/mock${url}`),
 | 
			
		||||
    type: type || 'get',
 | 
			
		||||
    response(req, res) {
 | 
			
		||||
      res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Table
 | 
			
		||||
Mock.mock(/\/table\/list/, 'get', tableAPI.list)
 | 
			
		||||
 | 
			
		||||
export default Mock
 | 
			
		||||
export default mocks.map(route => {
 | 
			
		||||
  return responseFake(route.url, route.type, route.response)
 | 
			
		||||
})
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										64
									
								
								mock/mock-server.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								mock/mock-server.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
const chokidar = require('chokidar')
 | 
			
		||||
const bodyParser = require('body-parser')
 | 
			
		||||
const chalk = require('chalk')
 | 
			
		||||
const path = require('path')
 | 
			
		||||
 | 
			
		||||
const mockDir = path.join(process.cwd(), 'mock')
 | 
			
		||||
 | 
			
		||||
function registerRoutes(app) {
 | 
			
		||||
  let mockLastIndex
 | 
			
		||||
  const { default: mocks } = require('./index.js')
 | 
			
		||||
  for (const mock of mocks) {
 | 
			
		||||
    app[mock.type](mock.url, mock.response)
 | 
			
		||||
    mockLastIndex = app._router.stack.length
 | 
			
		||||
  }
 | 
			
		||||
  const mockRoutesLength = Object.keys(mocks).length
 | 
			
		||||
  return {
 | 
			
		||||
    mockRoutesLength: mockRoutesLength,
 | 
			
		||||
    mockStartIndex: mockLastIndex - mockRoutesLength
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function unregisterRoutes() {
 | 
			
		||||
  Object.keys(require.cache).forEach(i => {
 | 
			
		||||
    if (i.includes(mockDir)) {
 | 
			
		||||
      delete require.cache[require.resolve(i)]
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
module.exports = app => {
 | 
			
		||||
  // es6 polyfill
 | 
			
		||||
  require('@babel/register')
 | 
			
		||||
 | 
			
		||||
  // parse app.body
 | 
			
		||||
  // https://expressjs.com/en/4x/api.html#req.body
 | 
			
		||||
  app.use(bodyParser.json())
 | 
			
		||||
  app.use(bodyParser.urlencoded({
 | 
			
		||||
    extended: true
 | 
			
		||||
  }))
 | 
			
		||||
 | 
			
		||||
  const mockRoutes = registerRoutes(app)
 | 
			
		||||
  var mockRoutesLength = mockRoutes.mockRoutesLength
 | 
			
		||||
  var mockStartIndex = mockRoutes.mockStartIndex
 | 
			
		||||
 | 
			
		||||
  // watch files, hot reload mock server
 | 
			
		||||
  chokidar.watch(mockDir, {
 | 
			
		||||
    ignored: /mock-server/,
 | 
			
		||||
    ignoreInitial: true
 | 
			
		||||
  }).on('all', (event, path) => {
 | 
			
		||||
    if (event === 'change' || event === 'add') {
 | 
			
		||||
      // remove mock routes stack
 | 
			
		||||
      app._router.stack.splice(mockStartIndex, mockRoutesLength)
 | 
			
		||||
 | 
			
		||||
      // clear routes cache
 | 
			
		||||
      unregisterRoutes()
 | 
			
		||||
 | 
			
		||||
      const mockRoutes = registerRoutes(app)
 | 
			
		||||
      mockRoutesLength = mockRoutes.mockRoutesLength
 | 
			
		||||
      mockStartIndex = mockRoutes.mockStartIndex
 | 
			
		||||
 | 
			
		||||
      console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed  ${path}`))
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +1,29 @@
 | 
			
		||||
import Mock from 'mockjs'
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  list: () => {
 | 
			
		||||
    const items = Mock.mock({
 | 
			
		||||
      'items|30': [{
 | 
			
		||||
        id: '@id',
 | 
			
		||||
        title: '@sentence(10, 20)',
 | 
			
		||||
        'status|1': ['published', 'draft', 'deleted'],
 | 
			
		||||
        author: 'name',
 | 
			
		||||
        display_time: '@datetime',
 | 
			
		||||
        pageviews: '@integer(300, 5000)'
 | 
			
		||||
      }]
 | 
			
		||||
    })
 | 
			
		||||
    return {
 | 
			
		||||
      code: 20000,
 | 
			
		||||
      data: items
 | 
			
		||||
const data = Mock.mock({
 | 
			
		||||
  'items|30': [{
 | 
			
		||||
    id: '@id',
 | 
			
		||||
    title: '@sentence(10, 20)',
 | 
			
		||||
    'status|1': ['published', 'draft', 'deleted'],
 | 
			
		||||
    author: 'name',
 | 
			
		||||
    display_time: '@datetime',
 | 
			
		||||
    pageviews: '@integer(300, 5000)'
 | 
			
		||||
  }]
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
export default [
 | 
			
		||||
  {
 | 
			
		||||
    url: '/table/list',
 | 
			
		||||
    type: 'get',
 | 
			
		||||
    response: config => {
 | 
			
		||||
      const items = data.items
 | 
			
		||||
      return {
 | 
			
		||||
        code: 20000,
 | 
			
		||||
        data: {
 | 
			
		||||
          total: items.length,
 | 
			
		||||
          items: items
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
]
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										68
									
								
								mock/user.js
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								mock/user.js
									
									
									
									
									
								
							@@ -1,4 +1,3 @@
 | 
			
		||||
import { param2Obj } from './utils'
 | 
			
		||||
 | 
			
		||||
const tokens = {
 | 
			
		||||
  admin: {
 | 
			
		||||
@@ -24,41 +23,62 @@ const users = {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
  login: res => {
 | 
			
		||||
    const { username } = JSON.parse(res.body)
 | 
			
		||||
    const data = tokens[username]
 | 
			
		||||
export default [
 | 
			
		||||
  // user login
 | 
			
		||||
  {
 | 
			
		||||
    url: '/user/login',
 | 
			
		||||
    type: 'post',
 | 
			
		||||
    response: config => {
 | 
			
		||||
      const { username } = config.body
 | 
			
		||||
      const token = tokens[username]
 | 
			
		||||
 | 
			
		||||
      // mock error
 | 
			
		||||
      if (!token) {
 | 
			
		||||
        return {
 | 
			
		||||
          code: 60204,
 | 
			
		||||
          message: 'Account and password are incorrect.'
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    if (data) {
 | 
			
		||||
      return {
 | 
			
		||||
        code: 20000,
 | 
			
		||||
        data
 | 
			
		||||
        data: token
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return {
 | 
			
		||||
      code: 60204,
 | 
			
		||||
      message: 'Account and password are incorrect.'
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  getInfo: res => {
 | 
			
		||||
    const { token } = param2Obj(res.url)
 | 
			
		||||
    const info = users[token]
 | 
			
		||||
 | 
			
		||||
    if (info) {
 | 
			
		||||
  // get user info
 | 
			
		||||
  {
 | 
			
		||||
    url: '/user/info\.*',
 | 
			
		||||
    type: 'get',
 | 
			
		||||
    response: config => {
 | 
			
		||||
      const { token } = config.query
 | 
			
		||||
      const info = users[token]
 | 
			
		||||
 | 
			
		||||
      // mock error
 | 
			
		||||
      if (!info) {
 | 
			
		||||
        return {
 | 
			
		||||
          code: 50008,
 | 
			
		||||
          message: 'Login failed, unable to get user details.'
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return {
 | 
			
		||||
        code: 20000,
 | 
			
		||||
        data: info
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    return {
 | 
			
		||||
      code: 50008,
 | 
			
		||||
      message: 'Login failed, unable to get user details.'
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  logout: () => {
 | 
			
		||||
    return {
 | 
			
		||||
      code: 20000,
 | 
			
		||||
      data: 'success'
 | 
			
		||||
 | 
			
		||||
  // user logout
 | 
			
		||||
  {
 | 
			
		||||
    url: '/user/logout',
 | 
			
		||||
    type: 'post',
 | 
			
		||||
    response: _ => {
 | 
			
		||||
      return {
 | 
			
		||||
        code: 20000,
 | 
			
		||||
        data: 'success'
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
]
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
export function param2Obj(url) {
 | 
			
		||||
  const search = url.split('?')[1]
 | 
			
		||||
  if (!search) {
 | 
			
		||||
    return {}
 | 
			
		||||
  }
 | 
			
		||||
  return JSON.parse(
 | 
			
		||||
    '{"' +
 | 
			
		||||
      decodeURIComponent(search)
 | 
			
		||||
        .replace(/"/g, '\\"')
 | 
			
		||||
        .replace(/&/g, '","')
 | 
			
		||||
        .replace(/=/g, '":"') +
 | 
			
		||||
      '"}'
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user