npm package: @maropost-tools/theme-cli
Description: Build tools for Maropost storefront themes - includes asset compilation, Tailwind CSS processing, file watching, and development server
Author: Maropost
Latest version: 2.0.4

# Maropost Theme CLI

Professional build tools for Maropost storefront themes - includes asset compilation, Tailwind CSS processing, file watching, and **integrated development server with theme preview functionality**.

## Features

### 🚀 All-in-One Development Server
- **Automatic asset building** on startup and file changes
- **Local theme development server** that proxies to remote Maropost storefront
- **Template preview functionality** - sends local templates to storefront `/preview` endpoint
- **Intelligent static asset serving** with manifest-based hash resolution
- **Route-based template matching** using `routes.json` configuration
- **Real-time file watching** with automatic rebuilds
- **Professional logging** with categorized, colored output
- **Gzip compression** for faster template transfers

### 🏗️ Asset Building
- **CSS/SCSS/SASS compilation** with Sass
- **JavaScript/TypeScript bundling** with esbuild
- **Tailwind CSS processing** with v4 support
- **Image optimization** with Sharp - fast WebP conversion for PNG, JPEG, GIF, TIFF, and BMP
- **PostCSS processing** with autoprefixer and cssnano
- **CSS purging** with PurgeCSS
- **Asset hashing** with manifest generation

### 🔧 Developer Experience
- **Professional CLI interface** with modern development workflow
- **Verbose debug mode** for troubleshooting
- **Graceful error handling** and recovery
- **Build timing** and performance metrics
- **Template rendering status** tracking

## Installation

Install globally (recommended):

```bash
npm install -g @maropost-tools/theme-cli
```

Then run the `maropost` command from anywhere:

```bash
maropost theme dev --storefront-url="https://your-store.example.com"
maropost theme build
maropost theme watch
```

### Local Installation (for team version control)

For teams that need to synchronize CLI versions:

```bash
cd your-theme-directory
npm install @maropost-tools/theme-cli --save-dev
```

Then use npm scripts:

```bash
# Add to package.json:
{
  "scripts": {
    "dev": "maropost theme dev --storefront-url=\"https://your-store.example.com\"",
    "build": "maropost theme build --bundle --clean"
  }
}

# Run with npm:
npm run dev
npm run build
```

## Quick Start

### 🎨 Create a New Theme

Create a new theme with the standard Maropost structure:

```bash
# Create theme with default name (my-theme)
maropost theme init

# Create theme with custom name
maropost theme init my-store-theme
```

This creates a complete theme structure with:
- Standard directory layout (assets, templates, sections, blocks, etc.)
- Basic configuration files
- Sample CSS and JavaScript files
- Package.json with helpful scripts
- README with getting started instructions

### 🚀 Development Server (Recommended)

The easiest way to start developing - builds, watches, and serves everything in one command:

```bash
# Start development server (recommended)
maropost theme dev --storefront-url="https://your-store.example.com"

# Or use 'serve' instead of 'dev'
maropost theme serve --storefront-url="https://your-store.example.com"

# With custom options
maropost theme dev --storefront-url="https://your-store.example.com" \
               --theme-path="./theme" \
               --port=3000 \
               --verbose

# Skip initial build (use existing assets)
maropost theme dev --storefront-url="https://your-store.example.com" --no-build

# Server only (no file watching)
maropost theme dev --storefront-url="https://your-store.example.com" --no-watch
```

### 🏗️ Build Assets

For CI/CD or when you only need to build assets without the dev server:

```bash
# Build individual files (default)
maropost theme build

# Build bundled files
maropost theme build --bundle

# Clean and build
maropost theme build --clean

# Build with CSS purging
maropost theme build --purge

# Combine options
maropost theme build --bundle --clean --purge
```

**Note:** `maropost theme dev` automatically builds assets on startup, so you typically don't need to run `maropost theme build` separately during development.

### 👀 Watch for Changes

For custom workflows (not needed with serve command):

```bash
# Watch for changes and rebuild
maropost theme watch

# Watch with bundle mode
maropost theme watch --bundle
```

**Note:** `maropost theme dev` includes file watching by default, so you typically don't need to run `maropost theme watch` separately.

## Development Server

The development server replicates the functionality of the `maropost-cli` Go project, providing a local development environment for Maropost themes.

### How It Works

1. **Route Matching**: Reads `config/routes.json` to determine which template to use for each URL path
2. **Template Loading**: Loads local template files from `templates/[type]/default.json`
3. **Asset Collection**: Automatically collects all required sections, blocks, and snippets
4. **Preview Request**: Sends the local template data to the storefront's `/preview` endpoint
5. **Response Proxying**: Returns the storefront's response with local theme changes applied

### Server Features

- **Static Assets**: Serves `/static` and `/public` directories
- **Template Preview**: Intercepts theme requests and sends to preview endpoint
- **Fallback Proxy**: Routes unmatched requests directly to storefront
- **CORS Support**: Full CORS headers for development
- **Request Logging**: Comprehensive request logging with Morgan
- **Graceful Shutdown**: Handles SIGINT and SIGTERM signals

### Configuration

```javascript
const { createDevServer } = require('@maropost-tools/theme-cli');

const server = createDevServer({
  port: 3333,                    // Server port (default: 3333)
  host: 'localhost',             // Host to bind to (default: localhost)
  storefrontURL: 'https://your-store.example.com',  // Required: Remote storefront URL
  themePath: './theme'           // Optional: Local theme directory path (default: current directory)
});

// Start the server
server.start().then(() => {
  console.log('Development server running');
});

// Stop the server
server.stop().then(() => {
  console.log('Development server stopped');
});
```

### CLI Usage

```bash
maropost theme dev [options]

Required Options:
  --storefront-url    Storefront store URL (e.g., https://your-store.example.com)

Optional Options:
  --theme-path        Path to local theme directory (default: current directory ".")
  --port              Port for local development server (default: 3333)
  --host              Host to bind to (default: localhost)
  --no-build          Skip initial build on startup
  --no-watch          Disable file watching and auto-rebuild
  --verbose           Enable verbose debug logging
  --help              Show help message

Examples:
  # Standard development workflow
  maropost theme dev --storefront-url="https://your-store.example.com"

  # With custom theme directory and port
  maropost theme dev --storefront-url="https://your-store.example.com" --theme-path="./theme" --port=3000

  # Debug mode with verbose logging
  maropost theme dev --storefront-url="https://your-store.example.com" --verbose

  # Server only (no build/watch)
  maropost theme dev --storefront-url="https://your-store.example.com" --no-build --no-watch
```

### Theme Structure

The development server expects your theme to follow this structure:

```
theme/
├── config/
│   ├── routes.json           # Route definitions
│   ├── settings_data.json    # Theme settings
│   └── settings_schema.json  # Settings schema
├── templates/
│   ├── home/
│   │   └── default.json      # Home page template
│   ├── product/
│   │   └── default.json      # Product page template
│   └── collection/
│       └── default.json      # Collection page template
├── sections/
│   ├── default.html          # Default section
│   ├── header.html           # Header section
│   └── footer.html           # Footer section
├── blocks/
│   ├── button.html           # Button block
│   ├── image.html            # Image block
│   └── text.html             # Text block
├── snippets/
│   ├── product-card.html     # Product card snippet
│   └── collection-card.html  # Collection card snippet
├── layouts/
│   ├── main.html             # Main layout
│   └── auth.html             # Auth layout
├── assets/
│   ├── css/                  # CSS/SCSS files
│   ├── js/                   # JavaScript files
│   └── images/               # Image files
└── public/                   # Public assets
```

### Routes Configuration

The `config/routes.json` file defines how URLs map to templates:

```json
[
  {
    "id": "home",
    "label": "Home",
    "path": "/",
    "method": "GET",
    "target": "template",
    "template_type": "home"
  },
  {
    "id": "product",
    "label": "Product",
    "path": "/products/{handle}",
    "method": "GET",
    "target": "template",
    "template_type": "product"
  },
  {
    "id": "collection",
    "label": "Collection",
    "path": "/collections/{handle}",
    "method": "GET",
    "target": "template",
    "template_type": "collection"
  }
]
```

### Template Structure

Templates in `templates/[type]/default.json` define the page structure:

```json
{
  "id": "home",
  "label": "Home Page",
  "type": "home",
  "layout": "main",
  "sections": {
    "header": {
      "id": "header",
      "type": "header",
      "settings": {},
      "blocks": {}
    },
    "hero": {
      "id": "hero",
      "type": "hero",
      "settings": {},
      "blocks": {}
    }
  },
  "order": ["header", "hero"]
}
```

## Asset Building

### Build Modes

#### Individual Mode (Default)
- Each CSS/SCSS/SASS file → separate .css file
- Each JS/TS/JSX/TSX file → separate .js file
- Good for: selective loading, debugging, modular themes

#### Bundle Mode
- All CSS → single theme.css file
- All JS → single theme.js file
- Good for: performance, single HTTP request, production

### Build Options

```bash
# Individual files (default)
maropost theme build

# Bundle mode
maropost theme build --bundle

# Clean output directories
maropost theme build --clean

# CSS purging
maropost theme build --purge

# Disable minification
maropost theme build --no-minify

# Combine options
maropost theme build --bundle --clean --purge
```

### Configuration

Create a `theme-cli.config.js` file in your project root:

```javascript
module.exports = {
  // Input directories
  cssDir: 'assets/css',
  jsDir: 'assets/js',
  imagesDir: 'assets/images',
  
  // Output directories
  outputCssDir: 'tmp/assets/css',
  outputJsDir: 'tmp/assets/js',
  outputImagesDir: 'tmp/assets/images',
  
  // Build options
  bundle: false,        // Bundle all files
  minify: true,         // Minify output
  purge: false,         // Run PurgeCSS
  
  // Tailwind CSS
  tailwindInput: 'assets/css/tailwind.css',
  
  // Theme directories for CSS purging
  themeDirs: [
    'templates',
    'sections',
    'blocks',
    'snippets',
    'layouts'
  ]
};
```

## File Watching

```bash
# Watch for changes and rebuild
maropost theme watch

# Watch with specific options
maropost theme watch --bundle --purge
```

## Programmatic Usage

### Asset Building

```javascript
const { build, config } = require('@maropost-tools/theme-cli');

// Use default configuration
build();

// Custom configuration
const customConfig = {
  ...config,
  bundle: true,
  purge: true
};

build(customConfig);
```

### Development Server

```javascript
const { createDevServer } = require('@maropost-tools/theme-cli');

const server = createDevServer({
  port: 3000,
  storefrontURL: 'https://your-store.example.com',
  themePath: './theme'
});

server.start().then(() => {
  console.log('Server running on port 3000');
});
```

## Dependencies

### Required
- Node.js >= 18.0.0
- npm >= 9.0.0

### Build Tools
- Sass for CSS/SCSS compilation
- esbuild for JavaScript/TypeScript bundling
- Tailwind CSS v4 for utility-first CSS
- PostCSS for CSS processing
- PurgeCSS for unused CSS removal
- Sharp for high-performance image processing and WebP conversion

### Development Server
- Express.js for HTTP server
- CORS for cross-origin requests
- Morgan for request logging
- http-proxy-middleware for proxying

## Examples

### Basic Theme Development

1. **Start the development server:**
   ```bash
   maropost theme dev --storefront-url="https://your-store.example.com"
   ```

2. **Make changes to your theme files**

3. **View changes in real-time** at `http://localhost:3333`

4. **Build production assets:**
   ```bash
   maropost theme build --bundle --clean
   ```

### Advanced Configuration

```javascript
// theme-cli.config.js
module.exports = {
  bundle: true,
  minify: true,
  purge: true,
  tailwindInput: 'assets/css/tailwind.css',
  themeDirs: ['templates', 'sections', 'blocks', 'snippets', 'layouts']
};
```

### Integration with Build Tools

```javascript
// package.json scripts
{
  "scripts": {
    "dev": "maropost theme dev --storefront-url=\"https://your-store.example.com\"",
    "build": "maropost theme build --bundle --clean",
    "watch": "maropost theme watch --bundle",
    "build:prod": "maropost theme build --bundle --clean --purge"
  }
}
```

## Troubleshooting

### Common Issues

1. **Port already in use**: Change the port with `--port` option
2. **Template not found**: Check your `routes.json` configuration
3. **Assets not loading**: Ensure theme directory structure is correct
4. **Preview endpoint errors**: Verify storefront URL and connectivity

### Debug Mode

Enable verbose logging with the `--verbose` flag:

```bash
maropost theme dev --storefront-url="..." --verbose
```

## Testing

Run the test suite to verify image processing and Sharp integration:

```bash
npm test
```

The test suite includes:
- Sharp installation verification
- PNG to WebP conversion
- JPEG to WebP conversion
- Quality settings validation
- Error handling for invalid inputs

## Development

### Working with the Example Theme

This repository includes `real-theme` as a git submodule in `examples/real-theme` for testing and development.

**Initial Setup:**
```bash
# Clone with submodules
git clone --recurse-submodules git@bitbucket.org:maropost-development/theme-cli.git

# Or if already cloned, initialize submodules
git submodule update --init --recursive
```

**Testing CLI Commands:**
```bash
# Test build command
cd examples/real-theme
maropost theme build

# Test dev server
maropost theme dev --storefront-url="https://your-store.example.com"

# Test watch
maropost theme watch
```

**Updating the Example Theme:**
```bash
# Pull latest changes from real-theme
git submodule update --remote examples/real-theme

# Commit the submodule update
git add examples/real-theme
git commit -m "Update real-theme submodule"
```

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests if applicable
5. Run `npm test` to verify your changes
6. Test with example theme in `examples/real-theme`
7. Submit a pull request

## License

MIT License - see [LICENSE](LICENSE) file for details.

## Support

- **Issues**: [Bitbucket Issues](https://bitbucket.org/maropost-development/theme-cli/issues)
- **Documentation**: [Bitbucket Wiki](https://bitbucket.org/maropost-development/theme-cli/wiki)
- **Repository**: [Bitbucket Repository](https://bitbucket.org/maropost-development/theme-cli)