npm package: @prodbirdy/mockup-generator
Description: Serverless-optimized TypeScript SDK for generating high-quality product mockups from PSD templates
Latest version: 1.0.1-r

# @prodbirdy/mockup-generator

A serverless-optimized TypeScript SDK for generating high-quality product mockups from PSD templates. Built for performance and scalability in serverless environments.

> **Note**: This package is based on [@printmadehq/mockup-generator](https://www.npmjs.com/package/@printmadehq/mockup-generator) with bug fixes and customizations for specific use cases.

## Features

- 🚀 **Serverless Optimized**: Built specifically for serverless environments with optimized cold starts
- 🔥 **High Performance**: Leverages headless Photopea for fast PSD processing
- 🎨 **Smart Object Replacement**: Automatically replace smart objects with your product images
- 📦 **Batch Processing**: Generate multiple mockups in parallel
- ☁️ **Cloud Storage**: Direct integration with AWS S3 and R2 storage
- 🔧 **TypeScript First**: Full TypeScript support with comprehensive type definitions
- 🎯 **Multiple Export Formats**: PNG, JPG, WebP support with quality control
- 🔒 **Type-Safe**: Comprehensive validation and error handling

## Installation

```bash
npm install @prodbirdy/mockup-generator
```

### Peer Dependencies

This package requires the following peer dependencies:

```bash
npm install canvas ag-psd puppeteer
```

## Quick Start

```typescript
import { MockupSDK } from '@prodbirdy/mockup-generator';

// Initialize SDK
const mockupSDK = await MockupSDK.create({
  mode: 'serverless', // or 'development', 'production'
  storage: {
    endpoint: 'https://your-r2-endpoint.com',
    accessKeyId: 'your-access-key',
    secretAccessKey: 'your-secret-key',
    region: 'auto',
    bucket: 'your-bucket'
  }
});

// Generate a mockup
const result = await mockupSDK.generateMockup({
  templateUrl: 'https://your-storage.com/template.psd',
  smartObjects: [
    {
      name: 'Product Image',
      image: 'https://your-storage.com/product.jpg',
      fillMode: 'fit'
    }
  ],
  exports: [
    { format: 'png', quality: 90 },
    { format: 'webp', quality: 85 }
  ]
});

console.log('Generated mockup URLs:', result.urls);
```

## API Reference

### MockupSDK

#### Configuration Options

```typescript
interface MockupSDKConfig {
  mode?: 'serverless' | 'development' | 'production' | 'auto';
  headless?: boolean;
  timeout?: number;
  verbose?: boolean;
  storage?: StorageConfig;
}
```

#### Mode Presets

- **`serverless`**: Optimized for serverless environments (headless, 45s timeout)
- **`development`**: Development-friendly settings (non-headless, verbose logging)
- **`production`**: Production settings (headless, 60s timeout)
- **`auto`**: Automatically detects environment

### Core Methods

#### `generateMockup(config: MockupGenerationConfig)`

Generate a single mockup from a PSD template.

```typescript
interface MockupGenerationConfig {
  templateUrl: string;
  smartObjects: SmartObjectReplacement[];
  exports: ExportOptions[];
  uploadOptions?: UploadOptions;
}
```

#### `generateBatchMockups(config: BatchMockupConfig)`

Generate multiple mockups in parallel.

```typescript
interface BatchMockupConfig {
  templates: MockupGenerationConfig[];
  maxConcurrency?: number;
}
```

#### `uploadBuffer(buffer: Buffer, options: UploadOptions)`

Upload a buffer directly to storage.

```typescript
interface UploadOptions {
  key: string;
  bucket?: string;
  contentType?: string;
  metadata?: Record<string, string>;
}
```

### Smart Object Replacement

Replace smart objects in your PSD templates with custom images:

```typescript
interface SmartObjectReplacement {
  name: string;                    // Smart object layer name
  image: string | Buffer;          // Image URL or Buffer
  fillMode?: 'fit' | 'fill' | 'stretch';
  printArea?: {                    // Custom print area
    x: number;
    y: number;
    width: number;
    height: number;
  };
}
```

### Export Options

Control output format and quality:

```typescript
interface ExportOptions {
  format: 'png' | 'jpg' | 'webp';
  quality?: number;                // 0-100 for lossy formats
  width?: number;                  // Custom width
  height?: number;                 // Custom height
}
```

## Usage Examples

### Basic Mockup Generation

```typescript
const mockupSDK = await MockupSDK.create({
  mode: 'serverless',
  storage: {
    endpoint: process.env.R2_ENDPOINT,
    accessKeyId: process.env.R2_ACCESS_KEY,
    secretAccessKey: process.env.R2_SECRET_KEY,
    region: 'auto',
    bucket: 'mockups'
  }
});

const result = await mockupSDK.generateMockup({
  templateUrl: 'https://storage.com/tshirt-template.psd',
  smartObjects: [
    {
      name: 'Design',
      image: 'https://storage.com/my-design.png',
      fillMode: 'fit'
    }
  ],
  exports: [
    { format: 'png', quality: 95 },
    { format: 'webp', quality: 80 }
  ]
});
```

### Batch Processing

```typescript
const batchResult = await mockupSDK.generateBatchMockups({
  templates: [
    {
      templateUrl: 'https://storage.com/template1.psd',
      smartObjects: [{ name: 'Product', image: 'https://storage.com/product1.jpg' }],
      exports: [{ format: 'png' }]
    },
    {
      templateUrl: 'https://storage.com/template2.psd',
      smartObjects: [{ name: 'Product', image: 'https://storage.com/product2.jpg' }],
      exports: [{ format: 'png' }]
    }
  ],
  maxConcurrency: 3
});
```

### Custom Print Areas

```typescript
const result = await mockupSDK.generateMockup({
  templateUrl: 'https://storage.com/template.psd',
  smartObjects: [
    {
      name: 'Product',
      image: 'https://storage.com/product.jpg',
      fillMode: 'fit',
      printArea: {
        x: 100,
        y: 100,
        width: 500,
        height: 500
      }
    }
  ],
  exports: [{ format: 'png' }]
});
```

### Error Handling

```typescript
import { MockupSDKError, ValidationError, StorageError } from '@prodbirdy/mockup-generator';

try {
  const result = await mockupSDK.generateMockup(config);
} catch (error) {
  if (error instanceof ValidationError) {
    console.error('Validation error:', error.message);
  } else if (error instanceof StorageError) {
    console.error('Storage error:', error.message);
  } else if (error instanceof MockupSDKError) {
    console.error('SDK error:', error.message);
  }
}
```

## Storage Configuration

### AWS S3

```typescript
const config = {
  storage: {
    endpoint: 'https://s3.amazonaws.com',
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
    region: 'us-east-1',
    bucket: 'my-mockups'
  }
};
```

### Cloudflare R2

```typescript
const config = {
  storage: {
    endpoint: process.env.R2_ENDPOINT,
    accessKeyId: process.env.R2_ACCESS_KEY_ID,
    secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
    region: 'auto',
    bucket: 'my-mockups'
  }
};
```

## Performance Tips

1. **Use URLs for large images**: Pass image URLs instead of Buffers for better memory efficiency
2. **Batch processing**: Use `generateBatchMockups` for multiple mockups
3. **Optimize export settings**: Use WebP format for smaller file sizes
4. **Cache templates**: Store frequently used PSD templates in fast storage
5. **Monitor memory**: Use appropriate instance sizes for your workload

## Environment Variables

```env
# Storage configuration
R2_ENDPOINT=https://your-account.r2.cloudflarestorage.com
R2_ACCESS_KEY_ID=your-access-key
R2_SECRET_ACCESS_KEY=your-secret-key
R2_BUCKET=your-bucket

# Optional: Puppeteer configuration for serverless
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
```

## Serverless Deployment

### AWS Lambda

```typescript
import { MockupSDK } from '@prodbirdy/mockup-generator';

export const handler = async (event) => {
  const mockupSDK = await MockupSDK.create({
    mode: 'serverless',
    storage: {
      endpoint: process.env.R2_ENDPOINT,
      accessKeyId: process.env.R2_ACCESS_KEY_ID,
      secretAccessKey: process.env.R2_SECRET_ACCESS_KEY,
      region: 'auto',
      bucket: process.env.R2_BUCKET
    }
  });

  const result = await mockupSDK.generateMockup({
    templateUrl: event.templateUrl,
    smartObjects: event.smartObjects,
    exports: event.exports
  });

  return {
    statusCode: 200,
    body: JSON.stringify(result)
  };
};
```

### Vercel

```typescript
import { MockupSDK } from '@prodbirdy/mockup-generator';
import type { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  const mockupSDK = await MockupSDK.create({
    mode: 'serverless',
    storage: {
      endpoint: process.env.R2_ENDPOINT!,
      accessKeyId: process.env.R2_ACCESS_KEY_ID!,
      secretAccessKey: process.env.R2_SECRET_ACCESS_KEY!,
      region: 'auto',
      bucket: process.env.R2_BUCKET!
    }
  });

  const result = await mockupSDK.generateMockup(req.body);
  res.status(200).json(result);
}
```

## Requirements

- Node.js 18+
- TypeScript 5.0+
- Canvas and ag-psd for PSD processing
- Puppeteer for headless rendering

## License

Mixed License - see LICENSE file for details.

- Original PrintMade code: MIT License
- Prodbirdy modifications: Proprietary (no commercial use or redistribution without permission)

## Credits

This package is based on [@printmadehq/mockup-generator](https://www.npmjs.com/package/@printmadehq/mockup-generator). We've made bug fixes and customizations to meet our specific requirements. Special thanks to the PrintMade team for their foundational work on PSD mockup generation.

## Support

For support and questions, please contact the Prodbirdy team.