@shipstatic/drop 0.1.12 → 0.1.14
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 +42 -42
- package/dist/index.cjs +47 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +47 -11
- package/dist/index.js.map +1 -1
- package/package.json +8 -6
package/README.md
CHANGED
|
@@ -85,7 +85,7 @@ function MyUploader() {
|
|
|
85
85
|
});
|
|
86
86
|
|
|
87
87
|
const handleUpload = async () => {
|
|
88
|
-
//
|
|
88
|
+
// Extract File objects from ProcessedFiles for Ship SDK
|
|
89
89
|
await ship.deployments.create(drop.validFiles.map(f => f.file));
|
|
90
90
|
};
|
|
91
91
|
|
|
@@ -231,7 +231,6 @@ interface DropOptions {
|
|
|
231
231
|
|
|
232
232
|
**Returns:**
|
|
233
233
|
|
|
234
|
-
```typescript
|
|
235
234
|
```typescript
|
|
236
235
|
interface DropReturn {
|
|
237
236
|
// Convenience getters (computed from state)
|
|
@@ -476,27 +475,34 @@ Use `clearAll()` to reset and try again:
|
|
|
476
475
|
|
|
477
476
|
```typescript
|
|
478
477
|
/**
|
|
479
|
-
* ProcessedFile
|
|
480
|
-
* This means it can be passed directly to ship.deployments.create()
|
|
478
|
+
* ProcessedFile - a file processed by Drop, ready for Ship SDK deployment
|
|
481
479
|
*
|
|
480
|
+
* Use the `file` property to pass to ship.deployments.create()
|
|
482
481
|
* Note: md5 is intentionally undefined - Ship SDK calculates it during deployment
|
|
483
482
|
*/
|
|
484
|
-
interface ProcessedFile
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
483
|
+
interface ProcessedFile {
|
|
484
|
+
/** Unique identifier for React keys */
|
|
485
|
+
id: string;
|
|
486
|
+
/** The File object - pass this to ship.deployments.create() */
|
|
487
|
+
file: File;
|
|
488
|
+
/** Relative path for deployment (e.g., "images/photo.jpg") */
|
|
489
|
+
path: string;
|
|
490
|
+
/** File size in bytes */
|
|
491
|
+
size: number;
|
|
492
|
+
/** MD5 hash (optional - Ship SDK calculates during deployment if not provided) */
|
|
493
|
+
md5?: string;
|
|
494
|
+
/** Filename without path */
|
|
495
|
+
name: string;
|
|
496
|
+
/** MIME type for UI icons/previews */
|
|
497
|
+
type: string;
|
|
498
|
+
/** Last modified timestamp */
|
|
496
499
|
lastModified: number;
|
|
500
|
+
/** Current processing/upload status */
|
|
497
501
|
status: FileStatus;
|
|
498
|
-
|
|
499
|
-
|
|
502
|
+
/** Human-readable status message for UI */
|
|
503
|
+
statusMessage?: string;
|
|
504
|
+
/** Upload progress (0-100) - only set during upload */
|
|
505
|
+
progress?: number;
|
|
500
506
|
}
|
|
501
507
|
|
|
502
508
|
interface ClientError {
|
|
@@ -519,36 +525,30 @@ type FileStatus =
|
|
|
519
525
|
|
|
520
526
|
## Direct Ship SDK Integration
|
|
521
527
|
|
|
522
|
-
|
|
528
|
+
Extract the `file` property from ProcessedFiles to pass to Ship SDK:
|
|
523
529
|
|
|
524
530
|
```typescript
|
|
525
|
-
|
|
531
|
+
// Get valid files and extract File objects for deployment
|
|
532
|
+
const filesToDeploy = drop.validFiles.map(f => f.file);
|
|
526
533
|
|
|
527
|
-
//
|
|
528
|
-
await ship.deployments.create(
|
|
534
|
+
// Pass File[] to Ship SDK
|
|
535
|
+
await ship.deployments.create(filesToDeploy);
|
|
529
536
|
```
|
|
530
537
|
|
|
531
|
-
###
|
|
538
|
+
### Why Extract `.file`?
|
|
539
|
+
|
|
540
|
+
Ship SDK's browser `deployments.create()` accepts `File[]`. Drop's `ProcessedFile` wraps the File with additional UI metadata (id, status, progress). The `.file` property gives you the raw File object that Ship SDK expects.
|
|
532
541
|
|
|
533
542
|
```typescript
|
|
534
|
-
//
|
|
535
|
-
interface ProcessedFile
|
|
536
|
-
|
|
537
|
-
path: string; //
|
|
538
|
-
|
|
539
|
-
md5?: string; // Required by StaticFile
|
|
540
|
-
|
|
541
|
-
// Additional UI properties
|
|
542
|
-
id: string;
|
|
543
|
-
file: File; // Alias for 'content' (better DX)
|
|
544
|
-
name: string;
|
|
545
|
-
type: string;
|
|
546
|
-
status: FileStatus;
|
|
547
|
-
// ... etc
|
|
543
|
+
// ProcessedFile structure
|
|
544
|
+
interface ProcessedFile {
|
|
545
|
+
file: File; // ← Pass this to Ship SDK
|
|
546
|
+
path: string; // Normalized path (set on file.webkitRelativePath)
|
|
547
|
+
// ... UI properties (id, status, progress, etc.)
|
|
548
548
|
}
|
|
549
549
|
```
|
|
550
550
|
|
|
551
|
-
**Important**:
|
|
551
|
+
**Important**: Drop automatically sets `webkitRelativePath` on each File to preserve folder structure. Ship SDK reads this property during deployment, so paths are handled correctly.
|
|
552
552
|
|
|
553
553
|
## Architecture Decisions
|
|
554
554
|
|
|
@@ -599,19 +599,19 @@ This is the same pattern used by popular libraries like `react-dropzone`, `downs
|
|
|
599
599
|
**3. Loosely Coupled Integration**
|
|
600
600
|
Following industry standards (Firebase hooks, Supabase utilities), we chose:
|
|
601
601
|
- ✅ **Ship instance as dependency**: Validates using `ship.getConfig()`
|
|
602
|
-
- ✅ **Simple output**: ProcessedFile[]
|
|
602
|
+
- ✅ **Simple output**: Extract `.file` from ProcessedFile[] for Ship SDK
|
|
603
603
|
- ✅ **Testable**: Easy to mock Ship SDK for testing
|
|
604
604
|
- ✅ **Flexible**: Host app controls WHEN to deploy
|
|
605
605
|
|
|
606
606
|
**4. Type System Integration**
|
|
607
607
|
|
|
608
|
-
ProcessedFile
|
|
608
|
+
ProcessedFile wraps File objects with UI-specific metadata:
|
|
609
609
|
|
|
610
610
|
```
|
|
611
|
-
File[] → ProcessedFile[] (
|
|
611
|
+
File[] → ProcessedFile[] → .map(f => f.file) → ship.deployments.create()
|
|
612
612
|
```
|
|
613
613
|
|
|
614
|
-
|
|
614
|
+
ProcessedFile adds UI properties (id, name, status, progress) while preserving the original File object. The `.file` property gives you direct access for Ship SDK deployment.
|
|
615
615
|
|
|
616
616
|
**5. No Visual Components**
|
|
617
617
|
|
package/dist/index.cjs
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
var react = require('react');
|
|
4
4
|
var ship = require('@shipstatic/ship');
|
|
5
|
-
var types = require('@shipstatic/types');
|
|
6
5
|
|
|
7
6
|
var __create = Object.create;
|
|
8
7
|
var __defProp = Object.defineProperty;
|
|
@@ -11703,6 +11702,42 @@ var require_mime_db = __commonJS({
|
|
|
11703
11702
|
}
|
|
11704
11703
|
});
|
|
11705
11704
|
|
|
11705
|
+
// node_modules/.pnpm/@shipstatic+types@0.3.19/node_modules/@shipstatic/types/dist/index.js
|
|
11706
|
+
var ErrorType;
|
|
11707
|
+
(function(ErrorType2) {
|
|
11708
|
+
ErrorType2["Validation"] = "validation_failed";
|
|
11709
|
+
ErrorType2["NotFound"] = "not_found";
|
|
11710
|
+
ErrorType2["RateLimit"] = "rate_limit_exceeded";
|
|
11711
|
+
ErrorType2["Authentication"] = "authentication_failed";
|
|
11712
|
+
ErrorType2["Business"] = "business_logic_error";
|
|
11713
|
+
ErrorType2["Api"] = "internal_server_error";
|
|
11714
|
+
ErrorType2["Network"] = "network_error";
|
|
11715
|
+
ErrorType2["Cancelled"] = "operation_cancelled";
|
|
11716
|
+
ErrorType2["File"] = "file_error";
|
|
11717
|
+
ErrorType2["Config"] = "config_error";
|
|
11718
|
+
})(ErrorType || (ErrorType = {}));
|
|
11719
|
+
({
|
|
11720
|
+
client: /* @__PURE__ */ new Set([ErrorType.Business, ErrorType.Config, ErrorType.File, ErrorType.Validation]),
|
|
11721
|
+
network: /* @__PURE__ */ new Set([ErrorType.Network]),
|
|
11722
|
+
auth: /* @__PURE__ */ new Set([ErrorType.Authentication])
|
|
11723
|
+
});
|
|
11724
|
+
var FileValidationStatus = {
|
|
11725
|
+
PENDING: "pending",
|
|
11726
|
+
PROCESSING_ERROR: "processing_error",
|
|
11727
|
+
EMPTY_FILE: "empty_file",
|
|
11728
|
+
VALIDATION_FAILED: "validation_failed",
|
|
11729
|
+
READY: "ready"
|
|
11730
|
+
};
|
|
11731
|
+
|
|
11732
|
+
// src/types.ts
|
|
11733
|
+
var FILE_STATUSES = {
|
|
11734
|
+
...FileValidationStatus,
|
|
11735
|
+
PROCESSING: "processing",
|
|
11736
|
+
UPLOADING: "uploading",
|
|
11737
|
+
COMPLETE: "complete",
|
|
11738
|
+
ERROR: "error"
|
|
11739
|
+
};
|
|
11740
|
+
|
|
11706
11741
|
// src/utils/zipExtractor.ts
|
|
11707
11742
|
var import_jszip = __toESM(require_jszip_min());
|
|
11708
11743
|
|
|
@@ -11778,15 +11813,6 @@ function normalizePath(path) {
|
|
|
11778
11813
|
function isZipFile(file) {
|
|
11779
11814
|
return file.type === "application/zip" || file.type === "application/x-zip-compressed" || file.name.toLowerCase().endsWith(".zip");
|
|
11780
11815
|
}
|
|
11781
|
-
var FILE_STATUSES = {
|
|
11782
|
-
...types.FileValidationStatus,
|
|
11783
|
-
PROCESSING: "processing",
|
|
11784
|
-
UPLOADING: "uploading",
|
|
11785
|
-
COMPLETE: "complete",
|
|
11786
|
-
ERROR: "error"
|
|
11787
|
-
};
|
|
11788
|
-
|
|
11789
|
-
// src/utils/fileProcessing.ts
|
|
11790
11816
|
var formatFileSize = ship.formatFileSize;
|
|
11791
11817
|
async function createProcessedFile(file, options) {
|
|
11792
11818
|
const webkitPath = file.webkitRelativePath || "";
|
|
@@ -12028,7 +12054,17 @@ function useDrop(options) {
|
|
|
12028
12054
|
e.preventDefault();
|
|
12029
12055
|
setState((prev) => {
|
|
12030
12056
|
if (prev.value !== "dragging") return prev;
|
|
12031
|
-
|
|
12057
|
+
if (prev.files.length === 0) {
|
|
12058
|
+
return { ...prev, value: "idle" };
|
|
12059
|
+
}
|
|
12060
|
+
const errorStatuses = [
|
|
12061
|
+
FILE_STATUSES.VALIDATION_FAILED,
|
|
12062
|
+
FILE_STATUSES.PROCESSING_ERROR,
|
|
12063
|
+
FILE_STATUSES.EMPTY_FILE,
|
|
12064
|
+
FILE_STATUSES.ERROR
|
|
12065
|
+
];
|
|
12066
|
+
const hasErrors = prev.files.some((f) => errorStatuses.includes(f.status));
|
|
12067
|
+
const nextValue = hasErrors ? "error" : "ready";
|
|
12032
12068
|
return { ...prev, value: nextValue };
|
|
12033
12069
|
});
|
|
12034
12070
|
}, []);
|