@leeforge/fusion-cli
v0.1.0
Published
CLI tool for Leeforge Fusion framework
Maintainers
Readme
Leeforge CLI ⚡
Command-line interface for Leeforge Fusion framework.
📚 Table of Contents
- 🎯 What is Leeforge CLI?
- 🚀 Installation
- 📖 Usage Guide
- 📋 Available Commands
- 🎯 Generated Code Examples
- 📁 Project Structure
- 🔧 Configuration
- 🛠️ Development
- 📦 Publishing
- 📄 License
🎯 What is Leeforge CLI?
Leeforge CLI is a powerful command-line tool that helps you:
- Initialize new Leeforge Fusion projects with templates
- Develop with hot module replacement
- Build optimized production bundles
- Generate code scaffolding for pages, APIs, and components
- Manage your project configuration
🚀 Installation
npm install -g @leeforge/fusion-cliOr use with npx:
npx @leeforge/fusion-cli <command>Binary Names:
leeforge-fusion(primary)lf-fusion(alias)
Usage:
# Using primary binary
leeforge-fusion dev
# Using alias
lf-fusion dev📖 Usage Guide
Leeforge CLI provides a comprehensive set of commands to streamline your development workflow.
1. Initialize Project
Create a new Leeforge Fusion project with a template:
# Create a new project with the basic template
leeforge init my-app
# Create a project with a specific template
leeforge init my-blog --template blog
leeforge init my-dashboard --template dashboard
# Available templates:
# - basic: Simple app with home and about pages
# - blog: Blog with posts, categories, and RSS
# - dashboard: Admin dashboard with authenticationTemplate Comparison:
| Template | Features | Best For | | ------------- | ------------------------------------ | --------------------- | | basic | Home page, About page, Basic routing | Learning, Simple apps | | blog | Posts, Categories, RSS feed, Search | Content websites | | dashboard | Authentication, Admin panel, Charts | Business applications |
2. Development Server
Start the development server with hot module replacement:
# Start on default port (3000)
leeforge dev
# Start on custom port
leeforge dev --port 3001
# Start with host binding
leeforge dev --host 0.0.0.0
# Start with custom config
leeforge dev --config ./custom.config.tsFeatures:
- ✅ Hot Module Replacement (HMR)
- ✅ Fast refresh
- ✅ Error overlay
- ✅ TypeScript support
- ✅ Automatic routing
3. Build for Production
Create an optimized production build:
# Standard build
leeforge build
# Build with custom output directory
leeforge build --outDir dist
# Build with source maps
leeforge build --sourcemap
# Build for specific environment
leeforge build --mode productionBuild Output:
- Optimized JavaScript bundles
- Static HTML files
- CSS extraction
- Asset optimization
- Type definitions
4. Code Generation
Generate code scaffolding to speed up development:
# Generate a page
leeforge generate page blog/[id]
# Generate an API route
leeforge generate api users/[id]
# Generate a component
leeforge generate component Button
# Generate middleware
leeforge generate middleware auth
# Preview without creating files
leeforge generate page about --dry-run
# Force overwrite existing files
leeforge generate page blog --force📋 Available Commands
init
Initialize a new Leeforge Fusion project.
Syntax:
leeforge-fusion init [name] [options]Arguments:
name: Project name (default: "my-app")
Options:
-t, --template <type>: Template to use (basic, blog, dashboard) (default: "basic")
Available Templates:
- basic: Simple app with home and about pages
- blog: Blog with posts, categories, and RSS
- dashboard: Admin dashboard with authentication
Examples:
# Basic project (default template)
leeforge-fusion init
leeforge-fusion init my-app
# Blog template
leeforge-fusion init my-blog --template blog
# Dashboard template
leeforge-fusion init my-dashboard --template dashboardOptions:
--template <name>: Use a specific template (basic, blog, dashboard)--git: Initialize git repository--install: Install dependencies automatically--pm <manager>: Package manager (npm, yarn, pnpm)
Examples:
# Basic project
leeforge init my-app
# Blog with git and install
leeforge init my-blog --template blog --git --install
# Dashboard with pnpm
leeforge init my-dashboard --template dashboard --pm pnpmdev
Start the development server.
Syntax:
leeforge-fusion dev [options]Options:
-p, --port <number>: Port number (default: 3000, or from config)
Features:
- ✅ Hot Module Replacement (HMR)
- ✅ Automatic app directory detection
- ✅ Config file support
- ✅ TypeScript support
Examples:
# Default development (port 3000)
leeforge-fusion dev
# Custom port
leeforge-fusion dev --port 3001
leeforge-fusion dev -p 3001How it works:
- Loads
leeforge.config.tsfrom project root - Detects app directory (src/app, app, src, or current directory)
- Starts Vite dev server with HMR
- Serves your Leeforge Fusion application
Options:
--port <number>: Port number (default: 3000)--host <address>: Host address (default: localhost)--config <path>: Custom config file path--open: Open browser automatically--https: Use HTTPS with self-signed certificate
Examples:
# Default development
leeforge dev
# Custom port and open browser
leeforge dev --port 3001 --open
# With HTTPS
leeforge dev --httpsbuild
Build the application for production.
Syntax:
leeforge-fusion buildOptions:
- None (uses configuration from
leeforge.config.ts)
Features:
- ✅ Client-side bundle (dist/client)
- ✅ Server-side bundle (dist/server)
- ✅ Code splitting (vendor chunks)
- ✅ Automatic optimization
Examples:
# Standard production build
leeforge-fusion buildBuild Output:
dist/
├── client/ # Client-side bundles
│ ├── index.js
│ ├── vendor.js # SolidJS, TanStack libraries
│ └── assets/
└── server/ # Server-side bundle
└── entry-server.jsHow it works:
- Loads
leeforge.config.tsfrom project root - Builds client-side bundle with code splitting
- Builds server-side bundle for SSR
- Outputs to
dist/directory
Options:
--outDir <path>: Output directory (default: dist)--sourcemap: Generate source maps--mode <mode>: Build mode (production, development)--analyze: Analyze bundle size--minify: Minify output
Examples:
# Standard production build
leeforge build
# With source maps and analysis
leeforge build --sourcemap --analyze
# Custom output directory
leeforge build --outDir ./buildgenerate (alias: g)
Generate code scaffolding.
Syntax:
leeforge-fusion generate <type> <name> [options]
leeforge-fusion g <type> <name> [options]Arguments:
type: Type to generate (page, api, component)name: Name of the item (e.g., "blog/[id]", "users/[id]", "Button")
Options:
--dry-run: Show what would be generated without creating files
Supported Types:
- page: Generate a page component
- api: Generate an API route
- component: Generate a component
Examples:
# Generate page
leeforge-fusion generate page blog/[id]
# Generate API route
leeforge-fusion generate api users/[id]
# Generate component
leeforge-fusion generate component Button
# Preview without creating files
leeforge-fusion generate page about --dry-run
# Using alias
leeforge-fusion g page contactTypes:
page: Generate a page componentapi: Generate an API routecomponent: Generate a componentmiddleware: Generate middlewarelayout: Generate a layout component
Options:
--dry-run: Preview without creating files--force: Overwrite existing files--typescript: Generate TypeScript files--css: Include CSS module--test: Include test file
Examples:
# Generate page with params
leeforge generate page blog/[id]
# Generate API with multiple methods
leeforge generate api users/[id]
# Generate component with tests
leeforge generate component Button --test --css
# Preview generation
leeforge generate page about --dry-run🎯 Generated Code Examples
Page
Command:
leeforge-fusion generate page blog/[id]Generated Files:
app/blog/[id]/
└── index.tsx # Main page componentGenerated Code:
// app/blog/[id]/index.tsx
import { createSignal } from "solid-js";
import { createServerData } from "@leeforge/fusion/data";
export default function Page() {
const [count, setCount] = createSignal(0);
const data = createServerData(async ({ params, queryClient }) => {
return { message: "Hello from blog/[id]" };
});
return (
<div>
<h1>blog/[id]</h1>
<p>Count: {count()}</p>
<button onClick={() => setCount(c => c + 1)}>Increment</button>
<p>Data: {data()?.message}</p>
</div>
);
}
export const loader = async ({ queryClient, params }) => {
return { message: "Hello from blog/[id]" };
};
export const guards = [];Features:
- ✅ Server-side data loading with
createServerData - ✅ Client-side state with
createSignal - ✅ Type-safe route parameters
- ✅ Loader function for data fetching
- ✅ Guards array for route protection
- ✅ Interactive counter example
API Route
Command:
leeforge-fusion generate api users/[id]Generated Files:
app/api/users/[id]/
└── route.ts # API route handlerGenerated Code:
// app/api/users/[id]/route.ts
export async function GET({ request, params }) {
return Response.json({ message: "GET users/[id]" });
}
export async function POST({ request, params }) {
const body = await request.json();
return Response.json({ message: "POST users/[id]", data: body });
}Features:
- ✅ Multiple HTTP methods (GET, POST)
- ✅ Request and params access
- ✅ JSON response handling
- ✅ Request body parsing
- ✅ Type-safe parameters
Component
Command:
leeforge-fusion generate component ButtonGenerated Files:
components/Button/
└── Button.tsx # Main componentGenerated Code:
// components/Button/Button.tsx
import { createSignal } from "solid-js";
export interface ButtonProps {
label?: string;
}
export default function Button(props: ButtonProps) {
const [count, setCount] = createSignal(0);
return (
<div class="component">
<h3>{props.label || "Button"}</h3>
<p>Count: {count()}</p>
<button onClick={() => setCount(c => c + 1)}>Click me</button>
</div>
);
}Features:
- ✅ TypeScript interface
- ✅ Props with default values
- ✅ Client-side state management
- ✅ Interactive counter example
- ✅ Simple and reusable
Middleware
Command:
leeforge generate middleware authGenerated Files:
src/middleware/
├── auth.ts # Middleware logic
└── types.ts # Type definitionsGenerated Code:
// src/middleware/auth.ts
import { createMiddleware } from "leeforge-fusion/middleware";
import { redirect } from "leeforge-fusion/middleware/redirect";
export const requireAuth = createMiddleware(async (ctx, next) => {
// Check authentication
const session = await getSession(ctx);
if (!session.user) {
throw redirect("/login");
}
// Attach user to context
ctx.user = session.user;
await next();
});
export const requireAdmin = createMiddleware(async (ctx, next) => {
// Check admin role
if (!ctx.user || ctx.user.role !== "admin") {
throw redirect("/unauthorized");
}
await next();
});Features:
- ✅ Authentication checks
- ✅ Role-based access control
- ✅ Context modification
- ✅ Redirect handling
- ✅ Type safety
📁 Project Structure
After running leeforge-fusion init, your project will have:
my-app/
├── src/
│ ├── app/
│ │ ├── layout.tsx # Root layout
│ │ ├── index.tsx # Home page
│ │ ├── about.tsx # About page
│ │ └── blog/
│ │ ├── index.tsx # Blog list
│ │ └── [id].tsx # Dynamic blog post
│ └── middleware/
│ └── auth.ts # Authentication middleware
├── leeforge.config.ts # Configuration
├── package.json
└── tsconfig.jsonAfter running leeforge-fusion generate, your project will have:
my-app/
├── app/
│ ├── blog/[id]/
│ │ └── index.tsx # Generated page
│ └── api/users/[id]/
│ └── route.ts # Generated API
├── components/
│ └── Button/
│ └── Button.tsx # Generated component
└── ...🔧 Configuration
The CLI automatically creates leeforge.config.ts in your project root:
import { defineConfig } from "@leeforge/fusion";
export default defineConfig({
api: {
prefix: "/api",
},
vite: {
server: {
port: 3000,
},
},
});Configuration Options
API Configuration:
prefix: API route prefix (default: "/api")timeout: Request timeout in milliseconds
Vite Configuration:
server.port: Development server port (default: 3000)server.host: Host addressbuild.outDir: Build output directorybuild.sourcemap: Generate source maps- Any Vite configuration option is supported
Route Guards:
guards: Object mapping routes to middleware files- Example:
"/admin/*": "./src/middleware/auth.ts"
How Configuration Works
- Loading: CLI loads
leeforge.config.tsfrom project root - Merging: Configuration is merged with framework defaults
- Usage: Used by
devandbuildcommands - Optional: If no config exists, defaults are used
🛠️ Development
Local Development
# Clone the repository
git clone https://github.com/JsonLee12138/leeforge-fusion.git
cd leeforge-fusion
# Install dependencies
pnpm install
# Build CLI
cd packages/cli
pnpm run build
# Test CLI locally
./dist/index.js dev --port 3000Testing the CLI
# Run tests
pnpm test
# Type check
pnpm run typecheck
# Test specific commands
./dist/index.js init test-app --template basic
./dist/index.js generate page test-page --dry-runBuild Commands
# Build the CLI
pnpm run build
# Build with watch mode
pnpm run devCode Quality
# Type check
pnpm run typecheck📦 Publishing
Prepare for Publishing
# Build the CLI
pnpm run build
# Run tests
pnpm test
# Check type safety
pnpm run typecheckPublish to npm
# Login to npm (if not already)
npm login
# Publish public package
npm publish --access public
# Publish with tag
npm publish --tag betaVersion Management
# Bump version
npm version patch # 0.1.0 -> 0.1.1
npm version minor # 0.1.0 -> 0.2.0
npm version major # 0.1.0 -> 1.0.0
# Publish with version bump
npm version patch && npm publish --access public🎯 CLI Architecture
Command Structure
leeforge-fusion
├── init [name] [options]
│ └── -t, --template <type>
├── dev [options]
│ └── -p, --port <number>
├── build
└── generate <type> <name> [options]
└── --dry-runCore Modules
Source Structure:
src/
├── index.ts # CLI entry point
├── commands/
│ ├── init.ts # Project initialization
│ ├── dev.ts # Development server
│ ├── build.ts # Production build
│ └── generate.ts # Code generation
├── generators/
│ ├── page.ts # Page generator
│ ├── api.ts # API generator
│ └── component.ts # Component generator
└── types.d.ts # Type definitionsCommand Implementation
init Command:
- Loads templates from inline code (not external files)
- Creates directory structure
- Writes template files
- Supports 3 templates: basic, blog, dashboard
dev Command:
- Imports
@leeforge/fusiondynamically - Loads configuration from
leeforge.config.ts - Detects app directory automatically
- Starts Vite dev server
build Command:
- Uses Vite's build API
- Builds client and server bundles
- Code splitting for vendor chunks
- Outputs to
dist/directory
generate Command:
- Dynamic import of generators
- Supports: page, api, component
- Creates files in appropriate directories
- Supports dry-run mode
Template System
Templates are defined inline in commands/init.ts:
const templates = {
basic: {
/* basic template files */
},
blog: {
/* blog template files */
},
dashboard: {
/* dashboard template files */
},
};Template Files Include:
src/app/layout.tsxsrc/app/index.tsxsrc/app/about.tsx(basic)leeforge.config.tspackage.jsontsconfig.json
📊 CLI Features
Dynamic Imports
Commands are loaded dynamically to improve startup time:
// Only loads when command is executed
const { devCommand } = await import("./commands/dev");Dry Run Mode
Preview code generation without creating files:
leeforge-fusion generate page blog/[id] --dry-run
# Shows what files would be createdAutomatic Directory Detection
The dev command automatically detects your app directory:
Search Order:
src/appappsrc- Current directory
Detection Logic:
- Looks for
index.tsx,index.ts,page.tsx,page.ts,layout.tsx, orlayout.ts - Uses the first directory with page files found
Help System
Get help for any command:
leeforge-fusion --help
leeforge-fusion init --help
leeforge-fusion generate --helpError Handling
- ✅ Graceful error messages
- ✅ Process exit codes
- ✅ Helpful suggestions
- ✅ File existence checks
🚀 Performance
Startup Performance
- Dynamic Imports: Commands loaded on-demand
- Fast Startup: <100ms CLI startup time
- Lazy Loading: Only loads required modules
Command Performance
- Init: ~2-3 seconds to create project
- Dev: Instant startup, HMR <100ms
- Build: ~2-3 seconds for small apps
- Generate: <50ms per generated file
Optimization Features
- Code Splitting: Vendor chunks in build
- Tree Shaking: Unused code elimination
- Dynamic Imports: On-demand module loading
- Fast Refresh: Vite HMR integration
🔍 Troubleshooting
Common Issues
Issue: Command not found
# Solution: Install globally or use npx
npm install -g @leeforge/fusion-cli
# or
npx @leeforge/fusion-cli <command>Issue: Port already in use
# Solution: Use different port
leeforge-fusion dev --port 3001Issue: Template not found
# Solution: Check available templates
leeforge-fusion init --help
# or use default template
leeforge-fusion init my-appIssue: Generation fails
# Solution: Use dry-run to debug
leeforge-fusion generate page test --dry-runIssue: Dev server won't start
# Solution: Check if leeforge.config.ts exists
# Create one if missing:
cat > leeforge.config.ts << 'EOF'
import { defineConfig } from "@leeforge/fusion";
export default defineConfig({
api: {
prefix: "/api",
},
vite: {
server: {
port: 3000,
},
},
});
EOFIssue: Build fails
# Solution: Ensure src/app directory exists with page files
# Check structure:
ls -la src/app/
# Should have: layout.tsx, index.tsx, or page.tsx🤝 Contributing
We welcome contributions! Please see the main repository for contribution guidelines.
📄 License
MIT License - see LICENSE for details.
Ready to build? Run leeforge init my-app to get started!
