ssh2-sftp-client 2.4.0 → 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 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 Chunk 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 'utf8'.
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, [useCompression], [encoding], [addtionalOptions]);
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, [useCompression], [encoding], [addtionalOptions]);
75
- sftp.put(Buffer, remoteFilePath, [useCompression], [encoding], [addtionalOptions]);
76
- sftp.put(Stream, remoteFilePath, [useCompression], [encoding], [addtionalOptions]);
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
@@ -157,7 +207,21 @@ sftp.on('error', callbackFn)
157
207
  ### FAQ
158
208
 
159
209
  ### Log
210
+ ### V2.4.3
211
+ - merge #108, #110
212
+ - fix connect promise if connection ends
213
+
214
+ ### V2.4.2
215
+ - merge #105
216
+ - fix windows path
217
+
218
+ ### V2.4.1
219
+ - merge pr #99, #100
220
+ - bug fix
221
+
160
222
  #### V2.4.0
223
+ Requires node.js v7.5.0 or above.
224
+
161
225
  - merge pr #97, thanks for @theophilusx
162
226
  - Remove emmitter.maxListener warnings
163
227
  - Upgraded ssh2 dependency from 0.5.5 to 0.6.1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ssh2-sftp-client",
3
- "version": "2.4.0",
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 test/index.js"
15
+ "test": "mocha"
16
16
  },
17
17
  "author": "见见",
18
18
  "email": "jyu213@gmail.com",
19
19
  "license": "MIT",
20
20
  "dependencies": {
21
- "ssh2": "^0.6.1"
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
@@ -5,9 +5,12 @@
5
5
  'use strict';
6
6
 
7
7
  const Client = require('ssh2').Client;
8
- const osPath = require('path');
8
+ const osPath = require('path').posix;
9
+ const utils = require('./utils');
10
+ const fs = require('fs');
11
+ const concat = require('concat-stream');
9
12
 
10
- let SftpClient = function(){
13
+ let SftpClient = function() {
11
14
  this.client = new Client();
12
15
  };
13
16
 
@@ -42,7 +45,7 @@ SftpClient.prototype.list = function(path) {
42
45
  accessTime: item.attrs.atime * 1000,
43
46
  rights: {
44
47
  user: item.longname.substr(1, 3).replace(reg, ''),
45
- group: item.longname.substr(4,3).replace(reg, ''),
48
+ group: item.longname.substr(4, 3).replace(reg, ''),
46
49
  other: item.longname.substr(7, 3).replace(reg, '')
47
50
  },
48
51
  owner: item.attrs.uid,
@@ -81,10 +84,14 @@ SftpClient.prototype.exists = function(path) {
81
84
  if (err.code === 2) {
82
85
  resolve(false);
83
86
  } else {
84
- reject(new Error(`Error listing ${dir}: code: ${err.code} ${err.message}`));
87
+ reject(
88
+ new Error(`Error listing ${dir}: code: ${err.code} ${err.message}`)
89
+ );
85
90
  }
86
91
  } else {
87
- let [type] = list.filter(item => item.filename === base).map(item => item.longname.substr(0, 1));
92
+ let [type] = list
93
+ .filter(item => item.filename === base)
94
+ .map(item => item.longname.substr(0, 1));
88
95
  if (type) {
89
96
  resolve(type);
90
97
  } else {
@@ -107,18 +114,18 @@ SftpClient.prototype.stat = function(remotePath) {
107
114
  let sftp = this.sftp;
108
115
 
109
116
  if (!sftp) {
110
- return reject(Error('sftp connect error'));
117
+ return reject(Error('sftp connect error'));
111
118
  }
112
- sftp.stat(remotePath, function (err, stats) {
113
- if (err){
119
+ sftp.stat(remotePath, function(err, stats) {
120
+ if (err) {
114
121
  reject(new Error(`Failed to stat ${remotePath}: ${err.message}`));
115
122
  } else {
116
- // format similarly to sftp.list
123
+ // format similarly to sftp.list
117
124
  resolve({
118
125
  mode: stats.mode,
119
126
  permissions: stats.permissions,
120
127
  owner: stats.uid,
121
- group: stats.guid,
128
+ group: stats.gid,
122
129
  size: stats.size,
123
130
  accessTime: stats.atime * 1000,
124
131
  modifyTime: stats.mtime * 1000
@@ -132,34 +139,53 @@ SftpClient.prototype.stat = function(remotePath) {
132
139
  /**
133
140
  * get file
134
141
  *
135
- * @param {String} path, path
136
- * @param {Object} useCompression, config options
137
- * @param {String} encoding. Encoding for the ReadStream, can be any value
138
- * supported by node streams. Use 'null' for binary
139
- * (https://nodejs.org/api/stream.html#stream_readable_setencoding_encoding)
140
- * @return {Promise} stream, readable stream
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}
141
152
  */
142
- SftpClient.prototype.get = function(path, useCompression, encoding, otherOptions) {
143
- let options = this.getOptions(useCompression, encoding, otherOptions);
144
-
153
+ SftpClient.prototype.get = function(path, dst, options) {
145
154
  return new Promise((resolve, reject) => {
146
155
  let sftp = this.sftp;
147
156
 
148
157
  if (sftp) {
149
158
  try {
150
- this.client.on('error', reject);
151
-
152
- let stream = sftp.createReadStream(path, options);
153
-
154
- stream.on('error', (err) => {
155
- this.client.removeListener('error', reject);
156
- return reject(new Error(`Failed get for ${path}: ${err.message}`));
157
- });
158
- stream.on('readable', () => {
159
- this.client.removeListener('error', reject);
160
- 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}`));
161
163
  });
162
- } catch(err) {
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) {
163
189
  this.client.removeListener('error', reject);
164
190
  return reject(new Error(`Failed get on ${path}: ${err.message}`));
165
191
  }
@@ -179,15 +205,14 @@ SftpClient.prototype.get = function(path, useCompression, encoding, otherOptions
179
205
  * @return {Promise} the result of downloading the file
180
206
  */
181
207
  SftpClient.prototype.fastGet = function(remotePath, localPath, options) {
182
- options = options || {concurrency: 64, chunkSize: 32768};
183
208
  return new Promise((resolve, reject) => {
184
209
  let sftp = this.sftp;
185
210
 
186
211
  if (!sftp) {
187
- return reject(Error('sftp connect error'));
212
+ return reject(Error('sftp connect error'));
188
213
  }
189
- sftp.fastGet(remotePath, localPath, options, function (err) {
190
- if (err){
214
+ sftp.fastGet(remotePath, localPath, options, function(err) {
215
+ if (err) {
191
216
  reject(new Error(`Failed to get ${remotePath}: ${err.message}`));
192
217
  }
193
218
  resolve(`${remotePath} was successfully download to ${localPath}!`);
@@ -206,16 +231,19 @@ SftpClient.prototype.fastGet = function(remotePath, localPath, options) {
206
231
  * @return {Promise} the result of downloading the file
207
232
  */
208
233
  SftpClient.prototype.fastPut = function(localPath, remotePath, options) {
209
- options = options || {};
210
234
  return new Promise((resolve, reject) => {
211
235
  let sftp = this.sftp;
212
236
 
213
237
  if (!sftp) {
214
- return reject(new Error('sftp connect error'));
238
+ return reject(new Error('sftp connect error'));
215
239
  }
216
- sftp.fastPut(localPath, remotePath, options, function (err) {
240
+ sftp.fastPut(localPath, remotePath, options, function(err) {
217
241
  if (err) {
218
- reject(new Error(`Failed to upload ${localPath} to ${remotePath}: ${err.message}`));
242
+ reject(
243
+ new Error(
244
+ `Failed to upload ${localPath} to ${remotePath}: ${err.message}`
245
+ )
246
+ );
219
247
  }
220
248
  resolve(`${localPath} was successfully uploaded to ${remotePath}!`);
221
249
  });
@@ -223,7 +251,6 @@ SftpClient.prototype.fastPut = function(localPath, remotePath, options) {
223
251
  });
224
252
  };
225
253
 
226
-
227
254
  /**
228
255
  * Create file
229
256
  *
@@ -233,17 +260,19 @@ SftpClient.prototype.fastPut = function(localPath, remotePath, options) {
233
260
  * @param {String} encoding. Encoding for the WriteStream, can be any value supported by node streams.
234
261
  * @return {[type]} [description]
235
262
  */
236
- SftpClient.prototype.put = function(input, remotePath, useCompression, encoding, otherOptions) {
237
- let options = this.getOptions(useCompression, encoding, otherOptions);
238
-
263
+ SftpClient.prototype.put = function(input, remotePath, options) {
239
264
  return new Promise((resolve, reject) => {
240
265
  let sftp = this.sftp;
241
266
 
242
267
  if (sftp) {
243
268
  if (typeof input === 'string') {
244
- sftp.fastPut(input, remotePath, options, (err) => {
269
+ sftp.fastPut(input, remotePath, options, err => {
245
270
  if (err) {
246
- return reject(new Error(`Failed to upload ${input} to ${remotePath}: ${err.message}`));
271
+ return reject(
272
+ new Error(
273
+ `Failed to upload ${input} to ${remotePath}: ${err.message}`
274
+ )
275
+ );
247
276
  }
248
277
  return resolve(`Uploaded ${input} to ${remotePath}`);
249
278
  });
@@ -252,13 +281,58 @@ SftpClient.prototype.put = function(input, remotePath, useCompression, encoding,
252
281
  let stream = sftp.createWriteStream(remotePath, options);
253
282
 
254
283
  stream.on('error', err => {
255
- return reject(new Error(`Failed to upload data stream to ${remotePath}: ${err.message}`));
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
+ );
256
330
  });
257
-
258
- stream.on('close', () => {
331
+
332
+ stream.on('finish', () => {
259
333
  return resolve(`Uploaded data stream to ${remotePath}`);
260
334
  });
261
-
335
+
262
336
  if (input instanceof Buffer) {
263
337
  stream.end(input);
264
338
  return false;
@@ -270,13 +344,20 @@ SftpClient.prototype.put = function(input, remotePath, useCompression, encoding,
270
344
  });
271
345
  };
272
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
+ */
273
356
  SftpClient.prototype.mkdir = function(path, recursive = false) {
274
357
  let sftp = this.sftp;
275
358
 
276
359
  let doMkdir = p => {
277
360
  return new Promise((resolve, reject) => {
278
-
279
-
280
361
  if (!sftp) {
281
362
  return reject(new Error('sftp connect error'));
282
363
  }
@@ -293,27 +374,35 @@ SftpClient.prototype.mkdir = function(path, recursive = false) {
293
374
  if (!recursive) {
294
375
  return doMkdir(path);
295
376
  }
296
- let mkdir = async p => {
297
- try {
298
- let {dir} = osPath.parse(p);
299
- let type = await this.exists(dir);
300
- if (!type) {
301
- await mkdir(dir);
302
- }
303
- return doMkdir(p);
304
- } catch (err) {
305
- throw err;
306
- }
377
+ let mkdir = p => {
378
+ let {dir} = osPath.parse(p);
379
+ return this.exists(dir)
380
+ .then(type => {
381
+ if (!type) {
382
+ return mkdir(dir);
383
+ }
384
+ })
385
+ .then(() => {
386
+ return doMkdir(p);
387
+ });
307
388
  };
308
389
  return mkdir(path);
309
390
  };
310
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
+ */
311
401
  SftpClient.prototype.rmdir = function(path, recursive = false) {
312
402
  let sftp = this.sftp;
313
403
 
314
404
  let doRmdir = p => {
315
405
  return new Promise((resolve, reject) => {
316
-
317
406
  if (!sftp) {
318
407
  return reject(new Error('sftp connect error'));
319
408
  }
@@ -331,21 +420,27 @@ SftpClient.prototype.rmdir = function(path, recursive = false) {
331
420
  return doRmdir(path);
332
421
  }
333
422
 
334
- let rmdir = async p => {
335
- try {
336
- let list = await this.list(p);
337
- let files = list.filter(item => item.type === '-');
338
- let dirs = list.filter(item => item.type === 'd');
339
- for (let f of files) {
340
- await this.delete(osPath.join(p, f.name));
341
- }
342
- for (let d of dirs) {
343
- await rmdir(osPath.join(p, d.name));
344
- }
345
- return doRmdir(p);
346
- } catch (err) {
347
- throw err;
348
- }
423
+ let rmdir = p => {
424
+ let list;
425
+ let files;
426
+ let dirs;
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);
443
+ });
349
444
  };
350
445
  return rmdir(path);
351
446
  };
@@ -357,16 +452,16 @@ SftpClient.prototype.rmdir = function(path, recursive = false) {
357
452
  *
358
453
  * @param {string} path - path to the file to delete
359
454
  * @return {Promise} with string 'Successfully deleeted file' once resolved
360
- *
455
+ *
361
456
  */
362
457
  SftpClient.prototype.delete = function(path) {
363
458
  return new Promise((resolve, reject) => {
364
459
  let sftp = this.sftp;
365
460
 
366
461
  if (!sftp) {
367
- return reject(new Error('sftp connect error'));
462
+ return reject(new Error('sftp connect error'));
368
463
  }
369
- sftp.unlink(path, (err) => {
464
+ sftp.unlink(path, err => {
370
465
  if (err) {
371
466
  reject(new Error(`Failed to delete file ${path}: ${err.message}`));
372
467
  }
@@ -385,18 +480,22 @@ SftpClient.prototype.delete = function(path) {
385
480
  * @param {string} remotePath - path to the new name.
386
481
  *
387
482
  * @return {Promise}
388
- *
483
+ *
389
484
  */
390
485
  SftpClient.prototype.rename = function(srcPath, remotePath) {
391
486
  return new Promise((resolve, reject) => {
392
487
  let sftp = this.sftp;
393
488
 
394
489
  if (!sftp) {
395
- return reject(new Error('sftp connect error'));
490
+ return reject(new Error('sftp connect error'));
396
491
  }
397
- sftp.rename(srcPath, remotePath, (err) => {
492
+ sftp.rename(srcPath, remotePath, err => {
398
493
  if (err) {
399
- reject(new Error(`Failed to rename file ${srcPath} to ${remotePath}: ${err.message}`));
494
+ reject(
495
+ new Error(
496
+ `Failed to rename file ${srcPath} to ${remotePath}: ${err.message}`
497
+ )
498
+ );
400
499
  }
401
500
  resolve(`Successfully renamed ${srcPath} to ${remotePath}`);
402
501
  });
@@ -419,11 +518,13 @@ SftpClient.prototype.chmod = function(remotePath, mode) {
419
518
  let sftp = this.sftp;
420
519
 
421
520
  if (!sftp) {
422
- return reject(new Error('sftp connect error'));
521
+ return reject(new Error('sftp connect error'));
423
522
  }
424
- sftp.chmod(remotePath, mode, (err) => {
523
+ sftp.chmod(remotePath, mode, err => {
425
524
  if (err) {
426
- reject(new Error(`Failed to change mode for ${remotePath}: ${err.message}`));
525
+ reject(
526
+ new Error(`Failed to change mode for ${remotePath}: ${err.message}`)
527
+ );
427
528
  }
428
529
  resolve('Successfully change file mode');
429
530
  });
@@ -440,7 +541,7 @@ SftpClient.prototype.chmod = function(remotePath, mode) {
440
541
  * @param {string} connectMethod - ???
441
542
  *
442
543
  * @return {Promise} which will resolve to an sftp client object
443
- *
544
+ *
444
545
  */
445
546
  SftpClient.prototype.connect = function(config, connectMethod) {
446
547
  connectMethod = connectMethod || 'on';
@@ -449,6 +550,7 @@ SftpClient.prototype.connect = function(config, connectMethod) {
449
550
  this.client[connectMethod]('ready', () => {
450
551
  this.client.sftp((err, sftp) => {
451
552
  this.client.removeListener('error', reject);
553
+ this.client.removeListener('end', reject);
452
554
  if (err) {
453
555
  reject(new Error(`Failed to connect to server: ${err.message}`));
454
556
  }
@@ -456,6 +558,7 @@ SftpClient.prototype.connect = function(config, connectMethod) {
456
558
  resolve(sftp);
457
559
  });
458
560
  })
561
+ .on('end', reject)
459
562
  .on('error', reject)
460
563
  .connect(config);
461
564
  });
@@ -465,33 +568,18 @@ SftpClient.prototype.connect = function(config, connectMethod) {
465
568
  * @async
466
569
  *
467
570
  * Close the SFTP connection
468
- *
571
+ *
469
572
  */
470
573
  SftpClient.prototype.end = function() {
471
- return new Promise((resolve) => {
574
+ return new Promise(resolve => {
472
575
  this.client.end();
473
576
  resolve();
474
577
  });
475
578
  };
476
579
 
477
- SftpClient.prototype.getOptions = function(useCompression, encoding, otherOptions) {
478
- if(encoding === undefined){
479
- encoding = 'utf8';
480
- }
481
- let options = Object.assign({}, otherOptions || {}, {encoding: encoding}, useCompression);
482
- return options;
483
- };
484
-
485
580
  // add Event type support
486
581
  SftpClient.prototype.on = function(eventType, callback) {
487
582
  this.client.on(eventType, callback);
488
583
  };
489
584
 
490
-
491
585
  module.exports = SftpClient;
492
-
493
- // sftp = new SftpClient()
494
- // sftp.client.on('event')
495
- //
496
- // sftp.on('end', ()=>{}) => this.client.on('event', callback)
497
- // sftp.on('error', () => {})
package/src/utils.js ADDED
@@ -0,0 +1,10 @@
1
+ var exports = module.exports;
2
+
3
+ exports.forEachAsync = function(array, callback) {
4
+ return array.reduce((promise, item) => {
5
+ return promise.then((result) => {
6
+ return callback(item);
7
+ });
8
+ }, Promise.resolve());
9
+ }
10
+