ssh2-sftp-client 6.0.1 → 7.0.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/CHANGELOG.org CHANGED
@@ -1,6 +1,13 @@
1
1
  * Change Logging
2
2
 
3
- ** Version 6.0.1
3
+ ** V7.0.0
4
+ - New version based on new SSH2 version 1.1.0.
5
+ - Expand option handling for get() and put() methods *Breaking Change*
6
+ - Re-factored the retry code in the connect() method
7
+ - Improve error reporting for adding/removing listeners
8
+ - Extend localExists() method to also verify read or write access
9
+
10
+ ** V6.0.1
4
11
  - Fix issue with connect retry not releasing 'ready' listeners
5
12
  - Add finally clauses to all promises to ensure temporary listeners are deleted
6
13
  - Add nyc module to report on code test coverage
package/README.md CHANGED
@@ -1,9 +1,7 @@
1
1
  - [Overview](#sec-1)
2
2
  - [Installation](#sec-2)
3
3
  - [Basic Usage](#sec-3)
4
- - [Version 6.x Changes](#sec-4)
5
- - [Version 6.0.1](#sec-4-1)
6
- - [Version 6.0.0 Changes](#sec-4-2)
4
+ - [Version 7.x Changes](#sec-4)
7
5
  - [Documentation](#sec-5)
8
6
  - [Specifying Paths](#sec-5-1)
9
7
  - [Methods](#sec-5-2)
@@ -59,24 +57,14 @@
59
57
 
60
58
  an SFTP client for node.js, a wrapper around [SSH2](https://github.com/mscdex/ssh2) which provides a high level convenience abstraction as well as a Promise based API.
61
59
 
62
- Documentation on the methods and available options in the underlying modules can be found on the [SSH2](https://github.com/mscdex/ssh2) and [SSH2-STREAMS](https://github.com/mscdex/ssh2-streams/blob/master/SFTPStream.md) project pages.
60
+ Documentation on the methods and available options in the underlying modules can be found on the [SSH2](https://github.com/mscdex/ssh2) project pages.
63
61
 
64
- Current stable release is **v5.3.2**.
62
+ Current stable release is **v7.0.0**.
65
63
 
66
- Code has been tested against Node versions 12.18.2 and 13.14.0
64
+ Code has been tested against Node versions 12.22.1, 14.17.0 and 16.2.0
67
65
 
68
66
  Node versions < 10.x are not supported.
69
67
 
70
- <span class="underline">WARNING</span> There is currently a regression error with versions of node later than version 14.0. It appears that when using streams with chunk sizes which exceed the high water mark for the stream, a drain event is no longer emitted. As a result, streams with sufficient data will hang indefinitely. This appears to affect fastput, fastget, put and possibly get operations. Until this issue is resolved and a new version of ssh2/ssh2-streams is released, using node v14 is not recommended.
71
-
72
- A bug report hass been logged against the ssh2-streams library as [issue 156](https://github.com/mscdex/ssh2-streams/issues/156).
73
-
74
- <span class="underline">UPDATE</span>: The author of the upstream ssh2 and ssh2-streams module has decided on a re-write of the ssh2 module to address the above issues as well as some other design limitations and to allow the module to better fit in with newer versions of node. As part of that process, the functionality of ssh2-streams is being incorporated into the main ssh2 module and the ssh2-streams module is being deprecated. This will require a significant update to this module and may result in some API changes, depending on what changes in the re-write of ssh2.
75
-
76
- To support these changes, a new branch called *version-6* has been created. This branch will use the newest version of ssh2 and for now is very much experimental and subject to change.
77
-
78
- <span class="underline">UPDATE</span>: Apparently the change in core node which cause the issue with ssh2 has been rolled back in node version 15.3.0. Testing seems to indicate the above issue does not exist in that version of node.
79
-
80
68
  # Installation<a id="sec-2"></a>
81
69
 
82
70
  ```shell
@@ -103,23 +91,13 @@ sftp.connect({
103
91
  });
104
92
  ```
105
93
 
106
- # Version 6.x Changes<a id="sec-4"></a>
94
+ # Version 7.x Changes<a id="sec-4"></a>
107
95
 
108
- ## Version 6.0.1<a id="sec-4-1"></a>
96
+ - This version is based on version 1.1.0 of `ssh2`. This version of `ssh2` is a complete re-write of the `ssh2` library. This re-write addresses issues encountered when using node v14 as well as some design weaknesses in the previous 0.8.x version.
109
97
 
110
- - Fix issue with connect retry not releasing 'ready' listener.
111
- - Add finally clauses to all promises to ensure release of temporary listeners.
112
- - Add nyc module to improve test coverage
113
- - Added additional utils tests to improve test coverage
114
- - Removed some unnecessary util functions to reduce code size
98
+ - **Breaking Change** Expanded option handling for `get()` and `put()` methods. A number of use cases were identified where setting specific options on the read and write streams and the pipe operation are necessary. For example, disabling `autoClose` on streams or the `end` event in pipes. The `options` argument for `get()` and `put()` calls now supports properties for `readStreamOptions`, `writeStreamOptions` and `pipeOptions`. Note that options are only applied to streams created by the `get()` and `put()` methods. Streams passed into these methods are under the control of the client code and therefore cannot have options supplied in arguments to those streams (you would apply such options when you create the streams). Options are typically only necessary in special use cases. Most of the time, no options are required. However, if you are currently using options to either `put()` or `get()`, you will need to update your code to map these options to the new structure.
115
99
 
116
- ## Version 6.0.0 Changes<a id="sec-4-2"></a>
117
-
118
- - Added new optional argument *notFoundOK* to `delete()` method. If true, no error is thrown when trying to delete a file which does not exist. Default is false.
119
- - Added new filter argument to `uploadDir()` and `downloadDir()` methods. The filter argument is a regular expression used to match the files and directories to be included in the upload or download. Defaults to match all files and directories.
120
- - New event handling approach. Have standardised the adding and removing of event handlers as well as added event handlers for *close* and *end* events. Some sftp servers appear to abruptly terminate connections without issuing an *error* event. This could result in failing to resolve the promise associated with the action being performed. Adding *close* and *end* listeners to reject a promise should prevent the scripts from hanging when the remote server does not return either a status or an error.
121
- - Replace the `retry` library module with the `promise-retry` library module. This module also uses the `retry` library, but at a higher level abstracted for use with Promises. As a result, the number of failed retries is no longer returned as part of the error message when all attempted connection retries fail.
122
- - Reduced argument verification code. Version 5.x added a lot of additional argument verification code in an attempt to provide more meaningful error messages. While this goal was achieved, it did have a significant performance impact, especially with respect to small file transfers. This additional argument verification has now been removed in favour of faster code. The downside is that some error messages have changed and in some cases, will not be as meaningful or will be more generic in nature. This seems as a reasonable compromise. It may result in increased difficulty tracking down why a script is failing, but once a script is working, it should be more efficient. If your code relies on the text in error messages, you will need to verify whether the text is still the same in any testing and adjust where necessary.
100
+ - Improved event handling. A listener for a global error event is now defined to catch errors which occur in-between method calls i.e. connection lost in-between calls to the library methods. A new mechanism has also been added for removal of listeners when no longer required.
123
101
 
124
102
  # Documentation<a id="sec-5"></a>
125
103
 
@@ -129,7 +107,7 @@ All the methods will return a Promise, except for `on()` and `removeListener()`,
129
107
 
130
108
  ## Specifying Paths<a id="sec-5-1"></a>
131
109
 
132
- The convention with both FTP and SFTP is that paths are specified using a 'nix' style i.e. use '*' as the path separator. This means that even if your SFTP server is running on a win32 platform, you should use '*' instead of '\\' as the path separator. For example, for a win32 path of 'C:\Users\fred' you would actually use '/C:/Users/fred'. If your win32 server does not support the 'nix' path convention, you can try setting the `remotePathSep` property of the `SftpClient` object to the path separator of your remote server. This **might** work, but has not been tested. Please let me know if you need to do this and provide details of the SFTP server so that I can try to create an appropriate environment and adjust things as necessary. At this point, I'm not aware of any win32 based SFTP servers which do not support the 'nix' path convention.
110
+ The convention with both FTP and SFTP is that paths are specified using a 'nix' style i.e. use `/` as the path separator. This means that even if your SFTP server is running on a win32 platform, you should use `/` instead of `\` as the path separator. For example, for a win32 path of `C:\Users\fred` you would actually use `/C:/Users/fred`. If your win32 server does not support the 'nix' path convention, you can try setting the `remotePathSep` property of the `SftpClient` object to the path separator of your remote server. This **might** work, but has not been tested. Please let me know if you need to do this and provide details of the SFTP server so that I can try to create an appropriate environment and adjust things as necessary. At this point, I'm not aware of any win32 based SFTP servers which do not support the 'nix' path convention.
133
111
 
134
112
  All remote paths must either be absolute e.g. `/absolute/path/to/file` or they can be relative with a prefix of either `./` (relative to current remote directory) or `../` (relative to parent of current remote directory) e.g. `./relative/path/to/file` or `../relative/to/parent/file`. It is also possible to do things like `../../../file` to specify the parent of the parent of the parent of the current remote directory. The shell tilde (`~`) and common environment variables like `$HOME` are NOT supported.
135
113
 
@@ -171,17 +149,17 @@ Constructor to create a new `ssh2-sftp-client` object. An optional `name` string
171
149
 
172
150
  ```javascript
173
151
  'use strict';
174
-
152
+
175
153
  const Client = require('ssh2-sftp-client');
176
-
154
+
177
155
  const config = {
178
156
  host: 'example.com',
179
157
  username: 'donald',
180
158
  password: 'my-secret'
181
159
  };
182
-
160
+
183
161
  const sftp = new Client('example-client');
184
-
162
+
185
163
  sftp.connect(config)
186
164
  .then(() => {
187
165
  return sftp.cwd();
@@ -202,12 +180,12 @@ Connect to an sftp server. Full documentation for connection options is availabl
202
180
  1. Connection Options
203
181
 
204
182
  This module is based on the excellent [SSH2](https://github.com/mscdex/ssh2#client) module. That module is a general SSH2 client and server library and provides much more functionality than just SFTP connectivity. Many of the connect options provided by that module are less relevant for SFTP connections. It is recommended you keep the config options to the minimum needed and stick to the options listed in the `commonOpts` below.
205
-
183
+
206
184
  The `retries`, `retry_factor` and `retry_minTimeout` options are not part of the SSH2 module. These are part of the configuration for the [retry](https://www.npmjs.com/package/retry) package and what is used to enable retrying of sftp connection attempts. See the documentation for that package for an explanation of these values.
207
-
185
+
208
186
  ```javascript
209
187
  // common options
210
-
188
+
211
189
  let commonOpts {
212
190
  host: 'localhost', // string Hostname or IP of server.
213
191
  port: 22, // Port number of the server.
@@ -226,9 +204,9 @@ Connect to an sftp server. Full documentation for connection options is availabl
226
204
  retry_factor: 2 // integer. Time factor used to calculate time between retries
227
205
  retry_minTimeout: 2000 // integer. Minimum timeout between attempts
228
206
  };
229
-
207
+
230
208
  // rarely used options
231
-
209
+
232
210
  let advancedOpts {
233
211
  localAddress,
234
212
  localPort,
@@ -269,16 +247,16 @@ Retrieves a directory listing. This method returns a Promise, which once realise
269
247
 
270
248
  ```javascript
271
249
  const Client = require('ssh2-sftp-client');
272
-
250
+
273
251
  const config = {
274
252
  host: 'example.com',
275
253
  port: 22,
276
254
  username: 'red-don',
277
255
  password: 'my-secret'
278
256
  };
279
-
257
+
280
258
  let sftp = new Client;
281
-
259
+
282
260
  sftp.connect(config)
283
261
  .then(() => {
284
262
  return sftp.list('/path/to/remote/dir');
@@ -297,7 +275,7 @@ Retrieves a directory listing. This method returns a Promise, which once realise
297
275
  2. Return Objects
298
276
 
299
277
  The objects in the array returned by `list()` have the following properties;
300
-
278
+
301
279
  ```javascript
302
280
  {
303
281
  type: // file type(-, d, l)
@@ -318,11 +296,11 @@ Retrieves a directory listing. This method returns a Promise, which once realise
318
296
  3. Pattern Filter
319
297
 
320
298
  The filter options can be a regular expression (most powerful option) or a simple *glob*-like string where \* will match any number of characters, e.g.
321
-
299
+
322
300
  foo* => foo, foobar, foobaz
323
301
  *bar => bar, foobar, tabbar
324
302
  *oo* => foo, foobar, look, book
325
-
303
+
326
304
  The *glob*-style matching is very simple. In most cases, you are best off using a real regular expression which will allow you to do more powerful matching and anchor matches to the beginning/end of the string etc.
327
305
 
328
306
  ### exists(path) ==> boolean<a id="sec-5-2-4"></a>
@@ -333,16 +311,16 @@ Tests to see if remote file or directory exists. Returns type of remote object i
333
311
 
334
312
  ```javascript
335
313
  const Client = require('ssh2-sftp-client');
336
-
314
+
337
315
  const config = {
338
316
  host: 'example.com',
339
317
  port: 22,
340
318
  username: 'red-don',
341
319
  password: 'my-secret'
342
320
  };
343
-
321
+
344
322
  let sftp = new Client;
345
-
323
+
346
324
  sftp.connect(config)
347
325
  .then(() => {
348
326
  return sftp.exists('/path/to/remote/dir');
@@ -367,7 +345,7 @@ Returns the attributes associated with the object pointed to by `path`.
367
345
  1. Attributes
368
346
 
369
347
  The `stat()` method returns an object with the following properties;
370
-
348
+
371
349
  ```javascript
372
350
  let stats = {
373
351
  mode: 33279, // integer representing type and permissions
@@ -390,7 +368,7 @@ Returns the attributes associated with the object pointed to by `path`.
390
368
 
391
369
  ```javascript
392
370
  let client = new Client();
393
-
371
+
394
372
  client.connect(config)
395
373
  .then(() => {
396
374
  return client.stat('/path/to/remote/file');
@@ -418,28 +396,33 @@ In general, if your going to pass in a string as the destination, you are better
418
396
 
419
397
  1. Options
420
398
 
421
- The options object can be used to pass options to the underlying readStream used to read the data from the remote server.
422
-
399
+ The `options` argument can be used to pass options to the underlying streams and pipe call used by this method. The argument is an object with three possible properties, `readStreamOptions`, `writeStreamOptions` and `pipeOptions`. The values for each of these properties should be an object containing the required options. For example, possible read stream and pipe options could be defined as
400
+
423
401
  ```javascript
424
- {
425
- flags: 'r',
426
- encoding: null,
427
- handle: null,
428
- mode: 0o666,
429
- autoClose: true
430
- }
402
+ let options = {
403
+ readStreamOptions: {
404
+ flags: 'r',
405
+ encoding: null,
406
+ handle: null,
407
+ mode: 0o666,
408
+ autoClose: true
409
+ },
410
+ pipeOptions: {
411
+ end: false
412
+ }};
413
+
431
414
  ```
432
-
415
+
433
416
  Most of the time, you won't want to use any options. Sometimes, it may be useful to set the encoding. For example, to 'utf-8'. However, it is important not to do this for binary files to avoid data corruption.
434
417
 
435
418
  2. Example Use
436
419
 
437
420
  ```javascript
438
421
  let client = new Client();
439
-
422
+
440
423
  let remotePath = '/remote/server/path/file.txt';
441
424
  let dst = fs.createWriteStream('/local/file/path/copy.txt');
442
-
425
+
443
426
  client.connect(config)
444
427
  .then(() => {
445
428
  return client.get(remotePath, dst);
@@ -451,7 +434,7 @@ In general, if your going to pass in a string as the destination, you are better
451
434
  console.error(err.message);
452
435
  });
453
436
  ```
454
-
437
+
455
438
  - **Tip:** See examples file in the Git repository for more examples. You can pass any writeable stream in as the destination. For example, if you pass in `zlib.createGunzip()` writeable stream, you can both download and decompress a gzip file 'on the fly'.
456
439
 
457
440
  ### fastGet(remotePath, localPath, options) ===> string<a id="sec-5-2-7"></a>
@@ -472,7 +455,7 @@ Downloads a file at remotePath to localPath using parallel reads for faster thro
472
455
  // chunk is transferred
473
456
  }
474
457
  ```
475
-
458
+
476
459
  - **Warning:** Some servers do not respond correctly to requests to alter chunk size. This can result in lost or corrupted data.
477
460
 
478
461
  2. Sample Use
@@ -481,7 +464,7 @@ Downloads a file at remotePath to localPath using parallel reads for faster thro
481
464
  let client = new Client();
482
465
  let remotePath = '/server/path/file.txt';
483
466
  let localPath = '/local/path/file.txt';
484
-
467
+
485
468
  client.connect(config)
486
469
  .then(() => {
487
470
  client.fastGet(remotePath, localPath);
@@ -500,31 +483,32 @@ Upload data from local system to remote server. If the `src` argument is a strin
500
483
 
501
484
  - **src:** string | buffer | readable stream. Data source for data to copy to the remote server.
502
485
  - **remotePath:** string. Path to the remote file to be created on the server.
503
- - **options:** object. Options which can be passed to adjust the write stream used in sending the data to the remote server (see below).
486
+ - **options:** object. Options which can be passed to adjust the read and write stream used in sending the data to the remote server or the pipe call used to make the data transfer (see below).
504
487
 
505
488
  1. Options
506
489
 
507
- The following options are supported;
508
-
490
+ The options object supports three properties, `readStreamOptions`, `writeStreamOptions` and `pipeOptions`. The value for each property should be an object with options as properties and their associated values representing the option value. For example, you might use the following to set `writeStream` options.
491
+
509
492
  ```javascript
510
493
  {
511
- flags: 'w', // w - write and a - append
512
- encoding: null, // use null for binary files
513
- mode: 0o666, // mode to use for created file (rwx)
514
- autoClose: true // automatically close the write stream when finished
515
- }
494
+ writeStreamOptions: {
495
+ flags: 'w', // w - write and a - append
496
+ encoding: null, // use null for binary files
497
+ mode: 0o666, // mode to use for created file (rwx)
498
+ autoClose: true // automatically close the write stream when finished
499
+ }}
516
500
  ```
517
-
501
+
518
502
  The most common options to use are mode and encoding. The values shown above are the defaults. You do not have to set encoding to utf-8 for text files, null is fine for all file types. However, using utf-8 encoding for binary files will often result in data corruption.
519
503
 
520
504
  2. Example Use
521
505
 
522
506
  ```javascript
523
507
  let client = new Client();
524
-
508
+
525
509
  let data = fs.createReadStream('/path/to/local/file.txt');
526
510
  let remote = '/path/to/remote/file.txt';
527
-
511
+
528
512
  client.connect(config)
529
513
  .then(() => {
530
514
  return client.put(data, remote);
@@ -536,7 +520,7 @@ Upload data from local system to remote server. If the `src` argument is a strin
536
520
  console.error(err.message);
537
521
  });
538
522
  ```
539
-
523
+
540
524
  - **Tip:** If the src argument is a path string, consider just using `fastPut()`.
541
525
 
542
526
  ### fastPut(localPath, remotePath, options) ==> string<a id="sec-5-2-9"></a>
@@ -558,7 +542,7 @@ Uploads the data in file at `localPath` to a new file on remote server at `remot
558
542
  // a part of a file was transferred
559
543
  }
560
544
  ```
561
-
545
+
562
546
  - **Warning:** There have been reports that some SFTP servers will not honour requests for non-default chunk sizes. This can result in data loss or corruption.
563
547
 
564
548
  2. Example Use
@@ -567,7 +551,7 @@ Uploads the data in file at `localPath` to a new file on remote server at `remot
567
551
  let localFile = '/path/to/file.txt';
568
552
  let remoteFile = '/path/to/remote/file.txt';
569
553
  let client = new Client();
570
-
554
+
571
555
  client.connect(config)
572
556
  .then(() => {
573
557
  client.fastPut(localFile, remoteFile);
@@ -591,7 +575,7 @@ Append the `input` data to an existing remote file. There is no integrity checki
591
575
  1. Options
592
576
 
593
577
  The following options are supported;
594
-
578
+
595
579
  ```javascript
596
580
  {
597
581
  flags: 'a', // w - write and a - append
@@ -600,7 +584,7 @@ Append the `input` data to an existing remote file. There is no integrity checki
600
584
  autoClose: true // automatically close the write stream when finished
601
585
  }
602
586
  ```
603
-
587
+
604
588
  The most common options to use are mode and encoding. The values shown above are the defaults. You do not have to set encoding to utf-8 for text files, null is fine for all file types. Generally, I would not attempt to append binary files.
605
589
 
606
590
  2. Example Use
@@ -608,7 +592,7 @@ Append the `input` data to an existing remote file. There is no integrity checki
608
592
  ```javascript
609
593
  let remotePath = '/path/to/remote/file.txt';
610
594
  let client = new Client();
611
-
595
+
612
596
  client.connect(config)
613
597
  .then(() => {
614
598
  return client.append(Buffer.from('Hello world'), remotePath);
@@ -633,7 +617,7 @@ Create a new directory. If the recursive flag is set to true, the method will cr
633
617
  ```javascript
634
618
  let remoteDir = '/path/to/new/dir';
635
619
  let client = new Client();
636
-
620
+
637
621
  client.connect(config)
638
622
  .then(() => {
639
623
  return client.mkdir(remoteDir, true);
@@ -660,7 +644,7 @@ Remove a directory. If removing a directory and recursive flag is set to `true`,
660
644
  ```javascript
661
645
  let remoteDir = '/path/to/remote/dir';
662
646
  let client = new Client();
663
-
647
+
664
648
  client.connect(config)
665
649
  .then(() => {
666
650
  return client.rmdir(remoteDir, true);
@@ -686,7 +670,7 @@ Delete a file on the remote server.
686
670
  ```javascript
687
671
  let remoteFile = '/path/to/remote/file.txt';
688
672
  let client = new Client();
689
-
673
+
690
674
  client.connect(config)
691
675
  .then(() => {
692
676
  return client.delete(remoteFile);
@@ -712,7 +696,7 @@ Rename a file or directory from `fromPath` to `toPath`. You must have the necess
712
696
  let from = '/remote/path/to/old.txt';
713
697
  let to = '/remote/path/to/new.txt';
714
698
  let client = new Client();
715
-
699
+
716
700
  client.connect(config)
717
701
  .then(() => {
718
702
  return client.rename(from, to);
@@ -762,7 +746,7 @@ Change the mode (read, write or execute permissions) of a remote file or directo
762
746
  let path = '/path/to/remote/file.txt';
763
747
  let newMode = 0o644; // rw-r-r
764
748
  let client = new Client();
765
-
749
+
766
750
  client.connect(config)
767
751
  .then(() => {
768
752
  return client.chmod(path, newMode);
@@ -803,28 +787,28 @@ The optionsl *filter* argument is a regular expression which can be used to sele
803
787
 
804
788
  ```javascript
805
789
  'use strict';
806
-
790
+
807
791
  // Example of using the uploadDir() method to upload a directory
808
792
  // to a remote SFTP server
809
-
793
+
810
794
  const path = require('path');
811
795
  const SftpClient = require('../src/index');
812
-
796
+
813
797
  const dotenvPath = path.join(__dirname, '..', '.env');
814
798
  require('dotenv').config({path: dotenvPath});
815
-
799
+
816
800
  const config = {
817
801
  host: process.env.SFTP_SERVER,
818
802
  username: process.env.SFTP_USER,
819
803
  password: process.env.SFTP_PASSWORD,
820
804
  port: process.env.SFTP_PORT || 22
821
805
  };
822
-
806
+
823
807
  async function main() {
824
808
  const client = new SftpClient('upload-test');
825
809
  const src = path.join(__dirname, '..', 'test', 'testData', 'upload-src');
826
810
  const dst = '/home/tim/upload-test';
827
-
811
+
828
812
  try {
829
813
  await client.connect(config);
830
814
  client.on('upload', info => {
@@ -836,7 +820,7 @@ The optionsl *filter* argument is a regular expression which can be used to sele
836
820
  client.end();
837
821
  }
838
822
  }
839
-
823
+
840
824
  main()
841
825
  .then(msg => {
842
826
  console.log(msg);
@@ -844,7 +828,7 @@ The optionsl *filter* argument is a regular expression which can be used to sele
844
828
  .catch(err => {
845
829
  console.log(`main error: ${err.message}`);
846
830
  });
847
-
831
+
848
832
  ```
849
833
 
850
834
  ### downloadDir(srcDir, dstDir, filter) ==> string<a id="sec-5-2-20"></a>
@@ -863,28 +847,28 @@ The optional *filter* argument is a regular expression which can be used to sele
863
847
 
864
848
  ```javascript
865
849
  'use strict';
866
-
850
+
867
851
  // Example of using the downloadDir() method to upload a directory
868
852
  // to a remote SFTP server
869
-
853
+
870
854
  const path = require('path');
871
855
  const SftpClient = require('../src/index');
872
-
856
+
873
857
  const dotenvPath = path.join(__dirname, '..', '.env');
874
858
  require('dotenv').config({path: dotenvPath});
875
-
859
+
876
860
  const config = {
877
861
  host: process.env.SFTP_SERVER,
878
862
  username: process.env.SFTP_USER,
879
863
  password: process.env.SFTP_PASSWORD,
880
864
  port: process.env.SFTP_PORT || 22
881
865
  };
882
-
866
+
883
867
  async function main() {
884
868
  const client = new SftpClient('upload-test');
885
869
  const dst = '/tmp';
886
870
  const src = '/home/tim/upload-test';
887
-
871
+
888
872
  try {
889
873
  await client.connect(config);
890
874
  client.on('download', info => {
@@ -896,7 +880,7 @@ The optional *filter* argument is a regular expression which can be used to sele
896
880
  client.end();
897
881
  }
898
882
  }
899
-
883
+
900
884
  main()
901
885
  .then(msg => {
902
886
  console.log(msg);
@@ -904,7 +888,7 @@ The optional *filter* argument is a regular expression which can be used to sele
904
888
  .catch(err => {
905
889
  console.log(`main error: ${err.message}`);
906
890
  });
907
-
891
+
908
892
  ```
909
893
 
910
894
  ### end() ==> boolean<a id="sec-5-2-21"></a>
@@ -915,7 +899,7 @@ Ends the current client session, releasing the client socket and associated reso
915
899
 
916
900
  ```javascript
917
901
  let client = new Client();
918
-
902
+
919
903
  client.connect(config)
920
904
  .then(() => {
921
905
  // do some sftp stuff
@@ -948,7 +932,7 @@ Although normally not required, you can add and remove custom listeners on the s
948
932
 
949
933
  ## Server Capabilities<a id="sec-6-1"></a>
950
934
 
951
- All SFTP servers and platforms are not equal. Some facilities provided by `ssh2-sfto-client` either depend on capabilities of the remote server or the underlying capabilities of the remote server platform. As an example, consider `chmod()`. This command depends on a remote filesystem which implements the 'nix' concept of users and groups. The *win32* platform does not have the same concept of users and groups, so `chmod()` will not behave in the same way.
935
+ All SFTP servers and platforms are not equal. Some facilities provided by `ssh2-sftp-client` either depend on capabilities of the remote server or the underlying capabilities of the remote server platform. As an example, consider `chmod()`. This command depends on a remote filesystem which implements the 'nix' concept of users and groups. The *win32* platform does not have the same concept of users and groups, so `chmod()` will not behave in the same way.
952
936
 
953
937
  One way to determine whether an issue you are encountering is due to `ssh2-sftp-client` or due to the remote server or server platform is to use a simple CLI sftp program, such as openSSH's sftp command. If you observe the same behaviour using plain `sftp` on the command line, the issue is likely due to server or remote platform limitations. Note that you should not use a GUI sftp client, like `Filezilla` or `winSCP` as such GUI programs often attempt to hide these server and platform incompatibilities and will take additional steps to simulate missing functionality etc. You want to use a CLI program which does as little as possible.
954
938