index.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. const fs = require('fs').promises
  2. const path = require('path')
  3. const Koa = require('koa')
  4. const { pathToRegexp } = require('path-to-regexp')
  5. const cors = require('@koa/cors')
  6. const logger = require('koa-logger')
  7. const { Random, mock } = require('mockjs')
  8. const randexp = require('randexp').randexp
  9. const installSerializers = require('./serializers')
  10. const PORT = 4000
  11. const DATA_ROOT = 'api'
  12. const app = new Koa()
  13. Random.extend({
  14. phone: () => randexp(/^1[345798][0-9]{9}$/)
  15. })
  16. installSerializers(Random, mock)
  17. app.use(cors())
  18. app.use(logger())
  19. app.use(async (ctx) => {
  20. const request = ctx.request
  21. const method = request.method.toLowerCase()
  22. const pathname = request.path
  23. const routes = await traverseDir(DATA_ROOT)
  24. const matchedRoute = routes.find((route) => {
  25. const regexp = pathToRegexp(`/${route}`.replace(/\/_/g, '/:'))
  26. return regexp.test(pathname)
  27. })
  28. if (matchedRoute) {
  29. const filePath = path.join(__dirname, matchedRoute, `${method}.json`)
  30. const rawData = await fs.readFile(filePath)
  31. // ctx.append('authorization', 'basic test-token')
  32. ctx.body = mock(JSON.parse(rawData))
  33. } else {
  34. ctx.throw(404, `pathname or method not found: ${method} ${pathname}`)
  35. }
  36. })
  37. app.listen(PORT)
  38. // eslint-disable-next-line no-console
  39. console.log(`mock start at http://localhost:${PORT} port`)
  40. /**
  41. * list all dir path
  42. * @param {string} dir root path
  43. */
  44. async function traverseDir(dir) {
  45. const basePath = path.join(__dirname, `${dir}`)
  46. const fileList = await fs.readdir(basePath)
  47. const allFiles = []
  48. let hasCurrentDir = false
  49. for (const filename of fileList) {
  50. const filepath = path.join(basePath, filename)
  51. const stat = await fs.lstat(filepath)
  52. const unixFilePath = `${dir}/${filename}`
  53. if (stat.isDirectory()) {
  54. const subFiles = await traverseDir(unixFilePath)
  55. allFiles.push(...subFiles)
  56. } else if (!hasCurrentDir) {
  57. hasCurrentDir = true
  58. allFiles.push(dir)
  59. }
  60. }
  61. return allFiles
  62. }