UNPKG

@quasarbright/projection

Version:

A static site generator that creates a beautiful, interactive gallery to showcase your coding projects. Features search, filtering, tags, responsive design, and an admin UI.

179 lines (173 loc) 6.28 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.serve = serve; const fs = __importStar(require("fs")); const path = __importStar(require("path")); const child_process_1 = require("child_process"); const logger_1 = require("../utils/logger"); const port_finder_1 = require("../utils/port-finder"); /** * Display help for the serve command */ function showServeHelp() { console.log(` Projection Serve - Serve Built Site USAGE: projection serve [options] DESCRIPTION: Serves the generated site with a local HTTP server. Use this to preview the built site before deployment. OPTIONS: --port <number> Server port (default: 8080) --open Open browser automatically --dir <path> Directory to serve (default: dist) --help Show this help message EXAMPLES: projection serve # Serve on port 8080 projection serve --port 3000 # Use custom port projection serve --open # Open browser automatically projection serve --dir public # Serve custom directory NOTE: Run 'projection build' first to generate the site. `); } /** * Serve command - serves the generated dist directory with a local HTTP server */ async function serve(options = {}) { if (options.help) { showServeHelp(); return; } const requestedPort = options.port || 8080; const userSuppliedPort = options.port !== undefined; const dir = options.dir || 'dist'; const shouldOpen = options.open || false; const distPath = path.resolve(process.cwd(), dir); // Check if dist directory exists if (!fs.existsSync(distPath)) { logger_1.Logger.newline(); logger_1.Logger.error(`Directory '${dir}' not found.`); logger_1.Logger.newline(); logger_1.Logger.info(`Run 'projection build' first to generate the site.`); logger_1.Logger.newline(); process.exit(1); } // Check if index.html exists const indexPath = path.join(distPath, 'index.html'); if (!fs.existsSync(indexPath)) { logger_1.Logger.newline(); logger_1.Logger.error(`No index.html found in '${dir}' directory.`); logger_1.Logger.newline(); logger_1.Logger.info(`Run 'projection build' first to generate the site.`); logger_1.Logger.newline(); process.exit(1); } // Find available port with fallback behavior let port; let portResult; try { portResult = await port_finder_1.PortFinder.findPortWithFallback(requestedPort, userSuppliedPort); port = portResult.port; } catch (error) { logger_1.Logger.newline(); logger_1.Logger.error(error.message); logger_1.Logger.newline(); process.exit(1); } logger_1.Logger.newline(); logger_1.Logger.header('🚀 Starting server'); logger_1.Logger.keyValue('Serving', distPath); // Show port fallback message if needed if (!portResult.wasRequested) { logger_1.Logger.newline(); logger_1.Logger.icon('⚠️', `Port ${requestedPort} was in use, using port ${port} instead`, '\x1b[33m'); } logger_1.Logger.keyValue('Server URL', `http://localhost:${port}`); if (shouldOpen) { logger_1.Logger.icon('🔗', 'Opening browser...', '\x1b[36m'); } logger_1.Logger.newline(); logger_1.Logger.dim('💡 Press Ctrl+C to stop the server'); logger_1.Logger.newline(); // Start http-server using npx const args = [ 'http-server', distPath, '-p', port.toString(), '-c-1', // Disable caching '--cors' // Enable CORS ]; if (shouldOpen) { args.push('-o'); } const serverProcess = (0, child_process_1.spawn)('npx', args, { stdio: 'inherit', shell: true }); // Handle process termination serverProcess.on('error', (error) => { logger_1.Logger.newline(); logger_1.Logger.error(`Failed to start server: ${error.message}`); logger_1.Logger.newline(); logger_1.Logger.info('Make sure you have Node.js installed.'); logger_1.Logger.newline(); process.exit(1); }); serverProcess.on('exit', (code) => { if (code !== 0 && code !== null) { logger_1.Logger.newline(); logger_1.Logger.error(`Server exited with code ${code}`); logger_1.Logger.newline(); process.exit(code); } }); // Handle Ctrl+C gracefully process.on('SIGINT', () => { logger_1.Logger.newline(); logger_1.Logger.newline(); logger_1.Logger.icon('👋', 'Shutting down server...', '\x1b[33m'); logger_1.Logger.newline(); serverProcess.kill('SIGINT'); process.exit(0); }); process.on('SIGTERM', () => { serverProcess.kill('SIGTERM'); process.exit(0); }); } //# sourceMappingURL=serve.js.map