ssh2-sftp-client 7.0.3 → 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 CHANGED
@@ -61,7 +61,7 @@ an SFTP client for node.js, a wrapper around [SSH2](https://github.com/mscdex/ss
61
61
 
62
62
  Documentation on the methods and available options in the underlying modules can be found on the [SSH2](https://github.com/mscdex/ssh2) project pages.
63
63
 
64
- Current stable release is **v7.0.3**.
64
+ Current stable release is **v7.0.4**.
65
65
 
66
66
  Code has been tested against Node versions 12.22.1, 14.17.0 and 16.2.0
67
67
 
package/README.org CHANGED
@@ -9,7 +9,7 @@ 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.0.3*.
12
+ Current stable release is *v7.0.4*.
13
13
 
14
14
  Code has been tested against Node versions 12.22.1, 14.17.0 and 16.2.0
15
15
 
package/package.json CHANGED
@@ -1,17 +1,24 @@
1
1
  {
2
2
  "name": "ssh2-sftp-client",
3
- "version": "7.0.3",
3
+ "version": "7.0.4",
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": ["sftp", "nodejs", "promises"],
10
+ "keywords": [
11
+ "sftp",
12
+ "nodejs",
13
+ "promises"
14
+ ],
11
15
  "scripts": {
12
16
  "test": "mocha",
13
17
  "coverage": "nyc npm run test",
14
- "lint": "eslint \"src/**/*.js\" --quiet"
18
+ "lint": "eslint \"src/**/*.js\" \"test/**/*.js\""
19
+ },
20
+ "engines": {
21
+ "node": ">=10.24.1"
15
22
  },
16
23
  "author": "Tim Cross",
17
24
  "email": "theophilusx@gmail.com",
@@ -25,7 +32,7 @@
25
32
  "dependencies": {
26
33
  "concat-stream": "^2.0.0",
27
34
  "promise-retry": "^2.0.1",
28
- "ssh2": "^1.2.0"
35
+ "ssh2": "^1.4.0"
29
36
  },
30
37
  "devDependencies": {
31
38
  "chai": "^4.2.0",
@@ -33,9 +40,16 @@
33
40
  "chai-subset": "^1.6.0",
34
41
  "checksum": "^1.0.0",
35
42
  "dotenv": "^10.0.0",
43
+ "eslint": "^7.32.0",
44
+ "eslint-config-prettier": "^8.3.0",
45
+ "eslint-plugin-mocha": "^9.0.0",
46
+ "eslint-plugin-node": "^11.1.0",
47
+ "eslint-plugin-promise": "^5.1.0",
48
+ "eslint-plugin-unicorn": "^35.0.0",
36
49
  "mocha": "^9.0.2",
37
50
  "moment": "^2.29.1",
38
51
  "nyc": "^15.1.0",
52
+ "prettier": "^2.3.2",
39
53
  "through2": "^4.0.2",
40
54
  "winston": "^3.3.3"
41
55
  }
package/src/constants.js CHANGED
@@ -1,12 +1,10 @@
1
- 'use strict';
2
-
3
1
  const errorCode = {
4
2
  generic: 'ERR_GENERIC_CLIENT',
5
3
  connect: 'ERR_NOT_CONNECTED',
6
4
  badPath: 'ERR_BAD_PATH',
7
5
  permission: 'EACCES',
8
6
  notexist: 'ENOENT',
9
- notdir: 'ENOTDIR'
7
+ notdir: 'ENOTDIR',
10
8
  };
11
9
 
12
10
  const targetType = {
@@ -15,10 +13,10 @@ const targetType = {
15
13
  writeDir: 3,
16
14
  readDir: 4,
17
15
  readObj: 5,
18
- writeObj: 6
16
+ writeObj: 6,
19
17
  };
20
18
 
21
19
  module.exports = {
22
20
  errorCode,
23
- targetType
21
+ targetType,
24
22
  };
package/src/index.js CHANGED
@@ -133,13 +133,12 @@ class SftpClient {
133
133
  // .catch((err) => {
134
134
  // return Promise.reject(err);
135
135
  // })
136
- .finally(async (resp) => {
136
+ .finally(async () => {
137
137
  this.debugMsg('getConnection: finally clause fired');
138
138
  await sleep(500);
139
139
  this.removeListener('ready', doReady);
140
140
  removeTempListeners(this, 'getConnection');
141
141
  this._resetEventFlags();
142
- return resp;
143
142
  })
144
143
  );
145
144
  }
@@ -158,7 +157,7 @@ class SftpClient {
158
157
  resolve(sftp);
159
158
  }
160
159
  });
161
- }).finally((resp) => {
160
+ }).finally(() => {
162
161
  this.debugMsg('getSftpChannel: finally clause fired');
163
162
  removeTempListeners(this, 'getSftpChannel');
164
163
  this._resetEventFlags();
@@ -244,10 +243,9 @@ class SftpClient {
244
243
  resolve(absPath);
245
244
  });
246
245
  }
247
- }).finally((rsp) => {
246
+ }).finally(() => {
248
247
  removeTempListeners(this, 'realPath');
249
248
  this._resetEventFlags();
250
- return rsp;
251
249
  });
252
250
  }
253
251
 
@@ -302,9 +300,8 @@ class SftpClient {
302
300
  resolve(result);
303
301
  }
304
302
  });
305
- }).finally((rsp) => {
303
+ }).finally(() => {
306
304
  removeTempListeners(this, 'stat');
307
- return rsp;
308
305
  });
309
306
  };
310
307
 
@@ -404,15 +401,15 @@ class SftpClient {
404
401
  if (fileList) {
405
402
  newList = fileList.map((item) => {
406
403
  return {
407
- type: item.longname.substr(0, 1),
404
+ type: item.longname.slice(0, 1),
408
405
  name: item.filename,
409
406
  size: item.attrs.size,
410
407
  modifyTime: item.attrs.mtime * 1000,
411
408
  accessTime: item.attrs.atime * 1000,
412
409
  rights: {
413
- user: item.longname.substr(1, 3).replace(reg, ''),
414
- group: item.longname.substr(4, 3).replace(reg, ''),
415
- other: item.longname.substr(7, 3).replace(reg, ''),
410
+ user: item.longname.slice(1, 4).replace(reg, ''),
411
+ group: item.longname.slice(4, 7).replace(reg, ''),
412
+ other: item.longname.slice(7, 10).replace(reg, ''),
416
413
  },
417
414
  owner: item.attrs.uid,
418
415
  group: item.attrs.gid,
@@ -433,10 +430,9 @@ class SftpClient {
433
430
  }
434
431
  });
435
432
  }
436
- }).finally((rsp) => {
433
+ }).finally(() => {
437
434
  removeTempListeners(this, 'list');
438
435
  this._resetEventFlags();
439
- return rsp;
440
436
  });
441
437
  }
442
438
 
@@ -521,7 +517,7 @@ class SftpClient {
521
517
  }
522
518
  rdr.pipe(wtr, options.pipeOptions ? options.pipeOptions : {});
523
519
  }
524
- }).finally((rsp) => {
520
+ }).finally(() => {
525
521
  removeTempListeners(this, 'get');
526
522
  this._resetEventFlags();
527
523
  if (
@@ -539,7 +535,6 @@ class SftpClient {
539
535
  ) {
540
536
  wtr.destroy();
541
537
  }
542
- return rsp;
543
538
  });
544
539
  }
545
540
 
@@ -589,9 +584,8 @@ class SftpClient {
589
584
  resolve(`${remotePath} was successfully download to ${localPath}!`);
590
585
  });
591
586
  }
592
- }).finally((rsp) => {
587
+ }).finally(() => {
593
588
  removeTempListeners(this, 'fastGet');
594
- return rsp;
595
589
  });
596
590
  } catch (err) {
597
591
  this._resetEventFlags();
@@ -654,10 +648,9 @@ class SftpClient {
654
648
  resolve(`${localPath} was successfully uploaded to ${remotePath}!`);
655
649
  });
656
650
  }
657
- }).finally((rsp) => {
651
+ }).finally(() => {
658
652
  removeTempListeners(this, 'fastPut');
659
653
  this._resetEventFlags();
660
- return rsp;
661
654
  });
662
655
  }
663
656
 
@@ -737,7 +730,7 @@ class SftpClient {
737
730
  rdr.pipe(wtr, options.pipeOptions ? options.pipeOptions : {});
738
731
  }
739
732
  }
740
- }).finally((resp) => {
733
+ }).finally(() => {
741
734
  removeTempListeners(this, 'put');
742
735
  this._resetEventFlags();
743
736
  if (
@@ -755,7 +748,6 @@ class SftpClient {
755
748
  ) {
756
749
  wtr.destroy();
757
750
  }
758
- return resp;
759
751
  });
760
752
  }
761
753
 
@@ -767,47 +759,44 @@ class SftpClient {
767
759
  * @param {Object} options
768
760
  * @return {Promise}
769
761
  */
770
- append(input, remotePath, options = {}) {
771
- return this.exists(remotePath).then((fileType) => {
772
- if (fileType && fileType === 'd') {
773
- return Promise.reject(
774
- fmtError(
775
- `Bad path: ${remotePath}: cannot append to a directory`,
776
- 'append',
777
- errorCode.badPath
778
- )
779
- );
780
- }
781
- return new Promise((resolve, reject) => {
782
- if (haveConnection(this, 'append', reject)) {
783
- if (typeof input === 'string') {
784
- reject(fmtError('Cannot append one file to another', 'append'));
762
+
763
+ async append(input, remotePath, options = {}) {
764
+ const fileType = await this.exists(remotePath);
765
+ if (fileType && fileType === 'd') {
766
+ throw fmtError(
767
+ `Bad path: ${remotePath}: cannot append to a directory`,
768
+ 'append',
769
+ errorCode.badPath
770
+ );
771
+ }
772
+ return await new Promise((resolve, reject) => {
773
+ if (haveConnection(this, 'append', reject)) {
774
+ if (typeof input === 'string') {
775
+ reject(fmtError('Cannot append one file to another', 'append'));
776
+ } else {
777
+ this.debugMsg(`append -> remote: ${remotePath} `, options);
778
+ addTempListeners(this, 'append', reject);
779
+ options.flags = 'a';
780
+ let stream = this.sftp.createWriteStream(remotePath, options);
781
+ stream.on('error', (err_1) => {
782
+ reject(
783
+ fmtError(`${err_1.message} ${remotePath}`, 'append', err_1.code)
784
+ );
785
+ });
786
+ stream.on('finish', () => {
787
+ resolve(`Appended data to ${remotePath}`);
788
+ });
789
+ if (input instanceof Buffer) {
790
+ stream.write(input);
791
+ stream.end();
785
792
  } else {
786
- this.debugMsg(`append -> remote: ${remotePath} `, options);
787
- addTempListeners(this, 'append', reject);
788
- options.flags = 'a';
789
- let stream = this.sftp.createWriteStream(remotePath, options);
790
- stream.on('error', (err) => {
791
- reject(
792
- fmtError(`${err.message} ${remotePath}`, 'append', err.code)
793
- );
794
- });
795
- stream.on('finish', () => {
796
- resolve(`Appended data to ${remotePath}`);
797
- });
798
- if (input instanceof Buffer) {
799
- stream.write(input);
800
- stream.end();
801
- } else {
802
- input.pipe(stream);
803
- }
793
+ input.pipe(stream);
804
794
  }
805
795
  }
806
- }).finally((rsp) => {
807
- removeTempListeners(this, 'append');
808
- this._resetEventFlags();
809
- return rsp;
810
- });
796
+ }
797
+ }).finally(() => {
798
+ removeTempListeners(this, 'append');
799
+ this._resetEventFlags();
811
800
  });
812
801
  }
813
802
 
@@ -847,10 +836,9 @@ class SftpClient {
847
836
  resolve(`${p} directory created`);
848
837
  }
849
838
  });
850
- }).finally((rsp) => {
839
+ }).finally(() => {
851
840
  removeTempListeners(this, '_mkdir');
852
841
  this._resetEventFlags();
853
- return rsp;
854
842
  });
855
843
  };
856
844
 
@@ -899,9 +887,8 @@ class SftpClient {
899
887
  }
900
888
  resolve('Successfully removed directory');
901
889
  });
902
- }).finally((rsp) => {
890
+ }).finally(() => {
903
891
  removeTempListeners(this, 'rmdir');
904
- return rsp;
905
892
  });
906
893
  };
907
894
 
@@ -962,10 +949,9 @@ class SftpClient {
962
949
  resolve(`Successfully deleted ${remotePath}`);
963
950
  });
964
951
  }
965
- }).finally((rsp) => {
952
+ }).finally(() => {
966
953
  removeTempListeners(this, 'delete');
967
954
  this._resetEventFlags();
968
- return rsp;
969
955
  });
970
956
  }
971
957
 
@@ -999,10 +985,9 @@ class SftpClient {
999
985
  resolve(`Successfully renamed ${fromPath} to ${toPath}`);
1000
986
  });
1001
987
  }
1002
- }).finally((rsp) => {
988
+ }).finally(() => {
1003
989
  removeTempListeners(this, 'rename');
1004
990
  this._resetEventFlags();
1005
- return rsp;
1006
991
  });
1007
992
  }
1008
993
 
@@ -1037,10 +1022,9 @@ class SftpClient {
1037
1022
  resolve(`Successful POSIX rename ${fromPath} to ${toPath}`);
1038
1023
  });
1039
1024
  }
1040
- }).finally((rsp) => {
1025
+ }).finally(() => {
1041
1026
  removeTempListeners(this, 'posixRename');
1042
1027
  this._resetEventFlags();
1043
- return rsp;
1044
1028
  });
1045
1029
  }
1046
1030
 
@@ -1064,10 +1048,9 @@ class SftpClient {
1064
1048
  }
1065
1049
  resolve('Successfully change file mode');
1066
1050
  });
1067
- }).finally((rsp) => {
1051
+ }).finally(() => {
1068
1052
  removeTempListeners(this, 'chmod');
1069
1053
  this._resetEventFlags();
1070
- return rsp;
1071
1054
  });
1072
1055
  }
1073
1056
 
@@ -1209,13 +1192,12 @@ class SftpClient {
1209
1192
  this.debugMsg('end: Have connection - calling end()');
1210
1193
  this.client.end();
1211
1194
  }
1212
- }).finally((resp) => {
1195
+ }).finally(() => {
1213
1196
  this.debugMsg('end: finally clause fired');
1214
1197
  removeTempListeners(this, 'end');
1215
1198
  this.removeListener('close', endCloseHandler);
1216
1199
  this.endCalled = false;
1217
1200
  this._resetEventFlags();
1218
- return resp;
1219
1201
  });
1220
1202
  }
1221
1203
  }
package/src/utils.js CHANGED
@@ -203,29 +203,33 @@ function haveLocalAccess(filePath, mode = 'r') {
203
203
  code: 0,
204
204
  };
205
205
  } catch (err) {
206
- if (err.errno === -2) {
207
- return {
208
- status: false,
209
- type: null,
210
- details: 'not exist',
211
- code: -2,
212
- };
213
- } else if (err.errno === -13) {
214
- const type = localExists(filePath);
215
- return {
216
- status: false,
217
- type: type,
218
- details: 'permission denied',
219
- code: -13,
220
- };
221
- } else if (err.errno === -20) {
222
- return {
223
- status: false,
224
- type: null,
225
- details: 'parent not a directory',
226
- };
227
- } else {
228
- throw 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
+ };
229
233
  }
230
234
  }
231
235
  }
@@ -281,10 +285,10 @@ async function normalizeRemotePath(client, aPath) {
281
285
  try {
282
286
  if (aPath.startsWith('..')) {
283
287
  let root = await client.realPath('..');
284
- return root + client.remotePathSep + aPath.substring(3);
288
+ return root + client.remotePathSep + aPath.slice(3);
285
289
  } else if (aPath.startsWith('.')) {
286
290
  let root = await client.realPath('.');
287
- return root + client.remotePathSep + aPath.substring(2);
291
+ return root + client.remotePathSep + aPath.slice(2);
288
292
  }
289
293
  return aPath;
290
294
  } catch (err) {