# @slynova/flydrive

> Flexible and Fluent way to manage storage in Node.js.

Latest version **1.0.3** (published 2020-09-04) · MIT license · 0 weekly downloads

## Install

```sh
npm install @slynova/flydrive
pnpm add @slynova/flydrive
yarn add @slynova/flydrive
bun add @slynova/flydrive
```

## Health

**Score 20/100 (F)** — status: abandoned.

Positive: has types; no vulnerabilities.

Warnings: low downloads; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.3 |
| Published | 2020-09-04 |
| First published | 2017-08-11 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 2 |
| Unpacked size | 70.8 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 406 |
| Author | Romain Lanz |
| Maintainers | romainlanz |
| Keywords | storage, filesystem, file, aws, s3, promise, async, spaces, google, cloud |

## Links

- npm: https://www.npmjs.com/package/@slynova/flydrive
- Repository: https://github.com/Slynova-Org/flydrive
- Homepage: https://github.com/Slynova-Org/flydrive#readme
- Issues: https://github.com/Slynova-Org/flydrive/issues
- npm.io page: https://npm.io/package/@slynova/flydrive

## Dependencies (2)

- [fs-extra](https://npm.io/package/fs-extra.md) ^9.0.0
- [node-exceptions](https://npm.io/package/node-exceptions.md) ^4.0.1

## Alternatives

- [unionfs](https://npm.io/package/unionfs.md) — 2.2M weekly downloads
- [path-starts-with](https://npm.io/package/path-starts-with.md) — 35.9K weekly downloads
- [redzip](https://npm.io/package/redzip.md) — 1.2K weekly downloads
- [vscode-anymatch](https://npm.io/package/vscode-anymatch.md) — 848 weekly downloads
- [@ledgerhq/coin-filecoin](https://npm.io/package/@ledgerhq/coin-filecoin.md) — 793 weekly downloads

## Recent versions

- 1.0.3 (latest) — 2020-09-04
- 1.0.1-alpha.0 (next) — 2020-06-03
- 1.0.2 — 2020-07-07
- 1.0.1 — 2020-06-17
- 1.0.0-0 — 2019-08-23
- 0.3.1 — 2018-05-16
- 0.3.0 — 2018-04-16
- 0.2.0 — 2018-03-19
- 0.1.6 — 2018-02-03
- 0.1.5 — 2017-10-06
- 0.1.4 — 2017-09-12
- 0.1.3 — 2017-09-11
- 0.1.2 — 2017-09-11
- 0.1.1 — 2017-09-11
- 0.1.0 — 2017-08-30
- … 1 more at https://npm.io/package/@slynova/flydrive/versions

## README

<p align="center">
  <img src="https://user-images.githubusercontent.com/2793951/54391096-418f4500-46a4-11e9-8d0c-b00ff7ba4198.png" alt="flydrive">
</p>

<p align="center">
  <a href="https://www.npmjs.com/package/@slynova/flydrive"><img src="https://img.shields.io/npm/dm/@slynova/flydrive.svg?style=flat-square" alt="Download"></a>
  <a href="https://www.npmjs.com/package/@slynova/flydrive"><img src="https://img.shields.io/npm/v/@slynova/flydrive.svg?style=flat-square" alt="Version"></a>
  <a href="https://opensource.org/licenses/MIT"><img src="https://img.shields.io/npm/l/@slynova/flydrive.svg?style=flat-square" alt="License"></a>
</p>

`flydrive` is a framework-agnostic package which provides a powerful wrapper to manage file Storage in [Node.js](https://nodejs.org).

There are currently 3 drivers available:

- `'local'`: Stores files on the local file system.
- `'s3'`: Amazon S3 and other compatible services
  - You need to install the `@slynova/flydrive-s3` package to be able to use this driver.
  - This driver is compatible with DigitalOcean Spaces and Scaleway Object Storage.
- `'gcs'`: Google Cloud Storage
  - You need to install the `@slynova/flydrive-gcs` package to be able to use this driver.

---

## Getting Started

This package is available in the npm registry.
It can easily be installed with `npm` or `yarn`.

```bash
$ 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](https://github.com/Slynova-Org/flydrive/blob/master/test/stubs/config.ts).

```javascript
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.

```javascript
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
```

## Registering External Driver

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)`.

```ts
const { GoogleCloudStorage } = require('@slynova/flydrive-gcs');
const { StorageManager } = require('@slynova/flydrive');
const storage = new StorageManager(...);

storage.registerDriver('gcs', GoogleCloudStorage);
```

## Driver's API

Each driver extends the abstract class [`Storage`](https://github.com/Slynova-Org/flydrive/blob/master/src/Storage.ts). 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.

```javascript
// 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:

```typescript
import { LocalFileSystemStorage } from '@slynova/flydrive';

storage.disk<LocalFileSystemStorage>('local');
```

### Response interface

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.

### Exceptions

In case of runtime errors, `flydrive` will try to throw driver-agnostic exceptions.
Exceptions also have a `raw` property which contains the original error.

### Methods

<details>
<summary markdown="span"><code>append(location: string, content: Buffer | Stream | string, options: object): Promise&lt;Response&gt;</code></summary>

This method will append the content to the file at the location.
If the file doesn't exist yet, it will be created.

```javascript
// Supported drivers: "local"

await storage.disk('local').append('foo.txt', 'bar');
// foo.txt now has the content `${initialContent}bar`
```

</details>

<details>
<summary markdown="span"><code>copy(src: string, dest: string, options: object): Promise&lt;Response&gt;</code></summary>

This method will copy a file to another location.

```javascript
// Supported drivers: "local", "s3", "gcs"

await storage.disk('local').copy('foo.txt', 'bar.txt');
// foo.txt was copied to bar.txt
```

</details>

<details>
<summary markdown="span"><code>delete(location: string): Promise&lt;DeleteResponse&gt;</code></summary>

This method will delete the file at the given location.

```javascript
// 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).

</details>

<details>
<summary markdown="span"><code>driver()</code></summary>

This method returns the driver used if you need to do anything specific not supported by default.

```javascript
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.
// ....
```

</details>

<details>
<summary markdown="span"><code>exists(location: string): Promise&lt;ExistsResponse&gt;</code></summary>

This method will determine if a file exists at the given location.

```javascript
// Supported drivers: "local", "s3", "gcs"

const { exists } = await storage.disk('local').exists('foo.txt');
// exists is true or false
```

</details>

<details>
<summary markdown="span"><code>get(location: string, encoding: string = 'utf-8'): Promise&lt;ContentResponse&lt;string&gt;&gt;</code></summary>

This method will return the file's content as a string for the given location.

```javascript
// Supported drivers: "local", "s3", "gcs"

const { content } = await storage.disk('local').get('foo.txt');
```

</details>

<details>
<summary markdown="span"><code>getBuffer(location: string): Promise&lt;ContentResponse&lt;Buffer&gt;&gt;</code></summary>

This method will return the file's content as a Buffer for the given location.

```javascript
// Supported drivers: "local", "s3", "gcs"

const { content } = await storage.disk('local').exists('foo.txt');
```

</details>

<details>
<summary markdown="span"><code>getSignedUrl(location: string, options: SignedUrlOptions = { expiry: 900 }): Promise&lt;SignedUrlResponse&gt;</code></summary>

This method will return the signed url for an existing file.

```javascript
// Supported drivers: "s3", "gcs"

const { signedUrl } = await storage.disk('awsCloud').getSignedUrl('foo.txt');
```

</details>

<details>
<summary markdown="span"><code>getStat(location: string): Promise&lt;StatResponse&gt;</code></summary>

This method will return the file's size (in bytes) and last modification date.

```javascript
// Supported drivers: "local", "s3", "gcs"

const { size, modified } = await storage.disk('local').getStat('foo.txt');
```

</details>

<details>
<summary markdown="span"><code>getStream(location: string, options: object | string): Stream</code></summary>

This method will return a Node.js readable stream for the given file.

```javascript
// Supported drivers: "local", "s3", "gcs"

const stream = storage.disk('local').getStream('foo.txt');
```

</details>

<details>
<summary markdown="span"><code>getUrl(location: string): string</code></summary>

This method will return a public URL for a given file.

```javascript
// Supported drivers: "s3", "gcs"

const uri = storage.disk('awsCloud').getUrl('foo.txt');
```

</details>

<details>
<summary markdown="span"><code>move(src: string, dest: string): Promise&lt;Response&gt;</code></summary>

This method will move the file to a new location.

```javascript
// Supported drivers: "local", "s3", "gcs"

await storage.disk('local').move('foo.txt', 'newFolder/foo.txt');
```

</details>

<details>
<summary markdown="span"><code>put(location: string, content: Buffer | Stream | string, options: object): Promise&lt;Response&gt;</code></summary>

This method will create a new file with the provided content.

```javascript
// Supported drivers: "local", "s3", "gcs"

await storage.disk('local').put('bar.txt', 'Foobar');
```

</details>

<details>
<summary markdown="span"><code>prepend(location: string, content: Buffer | string, options: object): Promise&lt;Response&gt;</code></summary>

This method will prepend content to a file.

```javascript
// Supported drivers: "local"

await storage.disk('local').prepend('foo.txt', 'bar');
// foo.txt now has the content `bar${initialContent}`
```

</details>

<details>
<summary markdown="span"><code>flatList(prefix?: string): AsyncIterable&lt;FileListResponse&gt;</code></summary>

This method will return an async iterator over all file names that start with `prefix` (recursive).

```javascript
// Supported drivers: "local", "s3", "gcs"

const disk = storage.disk('local');
for await (const filename of disk.flatList('a/b')) {
  console.log(filename);
}
```

</details>

## Contribution Guidelines

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.

---
_Source: https://npm.io/package/@slynova/flydrive · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
