1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 | const convert = require('koa-connect');
|
12 | const historyApiFallback = require('connect-history-api-fallback');
|
13 | const koaCompress = require('koa-compress');
|
14 | const koaStatic = require('koa-static');
|
15 | const onetime = require('onetime');
|
16 | const { createProxyMiddleware } = require('http-proxy-middleware');
|
17 |
|
18 | const { middleware: wsMiddleware } = require('./ws');
|
19 |
|
20 | let staticPaths = [];
|
21 |
|
22 | const render404 = (ctx) => {
|
23 | const faqUrl =
|
24 | 'https://github.com/shellscape/webpack-plugin-serve/blob/master/.github/FAQ.md#what-does-the-not-found--404-error-mean';
|
25 | const body = `<h1>Not Found / 404</h1>
|
26 | <p>
|
27 | You may be seeing this error due to misconfigured options.<br/>
|
28 | Please see <a href="${faqUrl}">this FAQ question</a> for information on possible causes and remedies.
|
29 | </p>
|
30 | <h2>Static Paths</h2>
|
31 | <code>${staticPaths.join('</code><code>')}</code>`;
|
32 | const css = `<style>
|
33 | @import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
|
34 |
|
35 | *, html {
|
36 | font-size: 10px;
|
37 | margin: 0;
|
38 | }
|
39 |
|
40 |
|
41 | body {
|
42 | background: #282d35;
|
43 | color: #fff;
|
44 | font-family: 'Open Sans', Helvetica, Arial, sans-serif;
|
45 | padding: 2rem;
|
46 | }
|
47 |
|
48 | h1 {
|
49 | font-size: 5rem;
|
50 | padding-bottom: 2rem;
|
51 | }
|
52 |
|
53 | p {
|
54 | color: #eee;
|
55 | font-size: 1.6rem;
|
56 | padding: 1rem 0 3rem 0;
|
57 | }
|
58 |
|
59 | a, a:visited, a:hover {
|
60 | color: #ffbd2e;
|
61 | font-size: 1.6rem;
|
62 | text-decoration: none;
|
63 | }
|
64 |
|
65 | h2 {
|
66 | color: #eee;
|
67 | font-size: 1.5rem;
|
68 | padding: 1rem 0;
|
69 | }
|
70 |
|
71 | code {
|
72 | color: #eee;
|
73 | font-size: 1.4rem;
|
74 | padding: 0.4rem 1rem;
|
75 | }
|
76 | </style>`;
|
77 | const html = `<!doctype><html><head>${css}</head><body>${body}</body></html>`;
|
78 |
|
79 | ctx.body = html;
|
80 | ctx.status = 404;
|
81 | };
|
82 |
|
83 | const getBuiltins = (app, options) => {
|
84 | const compress = (opts) => {
|
85 |
|
86 | if (opts || options.compress) {
|
87 | app.use(koaCompress(opts || options.compress));
|
88 | }
|
89 | };
|
90 |
|
91 | const four0four = (fn = () => {}) => {
|
92 | app.use(async (ctx, next) => {
|
93 | await next();
|
94 | if (ctx.status === 404) {
|
95 | render404(ctx);
|
96 | fn(ctx);
|
97 | }
|
98 | });
|
99 | };
|
100 |
|
101 | const headers = (reqHeaders) => {
|
102 | const headrs = reqHeaders || (options.headers || {});
|
103 | app.use(async (ctx, next) => {
|
104 | await next();
|
105 | for (const headr of Object.keys(headrs)) {
|
106 | ctx.set(headr, headrs[headr]);
|
107 | }
|
108 | });
|
109 | };
|
110 |
|
111 | const historyFallback = () => {
|
112 | if (options.historyFallback) {
|
113 |
|
114 |
|
115 | app.use(async (ctx, next) => {
|
116 | if (ctx.path.match(/^\/wps/)) {
|
117 | const { accept, ...reqHeaders } = ctx.request.header;
|
118 | ctx.request.header = reqHeaders;
|
119 | }
|
120 | await next();
|
121 | });
|
122 |
|
123 | app.use(convert(historyApiFallback(options.historyFallback)));
|
124 | }
|
125 | };
|
126 |
|
127 | const statik = (root, opts = {}) => {
|
128 | const paths = [].concat(root || options.static);
|
129 | staticPaths = paths;
|
130 | for (const path of paths) {
|
131 | app.use(koaStatic(path, opts));
|
132 | }
|
133 | };
|
134 |
|
135 | const proxy = (...args) => convert(createProxyMiddleware(...args));
|
136 | const websocket = () => app.use(wsMiddleware);
|
137 |
|
138 | proxy.skip = true;
|
139 |
|
140 |
|
141 |
|
142 | return {
|
143 | compress: onetime(compress),
|
144 | headers: onetime(headers),
|
145 | historyFallback: onetime(historyFallback),
|
146 | static: onetime(statik),
|
147 | websocket: onetime(websocket),
|
148 | proxy,
|
149 | four0four: onetime(four0four)
|
150 | };
|
151 | };
|
152 |
|
153 | module.exports = { getBuiltins };
|