UNPKG

2.89 kBJavaScriptView Raw
1'use strict';
2
3var path = require('path');
4var join = path.join;
5var mime = require('mime');
6var File = require('vinyl');
7var urlparse = require('url').parse;
8var debug = require('debug')('serve-spm:koa');
9
10var util = require('./util');
11var parse = require('./parse');
12var transport = require('./transport');
13
14module.exports = function(root, opts) {
15 opts = opts || {};
16 var log = opts.log || function() {};
17 var ignore = Array.isArray(opts.ignore) ? opts.ignore : [];
18
19 return function*(next) {
20 if (Array.isArray(opts.paths)) {
21 opts.paths.forEach(function(p) {
22 this.url = this.url.replace(p[0], p[1]);
23 }.bind(this));
24 }
25
26 if (opts.base) {
27 var basepath = urlparse(opts.base).pathname;
28 basepath = basepath.replace(/\/$/, '');
29 this.url = this.url.replace(basepath, '');
30 }
31
32 debug('parse url %s', this.url);
33 var pkg = util.getPackage(root);
34 var rootPkg = pkg;
35 var match;
36 if (pkg && (match = util.matchNameVersion(this.url))) {
37 pkg = pkg.getPackage(match.name + '@' + match.version);
38 }
39 if (!pkg) {
40 debug('can not find local module of %s', this.url);
41 return yield* next;
42 }
43
44 var file;
45 if (this.body) {
46 file = new File({
47 base: pkg.dest,
48 path: join(pkg.dest, this.url),
49 contents: new Buffer(this.body)
50 });
51 file.url = urlparse(this.url);
52 file.pkg = pkg;
53 file.wrap = true;
54 } else {
55 file = parse(this.url, {
56 rootPkg: rootPkg,
57 pkg: pkg,
58 rules: opts.rules
59 });
60 }
61
62 if (!file) {
63 debug('cat not find matched file of %s', this.url);
64 return yield* next;
65 }
66
67 if (opts.cache) {
68 var modifiedTime = util.getModifiedTime(file);
69 this.set('Last-Modified', modifiedTime);
70 if (!util.isModified(this.header, modifiedTime)) {
71 debug('file %s is not modified', file.path);
72 this.status = 304;
73 return;
74 }
75 }
76
77 log('>> ServeSPM %s < ./%s',
78 file.url.pathname, path.relative(process.cwd(), file.path));
79
80 // nowrap
81 var data, ext;
82 if (!file.wrap || this.headers['x-requested-with'] === 'XMLHttpRequest') {
83 debug('return unwrapped file %s', file.path);
84 data = file.contents;
85 ext = path.extname(file.path);
86 }
87
88 else {
89 // transport file
90 debug('return transported file %s', file.path);
91 file = yield transportThunk(file, {
92 pkg: pkg,
93 ignore: ignore,
94 base: opts.base
95 });
96 data = file.contents;
97 ext = path.extname(file.path);
98 }
99
100 if (['.tpl', '.json', '.handlebars'].indexOf(ext) > -1) {
101 ext = '.js';
102 }
103 this.set('Content-Type', mime.lookup(ext));
104 this.body = data;
105 this.status = 200;
106 };
107};
108
109module.exports.util = util;
110
111function transportThunk(file, opt) {
112 return function(cb) {
113 transport(file, opt, cb);
114 };
115}