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.

202 lines (196 loc) 7.71 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.admin = admin; const path = __importStar(require("path")); const child_process_1 = require("child_process"); const server_1 = require("../admin/server"); const logger_1 = require("../utils/logger"); const project_file_finder_1 = require("../utils/project-file-finder"); const port_finder_1 = require("../utils/port-finder"); /** * Display help for the admin command */ function showAdminHelp() { console.log(` Projection Admin - Project Management Interface USAGE: projection admin [options] DESCRIPTION: Starts a web-based admin interface for managing your projects. Provides a visual editor with live preview of your portfolio site. OPTIONS: --port <number> Server port (default: 3000) --no-open Don't open browser automatically --projects <path> Path to projects file --config <path> Path to config file --help Show this help message EXAMPLES: projection admin # Start on port 3000 projection admin --port 3001 # Use custom port projection admin --no-open # Don't open browser projection admin --projects data.yaml # Custom projects file FEATURES: • Visual project editor with form validation • Live preview of your portfolio site • Image upload and management • Tag management • Configuration editor • Deploy to GitHub Pages `); } /** * Open a URL in the default browser */ function openBrowser(url) { const platform = process.platform; let command; if (platform === 'darwin') { command = 'open'; } else if (platform === 'win32') { command = 'start'; } else { command = 'xdg-open'; } const child = (0, child_process_1.spawn)(command, [url], { stdio: 'ignore', detached: true, shell: platform === 'win32' }); child.unref(); } /** * Admin command - starts the admin server for managing projects */ async function admin(options = {}) { if (options.help) { showAdminHelp(); return; } try { const cwd = process.cwd(); // Parse port option (can be string or number from CLI) const requestedPort = options.port ? parseInt(options.port.toString(), 10) : 3000; const userSuppliedPort = options.port !== undefined; if (isNaN(requestedPort) || requestedPort < 1 || requestedPort > 65535) { logger_1.Logger.newline(); logger_1.Logger.error(`Invalid port number: ${options.port}`); logger_1.Logger.newline(); logger_1.Logger.info('Port must be a number between 1 and 65535.'); logger_1.Logger.newline(); process.exit(1); } // Find available port with fallback behavior const portResult = await port_finder_1.PortFinder.findPortWithFallback(requestedPort, userSuppliedPort); const port = portResult.port; // Determine if browser should auto-open // Default is true unless --no-open is specified const shouldOpen = options.noOpen ? false : (options.open !== false); // Find projects file using shared utility const projectFileResult = project_file_finder_1.ProjectFileFinder.resolve(cwd, options.projects); if (!projectFileResult) { logger_1.Logger.newline(); if (options.projects) { logger_1.Logger.error(`Projects file not found: ${options.projects}`); } else { logger_1.Logger.error('No projects file found.'); logger_1.Logger.newline(); logger_1.Logger.info(`Expected one of: ${project_file_finder_1.ProjectFileFinder.getSupportedFileNames().join(', ')}`); } logger_1.Logger.newline(); logger_1.Logger.info('Run \'projection init\' to create a new project.'); logger_1.Logger.newline(); process.exit(1); } const projectsFilePath = projectFileResult.path; // Resolve config file path if provided const configFilePath = options.config ? path.resolve(cwd, options.config) : undefined; // Create admin server configuration const serverConfig = { port, projectsFilePath, configFilePath, autoOpen: shouldOpen, cors: true }; // Display startup message logger_1.Logger.newline(); logger_1.Logger.header('🚀 Starting Admin Server'); logger_1.Logger.keyValue('Projects file', projectsFilePath); // 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 the admin server const { port: actualPort } = await (0, server_1.startAdminServer)(serverConfig); // Open browser if requested if (shouldOpen) { // Small delay to ensure server is ready setTimeout(() => { openBrowser(`http://localhost:${actualPort}`); }, 500); } } catch (error) { logger_1.Logger.newline(); if (error.message && error.message.includes('already in use')) { logger_1.Logger.error(error.message); logger_1.Logger.newline(); logger_1.Logger.info('Try using a different port with --port flag:'); logger_1.Logger.dim(' projection admin --port 3001'); } else { logger_1.Logger.error(`Failed to start admin server: ${error.message}`); logger_1.Logger.newline(); logger_1.Logger.dim('Please check the error message above for details.'); } logger_1.Logger.newline(); process.exit(1); } } //# sourceMappingURL=admin.js.map