CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-qiniu-js

JavaScript SDK for Qiniu Cloud Storage that enables browser-based file uploads with resumable transfer, image processing, and comprehensive error handling.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

configuration.mddocs/

Configuration & Regions

Regional configuration and upload settings for optimal performance across different geographic locations, along with API management functions.

Capabilities

Regional Configuration

Qiniu Cloud Storage operates in multiple regions worldwide. Choose the appropriate region for optimal upload performance.

const region = {
  /** East China (Huadong) */
  z0: 'z0',
  /** North China (Huabei) */
  z1: 'z1',
  /** South China (Huanan) */  
  z2: 'z2',
  /** North America */
  na0: 'na0',
  /** Southeast Asia */
  as0: 'as0',
  /** East China 2 (Huadong-Zhejiang 2) */
  cnEast2: 'cn-east-2'
} as const;

Usage Examples:

import { upload, region } from "qiniu-js";

// Upload to East China region (most common)
const subscription = upload(file, key, token, {
  fname: file.name
}, {
  region: region.z0,
  useCdnDomain: true
});

// Upload to North America region for US users
const usUpload = upload(file, key, token, {
  fname: file.name
}, {
  region: region.na0,
  upprotocol: 'https'
});

// Upload to Southeast Asia for Asian users
const asiaUpload = upload(file, key, token, {
  fname: file.name
}, {
  region: region.as0
});

// Dynamic region selection based on user location
function selectOptimalRegion(userCountry: string): string {
  const regionMap: { [key: string]: string } = {
    'US': region.na0,
    'CA': region.na0,
    'SG': region.as0,
    'MY': region.as0,
    'TH': region.as0,
    'CN': region.z0,
    'default': region.z0
  };
  
  return regionMap[userCountry] || regionMap['default'];
}

Upload URL Management

Functions for managing upload endpoints and cleaning up failed uploads.

/**
 * Get the optimal upload URL for given configuration
 * @param config - Upload URL configuration
 * @param token - Upload token
 * @returns Promise resolving to upload URL
 */
function getUploadUrl(config: UploadUrlConfig, token: string): Promise<string>;

/**
 * Delete uploaded chunks from a failed or cancelled resumable upload
 * @param token - Upload token
 * @param key - Target file key
 * @param uploadinfo - Upload session information
 * @returns Promise for cleanup completion
 */
function deleteUploadedChunks(
  token: string,
  key: string | null | undefined,
  uploadinfo: UploadInfo
): Promise<ResponseSuccess<void>>;

interface UploadUrlConfig {
  /** Upload protocol */
  upprotocol?: 'https' | 'http';
  /** Custom upload host */
  uphost?: string[];
  /** Target region */
  region?: string;
  /** Use CDN domain */
  useCdnDomain?: boolean;
}

interface UploadInfo {
  /** Upload session ID */
  id: string;
  /** Upload endpoint URL */
  url: string;
}

Usage Examples:

import { getUploadUrl, deleteUploadedChunks } from "qiniu-js";

// Get upload URL for specific configuration
async function getCustomUploadUrl(token: string) {
  try {
    const uploadUrl = await getUploadUrl({
      region: 'z0',
      upprotocol: 'https',
      useCdnDomain: true
    }, token);
    
    console.log('Upload URL:', uploadUrl);
    return uploadUrl;
  } catch (error) {
    console.error('Failed to get upload URL:', error);
    throw error;
  }
}

// Clean up failed resumable upload
async function cleanupFailedUpload(token: string, key: string, uploadInfo: UploadInfo) {
  try {
    await deleteUploadedChunks(token, key, uploadInfo);
    console.log('Cleanup completed for upload session:', uploadInfo.id);
  } catch (error) {
    console.error('Cleanup failed:', error);
  }
}

// Advanced upload URL management
class UploadManager {
  private uploadUrls: Map<string, string> = new Map();
  
  async getOrCreateUploadUrl(region: string, token: string): Promise<string> {
    const cacheKey = `${region}-${token.substring(0, 10)}`;
    
    if (this.uploadUrls.has(cacheKey)) {
      return this.uploadUrls.get(cacheKey)!;
    }
    
    const url = await getUploadUrl({
      region,
      upprotocol: 'https',
      useCdnDomain: true
    }, token);
    
    this.uploadUrls.set(cacheKey, url);
    return url;
  }
  
  clearCache() {
    this.uploadUrls.clear();
  }
}

Regional Configuration Details

Region Selection Guidelines

Choose the appropriate region based on your users' geographic location for optimal performance:

RegionCodeLocationBest For
East Chinaz0ShanghaiChina mainland users
North Chinaz1BeijingNorthern China users
South Chinaz2GuangzhouSouthern China users
North Americana0USAUS and Canada users
Southeast Asiaas0SingaporeAsian users outside China
East China 2cnEast2ZhejiangBackup for East China

Region Performance Example:

import { upload, region } from "qiniu-js";

// Measure upload performance across regions
async function benchmarkRegions(file: File, token: string): Promise<void> {
  const regions = [region.z0, region.z1, region.z2, region.na0, region.as0];
  const results: { region: string; time: number; speed: number }[] = [];
  
  for (const reg of regions) {
    const startTime = Date.now();
    
    try {
      await new Promise((resolve, reject) => {
        upload(file, `benchmark-${reg}.test`, token, {}, { region: reg })
          .subscribe({
            complete: resolve,
            error: reject
          });
      });
      
      const duration = Date.now() - startTime;
      const speed = (file.size / 1024) / (duration / 1000); // KB/s
      
      results.push({
        region: reg,
        time: duration,
        speed: Math.round(speed)
      });
      
    } catch (error) {
      console.error(`Region ${reg} failed:`, error);
    }
  }
  
  // Sort by speed
  results.sort((a, b) => b.speed - a.speed);
  console.log('Region performance results:', results);
}

Upload Configuration Best Practices

Optimize upload settings for different scenarios.

import { upload, region } from "qiniu-js";

// Configuration for different use cases
const configurations = {
  // Fast uploads for small files
  smallFiles: {
    forceDirect: true,
    useCdnDomain: true,
    retryCount: 3,
    region: region.z0
  },
  
  // Reliable uploads for large files
  largeFiles: {
    chunkSize: 8, // 8MB chunks
    concurrentRequestLimit: 3,
    retryCount: 5,
    useCdnDomain: true,
    region: region.z0
  },
  
  // Conservative settings for unstable networks
  unstableNetwork: {
    chunkSize: 2, // Smaller chunks
    concurrentRequestLimit: 1,
    retryCount: 10,
    useCdnDomain: false, // Direct to origin
    region: region.z0
  },
  
  // High-performance settings for stable networks
  highPerformance: {
    chunkSize: 16, // Large chunks
    concurrentRequestLimit: 6,
    retryCount: 3,
    useCdnDomain: true,
    region: region.z0
  }
};

// Smart configuration selection
function selectConfiguration(file: File, networkQuality: 'fast' | 'normal' | 'slow') {
  const fileSize = file.size;
  const isMobile = /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
  
  if (fileSize < 4 * 1024 * 1024) { // < 4MB
    return configurations.smallFiles;
  }
  
  if (networkQuality === 'slow' || isMobile) {
    return configurations.unstableNetwork;
  }
  
  if (networkQuality === 'fast' && fileSize > 100 * 1024 * 1024) { // > 100MB
    return configurations.highPerformance;
  }
  
  return configurations.largeFiles;
}

// Usage with smart configuration
function smartUpload(file: File, key: string, token: string, networkQuality: 'fast' | 'normal' | 'slow' = 'normal') {
  const config = selectConfiguration(file, networkQuality);
  
  return upload(file, key, token, {
    fname: file.name
  }, config);
}

Custom Host Configuration

Configure custom upload hosts for enterprise deployments.

import { upload } from "qiniu-js";

// Custom host configuration
const enterpriseConfig = {
  uphost: [
    'upload.your-domain.com',
    'upload-backup.your-domain.com'
  ],
  upprotocol: 'https' as const,
  useCdnDomain: false,
  retryCount: 3
};

// Upload using custom hosts
const enterpriseUpload = upload(file, key, token, {
  fname: file.name
}, enterpriseConfig);

// Fallback configuration with multiple hosts
const redundantConfig = {
  uphost: [
    'primary-upload.example.com',
    'secondary-upload.example.com',
    'tertiary-upload.example.com'
  ],
  upprotocol: 'https' as const,
  retryCount: 5 // Will try different hosts on failure
};

Dynamic Configuration

Adapt configuration based on runtime conditions.

import { upload, region } from "qiniu-js";

class DynamicUploadConfig {
  private userLocation: string = 'unknown';
  private networkSpeed: number = 0;
  private deviceType: 'mobile' | 'desktop' = 'desktop';
  
  constructor() {
    this.detectEnvironment();
  }
  
  private detectEnvironment() {
    // Detect device type
    this.deviceType = /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) 
      ? 'mobile' : 'desktop';
    
    // Estimate network speed (simplified)
    if ('connection' in navigator) {
      const connection = (navigator as any).connection;
      this.networkSpeed = connection.downlink || 1;
    }
  }
  
  getOptimalConfig(fileSize: number) {
    const config: any = {
      useCdnDomain: true,
      upprotocol: 'https'
    };
    
    // Region selection
    config.region = this.selectRegion();
    
    // Chunk size based on network and device
    if (this.deviceType === 'mobile' || this.networkSpeed < 2) {
      config.chunkSize = 2; // 2MB for mobile/slow networks
      config.concurrentRequestLimit = 1;
    } else if (this.networkSpeed > 10) {
      config.chunkSize = 16; // 16MB for fast networks
      config.concurrentRequestLimit = 6;
    } else {
      config.chunkSize = 8; // 8MB default
      config.concurrentRequestLimit = 3;
    }
    
    // Retry logic
    config.retryCount = this.deviceType === 'mobile' ? 5 : 3;
    
    // Force direct for small files
    if (fileSize < 4 * 1024 * 1024) {
      config.forceDirect = true;
    }
    
    return config;
  }
  
  private selectRegion(): string {
    // Simplified region selection
    const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
    
    if (timezone.includes('America')) {
      return region.na0;
    } else if (timezone.includes('Asia') && !timezone.includes('China')) {
      return region.as0;
    } else {
      return region.z0; // Default to East China
    }
  }
}

// Usage
const dynamicConfig = new DynamicUploadConfig();

function adaptiveUpload(file: File, key: string, token: string) {
  const config = dynamicConfig.getOptimalConfig(file.size);
  
  console.log('Using adaptive configuration:', config);
  
  return upload(file, key, token, {
    fname: file.name
  }, config);
}

Install with Tessl CLI

npx tessl i tessl/npm-qiniu-js

docs

configuration.md

error-handling.md

image-processing.md

index.md

upload.md

utilities.md

tile.json