ssh2-sftp-client
Advanced tools
Comparing version 5.0.2 to 5.1.0
{ | ||
"name": "ssh2-sftp-client", | ||
"version": "5.0.2", | ||
"version": "5.1.0", | ||
"description": "ssh2 sftp client for node", | ||
@@ -30,3 +30,3 @@ "main": "src/index.js", | ||
"retry": "^0.12.0", | ||
"ssh2": "^0.8.7" | ||
"ssh2": "^0.8.8" | ||
}, | ||
@@ -39,5 +39,5 @@ "devDependencies": { | ||
"dotenv": "^8.2.0", | ||
"mocha": "^7.0.0", | ||
"mocha": "^7.1.0", | ||
"through2": "^3.0.1" | ||
} | ||
} |
625
README.md
# Table of Contents | ||
1. [SSH2 SFTP Client](#org59926bb) | ||
2. [Installation](#orgfa12105) | ||
3. [Basic Usage](#orgdcb4ac8) | ||
4. [Version 5.x](#orgb1a2c3d) | ||
1. [Breaking Changes in Version 5.x](#org50ff9f1) | ||
1. [Error Event Handling](#orgbc36ac2) | ||
2. [Technical Details](#orgdc9ce74) | ||
2. [New Methods](#org2dd8843) | ||
3. [Version 5.0.1](#orge044fce) | ||
4. [Version 5.0.2](#org7ccd57d) | ||
5. [Documentation](#org050dbca) | ||
1. [Specifying Paths](#org899b50f) | ||
2. [Methods](#orgb3c2cb6) | ||
1. [new SftpClient(name) ===> SFTP client object](#org99655e8) | ||
2. [connect(config) ===> SFTPstream](#org29a9aa8) | ||
3. [list(path, pattern) ==> Array[object]](#org28fc220) | ||
4. [exists(path) ==> boolean](#org9bbdfd9) | ||
5. [stat(path) ==> object](#org9ae7824) | ||
6. [get(path, dst, options) ==> String|Stream|Buffer](#org1608509) | ||
7. [fastGet(remotePath, localPath, options) ===> string](#org9e40286) | ||
8. [put(src, remotePath, options) ==> string](#org21a04fa) | ||
9. [fastPut(localPath, remotePath, options) ==> string](#orgccbc75b) | ||
10. [append(input, remotePath, options) ==> string](#org37e8a28) | ||
11. [mkdir(path, recursive) ==> string](#orgc976219) | ||
12. [rmdir(path, recursive) ==> string](#orga51f516) | ||
13. [delete(path) ==> string](#org29f1cd8) | ||
14. [rename(fromPath, toPath) ==> string](#orgf371df6) | ||
15. [chmod(path, mode) ==> string](#org0ea3423) | ||
16. [realPath(path) ===> string](#org17fe515) | ||
17. [cwd() ==> string](#org8ba0584) | ||
18. [uploadDir(srcDir, dstDir) ==> string](#orgf015b8f) | ||
19. [downloadDir(srcDir, dstDir) ==> string](#org0c10cb8) | ||
20. [end() ==> boolean](#org936ae21) | ||
21. [Add and Remove Listeners](#org15a9c85) | ||
6. [FAQ](#orgc79f3d2) | ||
1. [Remote server drops connections with only an end event](#org8c068da) | ||
2. [How can you pass writable stream as dst for get method?](#org06acfd2) | ||
3. [How can I upload files without having to specify a password?](#orgcd6ac49) | ||
4. [How can I connect through a Socks Proxy](#orga601cc9) | ||
5. [Timeout while waiting for handshake or handshake errors](#orgb9d4439) | ||
7. [Examples](#org5c46982) | ||
8. [Change Log](#org39062e6) | ||
1. [v5.0.2 (Prod Version)](#orga3081db) | ||
2. [v5.0.1](#org5c223c2) | ||
3. [v5.0.0](#orgc1ea505) | ||
4. [v4.3.1](#org9674bc2) | ||
5. [v4.3.0](#org9fdf4b5) | ||
6. [v4.2.4](#org7ed824b) | ||
7. [v4.2.3](#orgd3028bd) | ||
8. [v4.2.2](#org2ac3d75) | ||
9. [v4.2.1](#orgcd4e9e2) | ||
10. [v4.2.0](#org199764b) | ||
11. [v4.1.0](#org10bedf8) | ||
12. [v4.0.4](#org0962876) | ||
13. [v4.0.3](#org3d4fa37) | ||
14. [v4.0.2](#orgeebc8d6) | ||
15. [v4.0.0](#org5d18cf9) | ||
16. [v2.5.2](#orgbc22ad1) | ||
17. [v2.5.1](#org2f89ba7) | ||
18. [v2.5.0](#orgb8683aa) | ||
19. [v2.4.3](#org8c37fb0) | ||
20. [v2.4.2](#orgbe5c717) | ||
21. [v2.4.1](#orgeeb9805) | ||
22. [v2.4.0](#orgbd36319) | ||
23. [v2.3.0](#orgf07ea36) | ||
24. [v3.0.0 – deprecate this version](#org95d7555) | ||
25. [v2.1.1](#orgcca455a) | ||
26. [v2.0.1](#orga11176a) | ||
27. [v1.1.0](#orgc33c477) | ||
28. [v1.0.5:](#orgb12a992) | ||
9. [Troubleshooting](#orgd779dc4) | ||
10. [Logging Issues](#orgfe3d18c) | ||
11. [Pull Requests](#orgd60ef19) | ||
12. [Contributors](#orgf30aa6b) | ||
1. [SSH2 SFTP Client](#org71b320d) | ||
2. [Installation](#orgc904404) | ||
3. [Basic Usage](#orgb7288c2) | ||
4. [Version 5.x](#org117386b) | ||
1. [Breaking Changes in Version 5.x](#orgaf9ad42) | ||
1. [Error Event Handling](#orgb01e3b7) | ||
2. [Technical Details](#org1ae0a28) | ||
2. [New Methods](#orgc8305e8) | ||
3. [Version 5.0.1](#orgc2e0e38) | ||
4. [Version 5.0.2](#org677cda9) | ||
5. [Version 5.1.0](#orgb363dc7) | ||
5. [Documentation](#org46b5997) | ||
1. [Specifying Paths](#orga935b97) | ||
2. [Methods](#org98305c1) | ||
1. [new SftpClient(name) ===> SFTP client object](#org13f62cb) | ||
2. [connect(config) ===> SFTPstream](#orgd1717c5) | ||
3. [list(path, pattern) ==> Array[object]](#org7ba4acf) | ||
4. [exists(path) ==> boolean](#orgdfefb95) | ||
5. [stat(path) ==> object](#orgc98fc30) | ||
6. [get(path, dst, options) ==> String|Stream|Buffer](#org71ac9c4) | ||
7. [fastGet(remotePath, localPath, options) ===> string](#org0ba08cd) | ||
8. [put(src, remotePath, options) ==> string](#org72f0ed8) | ||
9. [fastPut(localPath, remotePath, options) ==> string](#orgef22916) | ||
10. [append(input, remotePath, options) ==> string](#orgf632046) | ||
11. [mkdir(path, recursive) ==> string](#org58685da) | ||
12. [rmdir(path, recursive) ==> string](#org5e796c1) | ||
13. [delete(path) ==> string](#orgdbe4c26) | ||
14. [rename(fromPath, toPath) ==> string](#org269c68f) | ||
15. [chmod(path, mode) ==> string](#org6779ad7) | ||
16. [realPath(path) ===> string](#org40cf2d8) | ||
17. [cwd() ==> string](#org725a728) | ||
18. [uploadDir(srcDir, dstDir) ==> string](#orgae9657b) | ||
19. [downloadDir(srcDir, dstDir) ==> string](#orgd222561) | ||
20. [end() ==> boolean](#orge874563) | ||
21. [Add and Remove Listeners](#org1dfc8a0) | ||
6. [FAQ](#org3f4cd3f) | ||
1. [Remote server drops connections with only an end event](#org1f7302e) | ||
2. [How can you pass writable stream as dst for get method?](#org6e4ae33) | ||
3. [How can I upload files without having to specify a password?](#orgc7ddd7b) | ||
4. [How can I connect through a Socks Proxy](#orgd8d9681) | ||
5. [Timeout while waiting for handshake or handshake errors](#orgbb36729) | ||
7. [Examples](#orge55657d) | ||
8. [Change Log](#orgbc833f6) | ||
1. [v5.1.0 (Prod Version)](#org873e7dc) | ||
2. [v5.0.2](#org23aa953) | ||
3. [v5.0.1](#org512cca9) | ||
4. [v5.0.0](#orgffe1d77) | ||
5. [v4.3.1](#orgf1b1ab1) | ||
6. [v4.3.0](#org25a4659) | ||
7. [v4.2.4](#org5ea6cd7) | ||
8. [v4.2.3](#org9dd805f) | ||
9. [v4.2.2](#org1d5f037) | ||
10. [v4.2.1](#orgfdf42ef) | ||
11. [v4.2.0](#org1c700cb) | ||
12. [v4.1.0](#org1349876) | ||
13. [v4.0.4](#org8f40eff) | ||
14. [v4.0.3](#orga5a2b24) | ||
15. [v4.0.2](#orga51086a) | ||
16. [v4.0.0](#org8912607) | ||
17. [v2.5.2](#org69cd5a2) | ||
18. [v2.5.1](#org22c1cfa) | ||
19. [v2.5.0](#orge9fd1d9) | ||
20. [v2.4.3](#orgc46f51e) | ||
21. [v2.4.2](#orge36de5b) | ||
22. [v2.4.1](#orgb05ccdc) | ||
23. [v2.4.0](#org1720444) | ||
24. [v2.3.0](#orgd9d6b14) | ||
25. [v3.0.0 – deprecate this version](#orgaa07c2d) | ||
26. [v2.1.1](#org2f15e75) | ||
27. [v2.0.1](#org9c51b08) | ||
28. [v1.1.0](#orgca16e6c) | ||
29. [v1.0.5:](#org9995b3c) | ||
9. [Troubleshooting](#orgcc9e37c) | ||
1. [Debugging Support](#org668ad1e) | ||
10. [Logging Issues](#orgde016a7) | ||
11. [Pull Requests](#orga4e4a57) | ||
12. [Contributors](#org6b3cc00) | ||
<a id="org59926bb"></a> | ||
<a id="org71b320d"></a> | ||
@@ -90,3 +93,3 @@ # SSH2 SFTP Client | ||
Current stable release is **v5.0.2**. | ||
Current stable release is **v5.1.0**. | ||
@@ -98,3 +101,3 @@ Code has been tested against Node versions 10.18.1, 12.14.1 and 13.6.0 | ||
<a id="orgfa12105"></a> | ||
<a id="orgc904404"></a> | ||
@@ -106,3 +109,3 @@ # Installation | ||
<a id="orgdcb4ac8"></a> | ||
<a id="orgb7288c2"></a> | ||
@@ -113,3 +116,3 @@ # Basic Usage | ||
let sftp = new Client(); | ||
sftp.connect({ | ||
@@ -129,3 +132,3 @@ host: '127.0.0.1', | ||
<a id="orgb1a2c3d"></a> | ||
<a id="org117386b"></a> | ||
@@ -135,3 +138,3 @@ # Version 5.x | ||
<a id="org50ff9f1"></a> | ||
<a id="orgaf9ad42"></a> | ||
@@ -165,3 +168,3 @@ ## Breaking Changes in Version 5.x | ||
<a id="orgbc36ac2"></a> | ||
<a id="orgb01e3b7"></a> | ||
@@ -173,3 +176,3 @@ ### Error Event Handling | ||
events to communicate various state changes and error conditions. These | ||
events can fire at any time. | ||
events can fire at any time. | ||
@@ -183,3 +186,3 @@ On the client side, we wrap basic SFTP actions in Javascript Promises, | ||
downloaded or rejected, indicating the download failed. All pretty | ||
straight-forward. | ||
straight-forward. | ||
@@ -193,3 +196,3 @@ When the Promise is created, an error event handler is added to the SFTP | ||
a promise can only be resolved or rejected once, after the Promise has | ||
completed, the error listener is of no further use. | ||
completed, the error listener is of no further use. | ||
@@ -214,3 +217,3 @@ This all works fine when an error event fires during the execution of a | ||
try/catch block around the SFTP client object. Basically, there is nothing | ||
listening of any errors at this point. What will happen? | ||
listening of any errors at this point. What will happen? | ||
@@ -220,3 +223,3 @@ Well, basically, the error event will bubble up to the top level of the node | ||
dump a stack trace and cause the node process to exit. In basic terms, your | ||
process will crash. Not a great outcome. | ||
process will crash. Not a great outcome. | ||
@@ -250,3 +253,3 @@ There are a number of things we can do to improve the situation. However, | ||
attempts to use the connection will throw an error inside the Promise which | ||
attempts to use it. | ||
attempts to use it. | ||
@@ -265,6 +268,6 @@ The advantage of this approach is that it stops the abrupt exiting of the | ||
want to end, then you can just ignore the error, perform any necessary | ||
cleanup work and exit successfully. | ||
cleanup work and exit successfully. | ||
<a id="orgdc9ce74"></a> | ||
<a id="org1ae0a28"></a> | ||
@@ -276,3 +279,3 @@ ### Technical Details | ||
which may be defined. As part of the processing, these error handler set a flag | ||
property `this.errorHandled` to true, indicating the error has been handled. | ||
property `this.errorHandled` to true, indicating the error has been handled. | ||
@@ -287,6 +290,6 @@ In addition to the Promise error handlers, there is a default error handler | ||
further attempts to use it and finally, ensure the `this.errorHandler` flag is | ||
reset to false in preparation for the next error. | ||
reset to false in preparation for the next error. | ||
<a id="org2dd8843"></a> | ||
<a id="orgc8305e8"></a> | ||
@@ -307,3 +310,3 @@ ## New Methods | ||
<a id="orge044fce"></a> | ||
<a id="orgc2e0e38"></a> | ||
@@ -318,3 +321,3 @@ ## Version 5.0.1 | ||
<a id="org7ccd57d"></a> | ||
<a id="org677cda9"></a> | ||
@@ -328,4 +331,17 @@ ## Version 5.0.2 | ||
<a id="org050dbca"></a> | ||
<a id="orgb363dc7"></a> | ||
## Version 5.1.0 | ||
- Add missing connection check in end() method | ||
- Add debugging support. Now adding a debug property to the connection | ||
configuration object will enable debugging. The value of the debug property | ||
should be a function which accepts a single string argument. Typically, | ||
this function will send the value passed in to stderr or a file. | ||
- Fix bug in checkRemotePath() relating to poor path specifications where | ||
you cannot determine parent directory. | ||
<a id="org46b5997"></a> | ||
# Documentation | ||
@@ -340,19 +356,25 @@ | ||
<a id="org899b50f"></a> | ||
<a id="orga935b97"></a> | ||
## Specifying Paths | ||
Both `./` and `../` are supported in path specifiers. Tilde (`~`) expansion is | ||
not supported. Relative paths i.e. paths which do not start with a `/`, will be | ||
considered to be relative to whatever the remote server considers to be the | ||
`root` directory of the login. Depending on how the remote SFTP server is | ||
configured, this may not always be what you expect. The module also does some | ||
very basic tests on results returned from the remote server to try and determine | ||
platform type and will replace path separators with whatever the remote systems | ||
uses (e.g. replace `/` with `\` on MS Windows). | ||
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. | ||
It is important to recognise that the current remote directory may not always be | ||
what you may expect. A lot will depend on the remote platform of the SFTP server | ||
and how the SFTP server has been configured. When things don't seem to be | ||
working as expected, it is often a good idea to verify your assumptions | ||
regarding the remote directory and remote paths. One way to do this is to login | ||
using a command line program like `sftp` or `lftp`. | ||
There is a small performance hit for using `./` and `../` as the module must | ||
query the remote server to determine what the root path is and derive the | ||
absolute path. Using absolute paths are therefore more efficient and likely more | ||
robust. | ||
robust. | ||
@@ -379,3 +401,3 @@ When specifying file paths, ensure to include a full path i.e. include the | ||
<a id="orgb3c2cb6"></a> | ||
<a id="org98305c1"></a> | ||
@@ -385,3 +407,3 @@ ## Methods | ||
<a id="org99655e8"></a> | ||
<a id="org13f62cb"></a> | ||
@@ -401,5 +423,5 @@ ### new SftpClient(name) ===> SFTP client object | ||
'use strict'; | ||
const Client = require('ssh2-sftp-client'); | ||
const config = { | ||
@@ -410,5 +432,5 @@ host: 'example.com', | ||
}; | ||
const sftp = new Client('example-client'); | ||
sftp.connect(config) | ||
@@ -427,3 +449,3 @@ .then(() => { | ||
<a id="org29a9aa8"></a> | ||
<a id="orgd1717c5"></a> | ||
@@ -442,3 +464,3 @@ ### connect(config) ===> SFTPstream | ||
the minimum needed and stick to the options listed in the `commonOpts` below. | ||
The `retries`, `retry_factor` and `retry_minTimeout` options are not part of the | ||
@@ -448,5 +470,5 @@ SSH2 module. These are part of the configuration for the [retry](https://www.npmjs.com/package/retry) package and what | ||
for that package for an explanation of these values. | ||
// common options | ||
let commonOpts { | ||
@@ -465,3 +487,3 @@ host: 'localhost', // string Hostname or IP of server. | ||
debug: myDebug // function - Set this to a function that receives a single | ||
// string argument to get detailed (local) debug information. | ||
// string argument to get detailed (local) debug information. | ||
retries: 2 // integer. Number of times to retry connecting | ||
@@ -471,5 +493,5 @@ retry_factor: 2 // integer. Time factor used to calculate time between retries | ||
}; | ||
// rarely used options | ||
let advancedOpts { | ||
@@ -502,3 +524,3 @@ localAddress, | ||
<a id="org28fc220"></a> | ||
<a id="org7ba4acf"></a> | ||
@@ -519,3 +541,3 @@ ### list(path, pattern) ==> Array[object] | ||
const Client = require('ssh2-sftp-client'); | ||
const config = { | ||
@@ -527,5 +549,5 @@ host: 'example.com', | ||
}; | ||
let sftp = new Client; | ||
sftp.connect(config) | ||
@@ -548,3 +570,3 @@ .then(() => { | ||
The objects in the array returned by `list()` have the following properties; | ||
{ | ||
@@ -569,7 +591,7 @@ type: // file type(-, d, l) | ||
simple *glob*-like string where \* will match any number of characters, e.g. | ||
foo* => foo, foobar, foobaz | ||
*bar => bar, foobar, tabbar | ||
*oo* => foo, foobar, look, book | ||
The *glob*-style matching is very simple. In most cases, you are best off using | ||
@@ -580,3 +602,3 @@ a real regular expression which will allow you to do more powerful matching and | ||
<a id="org9bbdfd9"></a> | ||
<a id="orgdfefb95"></a> | ||
@@ -591,3 +613,3 @@ ### exists(path) ==> boolean | ||
const Client = require('ssh2-sftp-client'); | ||
const config = { | ||
@@ -599,5 +621,5 @@ host: 'example.com', | ||
}; | ||
let sftp = new Client; | ||
sftp.connect(config) | ||
@@ -618,3 +640,3 @@ .then(() => { | ||
<a id="org9ae7824"></a> | ||
<a id="orgc98fc30"></a> | ||
@@ -630,3 +652,3 @@ ### stat(path) ==> object | ||
The `stat()` method returns an object with the following properties; | ||
let stats = { | ||
@@ -651,3 +673,3 @@ mode: 33279, // integer representing type and permissions | ||
let client = new Client(); | ||
client.connect(config) | ||
@@ -668,3 +690,3 @@ .then(() => { | ||
<a id="org1608509"></a> | ||
<a id="org71ac9c4"></a> | ||
@@ -693,3 +715,3 @@ ### get(path, dst, options) ==> String|Stream|Buffer | ||
to read the data from the remote server. | ||
{ | ||
@@ -702,3 +724,3 @@ flags: 'r', | ||
} | ||
Most of the time, you won't want to use any options. Sometimes, it may be useful | ||
@@ -711,6 +733,6 @@ to set the encoding. For example, to 'utf-8'. However, it is important not to do | ||
let client = new Client(); | ||
let remotePath = '/remote/server/path/file.txt'; | ||
let dst = fs.createWriteStream('/local/file/path/copy.txt'); | ||
client.connect(config) | ||
@@ -726,3 +748,3 @@ .then(() => { | ||
}); | ||
- **Tip:** See examples file in the Git repository for more examples. You can pass | ||
@@ -734,3 +756,3 @@ any writeable stream in as the destination. For example, if you pass in | ||
<a id="org9e40286"></a> | ||
<a id="org0ba08cd"></a> | ||
@@ -754,5 +776,5 @@ ### fastGet(remotePath, localPath, options) ===> string | ||
step: function(total_transferred, chunk, total) // callback called each time a | ||
// chunk is transferred | ||
// chunk is transferred | ||
} | ||
- **Warning:** Some servers do not respond correctly to requests to alter chunk | ||
@@ -766,3 +788,3 @@ size. This can result in lost or corrupted data. | ||
let localPath = '/local/path/file.txt'; | ||
client.connect(config) | ||
@@ -780,3 +802,3 @@ .then(() => { | ||
<a id="org21a04fa"></a> | ||
<a id="org72f0ed8"></a> | ||
@@ -800,3 +822,3 @@ ### put(src, remotePath, options) ==> string | ||
The following options are supported; | ||
{ | ||
@@ -808,3 +830,3 @@ flags: 'w', // w - write and a - append | ||
} | ||
The most common options to use are mode and encoding. The values shown above are | ||
@@ -818,6 +840,6 @@ the defaults. You do not have to set encoding to utf-8 for text files, null is | ||
let client = new Client(); | ||
let data = fs.createReadStream('/path/to/local/file.txt'); | ||
let remote = '/path/to/remote/file.txt'; | ||
client.connect(config) | ||
@@ -833,7 +855,7 @@ .then(() => { | ||
}); | ||
- **Tip:** If the src argument is a path string, consider just using `fastPut()`. | ||
<a id="orgccbc75b"></a> | ||
<a id="orgef22916"></a> | ||
@@ -858,3 +880,3 @@ ### fastPut(localPath, remotePath, options) ==> string | ||
} | ||
- **Warning:** There have been reports that some SFTP servers will not honour | ||
@@ -869,3 +891,3 @@ requests for non-default chunk sizes. This can result in data loss | ||
let client = new Client(); | ||
client.connect(config) | ||
@@ -883,3 +905,3 @@ .then(() => { | ||
<a id="org37e8a28"></a> | ||
<a id="orgf632046"></a> | ||
@@ -900,3 +922,3 @@ ### append(input, remotePath, options) ==> string | ||
The following options are supported; | ||
{ | ||
@@ -908,3 +930,3 @@ flags: 'a', // w - write and a - append | ||
} | ||
The most common options to use are mode and encoding. The values shown above are | ||
@@ -918,3 +940,3 @@ the defaults. You do not have to set encoding to utf-8 for text files, null is | ||
let client = new Client(); | ||
client.connect(config) | ||
@@ -932,3 +954,3 @@ .then(() => { | ||
<a id="orgc976219"></a> | ||
<a id="org58685da"></a> | ||
@@ -949,3 +971,3 @@ ### mkdir(path, recursive) ==> string | ||
let client = new Client(); | ||
client.connect(config) | ||
@@ -963,3 +985,3 @@ .then(() => { | ||
<a id="orga51f516"></a> | ||
<a id="org5e796c1"></a> | ||
@@ -981,3 +1003,3 @@ ### rmdir(path, recursive) ==> string | ||
let client = new Client(); | ||
client.connect(config) | ||
@@ -995,3 +1017,3 @@ .then(() => { | ||
<a id="org29f1cd8"></a> | ||
<a id="orgdbe4c26"></a> | ||
@@ -1008,3 +1030,3 @@ ### delete(path) ==> string | ||
let client = new Client(); | ||
client.connect(config) | ||
@@ -1022,3 +1044,3 @@ .then(() => { | ||
<a id="orgf371df6"></a> | ||
<a id="org269c68f"></a> | ||
@@ -1035,3 +1057,3 @@ ### rename(fromPath, toPath) ==> string | ||
let client = new Client(); | ||
client.connect(config) | ||
@@ -1049,3 +1071,3 @@ .then(() => { | ||
<a id="org0ea3423"></a> | ||
<a id="org6779ad7"></a> | ||
@@ -1065,3 +1087,3 @@ ### chmod(path, mode) ==> string | ||
let client = new Client(); | ||
client.connect(config) | ||
@@ -1079,3 +1101,3 @@ .then(() => { | ||
<a id="org17fe515"></a> | ||
<a id="org40cf2d8"></a> | ||
@@ -1085,4 +1107,4 @@ ### realPath(path) ===> string | ||
Converts a relative path to an absolute path on the remote server. This method | ||
is mainly used internally to resolve remote path names. Returns '' if the | ||
path is not valid. | ||
is mainly used internally to resolve remote path names. Returns '' if the | ||
path is not valid. | ||
@@ -1093,3 +1115,3 @@ - **path:** A file path, either relative or absolute. Can handle '.' and '..', but | ||
<a id="org8ba0584"></a> | ||
<a id="org725a728"></a> | ||
@@ -1101,3 +1123,3 @@ ### cwd() ==> string | ||
<a id="orgf015b8f"></a> | ||
<a id="orgae9657b"></a> | ||
@@ -1117,3 +1139,3 @@ ### uploadDir(srcDir, dstDir) ==> string | ||
client code to get feedback on the upload progress. You can add your own lisener | ||
using the `on()` method. | ||
using the `on()` method. | ||
@@ -1125,48 +1147,48 @@ - **srcDir:** A local file path specified as a string | ||
'use strict'; | ||
// Example of using the uploadDir() method to upload a directory | ||
// to a remote SFTP server | ||
const path = require('path'); | ||
const SftpClient = require('../src/index'); | ||
const dotenvPath = path.join(__dirname, '..', '.env'); | ||
require('dotenv').config({path: dotenvPath}); | ||
const config = { | ||
host: process.env.SFTP_SERVER, | ||
username: process.env.SFTP_USER, | ||
password: process.env.SFTP_PASSWORD, | ||
port: process.env.SFTP_PORT || 22 | ||
}; | ||
async function main() { | ||
const client = new SftpClient('upload-test'); | ||
const src = path.join(__dirname, '..', 'test', 'testData', 'upload-src'); | ||
const dst = '/home/tim/upload-test'; | ||
try { | ||
await client.connect(config); | ||
client.on('upload', info => { | ||
console.log(`Listener: Uploaded ${info.source}`); | ||
}); | ||
let rslt = await client.uploadDir(src, dst); | ||
return rslt; | ||
} finally { | ||
client.end(); | ||
} | ||
'use strict'; | ||
// Example of using the uploadDir() method to upload a directory | ||
// to a remote SFTP server | ||
const path = require('path'); | ||
const SftpClient = require('../src/index'); | ||
const dotenvPath = path.join(__dirname, '..', '.env'); | ||
require('dotenv').config({path: dotenvPath}); | ||
const config = { | ||
host: process.env.SFTP_SERVER, | ||
username: process.env.SFTP_USER, | ||
password: process.env.SFTP_PASSWORD, | ||
port: process.env.SFTP_PORT || 22 | ||
}; | ||
async function main() { | ||
const client = new SftpClient('upload-test'); | ||
const src = path.join(__dirname, '..', 'test', 'testData', 'upload-src'); | ||
const dst = '/home/tim/upload-test'; | ||
try { | ||
await client.connect(config); | ||
client.on('upload', info => { | ||
console.log(`Listener: Uploaded ${info.source}`); | ||
}); | ||
let rslt = await client.uploadDir(src, dst); | ||
return rslt; | ||
} finally { | ||
client.end(); | ||
} | ||
main() | ||
.then(msg => { | ||
console.log(msg); | ||
}) | ||
.catch(err => { | ||
console.log(`main error: ${err.message}`); | ||
}); | ||
} | ||
main() | ||
.then(msg => { | ||
console.log(msg); | ||
}) | ||
.catch(err => { | ||
console.log(`main error: ${err.message}`); | ||
}); | ||
<a id="org0c10cb8"></a> | ||
<a id="orgd222561"></a> | ||
### downloadDir(srcDir, dstDir) ==> string | ||
@@ -1178,3 +1200,3 @@ | ||
files in the local path will be overwritten. No files in the local path will be | ||
deleted. | ||
deleted. | ||
@@ -1186,3 +1208,3 @@ The method also emites `download` events to provide a way to monitor download | ||
to where the file was downloaded to. You can add a listener for this event using | ||
the `on()` method. | ||
the `on()` method. | ||
@@ -1195,12 +1217,12 @@ - **srcDir:** A remote file path specified as a string | ||
'use strict'; | ||
// Example of using the downloadDir() method to upload a directory | ||
// to a remote SFTP server | ||
const path = require('path'); | ||
const SftpClient = require('../src/index'); | ||
const dotenvPath = path.join(__dirname, '..', '.env'); | ||
require('dotenv').config({path: dotenvPath}); | ||
const config = { | ||
@@ -1212,3 +1234,3 @@ host: process.env.SFTP_SERVER, | ||
}; | ||
async function main() { | ||
@@ -1218,7 +1240,7 @@ const client = new SftpClient('upload-test'); | ||
const src = '/home/tim/upload-test'; | ||
try { | ||
await client.connect(config); | ||
client.on('download', info => { | ||
console.log(`Listener: Download ${info.source}`); | ||
console.log(`Listener: Download ${info.source}`); | ||
}); | ||
@@ -1231,3 +1253,3 @@ let rslt = await client.downloadDir(src, dst); | ||
} | ||
main() | ||
@@ -1242,3 +1264,3 @@ .then(msg => { | ||
<a id="org936ae21"></a> | ||
<a id="orge874563"></a> | ||
@@ -1253,3 +1275,3 @@ ### end() ==> boolean | ||
let client = new Client(); | ||
client.connect(config) | ||
@@ -1267,3 +1289,3 @@ .then(() => { | ||
<a id="org15a9c85"></a> | ||
<a id="org1dfc8a0"></a> | ||
@@ -1294,3 +1316,3 @@ ### Add and Remove Listeners | ||
<a id="orgc79f3d2"></a> | ||
<a id="org3f4cd3f"></a> | ||
@@ -1300,3 +1322,3 @@ # FAQ | ||
<a id="org8c068da"></a> | ||
<a id="org1f7302e"></a> | ||
@@ -1331,3 +1353,3 @@ ## Remote server drops connections with only an end event | ||
<a id="org06acfd2"></a> | ||
<a id="org6e4ae33"></a> | ||
@@ -1348,7 +1370,7 @@ ## How can you pass writable stream as dst for get method? | ||
'use strict'; | ||
// Example of using a writeable with get to retrieve a file. | ||
// This code will read the remote file, convert all characters to upper case | ||
// and then save it to a local file | ||
const Client = require('../src/index.js'); | ||
@@ -1358,3 +1380,3 @@ const path = require('path'); | ||
const through = require('through2'); | ||
const config = { | ||
@@ -1366,6 +1388,6 @@ host: 'arch-vbox', | ||
}; | ||
const sftp = new Client(); | ||
const remoteDir = '/home/tim/testServer'; | ||
function toupper() { | ||
@@ -1376,3 +1398,3 @@ return through(function(buf, enc, next) { | ||
} | ||
sftp | ||
@@ -1400,3 +1422,3 @@ .connect(config) | ||
<a id="orgcd6ac49"></a> | ||
<a id="orgc7ddd7b"></a> | ||
@@ -1436,3 +1458,3 @@ ## How can I upload files without having to specify a password? | ||
<a id="orga601cc9"></a> | ||
<a id="orgd8d9681"></a> | ||
@@ -1445,6 +1467,6 @@ ## How can I connect through a Socks Proxy | ||
import SFTPClient from 'ssh2-sftp-client'; | ||
const host = 'my-sftp-server.net'; | ||
const port = 22; // default SSH/SFTP port on remote server | ||
// connect to SOCKS 5 proxy | ||
@@ -1460,3 +1482,3 @@ const { socket } = await SocksClient.createConnection({ | ||
}); | ||
const client = new SFTPClient(); | ||
@@ -1469,7 +1491,7 @@ client.connect({ | ||
}) | ||
// client is connected | ||
<a id="orgb9d4439"></a> | ||
<a id="orgbb36729"></a> | ||
@@ -1486,6 +1508,6 @@ ## Timeout while waiting for handshake or handshake errors | ||
documentation for details. Getting these parameters correct usually resolves the | ||
issue. | ||
issue. | ||
<a id="org5c46982"></a> | ||
<a id="orge55657d"></a> | ||
@@ -1498,6 +1520,6 @@ # Examples | ||
handling and may contain errors. However, I think they are still useful for | ||
helping developers see how the module and API can be used. | ||
helping developers see how the module and API can be used. | ||
<a id="org39062e6"></a> | ||
<a id="orgbc833f6"></a> | ||
@@ -1507,6 +1529,17 @@ # Change Log | ||
<a id="orga3081db"></a> | ||
<a id="org873e7dc"></a> | ||
## v5.0.2 (Prod Version) | ||
## v5.1.0 (Prod Version) | ||
- Fix bug in checkRemotePath() relating to handling of badly | ||
specified paths (issue #213) | ||
- Added additional debugging support | ||
- Add missing test for valid connection in end() method. | ||
- Bump ssh2 version to v0.8.8 | ||
<a id="org23aa953"></a> | ||
## v5.0.2 | ||
- Fix bugs related to win32 platform and local tests for valid directories | ||
@@ -1516,11 +1549,11 @@ - Fix problem with parsing of file paths | ||
<a id="org5c223c2"></a> | ||
<a id="org512cca9"></a> | ||
## v5.0.1 | ||
- Turn down error checking to be less stringent and handle situations | ||
- Turn down error checking to be less stringent and handle situations | ||
where user does not have read permission on parent directory. | ||
<a id="orgc1ea505"></a> | ||
<a id="orgffe1d77"></a> | ||
@@ -1544,3 +1577,3 @@ ## v5.0.0 | ||
<a id="org9674bc2"></a> | ||
<a id="orgf1b1ab1"></a> | ||
@@ -1555,3 +1588,3 @@ ## v4.3.1 | ||
<a id="org9fdf4b5"></a> | ||
<a id="org25a4659"></a> | ||
@@ -1566,3 +1599,3 @@ ## v4.3.0 | ||
<a id="org7ed824b"></a> | ||
<a id="org5ea6cd7"></a> | ||
@@ -1576,3 +1609,3 @@ ## v4.2.4 | ||
<a id="orgd3028bd"></a> | ||
<a id="org9dd805f"></a> | ||
@@ -1586,3 +1619,3 @@ ## v4.2.3 | ||
<a id="org2ac3d75"></a> | ||
<a id="org1d5f037"></a> | ||
@@ -1595,3 +1628,3 @@ ## v4.2.2 | ||
<a id="orgcd4e9e2"></a> | ||
<a id="orgfdf42ef"></a> | ||
@@ -1610,3 +1643,3 @@ ## v4.2.1 | ||
<a id="org199764b"></a> | ||
<a id="org1c700cb"></a> | ||
@@ -1622,3 +1655,3 @@ ## v4.2.0 | ||
<a id="org10bedf8"></a> | ||
<a id="org1349876"></a> | ||
@@ -1640,3 +1673,3 @@ ## v4.1.0 | ||
<a id="org0962876"></a> | ||
<a id="org8f40eff"></a> | ||
@@ -1649,3 +1682,3 @@ ## v4.0.4 | ||
<a id="org3d4fa37"></a> | ||
<a id="orga5a2b24"></a> | ||
@@ -1658,3 +1691,3 @@ ## v4.0.3 | ||
<a id="orgeebc8d6"></a> | ||
<a id="orga51086a"></a> | ||
@@ -1666,3 +1699,3 @@ ## v4.0.2 | ||
<a id="org5d18cf9"></a> | ||
<a id="org8912607"></a> | ||
@@ -1685,3 +1718,3 @@ ## v4.0.0 | ||
<a id="orgbc22ad1"></a> | ||
<a id="org69cd5a2"></a> | ||
@@ -1694,3 +1727,3 @@ ## v2.5.2 | ||
<a id="org2f89ba7"></a> | ||
<a id="org22c1cfa"></a> | ||
@@ -1702,3 +1735,3 @@ ## v2.5.1 | ||
<a id="orgb8683aa"></a> | ||
<a id="orge9fd1d9"></a> | ||
@@ -1710,3 +1743,3 @@ ## v2.5.0 | ||
<a id="org8c37fb0"></a> | ||
<a id="orgc46f51e"></a> | ||
@@ -1719,3 +1752,3 @@ ## v2.4.3 | ||
<a id="orgbe5c717"></a> | ||
<a id="orge36de5b"></a> | ||
@@ -1728,3 +1761,3 @@ ## v2.4.2 | ||
<a id="orgeeb9805"></a> | ||
<a id="orgb05ccdc"></a> | ||
@@ -1737,3 +1770,3 @@ ## v2.4.1 | ||
<a id="orgbd36319"></a> | ||
<a id="org1720444"></a> | ||
@@ -1751,3 +1784,3 @@ ## v2.4.0 | ||
<a id="orgf07ea36"></a> | ||
<a id="orgd9d6b14"></a> | ||
@@ -1761,3 +1794,3 @@ ## v2.3.0 | ||
<a id="org95d7555"></a> | ||
<a id="orgaa07c2d"></a> | ||
@@ -1770,3 +1803,3 @@ ## v3.0.0 – deprecate this version | ||
<a id="orgcca455a"></a> | ||
<a id="org2f15e75"></a> | ||
@@ -1779,3 +1812,3 @@ ## v2.1.1 | ||
<a id="orga11176a"></a> | ||
<a id="org9c51b08"></a> | ||
@@ -1790,3 +1823,3 @@ ## v2.0.1 | ||
<a id="orgc33c477"></a> | ||
<a id="orgca16e6c"></a> | ||
@@ -1798,3 +1831,3 @@ ## v1.1.0 | ||
<a id="orgb12a992"></a> | ||
<a id="org9995b3c"></a> | ||
@@ -1807,3 +1840,3 @@ ## v1.0.5: | ||
<a id="orgd779dc4"></a> | ||
<a id="orgcc9e37c"></a> | ||
@@ -1821,3 +1854,3 @@ # Troubleshooting | ||
to those later 2 modules and therefore and issue which should be referred to the | ||
maintainer of that module. | ||
maintainer of that module. | ||
@@ -1832,3 +1865,3 @@ The `ssh2` and `ssh2-streams` modules are very solid, high quality modules with | ||
documentation for both the `ssh2` and `ssh2-streams` module is quite | ||
comprehensive and there is lots of valuable information in the issue logs. | ||
comprehensive and there is lots of valuable information in the issue logs. | ||
@@ -1842,3 +1875,3 @@ If you run into an issue which is not repeatable with just the `ssh2` and | ||
to perform common tasks. A few minutes reviewing these examples can provide that | ||
additional bit of detail to help fix any problems you are encountering. | ||
additional bit of detail to help fix any problems you are encountering. | ||
@@ -1849,7 +1882,26 @@ The second directory is the tools directory. I have some very basic simple | ||
trying to determine if the issue is with the underlying `ssh2` and | ||
`ssh2-streams` modules. | ||
`ssh2-streams` modules. | ||
<a id="orgfe3d18c"></a> | ||
<a id="org668ad1e"></a> | ||
## Debugging Support | ||
You can add a `debug` property to the config object passed in to `connect()` to | ||
turn on debugging. This will generate quite a lot of output. The value of the | ||
property should be a function which accepts a single string argument. For example; | ||
config.debug = msg => { | ||
console.error(msg); | ||
}; | ||
Enabling debugging can generate a lot of output. If you use console.error() as | ||
the output (as in the example above), you can redirect the output to a file | ||
using shell redirection e.g. | ||
node script.js 2> debug.log | ||
<a id="orgde016a7"></a> | ||
# Logging Issues | ||
@@ -1875,6 +1927,6 @@ | ||
Perhaps the best assistance is a minimal reproducible example of the issue. Once | ||
the issue can be readily reproduced, it can usually be fixed very quickly. | ||
the issue can be readily reproduced, it can usually be fixed very quickly. | ||
<a id="orgd60ef19"></a> | ||
<a id="orga4e4a57"></a> | ||
@@ -1899,3 +1951,3 @@ # Pull Requests | ||
<a id="orgf30aa6b"></a> | ||
<a id="org6b3cc00"></a> | ||
@@ -1913,2 +1965,1 @@ # Contributors | ||
- **waldyrious:** Documentation fixes | ||
@@ -24,4 +24,17 @@ /** | ||
this.errorHandled = false; | ||
this.debug = undefined; | ||
} | ||
debugMsg(msg, obj) { | ||
if (this.debug) { | ||
if (obj) { | ||
this.debug( | ||
`CLIENT[${this.clientName}]: ${msg} ${JSON.stringify(obj, null, ' ')}` | ||
); | ||
} else { | ||
this.debug(`CLIENT[${this.clientName}]: ${msg}`); | ||
} | ||
} | ||
} | ||
/** | ||
@@ -37,2 +50,3 @@ * Add a listner to the client object. This is rarely necessary and can be | ||
on(eventType, callback) { | ||
this.debugMsg(`Adding listener to ${eventType}`); | ||
this.client.on(eventType, callback); | ||
@@ -42,2 +56,3 @@ } | ||
removeListener(eventType, callback) { | ||
this.debugMsg(`Removing listener from ${eventType}`); | ||
this.client.removeListener(eventType, callback); | ||
@@ -72,5 +87,9 @@ } | ||
// remove the listeners and try again | ||
this.debugMsg( | ||
`Connection attempt ${attemptCount} failed. Trying again.` | ||
); | ||
return; | ||
} | ||
// exhausted retries - do callback with error | ||
this.debugMsg('Exhausted all connection attempts. Giving up'); | ||
callback( | ||
@@ -98,2 +117,3 @@ utils.formatError(err, 'connect', err.code, attemptCount), | ||
} | ||
this.debugMsg('SFTP connection established'); | ||
this.sftp = sftp; | ||
@@ -133,2 +153,6 @@ // remove retry error listener and add generic error listener | ||
} else { | ||
if (config.debug) { | ||
this.debug = config.debug; | ||
this.debug('Debugging turned on'); | ||
} | ||
retryConnect(config, (err, sftp) => { | ||
@@ -151,5 +175,7 @@ if (err) { | ||
this.remotePlatform = 'unix'; | ||
this.debugMsg('Remote platform unix like'); | ||
} else { | ||
this.remotePathSep = '\\'; | ||
this.remotePlatform = 'windows'; | ||
this.debugMsg('remote platform windows like'); | ||
} | ||
@@ -182,2 +208,3 @@ resolve(sftp); | ||
try { | ||
this.debugMsg(`realPath -> ${remotePath}`); | ||
errorListener = utils.makeErrorListener(reject, this, 'realPath'); | ||
@@ -188,2 +215,3 @@ this.client.prependListener('error', errorListener); | ||
if (err) { | ||
this.debugMsg(`realPath Error: ${err.message} Code: ${err.code}`); | ||
if (err.code === 2) { | ||
@@ -201,2 +229,3 @@ resolve(''); | ||
} | ||
this.debugMsg(`realPath <- ${absPath}`); | ||
resolve(absPath); | ||
@@ -226,2 +255,3 @@ }); | ||
try { | ||
this.debugMsg(`stat -> ${aPath}`); | ||
errorListener = utils.makeErrorListener(reject, this, 'stat'); | ||
@@ -231,2 +261,3 @@ this.client.prependListener('error', errorListener); | ||
if (err) { | ||
this.debugMsg(`stat error ${err.message} code: ${err.code}`); | ||
if (err.code === 2) { | ||
@@ -246,2 +277,3 @@ reject( | ||
} else { | ||
this.debugMsg('stats <- ', stats); | ||
resolve({ | ||
@@ -298,3 +330,5 @@ mode: stats.mode, | ||
try { | ||
this.debugMsg(`exists -> ${absPath}`); | ||
let info = await this.stat(absPath); | ||
this.debugMsg('exists <- ', info); | ||
if (info.isDirectory) { | ||
@@ -345,2 +379,3 @@ return 'd'; | ||
try { | ||
this.debugMsg(`list -> ${aPath} filter -> ${filter}`); | ||
errorListener = utils.makeErrorListener(reject, this, 'list'); | ||
@@ -350,4 +385,6 @@ this.client.prependListener('error', errorListener); | ||
if (err) { | ||
this.debugMsg(`list error ${err.message} code: ${err.code}`); | ||
reject(utils.formatError(`${err.message} ${aPath}`, '_list')); | ||
} else { | ||
this.debugMsg('list <- ', fileList); | ||
let newList = []; | ||
@@ -426,2 +463,3 @@ // reset file info | ||
try { | ||
this.debugMsg(`get -> ${sftpPath} `, options); | ||
errorListener = utils.makeErrorListener(reject, this, 'get'); | ||
@@ -436,2 +474,3 @@ this.client.prependListener('error', errorListener); | ||
// no dst specified, return buffer of data | ||
this.debugMsg('get returning buffer of data'); | ||
let concatStream = concat(buff => { | ||
@@ -446,4 +485,6 @@ rdr.removeAllListeners('error'); | ||
// dst local file path | ||
this.debugMsg('get returning local file'); | ||
wtr = fs.createWriteStream(localDst); | ||
} else { | ||
this.debugMsg('get returning data into supplied stream'); | ||
wtr = localDst; | ||
@@ -483,2 +524,3 @@ } | ||
); | ||
this.debugMsg('get remote path info ', pathInfo); | ||
if (!pathInfo.valid) { | ||
@@ -490,2 +532,3 @@ let e = utils.formatError(pathInfo.msg, 'get', pathInfo.code); | ||
let localInfo = await utils.checkLocalPath(dst, targetType.writeFile); | ||
this.debugMsg('get local path info ', localInfo); | ||
if (localInfo.valid) { | ||
@@ -522,2 +565,3 @@ dst = localInfo.path; | ||
try { | ||
this.debugMsg(`fastGet -> ${from} ${to} `, opts); | ||
errorListener = utils.makeErrorListener(reject, this, 'fastGet'); | ||
@@ -527,2 +571,3 @@ this.client.prependListener('error', errorListener); | ||
if (err) { | ||
this.debugMsg(`fastGet error ${err.message} code: ${err.code}`); | ||
reject( | ||
@@ -550,2 +595,3 @@ utils.formatError( | ||
); | ||
this.debugMsg('fastGet remote path info ', pathInfo); | ||
if (!pathInfo.valid) { | ||
@@ -559,2 +605,3 @@ let e = utils.formatError(pathInfo.msg, 'fastGet', pathInfo.code); | ||
); | ||
this.debugMsg('fastGet local path info ', localInfo); | ||
if (!localInfo.valid) { | ||
@@ -592,2 +639,3 @@ let e = utils.formatError( | ||
try { | ||
this.debugMsg(`fastPut -> ${localPath} ${remotePath} `, opts); | ||
errorListener = utils.makeErrorListener(reject, this, 'fastPut'); | ||
@@ -597,2 +645,3 @@ this.client.prependListener('error', errorListener); | ||
if (err) { | ||
this.debugMsg(`fastPut error ${err.message} ${err.code}`); | ||
reject( | ||
@@ -616,2 +665,3 @@ utils.formatError( | ||
let localInfo = await utils.checkLocalPath(localPath); | ||
this.debugMsg('fastPut local path info ', localInfo); | ||
if (!localInfo.valid) { | ||
@@ -626,2 +676,3 @@ let e = utils.formatError(localInfo.msg, 'fastPut', localInfo.code); | ||
); | ||
this.debugMsg('fastPut remote path info ', pathInfo); | ||
if (!pathInfo.valid) { | ||
@@ -653,2 +704,3 @@ let e = utils.formatError(pathInfo.msg, 'fastPut', pathInfo.code); | ||
try { | ||
this.debugMsg(`put -> ${dst} `, opts); | ||
errorListener = utils.makeErrorListener(reject, this, 'put'); | ||
@@ -665,2 +717,3 @@ this.client.prependListener('error', errorListener); | ||
if (src instanceof Buffer) { | ||
this.debugMsg('put source is a buffer'); | ||
stream.end(src); | ||
@@ -670,4 +723,6 @@ } else { | ||
if (typeof src === 'string') { | ||
this.debugMsg(`put source is a file path: ${src}`); | ||
rdr = fs.createReadStream(src); | ||
} else { | ||
this.debugMsg('put source is a stream'); | ||
rdr = src; | ||
@@ -698,2 +753,3 @@ } | ||
let localInfo = await utils.checkLocalPath(localSrc); | ||
this.debugMsg('put local path info ', localInfo); | ||
if (!localInfo.valid) { | ||
@@ -710,2 +766,3 @@ let e = utils.formatError(localInfo.msg, 'put', localInfo.code); | ||
); | ||
this.debugMsg('put remote path info ', pathInfo); | ||
if (!pathInfo.valid) { | ||
@@ -734,2 +791,3 @@ let e = utils.formatError(pathInfo.msg, 'put', pathInfo.code); | ||
try { | ||
this.debugMsg(`append -> ${aPath} `, opts); | ||
errorListener = utils.makeErrorListener(reject, this, 'append'); | ||
@@ -781,2 +839,3 @@ this.client.prependListener('error', errorListener); | ||
); | ||
this.debugMsg('append remote path info ', pathInfo); | ||
if (!pathInfo.valid) { | ||
@@ -815,2 +874,3 @@ let e = utils.formatError(pathInfo.msg, 'append', pathInfo.code); | ||
try { | ||
this.debugMsg(`mkdir -> ${p}`); | ||
errorListener = utils.makeErrorListener(reject, this, 'mkdir'); | ||
@@ -820,2 +880,3 @@ this.client.prependListener('error', errorListener); | ||
if (err) { | ||
this.debugMsg(`mkdir error ${err.message} code: ${err.code}`); | ||
reject( | ||
@@ -840,2 +901,3 @@ utils.formatError(`${err.message} ${p}`, '_mkdir', err.code) | ||
); | ||
this.debugMsg('mkdir remote path info ', pathInfo); | ||
if (!pathInfo.valid) { | ||
@@ -852,2 +914,3 @@ throw utils.formatError(pathInfo.msg, 'mkdir', pathInfo.code); | ||
let parent = await utils.checkRemotePath(this, dir, targetType.writeDir); | ||
this.debugMsg('mkdir parent path info ', parent); | ||
if (parent.valid && !parent.type) { | ||
@@ -877,2 +940,3 @@ await this.mkdir(dir, true); | ||
try { | ||
this.debugMsg(`rmdir -> ${p}`); | ||
errorListener = utils.makeErrorListener(reject, this, 'rmdir'); | ||
@@ -882,2 +946,3 @@ this.client.prependListener('error', errorListener); | ||
if (err) { | ||
this.debugMsg(`rmdir error ${err.message} code: ${err.code}`); | ||
reject( | ||
@@ -902,2 +967,3 @@ utils.formatError(`${err.message} ${p}`, '_rmdir', err.code) | ||
); | ||
this.debugMsg('rmdir remoe path info ', pathInfo); | ||
if (!pathInfo.valid) { | ||
@@ -914,2 +980,4 @@ let e = utils.formatError(pathInfo.msg, 'rmdir', pathInfo.code); | ||
let dirs = list.filter(item => item.type === 'd'); | ||
this.debugMsg('rmdir contents (files): ', files); | ||
this.debugMsg('rmdir contents (dirs): ', dirs); | ||
for (let f of files) { | ||
@@ -942,2 +1010,3 @@ await this.delete(pathInfo.path + this.remotePathSep + f.name); | ||
try { | ||
this.debugMsg(`delete -> ${p}`); | ||
errorListener = utils.makeErrorListener(reject, this, 'delete'); | ||
@@ -947,2 +1016,3 @@ this.client.prependListener('error', errorListener); | ||
if (err) { | ||
this.debugMsg(`delete error ${err.message} code: ${err.code}`); | ||
reject( | ||
@@ -967,2 +1037,3 @@ utils.formatError(`${err.message} ${p}`, '_delete', err.code) | ||
); | ||
this.debugMsg('delete remote path info ', pathInfo); | ||
if (!pathInfo.valid) { | ||
@@ -994,2 +1065,3 @@ let e = utils.formatError(pathInfo.msg, 'delete', pathInfo.code); | ||
try { | ||
this.debugMsg(`rename -> ${from} ${to}`); | ||
errorListener = utils.makeErrorListener(reject, this, 'rename'); | ||
@@ -999,2 +1071,3 @@ this.client.prependListener('error', errorListener); | ||
if (err) { | ||
this.debugMsg(`rename error ${err.message} code: ${err.code}`); | ||
reject( | ||
@@ -1022,2 +1095,3 @@ utils.formatError( | ||
); | ||
this.debugMsg('rename from path info ', fromInfo); | ||
if (!fromInfo.valid) { | ||
@@ -1032,2 +1106,3 @@ let e = utils.formatError(fromInfo.msg, 'rename', fromInfo.code); | ||
); | ||
this.debugMsg('rename to path info ', toInfo); | ||
if (toInfo.type) { | ||
@@ -1070,2 +1145,3 @@ let e = utils.formatError( | ||
try { | ||
this.debugMsg(`chmod -> ${p} ${m}`); | ||
errorListener = utils.makeErrorListener(reject, this, 'chmod'); | ||
@@ -1092,2 +1168,3 @@ this.client.prependListener('error', errorListener); | ||
); | ||
this.debugMsg('chmod path info ', pathInfo); | ||
if (!pathInfo.valid) { | ||
@@ -1116,2 +1193,3 @@ let e = utils.formatError(pathInfo.msg, 'chmod', pathInfo.code); | ||
try { | ||
this.debugMsg(`uploadDir -> ${srcDir} ${dstDir}`); | ||
utils.haveConnection(this, 'uploadDir'); | ||
@@ -1123,2 +1201,3 @@ let localInfo = await utils.checkLocalPath(srcDir, targetType.readDir); | ||
} | ||
this.debugMsg('uploadDir local path info ', localInfo); | ||
let remoteInfo = await utils.checkRemotePath( | ||
@@ -1129,2 +1208,3 @@ this, | ||
); | ||
this.debugMsg('uploadDir remote path info ', remoteInfo); | ||
if (!remoteInfo.valid) { | ||
@@ -1163,2 +1243,3 @@ let e = utils.formatError(remoteInfo.msg, 'uploadDir', remoteInfo.code); | ||
try { | ||
this.debugMsg(`downloadDir -> ${srcDir} ${dstDir}`); | ||
utils.haveConnection(this, 'downloadDir'); | ||
@@ -1170,2 +1251,3 @@ let remoteInfo = await utils.checkRemotePath( | ||
); | ||
this.debugMsg('downloadDir remote path info ', remoteInfo); | ||
if (!remoteInfo.valid) { | ||
@@ -1180,2 +1262,3 @@ let e = utils.formatError( | ||
let localInfo = await utils.checkLocalPath(dstDir, targetType.writeDir); | ||
this.debugMsg('downloadDir lcoal path info ', localInfo); | ||
if (localInfo.valid && !localInfo.type) { | ||
@@ -1218,2 +1301,3 @@ fs.mkdirSync(localInfo.path, {recursive: true}); | ||
try { | ||
utils.haveConnection(this, 'end'); | ||
this.client.prependListener('error', err => { | ||
@@ -1220,0 +1304,0 @@ // we don't care about errors at this point |
@@ -480,2 +480,11 @@ 'use strict'; | ||
let parentDir = path.parse(aPath).dir; | ||
if (!parentDir) { | ||
return { | ||
path: aPath, | ||
type: false, | ||
valid: false, | ||
msg: `Bad path: ${aPath} cannot determine parent directory`, | ||
code: errorCode.badPath | ||
}; | ||
} | ||
let parentType = await client.exists(parentDir); | ||
@@ -523,2 +532,11 @@ if (!parentType) { | ||
let parentDir = path.parse(aPath).dir; | ||
if (!parentDir) { | ||
return { | ||
path: aPath, | ||
type: false, | ||
valid: false, | ||
msg: `Bad path: ${aPath} cannot determine directory parent`, | ||
code: errorCode.badPath | ||
}; | ||
} | ||
let parentType = await client.exists(parentDir); | ||
@@ -525,0 +543,0 @@ if (parentType && parentType !== 'd') { |
Sorry, the diff of this file is not supported yet
186969
1852
1833
7
Updatedssh2@^0.8.8