@shipstatic/drop 0.1.8 → 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 +42 -44
- package/dist/index.cjs +42 -22
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -10
- package/dist/index.d.ts +19 -10
- package/dist/index.js +43 -23
- package/dist/index.js.map +1 -1
- package/package.json +10 -9
package/dist/index.d.cts
CHANGED
|
@@ -62,6 +62,7 @@ type DropStateValue = 'idle' | 'dragging' | 'processing' | 'ready' | 'error';
|
|
|
62
62
|
interface DropStatus {
|
|
63
63
|
title: string;
|
|
64
64
|
details: string;
|
|
65
|
+
errors?: string[];
|
|
65
66
|
}
|
|
66
67
|
/**
|
|
67
68
|
* State machine state for the drop hook
|
|
@@ -84,12 +85,21 @@ interface DropOptions {
|
|
|
84
85
|
stripPrefix?: boolean;
|
|
85
86
|
}
|
|
86
87
|
interface DropReturn {
|
|
87
|
-
/** Current
|
|
88
|
-
|
|
88
|
+
/** Current phase of the state machine */
|
|
89
|
+
phase: DropStateValue;
|
|
89
90
|
/** Whether currently processing files (ZIP extraction, etc.) */
|
|
90
91
|
isProcessing: boolean;
|
|
91
92
|
/** Whether user is currently dragging over the dropzone */
|
|
92
93
|
isDragging: boolean;
|
|
94
|
+
/** Flattened access to files */
|
|
95
|
+
files: ProcessedFile[];
|
|
96
|
+
/** Flattened access to source name */
|
|
97
|
+
sourceName: string;
|
|
98
|
+
/** Flattened access to status */
|
|
99
|
+
status: {
|
|
100
|
+
title: string;
|
|
101
|
+
details: string;
|
|
102
|
+
} | null;
|
|
93
103
|
/** Get props to spread on dropzone element (handles drag & drop) */
|
|
94
104
|
getDropzoneProps: () => {
|
|
95
105
|
onDragOver: (e: React.DragEvent) => void;
|
|
@@ -115,7 +125,7 @@ interface DropReturn {
|
|
|
115
125
|
/** Clear all files and reset state */
|
|
116
126
|
clearAll: () => void;
|
|
117
127
|
/** Get only valid files ready for upload */
|
|
118
|
-
|
|
128
|
+
validFiles: ProcessedFile[];
|
|
119
129
|
/** Update upload state for a specific file (status, progress, message) */
|
|
120
130
|
updateFileStatus: (fileId: string, state: {
|
|
121
131
|
status: FileStatus;
|
|
@@ -144,7 +154,6 @@ declare function useDrop(options: DropOptions): DropReturn;
|
|
|
144
154
|
* Unified file processing utilities
|
|
145
155
|
* Converts Files directly to ProcessedFiles
|
|
146
156
|
*/
|
|
147
|
-
|
|
148
157
|
/**
|
|
149
158
|
* Format file size to human-readable string
|
|
150
159
|
* Re-exported from Ship SDK for convenience
|
|
@@ -166,16 +175,16 @@ declare function createProcessedFile(file: File, options?: {
|
|
|
166
175
|
/** Custom path (defaults to webkitRelativePath or file.name) */
|
|
167
176
|
path?: string;
|
|
168
177
|
}): Promise<ProcessedFile>;
|
|
169
|
-
/**
|
|
170
|
-
* Get only the valid files (status: READY) from a list
|
|
171
|
-
* Re-exported from Ship SDK for convenience
|
|
172
|
-
*/
|
|
173
|
-
declare const getValidFiles: (files: ProcessedFile[]) => ProcessedFile[];
|
|
174
178
|
/**
|
|
175
179
|
* Strip common directory prefix from file paths
|
|
176
180
|
* Only strips if ALL files share the same prefix
|
|
177
181
|
*/
|
|
178
182
|
declare function stripCommonPrefix(files: ProcessedFile[]): ProcessedFile[];
|
|
183
|
+
/**
|
|
184
|
+
* Recursively traverse FileSystemEntry from drag & drop to collect all files
|
|
185
|
+
* Properly sets webkitRelativePath to preserve folder structure
|
|
186
|
+
*/
|
|
187
|
+
declare function traverseFileTree(entry: FileSystemEntry, files: File[], currentPath?: string): Promise<void>;
|
|
179
188
|
|
|
180
189
|
interface ZipExtractionResult {
|
|
181
190
|
/** Extracted files as regular File objects */
|
|
@@ -203,4 +212,4 @@ declare function normalizePath(path: string): string;
|
|
|
203
212
|
*/
|
|
204
213
|
declare function isZipFile(file: File): boolean;
|
|
205
214
|
|
|
206
|
-
export { type ClientError, type DropOptions, type DropReturn, type DropState, type DropStateValue, type DropStatus, FILE_STATUSES, type FileStatus, type ProcessedFile, type ZipExtractionResult, createProcessedFile, extractZipToFiles, formatFileSize,
|
|
215
|
+
export { type ClientError, type DropOptions, type DropReturn, type DropState, type DropStateValue, type DropStatus, FILE_STATUSES, type FileStatus, type ProcessedFile, type ZipExtractionResult, createProcessedFile, extractZipToFiles, formatFileSize, isZipFile, normalizePath, stripCommonPrefix, traverseFileTree, useDrop };
|
package/dist/index.d.ts
CHANGED
|
@@ -62,6 +62,7 @@ type DropStateValue = 'idle' | 'dragging' | 'processing' | 'ready' | 'error';
|
|
|
62
62
|
interface DropStatus {
|
|
63
63
|
title: string;
|
|
64
64
|
details: string;
|
|
65
|
+
errors?: string[];
|
|
65
66
|
}
|
|
66
67
|
/**
|
|
67
68
|
* State machine state for the drop hook
|
|
@@ -84,12 +85,21 @@ interface DropOptions {
|
|
|
84
85
|
stripPrefix?: boolean;
|
|
85
86
|
}
|
|
86
87
|
interface DropReturn {
|
|
87
|
-
/** Current
|
|
88
|
-
|
|
88
|
+
/** Current phase of the state machine */
|
|
89
|
+
phase: DropStateValue;
|
|
89
90
|
/** Whether currently processing files (ZIP extraction, etc.) */
|
|
90
91
|
isProcessing: boolean;
|
|
91
92
|
/** Whether user is currently dragging over the dropzone */
|
|
92
93
|
isDragging: boolean;
|
|
94
|
+
/** Flattened access to files */
|
|
95
|
+
files: ProcessedFile[];
|
|
96
|
+
/** Flattened access to source name */
|
|
97
|
+
sourceName: string;
|
|
98
|
+
/** Flattened access to status */
|
|
99
|
+
status: {
|
|
100
|
+
title: string;
|
|
101
|
+
details: string;
|
|
102
|
+
} | null;
|
|
93
103
|
/** Get props to spread on dropzone element (handles drag & drop) */
|
|
94
104
|
getDropzoneProps: () => {
|
|
95
105
|
onDragOver: (e: React.DragEvent) => void;
|
|
@@ -115,7 +125,7 @@ interface DropReturn {
|
|
|
115
125
|
/** Clear all files and reset state */
|
|
116
126
|
clearAll: () => void;
|
|
117
127
|
/** Get only valid files ready for upload */
|
|
118
|
-
|
|
128
|
+
validFiles: ProcessedFile[];
|
|
119
129
|
/** Update upload state for a specific file (status, progress, message) */
|
|
120
130
|
updateFileStatus: (fileId: string, state: {
|
|
121
131
|
status: FileStatus;
|
|
@@ -144,7 +154,6 @@ declare function useDrop(options: DropOptions): DropReturn;
|
|
|
144
154
|
* Unified file processing utilities
|
|
145
155
|
* Converts Files directly to ProcessedFiles
|
|
146
156
|
*/
|
|
147
|
-
|
|
148
157
|
/**
|
|
149
158
|
* Format file size to human-readable string
|
|
150
159
|
* Re-exported from Ship SDK for convenience
|
|
@@ -166,16 +175,16 @@ declare function createProcessedFile(file: File, options?: {
|
|
|
166
175
|
/** Custom path (defaults to webkitRelativePath or file.name) */
|
|
167
176
|
path?: string;
|
|
168
177
|
}): Promise<ProcessedFile>;
|
|
169
|
-
/**
|
|
170
|
-
* Get only the valid files (status: READY) from a list
|
|
171
|
-
* Re-exported from Ship SDK for convenience
|
|
172
|
-
*/
|
|
173
|
-
declare const getValidFiles: (files: ProcessedFile[]) => ProcessedFile[];
|
|
174
178
|
/**
|
|
175
179
|
* Strip common directory prefix from file paths
|
|
176
180
|
* Only strips if ALL files share the same prefix
|
|
177
181
|
*/
|
|
178
182
|
declare function stripCommonPrefix(files: ProcessedFile[]): ProcessedFile[];
|
|
183
|
+
/**
|
|
184
|
+
* Recursively traverse FileSystemEntry from drag & drop to collect all files
|
|
185
|
+
* Properly sets webkitRelativePath to preserve folder structure
|
|
186
|
+
*/
|
|
187
|
+
declare function traverseFileTree(entry: FileSystemEntry, files: File[], currentPath?: string): Promise<void>;
|
|
179
188
|
|
|
180
189
|
interface ZipExtractionResult {
|
|
181
190
|
/** Extracted files as regular File objects */
|
|
@@ -203,4 +212,4 @@ declare function normalizePath(path: string): string;
|
|
|
203
212
|
*/
|
|
204
213
|
declare function isZipFile(file: File): boolean;
|
|
205
214
|
|
|
206
|
-
export { type ClientError, type DropOptions, type DropReturn, type DropState, type DropStateValue, type DropStatus, FILE_STATUSES, type FileStatus, type ProcessedFile, type ZipExtractionResult, createProcessedFile, extractZipToFiles, formatFileSize,
|
|
215
|
+
export { type ClientError, type DropOptions, type DropReturn, type DropState, type DropStateValue, type DropStatus, FILE_STATUSES, type FileStatus, type ProcessedFile, type ZipExtractionResult, createProcessedFile, extractZipToFiles, formatFileSize, isZipFile, normalizePath, stripCommonPrefix, traverseFileTree, useDrop };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useState, useRef, useMemo, useCallback } from 'react';
|
|
2
|
-
import { formatFileSize as formatFileSize$1, getValidFiles
|
|
2
|
+
import { formatFileSize as formatFileSize$1, getValidFiles, filterJunk, validateFiles } from '@shipstatic/ship';
|
|
3
3
|
|
|
4
4
|
var __create = Object.create;
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
@@ -11811,7 +11811,6 @@ async function createProcessedFile(file, options) {
|
|
|
11811
11811
|
status: FILE_STATUSES.PENDING
|
|
11812
11812
|
};
|
|
11813
11813
|
}
|
|
11814
|
-
var getValidFiles = getValidFiles$1;
|
|
11815
11814
|
function stripCommonPrefix(files) {
|
|
11816
11815
|
if (files.length === 0) return files;
|
|
11817
11816
|
const paths = files.map((f) => f.path);
|
|
@@ -11827,10 +11826,20 @@ function stripCommonPrefix(files) {
|
|
|
11827
11826
|
}
|
|
11828
11827
|
if (commonDepth === 0) return files;
|
|
11829
11828
|
const prefix = segments.slice(0, commonDepth).join("/") + "/";
|
|
11830
|
-
return files.map((f) =>
|
|
11831
|
-
|
|
11832
|
-
|
|
11833
|
-
|
|
11829
|
+
return files.map((f) => {
|
|
11830
|
+
const newPath = f.path.startsWith(prefix) ? f.path.slice(prefix.length) : f.path;
|
|
11831
|
+
if (f.file) {
|
|
11832
|
+
Object.defineProperty(f.file, "webkitRelativePath", {
|
|
11833
|
+
value: newPath,
|
|
11834
|
+
writable: false,
|
|
11835
|
+
configurable: true
|
|
11836
|
+
});
|
|
11837
|
+
}
|
|
11838
|
+
return {
|
|
11839
|
+
...f,
|
|
11840
|
+
path: newPath
|
|
11841
|
+
};
|
|
11842
|
+
});
|
|
11834
11843
|
}
|
|
11835
11844
|
async function traverseFileTree(entry, files, currentPath = "") {
|
|
11836
11845
|
try {
|
|
@@ -11841,7 +11850,8 @@ async function traverseFileTree(entry, files, currentPath = "") {
|
|
|
11841
11850
|
const relativePath = currentPath ? `${currentPath}/${file.name}` : file.name;
|
|
11842
11851
|
Object.defineProperty(file, "webkitRelativePath", {
|
|
11843
11852
|
value: relativePath,
|
|
11844
|
-
writable: false
|
|
11853
|
+
writable: false,
|
|
11854
|
+
configurable: true
|
|
11845
11855
|
});
|
|
11846
11856
|
files.push(file);
|
|
11847
11857
|
} else if (entry.isDirectory) {
|
|
@@ -11886,6 +11896,7 @@ function useDrop(options) {
|
|
|
11886
11896
|
const inputRef = useRef(null);
|
|
11887
11897
|
const isProcessing = useMemo(() => state.value === "processing", [state.value]);
|
|
11888
11898
|
const isDragging = useMemo(() => state.value === "dragging", [state.value]);
|
|
11899
|
+
const validFiles = useMemo(() => getValidFiles(state.files), [state.files]);
|
|
11889
11900
|
const processFiles = useCallback(async (newFiles) => {
|
|
11890
11901
|
if (isProcessingRef.current) {
|
|
11891
11902
|
console.warn("File processing already in progress. Ignoring duplicate call.");
|
|
@@ -11951,7 +11962,11 @@ function useDrop(options) {
|
|
|
11951
11962
|
value: "error",
|
|
11952
11963
|
files: validation.files,
|
|
11953
11964
|
sourceName: detectedSourceName,
|
|
11954
|
-
status: {
|
|
11965
|
+
status: {
|
|
11966
|
+
title: validation.error.error,
|
|
11967
|
+
details: validation.error.details,
|
|
11968
|
+
errors: validation.error.errors
|
|
11969
|
+
}
|
|
11955
11970
|
});
|
|
11956
11971
|
onValidationError?.(validation.error);
|
|
11957
11972
|
} else if (validation.validFiles.length > 0) {
|
|
@@ -11996,9 +12011,6 @@ function useDrop(options) {
|
|
|
11996
12011
|
setState(initialState);
|
|
11997
12012
|
isProcessingRef.current = false;
|
|
11998
12013
|
}, []);
|
|
11999
|
-
const getValidFilesCallback = useCallback(() => {
|
|
12000
|
-
return getValidFiles(state.files);
|
|
12001
|
-
}, [state.files]);
|
|
12002
12014
|
const updateFileStatus = useCallback((fileId, fileState) => {
|
|
12003
12015
|
setState((prev) => ({
|
|
12004
12016
|
...prev,
|
|
@@ -12028,21 +12040,21 @@ function useDrop(options) {
|
|
|
12028
12040
|
e.preventDefault();
|
|
12029
12041
|
const items = Array.from(e.dataTransfer.items);
|
|
12030
12042
|
const files = [];
|
|
12031
|
-
|
|
12043
|
+
const entriesToTraverse = [];
|
|
12032
12044
|
for (const item of items) {
|
|
12033
12045
|
if (item.kind === "file") {
|
|
12034
12046
|
try {
|
|
12035
12047
|
const entry = item.webkitGetAsEntry?.();
|
|
12036
|
-
if (entry) {
|
|
12037
|
-
|
|
12038
|
-
await traverseFileTree(
|
|
12039
|
-
entry,
|
|
12040
|
-
files,
|
|
12041
|
-
entry.isDirectory ? entry.name : ""
|
|
12042
|
-
);
|
|
12048
|
+
if (entry && entry.isDirectory) {
|
|
12049
|
+
entriesToTraverse.push({ entry, path: entry.name });
|
|
12043
12050
|
} else {
|
|
12044
12051
|
const file = item.getAsFile();
|
|
12045
12052
|
if (file) {
|
|
12053
|
+
Object.defineProperty(file, "webkitRelativePath", {
|
|
12054
|
+
value: file.name,
|
|
12055
|
+
writable: false,
|
|
12056
|
+
configurable: true
|
|
12057
|
+
});
|
|
12046
12058
|
files.push(file);
|
|
12047
12059
|
}
|
|
12048
12060
|
}
|
|
@@ -12055,7 +12067,12 @@ function useDrop(options) {
|
|
|
12055
12067
|
}
|
|
12056
12068
|
}
|
|
12057
12069
|
}
|
|
12058
|
-
if (
|
|
12070
|
+
if (entriesToTraverse.length > 0) {
|
|
12071
|
+
await Promise.all(entriesToTraverse.map(
|
|
12072
|
+
(item) => traverseFileTree(item.entry, files, item.path)
|
|
12073
|
+
));
|
|
12074
|
+
}
|
|
12075
|
+
if (files.length === 0 && e.dataTransfer.files.length > 0) {
|
|
12059
12076
|
files.push(...Array.from(e.dataTransfer.files));
|
|
12060
12077
|
}
|
|
12061
12078
|
if (files.length > 0) {
|
|
@@ -12089,10 +12106,13 @@ function useDrop(options) {
|
|
|
12089
12106
|
}), [handleInputChange]);
|
|
12090
12107
|
return {
|
|
12091
12108
|
// State machine
|
|
12092
|
-
state,
|
|
12093
12109
|
// Convenience getters (computed from state)
|
|
12110
|
+
phase: state.value,
|
|
12094
12111
|
isProcessing,
|
|
12095
12112
|
isDragging,
|
|
12113
|
+
files: state.files,
|
|
12114
|
+
sourceName: state.sourceName,
|
|
12115
|
+
status: state.status,
|
|
12096
12116
|
// Primary API: Prop getters
|
|
12097
12117
|
getDropzoneProps,
|
|
12098
12118
|
getInputProps,
|
|
@@ -12101,7 +12121,7 @@ function useDrop(options) {
|
|
|
12101
12121
|
processFiles,
|
|
12102
12122
|
clearAll,
|
|
12103
12123
|
// Helpers
|
|
12104
|
-
|
|
12124
|
+
validFiles,
|
|
12105
12125
|
updateFileStatus
|
|
12106
12126
|
};
|
|
12107
12127
|
}
|
|
@@ -12129,6 +12149,6 @@ mime-db/index.js:
|
|
|
12129
12149
|
*)
|
|
12130
12150
|
*/
|
|
12131
12151
|
|
|
12132
|
-
export { FILE_STATUSES, createProcessedFile, extractZipToFiles, formatFileSize,
|
|
12152
|
+
export { FILE_STATUSES, createProcessedFile, extractZipToFiles, formatFileSize, isZipFile, normalizePath, stripCommonPrefix, traverseFileTree, useDrop };
|
|
12133
12153
|
//# sourceMappingURL=index.js.map
|
|
12134
12154
|
//# sourceMappingURL=index.js.map
|