MinioStore — MinIO object storage

Read this page in the documentation

MinioStore — MinIO object storage Overview MinIO is a self-hostable, S3-compatible object store. Like Amazon S3 it has no query language, no rows, and no SQL-shaped access pattern — data is opaque objects (byte bodies plus metadata) addressed by a (bucket, key) pair, where the "key" is a flat object name that only looks like a path (foo/bar/baz.json). None of that fits the SQL-shaped Dialect interface, so MinioStore implements the minimal NoSqlStore marker interface (src/nosql/store.ts) — connection lifecycle plus a getClient() escape hatch — and exposes MinIO's own object-level operations directly. Identity: Property | Value | --------- | --------- | name | 'minio' | library | 'minio' | Unlike S3Store (which uses the AWS SDK v3 command pattern), this store is built on the official minio JS client, whose Minio.Client exposes a method per operation (putObject, getObject, removeObject, …). Two of those methods are stream-shaped rather than promise-of-value, and this store collects them for you: getObject(bucket, key) resolves to a readable byte stream — collected to completion into a single Buffer. listObjects(bucket, prefix, recursive) returns an object stream emitting one item per object — collected into an array of object names (item.name). Lazy loading — not a hard dependency The minio package is not a hard dependency of this package. It is loaded lazily via require('minio') inside connect() rather than a top-level import, so importing this module does not require the driver to be installed — it is only needed when a MinIO store is actually connected without an injected client. Injected client MinioStoreOptions.client accepts a pre-built Minio.Client (or compatible object, typed as MinioClientLike). When provided, connect() uses it directly and does not require the driver. This is how the test suite injects a mock client (no driver, no network), and how callers supply a custom-configured client. Connection Build a store from connection options (mirroring Minio.Client construction) and call connect(): Option | Type | Purpose | ----------- | ----------------- | --------------------------------------------------------------- | endPoint | string | Server hostname or IP, e.g. 'localhost' or 's3.example.com'.| port | number | TCP port the MinIO/S3 server listens on, e.g. 9000. | useSSL | boolean | Whether to use TLS (https). | accessKey | string | Access key (username) for the server. | secretKey | string | Secret key (password) for the server. | client | MinioClientLike | A pre-built Minio.Client to use directly (mock or custom config). When set, the driver is not required. | Injected-client form Methods Driver failures are wrapped in a DatabaseError (preserving the original error, e.g. MinIO putObject on 'bkt/k.txt' failed (Error): ...); using any method before connect() (or after disconnect()) throws a ConnectionError. Lifecycle Method | Signature | Behavior | ------------ | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | connect | connect(): Promise<void> | Uses an injected client if provided, otherwise lazy-requires minio and builds a new Minio.Client(...) from the options. Wraps failures in ConnectionError. | disconnect | disconnect(): Promise<void> | Drops the client reference (the MinIO client is stateless — no persistent socket to close). | isConnected| isConnected(): boolean | true only when connected and a client is present. | getClient | getClient(): MinioClientLike | Returns the underlying Minio.Client. Throws ConnectionError if not connected. | Object operations Method | Signature | Behavior | -------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | putObject | putObject(bucket: string, key: string, data: unknown, options?: PutObjectOptions): Promise<PutObjectResult> | Store data under bucket/key. options.size and options.metadata are passed as trailing args to the driver. Returns { etag?, versionId? }. | getObject | getObject(bucket: string, key: string): Promise<GetObjectResult> | Fetch an object; the driver's readable byte stream is collected to completion into a single Buffer. Returns { body: Buffer, stat? }. | removeObject | removeObject(bucket: string, key: string): Promise<void> | Delete an object. | listObjects | listObjects(bucket: string, prefix?: string): Promise<string[]> | List objects (recursively — passes recursive = true), optionally restricted to keys starting with prefix (defaults to ''). Collects the object stream into an array of object names (item.name, falling back to item.prefix). | statObject | statObject(bucket: string, key: string): Promise<StatObjectResult> | Fetch object metadata without the body. Returns { size?, etag?, lastModified?, metaData? }. | makeBucket | makeBucket(bucket: string, region?: string): Promise<void> | Create a bucket. When region is omitted the driver is called with just the bucket name; otherwise with (bucket, region). | bucketExists | bucketExists(bucket: string): Promise<boolean> | Whether a bucket exists (coerced to a boolean). | Both stream-collecting helpers (getObject, listObjects) support both Node.js event-emitter streams (.on('data'|'end'|'error')) and async iterables (for await). Option and result shapes Example Verification status Unit / mock-verified only. The tests in tests/nosql/minio.test.ts are fully mock-driven: a fake Minio.Client with spied methods is injected via MinioStoreOptions.client. The real minio package is not installed, and there is no live MinIO access and no network in the test run. What this proves: Each method calls the driver with the expected arguments and shapes the result: putObject forwards (bucket, key, data, size, metadata) and returns { etag, versionId }; statObject maps the driver's stat fields; makeBucket calls with or without a region; bucketExists coerces to a boolean. The two stream-shaped operations are the focus: getObject collects both a Node.js byte stream and an async-iterable stream into the correct Buffer, and listObjects collects both stream shapes into an array of names, defaulting the prefix to '' and passing recursive = true. Lifecycle: starts disconnected, connects via an injected client without loading the driver, clean disconnect, and ConnectionError when operating before connect() / after disconnect() and from getClient() before connect(). Error handling: driver failures and stream errors (both getObject and listObjects) wrapped in DatabaseError. What this does not prove: live execution against a real MinIO (or S3-compatible) server. Behavior is verified against the driver's documented contract, not end-to-end over the wire. Related reading All data stores — the full catalogue, grouped by purpose Database types — where this sits among the 22 categories