Documentation
¶
Index ¶
- Constants
- Variables
- func ConfigViper(envPrefix string) (*viper.Viper, error)
- func GetExtraConfig[T any](c *Config) (T, bool)
- func IsBadRequestError(err error) bool
- func IsBusinessError(err error) bool
- func IsForbiddenError(err error) bool
- func IsInternalError(err error) bool
- func IsNotFoundError(err error) bool
- func IsUnauthorizedError(err error) bool
- func Load(dest any, envPrefix string) error
- func MustGetExtraConfig[T any](c *Config) T
- func NewLogger(config *LogConfig) *slog.Logger
- func RegisterPostLoadHook(hook LoaderOption)
- func SortableMSToTime(st string) time.Time
- func SortableToTime(st string) time.Time
- func TimeToSortable(t time.Time) string
- func TimeToSortableMS(t time.Time) string
- func TruncateToSecond(t time.Time) time.Time
- type AppConfig
- type Config
- type DatabaseConfig
- type Error
- func GetError(err error) *Error
- func NewBadRequestError(subject, message string) *Error
- func NewBusinessError(subject, message string) *Error
- func NewError(errorType ErrorType, subject, message string) *Error
- func NewForbiddenError(subject, message string) *Error
- func NewInternalError(subject, message string) *Error
- func NewNotFoundError(subject, message string) *Error
- func NewUnauthorizedError(subject, message string) *Error
- func (e *Error) Error() string
- func (e *Error) Is(target error) bool
- func (e *Error) MarshalJSON() ([]byte, error)
- func (e *Error) Unwrap() error
- func (e *Error) WithCode(code int) *Error
- func (e *Error) WithInner(inner error) *Error
- func (e *Error) WithMessage(message string, params ...any) *Error
- func (e *Error) WithParams(keyvals ...any) *Error
- func (e *Error) WithSubject(subject string) *Error
- type ErrorResponse
- type ErrorType
- type FixedClock
- type LoaderOption
- type LogConfig
- type LogOutputConfig
- type MessagingConfig
- type ServerConfig
- type SystemClock
- type TimeProvider
Constants ¶
const ( EnvTest = "test" EnvDevelopment = "development" EnvProduction = "production" )
Variables ¶
var ( ErrBadRequest = NewBadRequestError("General", "Bad Request") ErrNotFound = NewNotFoundError("General", "Not Found") ErrBusiness = NewBusinessError("General", "Business") ErrForbidden = NewForbiddenError("General", "Forbidden") ErrInternal = NewInternalError("General", "Internal") )
var Clock = SystemClock{}
Clock is a process-wide SystemClock kept for backward compatibility. Prefer injecting a TimeProvider (host.WithClock) over reaching for this global.
Functions ¶
func ConfigViper ¶
ConfigViper builds the viper instance microjet uses to load configuration: it searches the standard config paths, reads config.toml plus an optional config.local.toml overlay, and binds APP_* environment overrides. It is exported so provider-specific modules (e.g. aws) can load their own typed config sections via Get/UnmarshalKey without core having to depend on them.
func GetExtraConfig ¶ added in v0.3.0
GetExtraConfig casts Config.Extra to T, returning false if the cast fails.
func IsBadRequestError ¶
func IsBusinessError ¶
func IsForbiddenError ¶
func IsInternalError ¶
func IsNotFoundError ¶
func IsUnauthorizedError ¶
func MustGetExtraConfig ¶
MustGetExtraConfig casts Config.Extra to T, panicking if the cast fails.
func NewLogger ¶
NewLogger constructs a *slog.Logger from LogConfig. Console output is always enabled unless config.Console.Enabled=false. A second file output is added when config.File.Enabled=true and config.File.Path is set. Each output has its own level and format, falling back to config.Level and config.Format.
func RegisterPostLoadHook ¶
func RegisterPostLoadHook(hook LoaderOption)
func SortableMSToTime ¶
func SortableToTime ¶
func TimeToSortable ¶
func TimeToSortableMS ¶
TimeToSortableMS formats t as a 17-digit lexicographically sortable string with millisecond precision: YYYYMMDDHHMMSSmmm. Go only recognizes fractional seconds when preceded by a separator, so we format with a dot and strip it.
Types ¶
type AppConfig ¶
type AppConfig struct {
Namespace string `mapstructure:"namespace"`
Environment string `mapstructure:"environment"`
Name string `mapstructure:"name"`
Version string `mapstructure:"version"`
Debug bool `mapstructure:"debug"`
}
func (*AppConfig) GetEnvironment ¶
func (*AppConfig) GetVersion ¶
func (*AppConfig) IsDevelopment ¶
func (*AppConfig) IsProduction ¶
type Config ¶
type Config struct {
App *AppConfig `mapstructure:"app"`
Server *ServerConfig `mapstructure:"server"`
Database *DatabaseConfig `mapstructure:"database"`
// Databases holds additional named connections from the [databases.<name>]
// config tables, registered via host.WithDatabasesFromConfig. The single
// [database] section above remains the default connection.
Databases map[string]*DatabaseConfig `mapstructure:"databases"`
Messaging *MessagingConfig `mapstructure:"messaging"`
Log *LogConfig `mapstructure:"log"`
Extra any `mapstructure:"extra"`
}
func LoadConfig ¶
LoadConfig loads application configuration from a TOML file. Searches cwd, cwd/config, executable dir, and executable_dir/config. A config.local.toml in the same directories is merged on top if present. Environment variables prefixed with APP_ override any file value (dots → underscores).
type DatabaseConfig ¶
type Error ¶
type Error struct {
Type ErrorType `json:"type"`
Subject string `json:"subject"`
Message string `json:"message"`
Params map[string]any `json:"params,omitempty"`
Code int `json:"code"`
Inner error `json:"-"`
}
func NewBadRequestError ¶
func NewBusinessError ¶
func NewForbiddenError ¶
func NewInternalError ¶
func NewNotFoundError ¶
func NewUnauthorizedError ¶
func (*Error) Is ¶
Is reports whether e matches target for errors.Is, letting a typed *Error be used as a sentinel by category. target matches when it is an *Error of the same Type; if target also sets a non-zero Code it must match, and if target sets a Subject other than the default "General" it must match too. This makes the package sentinels match any error of their category — errors.Is(err, ErrNotFound) is true for any NotFound error — while a custom sentinel carrying a Subject and/or Code matches more narrowly. Wrapped non-Error sentinels still match through Unwrap as usual.
func (*Error) MarshalJSON ¶
func (*Error) WithMessage ¶
WithMessage returns a copy of the error with the message replaced. Optional key-value pairs are merged into Params (same semantics as WithParams).
func (*Error) WithParams ¶
WithParams returns a copy of the error with additional key-value pairs merged into Params. Keys must be strings; non-string keys are silently skipped.
func (*Error) WithSubject ¶
type ErrorResponse ¶
type ErrorResponse struct {
Error string `json:"error"`
Subject string `json:"subject"`
Message string `json:"message"`
Params map[string]any `json:"params,omitempty"`
Code int `json:"code"`
InnerError *string `json:"innerError,omitempty"`
}
ErrorResponse is the JSON body returned by the HTTP error middleware.
type ErrorType ¶
type ErrorType string
ErrorType identifies the category of an error and controls HTTP status mapping: BadRequest→400, Unauthorized→401, Forbidden→403, NotFound→404, Business→409, Internal→500.
func GetErrorType ¶
type FixedClock ¶
FixedClock is a TimeProvider that reports a preset time, for deterministic tests. It is not safe for concurrent mutation; set the time before use.
func NewFixedClock ¶
func NewFixedClock(t time.Time) *FixedClock
NewFixedClock returns a FixedClock pinned to t (normalized to UTC).
func (*FixedClock) Advance ¶
func (c *FixedClock) Advance(d time.Duration)
Advance moves the clock forward by d.
func (*FixedClock) Now ¶
func (c *FixedClock) Now() time.Time
func (*FixedClock) NowSortable ¶
func (c *FixedClock) NowSortable() string
func (*FixedClock) NowSortableMS ¶
func (c *FixedClock) NowSortableMS() string
func (*FixedClock) NowTS ¶
func (c *FixedClock) NowTS() int64
func (*FixedClock) Set ¶
func (c *FixedClock) Set(t time.Time)
Set replaces the time the clock reports.
type LoaderOption ¶
type LogConfig ¶
type LogConfig struct {
Level string `mapstructure:"level"`
Format string `mapstructure:"format"`
Console *LogOutputConfig `mapstructure:"console"`
File *LogOutputConfig `mapstructure:"file"`
}
LogConfig configures the logger. Console output is always enabled unless explicitly disabled via Console.Enabled=false. A file output is added when File.Enabled=true and File.Path is set. Each output can independently override the top-level Level and Format. Valid levels: debug, info, warn, error. Valid formats: text, json.
type LogOutputConfig ¶
type LogOutputConfig struct {
Enabled bool `mapstructure:"enabled"`
Level string `mapstructure:"level"` // overrides LogConfig.Level for this output
Format string `mapstructure:"format"` // overrides LogConfig.Format for this output
Path string `mapstructure:"path"` // file output only; parent dirs are created automatically
}
LogOutputConfig configures a single log output destination (console or file).
type MessagingConfig ¶
type ServerConfig ¶
type SystemClock ¶
type SystemClock struct{}
SystemClock is a TimeProvider backed by the real wall clock, normalized to UTC.
func (SystemClock) Now ¶
func (SystemClock) Now() time.Time
Value receivers so both SystemClock{} and &SystemClock{} satisfy TimeProvider.
func (SystemClock) NowSortable ¶
func (c SystemClock) NowSortable() string
func (SystemClock) NowSortableMS ¶
func (c SystemClock) NowSortableMS() string
func (SystemClock) NowTS ¶
func (c SystemClock) NowTS() int64
type TimeProvider ¶
type TimeProvider interface {
Now() time.Time
NowTS() int64
NowSortable() string
NowSortableMS() string
}
TimeProvider supplies the current time. Inject it (e.g. via host.WithClock) so time-dependent code can be made deterministic in tests by swapping in a FixedClock instead of reaching for time.Now() directly.
var UTC TimeProvider = SystemClock{}
UTC is the default real-time clock, used when no clock is injected.