# @toa.io/extensions.storages

> Toa Storages

Latest version **0.24.0-alpha.0** (published 2023-11-16) · 0 weekly downloads

## Install

```sh
npm install @toa.io/extensions.storages
pnpm add @toa.io/extensions.storages
yarn add @toa.io/extensions.storages
bun add @toa.io/extensions.storages
```

## Health

**Score 35/100 (D)** — status: abandoned.

Positive: has types; no vulnerabilities; high maintenance score.

Warnings: low downloads; no esm support; pre 1.0.

Negative: abandoned.

## Facts

| | |
|---|---|
| Version | 0.24.0-alpha.0 |
| Published | 2023-11-16 |
| First published | 2023-10-28 |
| Weekly downloads | 0 |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 7 |
| Unpacked size | 2.9 MB |
| Known vulnerabilities | 0 (+1 in 1 direct dependencies) |
| Install scripts | no |
| GitHub stars | 3 |
| Author | temich |
| Maintainers | agurtovoi |

## Links

- npm: https://www.npmjs.com/package/@toa.io/extensions.storages
- Repository: https://github.com/toa-io/toa
- Homepage: https://github.com/toa-io/toa#readme
- Issues: https://github.com/toa-io/toa/issues
- npm.io page: https://npm.io/package/@toa.io/extensions.storages

## Dependencies (7)

- [fs-extra](https://npm.io/package/fs-extra.md) 11.1.1
- [msgpackr](https://npm.io/package/msgpackr.md) 1.9.9
- [matchacho](https://npm.io/package/matchacho.md) 0.3.5
- [error-value](https://npm.io/package/error-value.md) 0.3.0
- [@toa.io/generic](https://npm.io/package/@toa.io/generic.md) 0.20.0-alpha.2
- [@aws-sdk/client-s3](https://npm.io/package/@aws-sdk/client-s3.md) 3.435.0
- [@aws-sdk/lib-storage](https://npm.io/package/@aws-sdk/lib-storage.md) 3.437.0

## Recent versions

- 0.24.0-alpha.0 (latest) — 2023-11-16
- 1.0.0-alpha.309 (alpha) — 2026-09-16
- 1.0.0-alpha.308 — 2026-09-15
- 1.0.0-alpha.307 — 2026-09-15
- 1.0.0-alpha.306 — 2026-09-14
- 1.0.0-alpha.305 — 2026-09-13
- 1.0.0-alpha.304 — 2026-09-13
- 1.0.0-alpha.303 — 2026-09-12
- 1.0.0-alpha.302 — 2026-09-11
- 1.0.0-alpha.301 — 2026-09-11
- 1.0.0-alpha.300 — 2026-09-11
- 1.0.0-alpha.299 — 2026-09-10
- 1.0.0-alpha.298 — 2026-09-08
- 1.0.0-alpha.297 — 2026-09-08
- 1.0.0-alpha.296 — 2026-09-08
- … 149 more at https://npm.io/package/@toa.io/extensions.storages/versions

## README

# Toa Storages

Shared BLOB storage.

## Entry

BLOBs are stored with the meta-information object (Entry) having the following properties:

- `id` - checksum
- `size` - size in bytes
- `type` - MIME type
- `created` - creation timestamp (UNIX time, ms)
- `variants` - array of:
  - `name` - unique name
  - `size` - size in bytes
  - `type` - variant MIME type
- `meta` - object with application-specific information, empty by default

### Example

```yaml
id: eecd837c
type: image/jpeg
created: 1698004822358
variants:
  - name: thumbnail.jpeg
    type: image/jpeg
  - name: thumbnail.webp
    type: image/webp
meta:
  face: true
  nudity: false
```

## Aspect

The Storages extension provides `storages` aspect,
containing named Storage instances, according to the annotation.

```javascript
async function effect (_, context) {
  await context.storages.photos.fetch('/path/to/b4f577e0.thumbnail.jpeg')
}
```

### Storage interface

> `Maybe<T> = T | Error`

#### `async put(path: string, stream: Readable, type?: TypeControl): Maybe<Entry>`

```
interface TypeControl {
  claim?: string
  accept?: string
}
```

Add a BLOB to the storage and create an entry under specified `path`.

BLOB type is identified
using [magick numbers](https://github.com/sindresorhus/file-type).

If the `type` argument is specified and the value of the `claim` does not match the detected BLOB type, then
a `TYPE_MISMATCH` error is returned.
If the BLOB type cannot be identified and the value of the `claim` is not in the list of known types, then the given
value is used.
If the list of [acceptable types](https://datatracker.ietf.org/doc/html/rfc2616#section-14.1) is passed and the type of
the BLOB does not match any of its values, then a `NOT_ACCEPTABLE` error is returned.

Known types
are: `image/jpeg`, `image/png`, `image/gif`, `image/webp`, `image/heic`, `image/jxl`, `image/avif`.

See [source](source/Scanner.ts).

If the entry already exists, it is returned and [revealed](#async-revealpath-string-maybevoid).

#### `async get(path: string): Maybe<Entry>`

Get an entry.

If the entry does not exist, a `NOT_FOUND` error is returned.

#### `async fetch(path: string): Maybe<Readable>`

Fetch the BLOB specified by `path`. If the path does not exist, a `NOT_FOUND` error is returned.

`path` can be an entry id, or a path to the entry, or a path to a variant of the entry.

- `eecd837c` - fetch the BLOB by `id`
- `/path/to/eecd837c` - fetch the BLOB by path
- `/path/to/eecd837c.thumbnail.jpeg` - fetch the `thumbnail.jpeg` variant of the BLOB

#### `async delete(path: string): Maybe<void>`

Delete the entry specified by `path`.

#### `async list(path: string): string[]`

Get ordered list of `id`s of entries in under the `path`.

#### `async permute(path: string, ids: string[]): Maybe<void>`

Reorder entries under the `path`.

Given list must be a permutation of the current list, otherwise a `PERMUTATION_MISMATCH` error is
returned.

#### `async diversify(path: string, name: string, stream: Readable): Maybe<void>`

Add or replace a `name` variant of the entry specified by `path`.

#### `async conceal(path: string): Maybe<void>`

Remove the entry from the list.

#### `async reveal(path: string): Maybe<void>`

Restore the entry to the list.

#### `async annotate(path: string, key: string, value: any): Maybe<void>`

Set a `key` property in the `meta` of the entry specified by `path`.

## Providers

Storage uses underlying providers to store BLOBs and entries.

Custom providers are not supported.

### Amazon S3

Annotation value formats is `s3://{region}/{bucket}?endpoint={endpoint}`.

Requires secrets for the access key and secret key.
See [`toa conceal`](/runtime/cli/readme.md#conceal) for deployment
and [`toa env`](/runtime/cli/readme.md#env)
for local environment.
`endpoint` parameter is optional.

`s3://us-east-1/my-bucket?endpoint=http://s3.my-instance.com:4566`

### Filesystem

Annotation value format is `file:///{path}`.

`file:///var/my-storage`

### Temporary

Filesystem using OS temporary directory.

Annotation value format is `tmp:///{path}`.

`tmp:///my-storage`

## Deduplication

BLOBs are stored in the underlying storage with their checksum as the key, ensuring that identical
BLOBs are stored only once.
Variants, on the other hand, are not deduplicated across different entries.

Underlying directory structure:

```
/temp
  c28f4dfd            # random id
/blobs
  b4f577e0            # checksum
/storage
  /path/to
    .list             # list of entries
    /b4f577e0
      .meta           # entry
      thumbnail.jpeg  # variant BLOBs
      thumbnail.webp
```

## Manifest

Storage extension can be enabled by adding `storages` key to the component manifest.

```yaml
storages: [photos, videos]
```

Value of the `storages` key is an array of storage names, that should be declared in the context.

It the names are unknown, `null` declaration can be used:

```yaml
storages: ~
```

## Annotation

The `storages` context annotation is an object with keys that reference the storage name and
provider-specific URLs as values.

```yaml
storages:
  photos: s3://us-east-1/my-bucket
  photos@dev: file:///var/my-storage
```

## Secrets

Secrets declared by storage providers can be deployed
by [`toa conceal`](/runtime/cli/readme.md#conceal),
or set locally by [`toa env`](/runtime/cli/readme.md#env).

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