ssh2-sftp-client 7.2.1 → 8.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.
Files changed (5) hide show
  1. package/README.md +156 -157
  2. package/README.org +97 -79
  3. package/package.json +15 -19
  4. package/src/index.js +182 -104
  5. package/src/utils.js +28 -37
package/README.org CHANGED
@@ -9,12 +9,42 @@ convenience abstraction as well as a Promise based API.
9
9
  Documentation on the methods and available options in the underlying modules can
10
10
  be found on the [[https://github.com/mscdex/ssh2][SSH2]] project pages.
11
11
 
12
- Current stable release is *v7.2.1*.
13
-
14
- Code has been tested against Node versions 14.18.2, 16.13.1 and 17.2.0
15
-
16
- Node versions < 10.x are not supported.
17
-
12
+ Current stable release is *v8.0.0*.
13
+
14
+ Code has been tested against Node versions 14.19.1, 16.14.2 and 17.8.0
15
+
16
+ Node versions < 12.x are not supported. However, node v10.x should still work,
17
+ although some tests will fail due to changes in file system functions used in
18
+ test setup and tear down.
19
+
20
+ ** Version 8.x.x Changes
21
+
22
+ - *Breaking Change*: The API for ~uploadDir()~ and ~downloadDir()~ has been
23
+ changed. These methods now expect a function as the optional 3rd argument.
24
+ Previously, the 3rd argument was a regular expression used to filter out
25
+ which files and directories should be included in the upload or download
26
+ action. The method now expects a predicate function which will return true
27
+ if the target is to be included in the upload or download and false if it is
28
+ to be excluded. The predicate function will be called with two arguments, a
29
+ full path to the target object and a boolean value which is true when the
30
+ target is a directory, false otherwise. If no filter predicate is supplied,
31
+ all files and directories under the initial target directory will be
32
+ transferred. At this time, asynchronous filter functions are not supported.
33
+
34
+ - Internal Change: The ~rmdir()~ method has been refactored to enable
35
+ asynchronous deletion of files and sub-directories. This has significantly
36
+ increased performance when deleting larger directory trees, especially trees
37
+ which are /broad/ with lots of files and directories at the same level. For
38
+ deep narrow trees, there is less performance benefit because sub-directories
39
+ must be removed before parents, which imposes synchronous processing. It is
40
+ likely that for extremely large directory trees, the additional resources
41
+ required to run large numbers of asynchronous tasks will become problematic.
42
+ In such situations, it may be necessary to manually break up the deletion
43
+ process into multiple ~rmdir()~ calls. However, this is considered a fairly
44
+ extreme use case which is rare (a use case which wold also have been
45
+ problematic with the old implementation as performance would have been very
46
+ poor).
47
+
18
48
  * Installation
19
49
 
20
50
  #+begin_src shell
@@ -41,40 +71,6 @@ npm install ssh2-sftp-client
41
71
  });
42
72
  #+end_src
43
73
 
44
- * Version 7.x Changes
45
-
46
- - This version is based on version 1.x.x of ~ssh2~. This version of ~ssh2~ is a
47
- complete re-write of the ~ssh2~ library. This re-write addresses issues
48
- encountered when using node v14 as well as some design weaknesses in the
49
- previous 0.8.x version.
50
-
51
- - *Breaking Change* Expanded option handling for ~get()~ and ~put()~ methods. A number of use
52
- cases were identified where setting specific options on the read and write
53
- streams and the pipe operation are necessary. For example, disabling
54
- ~autoClose~ on streams or the ~end~ event in pipes. The ~options~ argument for
55
- ~get()~ and ~put()~ calls now supports properties for ~readStreamOptions~,
56
- ~writeStreamOptions~ and ~pipeOptions~. Note that options are only applied to
57
- streams created by the ~get()~ and ~put()~ methods. Streams passed into these
58
- methods are under the control of the client code and therefore cannot have
59
- options supplied in arguments to those streams (you would apply such options
60
- when you create the streams). Options are typically only necessary in special
61
- use cases. Most of the time, no options are required. However, if you are
62
- currently using options to either ~put()~ or ~get()~, you will need to update
63
- your code to map these options to the new structure.
64
-
65
- - *Breaking Change 7.1.0* A race condition was identified when using a put()
66
- call with a writeStream option of ~autoClose: false~. In some situations, the
67
- promise would be resolved before the final close of the write stream. This
68
- could result in errors if you immediately attempt to access the uploaded
69
- file. To avoid this situatioin, the promise is now resolved once a ~close~
70
- event is emitted. This means that setting ~autoClose: false~ can no longer be
71
- supported. The write stream for ~put()~ will autoClose once data writing has completed.
72
-
73
- - Improved event handling. A listener for a global error event is now defined to
74
- catch errors which occur in-between method calls i.e. connection lost
75
- in-between calls to the library methods. A new mechanism has also been added
76
- for removal of listeners when no longer required.
77
-
78
74
  * Documentation
79
75
 
80
76
  The connection options are the same as those offered by the underlying SSH2
@@ -422,7 +418,7 @@ is passed to it via a call to pipe(). If ~dst~ is undefined, the method will put
422
418
  the data into a buffer and return that buffer when the Promise is resolved. If
423
419
  ~dst~ is defined, it is returned when the Promise is resolved.
424
420
 
425
- In general, if your going to pass in a string as the destination, you are
421
+ In general, if you're going to pass in a string as the destination, you are
426
422
  better off using the ~fastGet()~ method.
427
423
 
428
424
  - path :: String. Path to the remote file to download
@@ -890,18 +886,29 @@ The upload process also emits 'upload' events. These events are fired for each
890
886
  successfully uploaded file. The ~upload~ event calls listeners with 1 argument,
891
887
  an object which has properties source and destination. The source property is
892
888
  the path of the file uploaded and the destination property is the path to where
893
- the file was uploaded to. The purpose of this event is to provide some way for
894
- client code to get feedback on the upload progress. You can add your own lisener
889
+ the file was uploaded. The purpose of this event is to provide some way for
890
+ client code to get feedback on the upload progress. You can add your own listener
895
891
  using the ~on()~ method.
896
892
 
897
- The optionsl /filter/ argument is a regular expression which can be used to
898
- select which files and directories to include in the upload.
893
+ The optionsl /filter/ argument is a function which will be called for each item
894
+ to be uploaded. The function will be called with two arguments. The first
895
+ argument is the full path of the item to be uploaded and the second argument is
896
+ a boolean, which will be true if the target path is for a directory. The filter
897
+ function will be called for each item in the source path. If the function
898
+ returns true, the item will be uploaded. If it returns false, it will be
899
+ filtered and not uploaded. The filter function is called via the ~Array.filter~
900
+ method. These array comprehension methods are known to be unsafe for
901
+ asynchronous functions. Therefore, only synchronous filter functions are
902
+ supported at this time.
899
903
 
900
904
  - srcDir :: A local file path specified as a string
901
905
  - dstDir :: A remote file path specified as a string
902
- - filter :: A regular expression used to filter which files and directories to
903
- include in the upload
904
-
906
+ - filter :: A filter predicate function which is called for each item in the
907
+ source path. The argument will receive two arguments. The first is the full
908
+ path to the item and the second is a boolean which will be true if the item is
909
+ a directory. If the function returns true, the item will be uploaded,
910
+ otherwise it will be filtered out and ignored.
911
+
905
912
  **** Example
906
913
 
907
914
  #+begin_src javascript
@@ -917,36 +924,38 @@ select which files and directories to include in the upload.
917
924
  require('dotenv').config({path: dotenvPath});
918
925
 
919
926
  const config = {
920
- host: process.env.SFTP_SERVER,
921
- username: process.env.SFTP_USER,
922
- password: process.env.SFTP_PASSWORD,
923
- port: process.env.SFTP_PORT || 22
927
+ host: process.env.SFTP_SERVER,
928
+ username: process.env.SFTP_USER,
929
+ password: process.env.SFTP_PASSWORD,
930
+ port: process.env.SFTP_PORT || 22
924
931
  };
925
932
 
926
933
  async function main() {
927
- const client = new SftpClient('upload-test');
928
- const src = path.join(__dirname, '..', 'test', 'testData', 'upload-src');
929
- const dst = '/home/tim/upload-test';
930
-
931
- try {
932
- await client.connect(config);
933
- client.on('upload', info => {
934
- console.log(`Listener: Uploaded ${info.source}`);
935
- });
936
- let rslt = await client.uploadDir(src, dst);
937
- return rslt;
938
- } finally {
939
- client.end();
940
- }
934
+ const client = new SftpClient('upload-test');
935
+ const src = path.join(__dirname, '..', 'test', 'testData', 'upload-src');
936
+ const dst = '/home/tim/upload-test';
937
+
938
+ try {
939
+ await client.connect(config);
940
+ client.on('upload', info => {
941
+ console.log(`Listener: Uploaded ${info.source}`);
942
+ });
943
+ let rslt = await client.uploadDir(src, dst);
944
+ return rslt;
945
+ } catch (err) {
946
+ console.error(err);
947
+ } finally {
948
+ client.end();
949
+ }
941
950
  }
942
951
 
943
952
  main()
944
- .then(msg => {
945
- console.log(msg);
946
- })
947
- .catch(err => {
948
- console.log(`main error: ${err.message}`);
949
- });
953
+ .then(msg => {
954
+ console.log(msg);
955
+ })
956
+ .catch(err => {
957
+ console.log(`main error: ${err.message}`);
958
+ });
950
959
 
951
960
  #+end_src
952
961
 
@@ -965,14 +974,21 @@ the remote file that has been downloaded and the destination is the local path
965
974
  to where the file was downloaded to. You can add a listener for this event using
966
975
  the ~on()~ method.
967
976
 
968
- The optional /filter/ argument is a regular expression which can be used to
969
- select which files and directories will be downloaded from the remote server.
977
+ The optional /filter/ argument is a predicate function which will be called with
978
+ two arguments for each potential item to be downloaded. The first argument is
979
+ the full path of the item and the second argument is a boolean, which will be
980
+ true if the item is a directory. If the function returns true, the item will be
981
+ included in the download. If it returns false, it will be filtered and ignored.
982
+ The filter function is called via the ~Array.filter~ method. These array
983
+ comprehension methods are known to be unsafe for asynchronous functions.
984
+ Therefore, only synchronous filter functions are supported at this time.
970
985
 
971
986
  - srcDir :: A remote file path specified as a string
972
987
  - dstDir :: A local file path specified as a string
973
- - filter :: A regular expression used to match the files and directories to be
974
- downloaded
975
-
988
+ - filter :: A predicate function called with two arguments, the full path to an
989
+ item and a boolean value which will be true if the item is a directory. The
990
+ function is called for each item in the download path.
991
+
976
992
  **** Example
977
993
 
978
994
  #+begin_src javascript
@@ -1732,10 +1748,10 @@ the issue. Things which will help
1732
1748
  Perhaps the best assistance is a minimal reproducible example of the issue. Once
1733
1749
  the issue can be readily reproduced, it can usually be fixed very quickly.
1734
1750
 
1735
- * Pull Requests
1751
+ * Pull Requests
1736
1752
 
1737
1753
  Pull requests are always welcomed. However, please ensure your changes pass all
1738
- tests and if your adding a new feature, that tests for that feature are
1754
+ tests and if you're adding a new feature, that tests for that feature are
1739
1755
  included. Likewise, for new features or enhancements, please include any
1740
1756
  relevant documentation updates.
1741
1757
 
@@ -1784,3 +1800,5 @@ Thanks to the following for their contributions -
1784
1800
  'close' to resolve promise
1785
1801
  - Maik Marschner :: Contributed fix for connect() not returning sftp object.
1786
1802
  Also included test to check for this regression in future.
1803
+ - cakemasher :: Contributed fix for removeTempListeners().
1804
+
package/package.json CHANGED
@@ -1,17 +1,13 @@
1
1
  {
2
2
  "name": "ssh2-sftp-client",
3
- "version": "7.2.1",
3
+ "version": "8.0.0",
4
4
  "description": "ssh2 sftp client for node",
5
5
  "main": "src/index.js",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/theophilusx/ssh2-sftp-client"
9
9
  },
10
- "keywords": [
11
- "sftp",
12
- "nodejs",
13
- "promises"
14
- ],
10
+ "keywords": ["sftp", "nodejs", "promises"],
15
11
  "scripts": {
16
12
  "test": "mocha",
17
13
  "coverage": "nyc npm run test",
@@ -29,28 +25,28 @@
29
25
  }
30
26
  ],
31
27
  "license": "Apache-2.0",
32
- "dependencies": {
33
- "concat-stream": "^2.0.0",
34
- "promise-retry": "^2.0.1",
35
- "ssh2": "^1.5.0"
36
- },
37
28
  "devDependencies": {
38
- "chai": "^4.3.4",
29
+ "chai": "^4.3.6",
39
30
  "chai-as-promised": "^7.1.1",
40
31
  "chai-subset": "^1.6.0",
41
32
  "checksum": "^1.0.0",
42
- "dotenv": "^10.0.0",
43
- "eslint": "^8.5.0",
44
- "eslint-config-prettier": "^8.3.0",
33
+ "dotenv": "^16.0.0",
34
+ "eslint": "^8.12.0",
35
+ "eslint-config-prettier": "^8.5.0",
45
36
  "eslint-plugin-mocha": "^10.0.3",
46
37
  "eslint-plugin-node": "^11.1.0",
47
38
  "eslint-plugin-promise": "^6.0.0",
48
- "eslint-plugin-unicorn": "^39.0.0",
49
- "mocha": "^9.1.2",
39
+ "eslint-plugin-unicorn": "^42.0.0",
40
+ "mocha": "^9.2.2",
50
41
  "moment": "^2.29.1",
51
42
  "nyc": "^15.1.0",
52
- "prettier": "^2.5.0",
43
+ "prettier": "^2.6.1",
53
44
  "through2": "^4.0.2",
54
- "winston": "^3.3.3"
45
+ "winston": "^3.6.0"
46
+ },
47
+ "dependencies": {
48
+ "concat-stream": "^2.0.0",
49
+ "promise-retry": "^2.0.1",
50
+ "ssh2": "^1.9.0"
55
51
  }
56
52
  }