npm package: @grasco/sdk
Description: Grasco SDK - Image editing and file upload SDK
Latest version: 0.1.1

# Grasco SDK

A powerful JavaScript SDK for image editing and file upload functionality. Built with TypeScript and bundled with Bun for maximum browser compatibility.

## Features

- 🎨 **Image Editing**: Apply filters, scenes, adjustments, and more
- 🖼️ **Professional Headshots**: Generate AI-powered professional headshots
- 💇 **Hair Transformation**: Change hair styles and colors
- 📤 **File Upload**: Easy file upload with progress tracking
- 🎭 **Facial Expressions**: Modify facial expressions in images
- 🔍 **AI Suggestions**: Get intelligent edit suggestions
- 🚀 **Lazy Loading**: Modules load on-demand for optimal performance
- 🔐 **Token Authentication**: Secure API access with JWT tokens
- 📦 **TypeScript Support**: Full type definitions included

## Installation

### NPM

```bash
npm install @grasco/sdk
```

### Yarn

```bash
yarn add @grasco/sdk
```

### Bun

```bash
bun add @grasco/sdk
```

### CDN (Browser)

```html
<script type="module" src="https://cdn.jsdelivr.net/npm/@grasco/sdk/dist/index.js"></script>
```

## Quick Start

### Initialize the SDK

```typescript
import { GrascoSDK } from '@grasco/sdk';

const sdk = new GrascoSDK();

sdk.init({
  apiKey: 'your-api-key',
  baseUrl: 'https://api.grasco.com',
  frontendUrl: 'https://app.grasco.com',
  isDev: false // Enable verbose logging in development
});

// Set user authentication token
sdk.setToken('user-jwt-token');
```

### Browser Usage (Script Tag)

```html
<!DOCTYPE html>
<html>
<head>
  <title>Grasco SDK Example</title>
</head>
<body>
  <button id="editBtn">Edit Image</button>

  <script type="module">
    import { GrascoSDK } from 'https://cdn.jsdelivr.net/npm/@grasco/sdk/dist/index.js';

    const sdk = new GrascoSDK();
    sdk.init({
      apiKey: 'your-api-key',
      baseUrl: 'https://api.grasco.com',
      isDev: true
    });

    sdk.setToken('user-token');

    document.getElementById('editBtn').addEventListener('click', async () => {
      const result = await sdk.openImageEditor({
        imageDataUrl: 'data:image/png;base64,...',
        features: ['filter', 'edit', 'headshot']
      });
      console.log('Edited image:', result);
    });
  </script>
</body>
</html>
```

## API Reference

### Image Editing

#### Open Image Editor UI

```typescript
const result = await sdk.openImageEditor({
  imageDataUrl: 'data:image/png;base64,...',
  sessionId: 'optional-session-id',
  features: ['filter', 'edit', 'scene', 'headshot', 'hair', 'expression', 'upscale']
});
```

#### Apply Filter

```typescript
const editedImage = await sdk.api.applyFilter(
  imageDataUrl,
  'vintage' // Filter key
);
```

#### Edit Image (Localized)

```typescript
const editedImage = await sdk.api.editImage(
  imageDataUrl,
  'Make the sky more blue',
  { x: 100, y: 50 } // Hotspot coordinates
);
```

#### Adjust Image (Global)

```typescript
const adjustedImage = await sdk.api.adjustImage(
  imageDataUrl,
  'Increase brightness and contrast'
);
```

#### Apply Scene

```typescript
const sceneImage = await sdk.api.applyScene(
  imageDataUrl,
  'beach-sunset'
);
```

#### Change Expression

```typescript
const newExpression = await sdk.api.changeExpression(
  imageDataUrl,
  'smiley' // Options: smiley, professional, serene, determined, etc.
);
```

#### Generate Professional Headshot

```typescript
const headshot = await sdk.api.generateHeadshot(imageDataUrl, {
  clothingStyles: ['business-formal'],
  backgroundStyles: ['office'],
  framingStyles: ['headshot'],
  poseStyles: ['professional']
});
```

#### Transform Hair

```typescript
const result = await sdk.api.transformHair(imageDataUrl, {
  hairStyles: ['long', 'wavy'],
  colorPresetId: 'blonde',
  gender: 'female'
});

console.log('New hair:', result.image);
console.log('Metadata:', result.metadata);
```

#### Upscale Image

```typescript
const upscaled = await sdk.api.upscaleImage(
  imageDataUrl,
  'hd' // Options: 'hd', 'fhd', 'extrahd'
);
```

#### Get AI Suggestions

```typescript
const suggestions = await sdk.api.suggestEdits(imageDataUrl);

suggestions.forEach(suggestion => {
  console.log(`${suggestion.title} (${suggestion.type})`);
  console.log(`Prompt: ${suggestion.prompt}`);
});
```

#### Detect Gender

```typescript
const gender = await sdk.api.detectGender(imageDataUrl);
console.log('Detected gender:', gender); // 'male' or 'female'
```

### File Upload

#### Upload File with UI

```typescript
const result = await sdk.uploadFile({
  acceptedTypes: ['application/pdf', 'image/*'],
  maxSize: 10 * 1024 * 1024, // 10MB
  onProgress: (percent) => {
    console.log(`Upload progress: ${percent}%`);
  }
});

console.log('Job ID:', result.jobId);
console.log('Document ID:', result.documentId);
```

### Event Handling

```typescript
// Listen to events
sdk.on('edit:complete', (data) => {
  console.log('Edit completed:', data.image);
});

sdk.on('upload:progress', (data) => {
  console.log(`Upload: ${data.percent}%`);
});

sdk.on('error', (error) => {
  console.error('SDK error:', error);
});

// Remove event listener
sdk.off('edit:complete', callback);

// Remove all listeners for an event
sdk.offAll('edit:complete');
```

### Available Events

- `modal:opened` - Modal opened
- `modal:closed` - Modal closed
- `upload:start` - Upload started
- `upload:progress` - Upload progress update
- `upload:complete` - Upload completed
- `upload:error` - Upload error
- `edit:start` - Edit operation started
- `edit:complete` - Edit operation completed
- `edit:error` - Edit operation error
- `error` - General error

## Advanced Usage

### Custom Configuration

```typescript
sdk.init({
  apiKey: 'your-api-key',
  baseUrl: 'https://api.grasco.com',
  frontendUrl: 'https://app.grasco.com',
  isDev: process.env.NODE_ENV === 'development'
});
```

### Token Management

```typescript
// Set token after user login
sdk.setToken(userToken);

// Clear token on logout
sdk.clearToken();
```

### Error Handling

```typescript
try {
  const result = await sdk.api.applyFilter(imageDataUrl, 'vintage');
  console.log('Success:', result);
} catch (error) {
  if (error.status === 402) {
    console.error('Insufficient credits');
  } else if (error.status === 401) {
    console.error('Unauthorized - token expired?');
  } else {
    console.error('Error:', error.message);
  }
}
```

## TypeScript Support

The SDK is written in TypeScript and includes full type definitions:

```typescript
import type {
  SDKConfig,
  GenerationResponse,
  EditImageRequest,
  FilterRequest,
  HeadshotRequest,
  HairTransformResponse,
  SDKEventType,
  EventCallback
} from '@grasco/sdk';

const config: SDKConfig = {
  apiKey: 'your-api-key',
  baseUrl: 'https://api.grasco.com',
  isDev: false
};

sdk.init(config);

// Type-safe event handling
const onEditComplete: EventCallback = (data) => {
  console.log('Edit complete:', data);
};

sdk.on('edit:complete', onEditComplete);
```

## Browser Support

- Chrome/Edge: Last 2 versions
- Firefox: Last 2 versions
- Safari: Last 2 versions
- Opera: Last 2 versions

Minimum requirements:
- ES2020 support
- Fetch API
- PostMessage API

## Security

### Token Storage

Never store tokens in the SDK. Always pass tokens dynamically:

```typescript
// ❌ Bad - Don't hardcode tokens
sdk.setToken('hardcoded-token');

// ✅ Good - Get token from secure storage
const token = await getTokenFromSecureStorage();
sdk.setToken(token);
```

### CORS Configuration

Ensure your backend allows requests from your domain:

```
Access-Control-Allow-Origin: https://yourdomain.com
Access-Control-Allow-Headers: Authorization, X-API-Key, Content-Type
```

### CSP (Content Security Policy)

If using iframe modals, allow iframe sources:

```html
<meta http-equiv="Content-Security-Policy" 
      content="frame-src https://app.grasco.com;">
```

## Examples

### React Integration

```typescript
import { useEffect, useState } from 'react';
import { GrascoSDK } from '@grasco/sdk';

const sdk = new GrascoSDK();

function ImageEditor() {
  const [image, setImage] = useState<string | null>(null);

  useEffect(() => {
    sdk.init({
      apiKey: process.env.REACT_APP_API_KEY!,
      baseUrl: process.env.REACT_APP_API_URL!,
      isDev: process.env.NODE_ENV === 'development'
    });

    sdk.setToken(getUserToken());

    sdk.on('edit:complete', (data) => {
      setImage(data.image);
    });

    return () => {
      sdk.offAll('edit:complete');
    };
  }, []);

  const handleEdit = async () => {
    await sdk.openImageEditor({
      imageDataUrl: image!,
      features: ['filter', 'edit']
    });
  };

  return (
    <div>
      {image && <img src={image} alt="Edited" />}
      <button onClick={handleEdit}>Edit Image</button>
    </div>
  );
}
```

### Vue Integration

```vue
<template>
  <div>
    <img v-if="image" :src="image" alt="Edited" />
    <button @click="editImage">Edit Image</button>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { GrascoSDK } from '@grasco/sdk';

const sdk = new GrascoSDK();
const image = ref<string | null>(null);

onMounted(() => {
  sdk.init({
    apiKey: import.meta.env.VITE_API_KEY,
    baseUrl: import.meta.env.VITE_API_URL,
    isDev: import.meta.env.DEV
  });

  sdk.setToken(getUserToken());

  sdk.on('edit:complete', (data) => {
    image.value = data.image;
  });
});

onUnmounted(() => {
  sdk.offAll('edit:complete');
});

const editImage = async () => {
  await sdk.openImageEditor({
    imageDataUrl: image.value!,
    features: ['filter', 'edit']
  });
};
</script>
```

## License

MIT

## Support

For issues and questions:
- GitHub Issues: https://github.com/grasco/sdk/issues
- Email: support@grasco.com
- Documentation: https://docs.grasco.com

## Changelog

### 0.1.0 (Initial Release)

- Image editing capabilities
- File upload functionality
- Token-based authentication
- Event system
- TypeScript support
- Lazy module loading