ssh2-sftp-client 2.4.3 → 2.5.0
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 +55 -5
- package/package.json +5 -3
- package/src/index.js +179 -95
- package/test/append.js +112 -0
- package/test/checksum-tests.js +222 -0
- package/test/fastget.js +103 -0
- package/test/fastput.js +99 -0
- package/test/get.js +104 -0
- package/test/hooks/append-hooks.js +50 -0
- package/test/hooks/checksum-hooks.js +24 -0
- package/test/hooks/chmod-hooks.js +24 -0
- package/test/hooks/delete-hooks.js +27 -0
- package/test/hooks/exist-hooks.js +39 -0
- package/test/hooks/fastGet-hooks.js +63 -0
- package/test/hooks/fastPut-hooks.js +33 -0
- package/test/hooks/get-hooks.js +52 -0
- package/test/hooks/global-hooks.js +66 -0
- package/test/hooks/list-hooks.js +63 -0
- package/test/hooks/mkdir-hooks.js +18 -0
- package/test/hooks/put-hooks.js +24 -0
- package/test/hooks/rename-hooks.js +36 -0
- package/test/hooks/rmdir-hooks.js +34 -0
- package/test/hooks/stat-hooks.js +33 -0
- package/test/mocha.opts +1 -1
- package/test/put.js +114 -0
- package/test/testData/test-file1.txt +39999 -54
- package/test/testData/test-file2.txt.gz +0 -0
- package/test/utility-methods.js +363 -0
- package/test/index.js +0 -686
package/README.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
## SSH2 SFTP Client
|
|
2
2
|
a SFTP client for node.js, a wrapper for [ssh2](https://github.com/mscdex/ssh2)
|
|
3
3
|
|
|
4
|
+
Additional documentation on the methods and available options can be found in
|
|
5
|
+
the [ssh2](https://github.com/mscdex/ssh2) and
|
|
6
|
+
[ssh2-streams](https://github.com/mscdex/ssh2-streams) documentation.
|
|
7
|
+
|
|
4
8
|
### Installation
|
|
5
9
|
```shell
|
|
6
10
|
npm install ssh2-sftp-client
|
|
@@ -24,11 +28,57 @@ sftp.connect({
|
|
|
24
28
|
});
|
|
25
29
|
```
|
|
26
30
|
|
|
31
|
+
### Breaking Changes
|
|
32
|
+
|
|
33
|
+
Due to some incompatibilities with stream handling which breaks this module when
|
|
34
|
+
used with Node 10.x, some changes have been implemented that should enhance the
|
|
35
|
+
interface, but which also break compatibility with previous versions.
|
|
36
|
+
|
|
37
|
+
#### Option Changes
|
|
38
|
+
|
|
39
|
+
- The default encoding is null not utf8 as it was previously. This is consistent
|
|
40
|
+
with the defaults for the underlying SSH2 module.
|
|
41
|
+
- The usedCompressed option has been removed. None of the shh2-steams methods
|
|
42
|
+
actually support this option. The 'compress' option can be set as part of the
|
|
43
|
+
connection options. See [ssh2 client event](https://github.com/mscdex/ssh2#user-content-client-methods).
|
|
44
|
+
- The separate explicit option arguments for encoding and useCompression for some methods
|
|
45
|
+
have been replaced with a single 'options' argument, which is an object that
|
|
46
|
+
can have the following properties (defaults shown). See the
|
|
47
|
+
[ssh2-streams](https://github.com/mscdex/ssh2-streams) documentation for an
|
|
48
|
+
explination of the opt8ons.
|
|
49
|
+
|
|
50
|
+
```javascript
|
|
51
|
+
const defaults = {
|
|
52
|
+
highWaterMark: 32 * 1024,
|
|
53
|
+
debug: undefined,
|
|
54
|
+
concurrency: 64,
|
|
55
|
+
chunkSize: 32768,
|
|
56
|
+
step: undefined,
|
|
57
|
+
mode: 0o666,
|
|
58
|
+
autoClose: true,
|
|
59
|
+
encoding: null
|
|
60
|
+
};
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### Method Changes
|
|
64
|
+
|
|
65
|
+
#### get(srcPath, dst, options)
|
|
66
|
+
|
|
67
|
+
Used to retrieve a file from a remote SFTP server.
|
|
68
|
+
|
|
69
|
+
- srcPath: path to the file on the remote server
|
|
70
|
+
- dst: Either a string, which will be used as the path to store the file on the
|
|
71
|
+
local system or a writable stream, which will be used as the destination for a
|
|
72
|
+
stream pipe. If undefined, the remote file will be read into a Buffer and
|
|
73
|
+
the buffer returned.
|
|
74
|
+
- options: Options for the get operation e.g. encoding.
|
|
75
|
+
|
|
27
76
|
### Documentation
|
|
28
77
|
the connection to server config pls see [ssh2 client event](https://github.com/mscdex/ssh2#user-content-client-methods).
|
|
29
78
|
|
|
30
79
|
list of methods:
|
|
31
80
|
all the methods will return a Promise;
|
|
81
|
+
|
|
32
82
|
#### List
|
|
33
83
|
Retrieves a directory listing.
|
|
34
84
|
|
|
@@ -54,10 +104,10 @@ group: // group ID
|
|
|
54
104
|
```
|
|
55
105
|
|
|
56
106
|
#### Get
|
|
57
|
-
Get a `ReadableStream` from remotePath. The encoding is passed to Node Stream (https://nodejs.org/api/stream.html) and it controls how the content is encoded. For example, when downloading binary data, 'null' should be passed (check node stream documentation). Default to '
|
|
107
|
+
Get a `ReadableStream` from remotePath. The encoding is passed to Node Stream (https://nodejs.org/api/stream.html) and it controls how the content is encoded. For example, when downloading binary data, 'null' should be passed (check node stream documentation). Default to 'null'.
|
|
58
108
|
|
|
59
109
|
```javascript
|
|
60
|
-
sftp.get(remoteFilePath, [
|
|
110
|
+
sftp.get(remoteFilePath, [options]);
|
|
61
111
|
```
|
|
62
112
|
|
|
63
113
|
#### FastGet
|
|
@@ -71,9 +121,9 @@ sftp.fastGet(remotePath, localPath, [options]);
|
|
|
71
121
|
upload a file from `localPath` or `Buffer`, `Stream` data to `remoteFilePath`.The encoding is passed to Node Stream to control how the content is encoded. Default to 'utf8'.
|
|
72
122
|
|
|
73
123
|
```javascript
|
|
74
|
-
sftp.put(localFilePath, remoteFilePath, [
|
|
75
|
-
sftp.put(Buffer, remoteFilePath, [
|
|
76
|
-
sftp.put(Stream, remoteFilePath, [
|
|
124
|
+
sftp.put(localFilePath, remoteFilePath, [optons]);
|
|
125
|
+
sftp.put(Buffer, remoteFilePath, [options]);
|
|
126
|
+
sftp.put(Stream, remoteFilePath, [options]);
|
|
77
127
|
```
|
|
78
128
|
|
|
79
129
|
#### FastPut
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ssh2-sftp-client",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "ssh2 sftp client for node",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -12,18 +12,20 @@
|
|
|
12
12
|
"nodejs"
|
|
13
13
|
],
|
|
14
14
|
"scripts": {
|
|
15
|
-
"test": "mocha
|
|
15
|
+
"test": "mocha"
|
|
16
16
|
},
|
|
17
17
|
"author": "见见",
|
|
18
18
|
"email": "jyu213@gmail.com",
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"
|
|
21
|
+
"concat-stream": "^2.0.0",
|
|
22
|
+
"ssh2": "^0.8.2"
|
|
22
23
|
},
|
|
23
24
|
"devDependencies": {
|
|
24
25
|
"chai": "^4.2.0",
|
|
25
26
|
"chai-as-promised": "^7.1.1",
|
|
26
27
|
"chai-subset": "^1.6.0",
|
|
28
|
+
"checksum": "^0.1.1",
|
|
27
29
|
"dotenv": "^6.1.0",
|
|
28
30
|
"mocha": "^5.2.0"
|
|
29
31
|
}
|
package/src/index.js
CHANGED
|
@@ -7,8 +7,10 @@
|
|
|
7
7
|
const Client = require('ssh2').Client;
|
|
8
8
|
const osPath = require('path').posix;
|
|
9
9
|
const utils = require('./utils');
|
|
10
|
+
const fs = require('fs');
|
|
11
|
+
const concat = require('concat-stream');
|
|
10
12
|
|
|
11
|
-
let SftpClient = function(){
|
|
13
|
+
let SftpClient = function() {
|
|
12
14
|
this.client = new Client();
|
|
13
15
|
};
|
|
14
16
|
|
|
@@ -43,7 +45,7 @@ SftpClient.prototype.list = function(path) {
|
|
|
43
45
|
accessTime: item.attrs.atime * 1000,
|
|
44
46
|
rights: {
|
|
45
47
|
user: item.longname.substr(1, 3).replace(reg, ''),
|
|
46
|
-
group: item.longname.substr(4,3).replace(reg, ''),
|
|
48
|
+
group: item.longname.substr(4, 3).replace(reg, ''),
|
|
47
49
|
other: item.longname.substr(7, 3).replace(reg, '')
|
|
48
50
|
},
|
|
49
51
|
owner: item.attrs.uid,
|
|
@@ -82,10 +84,14 @@ SftpClient.prototype.exists = function(path) {
|
|
|
82
84
|
if (err.code === 2) {
|
|
83
85
|
resolve(false);
|
|
84
86
|
} else {
|
|
85
|
-
reject(
|
|
87
|
+
reject(
|
|
88
|
+
new Error(`Error listing ${dir}: code: ${err.code} ${err.message}`)
|
|
89
|
+
);
|
|
86
90
|
}
|
|
87
91
|
} else {
|
|
88
|
-
let [type] = list
|
|
92
|
+
let [type] = list
|
|
93
|
+
.filter(item => item.filename === base)
|
|
94
|
+
.map(item => item.longname.substr(0, 1));
|
|
89
95
|
if (type) {
|
|
90
96
|
resolve(type);
|
|
91
97
|
} else {
|
|
@@ -108,18 +114,18 @@ SftpClient.prototype.stat = function(remotePath) {
|
|
|
108
114
|
let sftp = this.sftp;
|
|
109
115
|
|
|
110
116
|
if (!sftp) {
|
|
111
|
-
return reject(Error('sftp connect error'));
|
|
117
|
+
return reject(Error('sftp connect error'));
|
|
112
118
|
}
|
|
113
|
-
sftp.stat(remotePath, function
|
|
114
|
-
if (err){
|
|
119
|
+
sftp.stat(remotePath, function(err, stats) {
|
|
120
|
+
if (err) {
|
|
115
121
|
reject(new Error(`Failed to stat ${remotePath}: ${err.message}`));
|
|
116
122
|
} else {
|
|
117
|
-
|
|
123
|
+
// format similarly to sftp.list
|
|
118
124
|
resolve({
|
|
119
125
|
mode: stats.mode,
|
|
120
126
|
permissions: stats.permissions,
|
|
121
127
|
owner: stats.uid,
|
|
122
|
-
group: stats.
|
|
128
|
+
group: stats.gid,
|
|
123
129
|
size: stats.size,
|
|
124
130
|
accessTime: stats.atime * 1000,
|
|
125
131
|
modifyTime: stats.mtime * 1000
|
|
@@ -133,34 +139,53 @@ SftpClient.prototype.stat = function(remotePath) {
|
|
|
133
139
|
/**
|
|
134
140
|
* get file
|
|
135
141
|
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
140
|
-
*
|
|
141
|
-
* @
|
|
142
|
+
* If a dst argument is provided, it must be either a string, representing the
|
|
143
|
+
* local path to where the data will be put, a stream, in which case data is
|
|
144
|
+
* piped into the stream or undefined, in which case the data is returned as
|
|
145
|
+
* a Buffer object.
|
|
146
|
+
*
|
|
147
|
+
* @param {String} path, remote file path
|
|
148
|
+
* @param {string|stream|undefined} dst, data destination
|
|
149
|
+
* @param {Object} userOptions, options passed to get
|
|
150
|
+
*
|
|
151
|
+
* @return {Promise}
|
|
142
152
|
*/
|
|
143
|
-
SftpClient.prototype.get = function(path,
|
|
144
|
-
let options = this.getOptions(useCompression, encoding, otherOptions);
|
|
145
|
-
|
|
153
|
+
SftpClient.prototype.get = function(path, dst, options) {
|
|
146
154
|
return new Promise((resolve, reject) => {
|
|
147
155
|
let sftp = this.sftp;
|
|
148
156
|
|
|
149
157
|
if (sftp) {
|
|
150
158
|
try {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
stream.on('error', (err) => {
|
|
156
|
-
this.client.removeListener('error', reject);
|
|
157
|
-
return reject(new Error(`Failed get for ${path}: ${err.message}`));
|
|
158
|
-
});
|
|
159
|
-
stream.on('readable', () => {
|
|
160
|
-
this.client.removeListener('error', reject);
|
|
161
|
-
return resolve(stream);
|
|
159
|
+
let rdr = sftp.createReadStream(path, options);
|
|
160
|
+
|
|
161
|
+
rdr.on('error', err => {
|
|
162
|
+
return reject(new Error(`Failed to get ${path}: ${err.message}`));
|
|
162
163
|
});
|
|
163
|
-
|
|
164
|
+
|
|
165
|
+
if (dst === undefined) {
|
|
166
|
+
// no dst specified, return buffer of data
|
|
167
|
+
let concatStream = concat(buff => {
|
|
168
|
+
return resolve(buff);
|
|
169
|
+
});
|
|
170
|
+
rdr.pipe(concatStream);
|
|
171
|
+
} else if (typeof dst === 'string') {
|
|
172
|
+
// dst local file path
|
|
173
|
+
let wtr = fs.createWriteStream(dst);
|
|
174
|
+
wtr.on('error', err => {
|
|
175
|
+
return reject(new Error(`Failed get for ${path}: ${err.message}`));
|
|
176
|
+
});
|
|
177
|
+
wtr.on('finish', () => {
|
|
178
|
+
return resolve(dst);
|
|
179
|
+
});
|
|
180
|
+
rdr.pipe(wtr);
|
|
181
|
+
} else {
|
|
182
|
+
// assume dst is a writeStream
|
|
183
|
+
dst.on('finish', () => {
|
|
184
|
+
return resolve(dst);
|
|
185
|
+
});
|
|
186
|
+
rdr.pipe(dst);
|
|
187
|
+
}
|
|
188
|
+
} catch (err) {
|
|
164
189
|
this.client.removeListener('error', reject);
|
|
165
190
|
return reject(new Error(`Failed get on ${path}: ${err.message}`));
|
|
166
191
|
}
|
|
@@ -180,15 +205,14 @@ SftpClient.prototype.get = function(path, useCompression, encoding, otherOptions
|
|
|
180
205
|
* @return {Promise} the result of downloading the file
|
|
181
206
|
*/
|
|
182
207
|
SftpClient.prototype.fastGet = function(remotePath, localPath, options) {
|
|
183
|
-
options = options || {concurrency: 64, chunkSize: 32768};
|
|
184
208
|
return new Promise((resolve, reject) => {
|
|
185
209
|
let sftp = this.sftp;
|
|
186
210
|
|
|
187
211
|
if (!sftp) {
|
|
188
|
-
return reject(Error('sftp connect error'));
|
|
212
|
+
return reject(Error('sftp connect error'));
|
|
189
213
|
}
|
|
190
|
-
sftp.fastGet(remotePath, localPath, options, function
|
|
191
|
-
if (err){
|
|
214
|
+
sftp.fastGet(remotePath, localPath, options, function(err) {
|
|
215
|
+
if (err) {
|
|
192
216
|
reject(new Error(`Failed to get ${remotePath}: ${err.message}`));
|
|
193
217
|
}
|
|
194
218
|
resolve(`${remotePath} was successfully download to ${localPath}!`);
|
|
@@ -207,16 +231,19 @@ SftpClient.prototype.fastGet = function(remotePath, localPath, options) {
|
|
|
207
231
|
* @return {Promise} the result of downloading the file
|
|
208
232
|
*/
|
|
209
233
|
SftpClient.prototype.fastPut = function(localPath, remotePath, options) {
|
|
210
|
-
options = options || {};
|
|
211
234
|
return new Promise((resolve, reject) => {
|
|
212
235
|
let sftp = this.sftp;
|
|
213
236
|
|
|
214
237
|
if (!sftp) {
|
|
215
|
-
return reject(new Error('sftp connect error'));
|
|
238
|
+
return reject(new Error('sftp connect error'));
|
|
216
239
|
}
|
|
217
|
-
sftp.fastPut(localPath, remotePath, options, function
|
|
240
|
+
sftp.fastPut(localPath, remotePath, options, function(err) {
|
|
218
241
|
if (err) {
|
|
219
|
-
reject(
|
|
242
|
+
reject(
|
|
243
|
+
new Error(
|
|
244
|
+
`Failed to upload ${localPath} to ${remotePath}: ${err.message}`
|
|
245
|
+
)
|
|
246
|
+
);
|
|
220
247
|
}
|
|
221
248
|
resolve(`${localPath} was successfully uploaded to ${remotePath}!`);
|
|
222
249
|
});
|
|
@@ -224,7 +251,6 @@ SftpClient.prototype.fastPut = function(localPath, remotePath, options) {
|
|
|
224
251
|
});
|
|
225
252
|
};
|
|
226
253
|
|
|
227
|
-
|
|
228
254
|
/**
|
|
229
255
|
* Create file
|
|
230
256
|
*
|
|
@@ -234,17 +260,19 @@ SftpClient.prototype.fastPut = function(localPath, remotePath, options) {
|
|
|
234
260
|
* @param {String} encoding. Encoding for the WriteStream, can be any value supported by node streams.
|
|
235
261
|
* @return {[type]} [description]
|
|
236
262
|
*/
|
|
237
|
-
SftpClient.prototype.put = function(input, remotePath,
|
|
238
|
-
let options = this.getOptions(useCompression, encoding, otherOptions);
|
|
239
|
-
|
|
263
|
+
SftpClient.prototype.put = function(input, remotePath, options) {
|
|
240
264
|
return new Promise((resolve, reject) => {
|
|
241
265
|
let sftp = this.sftp;
|
|
242
266
|
|
|
243
267
|
if (sftp) {
|
|
244
268
|
if (typeof input === 'string') {
|
|
245
|
-
sftp.fastPut(input, remotePath, options,
|
|
269
|
+
sftp.fastPut(input, remotePath, options, err => {
|
|
246
270
|
if (err) {
|
|
247
|
-
return reject(
|
|
271
|
+
return reject(
|
|
272
|
+
new Error(
|
|
273
|
+
`Failed to upload ${input} to ${remotePath}: ${err.message}`
|
|
274
|
+
)
|
|
275
|
+
);
|
|
248
276
|
}
|
|
249
277
|
return resolve(`Uploaded ${input} to ${remotePath}`);
|
|
250
278
|
});
|
|
@@ -253,13 +281,58 @@ SftpClient.prototype.put = function(input, remotePath, useCompression, encoding,
|
|
|
253
281
|
let stream = sftp.createWriteStream(remotePath, options);
|
|
254
282
|
|
|
255
283
|
stream.on('error', err => {
|
|
256
|
-
return reject(
|
|
284
|
+
return reject(
|
|
285
|
+
new Error(
|
|
286
|
+
`Failed to upload data stream to ${remotePath}: ${err.message}`
|
|
287
|
+
)
|
|
288
|
+
);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
stream.on('finish', () => {
|
|
292
|
+
return resolve(`Uploaded data stream to ${remotePath}`);
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
if (input instanceof Buffer) {
|
|
296
|
+
stream.end(input);
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
input.pipe(stream);
|
|
300
|
+
} else {
|
|
301
|
+
return reject(Error('sftp connect error'));
|
|
302
|
+
}
|
|
303
|
+
});
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Append to file
|
|
308
|
+
*
|
|
309
|
+
* @param {Buffer|stream} input
|
|
310
|
+
* @param {String} remotePath,
|
|
311
|
+
* @param {Object} options
|
|
312
|
+
* @return {[type]} [description]
|
|
313
|
+
*/
|
|
314
|
+
SftpClient.prototype.append = function(input, remotePath, options) {
|
|
315
|
+
return new Promise((resolve, reject) => {
|
|
316
|
+
let sftp = this.sftp;
|
|
317
|
+
|
|
318
|
+
if (sftp) {
|
|
319
|
+
if (typeof input === 'string') {
|
|
320
|
+
throw new Error('Cannot append a file to another');
|
|
321
|
+
}
|
|
322
|
+
let stream = sftp.createWriteStream(remotePath, options);
|
|
323
|
+
|
|
324
|
+
stream.on('error', err => {
|
|
325
|
+
return reject(
|
|
326
|
+
new Error(
|
|
327
|
+
`Failed to upload data stream to ${remotePath}: ${err.message}`
|
|
328
|
+
)
|
|
329
|
+
);
|
|
257
330
|
});
|
|
258
|
-
|
|
259
|
-
stream.on('
|
|
331
|
+
|
|
332
|
+
stream.on('finish', () => {
|
|
260
333
|
return resolve(`Uploaded data stream to ${remotePath}`);
|
|
261
334
|
});
|
|
262
|
-
|
|
335
|
+
|
|
263
336
|
if (input instanceof Buffer) {
|
|
264
337
|
stream.end(input);
|
|
265
338
|
return false;
|
|
@@ -271,13 +344,20 @@ SftpClient.prototype.put = function(input, remotePath, useCompression, encoding,
|
|
|
271
344
|
});
|
|
272
345
|
};
|
|
273
346
|
|
|
347
|
+
/**
|
|
348
|
+
* @async
|
|
349
|
+
*
|
|
350
|
+
* Make a dirextory on remote server
|
|
351
|
+
*
|
|
352
|
+
* @param {string} path, remote directory path.
|
|
353
|
+
* @param {boolean} recursive, if true, recursively create directories
|
|
354
|
+
* @return {Promise}.
|
|
355
|
+
*/
|
|
274
356
|
SftpClient.prototype.mkdir = function(path, recursive = false) {
|
|
275
357
|
let sftp = this.sftp;
|
|
276
358
|
|
|
277
359
|
let doMkdir = p => {
|
|
278
360
|
return new Promise((resolve, reject) => {
|
|
279
|
-
|
|
280
|
-
|
|
281
361
|
if (!sftp) {
|
|
282
362
|
return reject(new Error('sftp connect error'));
|
|
283
363
|
}
|
|
@@ -295,24 +375,34 @@ SftpClient.prototype.mkdir = function(path, recursive = false) {
|
|
|
295
375
|
return doMkdir(path);
|
|
296
376
|
}
|
|
297
377
|
let mkdir = p => {
|
|
298
|
-
|
|
299
|
-
|
|
378
|
+
let {dir} = osPath.parse(p);
|
|
379
|
+
return this.exists(dir)
|
|
380
|
+
.then(type => {
|
|
300
381
|
if (!type) {
|
|
301
382
|
return mkdir(dir);
|
|
302
383
|
}
|
|
303
|
-
})
|
|
384
|
+
})
|
|
385
|
+
.then(() => {
|
|
304
386
|
return doMkdir(p);
|
|
305
387
|
});
|
|
306
388
|
};
|
|
307
389
|
return mkdir(path);
|
|
308
390
|
};
|
|
309
391
|
|
|
392
|
+
/**
|
|
393
|
+
* @async
|
|
394
|
+
*
|
|
395
|
+
* Remove directory on remote server
|
|
396
|
+
*
|
|
397
|
+
* @param {string} path, path to directory to be removed
|
|
398
|
+
* @param {boolean} recursive, if true, remove direcories/files in target
|
|
399
|
+
* @return {Promise}..
|
|
400
|
+
*/
|
|
310
401
|
SftpClient.prototype.rmdir = function(path, recursive = false) {
|
|
311
402
|
let sftp = this.sftp;
|
|
312
403
|
|
|
313
404
|
let doRmdir = p => {
|
|
314
405
|
return new Promise((resolve, reject) => {
|
|
315
|
-
|
|
316
406
|
if (!sftp) {
|
|
317
407
|
return reject(new Error('sftp connect error'));
|
|
318
408
|
}
|
|
@@ -334,20 +424,23 @@ SftpClient.prototype.rmdir = function(path, recursive = false) {
|
|
|
334
424
|
let list;
|
|
335
425
|
let files;
|
|
336
426
|
let dirs;
|
|
337
|
-
return this.list(p)
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
return
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
427
|
+
return this.list(p)
|
|
428
|
+
.then(res => {
|
|
429
|
+
list = res;
|
|
430
|
+
files = list.filter(item => item.type === '-');
|
|
431
|
+
dirs = list.filter(item => item.type === 'd');
|
|
432
|
+
return utils.forEachAsync(files, f => {
|
|
433
|
+
return this.delete(osPath.join(p, f.name));
|
|
434
|
+
});
|
|
435
|
+
})
|
|
436
|
+
.then(() => {
|
|
437
|
+
return utils.forEachAsync(dirs, d => {
|
|
438
|
+
return rmdir(osPath.join(p, d.name));
|
|
439
|
+
});
|
|
440
|
+
})
|
|
441
|
+
.then(() => {
|
|
442
|
+
return doRmdir(p);
|
|
347
443
|
});
|
|
348
|
-
}).then(() => {
|
|
349
|
-
return doRmdir(p);
|
|
350
|
-
});
|
|
351
444
|
};
|
|
352
445
|
return rmdir(path);
|
|
353
446
|
};
|
|
@@ -359,16 +452,16 @@ SftpClient.prototype.rmdir = function(path, recursive = false) {
|
|
|
359
452
|
*
|
|
360
453
|
* @param {string} path - path to the file to delete
|
|
361
454
|
* @return {Promise} with string 'Successfully deleeted file' once resolved
|
|
362
|
-
*
|
|
455
|
+
*
|
|
363
456
|
*/
|
|
364
457
|
SftpClient.prototype.delete = function(path) {
|
|
365
458
|
return new Promise((resolve, reject) => {
|
|
366
459
|
let sftp = this.sftp;
|
|
367
460
|
|
|
368
461
|
if (!sftp) {
|
|
369
|
-
return reject(new Error('sftp connect error'));
|
|
462
|
+
return reject(new Error('sftp connect error'));
|
|
370
463
|
}
|
|
371
|
-
sftp.unlink(path,
|
|
464
|
+
sftp.unlink(path, err => {
|
|
372
465
|
if (err) {
|
|
373
466
|
reject(new Error(`Failed to delete file ${path}: ${err.message}`));
|
|
374
467
|
}
|
|
@@ -387,18 +480,22 @@ SftpClient.prototype.delete = function(path) {
|
|
|
387
480
|
* @param {string} remotePath - path to the new name.
|
|
388
481
|
*
|
|
389
482
|
* @return {Promise}
|
|
390
|
-
*
|
|
483
|
+
*
|
|
391
484
|
*/
|
|
392
485
|
SftpClient.prototype.rename = function(srcPath, remotePath) {
|
|
393
486
|
return new Promise((resolve, reject) => {
|
|
394
487
|
let sftp = this.sftp;
|
|
395
488
|
|
|
396
489
|
if (!sftp) {
|
|
397
|
-
return reject(new Error('sftp connect error'));
|
|
490
|
+
return reject(new Error('sftp connect error'));
|
|
398
491
|
}
|
|
399
|
-
sftp.rename(srcPath, remotePath,
|
|
492
|
+
sftp.rename(srcPath, remotePath, err => {
|
|
400
493
|
if (err) {
|
|
401
|
-
reject(
|
|
494
|
+
reject(
|
|
495
|
+
new Error(
|
|
496
|
+
`Failed to rename file ${srcPath} to ${remotePath}: ${err.message}`
|
|
497
|
+
)
|
|
498
|
+
);
|
|
402
499
|
}
|
|
403
500
|
resolve(`Successfully renamed ${srcPath} to ${remotePath}`);
|
|
404
501
|
});
|
|
@@ -421,11 +518,13 @@ SftpClient.prototype.chmod = function(remotePath, mode) {
|
|
|
421
518
|
let sftp = this.sftp;
|
|
422
519
|
|
|
423
520
|
if (!sftp) {
|
|
424
|
-
return reject(new Error('sftp connect error'));
|
|
521
|
+
return reject(new Error('sftp connect error'));
|
|
425
522
|
}
|
|
426
|
-
sftp.chmod(remotePath, mode,
|
|
523
|
+
sftp.chmod(remotePath, mode, err => {
|
|
427
524
|
if (err) {
|
|
428
|
-
reject(
|
|
525
|
+
reject(
|
|
526
|
+
new Error(`Failed to change mode for ${remotePath}: ${err.message}`)
|
|
527
|
+
);
|
|
429
528
|
}
|
|
430
529
|
resolve('Successfully change file mode');
|
|
431
530
|
});
|
|
@@ -442,7 +541,7 @@ SftpClient.prototype.chmod = function(remotePath, mode) {
|
|
|
442
541
|
* @param {string} connectMethod - ???
|
|
443
542
|
*
|
|
444
543
|
* @return {Promise} which will resolve to an sftp client object
|
|
445
|
-
*
|
|
544
|
+
*
|
|
446
545
|
*/
|
|
447
546
|
SftpClient.prototype.connect = function(config, connectMethod) {
|
|
448
547
|
connectMethod = connectMethod || 'on';
|
|
@@ -469,33 +568,18 @@ SftpClient.prototype.connect = function(config, connectMethod) {
|
|
|
469
568
|
* @async
|
|
470
569
|
*
|
|
471
570
|
* Close the SFTP connection
|
|
472
|
-
*
|
|
571
|
+
*
|
|
473
572
|
*/
|
|
474
573
|
SftpClient.prototype.end = function() {
|
|
475
|
-
return new Promise(
|
|
574
|
+
return new Promise(resolve => {
|
|
476
575
|
this.client.end();
|
|
477
576
|
resolve();
|
|
478
577
|
});
|
|
479
578
|
};
|
|
480
579
|
|
|
481
|
-
SftpClient.prototype.getOptions = function(useCompression, encoding, otherOptions) {
|
|
482
|
-
if(encoding === undefined){
|
|
483
|
-
encoding = 'utf8';
|
|
484
|
-
}
|
|
485
|
-
let options = Object.assign({}, otherOptions || {}, {encoding: encoding}, useCompression);
|
|
486
|
-
return options;
|
|
487
|
-
};
|
|
488
|
-
|
|
489
580
|
// add Event type support
|
|
490
581
|
SftpClient.prototype.on = function(eventType, callback) {
|
|
491
582
|
this.client.on(eventType, callback);
|
|
492
583
|
};
|
|
493
584
|
|
|
494
|
-
|
|
495
585
|
module.exports = SftpClient;
|
|
496
|
-
|
|
497
|
-
// sftp = new SftpClient()
|
|
498
|
-
// sftp.client.on('event')
|
|
499
|
-
//
|
|
500
|
-
// sftp.on('end', ()=>{}) => this.client.on('event', callback)
|
|
501
|
-
// sftp.on('error', () => {})
|