package lazystorage ¶
import "golazy.dev/lazystorage"
Functions ¶
func Take[T any] ¶
Take removes the first option assignable to T and returns it with the remaining options. It is useful for director implementations that consume recognized options and pass unknown ones downstream.
func Take[T any](options []any) (T, []any, bool)
func ValidateKey ¶
ValidateKey validates an object key using io/fs path rules.
func ValidateKey(key string) error
Types ¶
type CacheControl ¶
CacheControl sets or requests a Cache-Control policy.
type CacheControl struct {
Value string
}
type ContentDisposition ¶
ContentDisposition sets or requests a Content-Disposition policy.
type ContentDisposition struct {
Value string
}
type ContentType ¶
ContentType sets or requests a content type.
type ContentType struct {
Value string
}
type Deleter ¶
Deleter is implemented by storages that can delete objects.
type Deleter interface {
Delete(context.Context, string, ...any) ([]any, error)
}
type DownloadName ¶
DownloadName requests a download filename for generated URLs.
type DownloadName struct {
Filename string
}
type Event ¶
Event describes a storage change.
type Event struct {
Key string
Op string
}
type Events ¶
Events streams storage change events.
type Events interface {
Next(context.Context) (Event, error)
Close() error
}
type ExpiresAt ¶
ExpiresAt requests a URL or token that expires at Time.
type ExpiresAt struct {
Time time.Time
}
type ExpiresIn ¶
ExpiresIn requests a URL or token that expires after Duration.
type ExpiresIn struct {
Duration time.Duration
}
type File ¶
File is an opened object. Callers must close it.
type File interface {
io.Reader
io.Closer
Stat() (Info, error)
}
type Filesystem ¶
Filesystem stores objects under a local root directory.
type Filesystem struct {
// contains filtered or unexported fields
}
func NewFilesystem ¶
NewFilesystem creates a filesystem storage rooted at root.
func NewFilesystem(root string, options ...FilesystemOption) *Filesystem
func (s *Filesystem) Delete ¶
Delete removes key.
func (s *Filesystem) Delete(ctx context.Context, key string, options ...any) ([]any, error)
func (s *Filesystem) List ¶
List lists object metadata below prefix.
func (s *Filesystem) List(ctx context.Context, prefix string, options ...any) (Iterator, []any, error)
func (s *Filesystem) Open ¶
Open opens key for reading.
func (s *Filesystem) Open(ctx context.Context, key string, options ...any) (File, []any, error)
func (s *Filesystem) Put ¶
Put writes key atomically where the host filesystem supports rename.
func (s *Filesystem) Put(ctx context.Context, key string, body io.Reader, options ...any) (Info, []any, error)
func (s *Filesystem) URL ¶
URL returns a public URL only when Filesystem was configured with a base URL.
func (s *Filesystem) URL(ctx context.Context, key string, options ...any) (URL, []any, error)
type FilesystemOption ¶
FilesystemOption configures a filesystem storage.
type FilesystemOption func(*Filesystem)
func WithBaseURL ¶
WithBaseURL lets Filesystem satisfy URLer. Leave it empty when lazyfiles should serve fallback application URLs instead.
func WithBaseURL(baseURL string) FilesystemOption
type Info ¶
Info describes a stored object.
type Info struct {
Key string
ContentType string
Size int64
Checksum string
ModifiedAt time.Time
Metadata map[string]any
}
type Iterator ¶
Iterator walks object metadata.
type Iterator interface {
Next() (Info, error)
Close() error
}
type Lister ¶
Lister is implemented by storages that can list object keys.
type Lister interface {
List(context.Context, string, ...any) (Iterator, []any, error)
}
type Private ¶
Private requests private access when the backend supports access policy.
type Private struct{}
type Public ¶
Public requests public access when the backend supports access policy.
type Public struct{}
type Storage ¶
Storage is the minimum read capability for a named object store.
type Storage interface {
Open(context.Context, string, ...any) (File, []any, error)
}
type URL ¶
URL describes a resolved object URL.
type URL struct {
String string
Public bool
ExpiresAt time.Time
}
type URLer ¶
URLer is implemented by storages that can expose object URLs.
type URLer interface {
URL(context.Context, string, ...any) (URL, []any, error)
}
type Watcher ¶
Watcher is implemented by storages that can watch for object changes.
type Watcher interface {
Watch(context.Context, string, ...any) (Events, []any, error)
}
type Writer ¶
Writer is implemented by storages that can write objects.
type Writer interface {
Put(context.Context, string, io.Reader, ...any) (Info, []any, error)
}
Directories ¶
| Path | Synopsis |
|---|---|
| lazystorage/s3 | Package s3 provides an S3-compatible lazystorage backend. |
Package lazystorage defines small interfaces for object-style storage.
Storage is the minimum read contract: Open receives an object key and returns a File that can be read, closed, and inspected with Stat. Optional interfaces add capabilities one at a time. Writer stores bytes with Put, Deleter removes a key, Lister returns object metadata below a prefix, URLer resolves an externally usable URL, and Watcher streams backend change events. Callers should test for the optional interface they need instead of assuming every backend can write, list, delete, or sign URLs.
Object keys are slash-separated logical paths, not host filesystem paths. ValidateKey applies io/fs path rules: keys must be relative, clean, and must not be ".". The local filesystem backend maps those keys below its configured root; S3-compatible and PostgreSQL backends store the same logical key in the remote bucket or database row. Prefixes passed to List and Watch use the same logical form and are matched by key prefix.
The variadic options are intentionally open-ended so storage can be composed with higher-level packages. An implementation consumes the options it knows and returns the remaining options to its caller. For example, filesystem Put consumes ContentType and leaves unknown options untouched, while lazystorage/s3 and pg/pgstorage also consume CacheControl and ContentDisposition. URL options such as ExpiresIn, ExpiresAt, Public, Private, and DownloadName are requests; a backend may use them, pass them through, or reject the operation when it cannot provide the requested URL. Use Take when writing decorators or services that need this same consume-and-forward behavior.
Info is metadata about the stored object. Key is always the logical key. ContentType, Size, Checksum, and ModifiedAt are best-effort backend metadata: filesystem writes compute a sha256 checksum and detect content type when not supplied, listing filesystem objects reports file size and modification time, and remote backends expose whatever their implementation can read cheaply. Metadata is reserved for backend-specific values that do not deserve their own portable field.
Higher-level packages depend on these narrow contracts. lazyassets.Registry uploads generated assets through a Writer, forwarding content type and cache policy for permanent hashed files and the manifest. lazyfiles stores file records separately from bytes and writes/opens those bytes through configured lazystorage backends; when a backend implements URLer, lazyfiles can return that direct URL, otherwise it falls back to application routes. lazymedia stores original media and generated variants through lazyfiles and lazystorage-backed file stores.
Use NewFilesystem for standalone local storage or development storage. Package lazystorage/s3 provides an S3-compatible backend for object stores such as AWS S3, MinIO, or SeaweedFS. The pg/pgstorage package in the golazy.dev/pg module provides a PostgreSQL implementation and migrations when keeping object bytes in the application database is the right tradeoff.