Storage
File storage abstraction — presigned media uploads backed by a Postgres object registry, split into client, server, and shared definition layers.
@halostack/storage handles file storage for the monorepo. It combines presigned media uploads with a Postgres-backed object registry — the media_files table in @halostack/db — so that uploaded objects are tracked in the database alongside the rest of the application's data. The package is deliberately split into three layers: a browser-safe client layer, a server layer that handles provider I/O, EXIF extraction, and preview generation, and a shared definition layer that both sides build on.
Importing
The client and server layers are exposed as separate subpaths, reflecting where each is meant to run:
Internally, the package shares its types and helpers through the #definition/* subpath import — mapped in the imports field to src/definition/*.ts. Keep using that import rather than reaching across folders with relative paths.
Structure
The three layers map onto three top-level folders:
src/definition/— the shared, runtime-free contracts:types,prefixes,errors,extract-extension,preview-helpers, andmedia-kinds/.src/server/—strategy,bucket-ops, andexif, plus themedia/,preview/, andproviders/subfolders that hold the actual storage backends.src/client/— the upload-side surface.
Conventions
Treat anything coming from the outside world as untrusted: validate filenames, content types, and sizes with Zod before acting on them. Keep the client layer free of server-only dependencies so it stays safe to bundle for the browser. And, as elsewhere in the monorepo, all configuration — bucket, region, and credentials — comes from @halostack/env.