New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

basic-ftp

Package Overview
Dependencies
Maintainers
1
Versions
112
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

basic-ftp - npm Package Compare versions

Comparing version 2.7.1 to 2.8.0

4

CHANGELOG.md
# Changelog
## 2.8.0
- Change uploadDir() so that it reuses directories on the FTP server if they already exist. (#5)
## 2.7.1

@@ -4,0 +8,0 @@

192

lib/ftp.js

@@ -502,4 +502,6 @@ "use strict";

/**
* Upload the contents of a local directory to the working directory. You can
* optionally provide a `remoteDirName` to put the contents inside a newly created directory.
* Upload the contents of a local directory to the working directory. You can optionally
* provide a `remoteDirName` to put the contents inside a directory which will be created
* if necessary. This will overwrite existing files with the same names and reuse existing
* directories. Unrelated files and directories will remain untouched.
*

@@ -515,6 +517,5 @@ * @param {string} localDirPath A local path, e.g. "foo/bar" or "../test"

}
await this.send("MKD " + remoteDirName);
await this.cd(remoteDirName);
await openDir(this, remoteDirName);
}
await this.uploadDirContents(localDirPath);
await uploadDirContents(this, localDirPath);
// The working directory should stay the same after this operation.

@@ -527,24 +528,2 @@ if (remoteDirName !== undefined) {

/**
* Upload the contents of a local directory to the working directory.
*
* @param {string} localDirPath
*/
async uploadDirContents(localDirPath) {
const files = await fsReadDir(localDirPath);
for (const file of files) {
const fullPath = path.join(localDirPath, file);
const stats = await fsStat(fullPath);
if (stats.isFile()) {
await this.upload(fs.createReadStream(fullPath), file);
}
else if (stats.isDirectory()) {
await this.send("MKD " + file);
await this.cd(file);
await this.uploadDirContents(fullPath);
await this.send("CDUP");
}
}
}
/**
* Download all files and directories of the working directory to a local directory.

@@ -571,4 +550,4 @@ *

/**
* Make sure a given remote path exists, creating all directories as necessary. This
* function also changes the current working directory to the given path.
* Make sure a given remote path exists, creating all directories as necessary.
* This function also changes the current working directory to the given path.
*

@@ -578,3 +557,2 @@ * @param {string} remoteDirPath

async ensureDir(remoteDirPath) {
const names = remoteDirPath.split("/").filter(name => name !== "");
// If the remoteDirPath was absolute go to root directory.

@@ -584,10 +562,5 @@ if (remoteDirPath.startsWith("/")) {

}
const names = remoteDirPath.split("/").filter(name => name !== "");
for (const name of names) {
// Check first if the directory exists. Just calling MKD might
// result in a permission error for intermediate directories.
const res = await this.send("CWD " + name, true);
if (res.code >= 400) {
await this.send("MKD " + name);
await this.cd(name);
}
await openDir(this, name);
}

@@ -654,2 +627,9 @@ }

/**
* Return true if an FTP return code describes a positive completion. Often it's not
* necessary to know which code it was specifically.
*
* @param {number} code
* @param {boolean}
*/
function positiveCompletion(code) {

@@ -659,3 +639,58 @@ return code >= 200 && code < 300;

function isSingle(line) {
return /^\d\d\d /.test(line);
}
function isMultiline(line) {
return /^\d\d\d-/.test(line);
}
function describeTLS(socket) {
if (socket.encrypted) {
return socket.getProtocol();
}
return "No encryption";
}
/**
* Parse an FTP control response as a collection of messages. A message is a complete
* single- or multiline response. A response can also contain multiple multiline responses
* that will each be represented by a message. A response can also be incomplete
* and be completed on the next incoming data chunk for which case this function also
* describes a `rest`. This function converts all CRLF to LF.
*
* @param {string} text
* @returns {{messages: string[], rest: string}}
*/
function parseControlResponse(text) {
const lines = text.split(/\r?\n/);
const messages = [];
let startAt = 0;
let token = "";
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
// No group has been opened.
if (token === "") {
if (isMultiline(line)) {
// Open a group by setting an expected token.
token = line.substr(0, 3) + " ";
startAt = i;
}
else if (isSingle(line)) {
// Single lines can be grouped immediately.
messages.push(line);
}
}
// Group has been opened, expect closing token.
else if (line.startsWith(token)) {
token = "";
messages.push(lines.slice(startAt, i + 1).join("\n"));
}
}
// The last group might not have been closed, report it as a rest.
const rest = token !== "" ? lines.slice(startAt).join("\n") + "\n" : "";
return { messages, rest };
}
/**
* Upgrade a socket connection with TLS.

@@ -854,9 +889,36 @@ *

function describeTLS(socket) {
if (socket.encrypted) {
return socket.getProtocol();
/**
* Upload the contents of a local directory to the working directory. This will overwrite
* existing files and reuse existing directories.
*
* @param {string} localDirPath
*/
async function uploadDirContents(client, localDirPath) {
const files = await fsReadDir(localDirPath);
for (const file of files) {
const fullPath = path.join(localDirPath, file);
const stats = await fsStat(fullPath);
if (stats.isFile()) {
await client.upload(fs.createReadStream(fullPath), file);
}
else if (stats.isDirectory()) {
await openDir(client, file);
await uploadDirContents(client, fullPath);
await client.send("CDUP");
}
}
return "No encryption";
}
/**
* Try to create a directory and enter it. This will not raise an exception if the directory
* couldn't be created if for example it already exists.
*
* @param {Client} client
* @param {string} dirName
*/
async function openDir(client, dirName) {
await client.send("MKD " + dirName, true); // Ignore FTP error codes
await client.cd(dirName);
}
async function ensureLocalDirectory(path) {

@@ -870,49 +932,1 @@ try {

}
/**
* Parse an FTP control response as a collection of messages. A message is a complete
* single- or multiline response. A response can also contain multiple multiline responses
* that will each be represented by a message. A response can also be incomplete
* and be completed on the next incoming data chunk for which case this function also
* describes a `rest`. This function converts all CRLF to LF.
*
* @param {string} text
* @returns {{messages: string[], rest: string}}
*/
function parseControlResponse(text) {
const lines = text.split(/\r?\n/);
const messages = [];
let startAt = 0;
let token = "";
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
// No group has been opened.
if (token === "") {
if (isMultiline(line)) {
// Open a group by setting an expected token.
token = line.substr(0, 3) + " ";
startAt = i;
}
else if (isSingle(line)) {
// Single lines can be grouped immediately.
messages.push(line);
}
}
// Group has been opened, expect closing token.
else if (line.startsWith(token)) {
token = "";
messages.push(lines.slice(startAt, i + 1).join("\n"));
}
}
// The last group might not have been closed, report it as a rest.
const rest = token !== "" ? lines.slice(startAt).join("\n") + "\n" : "";
return { messages, rest };
}
function isSingle(line) {
return /^\d\d\d /.test(line);
}
function isMultiline(line) {
return /^\d\d\d-/.test(line);
}
{
"name": "basic-ftp",
"version": "2.7.1",
"version": "2.8.0",
"description": "FTP/FTPS client library",

@@ -5,0 +5,0 @@ "main": "./lib/ftp",

@@ -58,3 +58,3 @@ # Basic FTP

else {
await client.send("DELE " + file.name);
await client.remove(file.name);
}

@@ -137,3 +137,3 @@ }

Upload all files and directories of a local directory to the current working directory. If you specify a `remoteDirName` it will place the uploads inside a directory of the given name.
Upload all files and directories of a local directory to the current working directory. If you specify a `remoteDirName` it will place the uploads inside a directory of the given name. This will overwrite existing files with the same names and reuse existing directories. Unrelated files and directories will remain untouched.

@@ -140,0 +140,0 @@ `downloadDir(localDirPath): Promise<void>`

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc