dragdropdo-sdk 1.0.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 ADDED
@@ -0,0 +1,635 @@
1
+ # DragDropDo SDK - Node.js
2
+
3
+ Official Node.js client library for the dragdropdo.com Business API. This library provides a simple and elegant interface for developers to interact with DragDropDo's file processing services at [dragdropdo.com](https://dragdropdo.com).
4
+
5
+ ## Features
6
+
7
+ - ✅ **File Upload** - Upload files with automatic multipart handling
8
+ - ✅ **Operation Support** - Check which operations are available for file types
9
+ - ✅ **File Operations** - Convert, compress, merge, zip, and more
10
+ - ✅ **Status Polling** - Built-in polling for operation status
11
+ - ✅ **TypeScript Support** - Full TypeScript definitions included
12
+ - ✅ **Error Handling** - Comprehensive error types and messages
13
+ - ✅ **Progress Tracking** - Upload progress callbacks
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install dragdropdo-sdk
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ```typescript
24
+ import { Dragdropdo } from "dragdropdo-sdk";
25
+
26
+ // Initialize the client
27
+ const client = new Dragdropdo({
28
+ apiKey: "your-api-key-here",
29
+ baseURL: "https://dragdropdo.com", // Optional, defaults to https://dragdropdo.com
30
+ timeout: 30000, // Optional, defaults to 30000ms
31
+ });
32
+
33
+ // Upload a file
34
+ const uploadResult = await client.uploadFile({
35
+ file: "/path/to/document.pdf",
36
+ fileName: "document.pdf",
37
+ mimeType: "application/pdf",
38
+ });
39
+
40
+ console.log("File key:", uploadResult.fileKey);
41
+
42
+ // Check if convert to PNG is supported
43
+ const supported = await client.checkSupportedOperation({
44
+ ext: "pdf",
45
+ action: "convert",
46
+ parameters: { convert_to: "png" },
47
+ });
48
+
49
+ if (supported.supported) {
50
+ // Convert PDF to PNG
51
+ const operation = await client.convert([uploadResult.fileKey], "png");
52
+
53
+ // Poll for completion
54
+ const status = await client.pollStatus({
55
+ mainTaskId: operation.mainTaskId,
56
+ interval: 2000, // Check every 2 seconds
57
+ onUpdate: (status) => {
58
+ console.log("Status:", status.operationStatus);
59
+ },
60
+ });
61
+
62
+ if (status.operationStatus === "completed") {
63
+ console.log(
64
+ "Download links:",
65
+ status.filesData.map((f) => f.downloadLink)
66
+ );
67
+ }
68
+ }
69
+ ```
70
+
71
+ ## API Reference
72
+
73
+ ### Initialization
74
+
75
+ #### `new Dragdropdo(config: DragdropdoConfig)`
76
+
77
+ Create a new D3 client instance.
78
+
79
+ **Parameters:**
80
+
81
+ - `config.apiKey` (required) - Your D3 API key
82
+ - `config.baseURL` (optional) - Base URL of the DragDropDo API (default: `'https://dragdropdo.com'`)
83
+ - `config.timeout` (optional) - Request timeout in milliseconds (default: `30000`)
84
+ - `config.headers` (optional) - Custom headers to include in all requests
85
+
86
+ **Example:**
87
+
88
+ ```typescript
89
+ const client = new Dragdropdo({
90
+ apiKey: "your-api-key",
91
+ baseURL: "https://dragdropdo.com",
92
+ timeout: 30000,
93
+ });
94
+ ```
95
+
96
+ ---
97
+
98
+ ### File Upload
99
+
100
+ #### `uploadFile(options: UploadFileOptions): Promise<UploadResponse>`
101
+
102
+ Upload a file to D3 storage. This method handles the complete upload flow including multipart uploads.
103
+
104
+ **Parameters:**
105
+
106
+ - `options.file` (required) - File path (string)
107
+ - `options.fileName` (required) - Original file name
108
+ - `options.mimeType` (optional) - MIME type (auto-detected if not provided)
109
+ - `options.parts` (optional) - Number of parts for multipart upload (auto-calculated if not provided)
110
+ - `options.onProgress` (optional) - Progress callback function
111
+
112
+ **Returns:** `Promise<UploadResponse>` with `fileKey` and `presignedUrls`
113
+
114
+ **Example:**
115
+
116
+ ```typescript
117
+ // Upload from file path
118
+ const result = await client.uploadFile({
119
+ file: "/path/to/file.pdf",
120
+ fileName: "document.pdf",
121
+ mimeType: "application/pdf",
122
+ onProgress: (progress) => {
123
+ console.log(`Upload: ${progress.percentage}%`);
124
+ },
125
+ });
126
+
127
+ // Upload from file path only (Buffer uploads are not supported)
128
+ const result = await client.uploadFile({
129
+ file: "/path/to/file.pdf",
130
+ fileName: "document.pdf",
131
+ mimeType: "application/pdf",
132
+ });
133
+ ```
134
+
135
+ ---
136
+
137
+ ### Check Supported Operations
138
+
139
+ #### `checkSupportedOperation(options: SupportedOperationOptions): Promise<SupportedOperationResponse>`
140
+
141
+ Check which operations are supported for a file extension.
142
+
143
+ **Parameters:**
144
+
145
+ - `options.ext` (required) - File extension (e.g., `'pdf'`, `'jpg'`)
146
+ - `options.action` (optional) - Specific action to check (e.g., `'convert'`, `'compress'`)
147
+ - `options.parameters` (optional) - Parameters for validation (e.g., `{ convert_to: 'png' }`)
148
+
149
+ **Returns:** `Promise<SupportedOperationResponse>` with support information
150
+
151
+ **Example:**
152
+
153
+ ```typescript
154
+ // Get all available actions for PDF
155
+ const result = await client.checkSupportedOperation({
156
+ ext: "pdf",
157
+ });
158
+ console.log("Available actions:", result.availableActions);
159
+ // Output: ['CONVERT', 'COMPRESS', 'MERGE', 'LOCK', 'UNLOCK', ...]
160
+
161
+ // Check if convert to PNG is supported
162
+ const result = await client.checkSupportedOperation({
163
+ ext: "pdf",
164
+ action: "convert",
165
+ parameters: { convert_to: "png" },
166
+ });
167
+ console.log("Supported:", result.supported); // true or false
168
+
169
+ // Get available compression levels
170
+ const result = await client.checkSupportedOperation({
171
+ ext: "pdf",
172
+ action: "compress",
173
+ });
174
+ console.log("Compression levels:", result.parameters?.compression_value);
175
+ // Output: [{ name: 'Recommended', value: 'recommended', ... }, ...]
176
+
177
+ // Get available convert targets
178
+ const result = await client.checkSupportedOperation({
179
+ ext: "pdf",
180
+ action: "convert",
181
+ });
182
+ console.log("Convert targets:", result.parameters?.convert_to);
183
+ // Output: { DOCUMENT: ['docx', 'txt'], IMAGE: ['png', 'jpg'], ... }
184
+ ```
185
+
186
+ ---
187
+
188
+ ### Create Operations
189
+
190
+ #### `createOperation(options: OperationOptions): Promise<OperationResponse>`
191
+
192
+ Create a file operation (convert, compress, merge, zip, etc.).
193
+
194
+ **Parameters:**
195
+
196
+ - `options.action` (required) - Action to perform: `'convert'`, `'compress'`, `'merge'`, `'zip'`, `'share'`, `'lock'`, `'unlock'`, `'reset_password'`
197
+ - `options.fileKeys` (required) - Array of file keys from upload
198
+ - `options.parameters` (optional) - Action-specific parameters
199
+ - `options.notes` (optional) - User metadata
200
+
201
+ **Returns:** `Promise<OperationResponse>` with `mainTaskId`
202
+
203
+ **Example:**
204
+
205
+ ```typescript
206
+ // Convert PDF to PNG
207
+ const result = await client.createOperation({
208
+ action: "convert",
209
+ fileKeys: ["file-key-123"],
210
+ parameters: { convert_to: "png" },
211
+ notes: { userId: "user-123" },
212
+ });
213
+
214
+ // Compress PDF
215
+ const result = await client.createOperation({
216
+ action: "compress",
217
+ fileKeys: ["file-key-123"],
218
+ parameters: { compression_value: "recommended" },
219
+ });
220
+
221
+ // Merge multiple PDFs
222
+ const result = await client.createOperation({
223
+ action: "merge",
224
+ fileKeys: ["file-key-1", "file-key-2", "file-key-3"],
225
+ });
226
+ ```
227
+
228
+ #### Convenience Methods
229
+
230
+ The client also provides convenience methods for common operations:
231
+
232
+ **Convert:**
233
+
234
+ ```typescript
235
+ await client.convert(fileKeys, convertTo, notes?);
236
+ // Example: await client.convert(['file-key-123'], 'png');
237
+ ```
238
+
239
+ **Compress:**
240
+
241
+ ```typescript
242
+ await client.compress(fileKeys, compressionValue?, notes?);
243
+ // Example: await client.compress(['file-key-123'], 'recommended');
244
+ ```
245
+
246
+ **Merge:**
247
+
248
+ ```typescript
249
+ await client.merge(fileKeys, notes?);
250
+ // Example: await client.merge(['file-key-1', 'file-key-2']);
251
+ ```
252
+
253
+ **Zip:**
254
+
255
+ ```typescript
256
+ await client.zip(fileKeys, notes?);
257
+ // Example: await client.zip(['file-key-1', 'file-key-2']);
258
+ ```
259
+
260
+ **Share:**
261
+
262
+ ```typescript
263
+ await client.share(fileKeys, notes?);
264
+ // Example: await client.share(['file-key-123']);
265
+ ```
266
+
267
+ **Lock PDF:**
268
+
269
+ ```typescript
270
+ await client.lockPdf(fileKeys, password, notes?);
271
+ // Example: await client.lockPdf(['file-key-123'], 'secure-password');
272
+ ```
273
+
274
+ **Unlock PDF:**
275
+
276
+ ```typescript
277
+ await client.unlockPdf(fileKeys, password, notes?);
278
+ // Example: await client.unlockPdf(['file-key-123'], 'password');
279
+ ```
280
+
281
+ **Reset PDF Password:**
282
+
283
+ ```typescript
284
+ await client.resetPdfPassword(fileKeys, oldPassword, newPassword, notes?);
285
+ // Example: await client.resetPdfPassword(['file-key-123'], 'old', 'new');
286
+ ```
287
+
288
+ ---
289
+
290
+ ### Get Status
291
+
292
+ #### `getStatus(options: StatusOptions): Promise<StatusResponse>`
293
+
294
+ Get the current status of an operation.
295
+
296
+ **Parameters:**
297
+
298
+ - `options.mainTaskId` (required) - Main task ID from operation creation
299
+ - `options.fileTaskId` (optional) - Specific file task ID
300
+
301
+ **Returns:** `Promise<StatusResponse>` with operation and file statuses
302
+
303
+ **Example:**
304
+
305
+ ```typescript
306
+ // Get main task status
307
+ const status = await client.getStatus({
308
+ mainTaskId: "task-123",
309
+ });
310
+
311
+ // Get specific file task status
312
+ const status = await client.getStatus({
313
+ mainTaskId: "task-123",
314
+ fileTaskId: "file-task-456",
315
+ });
316
+
317
+ console.log("Operation status:", status.operationStatus);
318
+ // Possible values: 'queued', 'running', 'completed', 'failed'
319
+
320
+ if (status.operationStatus === "completed") {
321
+ status.filesData.forEach((file) => {
322
+ console.log(`File ${file.fileKey}: ${file.status}`);
323
+ if (file.downloadLink) {
324
+ console.log(`Download: ${file.downloadLink}`);
325
+ }
326
+ });
327
+ }
328
+ ```
329
+
330
+ #### `pollStatus(options: PollStatusOptions): Promise<StatusResponse>`
331
+
332
+ Poll operation status until completion or failure.
333
+
334
+ **Parameters:**
335
+
336
+ - `options.mainTaskId` (required) - Main task ID
337
+ - `options.fileTaskId` (optional) - Specific file task ID
338
+ - `options.interval` (optional) - Polling interval in milliseconds (default: `2000`)
339
+ - `options.timeout` (optional) - Maximum polling duration in milliseconds (default: `300000` = 5 minutes)
340
+ - `options.onUpdate` (optional) - Callback for each status update
341
+
342
+ **Returns:** `Promise<StatusResponse>` with final status
343
+
344
+ **Example:**
345
+
346
+ ```typescript
347
+ const status = await client.pollStatus({
348
+ mainTaskId: "task-123",
349
+ interval: 2000, // Check every 2 seconds
350
+ timeout: 300000, // 5 minutes max
351
+ onUpdate: (status) => {
352
+ console.log("Status:", status.operationStatus);
353
+ console.log("Files:", status.filesData.length);
354
+ },
355
+ });
356
+
357
+ if (status.operationStatus === "completed") {
358
+ console.log("All files processed successfully!");
359
+ status.filesData.forEach((file) => {
360
+ console.log(`Download: ${file.downloadLink}`);
361
+ });
362
+ } else if (status.operationStatus === "failed") {
363
+ console.error("Operation failed");
364
+ status.filesData.forEach((file) => {
365
+ if (file.errorMessage) {
366
+ console.error(`Error: ${file.errorMessage}`);
367
+ }
368
+ });
369
+ }
370
+ ```
371
+
372
+ ---
373
+
374
+ ## Complete Workflow Example
375
+
376
+ Here's a complete example showing the typical workflow:
377
+
378
+ ```typescript
379
+ import { Dragdropdo } from "dragdropdo-sdk";
380
+ import * as fs from "fs";
381
+
382
+ async function processFile() {
383
+ // Initialize client
384
+ const client = new Dragdropdo({
385
+ apiKey: process.env.D3_API_KEY!,
386
+ baseURL: "https://dragdropdo.com",
387
+ });
388
+
389
+ try {
390
+ // Step 1: Upload file
391
+ console.log("Uploading file...");
392
+ const uploadResult = await client.uploadFile({
393
+ file: "./document.pdf",
394
+ fileName: "document.pdf",
395
+ onProgress: (progress) => {
396
+ console.log(`Upload progress: ${progress.percentage}%`);
397
+ },
398
+ });
399
+ console.log("Upload complete. File key:", uploadResult.fileKey);
400
+
401
+ // Step 2: Check if operation is supported
402
+ console.log("Checking supported operations...");
403
+ const supported = await client.checkSupportedOperation({
404
+ ext: "pdf",
405
+ action: "convert",
406
+ parameters: { convert_to: "png" },
407
+ });
408
+
409
+ if (!supported.supported) {
410
+ throw new Error("Convert to PNG is not supported for PDF");
411
+ }
412
+
413
+ // Step 3: Create operation
414
+ console.log("Creating convert operation...");
415
+ const operation = await client.convert([uploadResult.fileKey], "png", {
416
+ userId: "user-123",
417
+ source: "api",
418
+ });
419
+ console.log("Operation created. Task ID:", operation.mainTaskId);
420
+
421
+ // Step 4: Poll for completion
422
+ console.log("Waiting for operation to complete...");
423
+ const status = await client.pollStatus({
424
+ mainTaskId: operation.mainTaskId,
425
+ interval: 2000,
426
+ onUpdate: (status) => {
427
+ console.log(`Status: ${status.operationStatus}`);
428
+ },
429
+ });
430
+
431
+ // Step 5: Handle result
432
+ if (status.operationStatus === "completed") {
433
+ console.log("Operation completed successfully!");
434
+ status.filesData.forEach((file, index) => {
435
+ console.log(`File ${index + 1}:`);
436
+ console.log(` Status: ${file.status}`);
437
+ console.log(` Download: ${file.downloadLink}`);
438
+ });
439
+ } else {
440
+ console.error("Operation failed");
441
+ status.filesData.forEach((file) => {
442
+ if (file.errorMessage) {
443
+ console.error(`Error: ${file.errorMessage}`);
444
+ }
445
+ });
446
+ }
447
+ } catch (error) {
448
+ if (error instanceof D3APIError) {
449
+ console.error(`API Error (${error.statusCode}):`, error.message);
450
+ } else if (error instanceof D3ValidationError) {
451
+ console.error("Validation Error:", error.message);
452
+ } else {
453
+ console.error("Error:", error);
454
+ }
455
+ }
456
+ }
457
+
458
+ processFile();
459
+ ```
460
+
461
+ ---
462
+
463
+ ## Error Handling
464
+
465
+ The client provides several error types for better error handling:
466
+
467
+ ```typescript
468
+ import { DragdropdoError, D3APIError, D3ValidationError, D3UploadError, D3TimeoutError } from 'dragdropdo-sdk';
469
+
470
+ try {
471
+ await client.uploadFile({ ... });
472
+ } catch (error) {
473
+ if (error instanceof D3APIError) {
474
+ // API returned an error
475
+ console.error(`API Error (${error.statusCode}):`, error.message);
476
+ console.error('Error code:', error.code);
477
+ console.error('Details:', error.details);
478
+ } else if (error instanceof D3ValidationError) {
479
+ // Validation error (missing required fields, etc.)
480
+ console.error('Validation Error:', error.message);
481
+ } else if (error instanceof D3UploadError) {
482
+ // Upload-specific error
483
+ console.error('Upload Error:', error.message);
484
+ } else if (error instanceof D3TimeoutError) {
485
+ // Timeout error (from polling)
486
+ console.error('Timeout:', error.message);
487
+ } else {
488
+ // Other errors
489
+ console.error('Error:', error);
490
+ }
491
+ }
492
+ ```
493
+
494
+ ---
495
+
496
+ ## Supported Operations
497
+
498
+ ### Convert
499
+
500
+ Convert files from one format to another.
501
+
502
+ **Parameters:**
503
+
504
+ - `convert_to` (required) - Target format (e.g., `'pdf'`, `'png'`, `'docx'`)
505
+
506
+ **Example:**
507
+
508
+ ```typescript
509
+ await client.convert(["file-key-123"], "png");
510
+ ```
511
+
512
+ ### Compress
513
+
514
+ Compress files to reduce size.
515
+
516
+ **Parameters:**
517
+
518
+ - `compression_value` (required) - Compression level (e.g., `'recommended'`, `'high'`, `'low'`)
519
+
520
+ **Example:**
521
+
522
+ ```typescript
523
+ await client.compress(["file-key-123"], "recommended");
524
+ ```
525
+
526
+ ### Merge
527
+
528
+ Merge multiple files into one.
529
+
530
+ **Example:**
531
+
532
+ ```typescript
533
+ await client.merge(["file-key-1", "file-key-2", "file-key-3"]);
534
+ ```
535
+
536
+ ### Zip
537
+
538
+ Create a ZIP archive from multiple files.
539
+
540
+ **Example:**
541
+
542
+ ```typescript
543
+ await client.zip(["file-key-1", "file-key-2"]);
544
+ ```
545
+
546
+ ### Share
547
+
548
+ Generate shareable links for files.
549
+
550
+ **Example:**
551
+
552
+ ```typescript
553
+ await client.share(["file-key-123"]);
554
+ ```
555
+
556
+ ### Lock PDF
557
+
558
+ Protect PDF with password.
559
+
560
+ **Parameters:**
561
+
562
+ - `password` (required) - Password to protect the PDF
563
+
564
+ **Example:**
565
+
566
+ ```typescript
567
+ await client.lockPdf(["file-key-123"], "secure-password");
568
+ ```
569
+
570
+ ### Unlock PDF
571
+
572
+ Remove password protection from PDF.
573
+
574
+ **Parameters:**
575
+
576
+ - `password` (required) - Current password
577
+
578
+ **Example:**
579
+
580
+ ```typescript
581
+ await client.unlockPdf(["file-key-123"], "password");
582
+ ```
583
+
584
+ ### Reset PDF Password
585
+
586
+ Change PDF password.
587
+
588
+ **Parameters:**
589
+
590
+ - `old_password` (required) - Current password
591
+ - `new_password` (required) - New password
592
+
593
+ **Example:**
594
+
595
+ ```typescript
596
+ await client.resetPdfPassword(["file-key-123"], "old-password", "new-password");
597
+ ```
598
+
599
+ ---
600
+
601
+ ## TypeScript Support
602
+
603
+ The library is written in TypeScript and includes full type definitions. All types are exported for use in your projects:
604
+
605
+ ```typescript
606
+ import {
607
+ Dragdropdo,
608
+ DragdropdoConfig,
609
+ UploadFileOptions,
610
+ UploadResponse,
611
+ OperationOptions,
612
+ OperationResponse,
613
+ StatusResponse,
614
+ // ... and more
615
+ } from "dragdropdo-sdk";
616
+ ```
617
+
618
+ ---
619
+
620
+ ## Requirements
621
+
622
+ - Node.js 14.x or higher
623
+ - npm or yarn
624
+
625
+ ---
626
+
627
+ ## License
628
+
629
+ ISC
630
+
631
+ ---
632
+
633
+ ## Support
634
+
635
+ For API documentation and support, visit [dragdropdo.com](https://dragdropdo.com) or the [D3 Developer Portal](https://developer.d3.com).