Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions packages/atxp/src/help.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,21 @@ export function showHelp(): void {
console.log();

console.log(chalk.bold('Demo Options:'));
console.log(' ' + chalk.yellow('--verbose, -v') + ' ' + 'Show detailed logs');
console.log(' ' + chalk.yellow('--refresh') + ' ' + 'Force refresh the demo from GitHub');
console.log(' ' + chalk.yellow('--port, -p') + ' ' + 'Specify port number (default: 8016)');
console.log(' ' + chalk.yellow('--dir, -d') + ' ' + 'Specify demo directory (default: ~/.cache/atxp/demo)');
console.log(' ' + chalk.yellow('--verbose, -v') + ' ' + 'Show detailed logs');
console.log(' ' + chalk.yellow('--refresh') + ' ' + 'Force refresh the demo from GitHub');
console.log(' ' + chalk.yellow('--frontend-port, --fp') + ' ' + 'Specify frontend port (default: 8016)');
console.log(' ' + chalk.yellow('--backend-port, --bp') + ' ' + 'Specify backend port (default: 8017)');
console.log(' ' + chalk.yellow('--dir, -d') + ' ' + 'Specify demo directory (default: ~/.cache/atxp/demo)');
console.log();

console.log(chalk.bold('Examples:'));
console.log(' npx atxp demo # Run the demo with defaults');
console.log(' npx atxp demo # Run the demo with defaults (frontend: 8016, backend: 8017)');
console.log(' npx atxp demo --verbose # Run demo with detailed logs');
console.log(' npx atxp demo --port 3000 # Run demo on port 3000');
console.log(' npx atxp demo --frontend-port 4000 # Run demo with frontend on port 4000');
console.log(' npx atxp demo --backend-port 4001 # Run demo with backend on port 4001');
console.log(' npx atxp demo --dir ./my-demo # Use custom demo directory');
console.log(' npx atxp demo --port 3000 --dir ./demo # Custom port and directory');
console.log(' npx atxp demo --frontend-port 4000 --backend-port 4001 # Custom ports');
console.log(' npx atxp demo --dir ./my-demo --frontend-port 4000 # Custom directory and port');
console.log(' npx atxp create # Create a new project');
console.log();

Expand Down
20 changes: 15 additions & 5 deletions packages/atxp/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ import { showHelp } from './help.js';
import { checkAllDependencies, showDependencyError } from './check-dependencies.js';

interface DemoOptions {
port: number;
frontendPort: number;
backendPort: number;
dir: string;
verbose: boolean;
refresh: boolean;
Expand All @@ -24,13 +25,22 @@ function parseArgs(): { command: string; demoOptions: DemoOptions } {
return index !== -1 ? process.argv[index + 1] : undefined;
};

const port = (() => {
const portValue = getArgValue('--port', '-p');
const frontendPort = (() => {
const portValue = getArgValue('--frontend-port', '--fp');
if (portValue) {
const parsed = parseInt(portValue, 10);
if (parsed > 0 && parsed < 65536) return parsed;
}
return 8016; // default port
return 8016; // default frontend port
})();

const backendPort = (() => {
const portValue = getArgValue('--backend-port', '--bp');
if (portValue) {
const parsed = parseInt(portValue, 10);
if (parsed > 0 && parsed < 65536) return parsed;
}
return 8017; // default backend port
})();

const dir = (() => {
Expand All @@ -43,7 +53,7 @@ function parseArgs(): { command: string; demoOptions: DemoOptions } {

return {
command,
demoOptions: { port, dir, verbose, refresh }
demoOptions: { frontendPort, backendPort, dir, verbose, refresh }
};
}

Expand Down
53 changes: 46 additions & 7 deletions packages/atxp/src/run-demo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import chalk from 'chalk';
import { spawn } from 'child_process';
import fs from 'fs-extra';
import open from 'open';
import path from 'path';

interface DemoOptions {
port: number;
frontendPort: number;
backendPort: number;
dir: string;
verbose: boolean;
refresh: boolean;
Expand Down Expand Up @@ -32,8 +34,11 @@ export async function runDemo(options: DemoOptions): Promise<void> {
// Install dependencies if needed
await installDependencies(options.dir, options.verbose);

// Create .env files for configuration
await createEnvFiles(options.dir, options.frontendPort, options.backendPort, options.verbose);

// Start the demo and open browser
await startDemo(options.port, options.dir, options.verbose);
await startDemo(options.frontendPort, options.backendPort, options.dir, options.verbose);

} catch (error) {
console.error(chalk.red('Error starting demo:'), (error as Error).message);
Expand Down Expand Up @@ -124,9 +129,9 @@ async function installDependencies(demoDir: string, isVerbose: boolean): Promise
});
}

async function startDemo(port: number, demoDir: string, isVerbose: boolean): Promise<void> {
async function startDemo(frontendPort: number, backendPort: number, demoDir: string, isVerbose: boolean): Promise<void> {
console.log(chalk.blue('Starting demo application...'));
console.log(chalk.green(`Demo will be available at: http://localhost:${port}`));
console.log(chalk.green(`Demo will be available at: http://localhost:${frontendPort}`));
console.log(chalk.gray(`Demo directory: ${demoDir}`));
console.log(chalk.yellow('Press Ctrl+C to stop the demo'));
if (!isVerbose) {
Expand All @@ -137,7 +142,11 @@ async function startDemo(port: number, demoDir: string, isVerbose: boolean): Pro
// Set the port environment variable for the demo
const env = {
...process.env,
PORT: port.toString(),
// Backend will use PORT from its .env file, frontend will use PORT from its .env file
// We don't set PORT globally to avoid conflicts - let each service read its own .env
FRONTEND_PORT: frontendPort.toString(),
BACKEND_PORT: backendPort.toString(),
REACT_APP_BACKEND_PORT: backendPort.toString(),
// Suppress deprecation warnings
NODE_NO_WARNINGS: '1',
// Suppress React warnings in development
Expand Down Expand Up @@ -190,10 +199,10 @@ async function startDemo(port: number, demoDir: string, isVerbose: boolean): Pro
if (!demoOpenedBrowser) {
try {
console.log(chalk.blue('Opening browser...'));
await open(`http://localhost:${port}`);
await open(`http://localhost:${frontendPort}`);
} catch {
console.log(chalk.yellow('Could not open browser automatically'));
console.log(chalk.white(`Please open http://localhost:${port} in your browser`));
console.log(chalk.white(`Please open http://localhost:${frontendPort} in your browser`));
}
}
}, 2000);
Expand Down Expand Up @@ -224,6 +233,36 @@ async function startDemo(port: number, demoDir: string, isVerbose: boolean): Pro
});
}

async function createEnvFiles(demoDir: string, frontendPort: number, backendPort: number, isVerbose: boolean): Promise<void> {
if (isVerbose) {
console.log(chalk.blue('Creating .env files...'));
}

try {
// Create backend .env file
const backendEnvPath = path.join(demoDir, 'backend', '.env');
const backendEnvContent = `PORT=${backendPort}\nFRONTEND_PORT=${frontendPort}\n`;
await fs.writeFile(backendEnvPath, backendEnvContent);

if (isVerbose) {
console.log(chalk.gray(`Created backend .env: ${backendEnvPath}`));
}

// Create frontend .env file
const frontendEnvPath = path.join(demoDir, 'frontend', '.env');
const frontendEnvContent = `PORT=${frontendPort}\nREACT_APP_BACKEND_PORT=${backendPort}\n`;
await fs.writeFile(frontendEnvPath, frontendEnvContent);

if (isVerbose) {
console.log(chalk.gray(`Created frontend .env: ${frontendEnvPath}`));
}

} catch (error) {
console.log(chalk.yellow(`Warning: Could not create .env files: ${(error as Error).message}`));
console.log(chalk.gray('Demo will use environment variables passed directly'));
}
}

async function cleanup(): Promise<void> {
try {
// Optionally clean up the demo directory
Expand Down