Documentation
¶
Overview ¶
Package custom implements user-defined mod sources configured declaratively via YAML files in <configDir>/sources/. See the design doc: docs/plans/2026-07-13-custom-sources-design.md
Index ¶
- Constants
- func New(def SourceDefinition) (source.ModSource, error)
- type APIConfig
- type APIKeyConfig
- type AuthConfig
- type Directory
- func (d *Directory) AuthURL() string
- func (d *Directory) Capabilities() source.Capabilities
- func (d *Directory) CheckUpdates(ctx context.Context, installed []domain.InstalledMod) ([]domain.Update, error)
- func (d *Directory) ExchangeToken(ctx context.Context, code string) (*source.Token, error)
- func (d *Directory) GetDependencies(ctx context.Context, mod *domain.Mod) ([]domain.ModReference, error)
- func (d *Directory) GetDownloadURL(ctx context.Context, mod *domain.Mod, fileID string) (string, error)
- func (d *Directory) GetMod(ctx context.Context, gameID, modID string) (*domain.Mod, error)
- func (d *Directory) GetModFiles(ctx context.Context, mod *domain.Mod) ([]domain.DownloadableFile, error)
- func (d *Directory) ID() string
- func (d *Directory) Name() string
- func (d *Directory) Search(ctx context.Context, query source.SearchQuery) (source.SearchResult, error)
- type DirectoryConfig
- type Manifest
- func (m *Manifest) AuthURL() string
- func (m *Manifest) Capabilities() source.Capabilities
- func (m *Manifest) CheckUpdates(ctx context.Context, installed []domain.InstalledMod) ([]domain.Update, error)
- func (m *Manifest) DownloadHeaders(fileURL string) map[string]string
- func (m *Manifest) ExchangeToken(ctx context.Context, code string) (*source.Token, error)
- func (m *Manifest) GetDependencies(ctx context.Context, mod *domain.Mod) ([]domain.ModReference, error)
- func (m *Manifest) GetDownloadURL(ctx context.Context, mod *domain.Mod, fileID string) (string, error)
- func (m *Manifest) GetMod(ctx context.Context, gameID, modID string) (*domain.Mod, error)
- func (m *Manifest) GetModFiles(ctx context.Context, mod *domain.Mod) ([]domain.DownloadableFile, error)
- func (m *Manifest) ID() string
- func (m *Manifest) IsAuthenticated() bool
- func (m *Manifest) Name() string
- func (m *Manifest) Search(ctx context.Context, query source.SearchQuery) (source.SearchResult, error)
- func (m *Manifest) SetAPIKey(key string)
- type ManifestConfig
- type SourceDefinition
Constants ¶
const ( TypeDirectory = "directory" TypeManifest = "manifest" TypeAPI = "api" )
Source type identifiers for SourceDefinition.Type.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type APIConfig ¶
type APIConfig struct {
BaseURL string `yaml:"base_url"`
}
APIConfig configures a declarative REST source (expanded in Phase 4).
type APIKeyConfig ¶ added in v1.7.0
type APIKeyConfig struct {
In string `yaml:"in"` // "header" or "query"
Name string `yaml:"name"` // header name or query parameter name
}
APIKeyConfig says where the API key is attached on requests.
type AuthConfig ¶ added in v1.7.0
type AuthConfig struct {
APIKey *APIKeyConfig `yaml:"api_key"`
}
AuthConfig configures optional API-key authentication for a custom source. The key itself is never stored in the definition; it comes from the LMM_<ID>_API_KEY env var or the DB token store at startup.
type Directory ¶
type Directory struct {
// contains filtered or unexported fields
}
Directory is a ModSource backed by a local directory: each subdirectory (or .zip/.jar archive) is one mod. The directory is rescanned on each operation so edits show up without restarting lmm; scans are local and cheap.
func NewDirectory ¶
func NewDirectory(def SourceDefinition) (*Directory, error)
NewDirectory constructs a directory source from a validated definition. The configured path must exist and be a directory.
func (*Directory) Capabilities ¶
func (d *Directory) Capabilities() source.Capabilities
Capabilities implements source.CapabilityReporter.
func (*Directory) CheckUpdates ¶
func (d *Directory) CheckUpdates(ctx context.Context, installed []domain.InstalledMod) ([]domain.Update, error)
CheckUpdates implements source.ModSource by comparing installed versions to the current scan.
func (*Directory) ExchangeToken ¶
ExchangeToken implements source.ModSource.
func (*Directory) GetDependencies ¶
func (d *Directory) GetDependencies(ctx context.Context, mod *domain.Mod) ([]domain.ModReference, error)
GetDependencies implements source.ModSource; directory mods declare none.
func (*Directory) GetDownloadURL ¶
func (d *Directory) GetDownloadURL(ctx context.Context, mod *domain.Mod, fileID string) (string, error)
GetDownloadURL implements source.ModSource, returning a file:// URL that Service.DownloadModToCache ingests by local copy instead of HTTP download.
func (*Directory) GetMod ¶
GetMod implements source.ModSource. gameID is accepted from any game and not used to look up the mod (see Search); it is echoed onto the returned mod so downstream installs are attributed to the correct game.
func (*Directory) GetModFiles ¶
func (d *Directory) GetModFiles(ctx context.Context, mod *domain.Mod) ([]domain.DownloadableFile, error)
GetModFiles implements source.ModSource: every mod has exactly one synthetic file ("main") representing its directory or archive.
func (*Directory) Search ¶
func (d *Directory) Search(ctx context.Context, query source.SearchQuery) (source.SearchResult, error)
Search implements source.ModSource with client-side matching: case-insensitive substring on name and summary; name matches rank first, then alphabetical. GameID is accepted from any game (a directory source applies to any game that maps it — it does not filter by GameID) but is echoed onto every returned mod so downstream installs are attributed to the correct game.
type DirectoryConfig ¶
type DirectoryConfig struct {
Path string `yaml:"path"`
}
DirectoryConfig configures a local-directory source.
type Manifest ¶ added in v1.7.0
type Manifest struct {
// contains filtered or unexported fields
}
Manifest is a ModSource backed by a published mod-list document (design §3). Remote manifests are fetched on demand and cached in memory for the configured TTL; local paths are read on every operation (cheap). Construction is pure: a valid definition always registers, and fetch/parse problems surface as operation errors naming the manifest URL.
func NewManifest ¶ added in v1.7.0
func NewManifest(def SourceDefinition) (*Manifest, error)
NewManifest constructs a manifest source from a validated definition. It performs no I/O — the manifest is first fetched when an operation needs it.
func (*Manifest) AuthURL ¶ added in v1.7.0
AuthURL implements source.ModSource; manifest sources use API keys, not OAuth.
func (*Manifest) Capabilities ¶ added in v1.7.0
func (m *Manifest) Capabilities() source.Capabilities
Capabilities implements source.CapabilityReporter. Auth reflects whether the definition declares an auth block.
func (*Manifest) CheckUpdates ¶ added in v1.7.0
func (m *Manifest) CheckUpdates(ctx context.Context, installed []domain.InstalledMod) ([]domain.Update, error)
CheckUpdates implements source.ModSource by comparing installed versions to the current manifest.
func (*Manifest) DownloadHeaders ¶ added in v1.7.0
DownloadHeaders implements source.DownloadHeaderProvider. Header-mode auth applies the same key to file downloads as to manifest fetches (design §6), but for remote manifests only when the file URL is same-origin (scheme and host, via sameOrigin) with the manifest — a manifest pointing files at a third-party CDN, or downgrading from https to http on the same host, must not ship the repo's key there. Local-path manifests are user-authored and trusted, so their configured key attaches regardless of host.
func (*Manifest) ExchangeToken ¶ added in v1.7.0
ExchangeToken implements source.ModSource.
func (*Manifest) GetDependencies ¶ added in v1.7.0
func (m *Manifest) GetDependencies(ctx context.Context, mod *domain.Mod) ([]domain.ModReference, error)
GetDependencies implements source.ModSource: manifest dependencies are IDs within this source, returned as ModReferences for the resolver.
func (*Manifest) GetDownloadURL ¶ added in v1.7.0
func (m *Manifest) GetDownloadURL(ctx context.Context, mod *domain.Mod, fileID string) (string, error)
GetDownloadURL implements source.ModSource. Query-mode auth is appended here — for remote manifests, only when the file URL is same-origin with the manifest (see sameOrigin); a manifest pointing files at a third-party CDN must not ship the repo's key there via the URL either. Header-mode auth rides via DownloadHeaders (see DownloadHeaderProvider) under the same rule.
func (*Manifest) GetMod ¶ added in v1.7.0
GetMod implements source.ModSource. gameID does not filter (install-by-ID works from any game); it is echoed onto the returned mod for attribution.
func (*Manifest) GetModFiles ¶ added in v1.7.0
func (m *Manifest) GetModFiles(ctx context.Context, mod *domain.Mod) ([]domain.DownloadableFile, error)
GetModFiles implements source.ModSource, mapping manifest file entries — including declared sha256 checksums — onto DownloadableFiles.
func (*Manifest) IsAuthenticated ¶ added in v1.7.0
IsAuthenticated reports whether an API key is configured. Only meaningful when the definition declares auth (Capabilities().Auth).
func (*Manifest) Search ¶ added in v1.7.0
func (m *Manifest) Search(ctx context.Context, query source.SearchQuery) (source.SearchResult, error)
Search implements source.ModSource with the shared client-side semantics (design §5), filtered by the manifest's per-mod game_ids.
type ManifestConfig ¶
type ManifestConfig struct {
URL string `yaml:"url"`
Refresh string `yaml:"refresh"` // Go duration string, e.g. "15m"; empty = default
Auth *AuthConfig `yaml:"auth"`
}
ManifestConfig configures a manifest source (Phase 3).
type SourceDefinition ¶
type SourceDefinition struct {
ID string `yaml:"id"`
Name string `yaml:"name"`
Type string `yaml:"type"`
AllowHTTP bool `yaml:"allow_http"`
Directory *DirectoryConfig `yaml:"directory"`
Manifest *ManifestConfig `yaml:"manifest"`
API *APIConfig `yaml:"api"`
}
SourceDefinition is one user-defined source, parsed from a YAML file in <configDir>/sources/. Exactly one of Directory/Manifest/API must be set, matching Type.
func (*SourceDefinition) Validate ¶
func (d *SourceDefinition) Validate() error
Validate checks the definition for structural errors. It does not touch the filesystem or network; existence checks happen when the source is constructed.