utils.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. "use strict";
  2. var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
  3. function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
  4. return new (P || (P = Promise))(function (resolve, reject) {
  5. function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
  6. function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
  7. function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
  8. step((generator = generator.apply(thisArg, _arguments || [])).next());
  9. });
  10. };
  11. var __generator = (this && this.__generator) || function (thisArg, body) {
  12. var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
  13. return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
  14. function verb(n) { return function (v) { return step([n, v]); }; }
  15. function step(op) {
  16. if (f) throw new TypeError("Generator is already executing.");
  17. while (_) try {
  18. if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
  19. if (y = 0, t) op = [op[0] & 2, t.value];
  20. switch (op[0]) {
  21. case 0: case 1: t = op; break;
  22. case 4: _.label++; return { value: op[1], done: false };
  23. case 5: _.label++; y = op[1]; op = [0]; continue;
  24. case 7: op = _.ops.pop(); _.trys.pop(); continue;
  25. default:
  26. if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
  27. if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
  28. if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
  29. if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
  30. if (t[2]) _.ops.pop();
  31. _.trys.pop(); continue;
  32. }
  33. op = body.call(thisArg, _);
  34. } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
  35. if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
  36. }
  37. };
  38. var __importDefault = (this && this.__importDefault) || function (mod) {
  39. return (mod && mod.__esModule) ? mod : { "default": mod };
  40. };
  41. Object.defineProperty(exports, "__esModule", { value: true });
  42. exports.joinRemote = exports.hasListener = exports.dumpListeners = exports.haveConnection = exports.checkRemotePath = exports.checkWriteObject = exports.checkWriteDir = exports.checkWriteFile = exports.checkReadDir = exports.checkReadFile = exports.checkReadObject = exports.normalizeRemotePath = exports.checkLocalPath = exports.checkLocalWriteDir = exports.checkLocalWriteFile = exports.checkLocalReadDir = exports.checkLocalReadFile = exports.localAccess = exports.classifyError = exports.localExists = exports.makeCloseListener = exports.makeEndListener = exports.makeErrorListener = exports.handleError = exports.formatError = void 0;
  43. var fs_1 = __importDefault(require("fs"));
  44. var path_1 = __importDefault(require("path"));
  45. var constant_1 = require("./constant");
  46. var types_1 = require("./types");
  47. /**
  48. * Generate a new Error object with a reformatted error message which
  49. * is a little more informative and useful to users.
  50. *
  51. * @param {Error|string} err - The Error object the new error will be based on
  52. * @param {number} retryCount - For those functions which use retry. Number of
  53. * attempts to complete before giving up
  54. * @returns {Error} New error with custom error message
  55. */
  56. function formatError(err, name, eCode, retryCount) {
  57. if (name === void 0) { name = 'sftp'; }
  58. if (eCode === void 0) { eCode = constant_1.errorCode.generic; }
  59. var msg = '';
  60. var code = '';
  61. var retry = retryCount
  62. ? " after " + retryCount + " " + (retryCount > 1 ? 'attempts' : 'attempt')
  63. : '';
  64. if (err === undefined) {
  65. msg = name + ": Undefined error - probably a bug!";
  66. code = constant_1.errorCode.generic;
  67. }
  68. else if (typeof err === 'string') {
  69. msg = name + ": " + err + retry;
  70. code = eCode;
  71. }
  72. else if (err.custom) {
  73. msg = name + "->" + err.message + retry;
  74. code = err.code;
  75. }
  76. else {
  77. switch (err.code) {
  78. case 'ENOTFOUND':
  79. msg =
  80. name + ": " + err.level + " error. " +
  81. ("Address lookup failed for host " + err.hostname + retry);
  82. break;
  83. case 'ECONNREFUSED':
  84. msg =
  85. name + ": " + err.level + " error. Remote host at " +
  86. (err.address + " refused connection" + retry);
  87. break;
  88. case 'ECONNRESET':
  89. msg =
  90. name + ": Remote host has reset the connection: " +
  91. ("" + err.message + retry);
  92. break;
  93. case 'ENOENT':
  94. msg = name + ": " + err.message + retry;
  95. break;
  96. default:
  97. msg = name + ": " + err.message + retry;
  98. }
  99. code = err.code ? err.code : eCode;
  100. }
  101. var newError = new types_1.ErrorCustom(msg);
  102. newError.code = code;
  103. newError.custom = true;
  104. return newError;
  105. }
  106. exports.formatError = formatError;
  107. /**
  108. * Tests an error to see if it is one which has already been customised
  109. * by this module or not. If not, applies appropriate customisation.
  110. *
  111. * @param {Error} err - an Error object
  112. * @param {String} name - name to be used in customised error message
  113. * @param {Function} reject - If defined, call this function instead of
  114. * throwing the error
  115. * @throws {Error}
  116. */
  117. function handleError(err, name, reject) {
  118. if (reject) {
  119. if (err.custom) {
  120. reject(err);
  121. }
  122. else {
  123. reject(formatError(err, name, undefined, undefined));
  124. }
  125. }
  126. else {
  127. if (err.custom) {
  128. throw err;
  129. }
  130. else {
  131. throw formatError(err, name, undefined, undefined);
  132. }
  133. }
  134. }
  135. exports.handleError = handleError;
  136. /**
  137. * Remove all ready, error and end listeners.
  138. *
  139. * @param {Emitter} emitter - The emitter object to remove listeners from
  140. */
  141. // function removeListeners(emitter) {
  142. // const listeners = emitter.eventNames()
  143. // listeners.forEach((name) => {
  144. // emitter.removeAllListeners(name)
  145. // })
  146. // }
  147. /**
  148. * Simple default error listener. Will reformat the error message and
  149. * throw a new error.
  150. *
  151. * @param {Error} err - source for defining new error
  152. * @throws {Error} Throws new error
  153. */
  154. function makeErrorListener(reject, client, name) {
  155. return function (err) {
  156. client.errorHandled = true;
  157. reject(formatError(err, name));
  158. };
  159. }
  160. exports.makeErrorListener = makeErrorListener;
  161. function makeEndListener(client) {
  162. return function () {
  163. if (!client.endCalled) {
  164. console.error('End Listener: Connection ended unexpectedly');
  165. }
  166. };
  167. }
  168. exports.makeEndListener = makeEndListener;
  169. function makeCloseListener(client, reject, name) {
  170. return function () {
  171. if (!client.endCalled) {
  172. if (reject) {
  173. reject(formatError('Connection closed unexpectedly', name));
  174. }
  175. else {
  176. console.error('Connection closed unexpectedly');
  177. }
  178. }
  179. client.sftpWrapper = null;
  180. };
  181. }
  182. exports.makeCloseListener = makeCloseListener;
  183. /**
  184. * @async
  185. *
  186. * Tests to see if a path identifies an existing item. Returns either
  187. * 'd' = directory, 'l' = sym link or '-' regular file if item exists. Returns
  188. * false if it does not
  189. *
  190. * @param {String} localPath
  191. * @returns {Boolean | String}
  192. */
  193. function localExists(localPath) {
  194. return new Promise(function (resolve, reject) {
  195. fs_1.default.stat(localPath, function (err, stats) {
  196. if (err) {
  197. if (err.code === 'ENOENT') {
  198. resolve('ENOENT');
  199. }
  200. else {
  201. reject(err);
  202. }
  203. }
  204. else {
  205. if (stats.isDirectory()) {
  206. resolve('d');
  207. }
  208. else if (stats.isSymbolicLink()) {
  209. resolve('l');
  210. }
  211. else if (stats.isFile()) {
  212. resolve('-');
  213. }
  214. else {
  215. resolve('');
  216. }
  217. }
  218. });
  219. });
  220. }
  221. exports.localExists = localExists;
  222. /**
  223. * Used by checkRemotePath and checkLocalPath to help ensure consistent
  224. * error messages.
  225. *
  226. * @param {Error} err - original error
  227. * @param {String} testPath - path associated with the error
  228. * @returns {Object} with properties of 'msg' and 'code'.
  229. */
  230. function classifyError(err, testPath) {
  231. switch (err.code) {
  232. case 'EACCES':
  233. return {
  234. msg: "Permission denied: " + testPath,
  235. code: constant_1.errorCode.permission
  236. };
  237. case 'ENOENT':
  238. return {
  239. msg: "No such file: " + testPath,
  240. code: constant_1.errorCode.notexist
  241. };
  242. case 'ENOTDIR':
  243. return {
  244. msg: "Not a directory: " + testPath,
  245. code: constant_1.errorCode.notdir
  246. };
  247. default:
  248. return {
  249. msg: err.message,
  250. code: err.code ? err.code : constant_1.errorCode.generic
  251. };
  252. }
  253. }
  254. exports.classifyError = classifyError;
  255. function localAccess(localPath, mode) {
  256. return new Promise(function (resolve) {
  257. fs_1.default.access(localPath, mode, function (err) {
  258. if (err) {
  259. var _a = classifyError(err, localPath), msg = _a.msg, code = _a.code;
  260. resolve({
  261. path: localPath,
  262. valid: false,
  263. msg: msg,
  264. code: code
  265. });
  266. }
  267. else {
  268. resolve({
  269. path: localPath,
  270. valid: true
  271. });
  272. }
  273. });
  274. });
  275. }
  276. exports.localAccess = localAccess;
  277. function checkLocalReadFile(localPath, localType) {
  278. return __awaiter(this, void 0, void 0, function () {
  279. var rslt, access, err_1;
  280. return __generator(this, function (_a) {
  281. switch (_a.label) {
  282. case 0:
  283. _a.trys.push([0, 4, , 5]);
  284. rslt = {
  285. path: localPath,
  286. type: localType
  287. };
  288. if (!(localType === 'd')) return [3 /*break*/, 1];
  289. rslt.valid = false;
  290. rslt.msg = "Bad path: " + localPath + " must be a file";
  291. rslt.code = constant_1.errorCode.badPath;
  292. return [2 /*return*/, rslt];
  293. case 1: return [4 /*yield*/, localAccess(localPath, fs_1.default.constants.R_OK)];
  294. case 2:
  295. access = _a.sent();
  296. if (access.valid) {
  297. rslt.valid = true;
  298. return [2 /*return*/, rslt];
  299. }
  300. else {
  301. rslt.valid = false;
  302. rslt.msg = access.msg;
  303. rslt.code = access.code;
  304. return [2 /*return*/, rslt];
  305. }
  306. _a.label = 3;
  307. case 3: return [3 /*break*/, 5];
  308. case 4:
  309. err_1 = _a.sent();
  310. throw formatError(err_1, 'checkLocalReadFile');
  311. case 5: return [2 /*return*/];
  312. }
  313. });
  314. });
  315. }
  316. exports.checkLocalReadFile = checkLocalReadFile;
  317. function checkLocalReadDir(localPath, localType) {
  318. return __awaiter(this, void 0, void 0, function () {
  319. var rslt, access, err_2;
  320. return __generator(this, function (_a) {
  321. switch (_a.label) {
  322. case 0:
  323. _a.trys.push([0, 5, , 6]);
  324. rslt = {
  325. path: localPath,
  326. type: localType
  327. };
  328. if (!!localType) return [3 /*break*/, 1];
  329. rslt.valid = false;
  330. rslt.msg = "No such directory: " + localPath;
  331. rslt.code = constant_1.errorCode.notdir;
  332. return [2 /*return*/, rslt];
  333. case 1:
  334. if (!(localType !== 'd')) return [3 /*break*/, 2];
  335. rslt.valid = false;
  336. rslt.msg = "Bad path: " + localPath + " must be a directory";
  337. rslt.code = constant_1.errorCode.badPath;
  338. return [2 /*return*/, rslt];
  339. case 2: return [4 /*yield*/, localAccess(localPath, fs_1.default.constants.R_OK | fs_1.default.constants.X_OK)];
  340. case 3:
  341. access = _a.sent();
  342. if (!access.valid) {
  343. rslt.valid = false;
  344. rslt.msg = access.msg;
  345. rslt.code = access.code;
  346. return [2 /*return*/, rslt];
  347. }
  348. rslt.valid = true;
  349. return [2 /*return*/, rslt];
  350. case 4: return [3 /*break*/, 6];
  351. case 5:
  352. err_2 = _a.sent();
  353. throw formatError(err_2, 'checkLocalReadDir');
  354. case 6: return [2 /*return*/];
  355. }
  356. });
  357. });
  358. }
  359. exports.checkLocalReadDir = checkLocalReadDir;
  360. function checkLocalWriteFile(localPath, localType) {
  361. return __awaiter(this, void 0, void 0, function () {
  362. var rslt, dir, parent_1, access, err_3;
  363. return __generator(this, function (_a) {
  364. switch (_a.label) {
  365. case 0:
  366. _a.trys.push([0, 6, , 7]);
  367. rslt = {
  368. path: localPath,
  369. type: localType
  370. };
  371. if (!(localType === 'd')) return [3 /*break*/, 1];
  372. rslt.valid = false;
  373. rslt.msg = "Bad path: " + localPath + " must be a file";
  374. rslt.code = constant_1.errorCode.badPath;
  375. return [2 /*return*/, rslt];
  376. case 1:
  377. if (!!localType) return [3 /*break*/, 3];
  378. dir = path_1.default.parse(localPath).dir;
  379. return [4 /*yield*/, localAccess(dir, fs_1.default.constants.W_OK)];
  380. case 2:
  381. parent_1 = _a.sent();
  382. if (parent_1.valid) {
  383. rslt.valid = true;
  384. return [2 /*return*/, rslt];
  385. }
  386. else {
  387. rslt.valid = false;
  388. rslt.msg = parent_1.msg;
  389. rslt.code = parent_1.code;
  390. return [2 /*return*/, rslt];
  391. }
  392. return [3 /*break*/, 5];
  393. case 3: return [4 /*yield*/, localAccess(localPath, fs_1.default.constants.W_OK)];
  394. case 4:
  395. access = _a.sent();
  396. if (access.valid) {
  397. rslt.valid = true;
  398. return [2 /*return*/, rslt];
  399. }
  400. else {
  401. rslt.valid = false;
  402. rslt.msg = access.msg;
  403. rslt.code = access.code;
  404. return [2 /*return*/, rslt];
  405. }
  406. _a.label = 5;
  407. case 5: return [3 /*break*/, 7];
  408. case 6:
  409. err_3 = _a.sent();
  410. throw formatError(err_3, 'checkLocalWriteFile');
  411. case 7: return [2 /*return*/];
  412. }
  413. });
  414. });
  415. }
  416. exports.checkLocalWriteFile = checkLocalWriteFile;
  417. function checkLocalWriteDir(localPath, localType) {
  418. return __awaiter(this, void 0, void 0, function () {
  419. var rslt, parent_2, access, access, err_4;
  420. return __generator(this, function (_a) {
  421. switch (_a.label) {
  422. case 0:
  423. _a.trys.push([0, 6, , 7]);
  424. rslt = {
  425. path: localPath,
  426. type: localType
  427. };
  428. if (!!localType) return [3 /*break*/, 2];
  429. parent_2 = path_1.default.parse(localPath).dir;
  430. return [4 /*yield*/, localAccess(parent_2, fs_1.default.constants.W_OK)];
  431. case 1:
  432. access = _a.sent();
  433. if (access.valid) {
  434. rslt.valid = true;
  435. return [2 /*return*/, rslt];
  436. }
  437. else {
  438. rslt.valid = false;
  439. rslt.msg = access.msg;
  440. rslt.code = access.code;
  441. return [2 /*return*/, rslt];
  442. }
  443. return [3 /*break*/, 5];
  444. case 2:
  445. if (!(localType !== 'd')) return [3 /*break*/, 3];
  446. rslt.valid = false;
  447. rslt.msg = "Bad path: " + localPath + " must be a directory";
  448. rslt.code = constant_1.errorCode.badPath;
  449. return [2 /*return*/, rslt];
  450. case 3: return [4 /*yield*/, localAccess(localPath, fs_1.default.constants.W_OK)];
  451. case 4:
  452. access = _a.sent();
  453. if (access.valid) {
  454. rslt.valid = true;
  455. return [2 /*return*/, rslt];
  456. }
  457. else {
  458. rslt.valid = false;
  459. rslt.msg = access.msg;
  460. rslt.code = access.code;
  461. return [2 /*return*/, rslt];
  462. }
  463. _a.label = 5;
  464. case 5: return [3 /*break*/, 7];
  465. case 6:
  466. err_4 = _a.sent();
  467. throw formatError(err_4, 'checkLocalWriteDir');
  468. case 7: return [2 /*return*/];
  469. }
  470. });
  471. });
  472. }
  473. exports.checkLocalWriteDir = checkLocalWriteDir;
  474. function checkLocalPath(lPath, target) {
  475. if (target === void 0) { target = constant_1.targetType.readFile; }
  476. return __awaiter(this, void 0, void 0, function () {
  477. var localPath, type, err_5;
  478. return __generator(this, function (_a) {
  479. switch (_a.label) {
  480. case 0:
  481. _a.trys.push([0, 2, , 3]);
  482. localPath = path_1.default.resolve(lPath);
  483. return [4 /*yield*/, localExists(localPath)];
  484. case 1:
  485. type = _a.sent();
  486. switch (target) {
  487. case constant_1.targetType.readFile:
  488. return [2 /*return*/, checkLocalReadFile(localPath, type)];
  489. case constant_1.targetType.readDir:
  490. return [2 /*return*/, checkLocalReadDir(localPath, type)];
  491. case constant_1.targetType.writeFile:
  492. return [2 /*return*/, checkLocalWriteFile(localPath, type)];
  493. case constant_1.targetType.writeDir:
  494. return [2 /*return*/, checkLocalWriteDir(localPath, type)];
  495. default:
  496. return [2 /*return*/, {
  497. path: localPath,
  498. type: type,
  499. valid: true
  500. }];
  501. }
  502. return [3 /*break*/, 3];
  503. case 2:
  504. err_5 = _a.sent();
  505. throw new Error(err_5);
  506. case 3: return [2 /*return*/];
  507. }
  508. });
  509. });
  510. }
  511. exports.checkLocalPath = checkLocalPath;
  512. function normalizeRemotePath(client, aPath) {
  513. return __awaiter(this, void 0, void 0, function () {
  514. var root, root, err_6;
  515. return __generator(this, function (_a) {
  516. switch (_a.label) {
  517. case 0:
  518. _a.trys.push([0, 5, , 6]);
  519. if (!aPath.startsWith('..')) return [3 /*break*/, 2];
  520. return [4 /*yield*/, client.realPath('..')];
  521. case 1:
  522. root = _a.sent();
  523. return [2 /*return*/, root + client.remotePathSep + aPath.substring(3)];
  524. case 2:
  525. if (!aPath.startsWith('.')) return [3 /*break*/, 4];
  526. return [4 /*yield*/, client.realPath('.')];
  527. case 3:
  528. root = _a.sent();
  529. return [2 /*return*/, root + client.remotePathSep + aPath.substring(2)];
  530. case 4: return [2 /*return*/, aPath];
  531. case 5:
  532. err_6 = _a.sent();
  533. throw formatError(err_6, 'normalizeRemotePath');
  534. case 6: return [2 /*return*/];
  535. }
  536. });
  537. });
  538. }
  539. exports.normalizeRemotePath = normalizeRemotePath;
  540. function checkReadObject(aPath, type) {
  541. return {
  542. path: aPath,
  543. type: type,
  544. valid: type ? true : false,
  545. msg: type ? undefined : "No such file " + aPath,
  546. code: type ? undefined : constant_1.errorCode.notexist
  547. };
  548. }
  549. exports.checkReadObject = checkReadObject;
  550. function checkReadFile(aPath, type) {
  551. if (!type) {
  552. return {
  553. path: aPath,
  554. type: type,
  555. valid: false,
  556. msg: "No such file: " + aPath,
  557. code: constant_1.errorCode.notexist
  558. };
  559. }
  560. else if (type === 'd') {
  561. return {
  562. path: aPath,
  563. type: type,
  564. valid: false,
  565. msg: "Bad path: " + aPath + " must be a file",
  566. code: constant_1.errorCode.badPath
  567. };
  568. }
  569. return {
  570. path: aPath,
  571. type: type,
  572. valid: true
  573. };
  574. }
  575. exports.checkReadFile = checkReadFile;
  576. function checkReadDir(aPath, type) {
  577. if (!type) {
  578. return {
  579. path: aPath,
  580. type: type,
  581. valid: false,
  582. msg: "No such directory: " + aPath,
  583. code: constant_1.errorCode.notdir
  584. };
  585. }
  586. else if (type !== 'd') {
  587. return {
  588. path: aPath,
  589. type: type,
  590. valid: false,
  591. msg: "Bad path: " + aPath + " must be a directory",
  592. code: constant_1.errorCode.badPath
  593. };
  594. }
  595. return {
  596. path: aPath,
  597. type: type,
  598. valid: true
  599. };
  600. }
  601. exports.checkReadDir = checkReadDir;
  602. function checkWriteFile(client, aPath, type) {
  603. return __awaiter(this, void 0, void 0, function () {
  604. var _a, root, dir, parentType;
  605. return __generator(this, function (_b) {
  606. switch (_b.label) {
  607. case 0:
  608. if (!(type && type === 'd')) return [3 /*break*/, 1];
  609. return [2 /*return*/, {
  610. path: aPath,
  611. type: type,
  612. valid: false,
  613. msg: "Bad path: " + aPath + " must be a regular file",
  614. code: constant_1.errorCode.badPath
  615. }];
  616. case 1:
  617. if (!!type) return [3 /*break*/, 3];
  618. _a = path_1.default.parse(aPath), root = _a.root, dir = _a.dir;
  619. // let parentDir = path.parse(aPath).dir;
  620. if (!dir) {
  621. return [2 /*return*/, {
  622. path: aPath,
  623. type: false,
  624. valid: false,
  625. msg: "Bad path: " + aPath + " cannot determine parent directory",
  626. code: constant_1.errorCode.badPath
  627. }];
  628. }
  629. if (root === dir) {
  630. return [2 /*return*/, {
  631. path: aPath,
  632. type: type,
  633. valid: true
  634. }];
  635. }
  636. return [4 /*yield*/, client.exists(dir)];
  637. case 2:
  638. parentType = _b.sent();
  639. if (!parentType) {
  640. return [2 /*return*/, {
  641. path: aPath,
  642. type: type,
  643. valid: false,
  644. msg: "Bad path: " + dir + " parent not exist",
  645. code: constant_1.errorCode.badPath
  646. }];
  647. }
  648. else if (parentType !== 'd') {
  649. return [2 /*return*/, {
  650. path: aPath,
  651. type: type,
  652. valid: false,
  653. msg: "Bad path: " + dir + " must be a directory",
  654. code: constant_1.errorCode.badPath
  655. }];
  656. }
  657. return [2 /*return*/, {
  658. path: aPath,
  659. type: type,
  660. valid: true
  661. }];
  662. case 3: return [2 /*return*/, {
  663. path: aPath,
  664. type: type,
  665. valid: true
  666. }];
  667. }
  668. });
  669. });
  670. }
  671. exports.checkWriteFile = checkWriteFile;
  672. function checkWriteDir(client, aPath, type) {
  673. return __awaiter(this, void 0, void 0, function () {
  674. var _a, root, dir, parentType;
  675. return __generator(this, function (_b) {
  676. switch (_b.label) {
  677. case 0:
  678. if (!(type && type !== 'd')) return [3 /*break*/, 1];
  679. return [2 /*return*/, {
  680. path: aPath,
  681. type: type,
  682. valid: false,
  683. msg: "Bad path: " + aPath + " must be a directory",
  684. code: constant_1.errorCode.badPath
  685. }];
  686. case 1:
  687. if (!!type) return [3 /*break*/, 3];
  688. _a = path_1.default.parse(aPath), root = _a.root, dir = _a.dir;
  689. if (root === dir) {
  690. return [2 /*return*/, {
  691. path: aPath,
  692. type: type,
  693. valid: true
  694. }];
  695. }
  696. if (!dir) {
  697. return [2 /*return*/, {
  698. path: aPath,
  699. type: false,
  700. valid: false,
  701. msg: "Bad path: " + aPath + " cannot determine directory parent",
  702. code: constant_1.errorCode.badPath
  703. }];
  704. }
  705. return [4 /*yield*/, client.exists(dir)];
  706. case 2:
  707. parentType = _b.sent();
  708. if (parentType && parentType !== 'd') {
  709. return [2 /*return*/, {
  710. path: aPath,
  711. type: type,
  712. valid: false,
  713. msg: 'Bad path: Parent Directory must be a directory',
  714. code: constant_1.errorCode.badPath
  715. }];
  716. }
  717. _b.label = 3;
  718. case 3:
  719. // don't care if parent does not exist as it might be created
  720. // via recursive call to mkdir.
  721. return [2 /*return*/, {
  722. path: aPath,
  723. type: type,
  724. valid: true
  725. }];
  726. }
  727. });
  728. });
  729. }
  730. exports.checkWriteDir = checkWriteDir;
  731. function checkWriteObject(aPath, type) {
  732. // for writeObj, not much error checking we can do
  733. // Just return path, type and valid indicator
  734. return {
  735. path: aPath,
  736. type: type,
  737. valid: true
  738. };
  739. }
  740. exports.checkWriteObject = checkWriteObject;
  741. function checkRemotePath(client, rPath, target) {
  742. if (target === void 0) { target = constant_1.targetType.readFile; }
  743. return __awaiter(this, void 0, void 0, function () {
  744. var aPath, type;
  745. return __generator(this, function (_a) {
  746. switch (_a.label) {
  747. case 0: return [4 /*yield*/, normalizeRemotePath(client, rPath)];
  748. case 1:
  749. aPath = _a.sent();
  750. return [4 /*yield*/, client.exists(aPath)];
  751. case 2:
  752. type = _a.sent();
  753. switch (target) {
  754. case constant_1.targetType.readObj:
  755. return [2 /*return*/, checkReadObject(aPath, type)];
  756. case constant_1.targetType.readFile:
  757. return [2 /*return*/, checkReadFile(aPath, type)];
  758. case constant_1.targetType.readDir:
  759. return [2 /*return*/, checkReadDir(aPath, type)];
  760. case constant_1.targetType.writeFile:
  761. return [2 /*return*/, checkWriteFile(client, aPath, type)];
  762. case constant_1.targetType.writeDir:
  763. return [2 /*return*/, checkWriteDir(client, aPath, type)];
  764. case constant_1.targetType.writeObj:
  765. return [2 /*return*/, checkWriteObject(aPath, type)];
  766. default:
  767. throw formatError("Unknown target type: " + target, 'checkRemotePath', constant_1.errorCode.generic);
  768. }
  769. return [2 /*return*/];
  770. }
  771. });
  772. });
  773. }
  774. exports.checkRemotePath = checkRemotePath;
  775. /**
  776. * Check to see if there is an active sftp connection
  777. *
  778. * @param {Object} client - current sftp object
  779. * @param {String} name - name given to this connection
  780. * @param {Function} reject - if defined, call this rather than throw
  781. * an error
  782. * @returns {Boolean} True if connection OK
  783. * @throws {Error}
  784. */
  785. function haveConnection(client, name, reject) {
  786. if (!client.sftpWrapper) {
  787. var newError = formatError('No SFTP connection available', name, constant_1.errorCode.connect);
  788. if (reject) {
  789. reject(newError);
  790. return false;
  791. }
  792. else {
  793. throw newError;
  794. }
  795. }
  796. return true;
  797. }
  798. exports.haveConnection = haveConnection;
  799. function dumpListeners(emitter) {
  800. var eventNames = emitter.eventNames();
  801. if (eventNames.length) {
  802. console.log('Listener Data');
  803. eventNames.map(function (n) {
  804. var listeners = emitter.listeners(n);
  805. console.log(n + ": " + emitter.listenerCount(n));
  806. console.dir(listeners);
  807. listeners.map(function (l) {
  808. console.log("listener name = " + l.name);
  809. });
  810. });
  811. }
  812. }
  813. exports.dumpListeners = dumpListeners;
  814. function hasListener(emitter, eventName, listenerName) {
  815. var listeners = emitter.listeners(eventName);
  816. var matches = listeners.filter(function (l) { return l.name === listenerName; });
  817. return matches.length === 0 ? false : true;
  818. }
  819. exports.hasListener = hasListener;
  820. function joinRemote(client) {
  821. var _a, _b;
  822. var args = [];
  823. for (var _i = 1; _i < arguments.length; _i++) {
  824. args[_i - 1] = arguments[_i];
  825. }
  826. if (client.remotePathSep === path_1.default.win32.sep) {
  827. return (_a = path_1.default.win32).join.apply(_a, args);
  828. }
  829. return (_b = path_1.default.posix).join.apply(_b, args);
  830. }
  831. exports.joinRemote = joinRemote;