UNPKG

2.15 kBJavaScriptView Raw
1'use strict'
2
3const path = require('path')
4const mm = require('micromatch')
5const mime = require('mime')
6const rename = require('rename-extension')
7const log = require('./log')
8const cache = require('./cache')
9const execute = require('./execute')
10const send = require('./send')
11
12/**
13 * Match and rewrite a request.
14 * @public
15 * @param {Array} routes - Array of route configurations.
16 * @param {String} srcPath - Path to the source folder.
17 * @returns {Function} Middleware for Browsersync.
18 */
19module.exports = function(routes, srcPath) {
20
21 return (req, res, next) => {
22
23 // Remove first character and query to convert URL to a relative path
24 const fileRoute = req.url.substr(1).split('?')[0]
25
26 // Generate an array of matching routes and use the first matching route only
27 const matches = routes.filter((route) => mm.isMatch(fileRoute, route.path))
28 const route = matches[0]
29
30 // Continue without a rewrite when no matching route has been found
31 if (route==null) return next()
32
33 // Use cached handler response when available
34 if (cache.get(fileRoute)!=null) {
35
36 log(`{cyan:Using cached handler: {magenta:${ route.name } {grey:${ fileRoute }`)
37
38 const cachedHandler = cache.get(fileRoute)
39
40 // Send file to browser
41 return send(res, cachedHandler.contentType, cachedHandler.data)
42
43 }
44
45 // Absolute path to the requested file
46 const filePath = path.join(srcPath, fileRoute)
47
48 // Load file with a different extension as filePath points to the target extension
49 const fileLoad = (() => {
50
51 // Check if fn exists
52 const hasFn = (typeof route.handler.in==='function')
53
54 return (hasFn===true ? rename(filePath, route.handler.in(route.opts)) : filePath)
55
56 })()
57
58 // Get mime type of request files
59 const contentType = mime.lookup(filePath)
60
61 // Execute handler
62 execute(route, fileRoute, fileLoad, false, (err, data) => {
63
64 if (err!=null) return next(err)
65
66 // Send file to browser
67 send(res, contentType, data)
68
69 // Cache the response of the handler
70 cache.set(fileRoute, {
71 contentType : contentType,
72 data : data,
73 cache : route.handler.cache
74 })
75
76 })
77
78 }
79
80}
\No newline at end of file