0
# Directory Operations
1
2
Directory management functionality including listing, creation, deletion, and bulk transfer operations with filtering and concurrent processing support.
3
4
## Capabilities
5
6
### List Directory
7
8
Lists the contents of a remote directory with optional filtering.
9
10
```javascript { .api }
11
/**
12
* List contents of a remote directory
13
* @param remotePath - Path to remote directory
14
* @param filter - Optional filter function to select entries
15
* @param addListeners - Whether to add event listeners (default: true)
16
* @returns Promise resolving to array of file entry objects
17
*/
18
list(remotePath, filter, addListeners = true): Promise<Array>;
19
```
20
21
**Usage Examples:**
22
23
```javascript
24
// List all files and directories
25
const files = await sftp.list('/remote/directory');
26
console.log(files);
27
28
// List with filter function
29
const textFiles = await sftp.list('/remote/docs', (item) => {
30
return item.name.endsWith('.txt');
31
});
32
33
// List only directories
34
const directories = await sftp.list('/remote/path', (item) => {
35
return item.type === 'd';
36
});
37
38
// List files larger than 1MB
39
const largeFiles = await sftp.list('/remote/files', (item) => {
40
return item.type === '-' && item.size > 1024 * 1024;
41
});
42
```
43
44
**File Entry Object:**
45
46
```javascript { .api }
47
interface FileEntry {
48
type: string; // 'd' for directory, '-' for file, 'l' for link
49
name: string; // File/directory name
50
size: number; // Size in bytes
51
modifyTime: number; // Last modified time (milliseconds)
52
accessTime: number; // Last access time (milliseconds)
53
rights: {
54
user: string; // User permissions (rwx format)
55
group: string; // Group permissions (rwx format)
56
other: string; // Other permissions (rwx format)
57
};
58
owner: number; // Owner UID
59
group: number; // Group GID
60
longname: string; // Full listing format string
61
}
62
```
63
64
### Make Directory
65
66
Creates directories on the remote server with optional recursive creation.
67
68
```javascript { .api }
69
/**
70
* Create directory on remote server
71
* @param remotePath - Path for new directory
72
* @param recursive - Create parent directories if needed (default: false)
73
* @returns Promise resolving to success message
74
*/
75
mkdir(remotePath, recursive = false): Promise<String>;
76
```
77
78
**Usage Examples:**
79
80
```javascript
81
// Create single directory
82
await sftp.mkdir('/remote/new-folder');
83
84
// Create directory tree recursively
85
await sftp.mkdir('/remote/path/to/deep/folder', true);
86
87
// Create directory with error handling
88
try {
89
await sftp.mkdir('/remote/existing-folder');
90
} catch (err) {
91
if (err.code !== 'EEXIST') {
92
throw err; // Re-throw if not "already exists" error
93
}
94
}
95
```
96
97
### Remove Directory
98
99
Removes directories from the remote server with optional recursive deletion.
100
101
```javascript { .api }
102
/**
103
* Remove directory from remote server
104
* @param remoteDir - Path to directory to remove
105
* @param recursive - Remove contents recursively (default: false)
106
* @returns Promise resolving to success message
107
*/
108
rmdir(remoteDir, recursive = false): Promise<String>;
109
```
110
111
**Usage Examples:**
112
113
```javascript
114
// Remove empty directory
115
await sftp.rmdir('/remote/empty-folder');
116
117
// Remove directory and all contents
118
await sftp.rmdir('/remote/folder-with-files', true);
119
120
// Safe removal with existence check
121
const exists = await sftp.exists('/remote/maybe-folder');
122
if (exists === 'd') {
123
await sftp.rmdir('/remote/maybe-folder', true);
124
}
125
```
126
127
### Upload Directory
128
129
Recursively uploads a local directory to the remote server with filtering and performance options.
130
131
```javascript { .api }
132
/**
133
* Upload local directory to remote server recursively
134
* @param srcDir - Local source directory path
135
* @param dstDir - Remote destination directory path
136
* @param options - Optional upload configuration
137
* @returns Promise resolving to success message
138
*/
139
uploadDir(srcDir, dstDir, options): Promise<String>;
140
```
141
142
**Upload Options:**
143
144
```javascript { .api }
145
interface UploadDirectoryOptions {
146
filter?: (filePath: string, isDirectory: boolean) => boolean;
147
useFastput?: boolean; // Use fastPut for file uploads (default: false)
148
}
149
```
150
151
**Usage Examples:**
152
153
```javascript
154
// Upload entire directory
155
await sftp.uploadDir('/local/project', '/remote/project');
156
157
// Upload with filtering
158
await sftp.uploadDir('/local/source', '/remote/source', {
159
filter: (filePath, isDirectory) => {
160
// Skip hidden files and node_modules
161
const name = path.basename(filePath);
162
return !name.startsWith('.') && name !== 'node_modules';
163
}
164
});
165
166
// Upload with fast transfers
167
await sftp.uploadDir('/local/data', '/remote/data', {
168
useFastput: true,
169
filter: (filePath, isDirectory) => {
170
// Only upload .txt and .json files
171
return isDirectory || filePath.match(/\.(txt|json)$/);
172
}
173
});
174
```
175
176
### Download Directory
177
178
Recursively downloads a remote directory to the local system with filtering and performance options.
179
180
```javascript { .api }
181
/**
182
* Download remote directory to local system recursively
183
* @param srcDir - Remote source directory path
184
* @param dstDir - Local destination directory path
185
* @param options - Optional download configuration
186
* @returns Promise resolving to success message
187
*/
188
downloadDir(srcDir, dstDir, options = { filter: null, useFastget: false }): Promise<String>;
189
```
190
191
**Download Options:**
192
193
```javascript { .api }
194
interface DownloadDirectoryOptions {
195
filter?: (filePath: string, isDirectory: boolean) => boolean;
196
useFastget?: boolean; // Use fastGet for file downloads (default: false)
197
}
198
```
199
200
**Usage Examples:**
201
202
```javascript
203
// Download entire directory
204
await sftp.downloadDir('/remote/backup', '/local/backup');
205
206
// Download with filtering
207
await sftp.downloadDir('/remote/logs', '/local/logs', {
208
filter: (filePath, isDirectory) => {
209
// Only download .log files from today
210
if (isDirectory) return true;
211
const today = new Date().toISOString().split('T')[0];
212
return filePath.includes(today) && filePath.endsWith('.log');
213
}
214
});
215
216
// Download with fast transfers
217
await sftp.downloadDir('/remote/media', '/local/media', {
218
useFastget: true,
219
filter: (filePath, isDirectory) => {
220
// Download images and videos only
221
return isDirectory || filePath.match(/\.(jpg|png|mp4|avi)$/i);
222
}
223
});
224
```
225
226
## Bulk Operation Features
227
228
### Concurrent Processing
229
230
Directory operations use concurrent processing with configurable limits:
231
232
- **Promise Limit**: Control maximum concurrent operations (default: 10)
233
- **Batch Processing**: Operations are grouped into batches for efficiency
234
- **Progress Events**: Upload/download operations emit progress events
235
236
### Event Monitoring
237
238
Monitor bulk operations with custom event handlers:
239
240
```javascript
241
// Listen for upload progress
242
sftp.client.on('upload', (info) => {
243
console.log(`Uploading: ${info.source} -> ${info.destination}`);
244
});
245
246
// Listen for download progress
247
sftp.client.on('download', (info) => {
248
console.log(`Downloading: ${info.source} -> ${info.destination}`);
249
});
250
```
251
252
### Filtering Strategies
253
254
Common filtering patterns for directory operations:
255
256
```javascript
257
// File extension filter
258
const imageFilter = (filePath, isDirectory) => {
259
return isDirectory || /\.(jpg|jpeg|png|gif)$/i.test(filePath);
260
};
261
262
// Size-based filter
263
const smallFilesFilter = (filePath, isDirectory) => {
264
if (isDirectory) return true;
265
const stats = fs.statSync(filePath);
266
return stats.size < 10 * 1024 * 1024; // Less than 10MB
267
};
268
269
// Date-based filter
270
const recentFilter = (filePath, isDirectory) => {
271
if (isDirectory) return true;
272
const stats = fs.statSync(filePath);
273
const weekAgo = Date.now() - (7 * 24 * 60 * 60 * 1000);
274
return stats.mtime.getTime() > weekAgo;
275
};
276
277
// Complex filter combining multiple criteria
278
const complexFilter = (filePath, isDirectory) => {
279
if (isDirectory) {
280
// Skip hidden and system directories
281
const dirName = path.basename(filePath);
282
return !dirName.startsWith('.') && dirName !== 'node_modules';
283
}
284
285
// For files: only .js/.json files, not too large
286
const ext = path.extname(filePath).toLowerCase();
287
if (!['.js', '.json'].includes(ext)) return false;
288
289
const stats = fs.statSync(filePath);
290
return stats.size < 5 * 1024 * 1024; // Less than 5MB
291
};
292
```
293
294
## Performance Optimization
295
296
- **Use filtering** to reduce unnecessary transfers
297
- **Enable fast transfers** for large files when server supports it
298
- **Adjust promise limits** based on server capabilities and network conditions
299
- **Monitor progress events** to track bulk operation status
300
- **Handle errors gracefully** to avoid partial transfers
301
302
## Error Handling
303
304
Directory operation errors provide detailed context:
305
306
- `ERR_BAD_PATH`: Invalid directory path or permissions
307
- `ENOENT`: Directory does not exist
308
- `ENOTDIR`: Path exists but is not a directory
309
- `EEXIST`: Directory already exists (mkdir)
310
- `ENOTEMPTY`: Directory not empty (rmdir without recursive)
311
- Local file system errors during directory transfers