@shipstatic/drop 0.1.9 → 0.1.10

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 CHANGED
@@ -85,9 +85,8 @@ function MyUploader() {
85
85
  });
86
86
 
87
87
  const handleUpload = async () => {
88
- const validFiles = drop.getValidFiles();
89
88
  // ProcessedFile extends StaticFile - no conversion needed!
90
- await ship.deployments.create(validFiles.map(f => f.file));
89
+ await ship.deployments.create(drop.validFiles.map(f => f.file));
91
90
  };
92
91
 
93
92
  return (
@@ -126,7 +125,7 @@ function MyUploader() {
126
125
  onClick={handleUpload}
127
126
  disabled={drop.phase !== 'ready'}
128
127
  >
129
- Upload {drop.getValidFiles().length} files
128
+ Upload {drop.validFiles.length} files
130
129
  </button>
131
130
  </div>
132
131
  );
@@ -277,7 +276,7 @@ interface DropReturn {
277
276
 
278
277
  // Helpers
279
278
  /** Get only valid files ready for upload */
280
- getValidFiles: () => ProcessedFile[];
279
+ validFiles: ProcessedFile[];
281
280
  /** Update upload state for a specific file (status, progress, message) */
282
281
  updateFileStatus: (fileId: string, state: {
283
282
  status: FileStatus;
@@ -628,7 +627,7 @@ All errors are surfaced at the per-file level:
628
627
  - Processing errors (e.g., ZIP extraction failures) are marked with `status: 'processing_error'`
629
628
  - Validation failures are marked with `status: 'validation_failed'`
630
629
  - The `statusMessage` always contains specific error details
631
- - Failed files are excluded from `getValidFiles()` and cannot be deployed
630
+ - Failed files are excluded from `validFiles` and cannot be deployed
632
631
  - No silent failures - all errors are visible to users
633
632
 
634
633
  See the [Error Handling](#error-handling) section for examples of displaying per-file errors in your UI.
package/dist/index.cjs CHANGED
@@ -11828,10 +11828,20 @@ function stripCommonPrefix(files) {
11828
11828
  }
11829
11829
  if (commonDepth === 0) return files;
11830
11830
  const prefix = segments.slice(0, commonDepth).join("/") + "/";
11831
- return files.map((f) => ({
11832
- ...f,
11833
- path: f.path.startsWith(prefix) ? f.path.slice(prefix.length) : f.path
11834
- }));
11831
+ return files.map((f) => {
11832
+ const newPath = f.path.startsWith(prefix) ? f.path.slice(prefix.length) : f.path;
11833
+ if (f.file) {
11834
+ Object.defineProperty(f.file, "webkitRelativePath", {
11835
+ value: newPath,
11836
+ writable: false,
11837
+ configurable: true
11838
+ });
11839
+ }
11840
+ return {
11841
+ ...f,
11842
+ path: newPath
11843
+ };
11844
+ });
11835
11845
  }
11836
11846
  async function traverseFileTree(entry, files, currentPath = "") {
11837
11847
  try {
@@ -11842,7 +11852,8 @@ async function traverseFileTree(entry, files, currentPath = "") {
11842
11852
  const relativePath = currentPath ? `${currentPath}/${file.name}` : file.name;
11843
11853
  Object.defineProperty(file, "webkitRelativePath", {
11844
11854
  value: relativePath,
11845
- writable: false
11855
+ writable: false,
11856
+ configurable: true
11846
11857
  });
11847
11858
  files.push(file);
11848
11859
  } else if (entry.isDirectory) {
@@ -12031,21 +12042,21 @@ function useDrop(options) {
12031
12042
  e.preventDefault();
12032
12043
  const items = Array.from(e.dataTransfer.items);
12033
12044
  const files = [];
12034
- let hasEntries = false;
12045
+ const entriesToTraverse = [];
12035
12046
  for (const item of items) {
12036
12047
  if (item.kind === "file") {
12037
12048
  try {
12038
12049
  const entry = item.webkitGetAsEntry?.();
12039
- if (entry) {
12040
- hasEntries = true;
12041
- await traverseFileTree(
12042
- entry,
12043
- files,
12044
- entry.isDirectory ? entry.name : ""
12045
- );
12050
+ if (entry && entry.isDirectory) {
12051
+ entriesToTraverse.push({ entry, path: entry.name });
12046
12052
  } else {
12047
12053
  const file = item.getAsFile();
12048
12054
  if (file) {
12055
+ Object.defineProperty(file, "webkitRelativePath", {
12056
+ value: file.name,
12057
+ writable: false,
12058
+ configurable: true
12059
+ });
12049
12060
  files.push(file);
12050
12061
  }
12051
12062
  }
@@ -12058,7 +12069,12 @@ function useDrop(options) {
12058
12069
  }
12059
12070
  }
12060
12071
  }
12061
- if (!hasEntries && e.dataTransfer.files.length > 0) {
12072
+ if (entriesToTraverse.length > 0) {
12073
+ await Promise.all(entriesToTraverse.map(
12074
+ (item) => traverseFileTree(item.entry, files, item.path)
12075
+ ));
12076
+ }
12077
+ if (files.length === 0 && e.dataTransfer.files.length > 0) {
12062
12078
  files.push(...Array.from(e.dataTransfer.files));
12063
12079
  }
12064
12080
  if (files.length > 0) {
@@ -12092,7 +12108,6 @@ function useDrop(options) {
12092
12108
  }), [handleInputChange]);
12093
12109
  return {
12094
12110
  // State machine
12095
- // state, // REMOVED
12096
12111
  // Convenience getters (computed from state)
12097
12112
  phase: state.value,
12098
12113
  isProcessing,