UNPKG

3.77 kBJavaScriptView Raw
1"use strict";
2/**
3 * @license
4 * Copyright (c) 2015 The Polymer Project Authors. All rights reserved.
5 * This code may only be used under the BSD style license found at
6 * http://polymer.github.io/LICENSE.txt
7 * The complete set of authors may be found at
8 * http://polymer.github.io/AUTHORS.txt
9 * The complete set of contributors may be found at
10 * http://polymer.github.io/CONTRIBUTORS.txt
11 * Code distributed by Google as part of the polymer project is also
12 * subject to an additional IP rights grant found at
13 * http://polymer.github.io/PATENTS.txt
14 */
15Object.defineProperty(exports, "__esModule", { value: true });
16const escapeHtml = require("escape-html");
17const express = require("express");
18const path = require("path");
19const url_1 = require("url");
20const send = require("send");
21/**
22 * Make a polyserve express app.
23 * @param {Object} options
24 * @param {string} options.componentDir The directory to serve components from.
25 * @param {string} options.packageName A name for this polyserve package.
26 * @param {Object} options.headers An object keyed by header name containing
27 * header values.
28 * @param {string} options.root The root directory to serve a package from
29 * @return {Object} An express app which can be served with `app.get`
30 */
31function makeApp(options) {
32 const root = path.resolve(options.root);
33 const baseComponentDir = options.componentDir;
34 const componentDir = path.resolve(root, baseComponentDir);
35 const packageName = options.packageName;
36 const headers = options.headers || {};
37 if (packageName == null) {
38 throw new Error('packageName not provided');
39 }
40 const app = express();
41 app.get('*', (req, res) => {
42 // Serve local files from . and other components from bower_components
43 const url = url_1.parse(req.url, true);
44 let splitPath = url.pathname.split('/').slice(1);
45 const splitPackagePath = packageName.split('/');
46 if (arrayStartsWith(splitPath, splitPackagePath)) {
47 if (root) {
48 splitPath = [root].concat(splitPath.slice(splitPackagePath.length));
49 }
50 else {
51 splitPath = splitPath.slice(splitPackagePath.length);
52 }
53 }
54 else {
55 splitPath = [componentDir].concat(splitPath);
56 }
57 const filePath = splitPath.join('/');
58 if (headers) {
59 for (const header in headers) {
60 res.setHeader(header, headers[header]);
61 }
62 }
63 const _send = send(req, filePath, { etag: false, lastModified: false });
64 // Uncomment this to disable 304s from send(). This will make the
65 // compileMiddleware used in startServer always compile. Useful for testing
66 // and working on the compilation middleware.
67 // _send.isFresh = () => false;
68 // The custom redirect is needed becuase send() redirects to the
69 // _file_ path plus a leading slash, not the URL. :(
70 // https://github.com/pillarjs/send/issues/132
71 _send
72 .on('directory', () => {
73 res.statusCode = 301;
74 res.setHeader('Location', req.originalUrl + '/');
75 res.end('Redirecting to ' + req.originalUrl + '/');
76 })
77 .on('error', (err) => {
78 res.status(err.statusCode);
79 res.type('html');
80 res.end(escapeHtml(err.Error));
81 })
82 .pipe(res);
83 });
84 app.packageName = packageName;
85 return app;
86}
87exports.makeApp = makeApp;
88function arrayStartsWith(array, prefix) {
89 for (let i = 0; i < prefix.length; i++) {
90 if (i >= array.length || array[i] !== prefix[i]) {
91 return false;
92 }
93 }
94 return true;
95}
96//# sourceMappingURL=make_app.js.map
\No newline at end of file