npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@walsync/mcs-sdk

v0.0.1

Published

TypeScript SDK for Multi-Cloud Storage - unified API for S3, Google Drive, OneDrive, Dropbox

Readme

@mcs/sdk - Multi-Cloud Storage SDK

A comprehensive TypeScript SDK for multi-cloud storage management. Supports files, folders, connections, and storage provider operations with built-in authentication, retry logic, and error handling.

Features

  • 🔐 Authentication: Support for API key and JWT authentication with auto-refresh
  • 📁 File Operations: Upload, download, copy, move, delete files
  • 📂 Folder Management: Create, list, move, copy folders with tree navigation
  • ☁️ Multi-Provider: Connect and manage multiple cloud storage providers
  • 🔄 Chunked Uploads: Large file uploads with progress tracking and resumption
  • Retry Logic: Automatic retry with exponential backoff
  • 🛡️ Type Safety: Full TypeScript support with comprehensive types
  • 📊 Progress Tracking: Real-time upload/download progress

Installation

pnpm add @mcs/sdk
# or
npm install @mcs/sdk
# or
yarn add @mcs/sdk

Quick Start

Basic Setup

import { MultiCloudStorage } from '@mcs/sdk';

// Initialize with API key
const mcs = new MultiCloudStorage({
  baseUrl: 'https://api.example.com',
  apiKey: 'your-api-key',
  organizationId: 'org-123',
});

// Or with JWT
const mcs = new MultiCloudStorage({
  baseUrl: 'https://api.example.com',
  jwtToken: 'your-jwt-token',
  onTokenRefresh: async () => {
    // Return new token
    return await refreshToken();
  },
});

File Operations

// Upload a file
const uploadResult = await mcs.files.upload(file, {
  folderId: 'folder-123',
  strategy: 'performance',
  onProgress: (progress) => {
    console.log(`Upload: ${progress.percentage}%`);
  },
});

// List files
const files = await mcs.files.list({
  folderId: 'folder-123',
  limit: 20,
  sortBy: 'name',
});

// Download file
const downloadUrl = await mcs.files.getDownloadUrl('file-123');

// Move file
await mcs.files.move('file-123', {
  targetFolderId: 'new-folder-id',
});

// Delete file
await mcs.files.delete('file-123');

Folder Operations

// Create folder
const folder = await mcs.folders.create({
  name: 'My Folder',
  parentId: null, // Root folder
});

// List folders
const folders = await mcs.folders.list({
  parentId: 'parent-folder-id',
  includeFileCount: true,
});

// Get folder tree
const tree = await mcs.folders.getTree({
  maxDepth: 3,
  includeFiles: true,
});

// Move folder
await mcs.folders.move('folder-123', {
  newParentId: 'new-parent-id',
});

Storage Providers

// List providers
const providers = await mcs.storageProviders.list();

// Get provider usage
const usage = await mcs.storageProviders.getUsage('provider-123');

// OAuth flow for Google Drive
const authUrl = await mcs.storageProviders.getAuthorizationUrl({
  providerType: 'GOOGLE_DRIVE',
  redirectUri: 'https://app.example.com/oauth/callback',
});

// Connect after OAuth callback
const connected = await mcs.storageProviders.connectWithOAuth({
  name: 'My Google Drive',
  providerType: 'GOOGLE_DRIVE',
  code: 'oauth-code',
  redirectUri: 'https://app.example.com/oauth/callback',
});

Advanced Usage

Chunked Upload for Large Files

import { ChunkedUploader, uploadFile } from '@mcs/sdk';

// Using helper function
const result = await uploadFile(mcs.files, largeFile, {
  chunkSize: 10 * 1024 * 1024, // 10MB chunks
  concurrency: 3,
  onProgress: (progress) => {
    console.log(`Part ${progress.uploadedParts}/${progress.totalParts}`);
    console.log(`Speed: ${progress.speed} bytes/sec`);
    console.log(`ETA: ${progress.estimatedTimeRemaining}s`);
  },
});

// Or using ChunkedUploader class for more control
const uploader = new ChunkedUploader(mcs.files, {
  chunkSize: 5 * 1024 * 1024,
  concurrency: 5,
  retryFailedParts: true,
  maxPartRetries: 3,
});

// Can abort upload
abortButton.onclick = () => uploader.abort();

const result = await uploader.upload(file);

Custom Authentication

import {
  AuthManager,
  LocalStorageTokenStorage,
  createJWTAuth,
} from '@mcs/sdk';

// Use localStorage for token persistence
const authManager = createJWTAuth(
  initialToken,
  async () => {
    // Refresh token logic
    const response = await fetch('/api/auth/refresh');
    const data = await response.json();
    return data.accessToken;
  },
  new LocalStorageTokenStorage('my-app-'),
);

// Listen for auth events
authManager.onAuthEvent((event) => {
  switch (event.type) {
    case 'tokenExpired':
      console.log('Token expired, refreshing...');
      break;
    case 'unauthenticated':
      window.location.href = '/login';
      break;
  }
});

Error Handling

import {
  isSDKError,
  isAuthenticationError,
  isNetworkError,
  isRateLimitError,
  SDKErrorCode,
} from '@mcs/sdk';

try {
  await mcs.files.upload(file);
} catch (error) {
  if (isAuthenticationError(error)) {
    // Handle auth error
    await redirectToLogin();
  } else if (isRateLimitError(error)) {
    // Wait and retry
    const delay = error.retryAfter || 60000;
    await sleep(delay);
    await mcs.files.upload(file);
  } else if (isNetworkError(error)) {
    // Network issue
    showOfflineMessage();
  } else if (isSDKError(error)) {
    // Other SDK errors
    switch (error.code) {
      case SDKErrorCode.FILE_TOO_LARGE:
        showError('File is too large');
        break;
      case SDKErrorCode.PROVIDER_UNAVAILABLE:
        showError('Storage provider is unavailable');
        break;
      default:
        showError(error.message);
    }
  }
}

Request Cancellation

// Create abort controller
const controller = new AbortController();

// Cancel button
cancelButton.onclick = () => controller.abort();

// Pass signal to request
const result = await uploadFile(mcs.files, file, {
  signal: controller.signal,
});

// Or cancel all requests
mcs.cancelAllRequests('User cancelled');

Configuration Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | baseUrl | string | - | API base URL (required) | | apiKey | string | - | API key for authentication | | jwtToken | string | - | JWT token for authentication | | organizationId | string | - | Organization ID for scoped operations | | timeout | number | 30000 | Request timeout in milliseconds | | maxRetries | number | 3 | Maximum retry attempts | | debug | boolean | false | Enable debug logging | | headers | object | - | Custom headers for all requests | | onUnauthorized | function | - | Callback on 401 response | | onError | function | - | Callback on any error | | onTokenRefresh | function | - | JWT refresh function | | tokenStorage | TokenStorage | MemoryTokenStorage | Token storage implementation |

API Reference

MultiCloudStorage

Main SDK class providing access to all clients.

Properties

  • files: FilesClient - File operations
  • folders: FoldersClient - Folder operations
  • connections: ConnectionsClient - Connection management
  • storageProviders: StorageProvidersClient - Provider management
  • auth: AuthManager - Authentication manager
  • http: HttpClient - HTTP client for direct requests

Methods

  • setOrganization(id: string) - Set organization context
  • setJwtToken(token: string) - Update JWT token
  • setApiKey(key: string) - Update API key
  • logout() - Clear authentication
  • on(handler) - Subscribe to SDK events
  • cancelAllRequests(reason?) - Cancel pending requests
  • destroy() - Clean up resources

FilesClient

  • upload(file, options?) - Upload a file
  • list(query?) - List files with pagination
  • get(fileId) - Get file details
  • search(query) - Search files
  • move(fileId, request) - Move file
  • copy(fileId, request) - Copy file
  • rename(fileId, newName) - Rename file
  • delete(fileId) - Delete file
  • getDownloadUrl(fileId) - Get presigned download URL
  • bulkDelete(request) - Delete multiple files
  • bulkMove(request) - Move multiple files
  • bulkCopy(request) - Copy multiple files

FoldersClient

  • create(request) - Create folder
  • list(query?) - List folders
  • get(folderId) - Get folder details
  • update(folderId, request) - Update folder
  • delete(folderId, force?) - Delete folder
  • move(folderId, request) - Move folder
  • copy(folderId, request) - Copy folder
  • getTree(query?) - Get folder tree
  • getBreadcrumbs(folderId) - Get folder path
  • getStats(folderId) - Get folder statistics

StorageProvidersClient

  • list() - List all providers
  • get(providerId) - Get provider details
  • create(request) - Create provider
  • update(providerId, request) - Update provider
  • delete(providerId) - Delete provider
  • testConnection(providerId) - Test provider connection
  • getUsage(providerId) - Get storage usage
  • getAuthorizationUrl(request) - Get OAuth URL
  • connectWithOAuth(request) - Connect via OAuth
  • refreshOAuthTokens(providerId) - Refresh OAuth tokens
  • disconnectProvider(providerId) - Disconnect provider

Error Types

| Error Class | Description | |-------------|-------------| | SDKError | Base error class | | NetworkError | Network connectivity issues | | TimeoutError | Request timeout | | AuthenticationError | Authentication failures | | AuthorizationError | Permission denied | | ValidationError | Request validation errors | | NotFoundError | Resource not found | | ConflictError | Resource conflicts | | ProviderError | Storage provider errors | | RateLimitError | Rate limit exceeded | | UploadError | File upload errors | | DownloadError | File download errors | | OAuthError | OAuth flow errors | | MigrationError | Migration errors | | ServerError | Server-side errors |

License

MIT