1 | 'use strict';
|
2 |
|
3 | var path = require('path');
|
4 | var mime = require('mime');
|
5 | var debug = require('debug')('serve-spm:express');
|
6 | var urlparse = require('url').parse;
|
7 |
|
8 | var parse = require('./parse');
|
9 | var util = require('./util');
|
10 | var transport = require('./transport');
|
11 |
|
12 | module.exports = function(root, opts) {
|
13 | opts = opts || {};
|
14 | var log = opts.log || function() {};
|
15 | var ignore = Array.isArray(opts.ignore) ? opts.ignore : [];
|
16 |
|
17 | return function(req, res, next) {
|
18 | if (Array.isArray(opts.paths)) {
|
19 | opts.paths.forEach(function(p) {
|
20 | req.url = req.url.replace(p[0], p[1]);
|
21 | });
|
22 | }
|
23 |
|
24 | if (opts.base) {
|
25 | var basepath = urlparse(opts.base).pathname;
|
26 | basepath = basepath.replace(/\/$/, '');
|
27 | req.url = req.url.replace(basepath, '');
|
28 | }
|
29 |
|
30 | debug('parse url %s', req.url);
|
31 | var pkg = util.getPackage(root);
|
32 | var rootPkg = pkg;
|
33 | var match;
|
34 | if (pkg && (match = util.matchNameVersion(req.url))) {
|
35 | pkg = pkg.getPackage(match.name + '@' + match.version);
|
36 | }
|
37 | if (!pkg) {
|
38 | debug('can not find local module of %s', req.url);
|
39 | return next();
|
40 | }
|
41 |
|
42 | var file = parse(req.url, {
|
43 | pkg: pkg,
|
44 | rootPkg: rootPkg,
|
45 | rules: opts.rules
|
46 | });
|
47 |
|
48 | if (!file) {
|
49 | return next();
|
50 | }
|
51 |
|
52 |
|
53 | var modifiedTime = util.getModifiedTime(file);
|
54 | res.setHeader('Last-Modified', modifiedTime);
|
55 | if (!util.isModified(req.headers, modifiedTime)) {
|
56 | debug('file %s is not modified', file.path);
|
57 | res.writeHead(304);
|
58 | return res.end('');
|
59 | }
|
60 |
|
61 | log('>> ServeSPM %s < ./%s',
|
62 | file.url.pathname, path.relative(process.cwd(), file.path));
|
63 |
|
64 |
|
65 | if (!file.wrap || req.headers['x-requested-with'] === 'XMLHttpRequest') {
|
66 | debug('return unwrapped file %s', file.path);
|
67 | return end(file.contents, res, path.extname(file.path));
|
68 | }
|
69 |
|
70 | var opt = {
|
71 | pkg: pkg,
|
72 | ignore: ignore,
|
73 | base: opts.base
|
74 | };
|
75 | debug('return transported file %s', file.path);
|
76 | transport(file, opt, function(err, file) {
|
77 | var ext = path.extname(file.path);
|
78 | end(file.contents, res, ext);
|
79 | });
|
80 |
|
81 | function notFound() {
|
82 | res.writeHead(404);
|
83 | res.end('');
|
84 | }
|
85 | };
|
86 | };
|
87 |
|
88 | function end(data, res, extname) {
|
89 | if (['.tpl', '.json', '.handlebars'].indexOf(extname) > -1) {
|
90 | extname = '.js';
|
91 | }
|
92 | res.setHeader('Content-Type', mime.lookup(extname));
|
93 | res.writeHead(200);
|
94 | res.end(data);
|
95 | }
|