@shipstatic/drop 0.1.12 → 0.1.13
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 -41
- 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
|
|
|
@@ -476,27 +476,34 @@ Use `clearAll()` to reset and try again:
|
|
|
476
476
|
|
|
477
477
|
```typescript
|
|
478
478
|
/**
|
|
479
|
-
* ProcessedFile
|
|
480
|
-
* This means it can be passed directly to ship.deployments.create()
|
|
479
|
+
* ProcessedFile - a file processed by Drop, ready for Ship SDK deployment
|
|
481
480
|
*
|
|
481
|
+
* Use the `file` property to pass to ship.deployments.create()
|
|
482
482
|
* Note: md5 is intentionally undefined - Ship SDK calculates it during deployment
|
|
483
483
|
*/
|
|
484
|
-
interface ProcessedFile
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
484
|
+
interface ProcessedFile {
|
|
485
|
+
/** Unique identifier for React keys */
|
|
486
|
+
id: string;
|
|
487
|
+
/** The File object - pass this to ship.deployments.create() */
|
|
488
|
+
file: File;
|
|
489
|
+
/** Relative path for deployment (e.g., "images/photo.jpg") */
|
|
490
|
+
path: string;
|
|
491
|
+
/** File size in bytes */
|
|
492
|
+
size: number;
|
|
493
|
+
/** MD5 hash (optional - Ship SDK calculates during deployment if not provided) */
|
|
494
|
+
md5?: string;
|
|
495
|
+
/** Filename without path */
|
|
496
|
+
name: string;
|
|
497
|
+
/** MIME type for UI icons/previews */
|
|
498
|
+
type: string;
|
|
499
|
+
/** Last modified timestamp */
|
|
496
500
|
lastModified: number;
|
|
501
|
+
/** Current processing/upload status */
|
|
497
502
|
status: FileStatus;
|
|
498
|
-
|
|
499
|
-
|
|
503
|
+
/** Human-readable status message for UI */
|
|
504
|
+
statusMessage?: string;
|
|
505
|
+
/** Upload progress (0-100) - only set during upload */
|
|
506
|
+
progress?: number;
|
|
500
507
|
}
|
|
501
508
|
|
|
502
509
|
interface ClientError {
|
|
@@ -519,36 +526,30 @@ type FileStatus =
|
|
|
519
526
|
|
|
520
527
|
## Direct Ship SDK Integration
|
|
521
528
|
|
|
522
|
-
|
|
529
|
+
Extract the `file` property from ProcessedFiles to pass to Ship SDK:
|
|
523
530
|
|
|
524
531
|
```typescript
|
|
525
|
-
|
|
532
|
+
// Get valid files and extract File objects for deployment
|
|
533
|
+
const filesToDeploy = drop.validFiles.map(f => f.file);
|
|
526
534
|
|
|
527
|
-
//
|
|
528
|
-
await ship.deployments.create(
|
|
535
|
+
// Pass File[] to Ship SDK
|
|
536
|
+
await ship.deployments.create(filesToDeploy);
|
|
529
537
|
```
|
|
530
538
|
|
|
531
|
-
###
|
|
539
|
+
### Why Extract `.file`?
|
|
540
|
+
|
|
541
|
+
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
542
|
|
|
533
543
|
```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
|
|
544
|
+
// ProcessedFile structure
|
|
545
|
+
interface ProcessedFile {
|
|
546
|
+
file: File; // ← Pass this to Ship SDK
|
|
547
|
+
path: string; // Normalized path (set on file.webkitRelativePath)
|
|
548
|
+
// ... UI properties (id, status, progress, etc.)
|
|
548
549
|
}
|
|
549
550
|
```
|
|
550
551
|
|
|
551
|
-
**Important**:
|
|
552
|
+
**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
553
|
|
|
553
554
|
## Architecture Decisions
|
|
554
555
|
|
|
@@ -599,19 +600,19 @@ This is the same pattern used by popular libraries like `react-dropzone`, `downs
|
|
|
599
600
|
**3. Loosely Coupled Integration**
|
|
600
601
|
Following industry standards (Firebase hooks, Supabase utilities), we chose:
|
|
601
602
|
- ✅ **Ship instance as dependency**: Validates using `ship.getConfig()`
|
|
602
|
-
- ✅ **Simple output**: ProcessedFile[]
|
|
603
|
+
- ✅ **Simple output**: Extract `.file` from ProcessedFile[] for Ship SDK
|
|
603
604
|
- ✅ **Testable**: Easy to mock Ship SDK for testing
|
|
604
605
|
- ✅ **Flexible**: Host app controls WHEN to deploy
|
|
605
606
|
|
|
606
607
|
**4. Type System Integration**
|
|
607
608
|
|
|
608
|
-
ProcessedFile
|
|
609
|
+
ProcessedFile wraps File objects with UI-specific metadata:
|
|
609
610
|
|
|
610
611
|
```
|
|
611
|
-
File[] → ProcessedFile[] (
|
|
612
|
+
File[] → ProcessedFile[] → .map(f => f.file) → ship.deployments.create()
|
|
612
613
|
```
|
|
613
614
|
|
|
614
|
-
|
|
615
|
+
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
616
|
|
|
616
617
|
**5. No Visual Components**
|
|
617
618
|
|
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.18/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
|
}, []);
|