
Research
Supply Chain Attack on Axios Pulls Malicious Dependency from npm
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.
@slynova/flydrive
Advanced tools
flydrive is a framework-agnostic package which provides a powerful wrapper to manage file Storage in Node.js.
There are currently 3 drivers available:
'local': Stores files on the local file system.'s3': Amazon S3 and other compatible services
@slynova/flydrive-s3 package to be able to use this driver.'gcs': Google Cloud Storage
@slynova/flydrive-gcs package to be able to use this driver.This package is available in the npm registry.
It can easily be installed with npm or yarn.
$ npm i @slynova/flydrive
# or
$ yarn add @slynova/flydrive
When you require the package in your file, it will give you access to the StorageManager class.
This class is a facade for the package and should be instantiated with a configuration object.
const { StorageManager } = require('@slynova/flydrive');
const storage = new StorageManager(...);
Once you instantiated the manager, you can use the StorageManager#disk() method to retrieve a disk an use it.
storage.disk(); // Returns the default disk (specified in the config)
storage.disk('awsCloud'); // Returns the driver for the disk "s3"
storage.disk('awsCloud', customConfig); // Overwrite the default configuration of the disk
After installing any external driver, like @slynova/flydrive-gcs, you need to register it inside our manager to be able to use it.
The following is done by using the method storage.registerDriver(name: string, Driver).
const { GoogleCloudStorage } = require('@slynova/flydrive-gcs');
const { StorageManager } = require('@slynova/flydrive');
const storage = new StorageManager(...);
storage.registerDriver('gcs', GoogleCloudStorage);
Each driver extends the abstract class Storage. This class will throw an exception for each methods by default. The driver needs to overwrite the methods it supports.
The following method doesn't exist on the LocalFileSystemStorage driver, therefore, it will throw an exception.
// throws "E_METHOD_NOT_SUPPORTED: Method getSignedUrl is not supported for the driver LocalFileSystemStorage"
storage.disk('local').getSignedUrl();
Since we are using TypeScript, you can make use of casting to get the real interface:
import { LocalFileSystemStorage } from '@slynova/flydrive';
storage.disk<LocalFileSystemStorage>('local');
Asynchronous methods will always return a Promise which resolves with a Response
object. The response object may contain relevant data in its properties (for
example, the ExistsResponse object for the exists method contains a boolean
exists property).
All responses additionally have a raw property which is driver-specific and
contains the result from the original call made by the driver.
In case of runtime errors, flydrive will try to throw driver-agnostic exceptions.
Exceptions also have a raw property which contains the original error.
append(location: string, content: Buffer | Stream | string, options: object): Promise<Response>This method will append the content to the file at the location. If the file doesn't exist yet, it will be created.
// Supported drivers: "local"
await storage.disk('local').append('foo.txt', 'bar');
// foo.txt now has the content `${initialContent}bar`
copy(src: string, dest: string, options: object): Promise<Response>This method will copy a file to another location.
// Supported drivers: "local", "s3", "gcs"
await storage.disk('local').copy('foo.txt', 'bar.txt');
// foo.txt was copied to bar.txt
delete(location: string): Promise<DeleteResponse>This method will delete the file at the given location.
// Supported drivers: "local", "s3", "gcs"
const { wasDeleted } = await storage.disk('local').delete('foo.txt');
// If a file named foo.txt has been deleted, wasDeleted is true.
The value returned by this method will have a wasDeleted property that
can be either a boolean (true if a file was deleted, false if there was
no file to delete) or null (if no information about the file is available).
driver()This method returns the driver used if you need to do anything specific not supported by default.
storage.disk('local').driver(); // Returns the "fs-extra" module.
storage.disk('awsCloud').driver(); // Returns an instance of the AWS S3 client.
storage.disk('googleCloud').driver(); // Returns an instance of the the Google Cloud Storage client.
// ....
exists(location: string): Promise<ExistsResponse>This method will determine if a file exists at the given location.
// Supported drivers: "local", "s3", "gcs"
const { exists } = await storage.disk('local').exists('foo.txt');
// exists is true or false
get(location: string, encoding: string = 'utf-8'): Promise<ContentResponse<string>>This method will return the file's content as a string for the given location.
// Supported drivers: "local", "s3", "gcs"
const { content } = await storage.disk('local').get('foo.txt');
getBuffer(location: string): Promise<ContentResponse<Buffer>>This method will return the file's content as a Buffer for the given location.
// Supported drivers: "local", "s3", "gcs"
const { content } = await storage.disk('local').exists('foo.txt');
getSignedUrl(location: string, options: SignedUrlOptions = { expiry: 900 }): Promise<SignedUrlResponse>This method will return the signed url for an existing file.
// Supported drivers: "s3", "gcs"
const { signedUrl } = await storage.disk('awsCloud').getSignedUrl('foo.txt');
getStat(location: string): Promise<StatResponse>This method will return the file's size (in bytes) and last modification date.
// Supported drivers: "local", "s3", "gcs"
const { size, modified } = await storage.disk('local').getStat('foo.txt');
getStream(location: string, options: object | string): StreamThis method will return a Node.js readable stream for the given file.
// Supported drivers: "local", "s3", "gcs"
const stream = storage.disk('local').getStream('foo.txt');
getUrl(location: string): stringThis method will return a public URL for a given file.
// Supported drivers: "s3", "gcs"
const uri = storage.disk('awsCloud').getUrl('foo.txt');
move(src: string, dest: string): Promise<Response>This method will move the file to a new location.
// Supported drivers: "local", "s3", "gcs"
await storage.disk('local').move('foo.txt', 'newFolder/foo.txt');
put(location: string, content: Buffer | Stream | string, options: object): Promise<Response>This method will create a new file with the provided content.
// Supported drivers: "local", "s3", "gcs"
await storage.disk('local').put('bar.txt', 'Foobar');
prepend(location: string, content: Buffer | string, options: object): Promise<Response>This method will prepend content to a file.
// Supported drivers: "local"
await storage.disk('local').prepend('foo.txt', 'bar');
// foo.txt now has the content `bar${initialContent}`
flatList(prefix?: string): AsyncIterable<FileListResponse>This method will return an async iterator over all file names that start with prefix (recursive).
// Supported drivers: "local", "s3", "gcs"
const disk = storage.disk('local');
for await (const filename of disk.flatList('a/b')) {
console.log(filename);
}
Any pull requests or discussions are welcome. Note that every pull request providing new feature or correcting a bug should be created with appropriate unit tests.
FAQs
Flexible and Fluent way to manage storage in Node.js.
The npm package @slynova/flydrive receives a total of 6,797 weekly downloads. As such, @slynova/flydrive popularity was classified as popular.
We found that @slynova/flydrive demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.

Security News
TeamPCP is partnering with ransomware group Vect to turn open source supply chain attacks on tools like Trivy and LiteLLM into large-scale ransomware operations.