# CDN API

The CDN API allows you to upload and retrieve files from the Lua CDN. Use this for handling file uploads, document storage, and media management.

## Import

```typescript
import { CDN } from 'lua-cli';
```

## Overview

The CDN API enables:
- Upload files to the Lua CDN
- Retrieve files by ID
- Store images, documents, and media
- Share files with users
- Generate file URLs for access

## Methods

| Method | Description |
|--------|-------------|
| `CDN.upload(file)` | Upload a file to the CDN |
| `CDN.get(fileId)` | Retrieve a file by its ID |

## Methods

### `CDN.upload(file)`

Uploads a file to the CDN and returns a file ID.

**Parameters:**
- `file` (File) - The file object to upload

**Returns:** `Promise<string>` - File ID

**Example:**
```typescript
const fileId = await CDN.upload(file);
console.log('Uploaded file ID:', fileId);
```

### `CDN.get(fileId)`

Retrieves a file from the CDN by its ID.

**Parameters:**
- `fileId` (string) - The unique file identifier

**Returns:** `Promise<File>` - File object

**Example:**
```typescript
const file = await CDN.get('file_abc123');
console.log('File name:', file.name);
console.log('File type:', file.type);
console.log('File size:', file.size);
```

## Complete Examples

### File Upload Tool

```typescript
import { LuaTool, CDN, Data } from 'lua-cli';
import { z } from 'zod';

export default class UploadFileTool implements LuaTool {
  name = 'upload_file';
  description = 'Upload a file to storage';

  inputSchema = z.object({
    file: z.instanceof(File).describe('File to upload'),
    category: z.string().optional().describe('File category')
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    try {
      // Upload to CDN
      const fileId = await CDN.upload(input.file);

      // Store file metadata in custom data
      await Data.create('files', {
        fileId,
        fileName: input.file.name,
        fileType: input.file.type,
        fileSize: input.file.size,
        category: input.category || 'general',
        uploadedAt: new Date().toISOString()
      });

      return {
        success: true,
        message: `File "${input.file.name}" uploaded successfully`,
        fileId,
        fileName: input.file.name,
        fileSize: input.file.size
      };
    } catch (error) {
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Upload failed'
      };
    }
  }
}
```

### Download File Tool

```typescript
import { LuaTool, CDN } from 'lua-cli';
import { z } from 'zod';

export default class DownloadFileTool implements LuaTool {
  name = 'download_file';
  description = 'Download a file by ID';

  inputSchema = z.object({
    fileId: z.string().describe('File ID to download')
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    try {
      const file = await CDN.get(input.fileId);

      return {
        success: true,
        fileName: file.name,
        fileType: file.type,
        fileSize: file.size,
        file: file // Can be sent to user or processed
      };
    } catch (error) {
      return {
        success: false,
        error: 'File not found or download failed'
      };
    }
  }
}
```

### Image Upload with Processing

```typescript
import { LuaTool, CDN, User } from 'lua-cli';
import { z } from 'zod';

export default class UploadImageTool implements LuaTool {
  name = 'upload_image';
  description = 'Upload and share an image';

  inputSchema = z.object({
    image: z.instanceof(File).describe('Image file'),
    caption: z.string().optional()
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    // Validate file type
    if (!input.image.type.startsWith('image/')) {
      return {
        success: false,
        error: 'File must be an image'
      };
    }

    // Validate file size (max 5MB)
    const maxSize = 5 * 1024 * 1024; // 5MB in bytes
    if (input.image.size > maxSize) {
      return {
        success: false,
        error: 'Image must be smaller than 5MB'
      };
    }

    try {
      // Upload to CDN
      const fileId = await CDN.upload(input.image);

      // Get current user
      const user = await User.get();

      // Send confirmation with image
      await user.send([
        {
          type: 'text',
          text: input.caption || 'Image uploaded successfully'
        },
        {
          type: 'image',
          url: `https://cdn.heylua.ai/${fileId}`
        }
      ]);

      return {
        success: true,
        fileId,
        fileName: input.image.name,
        fileSize: input.image.size,
        message: 'Image uploaded and shared'
      };
    } catch (error) {
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Upload failed'
      };
    }
  }
}
```

### Document Manager Tool

```typescript
import { LuaTool, CDN, Data } from 'lua-cli';
import { z } from 'zod';

export default class ManageDocumentsTool implements LuaTool {
  name = 'manage_documents';
  description = 'Upload and list user documents';

  inputSchema = z.object({
    action: z.enum(['upload', 'list', 'get']),
    file: z.instanceof(File).optional(),
    fileId: z.string().optional()
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    if (input.action === 'upload') {
      if (!input.file) {
        return { success: false, error: 'File is required for upload' };
      }

      // Upload file
      const fileId = await CDN.upload(input.file);

      // Store metadata
      const entry = await Data.create('documents', {
        fileId,
        fileName: input.file.name,
        fileType: input.file.type,
        fileSize: input.file.size,
        uploadedAt: new Date().toISOString()
      });

      return {
        success: true,
        message: 'Document uploaded',
        fileId,
        entryId: entry.id
      };
    }

    if (input.action === 'list') {
      // List all user documents
      const documents = await Data.get('documents');

      return {
        success: true,
        documents: documents.map(doc => ({
          id: doc.id,
          fileName: doc.data.fileName,
          fileSize: doc.data.fileSize,
          uploadedAt: doc.data.uploadedAt
        }))
      };
    }

    if (input.action === 'get') {
      if (!input.fileId) {
        return { success: false, error: 'fileId is required' };
      }

      // Retrieve file
      const file = await CDN.get(input.fileId);

      return {
        success: true,
        fileName: file.name,
        fileType: file.type,
        fileSize: file.size
      };
    }

    return { success: false, error: 'Invalid action' };
  }
}
```

### Avatar Upload Tool

```typescript
import { LuaTool, CDN, User } from 'lua-cli';
import { z } from 'zod';

export default class UploadAvatarTool implements LuaTool {
  name = 'upload_avatar';
  description = 'Upload user profile picture';

  inputSchema = z.object({
    avatar: z.instanceof(File).describe('Avatar image file')
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    // Validate image type
    const validTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
    if (!validTypes.includes(input.avatar.type)) {
      return {
        success: false,
        error: 'Avatar must be JPEG, PNG, GIF, or WebP'
      };
    }

    // Validate size (max 2MB)
    const maxSize = 2 * 1024 * 1024;
    if (input.avatar.size > maxSize) {
      return {
        success: false,
        error: 'Avatar must be smaller than 2MB'
      };
    }

    try {
      // Upload to CDN
      const fileId = await CDN.upload(input.avatar);

      // Update user profile
      const user = await User.get();
      await user.update({
        avatarUrl: `https://cdn.heylua.ai/${fileId}`,
        avatarFileId: fileId
      });

      return {
        success: true,
        message: 'Avatar updated successfully',
        fileId,
        avatarUrl: `https://cdn.heylua.ai/${fileId}`
      };
    } catch (error) {
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Avatar upload failed'
      };
    }
  }
}
```

### File Share Tool

```typescript
import { LuaTool, CDN, Data, User } from 'lua-cli';
import { z } from 'zod';

export default class ShareFileTool implements LuaTool {
  name = 'share_file';
  description = 'Share a file with the user';

  inputSchema = z.object({
    fileId: z.string().describe('File ID to share'),
    message: z.string().optional()
  });

  async execute(input: z.infer<typeof this.inputSchema>) {
    try {
      // Get file info from metadata
      const files = await Data.search('files', input.fileId);

      if (files.data.length === 0) {
        return {
          success: false,
          error: 'File not found'
        };
      }

      const fileInfo = files.data[0].data;
      const user = await User.get();

      // Send file to user
      const fileUrl = `https://cdn.heylua.ai/${input.fileId}`;

      await user.send([
        {
          type: 'text',
          text: input.message || `Here's your file: ${fileInfo.fileName}`
        },
        {
          type: 'file',
          url: fileUrl,
          mimeType: fileInfo.fileType
        }
      ]);

      return {
        success: true,
        message: 'File shared successfully',
        fileName: fileInfo.fileName,
        fileUrl
      };
    } catch (error) {
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Share failed'
      };
    }
  }
}
```

## File Object Properties

The `File` object returned by `CDN.get()` has:

```typescript
const file = await CDN.get('file_123');

console.log(file.name);    // File name (e.g., "document.pdf")
console.log(file.type);    // MIME type (e.g., "application/pdf")
console.log(file.size);    // File size in bytes
```

## Best Practices

### ✅ DO

- Validate file types before uploading
- Check file size limits to prevent large uploads
- Store file metadata in Data API for tracking
- Use meaningful file IDs and organize by category
- Handle upload/download errors gracefully
- Compress images before uploading when possible
- Clean up unused files periodically

### ❌ DON'T

- Don't upload files without validation
- Don't store sensitive data without encryption
- Don't exceed reasonable file size limits
- Don't lose track of file IDs
- Don't upload files without proper error handling
- Don't forget to inform users about upload status

## Common File Types

| Category | MIME Types |
|----------|-----------|
| Images | `image/jpeg`, `image/png`, `image/gif`, `image/webp` |
| Documents | `application/pdf`, `application/msword`, `application/vnd.openxmlformats-officedocument.wordprocessingml.document` |
| Spreadsheets | `application/vnd.ms-excel`, `application/vnd.openxmlformats-officedocument.spreadsheetml.sheet` |
| Text | `text/plain`, `text/csv`, `text/html` |
| Audio | `audio/mpeg`, `audio/wav`, `audio/ogg` |
| Video | `video/mp4`, `video/webm`, `video/quicktime` |

## Error Handling

```typescript
try {
  const fileId = await CDN.upload(file);
  console.log('Upload successful:', fileId);
} catch (error) {
  if (error.message.includes('size')) {
    console.log('File too large');
  } else if (error.message.includes('type')) {
    console.log('Invalid file type');
  } else {
    console.log('Upload failed:', error.message);
  }
}
```

## Common Patterns

### File Size Validation

```typescript
function validateFileSize(file: File, maxSizeMB: number): boolean {
  const maxBytes = maxSizeMB * 1024 * 1024;
  return file.size <= maxBytes;
}

// Usage
if (!validateFileSize(file, 5)) {
  throw new Error('File must be smaller than 5MB');
}
```

### File Type Validation

```typescript
function validateFileType(
  file: File,
  allowedTypes: string[]
): boolean {
  return allowedTypes.includes(file.type);
}

// Usage
const imageTypes = ['image/jpeg', 'image/png', 'image/gif'];
if (!validateFileType(file, imageTypes)) {
  throw new Error('File must be an image');
}
```

### Generate CDN URL

```typescript
function getCdnUrl(fileId: string): string {
  return `https://cdn.heylua.ai/${fileId}`;
}
```

## Related APIs

- [Data API](./Data.md) - Store file metadata
- [User API](./User.md) - Send files to users
- [AI API](./AI.md) - Analyze uploaded images/documents

## See Also

- [File Upload Guide](../guides/FileUploads.md)
- [Media Management](../guides/MediaManagement.md)
