@mostajs/blob-store
v0.4.0
Published
Ranger des octets — contrat StorageDriver + pilotes filesystem, caching et S3 (SigV4 intégré, tout service S3-compatible). Primitive N0. Primitives crypto déléguées à @mostajs/crypto-box.
Maintainers
Readme
@mostajs/blob-store
Auteur : Dr Hamid MADANI [email protected] · Licence : AGPL-3.0-or-later Niveau : N0 (primitif) · Zéro dépendance
Ranger des octets. Rien d'autre.
Contrat StorageDriver — put / get / delete / exists / stat / list — avec flux,
métadonnées, etag, checksum SHA-256 et création atomique (ifNotExists).
Pourquoi ce module existe
Ce code vivait dans @mostajs/storage. Il y était déjà pur — aucun import d'ORM, de RBAC
ni de data-plug — mais prisonnier : @mostajs/storage déclare @mostajs/orm,
@mostajs/data-plug et @mostajs/config en dépendances. Importer le seul driver traînait donc
tout l'ORM derrière. Impossible d'obtenir « juste des octets ».
Extrait ici, il devient une brique réellement réutilisable :
| Consommateur | Ce qu'il en fait |
|---|---|
| @mostajs/storage | octets + métadonnées en base + RBAC (ré-exporte d'ici — aucune rupture) |
| @mostajs/archive-box | les octets d'une archive |
| @mostajs/backup | les octets d'une sauvegarde, locale ou externalisée |
Le module ignore délibérément ce que les octets représentent. C'est ce qui le rend malléable.
Usage
import { FilesystemDriver, StorageError } from '@mostajs/blob-store';
const driver = new FilesystemDriver({ rootDir: '/var/data/blobs' });
const { size, checksum } = await driver.put(
{ bucket: 'backups', path: '2026-07-13.zip' },
bytes,
{ mimeType: 'application/zip' },
);
const obj = await driver.get({ bucket: 'backups', path: '2026-07-13.zip' });
// obj.stream, obj.size, obj.mimeType, obj.etagErreurs typées (jamais nues) : StorageError avec un code (not_found, invalid_path,
access_denied…) et STORAGE_ERROR_HTTP pour le mapping HTTP.
Pilotes
FilesystemDriver— disque local. Sanitise les chemins (le..est refusé : un driver de stockage est une surface d'attaque).CachingDriver— décorateur de cache devant un driver d'origine.S3Driver— S3 et tout service S3-compatible : AWS, MinIO, Scaleway, Wasabi, Backblaze… Zéro dépendance : SigV4 est implémenté ici (S3 n'est que du HTTP signé), au lieu de tirer@aws-sdk/client-s3et ses dizaines de mégaoctets. Pour héberger les sauvegardes de vos clients sur vos propres serveurs, cette souveraineté n'est pas un détail.import { S3Driver } from '@mostajs/blob-store/drivers/s3'; const s3 = new S3Driver({ endpoint: 'http://localhost:9000', // MinIO auto-hébergé, ou https://s3.eu-west-3.amazonaws.com region: 'eu-west-3', accessKeyId: process.env.S3_KEY, secretAccessKey: process.env.S3_SECRET, forcePathStyle: true, // requis par la plupart des services auto-hébergés });Dette soldée :
@mostajs/storageannonçait « bytes in object storage (FS / S3) » depuis sa 0.2.0 — sans qu'aucun pilote S3 n'existe. La promesse est tenue ici, au niveau de la primitive, pour qu'archive-boxetbackupen profitent aussi. La poser dansstorageaurait payé la dette au mauvais étage.
Tests
npm test # 28 tests mjs-unit : disque réel, SigV4, serveur S3 simuléUn test de stockage qui n'écrit rien ne prouve rien :
- Filesystem — disque réel, vecteur SHA-256 vérifié indépendamment (et non recopié depuis le pilote lui-même).
- SigV4 — validée contre les vecteurs officiels d'AWS (dérivation de clé, requête
canonique et signature de la suite « get-vanilla »). Une signature fausse ne se manifesterait
qu'à l'exécution, par un
403 SignatureDoesNotMatchindéchiffrable sur un serveur distant. - S3 — serveur S3 simulé qui refuse toute requête non signée : un pilote qui
« marcherait » sans
Authorizationpasserait des tests naïfs, puis échouerait chez le client.
