or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration.mderror-handling.mdimage-processing.mdindex.mdupload.mdutilities.md

upload.mddocs/

0

# File Upload

1

2

Core file upload functionality with automatic upload strategy selection, progress tracking, and resume capabilities for large files.

3

4

## Capabilities

5

6

### Upload Function

7

8

Main upload function that automatically selects between direct upload (≤4MB) and resumable chunked upload (>4MB).

9

10

```typescript { .api }

11

/**

12

* Upload a file to Qiniu Cloud Storage

13

* @param file - File object to upload

14

* @param key - Target filename, null for auto-generated key

15

* @param token - Upload token from server

16

* @param putExtra - Optional upload metadata and custom variables

17

* @param config - Optional upload configuration

18

* @returns Observable for tracking upload progress and completion

19

*/

20

function upload(

21

file: File,

22

key: string | null | undefined,

23

token: string,

24

putExtra?: Partial<Extra>,

25

config?: Config

26

): Observable<UploadProgress, QiniuError | QiniuRequestError | QiniuNetworkError, UploadCompleteData>;

27

```

28

29

**Usage Examples:**

30

31

```typescript

32

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

33

34

// Basic upload with minimal configuration

35

const file = document.getElementById('fileInput').files[0];

36

const token = await getTokenFromServer(); // Your server implementation

37

38

const subscription = upload(file, null, token).subscribe({

39

next: (progress) => {

40

console.log(`Upload progress: ${progress.total.percent.toFixed(1)}%`);

41

console.log(`Uploaded: ${progress.total.loaded} / ${progress.total.size} bytes`);

42

},

43

error: (error) => {

44

if (error instanceof QiniuRequestError) {

45

console.error(`Request failed with code ${error.code}:`, error.message);

46

} else if (error instanceof QiniuNetworkError) {

47

console.error('Network error:', error.message);

48

} else {

49

console.error('Upload error:', error.message);

50

}

51

},

52

complete: (response) => {

53

console.log('Upload completed successfully:', response);

54

// response contains server response data

55

}

56

});

57

58

// Upload with custom variables and metadata

59

const uploadWithMetadata = upload(file, 'user-photos/avatar.jpg', token, {

60

fname: file.name,

61

customVars: {

62

'x:userId': '12345',

63

'x:uploadSource': 'profile-page'

64

},

65

metadata: {

66

'x-qn-meta-author': 'John Doe',

67

'x-qn-meta-description': 'Profile avatar'

68

},

69

mimeType: 'image/jpeg'

70

}, {

71

region: region.z0,

72

useCdnDomain: true,

73

retryCount: 5,

74

chunkSize: 8, // 8MB chunks for large files

75

concurrentRequestLimit: 3

76

});

77

```

78

79

### Upload Configuration

80

81

Configuration options for controlling upload behavior and performance.

82

83

```typescript { .api }

84

interface Config {

85

/** Enable CDN domain for uploads (recommended) */

86

useCdnDomain?: boolean;

87

/** Upload region selection */

88

region?: typeof region[keyof typeof region];

89

/** Force direct upload even for large files */

90

forceDirect?: boolean;

91

/** Number of retry attempts on failure */

92

retryCount?: number;

93

/** Chunk size in MB for resumable uploads */

94

chunkSize?: number;

95

/** Maximum concurrent upload requests */

96

concurrentRequestLimit?: number;

97

/** Upload protocol */

98

upprotocol?: 'https' | 'http';

99

/** Disable statistics reporting */

100

disableStatisticsReport?: boolean;

101

}

102

```

103

104

### Upload Metadata

105

106

Additional information and custom data for uploads.

107

108

```typescript { .api }

109

interface Extra {

110

/** Original filename */

111

fname: string;

112

/** Custom variables (must start with 'x:') */

113

customVars?: { [key: string]: string };

114

/** Metadata (must start with 'x-qn-meta-') */

115

metadata?: { [key: string]: string };

116

/** MIME type override */

117

mimeType?: string;

118

}

119

```

120

121

**Custom Variables Example:**

122

123

```typescript

124

// Custom variables for application use

125

const putExtra = {

126

fname: 'document.pdf',

127

customVars: {

128

'x:userId': '12345',

129

'x:category': 'documents',

130

'x:public': 'false'

131

},

132

metadata: {

133

'x-qn-meta-title': 'Important Document',

134

'x-qn-meta-author': 'Jane Smith'

135

}

136

};

137

```

138

139

### Upload Progress Tracking

140

141

Detailed progress information during upload operations.

142

143

```typescript { .api }

144

interface UploadProgress {

145

/** Overall upload progress */

146

total: ProgressCompose;

147

/** Upload session information for resumable uploads */

148

uploadInfo?: UploadInfo;

149

/** Individual chunk progress for large files */

150

chunks?: ProgressCompose[];

151

}

152

153

interface ProgressCompose {

154

/** Total size in bytes */

155

size: number;

156

/** Bytes uploaded so far */

157

loaded: number;

158

/** Completion percentage (0-100) */

159

percent: number;

160

/** Whether data was loaded from cache (resume) */

161

fromCache?: boolean;

162

}

163

164

interface UploadInfo {

165

/** Upload session ID for resumable uploads */

166

id: string;

167

/** Upload endpoint URL */

168

url: string;

169

}

170

```

171

172

### Observable Interface

173

174

Upload function returns an Observable for reactive programming patterns.

175

176

```typescript { .api }

177

interface Observable<T, E, R> {

178

subscribe(observer: {

179

next?: (value: T) => void;

180

error?: (error: E) => void;

181

complete?: (result: R) => void;

182

}): Subscription;

183

}

184

185

interface Subscription {

186

/** Cancel the upload operation */

187

unsubscribe(): void;

188

}

189

```

190

191

**Advanced Usage Example:**

192

193

```typescript

194

import { upload, QiniuRequestError, QiniuNetworkError } from "qiniu-js";

195

196

let uploadSubscription;

197

198

function startUpload(file, token) {

199

uploadSubscription = upload(file, null, token, {

200

fname: file.name

201

}, {

202

region: region.z2,

203

retryCount: 3,

204

chunkSize: 4

205

}).subscribe({

206

next: (progress) => {

207

updateProgressBar(progress.total.percent);

208

209

// Show chunk details for large files

210

if (progress.chunks) {

211

progress.chunks.forEach((chunk, index) => {

212

console.log(`Chunk ${index}: ${chunk.percent}% ${chunk.fromCache ? '(cached)' : ''}`);

213

});

214

}

215

},

216

error: (error) => {

217

if (error instanceof QiniuRequestError) {

218

// Server returned an error

219

handleServerError(error.code, error.data);

220

} else if (error instanceof QiniuNetworkError) {

221

// Network connectivity issue

222

handleNetworkError();

223

} else {

224

// Other errors (validation, file issues, etc.)

225

handleGenericError(error.message);

226

}

227

},

228

complete: (response) => {

229

// Upload successful

230

console.log('File uploaded successfully:', response);

231

}

232

});

233

}

234

235

function cancelUpload() {

236

if (uploadSubscription) {

237

uploadSubscription.unsubscribe();

238

console.log('Upload cancelled');

239

}

240

}

241

```