Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

rollup-plugin-serve

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

rollup-plugin-serve - npm Package Compare versions

Comparing version 1.0.1 to 2.0.0-beta.0

318

dist/index.cjs.js

@@ -5,3 +5,8 @@ 'use strict';

var fs = require('fs');
var Express = _interopDefault(require('express'));
var killable = _interopDefault(require('killable'));
var compress = _interopDefault(require('compression'));
var serveIndex = _interopDefault(require('serve-index'));
var historyApiFallback = _interopDefault(require('connect-history-api-fallback'));
var httpProxyMiddleware = require('http-proxy-middleware');
var https = require('https');

@@ -14,2 +19,3 @@ var http = require('http');

var server;
var app;

@@ -26,4 +32,4 @@ /**

}
options.contentBase = Array.isArray(options.contentBase) ? options.contentBase : [options.contentBase];
options.host = options.host || 'localhost';
options.contentBase = Array.isArray(options.contentBase) ? options.contentBase : [options.contentBase || ''];
options.contentBasePublicPath = options.contentBasePublicPath || '/';
options.port = options.port || 10001;

@@ -33,52 +39,249 @@ options.headers = options.headers || {};

options.openPage = options.openPage || '';
options.compress = !!options.compress;
options.serveIndex = options.serveIndex || (options.serveIndex === undefined);
mime.default_type = 'text/plain';
var requestListener = function (request, response) {
// Remove querystring
var urlPath = decodeURI(request.url.split('?')[0]);
function setupProxy () {
/**
* Assume a proxy configuration specified as:
* proxy: {
* 'context': { options }
* }
* OR
* proxy: {
* 'context': 'target'
* }
*/
if (!Array.isArray(options.proxy)) {
if (Object.prototype.hasOwnProperty.call(options.proxy, 'target')) {
options.proxy = [options.proxy];
} else {
options.proxy = Object.keys(options.proxy).map(function (context) {
var proxyOptions;
// For backwards compatibility reasons.
var correctedContext = context
.replace(/^\*$/, '**')
.replace(/\/\*$/, '');
Object.keys(options.headers).forEach(function (key) {
response.setHeader(key, options.headers[key]);
if (typeof options.proxy[context] === 'string') {
proxyOptions = {
context: correctedContext,
target: options.proxy[context]
};
} else {
proxyOptions = Object.assign({}, options.proxy[context]);
proxyOptions.context = correctedContext;
}
proxyOptions.logLevel = proxyOptions.logLevel || 'warn';
return proxyOptions
});
}
}
var getProxyMiddleware = function (proxyConfig) {
var context = proxyConfig.context || proxyConfig.path;
// It is possible to use the `bypass` method without a `target`.
// However, the proxy middleware has no use in this case, and will fail to instantiate.
if (proxyConfig.target) {
return httpProxyMiddleware.createProxyMiddleware(context, proxyConfig)
}
};
/**
* Assume a proxy configuration specified as:
* proxy: [
* {
* context: ...,
* ...options...
* },
* // or:
* function() {
* return {
* context: ...,
* ...options...
* };
* }
* ]
*/
options.proxy.forEach(function (proxyConfigOrCallback) {
var proxyMiddleware;
var proxyConfig =
typeof proxyConfigOrCallback === 'function'
? proxyConfigOrCallback()
: proxyConfigOrCallback;
proxyMiddleware = getProxyMiddleware(proxyConfig);
function proxyHandle (req, res, next) {
if (typeof proxyConfigOrCallback === 'function') {
var newProxyConfig = proxyConfigOrCallback();
if (newProxyConfig !== proxyConfig) {
proxyConfig = newProxyConfig;
proxyMiddleware = getProxyMiddleware(proxyConfig);
}
}
// - Check if we have a bypass function defined
// - In case the bypass function is defined we'll retrieve the
// bypassUrl from it otherwise bypassUrl would be null
var isByPassFuncDefined = typeof proxyConfig.bypass === 'function';
var bypassUrl = isByPassFuncDefined
? proxyConfig.bypass(req, res, proxyConfig)
: null;
if (typeof bypassUrl === 'boolean') {
// skip the proxy
req.url = null;
next();
} else if (typeof bypassUrl === 'string') {
// byPass to that url
req.url = bypassUrl;
next();
} else if (proxyMiddleware) {
return proxyMiddleware(req, res, next)
} else {
next();
}
}
app.use(proxyHandle);
// Also forward error requests to the proxy so it can handle them.
// eslint-disable-next-line handle-callback-err
app.use(function (error, req, res, next) { return proxyHandle(req, res, next); });
});
}
readFileFromContentBase(options.contentBase, urlPath, function (error, content, filePath) {
if (!error) {
return found(response, filePath, content)
// release previous server instance if rollup is reloading configuration in watch mode
if (server) {
server.kill();
} else {
closeServerOnTermination();
}
app = new Express();
// Implement webpack-dev-server features
var features = {
compress: function () {
if (options.compress) {
app.use(compress());
}
if (error.code !== 'ENOENT') {
response.writeHead(500);
response.end('500 Internal Server Error' +
'\n\n' + filePath +
'\n\n' + Object.values(error).join('\n') +
'\n\n(rollup-plugin-serve)', 'utf-8');
return
},
proxy: function () {
if (options.proxy) {
setupProxy();
}
},
historyApiFallback: function () {
if (options.historyApiFallback) {
var fallbackPath = typeof options.historyApiFallback === 'string' ? options.historyApiFallback : '/index.html';
readFileFromContentBase(options.contentBase, fallbackPath, function (error, content, filePath) {
if (error) {
notFound(response, filePath);
} else {
found(response, filePath, content);
}
var fallback =
typeof options.historyApiFallback === 'object'
? options.historyApiFallback
: typeof options.historyApiFallback === 'string'
? { index: options.historyApiFallback, disableDotRule: true } : null;
app.use(historyApiFallback(fallback));
}
},
contentBaseFiles: function () {
if (Array.isArray(options.contentBase)) {
options.contentBase.forEach(function (item) {
app.use(options.contentBasePublicPath, Express.static(item));
});
} else {
notFound(response, filePath);
app.use(
options.contentBasePublicPath,
Express.static(options.contentBase, options.staticOptions)
);
}
});
},
contentBaseIndex: function () {
if (options.contentBase && options.serveIndex) {
var getHandler = function (item) { return function indexHandler (req, res, next) {
// serve-index doesn't fallthrough non-get/head request to next middleware
if (req.method !== 'GET' && req.method !== 'HEAD') {
return next()
}
serveIndex(item)(req, res, next);
}; };
if (Array.isArray(options.contentBase)) {
options.contentBase.forEach(function (item) {
app.use(options.contentBasePublicPath, getHandler(item));
});
} else {
app.use(options.contentBasePublicPath, getHandler(options.contentBase));
}
}
},
before: function () {
if (typeof options.before === 'function') {
options.before(app);
}
},
after: function () {
if (typeof options.after === 'function') {
options.after(app);
}
},
headers: function () {
app.all('*', function headersHandler (req, res, next) {
if (options.headers) {
for (var name in options.headers) {
res.setHeader(name, options.headers[name]);
}
}
next();
});
}
};
// release previous server instance if rollup is reloading configuration in watch mode
if (server) {
server.close();
var runnableFeatures = [];
if (options.compress) {
runnableFeatures.push('compress');
}
runnableFeatures.push('before', 'headers');
if (options.proxy) {
runnableFeatures.push('proxy');
}
if (options.contentBase !== false) {
runnableFeatures.push('contentBaseFiles');
}
if (options.historyApiFallback) {
runnableFeatures.push('historyApiFallback');
if (options.contentBase !== false) {
runnableFeatures.push('contentBaseFiles');
}
}
if (options.contentBase && options.serveIndex) {
runnableFeatures.push('contentBaseIndex');
}
if (options.after) {
runnableFeatures.push('after');
}
(options.features || runnableFeatures).forEach(function (feature) {
features[feature]();
});
// If HTTPS options are available, create an HTTPS server
if (options.https) {
server = https.createServer(options.https, requestListener).listen(options.port, options.host);
server = https.createServer(options.https, app).listen(options.port, options.host);
} else {
server = http.createServer(requestListener).listen(options.port, options.host);
server = http.createServer(app).listen(options.port, options.host);
}
closeServerOnTermination(server);
killable(server);

@@ -94,3 +297,3 @@ var running = options.verbose === false;

// Log which url to visit
var url = (options.https ? 'https' : 'http') + '://' + options.host + ':' + options.port;
var url = (options.https ? 'https' : 'http') + '://' + (options.host || 'localhost') + ':' + options.port;
options.contentBase.forEach(function (base) {

@@ -102,3 +305,7 @@ console.log(green(url) + ' -> ' + path.resolve(base));

if (options.open) {
opener(url + options.openPage);
if (/https?:\/\/.+/.test(options.openPage)) {
opener(options.openPage);
} else {
opener(url + options.openPage);
}
}

@@ -110,33 +317,2 @@ }

function readFileFromContentBase (contentBase, urlPath, callback) {
var filePath = path.resolve(contentBase[0] || '.', '.' + urlPath);
// Load index.html in directories
if (urlPath.endsWith('/')) {
filePath = path.resolve(filePath, 'index.html');
}
fs.readFile(filePath, function (error, content) {
if (error && contentBase.length > 1) {
// Try to read from next contentBase
readFileFromContentBase(contentBase.slice(1), urlPath, callback);
} else {
// We know enough
callback(error, content, filePath);
}
});
}
function notFound (response, filePath) {
response.writeHead(404);
response.end('404 Not Found' +
'\n\n' + filePath +
'\n\n(rollup-plugin-serve)', 'utf-8');
}
function found (response, filePath, content) {
response.writeHead(200, { 'Content-Type': mime.getType(filePath) });
response.end(content, 'utf-8');
}
function green (text) {

@@ -146,8 +322,10 @@ return '\u001b[1m\u001b[32m' + text + '\u001b[39m\u001b[22m'

function closeServerOnTermination (server) {
var terminationSignals = ['SIGINT', 'SIGTERM'];
function closeServerOnTermination () {
var terminationSignals = ['SIGINT', 'SIGTERM', 'SIGQUIT', 'SIGHUP'];
terminationSignals.forEach(function (signal) {
process.on(signal, function () {
server.close();
process.exit();
if (server) {
server.kill();
process.exit();
}
});

@@ -154,0 +332,0 @@ });

@@ -1,2 +0,7 @@

import { readFile } from 'fs';
import Express from 'express';
import killable from 'killable';
import compress from 'compression';
import serveIndex from 'serve-index';
import historyApiFallback from 'connect-history-api-fallback';
import { createProxyMiddleware } from 'http-proxy-middleware';
import { createServer } from 'https';

@@ -9,2 +14,3 @@ import { createServer as createServer$1 } from 'http';

var server;
var app;

@@ -21,4 +27,4 @@ /**

}
options.contentBase = Array.isArray(options.contentBase) ? options.contentBase : [options.contentBase];
options.host = options.host || 'localhost';
options.contentBase = Array.isArray(options.contentBase) ? options.contentBase : [options.contentBase || ''];
options.contentBasePublicPath = options.contentBasePublicPath || '/';
options.port = options.port || 10001;

@@ -28,52 +34,249 @@ options.headers = options.headers || {};

options.openPage = options.openPage || '';
options.compress = !!options.compress;
options.serveIndex = options.serveIndex || (options.serveIndex === undefined);
mime.default_type = 'text/plain';
var requestListener = function (request, response) {
// Remove querystring
var urlPath = decodeURI(request.url.split('?')[0]);
function setupProxy () {
/**
* Assume a proxy configuration specified as:
* proxy: {
* 'context': { options }
* }
* OR
* proxy: {
* 'context': 'target'
* }
*/
if (!Array.isArray(options.proxy)) {
if (Object.prototype.hasOwnProperty.call(options.proxy, 'target')) {
options.proxy = [options.proxy];
} else {
options.proxy = Object.keys(options.proxy).map(function (context) {
var proxyOptions;
// For backwards compatibility reasons.
var correctedContext = context
.replace(/^\*$/, '**')
.replace(/\/\*$/, '');
Object.keys(options.headers).forEach(function (key) {
response.setHeader(key, options.headers[key]);
if (typeof options.proxy[context] === 'string') {
proxyOptions = {
context: correctedContext,
target: options.proxy[context]
};
} else {
proxyOptions = Object.assign({}, options.proxy[context]);
proxyOptions.context = correctedContext;
}
proxyOptions.logLevel = proxyOptions.logLevel || 'warn';
return proxyOptions
});
}
}
var getProxyMiddleware = function (proxyConfig) {
var context = proxyConfig.context || proxyConfig.path;
// It is possible to use the `bypass` method without a `target`.
// However, the proxy middleware has no use in this case, and will fail to instantiate.
if (proxyConfig.target) {
return createProxyMiddleware(context, proxyConfig)
}
};
/**
* Assume a proxy configuration specified as:
* proxy: [
* {
* context: ...,
* ...options...
* },
* // or:
* function() {
* return {
* context: ...,
* ...options...
* };
* }
* ]
*/
options.proxy.forEach(function (proxyConfigOrCallback) {
var proxyMiddleware;
var proxyConfig =
typeof proxyConfigOrCallback === 'function'
? proxyConfigOrCallback()
: proxyConfigOrCallback;
proxyMiddleware = getProxyMiddleware(proxyConfig);
function proxyHandle (req, res, next) {
if (typeof proxyConfigOrCallback === 'function') {
var newProxyConfig = proxyConfigOrCallback();
if (newProxyConfig !== proxyConfig) {
proxyConfig = newProxyConfig;
proxyMiddleware = getProxyMiddleware(proxyConfig);
}
}
// - Check if we have a bypass function defined
// - In case the bypass function is defined we'll retrieve the
// bypassUrl from it otherwise bypassUrl would be null
var isByPassFuncDefined = typeof proxyConfig.bypass === 'function';
var bypassUrl = isByPassFuncDefined
? proxyConfig.bypass(req, res, proxyConfig)
: null;
if (typeof bypassUrl === 'boolean') {
// skip the proxy
req.url = null;
next();
} else if (typeof bypassUrl === 'string') {
// byPass to that url
req.url = bypassUrl;
next();
} else if (proxyMiddleware) {
return proxyMiddleware(req, res, next)
} else {
next();
}
}
app.use(proxyHandle);
// Also forward error requests to the proxy so it can handle them.
// eslint-disable-next-line handle-callback-err
app.use(function (error, req, res, next) { return proxyHandle(req, res, next); });
});
}
readFileFromContentBase(options.contentBase, urlPath, function (error, content, filePath) {
if (!error) {
return found(response, filePath, content)
// release previous server instance if rollup is reloading configuration in watch mode
if (server) {
server.kill();
} else {
closeServerOnTermination();
}
app = new Express();
// Implement webpack-dev-server features
var features = {
compress: function () {
if (options.compress) {
app.use(compress());
}
if (error.code !== 'ENOENT') {
response.writeHead(500);
response.end('500 Internal Server Error' +
'\n\n' + filePath +
'\n\n' + Object.values(error).join('\n') +
'\n\n(rollup-plugin-serve)', 'utf-8');
return
},
proxy: function () {
if (options.proxy) {
setupProxy();
}
},
historyApiFallback: function () {
if (options.historyApiFallback) {
var fallbackPath = typeof options.historyApiFallback === 'string' ? options.historyApiFallback : '/index.html';
readFileFromContentBase(options.contentBase, fallbackPath, function (error, content, filePath) {
if (error) {
notFound(response, filePath);
} else {
found(response, filePath, content);
}
var fallback =
typeof options.historyApiFallback === 'object'
? options.historyApiFallback
: typeof options.historyApiFallback === 'string'
? { index: options.historyApiFallback, disableDotRule: true } : null;
app.use(historyApiFallback(fallback));
}
},
contentBaseFiles: function () {
if (Array.isArray(options.contentBase)) {
options.contentBase.forEach(function (item) {
app.use(options.contentBasePublicPath, Express.static(item));
});
} else {
notFound(response, filePath);
app.use(
options.contentBasePublicPath,
Express.static(options.contentBase, options.staticOptions)
);
}
});
},
contentBaseIndex: function () {
if (options.contentBase && options.serveIndex) {
var getHandler = function (item) { return function indexHandler (req, res, next) {
// serve-index doesn't fallthrough non-get/head request to next middleware
if (req.method !== 'GET' && req.method !== 'HEAD') {
return next()
}
serveIndex(item)(req, res, next);
}; };
if (Array.isArray(options.contentBase)) {
options.contentBase.forEach(function (item) {
app.use(options.contentBasePublicPath, getHandler(item));
});
} else {
app.use(options.contentBasePublicPath, getHandler(options.contentBase));
}
}
},
before: function () {
if (typeof options.before === 'function') {
options.before(app);
}
},
after: function () {
if (typeof options.after === 'function') {
options.after(app);
}
},
headers: function () {
app.all('*', function headersHandler (req, res, next) {
if (options.headers) {
for (var name in options.headers) {
res.setHeader(name, options.headers[name]);
}
}
next();
});
}
};
// release previous server instance if rollup is reloading configuration in watch mode
if (server) {
server.close();
var runnableFeatures = [];
if (options.compress) {
runnableFeatures.push('compress');
}
runnableFeatures.push('before', 'headers');
if (options.proxy) {
runnableFeatures.push('proxy');
}
if (options.contentBase !== false) {
runnableFeatures.push('contentBaseFiles');
}
if (options.historyApiFallback) {
runnableFeatures.push('historyApiFallback');
if (options.contentBase !== false) {
runnableFeatures.push('contentBaseFiles');
}
}
if (options.contentBase && options.serveIndex) {
runnableFeatures.push('contentBaseIndex');
}
if (options.after) {
runnableFeatures.push('after');
}
(options.features || runnableFeatures).forEach(function (feature) {
features[feature]();
});
// If HTTPS options are available, create an HTTPS server
if (options.https) {
server = createServer(options.https, requestListener).listen(options.port, options.host);
server = createServer(options.https, app).listen(options.port, options.host);
} else {
server = createServer$1(requestListener).listen(options.port, options.host);
server = createServer$1(app).listen(options.port, options.host);
}
closeServerOnTermination(server);
killable(server);

@@ -89,3 +292,3 @@ var running = options.verbose === false;

// Log which url to visit
var url = (options.https ? 'https' : 'http') + '://' + options.host + ':' + options.port;
var url = (options.https ? 'https' : 'http') + '://' + (options.host || 'localhost') + ':' + options.port;
options.contentBase.forEach(function (base) {

@@ -97,3 +300,7 @@ console.log(green(url) + ' -> ' + resolve(base));

if (options.open) {
opener(url + options.openPage);
if (/https?:\/\/.+/.test(options.openPage)) {
opener(options.openPage);
} else {
opener(url + options.openPage);
}
}

@@ -105,33 +312,2 @@ }

function readFileFromContentBase (contentBase, urlPath, callback) {
var filePath = resolve(contentBase[0] || '.', '.' + urlPath);
// Load index.html in directories
if (urlPath.endsWith('/')) {
filePath = resolve(filePath, 'index.html');
}
readFile(filePath, function (error, content) {
if (error && contentBase.length > 1) {
// Try to read from next contentBase
readFileFromContentBase(contentBase.slice(1), urlPath, callback);
} else {
// We know enough
callback(error, content, filePath);
}
});
}
function notFound (response, filePath) {
response.writeHead(404);
response.end('404 Not Found' +
'\n\n' + filePath +
'\n\n(rollup-plugin-serve)', 'utf-8');
}
function found (response, filePath, content) {
response.writeHead(200, { 'Content-Type': mime.getType(filePath) });
response.end(content, 'utf-8');
}
function green (text) {

@@ -141,8 +317,10 @@ return '\u001b[1m\u001b[32m' + text + '\u001b[39m\u001b[22m'

function closeServerOnTermination (server) {
var terminationSignals = ['SIGINT', 'SIGTERM'];
function closeServerOnTermination () {
var terminationSignals = ['SIGINT', 'SIGTERM', 'SIGQUIT', 'SIGHUP'];
terminationSignals.forEach(function (signal) {
process.on(signal, function () {
server.close();
process.exit();
if (server) {
server.kill();
process.exit();
}
});

@@ -149,0 +327,0 @@ });

{
"name": "rollup-plugin-serve",
"version": "1.0.1",
"version": "2.0.0-beta.0",
"description": "Serve your rolled up bundle",

@@ -36,4 +36,10 @@ "main": "dist/index.cjs.js",

"dependencies": {
"compression": "^1.7.4",
"connect-history-api-fallback": "^1.6.0",
"express": "^4.17.1",
"http-proxy-middleware": "^1.0.0",
"killable": "^1.0.1",
"mime": ">=2.0.3",
"opener": "1"
"opener": "1",
"serve-index": "^1.9.1"
},

@@ -43,4 +49,4 @@ "devDependencies": {

"rollup-plugin-buble": "^0.15.0",
"standard": "12"
"standard": "14"
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc