converteverything-mcp 2.0.5 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -19
- package/dist/client.d.ts +58 -5
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +274 -21
- package/dist/client.js.map +1 -1
- package/dist/index.js +60 -24
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +0 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -17,6 +17,7 @@ Tired of sketchy converter websites with popup ads and "premium" upsells? We bui
|
|
|
17
17
|
## Features
|
|
18
18
|
|
|
19
19
|
- **100+ Supported Formats**: Audio, video, image (including RAW camera formats), document, ebook, data, 3D, font, archive, and CAD files
|
|
20
|
+
- **Large File Support**: Convert files up to 10GB with optimized direct cloud upload
|
|
20
21
|
- **File Compression**: Compress images, videos, and PDFs with quality presets
|
|
21
22
|
- **Archive Creation**: Create ZIP, TAR, 7z archives from multiple files
|
|
22
23
|
- **File Sharing**: Generate shareable links and send files via email
|
|
@@ -48,7 +49,7 @@ Browse all [audio converters](https://converteverything.io/audio-converters), [v
|
|
|
48
49
|
|
|
49
50
|
| Category | Formats |
|
|
50
51
|
|----------|---------|
|
|
51
|
-
| **Audio** (
|
|
52
|
+
| **Audio** (16) | mp3, wav, flac, aac, ogg, ogx, m4a, m4b, wma, aiff, midi, mid, opus, ac3, amr, ape |
|
|
52
53
|
| **Video** (15) | mp4, avi, mkv, mov, webm, wmv, flv, m4v, 3gp, ts, vob, mts, mpeg, m2ts, divx |
|
|
53
54
|
| **Image** (25) | jpg, jpeg, png, gif, webp, bmp, tiff, svg, ico, prn, heic, heif, avif, + RAW formats |
|
|
54
55
|
| **RAW Camera** | cr2, cr3, nef, nrw, arw, orf, rw2, raf, dng, pef, raw (read-only input) |
|
|
@@ -69,19 +70,6 @@ Browse all [audio converters](https://converteverything.io/audio-converters), [v
|
|
|
69
70
|
- Silver ($9.99/mo): 400 API calls/day
|
|
70
71
|
- Gold ($24.99/mo): Unlimited API calls
|
|
71
72
|
|
|
72
|
-
### File Retention
|
|
73
|
-
|
|
74
|
-
Converted files are stored temporarily. Use the `retention_hours` parameter to control how long files are kept:
|
|
75
|
-
|
|
76
|
-
| Tier | Max Retention |
|
|
77
|
-
|------|---------------|
|
|
78
|
-
| Free/Basic | 24 hours |
|
|
79
|
-
| Bronze | 7 days (168 hours) |
|
|
80
|
-
| Silver | 15 days (360 hours) |
|
|
81
|
-
| Gold | 30 days (720 hours) |
|
|
82
|
-
|
|
83
|
-
Default retention is 24 hours if not specified.
|
|
84
|
-
|
|
85
73
|
## Installation
|
|
86
74
|
|
|
87
75
|
### From npm (recommended)
|
|
@@ -460,7 +448,6 @@ Claude: [Uses compress_image] Compressed from 5.2 MB to 1.1 MB (79% reduction)
|
|
|
460
448
|
- `file_path` (required): Path to the image file
|
|
461
449
|
- `quality` (optional): Quality level 1-100 (default: 80)
|
|
462
450
|
- `max_dimension` (optional): Max width/height in pixels
|
|
463
|
-
- `retention_hours` (optional): File retention 1-720 hours (default: 24, max based on tier)
|
|
464
451
|
|
|
465
452
|
### `compress_video`
|
|
466
453
|
|
|
@@ -477,7 +464,6 @@ Claude: [Uses compress_video] Compressed from 500 MB to 85 MB
|
|
|
477
464
|
- `preset` (optional): Speed preset (ultrafast, fast, medium, slow)
|
|
478
465
|
- `max_resolution` (optional): Max resolution (e.g., "1920x1080", "720p")
|
|
479
466
|
- `remove_audio` (optional): Remove audio track
|
|
480
|
-
- `retention_hours` (optional): File retention 1-720 hours (default: 24, max based on tier)
|
|
481
467
|
|
|
482
468
|
### `compress_pdf`
|
|
483
469
|
|
|
@@ -490,8 +476,7 @@ Claude: [Uses compress_pdf] Compressed from 25 MB to 3.2 MB
|
|
|
490
476
|
|
|
491
477
|
**Parameters:**
|
|
492
478
|
- `file_path` (required): Path to the PDF file
|
|
493
|
-
- `quality` (optional):
|
|
494
|
-
- `retention_hours` (optional): File retention 1-720 hours (default: 24, max based on tier)
|
|
479
|
+
- `quality` (optional): Quality level 1-100 (default: 80)
|
|
495
480
|
|
|
496
481
|
### `get_compression_usage`
|
|
497
482
|
|
|
@@ -520,7 +505,6 @@ Claude: [Uses create_archive] Created project.zip with 12 files (45 MB)
|
|
|
520
505
|
- `output_format` (optional): zip, tar, tar.gz, tar.bz2, or 7z (default: zip)
|
|
521
506
|
- `archive_name` (optional): Custom name for the archive
|
|
522
507
|
- `compression_level` (optional): 1-9 (default: 6)
|
|
523
|
-
- `retention_hours` (optional): File retention 1-720 hours (default: 24, max based on tier)
|
|
524
508
|
|
|
525
509
|
---
|
|
526
510
|
|
package/dist/client.d.ts
CHANGED
|
@@ -118,25 +118,33 @@ export declare class ConvertEverythingClient {
|
|
|
118
118
|
*/
|
|
119
119
|
retryConversion(conversionId: string, newOptions?: ConversionOptions): Promise<ConversionResponse>;
|
|
120
120
|
/**
|
|
121
|
-
* Compress
|
|
121
|
+
* Compress a large file using direct upload
|
|
122
|
+
*/
|
|
123
|
+
private compressLargeFile;
|
|
124
|
+
/**
|
|
125
|
+
* Compress an image file (smart - uses direct upload for large files)
|
|
122
126
|
*/
|
|
123
127
|
compressImage(filePath: string, options?: CompressionOptions): Promise<ConversionResponse>;
|
|
124
128
|
/**
|
|
125
|
-
* Compress a video file
|
|
129
|
+
* Compress a video file (smart - uses direct upload for large files)
|
|
126
130
|
*/
|
|
127
131
|
compressVideo(filePath: string, options?: CompressionOptions): Promise<ConversionResponse>;
|
|
128
132
|
/**
|
|
129
|
-
* Compress a PDF file
|
|
133
|
+
* Compress a PDF file (smart - uses direct upload for large files)
|
|
130
134
|
*/
|
|
131
|
-
compressPdf(filePath: string, quality?: "low" | "medium" | "high"
|
|
135
|
+
compressPdf(filePath: string, quality?: "low" | "medium" | "high"): Promise<ConversionResponse>;
|
|
132
136
|
/**
|
|
133
137
|
* Get compression usage statistics
|
|
134
138
|
*/
|
|
135
139
|
getCompressionUsage(): Promise<CompressionUsageResponse>;
|
|
136
140
|
/**
|
|
137
|
-
* Create an archive from multiple files
|
|
141
|
+
* Create an archive from multiple files (smart - uses direct upload for large files)
|
|
138
142
|
*/
|
|
139
143
|
createArchive(filePaths: string[], options?: ArchiveOptions): Promise<ConversionResponse>;
|
|
144
|
+
/**
|
|
145
|
+
* Create archive from large files using direct upload
|
|
146
|
+
*/
|
|
147
|
+
private createArchiveLargeFiles;
|
|
140
148
|
/**
|
|
141
149
|
* Reconvert an existing conversion with new settings
|
|
142
150
|
*/
|
|
@@ -188,6 +196,51 @@ export declare class ConvertEverythingClient {
|
|
|
188
196
|
* Import from cloud and convert in one step
|
|
189
197
|
*/
|
|
190
198
|
importAndConvert(provider: CloudProvider, fileId: string, fileName: string, targetFormat: string, options?: ConversionOptions): Promise<ConversionResponse>;
|
|
199
|
+
/**
|
|
200
|
+
* Check if a file requires direct upload (>100MB)
|
|
201
|
+
*/
|
|
202
|
+
requiresDirectUpload(fileSize: number): boolean;
|
|
203
|
+
/**
|
|
204
|
+
* Get presigned URL for direct upload to R2
|
|
205
|
+
*/
|
|
206
|
+
private getPresignedUrl;
|
|
207
|
+
/**
|
|
208
|
+
* Upload file directly to R2 using presigned URL
|
|
209
|
+
*/
|
|
210
|
+
private uploadToR2;
|
|
211
|
+
/**
|
|
212
|
+
* Start conversion from a directly uploaded file
|
|
213
|
+
*/
|
|
214
|
+
private convertFromUpload;
|
|
215
|
+
/**
|
|
216
|
+
* Convert a large file using direct upload
|
|
217
|
+
*
|
|
218
|
+
* This method uses a three-step process optimized for large files:
|
|
219
|
+
* 1. Get a presigned URL for direct upload
|
|
220
|
+
* 2. Upload the file directly to cloud storage
|
|
221
|
+
* 3. Start the conversion from the uploaded file
|
|
222
|
+
*
|
|
223
|
+
* Benefits:
|
|
224
|
+
* - Faster uploads through direct cloud connectivity
|
|
225
|
+
* - Support for files up to 10GB (tier dependent)
|
|
226
|
+
* - More reliable transfers with fewer timeouts
|
|
227
|
+
*/
|
|
228
|
+
convertLargeFile(filePath: string, targetFormat: string, options?: ConversionOptions): Promise<ConversionResponse>;
|
|
229
|
+
/**
|
|
230
|
+
* Smart convert: automatically uses direct upload for large files
|
|
231
|
+
*
|
|
232
|
+
* This is the recommended method for converting files of any size.
|
|
233
|
+
* - Files under 100MB use the standard upload flow
|
|
234
|
+
* - Files over 100MB automatically use direct upload for better performance
|
|
235
|
+
*/
|
|
236
|
+
smartConvertFile(filePath: string, targetFormat: string, options?: ConversionOptions): Promise<ConversionResponse>;
|
|
237
|
+
/**
|
|
238
|
+
* Check if direct upload is supported by the server
|
|
239
|
+
*/
|
|
240
|
+
isDirectUploadSupported(): Promise<{
|
|
241
|
+
supported: boolean;
|
|
242
|
+
reason: string;
|
|
243
|
+
}>;
|
|
191
244
|
/**
|
|
192
245
|
* Validate UUID format
|
|
193
246
|
*/
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,sBAAsB,EACtB,iBAAiB,EACjB,wBAAwB,EACxB,aAAa,EAKb,kBAAkB,EAClB,wBAAwB,EACxB,cAAc,EACd,aAAa,EACb,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,aAAa,EACb,sBAAsB,EACtB,wBAAwB,EACxB,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,WAAW;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/client.js
CHANGED
|
@@ -44,7 +44,9 @@ const fs = __importStar(require("fs"));
|
|
|
44
44
|
const path = __importStar(require("path"));
|
|
45
45
|
const types_js_1 = require("./types.js");
|
|
46
46
|
// Package version for User-Agent
|
|
47
|
-
const CLIENT_VERSION = "1.
|
|
47
|
+
const CLIENT_VERSION = "2.1.0";
|
|
48
|
+
// Large file threshold for direct upload (100MB)
|
|
49
|
+
const DIRECT_UPLOAD_THRESHOLD = 100 * 1024 * 1024;
|
|
48
50
|
// Retry configuration
|
|
49
51
|
const DEFAULT_MAX_RETRIES = 3;
|
|
50
52
|
const DEFAULT_RETRY_DELAY = 1000; // 1 second
|
|
@@ -566,10 +568,65 @@ class ConvertEverythingClient {
|
|
|
566
568
|
// Compression Methods
|
|
567
569
|
// ==========================================================================
|
|
568
570
|
/**
|
|
569
|
-
* Compress
|
|
571
|
+
* Compress a large file using direct upload
|
|
572
|
+
*/
|
|
573
|
+
async compressLargeFile(filePath, compressType, options) {
|
|
574
|
+
const realPath = this.validateFilePath(filePath);
|
|
575
|
+
const stats = fs.statSync(realPath);
|
|
576
|
+
const fileBuffer = fs.readFileSync(realPath);
|
|
577
|
+
const fileName = path.basename(realPath);
|
|
578
|
+
// Detect content type
|
|
579
|
+
const ext = path.extname(fileName).toLowerCase().replace(".", "");
|
|
580
|
+
const mimeTypes = {
|
|
581
|
+
jpg: "image/jpeg", jpeg: "image/jpeg", png: "image/png", gif: "image/gif",
|
|
582
|
+
webp: "image/webp", tiff: "image/tiff", bmp: "image/bmp",
|
|
583
|
+
mp4: "video/mp4", mkv: "video/x-matroska", mov: "video/quicktime",
|
|
584
|
+
avi: "video/x-msvideo", webm: "video/webm", pdf: "application/pdf",
|
|
585
|
+
};
|
|
586
|
+
const contentType = mimeTypes[ext] || "application/octet-stream";
|
|
587
|
+
// Step 1: Get presigned URL
|
|
588
|
+
const { uploadUrl, objectPath, uploadId } = await this.getPresignedUrl(fileName, stats.size, contentType);
|
|
589
|
+
// Step 2: Upload directly to R2
|
|
590
|
+
await this.uploadToR2(fileBuffer, uploadUrl, contentType);
|
|
591
|
+
// Step 3: Call compress from-upload endpoint
|
|
592
|
+
const formData = new FormData();
|
|
593
|
+
formData.append("upload_id", uploadId);
|
|
594
|
+
formData.append("object_path", objectPath);
|
|
595
|
+
formData.append("original_filename", fileName);
|
|
596
|
+
formData.append("compress_type", compressType);
|
|
597
|
+
if (options?.quality !== undefined) {
|
|
598
|
+
formData.append("quality", options.quality.toString());
|
|
599
|
+
}
|
|
600
|
+
if (options?.max_dimension !== undefined) {
|
|
601
|
+
formData.append("max_dimension", options.max_dimension.toString());
|
|
602
|
+
}
|
|
603
|
+
if (options?.crf !== undefined) {
|
|
604
|
+
formData.append("crf", options.crf.toString());
|
|
605
|
+
}
|
|
606
|
+
if (options?.preset) {
|
|
607
|
+
formData.append("preset", options.preset);
|
|
608
|
+
}
|
|
609
|
+
if (options?.max_resolution) {
|
|
610
|
+
formData.append("max_resolution", options.max_resolution);
|
|
611
|
+
}
|
|
612
|
+
if (options?.remove_audio !== undefined) {
|
|
613
|
+
formData.append("remove_audio", options.remove_audio.toString());
|
|
614
|
+
}
|
|
615
|
+
return this.request("/tools/compress/from-upload", {
|
|
616
|
+
method: "POST",
|
|
617
|
+
body: formData,
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Compress an image file (smart - uses direct upload for large files)
|
|
570
622
|
*/
|
|
571
623
|
async compressImage(filePath, options) {
|
|
572
624
|
const realPath = this.validateFilePath(filePath);
|
|
625
|
+
const stats = fs.statSync(realPath);
|
|
626
|
+
// Use direct upload for large files
|
|
627
|
+
if (this.requiresDirectUpload(stats.size)) {
|
|
628
|
+
return this.compressLargeFile(realPath, "image", options);
|
|
629
|
+
}
|
|
573
630
|
const fileBuffer = fs.readFileSync(realPath);
|
|
574
631
|
const fileName = path.basename(realPath);
|
|
575
632
|
const formData = new FormData();
|
|
@@ -581,19 +638,21 @@ class ConvertEverythingClient {
|
|
|
581
638
|
if (options?.max_dimension !== undefined) {
|
|
582
639
|
formData.append("max_dimension", options.max_dimension.toString());
|
|
583
640
|
}
|
|
584
|
-
if (options?.retention_hours !== undefined) {
|
|
585
|
-
formData.append("retention_hours", options.retention_hours.toString());
|
|
586
|
-
}
|
|
587
641
|
return this.request("/tools/compress/image", {
|
|
588
642
|
method: "POST",
|
|
589
643
|
body: formData,
|
|
590
644
|
});
|
|
591
645
|
}
|
|
592
646
|
/**
|
|
593
|
-
* Compress a video file
|
|
647
|
+
* Compress a video file (smart - uses direct upload for large files)
|
|
594
648
|
*/
|
|
595
649
|
async compressVideo(filePath, options) {
|
|
596
650
|
const realPath = this.validateFilePath(filePath);
|
|
651
|
+
const stats = fs.statSync(realPath);
|
|
652
|
+
// Use direct upload for large files
|
|
653
|
+
if (this.requiresDirectUpload(stats.size)) {
|
|
654
|
+
return this.compressLargeFile(realPath, "video", options);
|
|
655
|
+
}
|
|
597
656
|
const fileBuffer = fs.readFileSync(realPath);
|
|
598
657
|
const fileName = path.basename(realPath);
|
|
599
658
|
const formData = new FormData();
|
|
@@ -611,19 +670,21 @@ class ConvertEverythingClient {
|
|
|
611
670
|
if (options?.remove_audio !== undefined) {
|
|
612
671
|
formData.append("remove_audio", options.remove_audio.toString());
|
|
613
672
|
}
|
|
614
|
-
if (options?.retention_hours !== undefined) {
|
|
615
|
-
formData.append("retention_hours", options.retention_hours.toString());
|
|
616
|
-
}
|
|
617
673
|
return this.request("/tools/compress/video", {
|
|
618
674
|
method: "POST",
|
|
619
675
|
body: formData,
|
|
620
676
|
});
|
|
621
677
|
}
|
|
622
678
|
/**
|
|
623
|
-
* Compress a PDF file
|
|
679
|
+
* Compress a PDF file (smart - uses direct upload for large files)
|
|
624
680
|
*/
|
|
625
|
-
async compressPdf(filePath, quality
|
|
681
|
+
async compressPdf(filePath, quality) {
|
|
626
682
|
const realPath = this.validateFilePath(filePath);
|
|
683
|
+
const stats = fs.statSync(realPath);
|
|
684
|
+
// Use direct upload for large files
|
|
685
|
+
if (this.requiresDirectUpload(stats.size)) {
|
|
686
|
+
return this.compressLargeFile(realPath, "pdf", { quality: quality === "low" ? 60 : quality === "high" ? 95 : 80 });
|
|
687
|
+
}
|
|
627
688
|
const fileBuffer = fs.readFileSync(realPath);
|
|
628
689
|
const fileName = path.basename(realPath);
|
|
629
690
|
const formData = new FormData();
|
|
@@ -632,9 +693,6 @@ class ConvertEverythingClient {
|
|
|
632
693
|
if (quality) {
|
|
633
694
|
formData.append("quality", quality);
|
|
634
695
|
}
|
|
635
|
-
if (retentionHours !== undefined) {
|
|
636
|
-
formData.append("retention_hours", retentionHours.toString());
|
|
637
|
-
}
|
|
638
696
|
return this.request("/tools/compress/pdf", {
|
|
639
697
|
method: "POST",
|
|
640
698
|
body: formData,
|
|
@@ -650,16 +708,33 @@ class ConvertEverythingClient {
|
|
|
650
708
|
// Archive Methods
|
|
651
709
|
// ==========================================================================
|
|
652
710
|
/**
|
|
653
|
-
* Create an archive from multiple files
|
|
711
|
+
* Create an archive from multiple files (smart - uses direct upload for large files)
|
|
654
712
|
*/
|
|
655
713
|
async createArchive(filePaths, options) {
|
|
656
|
-
|
|
714
|
+
// Check if any file requires direct upload
|
|
715
|
+
const fileInfos = [];
|
|
716
|
+
let hasLargeFile = false;
|
|
717
|
+
let totalSize = 0;
|
|
657
718
|
for (const filePath of filePaths) {
|
|
658
719
|
const realPath = this.validateFilePath(filePath);
|
|
659
|
-
const
|
|
720
|
+
const stats = fs.statSync(realPath);
|
|
660
721
|
const fileName = path.basename(realPath);
|
|
722
|
+
fileInfos.push({ path: realPath, size: stats.size, name: fileName });
|
|
723
|
+
totalSize += stats.size;
|
|
724
|
+
if (this.requiresDirectUpload(stats.size)) {
|
|
725
|
+
hasLargeFile = true;
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
// If any file is large or total is large, use direct upload for all
|
|
729
|
+
if (hasLargeFile || this.requiresDirectUpload(totalSize)) {
|
|
730
|
+
return this.createArchiveLargeFiles(fileInfos, options);
|
|
731
|
+
}
|
|
732
|
+
// Standard upload for small files
|
|
733
|
+
const formData = new FormData();
|
|
734
|
+
for (const fileInfo of fileInfos) {
|
|
735
|
+
const fileBuffer = fs.readFileSync(fileInfo.path);
|
|
661
736
|
const blob = new Blob([fileBuffer]);
|
|
662
|
-
formData.append("files", blob, this.sanitizeFilename(
|
|
737
|
+
formData.append("files", blob, this.sanitizeFilename(fileInfo.name));
|
|
663
738
|
}
|
|
664
739
|
if (options?.output_format) {
|
|
665
740
|
formData.append("output_format", options.output_format);
|
|
@@ -670,14 +745,53 @@ class ConvertEverythingClient {
|
|
|
670
745
|
if (options?.compression_level !== undefined) {
|
|
671
746
|
formData.append("compression_level", options.compression_level.toString());
|
|
672
747
|
}
|
|
673
|
-
if (options?.retention_hours !== undefined) {
|
|
674
|
-
formData.append("retention_hours", options.retention_hours.toString());
|
|
675
|
-
}
|
|
676
748
|
return this.request("/tools/create-archive", {
|
|
677
749
|
method: "POST",
|
|
678
750
|
body: formData,
|
|
679
751
|
});
|
|
680
752
|
}
|
|
753
|
+
/**
|
|
754
|
+
* Create archive from large files using direct upload
|
|
755
|
+
*/
|
|
756
|
+
async createArchiveLargeFiles(fileInfos, options) {
|
|
757
|
+
// Upload each file via presigned URL
|
|
758
|
+
const uploadedFiles = [];
|
|
759
|
+
for (const fileInfo of fileInfos) {
|
|
760
|
+
const fileBuffer = fs.readFileSync(fileInfo.path);
|
|
761
|
+
const ext = path.extname(fileInfo.name).toLowerCase().replace(".", "");
|
|
762
|
+
const mimeTypes = {
|
|
763
|
+
jpg: "image/jpeg", jpeg: "image/jpeg", png: "image/png", gif: "image/gif",
|
|
764
|
+
mp4: "video/mp4", mkv: "video/x-matroska", mov: "video/quicktime",
|
|
765
|
+
pdf: "application/pdf", zip: "application/zip", txt: "text/plain",
|
|
766
|
+
};
|
|
767
|
+
const contentType = mimeTypes[ext] || "application/octet-stream";
|
|
768
|
+
// Get presigned URL for this file
|
|
769
|
+
const { uploadUrl, objectPath, uploadId } = await this.getPresignedUrl(fileInfo.name, fileInfo.size, contentType);
|
|
770
|
+
// Upload to R2
|
|
771
|
+
await this.uploadToR2(fileBuffer, uploadUrl, contentType);
|
|
772
|
+
uploadedFiles.push({
|
|
773
|
+
upload_id: uploadId,
|
|
774
|
+
object_path: objectPath,
|
|
775
|
+
original_filename: fileInfo.name,
|
|
776
|
+
});
|
|
777
|
+
}
|
|
778
|
+
// Call create-archive from-upload endpoint
|
|
779
|
+
const formData = new FormData();
|
|
780
|
+
formData.append("files_json", JSON.stringify(uploadedFiles));
|
|
781
|
+
if (options?.output_format) {
|
|
782
|
+
formData.append("output_format", options.output_format);
|
|
783
|
+
}
|
|
784
|
+
if (options?.archive_name) {
|
|
785
|
+
formData.append("archive_name", options.archive_name);
|
|
786
|
+
}
|
|
787
|
+
if (options?.compression_level !== undefined) {
|
|
788
|
+
formData.append("compression_level", options.compression_level.toString());
|
|
789
|
+
}
|
|
790
|
+
return this.request("/tools/create-archive/from-upload", {
|
|
791
|
+
method: "POST",
|
|
792
|
+
body: formData,
|
|
793
|
+
});
|
|
794
|
+
}
|
|
681
795
|
// ==========================================================================
|
|
682
796
|
// Advanced Conversion Methods
|
|
683
797
|
// ==========================================================================
|
|
@@ -854,6 +968,145 @@ class ConvertEverythingClient {
|
|
|
854
968
|
`Direct import-and-convert is not yet supported. ` +
|
|
855
969
|
`Please download the file and use convert_file instead.`);
|
|
856
970
|
}
|
|
971
|
+
// ==========================================================================
|
|
972
|
+
// Direct Upload Methods (for large files)
|
|
973
|
+
// ==========================================================================
|
|
974
|
+
/**
|
|
975
|
+
* Check if a file requires direct upload (>100MB)
|
|
976
|
+
*/
|
|
977
|
+
requiresDirectUpload(fileSize) {
|
|
978
|
+
return fileSize > DIRECT_UPLOAD_THRESHOLD;
|
|
979
|
+
}
|
|
980
|
+
/**
|
|
981
|
+
* Get presigned URL for direct upload to R2
|
|
982
|
+
*/
|
|
983
|
+
async getPresignedUrl(filename, fileSize, contentType) {
|
|
984
|
+
const formData = new FormData();
|
|
985
|
+
formData.append("filename", filename);
|
|
986
|
+
formData.append("file_size", fileSize.toString());
|
|
987
|
+
formData.append("content_type", contentType);
|
|
988
|
+
const result = await this.request("/upload/presign", {
|
|
989
|
+
method: "POST",
|
|
990
|
+
body: formData,
|
|
991
|
+
});
|
|
992
|
+
return {
|
|
993
|
+
uploadUrl: result.upload_url,
|
|
994
|
+
objectPath: result.object_path,
|
|
995
|
+
uploadId: result.upload_id,
|
|
996
|
+
};
|
|
997
|
+
}
|
|
998
|
+
/**
|
|
999
|
+
* Upload file directly to R2 using presigned URL
|
|
1000
|
+
*/
|
|
1001
|
+
async uploadToR2(buffer, uploadUrl, contentType, onProgress) {
|
|
1002
|
+
// Use fetch for the direct upload (no auth header needed - URL is pre-signed)
|
|
1003
|
+
const response = await this.fetchWithTimeout(uploadUrl, {
|
|
1004
|
+
method: "PUT",
|
|
1005
|
+
body: buffer,
|
|
1006
|
+
headers: {
|
|
1007
|
+
"Content-Type": contentType,
|
|
1008
|
+
},
|
|
1009
|
+
});
|
|
1010
|
+
if (!response.ok) {
|
|
1011
|
+
throw new Error(`Direct upload failed: ${response.status} ${response.statusText}`);
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
/**
|
|
1015
|
+
* Start conversion from a directly uploaded file
|
|
1016
|
+
*/
|
|
1017
|
+
async convertFromUpload(uploadId, objectPath, originalFilename, targetFormat, options) {
|
|
1018
|
+
const formData = new FormData();
|
|
1019
|
+
formData.append("upload_id", uploadId);
|
|
1020
|
+
formData.append("object_path", objectPath);
|
|
1021
|
+
formData.append("original_filename", originalFilename);
|
|
1022
|
+
formData.append("output_format", targetFormat);
|
|
1023
|
+
if (options && Object.keys(options).length > 0) {
|
|
1024
|
+
formData.append("options", JSON.stringify(options));
|
|
1025
|
+
}
|
|
1026
|
+
return this.request("/convert/from-upload", {
|
|
1027
|
+
method: "POST",
|
|
1028
|
+
body: formData,
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
1031
|
+
/**
|
|
1032
|
+
* Convert a large file using direct upload
|
|
1033
|
+
*
|
|
1034
|
+
* This method uses a three-step process optimized for large files:
|
|
1035
|
+
* 1. Get a presigned URL for direct upload
|
|
1036
|
+
* 2. Upload the file directly to cloud storage
|
|
1037
|
+
* 3. Start the conversion from the uploaded file
|
|
1038
|
+
*
|
|
1039
|
+
* Benefits:
|
|
1040
|
+
* - Faster uploads through direct cloud connectivity
|
|
1041
|
+
* - Support for files up to 10GB (tier dependent)
|
|
1042
|
+
* - More reliable transfers with fewer timeouts
|
|
1043
|
+
*/
|
|
1044
|
+
async convertLargeFile(filePath, targetFormat, options) {
|
|
1045
|
+
// Validate and get the real path
|
|
1046
|
+
const realPath = this.validateFilePath(filePath);
|
|
1047
|
+
// Validate target format
|
|
1048
|
+
const normalizedFormat = targetFormat.toLowerCase().replace(/^\./, "");
|
|
1049
|
+
if (!(0, types_js_1.isFormatSupported)(normalizedFormat)) {
|
|
1050
|
+
throw new Error(`Unsupported target format: ${targetFormat}. ` +
|
|
1051
|
+
"Use get_supported_formats to see available formats.");
|
|
1052
|
+
}
|
|
1053
|
+
// Get file info
|
|
1054
|
+
const stats = fs.statSync(realPath);
|
|
1055
|
+
const fileSize = stats.size;
|
|
1056
|
+
const fileName = path.basename(realPath);
|
|
1057
|
+
// Detect content type
|
|
1058
|
+
const mimeTypes = {
|
|
1059
|
+
mp3: "audio/mpeg", wav: "audio/wav", flac: "audio/flac", m4a: "audio/mp4",
|
|
1060
|
+
m4b: "audio/mp4", ogg: "audio/ogg", mp4: "video/mp4", mkv: "video/x-matroska",
|
|
1061
|
+
mov: "video/quicktime", avi: "video/x-msvideo", webm: "video/webm",
|
|
1062
|
+
jpg: "image/jpeg", jpeg: "image/jpeg", png: "image/png", gif: "image/gif",
|
|
1063
|
+
webp: "image/webp", pdf: "application/pdf", docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
1064
|
+
zip: "application/zip", json: "application/json", xml: "application/xml",
|
|
1065
|
+
};
|
|
1066
|
+
const ext = path.extname(fileName).toLowerCase().replace(".", "");
|
|
1067
|
+
const contentType = mimeTypes[ext] || "application/octet-stream";
|
|
1068
|
+
// Read the file
|
|
1069
|
+
const fileBuffer = fs.readFileSync(realPath);
|
|
1070
|
+
// Step 1: Get presigned URL
|
|
1071
|
+
const { uploadUrl, objectPath, uploadId } = await this.getPresignedUrl(fileName, fileSize, contentType);
|
|
1072
|
+
// Step 2: Upload directly to R2
|
|
1073
|
+
await this.uploadToR2(fileBuffer, uploadUrl, contentType);
|
|
1074
|
+
// Step 3: Start conversion
|
|
1075
|
+
return this.convertFromUpload(uploadId, objectPath, fileName, normalizedFormat, options);
|
|
1076
|
+
}
|
|
1077
|
+
/**
|
|
1078
|
+
* Smart convert: automatically uses direct upload for large files
|
|
1079
|
+
*
|
|
1080
|
+
* This is the recommended method for converting files of any size.
|
|
1081
|
+
* - Files under 100MB use the standard upload flow
|
|
1082
|
+
* - Files over 100MB automatically use direct upload for better performance
|
|
1083
|
+
*/
|
|
1084
|
+
async smartConvertFile(filePath, targetFormat, options) {
|
|
1085
|
+
const realPath = this.validateFilePath(filePath);
|
|
1086
|
+
const stats = fs.statSync(realPath);
|
|
1087
|
+
if (this.requiresDirectUpload(stats.size)) {
|
|
1088
|
+
return this.convertLargeFile(filePath, targetFormat, options);
|
|
1089
|
+
}
|
|
1090
|
+
return this.convertFile(filePath, targetFormat, options);
|
|
1091
|
+
}
|
|
1092
|
+
/**
|
|
1093
|
+
* Check if direct upload is supported by the server
|
|
1094
|
+
*/
|
|
1095
|
+
async isDirectUploadSupported() {
|
|
1096
|
+
try {
|
|
1097
|
+
const result = await this.request("/upload/supported");
|
|
1098
|
+
return {
|
|
1099
|
+
supported: result.supported,
|
|
1100
|
+
reason: result.reason,
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
catch {
|
|
1104
|
+
return {
|
|
1105
|
+
supported: false,
|
|
1106
|
+
reason: "Unable to check direct upload support",
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
857
1110
|
/**
|
|
858
1111
|
* Validate UUID format
|
|
859
1112
|
*/
|