ssh2-sftp-client 7.0.0 → 7.0.4
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 +38 -14
- package/README.org +115 -62
- package/package.json +20 -6
- package/src/constants.js +3 -5
- package/src/index.js +412 -311
- package/src/utils.js +161 -51
- package/CHANGELOG.org +0 -232
package/src/utils.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
4
6
|
const { errorCode } = require('./constants');
|
|
5
7
|
|
|
6
8
|
/**
|
|
@@ -67,15 +69,19 @@ let tempListeners = [];
|
|
|
67
69
|
*/
|
|
68
70
|
function errorListener(client, name, reject) {
|
|
69
71
|
let fn = (err) => {
|
|
70
|
-
if (
|
|
72
|
+
if (client.endCalled || client.errorHandled) {
|
|
73
|
+
client.debugMsg(`${name}: Ignoring handled error: ${err.message}`);
|
|
74
|
+
} else {
|
|
75
|
+
client.debugMsg(`${name}: Handling error: ${err.message}`);
|
|
71
76
|
client.errorHandled = true;
|
|
72
77
|
if (reject) {
|
|
78
|
+
client.debugMsg(`${name}: handled error with reject`);
|
|
73
79
|
reject(fmtError(err, name, err.code));
|
|
74
80
|
} else {
|
|
81
|
+
client.debugMsg(`${name}: handling error with throw`);
|
|
75
82
|
throw fmtError(err, name, err.code);
|
|
76
83
|
}
|
|
77
84
|
}
|
|
78
|
-
client.debugMsg(`Handled Error: ${err.message} ${err.code}`);
|
|
79
85
|
};
|
|
80
86
|
tempListeners.push(['error', fn]);
|
|
81
87
|
return fn;
|
|
@@ -83,12 +89,17 @@ function errorListener(client, name, reject) {
|
|
|
83
89
|
|
|
84
90
|
function endListener(client, name, reject) {
|
|
85
91
|
let fn = function () {
|
|
86
|
-
client.
|
|
87
|
-
|
|
92
|
+
if (client.endCalled || client.endHandled) {
|
|
93
|
+
client.debugMsg(`${name}: Ignoring expected end event`);
|
|
94
|
+
} else {
|
|
95
|
+
client.debugMsg(`${name}: Handling end event`);
|
|
88
96
|
client.sftp = undefined;
|
|
97
|
+
client.endHandled = true;
|
|
89
98
|
if (reject) {
|
|
99
|
+
client.debugMsg(`${name}: handling end event with reject'`);
|
|
90
100
|
reject(fmtError('Unexpected end event raised', name));
|
|
91
101
|
} else {
|
|
102
|
+
client.debugMsg(`${name}: handling end event with throw`);
|
|
92
103
|
throw fmtError('Unexpected end event raised', name);
|
|
93
104
|
}
|
|
94
105
|
}
|
|
@@ -99,12 +110,17 @@ function endListener(client, name, reject) {
|
|
|
99
110
|
|
|
100
111
|
function closeListener(client, name, reject) {
|
|
101
112
|
let fn = function () {
|
|
102
|
-
client.
|
|
103
|
-
|
|
113
|
+
if (client.endCalled || client.closeHandled) {
|
|
114
|
+
client.debugMsg(`${name}: ignoring expected close event`);
|
|
115
|
+
} else {
|
|
116
|
+
client.debugMsg(`${name}: handling unexpected close event`);
|
|
104
117
|
client.sftp = undefined;
|
|
118
|
+
client.closeHandled = true;
|
|
105
119
|
if (reject) {
|
|
120
|
+
client.debugMsg(`${name}: handling close event with reject`);
|
|
106
121
|
reject(fmtError('Unexpected close event raised', name));
|
|
107
122
|
} else {
|
|
123
|
+
client.debugMsg(`${name}: handling close event with throw`);
|
|
108
124
|
throw fmtError('Unexpected close event raised', name);
|
|
109
125
|
}
|
|
110
126
|
}
|
|
@@ -114,73 +130,165 @@ function closeListener(client, name, reject) {
|
|
|
114
130
|
}
|
|
115
131
|
|
|
116
132
|
function addTempListeners(obj, name, reject) {
|
|
117
|
-
obj.debugMsg(`${name}: Adding
|
|
133
|
+
obj.debugMsg(`${name}: Adding temp event listeners`);
|
|
118
134
|
obj.client.prependListener('end', endListener(obj, name, reject));
|
|
119
|
-
obj.debugMsg(`${name}: Adding close listener`);
|
|
120
135
|
obj.client.prependListener('close', closeListener(obj, name, reject));
|
|
121
|
-
obj.debugMsg(`${name}: Adding error listener`);
|
|
122
136
|
obj.client.prependListener('error', errorListener(obj, name, reject));
|
|
123
137
|
}
|
|
124
138
|
|
|
125
|
-
function removeTempListeners(obj) {
|
|
139
|
+
function removeTempListeners(obj, name) {
|
|
140
|
+
obj.debugMsg(`${name}: Removing temp event listeners`);
|
|
126
141
|
tempListeners.forEach(([e, fn]) => {
|
|
127
|
-
obj.debugMsg(`${obj.clientName}: Removing ${e} listener`);
|
|
128
142
|
obj.client.removeListener(e, fn);
|
|
129
143
|
});
|
|
130
144
|
tempListeners = [];
|
|
131
145
|
}
|
|
132
146
|
|
|
133
147
|
/**
|
|
134
|
-
*
|
|
148
|
+
* Checks to verify local object exists. Returns a character string representing the type
|
|
149
|
+
* type of local object if it exists, false if it doesn't.
|
|
135
150
|
*
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
151
|
+
* Return codes: l = symbolic link
|
|
152
|
+
* - = regular file
|
|
153
|
+
* d = directory
|
|
154
|
+
* s = socket
|
|
139
155
|
*
|
|
140
|
-
* @param {
|
|
141
|
-
* @returns {
|
|
156
|
+
* @param {string} filePath - path to local object
|
|
157
|
+
* @returns {string | boolean} returns a string for object type if it exists, false otherwise
|
|
142
158
|
*/
|
|
143
|
-
function localExists(filePath
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
159
|
+
function localExists(filePath) {
|
|
160
|
+
const stats = fs.statSync(filePath, { throwIfNoEntry: false });
|
|
161
|
+
if (!stats) {
|
|
162
|
+
return false;
|
|
163
|
+
} else if (stats.isDirectory()) {
|
|
164
|
+
return 'd';
|
|
165
|
+
} else if (stats.isFile()) {
|
|
166
|
+
return '-';
|
|
167
|
+
} else {
|
|
168
|
+
throw fmtError(
|
|
169
|
+
`Bad path: ${filePath}: target must be a file or directory`,
|
|
170
|
+
'localExists',
|
|
171
|
+
errorCode.badPath
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Verify access to local object. Returns an object with properties for status, type,
|
|
178
|
+
* details and code.
|
|
179
|
+
*
|
|
180
|
+
* return object {
|
|
181
|
+
* status: true if exists and can be accessed, false otherwise
|
|
182
|
+
* type: type of object '-' = file, 'd' = dir, 'l' = link, 's' = socket
|
|
183
|
+
* details: 'access ok' if object can be accessed, 'not found' if
|
|
184
|
+
* object does not exist, 'permission denied' if access denied
|
|
185
|
+
* code: error code if object does not exist or permission denied
|
|
186
|
+
* }
|
|
187
|
+
*
|
|
188
|
+
* @param {string} filePath = path to local object
|
|
189
|
+
* @param {string} mode = access mode - either 'r' or 'w'. Defaults to 'r'
|
|
190
|
+
* @returns {Object} with properties status, type, details and code
|
|
191
|
+
*/
|
|
192
|
+
function haveLocalAccess(filePath, mode = 'r') {
|
|
193
|
+
const accessMode =
|
|
194
|
+
fs.constants.F_OK | (mode === 'w') ? fs.constants.W_OK : fs.constants.R_OK;
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
fs.accessSync(filePath, accessMode);
|
|
198
|
+
const type = localExists(filePath);
|
|
199
|
+
return {
|
|
200
|
+
status: true,
|
|
201
|
+
type: type,
|
|
202
|
+
details: 'access OK',
|
|
203
|
+
code: 0,
|
|
204
|
+
};
|
|
205
|
+
} catch (err) {
|
|
206
|
+
switch (err.errno) {
|
|
207
|
+
case -2:
|
|
208
|
+
return {
|
|
209
|
+
status: false,
|
|
210
|
+
type: null,
|
|
211
|
+
details: 'not exist',
|
|
212
|
+
code: -2,
|
|
213
|
+
};
|
|
214
|
+
case -13:
|
|
215
|
+
return {
|
|
216
|
+
status: false,
|
|
217
|
+
type: localExists(filePath),
|
|
218
|
+
details: 'permission denied',
|
|
219
|
+
code: -13,
|
|
220
|
+
};
|
|
221
|
+
case -20:
|
|
222
|
+
return {
|
|
223
|
+
status: false,
|
|
224
|
+
type: null,
|
|
225
|
+
details: 'parent not a directory',
|
|
226
|
+
};
|
|
227
|
+
default:
|
|
228
|
+
return {
|
|
229
|
+
status: false,
|
|
230
|
+
type: null,
|
|
231
|
+
details: err.message,
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Checks to verify the object specified by filePath can either be written to or created
|
|
239
|
+
* if it doens't already exist. If it does not exist, checks to see if the parent entry in the
|
|
240
|
+
* path is a directory and can be written to. Returns an object with the same format as the object
|
|
241
|
+
* returned by 'haveLocalAccess'.
|
|
242
|
+
*
|
|
243
|
+
* @param {string} filePath - path to object to be created or written t
|
|
244
|
+
* @returns {Object} Object with properties status, type, destils and code
|
|
245
|
+
*/
|
|
246
|
+
function haveLocalCreate(filePath) {
|
|
247
|
+
const { status, details, type } = haveLocalAccess(filePath, 'w');
|
|
248
|
+
if (!status && details === 'permission denied') {
|
|
249
|
+
//throw new Error(`Bad path: ${filePath}: permission denied`);
|
|
250
|
+
return {
|
|
251
|
+
status,
|
|
252
|
+
details,
|
|
253
|
+
type,
|
|
254
|
+
};
|
|
255
|
+
} else if (!status) {
|
|
256
|
+
const dirPath = path.dirname(filePath);
|
|
257
|
+
const localCheck = haveLocalAccess(dirPath, 'w');
|
|
258
|
+
if (localCheck.status && localCheck.type !== 'd') {
|
|
259
|
+
//throw new Error(`Bad path: ${dirPath}: not a directory`);
|
|
260
|
+
return {
|
|
261
|
+
status: false,
|
|
262
|
+
details: `${dirPath}: not a directory`,
|
|
263
|
+
type: null,
|
|
264
|
+
};
|
|
265
|
+
} else if (!localCheck.status) {
|
|
266
|
+
//throw new Error(`Bad path: ${dirPath}: ${localCheck.details}`);
|
|
267
|
+
return {
|
|
268
|
+
status: localCheck.status,
|
|
269
|
+
details: `${dirPath}: ${localCheck.details}`,
|
|
270
|
+
type: null,
|
|
271
|
+
};
|
|
272
|
+
} else {
|
|
273
|
+
return {
|
|
274
|
+
status: true,
|
|
275
|
+
details: 'access OK',
|
|
276
|
+
type: null,
|
|
277
|
+
code: 0,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return { status, details, type };
|
|
174
282
|
}
|
|
175
283
|
|
|
176
284
|
async function normalizeRemotePath(client, aPath) {
|
|
177
285
|
try {
|
|
178
286
|
if (aPath.startsWith('..')) {
|
|
179
287
|
let root = await client.realPath('..');
|
|
180
|
-
return root + client.remotePathSep + aPath.
|
|
288
|
+
return root + client.remotePathSep + aPath.slice(3);
|
|
181
289
|
} else if (aPath.startsWith('.')) {
|
|
182
290
|
let root = await client.realPath('.');
|
|
183
|
-
return root + client.remotePathSep + aPath.
|
|
291
|
+
return root + client.remotePathSep + aPath.slice(2);
|
|
184
292
|
}
|
|
185
293
|
return aPath;
|
|
186
294
|
} catch (err) {
|
|
@@ -234,8 +342,10 @@ module.exports = {
|
|
|
234
342
|
closeListener,
|
|
235
343
|
addTempListeners,
|
|
236
344
|
removeTempListeners,
|
|
237
|
-
|
|
345
|
+
haveLocalAccess,
|
|
346
|
+
haveLocalCreate,
|
|
238
347
|
normalizeRemotePath,
|
|
348
|
+
localExists,
|
|
239
349
|
haveConnection,
|
|
240
350
|
sleep,
|
|
241
351
|
};
|
package/CHANGELOG.org
DELETED
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
* Change Logging
|
|
2
|
-
|
|
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
|
|
11
|
-
- Fix issue with connect retry not releasing 'ready' listeners
|
|
12
|
-
- Add finally clauses to all promises to ensure temporary listeners are deleted
|
|
13
|
-
- Add nyc module to report on code test coverage
|
|
14
|
-
- Add additional utils tests to increase test coverage
|
|
15
|
-
- Removed some dead code and unused utility functions to reduce download size
|
|
16
|
-
- Cleanup tests and reduce inter-test dependencies
|
|
17
|
-
|
|
18
|
-
** V6.0.0.0
|
|
19
|
-
- Update connection retry code to use the promise-retry module instead of
|
|
20
|
-
plain rety module
|
|
21
|
-
- Added optional filter argument for uploadDir/downlDir to select which files
|
|
22
|
-
and directories are included
|
|
23
|
-
- Added an optional boolean argument to delete to turn off raising an error
|
|
24
|
-
when delete target does not exists
|
|
25
|
-
- Reduced/simplified argument verification code to reduce package size and
|
|
26
|
-
increase performance
|
|
27
|
-
- Refactored handling of events and add default close and error listeners to
|
|
28
|
-
catch connections closed abruptly without an error being raised.
|
|
29
|
-
|
|
30
|
-
** V5.3.2
|
|
31
|
-
- Minor README typo fixes
|
|
32
|
-
- Fix error in local file path checks (#294)
|
|
33
|
-
|
|
34
|
-
** V5.3.1
|
|
35
|
-
- Fix bug in handling of relative local paths
|
|
36
|
-
- Change handling of stream closures in ~get()~ and ~put()~ methods
|
|
37
|
-
|
|
38
|
-
** v5.3.0
|
|
39
|
-
- Refine event handler management
|
|
40
|
-
- Fix path processing for win32 based sftp servers
|
|
41
|
-
- Update documentation
|
|
42
|
-
** v5.2.2
|
|
43
|
-
- Bug fix release. Add error code 4 check to stat() method.
|
|
44
|
-
- bump Mocha version for tests
|
|
45
|
-
|
|
46
|
-
** v5.2.1
|
|
47
|
-
- Move some dependencies into dev-Dependencies
|
|
48
|
-
** v5.2.0
|
|
49
|
-
- Add new method posixRename() which uses the openSSH POSIX rename extension.
|
|
50
|
-
** v5.1.3
|
|
51
|
-
- Fix bug when writing to root directory and failure due to not being able to
|
|
52
|
-
determine parent
|
|
53
|
-
- Refactor some tests to eliminate need to have artificial delays between
|
|
54
|
-
tests
|
|
55
|
-
- Bumped some dependency versions to latest version
|
|
56
|
-
** v5.1.2
|
|
57
|
-
- Added back global close handler
|
|
58
|
-
- Added dumpListeners() method
|
|
59
|
-
|
|
60
|
-
** v5.1.1
|
|
61
|
-
- Added separate close handlers to each method.
|
|
62
|
-
- Added missing return statement in connect method
|
|
63
|
-
- Added additional troubleshooting documentation for
|
|
64
|
-
common errors.
|
|
65
|
-
|
|
66
|
-
** v5.1.0
|
|
67
|
-
- Fix bug in checkRemotePath() relating to handling of badly
|
|
68
|
-
specified paths (issue #213)
|
|
69
|
-
- Added additional debugging support
|
|
70
|
-
- Add missing test for valid connection in end() method.
|
|
71
|
-
- Bump ssh2 version to v0.8.8
|
|
72
|
-
|
|
73
|
-
** v5.0.2
|
|
74
|
-
- Fix bugs related to win32 platform and local tests for valid directories
|
|
75
|
-
- Fix problem with parsing of file paths
|
|
76
|
-
|
|
77
|
-
** v5.0.1
|
|
78
|
-
- Turn down error checking to be less stringent and handle situations
|
|
79
|
-
where user does not have read permission on parent directory.
|
|
80
|
-
|
|
81
|
-
** v5.0.0
|
|
82
|
-
- Added two new methods ~uploadDir()~ and ~downloadDir()~
|
|
83
|
-
- Removed deprecated ~auxList()~ method
|
|
84
|
-
- Improved error message consistency
|
|
85
|
-
- Added additional error checking to enable more accurate and useful error
|
|
86
|
-
messages.
|
|
87
|
-
- Added default error handler to deal with event errors which fire outside of
|
|
88
|
-
active SftpClient methods (i.e. connection unexpectedly reset by remote host).
|
|
89
|
-
- Modified event handlers to ensure that only event handlers added by the
|
|
90
|
-
module are removed by the module (users now responsible for removing any
|
|
91
|
-
custom event handlers they add).
|
|
92
|
-
- Module error handlers added using ~prependListener~ to ensure they are
|
|
93
|
-
called before any additional custom handlers added by client code.
|
|
94
|
-
- Any error events fired during an ~end()~ call are now ignored.
|
|
95
|
-
|
|
96
|
-
** v4.3.1
|
|
97
|
-
- Updated end() method to resolve once close event fires
|
|
98
|
-
- Added errorListener to error event in each promise to catch error events
|
|
99
|
-
and reject the promise. This should resolve the issue of some error events
|
|
100
|
-
causing uncaughtException erros and causing the process to exit.
|
|
101
|
-
|
|
102
|
-
** v4.3.0
|
|
103
|
-
- Ensure errors include an err.code property and pass through the error code
|
|
104
|
-
from the originating error
|
|
105
|
-
- Change tests for error type to use ~error.code~ instead of matching on
|
|
106
|
-
~error.message~.
|
|
107
|
-
|
|
108
|
-
** v4.2.4
|
|
109
|
-
- Bumped ssh2 to v0.8.6
|
|
110
|
-
- Added exists() usage example to examples directory
|
|
111
|
-
- Clarify documentation on get() method
|
|
112
|
-
** v4.2.3
|
|
113
|
-
- Fix bug in ~exist()~ where tests on root directory returned false
|
|
114
|
-
- Minor documentation fixes
|
|
115
|
-
- Clean up mkdir example
|
|
116
|
-
|
|
117
|
-
** v4.2.2
|
|
118
|
-
- Minor documentation fixes
|
|
119
|
-
- Added additional examples in the ~example~ directory
|
|
120
|
-
|
|
121
|
-
** v4.2.1
|
|
122
|
-
- Remove default close listener. changes in ssh2 API removed the utility of a
|
|
123
|
-
default close listener
|
|
124
|
-
- Fix path handling. Under mixed environments (where client platform and
|
|
125
|
-
server platform were different i.e. one windows the other unix), path
|
|
126
|
-
handling was broken due tot he use of path.join().
|
|
127
|
-
- Ensure error messages include path details. Instead of errors such as "No
|
|
128
|
-
such file" now report "No such file /path/to/missing/file" to help with
|
|
129
|
-
debugging
|
|
130
|
-
|
|
131
|
-
** v4.2.0
|
|
132
|
-
- Work-around for SSH2 =end= event bug
|
|
133
|
-
- Added ability to set client name in constructor method
|
|
134
|
-
- Added additional error checking to prevent ~connect()~ being called on
|
|
135
|
-
already connected client
|
|
136
|
-
- Added additional examples in =example= directory
|
|
137
|
-
|
|
138
|
-
** v4.1.0
|
|
139
|
-
- move ~end()~ call to resolve into close hook
|
|
140
|
-
- Prevent ~put()~ and ~get()~ from creating empty files in destination when
|
|
141
|
-
unable to read source
|
|
142
|
-
- Expand tests for operations when lacking required permissions
|
|
143
|
-
- Add additional data checks for ~append()~
|
|
144
|
-
- Verify file exists
|
|
145
|
-
- Verify file is writeable
|
|
146
|
-
- Verify file is a regular file
|
|
147
|
-
- Fix handling of relative paths
|
|
148
|
-
- Add ~realPath()~ method
|
|
149
|
-
- Add ~cwd()~ method
|
|
150
|
-
|
|
151
|
-
** v4.0.4
|
|
152
|
-
- Minor documentation fix
|
|
153
|
-
- Fix return value from ~get()~
|
|
154
|
-
|
|
155
|
-
** v4.0.3
|
|
156
|
-
- Fix bug in mkdir() relating to handling of relative paths
|
|
157
|
-
- Modify exists() to always return 'd' if path is '.'
|
|
158
|
-
|
|
159
|
-
** v4.0.2
|
|
160
|
-
- Fix some minor packaging issues
|
|
161
|
-
|
|
162
|
-
** v4.0.0
|
|
163
|
-
- Remove support for node < 8.x
|
|
164
|
-
- Fix connection retry feature
|
|
165
|
-
- sftp connection object set to null when 'end' signal is raised
|
|
166
|
-
- Removed 'connectMethod' argument from connect method.
|
|
167
|
-
- Refined adding/removing of listeners in connect() and end() methods to enable
|
|
168
|
-
errors to be adequately caught and reported.
|
|
169
|
-
- Deprecate auxList() and add pattern/regexp filter option to list()
|
|
170
|
-
- Refactored handling of event signals to provide better feedback to clients
|
|
171
|
-
- Removed pointless 'permissions' property from objects returned by ~stat()~
|
|
172
|
-
(same as mode property). Added additional properties describing the type of
|
|
173
|
-
object.
|
|
174
|
-
- Added the ~removeListener()~ method to compliment the existing ~on()~ method.
|
|
175
|
-
|
|
176
|
-
** Older Versions
|
|
177
|
-
*** v2.5.2
|
|
178
|
-
- Repository transferred to theophilusx
|
|
179
|
-
- Fix error in package.json pointing to wrong repository
|
|
180
|
-
|
|
181
|
-
*** v2.5.1
|
|
182
|
-
- Apply 4 pull requests to address minor issues prior to transfer
|
|
183
|
-
|
|
184
|
-
*** v2.5.0
|
|
185
|
-
- ???
|
|
186
|
-
|
|
187
|
-
*** v2.4.3
|
|
188
|
-
- merge #108, #110
|
|
189
|
-
- fix connect promise if connection ends
|
|
190
|
-
|
|
191
|
-
*** v2.4.2
|
|
192
|
-
- merge #105
|
|
193
|
-
- fix windows path
|
|
194
|
-
|
|
195
|
-
*** v2.4.1
|
|
196
|
-
- merge pr #99, #100
|
|
197
|
-
- bug fix
|
|
198
|
-
|
|
199
|
-
*** v2.4.0
|
|
200
|
-
- Requires node.js v7.5.0 or above.
|
|
201
|
-
- merge pr #97, thanks for @theophilusx
|
|
202
|
-
- Remove emitter.maxListener warnings
|
|
203
|
-
- Upgraded ssh2 dependency from 0.5.5 to 0.6.1
|
|
204
|
-
- Enhanced error messages to provide more context and to be more consistent
|
|
205
|
-
- re-factored test
|
|
206
|
-
- Added new 'exists' method and re-factored mkdir/rmdir
|
|
207
|
-
|
|
208
|
-
*** v2.3.0
|
|
209
|
-
- add: ~stat~ method
|
|
210
|
-
- add ~fastGet~ and ~fastPut~ method.
|
|
211
|
-
- fix: ~mkdir~ file exists decision logic
|
|
212
|
-
|
|
213
|
-
*** v3.0.0 -- deprecate this version
|
|
214
|
-
- change: ~sftp.get~ will return chunk not stream anymore
|
|
215
|
-
- fix: get readable not emitting data events in node 10.0.0
|
|
216
|
-
|
|
217
|
-
*** v2.1.1
|
|
218
|
-
- add: event listener. [[https://github.com/jyu213/ssh2-sftp-client#Event][doc]]
|
|
219
|
-
- add: ~get~ or ~put~ method add extra options [[https://github.com/jyu213/ssh2-sftp-client/pull/52][pr#52]]
|
|
220
|
-
|
|
221
|
-
*** v2.0.1
|
|
222
|
-
- add: ~chmod~ method [[https://github.com/jyu213/ssh2-sftp-client/pull/33][pr#33]]
|
|
223
|
-
- update: upgrade ssh2 to V0.5.0 [[https://github.com/jyu213/ssh2-sftp-client/pull/30][pr#30]]
|
|
224
|
-
- fix: get method stream error reject unwork [[https://github.com/jyu213/ssh2-sftp-client/issues/22][#22]]
|
|
225
|
-
- fix: return Error object on promise rejection [[https://github.com/jyu213/ssh2-sftp-client/pull/20][pr#20]]
|
|
226
|
-
|
|
227
|
-
*** v1.1.0
|
|
228
|
-
- fix: add encoding control support for binary stream
|
|
229
|
-
|
|
230
|
-
*** v1.0.5:
|
|
231
|
-
- fix: multi image upload
|
|
232
|
-
- change: remove ~this.client.sftp~ to ~connect~ function
|