core

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 5, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Index

Constants

View Source
const (
	EnvTest        = "test"
	EnvDevelopment = "development"
	EnvProduction  = "production"
)

Variables

View Source
var (
	ErrBadRequest   = NewBadRequestError("General", "Bad Request")
	ErrNotFound     = NewNotFoundError("General", "Not Found")
	ErrBusiness     = NewBusinessError("General", "Business")
	ErrUnauthorized = NewUnauthorizedError("General", "Unauthorized")
	ErrForbidden    = NewForbiddenError("General", "Forbidden")
	ErrInternal     = NewInternalError("General", "Internal")
)
View Source
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

func ConfigViper(envPrefix string) (*viper.Viper, error)

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 GetExtra

func GetExtra[T any](c *Config, key string) (T, error)

func IsBadRequestError

func IsBadRequestError(err error) bool

func IsBusinessError

func IsBusinessError(err error) bool

func IsForbiddenError

func IsForbiddenError(err error) bool

func IsInternalError

func IsInternalError(err error) bool

func IsNotFoundError

func IsNotFoundError(err error) bool

func IsUnauthorizedError

func IsUnauthorizedError(err error) bool

func Load

func Load(dest any, envPrefix string) error

func MustGetExtraConfig

func MustGetExtraConfig[T any](c *Config, key string) T

func NewLogger

func NewLogger(config *LogConfig) *slog.Logger

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 SortableMSToTime(st string) time.Time

func SortableToTime

func SortableToTime(st string) time.Time

func TimeToSortable

func TimeToSortable(t time.Time) string

func TimeToSortableMS

func TimeToSortableMS(t time.Time) string

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.

func TruncateToSecond

func TruncateToSecond(t time.Time) time.Time

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) GetDebug

func (a *AppConfig) GetDebug() bool

func (*AppConfig) GetEnvironment

func (a *AppConfig) GetEnvironment() string

func (*AppConfig) GetName

func (a *AppConfig) GetName() string

func (*AppConfig) GetVersion

func (a *AppConfig) GetVersion() string

func (*AppConfig) IsDevelopment

func (a *AppConfig) IsDevelopment() bool

func (*AppConfig) IsProduction

func (a *AppConfig) IsProduction() bool

func (*AppConfig) IsTest

func (a *AppConfig) IsTest() bool

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     map[string]any             `mapstructure:"extra"`
}

func LoadConfig

func LoadConfig() (*Config, error)

func (*Config) GetExtra

func (c *Config) GetExtra(key string) (any, bool)

func (*Config) MustGetExtra

func (c *Config) MustGetExtra(key string) any

func (*Config) MustGetExtraBool

func (c *Config) MustGetExtraBool(key string) bool

func (*Config) MustGetExtraFloat32

func (c *Config) MustGetExtraFloat32(key string) float32

func (*Config) MustGetExtraFloat64

func (c *Config) MustGetExtraFloat64(key string) float64

func (*Config) MustGetExtraInt32

func (c *Config) MustGetExtraInt32(key string) int32

func (*Config) MustGetExtraInt64

func (c *Config) MustGetExtraInt64(key string) int64

func (*Config) MustGetExtraString

func (c *Config) MustGetExtraString(key string) string

type DatabaseConfig

type DatabaseConfig struct {
	Driver   string `mapstructure:"driver"`
	Host     string `mapstructure:"host"`
	Port     int    `mapstructure:"port"`
	User     string `mapstructure:"user"`
	Password string `mapstructure:"password"`
	Name     string `mapstructure:"name"`
	SSLMode  string `mapstructure:"sslMode"`
}

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 GetError

func GetError(err error) *Error

func NewBadRequestError

func NewBadRequestError(subject, message string) *Error

func NewBusinessError

func NewBusinessError(subject, message string) *Error

func NewError

func NewError(errorType ErrorType, subject, message string) *Error

func NewForbiddenError

func NewForbiddenError(subject, message string) *Error

func NewInternalError

func NewInternalError(subject, message string) *Error

func NewNotFoundError

func NewNotFoundError(subject, message string) *Error

func NewUnauthorizedError

func NewUnauthorizedError(subject, message string) *Error

func (*Error) Error

func (e *Error) Error() string

func (*Error) Is

func (e *Error) Is(target error) bool

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 (e *Error) MarshalJSON() ([]byte, error)

func (*Error) Unwrap

func (e *Error) Unwrap() error

func (*Error) WithCode

func (e *Error) WithCode(code int) *Error

func (*Error) WithInner

func (e *Error) WithInner(inner error) *Error

func (*Error) WithMessage

func (e *Error) WithMessage(message string, params ...any) *Error

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

func (e *Error) WithParams(keyvals ...any) *Error

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

func (e *Error) WithSubject(subject string) *Error

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.

const (
	BadRequestErrorType   ErrorType = "BAD_REQUEST"
	NotFoundErrorType     ErrorType = "NOT_FOUND"
	BusinessErrorType     ErrorType = "BUSINESS"
	UnauthorizedErrorType ErrorType = "UNAUTHORIZED"
	ForbiddenErrorType    ErrorType = "FORBIDDEN"
	InternalErrorType     ErrorType = "INTERNAL"
)

func GetErrorType

func GetErrorType(err error) (ErrorType, bool)

type FixedClock

type FixedClock struct{ T time.Time }

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 LoaderOption func(any) error

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 MessagingConfig struct {
	URL     string `mapstructure:"url"`
	Source  string `mapstructure:"source"`
	Version int    `mapstructure:"version"`
}

type ServerConfig

type ServerConfig struct {
	Host string `mapstructure:"host"`
	Port int    `mapstructure:"port"`
}

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.

UTC is the default real-time clock, used when no clock is injected.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL