npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

spine-ftp

v1.0.13

Published

Yet another ftp client for nodejs written with TypeScript. Fast, reliable & battle tested.

Readme

Spine Ftp Client

Yet another implementation of ftp client protocol. Written in pure typescript. Fast, stable & reliable. Easy extensible.

Requirements

  • node.js - v. 4.x

Installation

npm install spine-ftp

Examples

  • Get a directory listing of the current remote working directory (list files)

import { FtpClient } from 'spine-ftp';

const client = await FtpClient.connect({

    host: "127.0.0.1",
    port: 21,
    user: "anonymous",
    password: "anonymous"
    timeout: 1000
});

const files = await client.getFiles();

await client.disconnect();
  • Download remote file & save to local fs

import { FtpClient } from 'spine-ftp';

const client = await FtpClient.connect({

    host: "127.0.0.1",
    port: 21,
    user: "anonymous",
    password: "anonymous"
    timeout: 1000
});

// download to local file `local.txt` and overwrite if exists
await client.download("foo.txt", "local.txt", true);
await client.disconnect();

  • Upload local file to the server

import { FtpClient } from 'spine-ftp';

const client = await FtpClient.connect({

    host: "127.0.0.1",
    port: 21,
    user: "anonymous",
    password: "anonymous"
    timeout: 1000
});

// upload to server with remote name `remote.txt`
await client.upload("foo.txt", "remote.txt");
await client.disconnect();
  • Check if file exists on server

import { FtpClient } from 'spine-ftp';

const client = await FtpClient.connect({

    host: "127.0.0.1",
    port: 21,
    user: "anonymous",
    password: "anonymous"
    timeout: 1000
});

const exists = await client.fileExists("foo.txt");
client.disconnect();

API


 /**
     * Creates FtpClient
     *
     * @param options - connection options (host, user, password etc.)
     */
    constructor(commandConnection: FtpCommandConnectionInterface);

    /**
     * Connects to FTP server
     *
     * @throws { FtpException | Error | FtpTimeoutException } if cannot connect ( host not exists, timeout etc.)
     * @returns void
     */
    connect(): Promise<void>;

    /**
     * List all files on server at given path
     *
     * @param path - path on server to list files. If not set current directory is assumed
     * @return { FtpEntryInfo [] } - array with files found in directory
     * @throws { FtpException | Error} - if listing fails due connection error or path not exists on FTP server
     */
    getFiles(path?: string): Promise<FtpEntryInfo[]>;

    /**
     * List all files on server at given path
     *
     * @param path - path on server to list directories. If not set current directory is assumed
     * @return { FtpEntryInfo[] } - array with directories found
     * @throws { FtpException | Error} - if listing fails due connection error or path not exists on FTP server
     */
    getDirectories(path?: string): Promise<FtpEntryInfo[]>;

    /**
     * Creates directory on FTP server. After creation sets current directory to created dir.
     *
     * @param path - dir or path to create. Path must be absolute to root dir
     * @param recursive  - create subfolders recursively
     * @throws { FtpException } on invalid args or when cannot create specified dir
     */
    createDir(path: string, recursive?: boolean): Promise<void>;

    /**
     * Change file or dir name (must exists in current directory)
     *
     * @param from - name from (file or dir), must exists in current directory. Value cannot be absolute path
     * @param to - name that will be changed to. Value cannot be absolute path
     * @throws {FtpException} if cannot rename
     */
    rename(from: string, to: string): Promise<void>;

    /**
     * Deletes directory with all files in it. If recursive is set to true all subfolders will be deleted.
     *
     * @param path - dir to delete
     * @param recursive - delete subfolders
     * @throws {FtpDirectoryNotFoundException} if no directory is found on server
     * @throws {FtpException} every other problem
     */
    deleteDirectory(path?: string, recursive?: boolean): Promise<void>;

    /**
     * Deletes file from FTP server
     *
     * @param path - path to file
     * @throws {FtpFileNotFoundException} if file not exists on server
     * @throws {FtpException} every other problem eg. connection problem, etc.
     */
    deleteFile(path: string): Promise<void>;

    /**
     * Gets features list from server. It sends command to server. Feature list is also
     * avaible in `FtpCommandConnection.getFeatures()`
     *
     * @throws { FtpException } if cannot retrieve features
     * @returns { FtpFeatures } feature list
     */
    getFeatures(): Promise<FtpFeatures>;

    /**
     * Checks if file exists in server
     *
     * @param path - file to check. Absolute path or filename is supported. If filename is provided, current working working directory will be check
     * @throws {FtpException} when error occurs
     * @throws { FtpDirectoryNotFoundException} if file is not found in one of path dir
     * @returns { boolean } true if exists, error if not
     */
    fileExists(path: string): Promise<boolean>;

    /**
     * Checks if directory exists in server
     *
     * @param path - dir to check. Absolute path or dirname is supported. If dirname is provided, current working working directory will be check
     * @returns { boolean } true if exists, error if not
     * @throws { FtpException} if error occurs
     *
     */
    directoryExists(path?: string): Promise<boolean>;

    /**
     * Uploads file to server
     *
     * @param localPath - file to copy, absolute or relative path
     * @param target  - target filename, if not set filename from local path is taken
     * @param progress
     * @throws {FtpException} if cannot upload file eg. no acces to folder or connection problem
     */
    upload(localPath: string, target?: string, progress?: ProgressCallback): Promise<void>;

    /**
     * Gets file size in bytes
     *
     * @param path - path to file, absolute or relative.
     * @returns {number} file size in bytes
     * @throws { FtpException } if cannot retrieve file size
     */
    getFileSize(path: string): Promise<number>;

    /**
     * Returns last modification time of a file
     *
     * @param path - path to file, absolute or relative
     * @returns { Date } date of modicitaion time
     * @throws {FtpException} when cannot retrieve modification time
     */
    getLastModificationTime(path: string): Promise<Date>;

    /**
     * Change file modification time
     *
     * @param path - file path, absolute or file in current dir
     * @param newDate - date to set
     * @throws {FtpException} when cannot set new date
     */
    setModificationTime(path: string, newDate: Date): Promise<void>;

    /**
     * Retrieves current directory on server
     *
     * @return { string | null } - current directory on ftp server
     */
    getCurrentDirectory(): Promise<string>;

    /**
     * Sets current directory on server
     *
     * @param path - path to directory
     * @throws { FtpException } if no directory exists or problems with connection
     */
    setCurrentDirectory(path: string): Promise<any>;

    /**
     * Download file from FTP server
     *
     * @param source - source file name on server, must be file that exists in current directory
     * @param target - target file name or absolute path where file will be downloaded
     * @param overwrite - if true target file will be overwitten if exists
     * @param progress - callback function for progress. Called every time if bytes are send
     * @throws { FtpException } - on download fail / file not exists, connection problems or file exists & overwrite is set to false
     */
    download(source: string, target: string, overwrite?: boolean, progress?: ProgressCallback): Promise<void>;

    /**
     * Disconnects from FTP server gracefully
     */
    disconnect(): Promise<void>;

TODO

Feel free to commit:

  • Full code coverage in tests
  • Some missing FTP commands eg. append
  • Secure connection