@xemahq/blob-storage
v0.3.0
Published
<p align="center"> <svg width="680" height="120" viewBox="0 0 680 120" fill="none" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="@xemahq/blob-storage"> <rect width="680" height="120" rx="14" fill="#0B1020"/> <g transform="translate(28,34)"
Readme
@xemahq/blob-storage
Backend-agnostic blob storage for NestJS services
Overview
A single BlobStorage abstraction over S3-compatible stores and Azure Blob
Storage. Consumers depend only on the interface — put, get, delete, and
prefix-delete objects — while the concrete adapter is selected by configuration
and injected at boot. Switching backends never touches consumer code.
When to use it
- Use it when a NestJS service needs object storage but should not be coupled to a specific S3 or Azure SDK.
Installation
pnpm add @xemahq/blob-storageUsage
import { BlobStorageModule, BlobStorage } from '@xemahq/blob-storage';
@Module({ imports: [BlobStorageModule.forRoot(options)] })
export class AppModule {}
// Then inject BlobStorage and read/write objects:
await storage.put(container, key, body);
const obj = await storage.getBuffer(container, key);A service usually declares only its own logical containers and reads the rest of the configuration from the environment, so it never restates which variables each backend needs:
import {
BlobStorageModule,
blobStorageOptionsFromEnv,
} from '@xemahq/blob-storage';
BlobStorageModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) =>
blobStorageOptionsFromEnv((name) => config.get<string>(name), {
declaredContainers: ['uploads'],
}),
});The reader is a plain function, so plain Node ((name) => process.env[name])
and tests work the same way. BLOB_STORAGE_ENV_VARS names every variable it
reads.
Peer requirements
@nestjs/common>= 10@nestjs/core>= 10reflect-metadata>= 0.1.13rxjs>= 7
License
Apache-2.0 © Xema — xema.dev
