diff --git a/cli.js b/cli.js index beac9d2..0abbd63 100755 --- a/cli.js +++ b/cli.js @@ -21,6 +21,16 @@ const open = : 'xdg-open'; (async () => { + // Merging --extern arguments with it's next value to avoid messing with positional values + + for (let i = 0; i < process.argv.length; i++) { + const arg = process.argv[i] + if (arg === '--extern') { + process.argv[i] = arg + '=' + process.argv[i + 1] + process.argv.splice(i + 1, 1) + } + } + const args = process.argv.slice(2).filter((x) => !~x.indexOf('--')); const admin = process.getuid && process.getuid() === 0; let credentials; @@ -74,6 +84,10 @@ const open = // Parse arguments from the command line + const extern = process.argv + .filter((x) => x.indexOf('--extern') === 0) + .map((x) => x.split('=', 2)[1]) + const { root, protocol, port, ips, url } = await servor({ root: args[0], fallback: args[1], @@ -81,6 +95,7 @@ const open = reload: !!~process.argv.indexOf('--reload'), module: !!~process.argv.indexOf('--module'), static: !!~process.argv.indexOf('--static'), + extern, credentials, }); diff --git a/servor.js b/servor.js index bc3b52b..919056e 100644 --- a/servor.js +++ b/servor.js @@ -17,6 +17,7 @@ module.exports = async ({ fallback = module ? 'index.js' : 'index.html', reload = true, static = false, + extern = [], inject = '', credentials, port, @@ -35,16 +36,20 @@ module.exports = async ({ // Configure globals - root = root.startsWith('/') ? root : path.join(process.cwd(), root); + const entrypoints = [root, ...extern]; - if (!fs.existsSync(root)) { - console.log(`[ERR] Root directory ${root} does not exist!`); - process.exit(); - } + for (const entrypoint of entrypoints) { + const root = entrypoint.startsWith('/') ? entrypoint : path.join(process.cwd(), entrypoint); - if (!fs.statSync(root).isDirectory()) { - console.log(`[ERR] Root directory "${root}" is not directory!`); - process.exit(); + if (!fs.existsSync(root)) { + console.log(`[ERR] Root directory ${root} does not exist!`); + process.exit(); + } + + if (!fs.statSync(root).isDirectory()) { + console.log(`[ERR] Root directory "${root}" is not directory!`); + process.exit(); + } } const reloadClients = []; @@ -113,9 +118,9 @@ module.exports = async ({ // Respond to requests with a file extension const serveStaticFile = (res, pathname) => { - const uri = path.join(root, pathname); + let uri = searchPath(pathname); + if (!uri) return sendError(res, 404); let ext = uri.replace(/^.*[\.\/\\]/, '').toLowerCase(); - if (!fs.existsSync(uri)) return sendError(res, 404); fs.readFile(uri, 'binary', (err, file) => err ? sendError(res, 500) : sendFile(res, 200, file, ext) ); @@ -125,9 +130,9 @@ module.exports = async ({ const serveRoute = (res, pathname) => { const index = static - ? path.join(root, pathname, fallback) - : path.join(root, fallback); - if (!fs.existsSync(index) || (pathname.endsWith('/') && pathname !== '/')) + ? searchPath(pathname, fallback) + : searchPath(fallback); + if (!index || (pathname.endsWith('/') && pathname !== '/')) return serveDirectoryListing(res, pathname); fs.readFile(index, 'binary', (err, file) => { if (err) return sendError(res, 500); @@ -142,13 +147,20 @@ module.exports = async ({ // Respond to requests with a trailing slash const serveDirectoryListing = (res, pathname) => { - const uri = path.join(root, pathname); + const uri = searchPath(pathname); if (!fs.existsSync(uri)) return sendError(res, 404); res.writeHead(200, { 'Content-Type': 'text/html' }); res.write(baseDoc(pathname) + directoryListing(uri) + livereload); res.end(); }; + const searchPath = (pathname, fallback = '') => { + for (const entrypoint of entrypoints) { + const uri = path.join(entrypoint, pathname, fallback); + if (fs.existsSync(uri)) return uri + } + } + // Start the server and route requests server((req, res) => {