ftp.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. exports.ftp = void 0;
  7. const basic_ftp_1 = require("basic-ftp");
  8. const stream_1 = require("stream");
  9. const path_1 = require("path");
  10. const debug_1 = __importDefault(require("debug"));
  11. const notfound_1 = __importDefault(require("./notfound"));
  12. const notmodified_1 = __importDefault(require("./notmodified"));
  13. const debug = (0, debug_1.default)('get-uri:ftp');
  14. /**
  15. * Returns a Readable stream from an "ftp:" URI.
  16. */
  17. const ftp = async (url, opts = {}) => {
  18. const { cache } = opts;
  19. const filepath = decodeURIComponent(url.pathname);
  20. let lastModified;
  21. if (!filepath) {
  22. throw new TypeError('No "pathname"!');
  23. }
  24. const client = new basic_ftp_1.Client();
  25. try {
  26. const host = url.hostname || url.host || 'localhost';
  27. const port = parseInt(url.port || '0', 10) || 21;
  28. const user = url.username
  29. ? decodeURIComponent(url.username)
  30. : undefined;
  31. const password = url.password
  32. ? decodeURIComponent(url.password)
  33. : undefined;
  34. await client.access({
  35. host,
  36. port,
  37. user,
  38. password,
  39. ...opts,
  40. });
  41. // first we have to figure out the Last Modified date.
  42. // try the MDTM command first, which is an optional extension command.
  43. try {
  44. lastModified = await client.lastMod(filepath);
  45. }
  46. catch (err) {
  47. // handle the "file not found" error code
  48. if (err.code === 550) {
  49. throw new notfound_1.default();
  50. }
  51. }
  52. if (!lastModified) {
  53. // Try to get the last modified date via the LIST command (uses
  54. // more bandwidth, but is more compatible with older FTP servers
  55. const list = await client.list((0, path_1.dirname)(filepath));
  56. // attempt to find the "entry" with a matching "name"
  57. const name = (0, path_1.basename)(filepath);
  58. const entry = list.find((e) => e.name === name);
  59. if (entry) {
  60. lastModified = entry.modifiedAt;
  61. }
  62. }
  63. if (lastModified) {
  64. if (isNotModified()) {
  65. throw new notmodified_1.default();
  66. }
  67. }
  68. else {
  69. throw new notfound_1.default();
  70. }
  71. const stream = new stream_1.PassThrough();
  72. const rs = stream;
  73. client.downloadTo(stream, filepath).then((result) => {
  74. debug(result.message);
  75. client.close();
  76. });
  77. rs.lastModified = lastModified;
  78. return rs;
  79. }
  80. catch (err) {
  81. client.close();
  82. throw err;
  83. }
  84. // called when `lastModified` is set, and a "cache" stream was provided
  85. function isNotModified() {
  86. if (cache?.lastModified && lastModified) {
  87. return +cache.lastModified === +lastModified;
  88. }
  89. return false;
  90. }
  91. };
  92. exports.ftp = ftp;
  93. //# sourceMappingURL=ftp.js.map