> ## Documentation Index
> Fetch the complete documentation index at: https://docs.apexxcloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# JavaScript SDK

> Documentation for ApexxCloud JavaScript SDK

## Installation

<CodeGroup>
  ```bash npm theme={null}
  npm install @apexxcloud/sdk-js
  ```

  ```bash yarn theme={null}
  yarn add @apexxcloud/sdk-js
  ```
</CodeGroup>

## Initialization

```javascript theme={null}
import ApexxCloud from "@apexxcloud/sdk-js";

const storage = new ApexxCloud({
  baseUrl: "https://api.apexxcloud.com", // optional
});
```

## Backend Implementation

Your backend needs to implement an endpoint that generates signed URLs. Here's an example using Node.js:

```javascript theme={null}
const ApexxCloud = require("@apexxcloud/sdk-node");

const storage = new ApexxCloud({
  accessKey: process.env.APEXXCLOUD_ACCESS_KEY,
  secretKey: process.env.APEXXCLOUD_SECRET_KEY,
  region: "bucket-region",
  bucket: "bucket-name",
});

app.post("/api/get-signed-url/:type", async (req, res) => {
  try {
    const { type } = req.params;
    const params = req.body; // Contains key, mimeType, totalParts, etc.

    const signedUrl = await storage.getSignedUrl(
      "your-bucket-name",
      params.key,
      {
        type: type,
        ...params,
      }
    );

    res.send(signedUrl);
  } catch (error) {
    res.status(500).send(error.message);
  }
});
```

The endpoint should handle these types of requests:

| Type | Description | Required Parameters | Example Response |
| - | - | - | - |
| upload | Single file upload | key, mimeType | `https://api.apexxcloud.com/upload?signature=...` |
| start-multipart | Start multipart upload | key, totalParts, mimeType | `https://api.apexxcloud.com/multipart/start?signature=...` |
| uploadpart | Upload individual part | uploadId, partNumber, key, totalParts | `https://api.apexxcloud.com/multipart/{uploadId}/upload?signature=...` |
| completemultipart | Complete multipart upload | uploadId, key | `https://api.apexxcloud.com/multipart/{uploadId}/complete?signature=...` |
| cancelmultipart | Cancel multipart upload | uploadId, key | `https://api.apexxcloud.com/multipart/{uploadId}/cancel?signature=...` |

## File Upload

### Basic Upload

```javascript theme={null}
const controller = new AbortController();

// Function to get signed URLs from your backend
const getSignedUrl = async (type, params) => {
  const response = await fetch(`/api/get-signed-url/${type}`, {
    method: "POST",
    body: JSON.stringify(params),
  });
  return response.text();
};

try {
  const result = await storage.files.upload(getSignedUrl, file, {
    signal: controller.signal,

    onStart: (event) => {
      console.log("Upload started:", event);
      // event.type: 'start'
      // event.timestamp: Start time
      // event.file: {
      //   name: string,
      //   size: number,
      //   type: string
      // }
    },

    onProgress: (event) => {
      console.log(`Upload progress: ${event.progress}%`);
      // event.loaded: Bytes uploaded
      // event.total: Total bytes
      // event.progress: Percentage complete (0-100)
      // event.type: 'progress'
    },

    onComplete: (event) => {
      console.log("Upload completed:", event);
      // event.type: 'complete'
      // event.response: Server response
      // event.timestamp: Completion time
      // event.file: File metadata
    },

    onError: (event) => {
      console.error("Upload failed:", event);
      // event.type: 'error' | 'abort'
      // event.error: Error object
      // event.timestamp: Error time
      // event.status?: HTTP status code (if applicable)
    },
  });
} catch (error) {
  console.error("Upload failed:", error);
}

// To cancel the upload:
controller.abort();
```

### Multipart Upload

```javascript theme={null}
const controller = new AbortController();

try {
  const result = await storage.files.uploadMultipart(getSignedUrl, file, {
    signal: controller.signal,
    partSize: 5 * 1024 * 1024, // 5MB chunks (optional)
    concurrency: 3, // Number of concurrent uploads (optional)

    onProgress: (event) => {
      console.log(`Total progress: ${event.progress}%`);
      console.log(
        `Part ${event.part.number} progress: ${event.part.progress}%`
      );
      // event.loaded: Total bytes uploaded
      // event.total: Total file size
      // event.progress: Overall percentage
      // event.part: {
      //   number: Current part number
      //   progress: Current part progress (0-100)
      // }
    },

    onPartComplete: (part) => {
      console.log("Part completed:", part);
      // part.ETag: Part ETag from server
      // part.PartNumber: Completed part number
    },

    onComplete: (event) => {
      console.log("Upload completed:", event);
      // event.type: 'complete'
      // event.response: Server response
      // event.timestamp: Completion time
      // event.file: File metadata
    },

    onError: (event) => {
      console.error("Upload error:", event);
      // event.type: 'error' | 'abort'
      // event.error: Error object
      // event.phase: 'start' | 'upload' | 'complete' | 'cancel'
      // event.status?: HTTP status code (if applicable)
      // event.timestamp: Error time
    },
  });
} catch (error) {
  console.error("Upload failed:", error);
}
```

### Error Handling

The SDK provides detailed error information through the onError callback:

```javascript theme={null}
try {
  await storage.files.upload(getSignedUrl, file, {
    onError: (event) => {
      if (event.type === "abort") {
        console.log("Upload was cancelled");
      } else {
        console.error("Upload failed:", event.error.message);
        if (event.status) {
          console.error("HTTP Status:", event.status);
        }
        if (event.phase) {
          // For multipart uploads
          console.error("Failed during phase:", event.phase);
        }
      }
    },
  });
} catch (error) {
  console.error("Upload failed:", error.message);
}
```

### Multipart Upload Phases

The multipart upload process includes different phases where errors might occur:

| Phase | Description |
| - | - |
| start | During the initialization of multipart upload |
| upload | During the upload of individual parts |
| complete | During the completion of multipart upload |
| cancel | During attempt to cancel a failed upload |

## Image Transformations

The SDK provides a powerful image transformation API that allows you to modify images on-the-fly:

```javascript theme={null}
const storage = new ApexxCloud({
  accessId: "your-access-id",
  cdnUrl: "https://cdn.apexxcloud.com", // optional
});

// Basic transformations
const url = storage.transformimage
  .width(800)
  .height(600)
  .crop("fill")
  .quality("auto:good")
  .buildUrl("path/to/image.jpg");

// Chaining multiple transformations
const complexUrl = storage.transformimage
  .width(800)
  .height(600)
  .crop("fill")
  .chain()
  .blur(20)
  .grayscale()
  .buildUrl("path/to/image.jpg");

// Text overlay
const withText = storage.transformimage
  .text("Hello World", {
    font: "Arial",
    size: 32,
    color: "#FFFFFF",
    gravity: "center",
    opacity: 100,
  })
  .buildUrl("path/to/image.jpg");

// Image overlay
const withImage = storage.transformimage
  .overlay("path/to/logo.png", {
    type: "image",
    gravity: "southeast",
    x: 20,
    y: 20,
    width: 100,
    opacity: 80,
  })
  .buildUrl("path/to/image.jpg");
```

### Available Image Transformations

| Transformation | Method | Parameters | Example |
| - | - | - | - |
| Width | `width(value)` | 1-5000px | `.width(800)` |
| Height | `height(value)` | 1-5000px | `.height(600)` |
| Crop | `crop(mode)` | 'fill', 'fit', 'scale' | `.crop('fill')` |
| Quality | `quality(value)` | 1-100 or auto modes | `.quality('auto:good')` |
| Format | `format(type)` | 'auto', 'webp', 'jpeg' | `.format('webp')` |
| Blur | `blur(radius)` | 1-100 | `.blur(20)` |
| Grayscale | `grayscale()` | - | `.grayscale()` |
| Background | `background(color)` | hex or 'transparent' | `.background('#ff0000')` |
| Border | `border(width, style, color)` | width, style, color | `.border(2, 'solid', '#000')` |
| Radius | `radius(value)` | pixels or array | `.radius(10)` |
| Opacity | `opacity(value)` | 0-100 | `.opacity(50)` |
| Text Overlay | `text(text, options)` | text, options | `.text('Hello', options)` |
| Image Overlay | `overlay(path, options)` | path, options | `.overlay('logo.png', options)` |

### Overlay Options

| Option | Type | Description | Supported Types |
| - | - | - | - |
| `type` | string | 'image' or 'video' | Video only |
| `gravity` | string | Position on target | All |
| `x` | number | Horizontal offset | All |
| `y` | number | Vertical offset | All |
| `scale` | number | Scale factor | Image, Video |
| `width` | number | Width in pixels | Image, Video |
| `height` | number | Height in pixels | Image, Video |
| `opacity` | number | Opacity (0-100) | All |
| `aspectRatio` | string | Aspect ratio | Image, Video |

Text-specific options:

| Option | Type | Description |
| - | - | - |
| `font` | string | Font family name |
| `size` | number | Font size in pixels |
| `color` | string | Text color (hex) |

## Video Transformations

Similar to images, you can transform videos:

```javascript theme={null}
// Basic video transformation
const videoUrl = storage.transformvideo
  .width(1280)
  .height(720)
  .format("mp4")
  .buildUrl("path/to/video.mp4");

// Generate video thumbnail
const thumbnailUrl = storage.transformvideo
  .thumbnail(5.0) // Seek to 5 seconds
  .width(400)
  .height(300)
  .crop("fill")
  .buildUrl("path/to/video.mp4");

// Text overlay
const withText = storage.transformvideo
  .text("Hello World", {
    font: "Arial",
    size: 32,
    color: "#FFFFFF",
    gravity: "center",
    opacity: 100,
  })
  .buildUrl("path/to/video.mp4");

// Image overlay
const withImage = storage.transformvideo
  .overlay("path/to/logo.png", {
    type: "image",
    gravity: "southeast",
    x: 20,
    y: 20,
    width: 100,
    opacity: 80,
  })
  .buildUrl("path/to/video.mp4");

// Video overlay (for videos only)
const withVideoOverlay = storage.transformvideo
  .overlay("path/to/overlay.mp4", {
    type: "video",
    gravity: "center",
    width: 200,
    height: 200,
    opacity: 70,
  })
  .buildUrl("path/to/video.mp4");
```

### Available Video Transformations

| Transformation | Method | Parameters | Example |
| - | - | - | - |
| Width | `width(value)` | 1-5000px | `.width(1280)` |
| Height | `height(value)` | 1-5000px | `.height(720)` |
| Format | `format(type)` | 'mp4', 'webm', 'mov' | `.format('mp4')` |
| Thumbnail | `thumbnail(seekOffset)` | seconds | `.thumbnail(5.0)` |
| Crop | `crop(mode)` | 'crop', 'fill', 'fit' | `.crop('fill')` |
| Background | `background(color)` | hex or 'blur' | `.background('blur')` |
| Text Overlay | `text(text, options)` | text, options | `.text('Title', options)` |
| Image Overlay | `overlay(path, options)` | path, options | `.overlay('logo.png', imageOpts)` |
| Video Overlay | `overlay(path, options)` | path, options | `.overlay('intro.mp4', videoOpts)` |

### Overlay Options

| Option | Type | Description | Supported Types |
| - | - | - | - |
| `type` | string | 'image' or 'video' | Video only |
| `gravity` | string | Position on target | All |
| `x` | number | Horizontal offset | All |
| `y` | number | Vertical offset | All |
| `scale` | number | Scale factor | Image, Video |
| `width` | number | Width in pixels | Image, Video |
| `height` | number | Height in pixels | Image, Video |
| `opacity` | number | Opacity (0-100) | All |
| `aspectRatio` | string | Aspect ratio | Image, Video |

Text-specific options:

| Option | Type | Description |
| - | - | - |
| `font` | string | Font family name |
| `size` | number | Font size in pixels |
| `color` | string | Text color (hex) |

## Document Transformations

Transform and convert documents:

```javascript theme={null}
// Convert document format
const pdfUrl = storage.transformdocument
  .format("pdf")
  .quality("auto:high")
  .buildUrl("path/to/document.docx");

// Generate document thumbnail
const thumbnailUrl = storage.transformdocument
  .thumbnail(1) // First page
  .width(800)
  .height(1200)
  .buildUrl("path/to/document.pdf");
```

### Available Document Transformations

| Transformation | Method | Parameters | Example |
| - | - | - | - |
| Format | `format(type)` | 'pdf', 'docx', 'xlsx', 'pptx' | `.format('pdf')` |
| Quality | `quality(mode)` | 'auto:high', 'auto:standard', 'auto:low' | `.quality('auto:high')` |
| Compress | `compress(mode)` | 'high', 'medium', 'low' | `.compress('medium')` |
| Pages | `pages(range)` | number or range ('1-3,5-7') | `.pages('1-3')` |
| Thumbnail | `thumbnail(page)` | Page number | `.thumbnail(1)` |

### Chaining Transformations

You can chain multiple transformations together using the `chain()` method:

```javascript theme={null}
const url = storage.transformimage
  .width(800)
  .height(600)
  .crop("fill")
  .chain()
  .blur(20)
  .grayscale()
  .buildUrl("path/to/image.jpg");
```

Each transformation chain is applied sequentially, allowing for complex transformation pipelines.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.