ssh2-sftp-client 8.0.0 → 9.0.1
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 +348 -125
- package/README.org +138 -52
- package/package.json +9 -5
- package/src/constants.js +1 -0
- package/src/index.js +888 -657
- package/src/utils.js +43 -106
package/src/utils.js
CHANGED
|
@@ -1,63 +1,7 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
1
|
const fs = require('fs');
|
|
4
2
|
const path = require('path');
|
|
5
|
-
|
|
6
3
|
const { errorCode } = require('./constants');
|
|
7
4
|
|
|
8
|
-
/**
|
|
9
|
-
* Generate a new Error object with a reformatted error message which
|
|
10
|
-
* is a little more informative and useful to users.
|
|
11
|
-
*
|
|
12
|
-
* @param {Error|string} err - The Error object the new error will be based on
|
|
13
|
-
* @param {number} retryCount - For those functions which use retry. Number of
|
|
14
|
-
* attempts to complete before giving up
|
|
15
|
-
* @returns {Error} New error with custom error message
|
|
16
|
-
*/
|
|
17
|
-
function fmtError(err, name = 'sftp', eCode, retryCount) {
|
|
18
|
-
let msg = '';
|
|
19
|
-
let code = '';
|
|
20
|
-
let retry = retryCount
|
|
21
|
-
? ` after ${retryCount} ${retryCount > 1 ? 'attempts' : 'attempt'}`
|
|
22
|
-
: '';
|
|
23
|
-
|
|
24
|
-
if (err === undefined) {
|
|
25
|
-
msg = `${name}: Undefined error - probably a bug!`;
|
|
26
|
-
code = errorCode.generic;
|
|
27
|
-
} else if (typeof err === 'string') {
|
|
28
|
-
msg = `${name}: ${err}${retry}`;
|
|
29
|
-
code = eCode ? eCode : errorCode.generic;
|
|
30
|
-
} else if (err.custom) {
|
|
31
|
-
msg = `${name}->${err.message}${retry}`;
|
|
32
|
-
code = err.code;
|
|
33
|
-
} else {
|
|
34
|
-
switch (err.code) {
|
|
35
|
-
case 'ENOTFOUND':
|
|
36
|
-
msg =
|
|
37
|
-
`${name}: ${err.level} error. ` +
|
|
38
|
-
`Address lookup failed for host ${err.hostname}${retry}`;
|
|
39
|
-
break;
|
|
40
|
-
case 'ECONNREFUSED':
|
|
41
|
-
msg =
|
|
42
|
-
`${name}: ${err.level} error. Remote host at ` +
|
|
43
|
-
`${err.address} refused connection${retry}`;
|
|
44
|
-
break;
|
|
45
|
-
case 'ECONNRESET':
|
|
46
|
-
msg =
|
|
47
|
-
`${name}: Remote host has reset the connection: ` +
|
|
48
|
-
`${err.message}${retry}`;
|
|
49
|
-
break;
|
|
50
|
-
default:
|
|
51
|
-
msg = `${name}: ${err.message}${retry}`;
|
|
52
|
-
}
|
|
53
|
-
code = err.code ? err.code : errorCode.generic;
|
|
54
|
-
}
|
|
55
|
-
let newError = new Error(msg);
|
|
56
|
-
newError.code = code;
|
|
57
|
-
newError.custom = true;
|
|
58
|
-
return newError;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
5
|
/**
|
|
62
6
|
* Simple default error listener. Will reformat the error message and
|
|
63
7
|
* throw a new error.
|
|
@@ -68,17 +12,16 @@ function fmtError(err, name = 'sftp', eCode, retryCount) {
|
|
|
68
12
|
function errorListener(client, name, reject) {
|
|
69
13
|
let fn = (err) => {
|
|
70
14
|
if (client.endCalled || client.errorHandled) {
|
|
71
|
-
|
|
15
|
+
// error already handled or expected - ignore
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
client.errorHandled = true;
|
|
19
|
+
let newError = new Error(`${name}: ${err.message}`);
|
|
20
|
+
newError.code = err.code;
|
|
21
|
+
if (reject) {
|
|
22
|
+
reject(newError);
|
|
72
23
|
} else {
|
|
73
|
-
|
|
74
|
-
client.errorHandled = true;
|
|
75
|
-
if (reject) {
|
|
76
|
-
client.debugMsg(`${name} Error: handled error with reject`);
|
|
77
|
-
reject(fmtError(err, name, err.code));
|
|
78
|
-
} else {
|
|
79
|
-
client.debugMsg(`${name} Error: handling error with throw`);
|
|
80
|
-
throw fmtError(err, name, err.code);
|
|
81
|
-
}
|
|
24
|
+
throw newError;
|
|
82
25
|
}
|
|
83
26
|
};
|
|
84
27
|
return fn;
|
|
@@ -87,18 +30,16 @@ function errorListener(client, name, reject) {
|
|
|
87
30
|
function endListener(client, name, reject) {
|
|
88
31
|
let fn = function () {
|
|
89
32
|
if (client.endCalled || client.endHandled) {
|
|
90
|
-
|
|
33
|
+
// end event already handled - ignore
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
client.sftp = undefined;
|
|
37
|
+
client.endHandled = true;
|
|
38
|
+
let err = new Error(`${name} Unexpected end event raised`);
|
|
39
|
+
if (reject) {
|
|
40
|
+
reject(err);
|
|
91
41
|
} else {
|
|
92
|
-
|
|
93
|
-
client.sftp = undefined;
|
|
94
|
-
client.endHandled = true;
|
|
95
|
-
if (reject) {
|
|
96
|
-
client.debugMsg(`${name} End: handling end event with reject'`);
|
|
97
|
-
reject(fmtError('Unexpected end event raised', name));
|
|
98
|
-
} else {
|
|
99
|
-
client.debugMsg(`${name} End: handling end event with throw`);
|
|
100
|
-
throw fmtError('Unexpected end event raised', name);
|
|
101
|
-
}
|
|
42
|
+
throw err;
|
|
102
43
|
}
|
|
103
44
|
};
|
|
104
45
|
return fn;
|
|
@@ -107,18 +48,16 @@ function endListener(client, name, reject) {
|
|
|
107
48
|
function closeListener(client, name, reject) {
|
|
108
49
|
let fn = function () {
|
|
109
50
|
if (client.endCalled || client.closeHandled) {
|
|
110
|
-
|
|
51
|
+
// handled or expected close event - ignore
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
client.sftp = undefined;
|
|
55
|
+
client.closeHandled = true;
|
|
56
|
+
let err = new Error(`${name}: Unexpected close event raised`);
|
|
57
|
+
if (reject) {
|
|
58
|
+
reject(err);
|
|
111
59
|
} else {
|
|
112
|
-
|
|
113
|
-
client.sftp = undefined;
|
|
114
|
-
client.closeHandled = true;
|
|
115
|
-
if (reject) {
|
|
116
|
-
client.debugMsg(`${name} Close: handling close event with reject`);
|
|
117
|
-
reject(fmtError('Unexpected close event raised', name));
|
|
118
|
-
} else {
|
|
119
|
-
client.debugMsg(`${name} Close: handling close event with throw`);
|
|
120
|
-
throw fmtError('Unexpected close event raised', name);
|
|
121
|
-
}
|
|
60
|
+
throw err;
|
|
122
61
|
}
|
|
123
62
|
};
|
|
124
63
|
return fn;
|
|
@@ -130,7 +69,6 @@ function addTempListeners(client, name, reject) {
|
|
|
130
69
|
close: closeListener(client, name, reject),
|
|
131
70
|
error: errorListener(client, name, reject),
|
|
132
71
|
};
|
|
133
|
-
client.debugMsg(`${name}: Adding temp event listeners`);
|
|
134
72
|
client.on('end', listeners.end);
|
|
135
73
|
client.on('close', listeners.close);
|
|
136
74
|
client.on('error', listeners.error);
|
|
@@ -138,10 +76,13 @@ function addTempListeners(client, name, reject) {
|
|
|
138
76
|
}
|
|
139
77
|
|
|
140
78
|
function removeTempListeners(client, listeners, name) {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
79
|
+
try {
|
|
80
|
+
client.removeListener('end', listeners.end);
|
|
81
|
+
client.removeListener('close', listeners.close);
|
|
82
|
+
client.removeListener('error', listeners.error);
|
|
83
|
+
} catch (err) {
|
|
84
|
+
throw new Error(`${name}: Error removing temp listeners: ${err.message}`);
|
|
85
|
+
}
|
|
145
86
|
}
|
|
146
87
|
|
|
147
88
|
/**
|
|
@@ -165,11 +106,11 @@ function localExists(filePath) {
|
|
|
165
106
|
} else if (stats.isFile()) {
|
|
166
107
|
return '-';
|
|
167
108
|
} else {
|
|
168
|
-
|
|
169
|
-
`Bad path: ${filePath}: target must be a file or directory
|
|
170
|
-
'localExists',
|
|
171
|
-
errorCode.badPath
|
|
109
|
+
let err = new Error(
|
|
110
|
+
`Bad path: ${filePath}: target must be a file or directory`
|
|
172
111
|
);
|
|
112
|
+
err.code = errorCode.badPath;
|
|
113
|
+
throw err;
|
|
173
114
|
}
|
|
174
115
|
}
|
|
175
116
|
|
|
@@ -284,15 +225,15 @@ function haveLocalCreate(filePath) {
|
|
|
284
225
|
async function normalizeRemotePath(client, aPath) {
|
|
285
226
|
try {
|
|
286
227
|
if (aPath.startsWith('..')) {
|
|
287
|
-
|
|
228
|
+
const root = await client.realPath('..');
|
|
288
229
|
return root + client.remotePathSep + aPath.slice(3);
|
|
289
230
|
} else if (aPath.startsWith('.')) {
|
|
290
|
-
|
|
231
|
+
const root = await client.realPath('.');
|
|
291
232
|
return root + client.remotePathSep + aPath.slice(2);
|
|
292
233
|
}
|
|
293
234
|
return aPath;
|
|
294
235
|
} catch (err) {
|
|
295
|
-
throw
|
|
236
|
+
throw new Error(`normalizeRemotePath: ${err.message}`);
|
|
296
237
|
}
|
|
297
238
|
}
|
|
298
239
|
|
|
@@ -308,11 +249,8 @@ async function normalizeRemotePath(client, aPath) {
|
|
|
308
249
|
*/
|
|
309
250
|
function haveConnection(client, name, reject) {
|
|
310
251
|
if (!client.sftp) {
|
|
311
|
-
let newError =
|
|
312
|
-
|
|
313
|
-
name,
|
|
314
|
-
errorCode.connect
|
|
315
|
-
);
|
|
252
|
+
let newError = new Error(`${name}: No SFTP connection available`);
|
|
253
|
+
newError.code = errorCode.connect;
|
|
316
254
|
if (reject) {
|
|
317
255
|
reject(newError);
|
|
318
256
|
return false;
|
|
@@ -336,7 +274,6 @@ function sleep(ms) {
|
|
|
336
274
|
}
|
|
337
275
|
|
|
338
276
|
module.exports = {
|
|
339
|
-
fmtError,
|
|
340
277
|
errorListener,
|
|
341
278
|
endListener,
|
|
342
279
|
closeListener,
|