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 4.2.1 to 4.3.0

6

CHANGELOG.md
# Changelog
## 4.3.0
- Added: More explicit API `uploadFrom`, `appendFrom` and `downloadTo`. `upload` and `download` are still available but deprecated.
- Added: Handle file downloads and uploads directly by supporting local file paths in `uploadFrom` and `downloadTo`.
- Added: Make it easier to resume a download of a partially downloaded file. See documentation of `downloadTo` for more details.
## 4.2.1

@@ -4,0 +10,0 @@

65

dist/Client.d.ts

@@ -7,2 +7,3 @@ /// <reference types="node" />

import { ProgressHandler, ProgressTracker } from "./ProgressTracker";
import { UploadCommand } from "./transfer";
export interface AccessOptions {

@@ -26,2 +27,8 @@ /** Host the client should connect to. Optional, default is "localhost". */

export declare type RawListParser = (rawList: string) => FileInfo[];
export interface UploadOptions {
/** Offset in the local file to start uploading from. */
localStart?: number;
/** Final byte position to include in upload from the local file. */
localEndInclusive?: number;
}
/**

@@ -169,32 +176,54 @@ * High-level API to interact with an FTP server.

/**
* Upload data from a readable stream and store it as a file with a given filename in the current working directory.
* If such a file already exists it will be overwritten.
* Upload data from a readable stream or a local file to a remote file.
*
* @param source The stream to read from.
* @param remotePath The path of the remote file to write to.
* @param source Readable stream or path to a local file.
* @param toRemotePath Path to a remote file to write to.
*/
upload(source: Readable, remotePath: string): Promise<FTPResponse>;
uploadFrom(source: Readable | string, toRemotePath: string, options?: UploadOptions): Promise<FTPResponse>;
/**
* Upload data from a readable stream and append it to an existing file with a given filename in the current working directory.
* If the file doesn't exist the FTP server should create it.
* DEPRECATED, use `uploadFrom`.
* @deprecated
*/
upload(source: Readable | string, toRemotePath: string, options?: UploadOptions): Promise<FTPResponse>;
/**
* Upload data from a readable stream or a local file by appending it to an existing file. If the file doesn't
* exist the FTP server should create it.
*
* @param source The stream to read from.
* @param remotePath The path of the existing remote file to append to.
* @param source Readable stream or path to a local file.
* @param toRemotePath Path to a remote file to write to.
*/
append(source: Readable, remotePath: string): Promise<FTPResponse>;
appendFrom(source: Readable | string, toRemotePath: string, options?: UploadOptions): Promise<FTPResponse>;
/**
* DEPRECATED, use `appendFrom`.
* @deprecated
*/
append(source: Readable | string, toRemotePath: string, options?: UploadOptions): Promise<FTPResponse>;
protected _uploadWithCommand(source: Readable | string, remotePath: string, command: UploadCommand, options: UploadOptions): Promise<FTPResponse>;
protected _uploadLocalFile(localPath: string, remotePath: string, command: UploadCommand, options: UploadOptions): Promise<FTPResponse>;
/**
* @protected
*/
protected _uploadWithCommand(source: Readable, remotePath: string, command: "STOR" | "APPE"): Promise<FTPResponse>;
protected _uploadFromStream(source: Readable, remotePath: string, command: UploadCommand): Promise<FTPResponse>;
/**
* Download a file with a given filename from the current working directory
* and pipe its data to a writable stream. You may optionally start at a specific
* offset, for example to resume a cancelled transfer.
* Download a remote file and pipe its data to a writable stream or to a local file.
*
* @param destination The stream to write to.
* @param remotePath The name of the remote file to read from.
* @param startAt The offset to start at.
* You can optionally define at which position of the remote file you'd like to start
* downloading. If the destination you provide is a file, the offset will be applied
* to it as well. For example: To resume a failed download, you'd request the size of
* the local, partially downloaded file and use that as the offset. Assuming the size
* is 23, you'd download the rest using `downloadTo("local.txt", "remote.txt", 23)`.
*
* @param destination Stream or path for a local file to write to.
* @param fromRemotePath Path of the remote file to read from.
* @param startAt Position within the remote file to start downloading at. If the destination is a file, this offset is also applied to it.
*/
download(destination: Writable, remotePath: string, startAt?: number): Promise<FTPResponse>;
downloadTo(destination: Writable | string, fromRemotePath: string, startAt?: number): Promise<FTPResponse>;
/**
* DEPRECATED, use `downloadTo`.
* @deprecated
*/
download(destination: Writable | string, fromRemotePath: string, startAt?: number): Promise<FTPResponse>;
protected _downloadToFile(localPath: string, remotePath: string, startAt: number): Promise<FTPResponse>;
protected _downloadToStream(destination: Writable, remotePath: string, startAt: number): Promise<FTPResponse>;
/**
* List files and directories in the current working directory, or from `path` if specified.

@@ -201,0 +230,0 @@ *

@@ -19,2 +19,5 @@ "use strict";

const fsStat = util_1.promisify(fs_1.stat);
const fsOpen = util_1.promisify(fs_1.open);
const fsClose = util_1.promisify(fs_1.close);
const fsUnlink = util_1.promisify(fs_1.unlink);
/**

@@ -301,25 +304,59 @@ * High-level API to interact with an FTP server.

/**
* Upload data from a readable stream and store it as a file with a given filename in the current working directory.
* If such a file already exists it will be overwritten.
* Upload data from a readable stream or a local file to a remote file.
*
* @param source The stream to read from.
* @param remotePath The path of the remote file to write to.
* @param source Readable stream or path to a local file.
* @param toRemotePath Path to a remote file to write to.
*/
async upload(source, remotePath) {
return this._uploadWithCommand(source, remotePath, "STOR");
async uploadFrom(source, toRemotePath, options = {}) {
return this._uploadWithCommand(source, toRemotePath, "STOR", options);
}
/**
* Upload data from a readable stream and append it to an existing file with a given filename in the current working directory.
* If the file doesn't exist the FTP server should create it.
* DEPRECATED, use `uploadFrom`.
* @deprecated
*/
async upload(source, toRemotePath, options = {}) {
return this.uploadFrom(source, toRemotePath, options);
}
/**
* Upload data from a readable stream or a local file by appending it to an existing file. If the file doesn't
* exist the FTP server should create it.
*
* @param source The stream to read from.
* @param remotePath The path of the existing remote file to append to.
* @param source Readable stream or path to a local file.
* @param toRemotePath Path to a remote file to write to.
*/
async append(source, remotePath) {
return this._uploadWithCommand(source, remotePath, "APPE");
async appendFrom(source, toRemotePath, options = {}) {
return this._uploadWithCommand(source, toRemotePath, "APPE", options);
}
/**
* DEPRECATED, use `appendFrom`.
* @deprecated
*/
async append(source, toRemotePath, options = {}) {
return this.appendFrom(source, toRemotePath, options);
}
async _uploadWithCommand(source, remotePath, command, options) {
if (typeof source === "string") {
return this._uploadLocalFile(source, remotePath, command, options);
}
return this._uploadFromStream(source, remotePath, command);
}
async _uploadLocalFile(localPath, remotePath, command, options) {
const fd = await fsOpen(localPath, "r");
const source = fs_1.createReadStream("", {
fd,
start: options.localStart,
end: options.localEndInclusive,
autoClose: false
});
try {
return await this._uploadFromStream(source, remotePath, command);
}
finally {
await ignoreError(() => fsClose(fd));
}
}
/**
* @protected
*/
async _uploadWithCommand(source, remotePath, command) {
async _uploadFromStream(source, remotePath, command) {
const onError = (err) => this.ftp.closeWithError(err);

@@ -339,11 +376,50 @@ source.once("error", onError);

/**
* Download a file with a given filename from the current working directory
* and pipe its data to a writable stream. You may optionally start at a specific
* offset, for example to resume a cancelled transfer.
* Download a remote file and pipe its data to a writable stream or to a local file.
*
* @param destination The stream to write to.
* @param remotePath The name of the remote file to read from.
* @param startAt The offset to start at.
* You can optionally define at which position of the remote file you'd like to start
* downloading. If the destination you provide is a file, the offset will be applied
* to it as well. For example: To resume a failed download, you'd request the size of
* the local, partially downloaded file and use that as the offset. Assuming the size
* is 23, you'd download the rest using `downloadTo("local.txt", "remote.txt", 23)`.
*
* @param destination Stream or path for a local file to write to.
* @param fromRemotePath Path of the remote file to read from.
* @param startAt Position within the remote file to start downloading at. If the destination is a file, this offset is also applied to it.
*/
async download(destination, remotePath, startAt = 0) {
async downloadTo(destination, fromRemotePath, startAt = 0) {
if (typeof destination === "string") {
return this._downloadToFile(destination, fromRemotePath, startAt);
}
return this._downloadToStream(destination, fromRemotePath, startAt);
}
/**
* DEPRECATED, use `downloadTo`.
* @deprecated
*/
async download(destination, fromRemotePath, startAt = 0) {
return this.downloadTo(destination, fromRemotePath, startAt);
}
async _downloadToFile(localPath, remotePath, startAt) {
const expectLocalFile = startAt > 0;
const fileSystemFlags = expectLocalFile ? "r+" : "w";
const fd = await fsOpen(localPath, fileSystemFlags);
const destination = fs_1.createWriteStream("", {
fd,
start: startAt,
autoClose: false
});
try {
return await this._downloadToStream(destination, remotePath, startAt);
}
catch (err) {
if (!expectLocalFile) {
await ignoreError(() => fsUnlink(localPath));
}
throw err;
}
finally {
await ignoreError(() => fsClose(fd));
}
}
async _downloadToStream(destination, remotePath, startAt) {
const onError = (err) => this.ftp.closeWithError(err);

@@ -478,4 +554,3 @@ destination.once("error", onError);

else {
const writable = fs_1.createWriteStream(localPath);
await this.download(writable, file.name);
await this.downloadTo(localPath, file.name);
}

@@ -561,3 +636,3 @@ }

if (stats.isFile()) {
await client.upload(fs_1.createReadStream(fullPath), file);
await client.uploadFrom(fullPath, file);
}

@@ -584,4 +659,12 @@ else if (stats.isDirectory()) {

catch (err) {
await fsMkDir(path);
await fsMkDir(path, { recursive: true });
}
}
async function ignoreError(func) {
try {
await func();
}
catch (err) {
// Ignore
}
}

@@ -5,2 +5,3 @@ /// <reference types="node" />

import { ProgressTracker } from "./ProgressTracker";
export declare type UploadCommand = "STOR" | "APPE";
/**

@@ -31,3 +32,3 @@ * Prepare a data socket using passive mode over IPv6.

*/
export declare function upload(ftp: FTPContext, progress: ProgressTracker, source: Readable, command: "STOR" | "APPE", remoteFilename: string): Promise<FTPResponse>;
export declare function upload(ftp: FTPContext, progress: ProgressTracker, source: Readable, command: UploadCommand, remoteFilename: string): Promise<FTPResponse>;
/**

@@ -34,0 +35,0 @@ * Download data from the data connection. Used for downloading files and directory listings.

{
"name": "basic-ftp",
"version": "4.2.1",
"version": "4.3.0",
"description": "FTP client for Node.js, supports explicit FTPS over TLS, IPv6, Async/Await, and Typescript.",

@@ -39,8 +39,8 @@ "main": "dist/index",

"devDependencies": {
"@types/node": "12.7.12",
"@typescript-eslint/eslint-plugin": "2.3.3",
"@typescript-eslint/parser": "2.3.3",
"@types/node": "12.11.1",
"@typescript-eslint/eslint-plugin": "2.4.0",
"@typescript-eslint/parser": "2.4.0",
"eslint": "6.5.1",
"js-yaml": ">=3.13.1",
"mocha": "6.2.1",
"mocha": "6.2.2",
"rimraf": "3.0.0",

@@ -47,0 +47,0 @@ "typescript": "3.6.4"

@@ -17,7 +17,6 @@ # Basic FTP

The first example will connect to an FTP server using TLS, get a directory listing, and upload a file. Note that the FTP protocol doesn't allow multiple requests running in parallel.
The first example will connect to an FTP server using TLS, get a directory listing, upload a file and download it as a copy. Note that the FTP protocol doesn't allow multiple requests running in parallel.
```js
const ftp = require("basic-ftp")
const fs = require("fs")

@@ -37,3 +36,4 @@ example()

console.log(await client.list())
await client.upload(fs.createReadStream("README.md"), "README.md")
await client.uploadFrom("README.md", "README_FTP.md")
await client.downloadTo("README_COPY.md", "README_FTP.md")
}

@@ -94,11 +94,11 @@ catch(err) {

Send an FTP command.
Send an FTP command and return the first response.
`sendIgnoringError(command): Promise<FTPResponse>`
Send an FTP command and ignore an FTP error response. Any other error or timeout will still reject the Promise.
Send an FTP command, return the first response, and ignore an FTP error response. Any other error or timeout will still reject the Promise.
`cd(remotePath): Promise<FTPResponse>`
`cd(path): Promise<FTPResponse>`
Change the working directory.
Change the current working directory.

@@ -111,11 +111,11 @@ `pwd(): Promise<string>`

List files and directories in the current working directory, or from `path` if specified. Currently, this library only supports MLSD, Unix and DOS directory listings. See [FileInfo](src/FileInfo.ts) for more details.
List files and directories in the current working directory, or at `path` if specified. Currently, this library only supports MLSD, Unix and DOS directory listings. See [FileInfo](src/FileInfo.ts) for more details.
`lastMod(filename): Promise<Date>`
`lastMod(path): Promise<Date>`
Get the last modification time of a file in the working directory. This command might not be supported by your FTP server and throw an exception.
Get the last modification time of a file. This command might not be supported by your FTP server and throw an exception.
`size(filename): Promise<number>`
`size(path): Promise<number>`
Get the size of a file in the working directory.
Get the size of a file in bytes.

@@ -126,17 +126,17 @@ `rename(path, newPath): Promise<FTPResponse>`

`remove(filename): Promise<FTPResponse>`
`remove(path): Promise<FTPResponse>`
Remove a file from the working directory.
Remove a file.
`upload(readableStream, remoteFilename): Promise<FTPResponse>`
`uploadFrom(readableStream | localPath, remotePath): Promise<FTPResponse>`
Upload data from a readable stream and store it as a file with a given filename in the current working directory. If such a file already exists it will be overwritten.
Upload data from a readable stream or a local file to a remote file. If such a file already exists it will be overwritten.
`append(readableStream, remoteFilename): Promise<FTPResponse>`
`appendFrom(readableStream | localPath, remotePath): Promise<FTPResponse>`
Upload data from a readable stream and append it to an existing file with a given filename in the current working directory. If the file doesn't exist the FTP server should create it.
Upload data from a readable stream or a local file by appending it to an existing file. If the file doesn't exist the FTP server should create it.
`download(writableStream, remoteFilename, startAt = 0): Promise<FTPResponse>`
`downloadTo(writableStream | localPath, remotePath, startAt = 0): Promise<FTPResponse>`
Download a file with a given filename from the current working directory and pipe its data to a writable stream. You may optionally start at a specific offset, for example to resume a cancelled transfer.
Download a remote file and pipe its data to a writable stream or to a local file. You can optionally define at which position of the remote file you'd like to start downloading. If the destination you provide is a file, the offset will be applied to it as well. For example: To resume a failed download, you'd request the size of the local, partially downloaded file and use that as the offset.

@@ -143,0 +143,0 @@ ---

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