or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

body-processing.mderror-handling.mdfile-blob.mdheaders.mdhttp-client.mdindex.mdrequest-response.mdutilities.md

file-blob.mddocs/

0

# File and Blob Operations

1

2

Integration with file system and blob operations for uploading files and handling binary data. node-fetch re-exports classes and utilities from the fetch-blob package for comprehensive file handling.

3

4

## Capabilities

5

6

### Blob Class

7

8

Web-compatible Blob implementation for handling binary data with MIME type support.

9

10

```javascript { .api }

11

/**

12

* Blob implementation for binary data handling

13

*/

14

class Blob {

15

constructor(blobParts?: BlobPart[], options?: BlobPropertyBag);

16

17

readonly size: number;

18

readonly type: string;

19

20

arrayBuffer(): Promise<ArrayBuffer>;

21

stream(): ReadableStream<Uint8Array>;

22

text(): Promise<string>;

23

slice(start?: number, end?: number, contentType?: string): Blob;

24

}

25

26

interface BlobPropertyBag {

27

type?: string;

28

endings?: 'transparent' | 'native';

29

}

30

31

type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob;

32

```

33

34

**Usage Examples:**

35

36

```javascript

37

import { Blob } from 'node-fetch';

38

39

// Create blob from string

40

const textBlob = new Blob(['Hello, World!'], { type: 'text/plain' });

41

console.log('Size:', textBlob.size); // 13

42

console.log('Type:', textBlob.type); // 'text/plain'

43

44

// Create blob from binary data

45

const binaryData = new Uint8Array([0x48, 0x65, 0x6c, 0x6c, 0x6f]); // "Hello"

46

const binaryBlob = new Blob([binaryData], { type: 'application/octet-stream' });

47

48

// Create blob from multiple parts

49

const multipartBlob = new Blob([

50

'Data: ',

51

binaryData,

52

'\nEnd of data'

53

], { type: 'text/plain' });

54

55

// Read blob content

56

const text = await textBlob.text();

57

console.log(text); // 'Hello, World!'

58

59

const buffer = await textBlob.arrayBuffer();

60

console.log(new Uint8Array(buffer)); // [72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33]

61

```

62

63

### File Class

64

65

Extended Blob class with file metadata like name and modification time.

66

67

```javascript { .api }

68

/**

69

* File implementation extending Blob with file metadata

70

*/

71

class File extends Blob {

72

constructor(fileBits: BlobPart[], fileName: string, options?: FilePropertyBag);

73

74

readonly name: string;

75

readonly lastModified: number;

76

readonly webkitRelativePath: string;

77

}

78

79

interface FilePropertyBag extends BlobPropertyBag {

80

lastModified?: number;

81

}

82

```

83

84

**Usage Examples:**

85

86

```javascript

87

import { File } from 'node-fetch';

88

89

// Create file from string content

90

const textFile = new File(['File content'], 'example.txt', {

91

type: 'text/plain',

92

lastModified: Date.now()

93

});

94

95

console.log('Name:', textFile.name); // 'example.txt'

96

console.log('Size:', textFile.size); // 12

97

console.log('Type:', textFile.type); // 'text/plain'

98

console.log('Modified:', textFile.lastModified);

99

100

// Create JSON file

101

const jsonData = { name: 'Alice', age: 30 };

102

const jsonFile = new File([JSON.stringify(jsonData)], 'data.json', {

103

type: 'application/json'

104

});

105

106

// Use with FormData for file uploads

107

const formData = new FormData();

108

formData.append('upload', textFile);

109

formData.append('metadata', jsonFile);

110

111

const response = await fetch('https://httpbin.org/post', {

112

method: 'POST',

113

body: formData

114

});

115

```

116

117

### File System Integration

118

119

Utilities for creating Blob and File objects from file system paths.

120

121

```javascript { .api }

122

/**

123

* Create File from file system path (async)

124

* @param path - File system path

125

* @param type - MIME type (optional, auto-detected if not provided)

126

* @returns Promise resolving to File object

127

*/

128

function fileFrom(path: string, type?: string): Promise<File>;

129

130

/**

131

* Create File from file system path (sync)

132

* @param path - File system path

133

* @param type - MIME type (optional, auto-detected if not provided)

134

* @returns File object

135

*/

136

function fileFromSync(path: string, type?: string): File;

137

138

/**

139

* Create Blob from file system path (async)

140

* @param path - File system path

141

* @param type - MIME type (optional, auto-detected if not provided)

142

* @returns Promise resolving to Blob object

143

*/

144

function blobFrom(path: string, type?: string): Promise<Blob>;

145

146

/**

147

* Create Blob from file system path (sync)

148

* @param path - File system path

149

* @param type - MIME type (optional, auto-detected if not provided)

150

* @returns Blob object

151

*/

152

function blobFromSync(path: string, type?: string): Blob;

153

```

154

155

**Usage Examples:**

156

157

```javascript

158

import { fileFrom, fileFromSync, blobFrom, blobFromSync } from 'node-fetch';

159

160

// Async file loading

161

const imageFile = await fileFrom('./image.jpg', 'image/jpeg');

162

console.log('File name:', imageFile.name); // 'image.jpg'

163

console.log('File size:', imageFile.size); // File size in bytes

164

console.log('File type:', imageFile.type); // 'image/jpeg'

165

166

// Sync file loading

167

const textFile = fileFromSync('./document.txt', 'text/plain');

168

169

// Auto-detect MIME type

170

const autoFile = await fileFrom('./data.json'); // Type will be 'application/json'

171

172

// Create blob from file

173

const documentBlob = await blobFrom('./document.pdf');

174

console.log('Blob type:', documentBlob.type); // 'application/pdf'

175

176

// Use with fetch for file uploads

177

const uploadFile = await fileFrom('./upload.png', 'image/png');

178

179

const formData = new FormData();

180

formData.append('file', uploadFile);

181

182

const response = await fetch('https://httpbin.org/post', {

183

method: 'POST',

184

body: formData

185

});

186

```

187

188

### FormData Integration

189

190

Using File and Blob objects with FormData for multipart uploads.

191

192

```javascript { .api }

193

/**

194

* FormData class for multipart/form-data requests

195

*/

196

class FormData {

197

append(name: string, value: string | Blob | File, filename?: string): void;

198

delete(name: string): void;

199

get(name: string): FormDataEntryValue | null;

200

getAll(name: string): FormDataEntryValue[];

201

has(name: string): boolean;

202

set(name: string, value: string | Blob | File, filename?: string): void;

203

forEach(callback: (value: FormDataEntryValue, key: string, parent: FormData) => void): void;

204

entries(): IterableIterator<[string, FormDataEntryValue]>;

205

keys(): IterableIterator<string>;

206

values(): IterableIterator<FormDataEntryValue>;

207

}

208

209

type FormDataEntryValue = string | File;

210

```

211

212

**Usage Examples:**

213

214

```javascript

215

import { FormData, fileFrom } from 'node-fetch';

216

217

// Create form with file uploads

218

const formData = new FormData();

219

220

// Add text fields

221

formData.append('username', 'alice');

222

formData.append('description', 'Profile update');

223

224

// Add file from file system

225

const avatarFile = await fileFrom('./avatar.jpg', 'image/jpeg');

226

formData.append('avatar', avatarFile);

227

228

// Add file created in memory

229

const jsonFile = new File([JSON.stringify({ key: 'value' })], 'config.json', {

230

type: 'application/json'

231

});

232

formData.append('config', jsonFile);

233

234

// Add blob data

235

const binaryBlob = new Blob([new Uint8Array([1, 2, 3, 4])], {

236

type: 'application/octet-stream'

237

});

238

formData.append('data', binaryBlob, 'binary-data.bin');

239

240

// Upload form data

241

const response = await fetch('https://httpbin.org/post', {

242

method: 'POST',

243

body: formData

244

// Content-Type header is set automatically with boundary

245

});

246

247

const result = await response.json();

248

console.log('Files uploaded:', Object.keys(result.files));

249

```

250

251

### Stream Integration

252

253

Working with streams for efficient file processing and uploads.

254

255

```javascript { .api }

256

interface StreamOperations {

257

stream(): ReadableStream<Uint8Array>;

258

arrayBuffer(): Promise<ArrayBuffer>;

259

}

260

```

261

262

**Usage Examples:**

263

264

```javascript

265

import { createReadStream } from 'fs';

266

import { pipeline } from 'stream/promises';

267

268

// Stream file upload

269

const fileStream = createReadStream('./large-file.zip');

270

271

const response = await fetch('https://httpbin.org/post', {

272

method: 'POST',

273

body: fileStream,

274

headers: {

275

'Content-Type': 'application/zip'

276

}

277

});

278

279

// Process blob as stream

280

const imageBlob = await blobFrom('./image.jpg');

281

const stream = imageBlob.stream();

282

283

// Transform stream data

284

const reader = stream.getReader();

285

const chunks = [];

286

287

while (true) {

288

const { done, value } = await reader.read();

289

if (done) break;

290

291

chunks.push(value);

292

console.log('Read chunk:', value.length, 'bytes');

293

}

294

295

const totalData = new Uint8Array(chunks.reduce((acc, chunk) => acc + chunk.length, 0));

296

let offset = 0;

297

for (const chunk of chunks) {

298

totalData.set(chunk, offset);

299

offset += chunk.length;

300

}

301

302

// Use with pipeline for efficient processing

303

const sourceBlob = await blobFrom('./input.txt');

304

const destinationStream = createWriteStream('./output.txt');

305

306

await pipeline(sourceBlob.stream(), destinationStream);

307

console.log('File copied successfully');

308

```

309

310

### File Upload Patterns

311

312

Common patterns for uploading files with progress tracking and error handling.

313

314

```javascript { .api }

315

interface FileUploadPattern {

316

uploadSingleFile(file: File, url: string): Promise<Response>;

317

uploadMultipleFiles(files: File[], url: string): Promise<Response>;

318

uploadWithProgress(file: File, url: string, onProgress: (progress: number) => void): Promise<Response>;

319

}

320

```

321

322

**Usage Examples:**

323

324

```javascript

325

// Single file upload

326

async function uploadFile(filePath, uploadUrl) {

327

const file = await fileFrom(filePath);

328

329

const formData = new FormData();

330

formData.append('file', file);

331

332

const response = await fetch(uploadUrl, {

333

method: 'POST',

334

body: formData

335

});

336

337

if (!response.ok) {

338

throw new Error(`Upload failed: ${response.status} ${response.statusText}`);

339

}

340

341

return await response.json();

342

}

343

344

// Multiple file upload

345

async function uploadFiles(filePaths, uploadUrl) {

346

const formData = new FormData();

347

348

for (let i = 0; i < filePaths.length; i++) {

349

const file = await fileFrom(filePaths[i]);

350

formData.append(`file${i}`, file);

351

}

352

353

return await fetch(uploadUrl, {

354

method: 'POST',

355

body: formData

356

});

357

}

358

359

// File upload with custom metadata

360

async function uploadWithMetadata(filePath, metadata, uploadUrl) {

361

const file = await fileFrom(filePath);

362

363

const formData = new FormData();

364

formData.append('file', file);

365

formData.append('metadata', JSON.stringify(metadata));

366

formData.append('timestamp', new Date().toISOString());

367

368

return await fetch(uploadUrl, {

369

method: 'POST',

370

body: formData

371

});

372

}

373

374

// Usage examples

375

try {

376

// Upload single file

377

const result = await uploadFile('./document.pdf', 'https://api.example.com/upload');

378

console.log('Upload successful:', result);

379

380

// Upload multiple files

381

const multiResult = await uploadFiles([

382

'./image1.jpg',

383

'./image2.png',

384

'./document.txt'

385

], 'https://api.example.com/upload/batch');

386

387

// Upload with metadata

388

const metaResult = await uploadWithMetadata('./data.csv', {

389

category: 'reports',

390

department: 'sales',

391

confidential: false

392

}, 'https://api.example.com/upload/data');

393

394

} catch (error) {

395

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

396

}

397

```

398

399

### Binary Data Handling

400

401

Advanced patterns for working with binary data and custom file formats.

402

403

```javascript { .api }

404

interface BinaryDataHandling {

405

processBinaryFile(path: string): Promise<ProcessedData>;

406

createCustomFile(data: Uint8Array, metadata: FileMetadata): File;

407

validateFileFormat(file: File): Promise<boolean>;

408

}

409

```

410

411

**Usage Examples:**

412

413

```javascript

414

// Process binary file with custom format

415

async function processBinaryFile(filePath) {

416

const blob = await blobFrom(filePath);

417

const buffer = await blob.arrayBuffer();

418

const data = new Uint8Array(buffer);

419

420

// Example: Read custom header (first 16 bytes)

421

const header = data.slice(0, 16);

422

const magic = new TextDecoder().decode(header.slice(0, 4));

423

424

if (magic !== 'MYMT') { // Custom magic bytes

425

throw new Error('Invalid file format');

426

}

427

428

const version = data[4];

429

const flags = data[5];

430

const dataLength = new DataView(buffer).getUint32(6, true); // Little endian

431

432

return {

433

magic,

434

version,

435

flags,

436

dataLength,

437

data: data.slice(16) // Actual data starts after header

438

};

439

}

440

441

// Create custom binary file

442

function createBinaryFile(content, filename) {

443

// Create header

444

const header = new Uint8Array(16);

445

const encoder = new TextEncoder();

446

447

// Magic bytes

448

header.set(encoder.encode('MYMT'), 0);

449

450

// Version and flags

451

header[4] = 1; // Version

452

header[5] = 0; // Flags

453

454

// Data length (little endian)

455

const view = new DataView(header.buffer);

456

view.setUint32(6, content.length, true);

457

458

// Combine header and content

459

const fileData = new Uint8Array(header.length + content.length);

460

fileData.set(header, 0);

461

fileData.set(content, header.length);

462

463

return new File([fileData], filename, {

464

type: 'application/octet-stream'

465

});

466

}

467

468

// Validate file format

469

async function validateImageFile(file) {

470

if (!file.type.startsWith('image/')) {

471

return false;

472

}

473

474

const buffer = await file.arrayBuffer();

475

const data = new Uint8Array(buffer);

476

477

// Check for common image format signatures

478

if (data.length < 4) return false;

479

480

// JPEG

481

if (data[0] === 0xFF && data[1] === 0xD8 && data[2] === 0xFF) {

482

return true;

483

}

484

485

// PNG

486

if (data[0] === 0x89 && data[1] === 0x50 && data[2] === 0x4E && data[3] === 0x47) {

487

return true;

488

}

489

490

// GIF

491

if ((data[0] === 0x47 && data[1] === 0x49 && data[2] === 0x46) &&

492

(data[3] === 0x38 && (data[4] === 0x37 || data[4] === 0x39))) {

493

return true;

494

}

495

496

return false;

497

}

498

499

// Usage

500

const customFile = createBinaryFile(

501

new TextEncoder().encode('Hello, World!'),

502

'custom-data.bin'

503

);

504

505

const isValid = await validateImageFile(await fileFrom('./image.jpg'));

506

console.log('Valid image:', isValid);

507

```