Documentation
¶
Index ¶
- Variables
- func TypeLabelOf(src ModSource) string
- type AuthInstructionsProvider
- type Capabilities
- type CapabilityReporter
- type DownloadHeaderProvider
- type EnvKeyProvider
- type GameCatalog
- type GameEntry
- type KeyValidator
- type MergeCompiler
- type MergeFailure
- type MergeSource
- type ModSource
- type Registry
- type SearchQuery
- type SearchResult
- type Token
- type TypeLabeler
Constants ¶
This section is empty.
Variables ¶
var ErrNotSupported = errors.New("operation not supported by this source")
ErrNotSupported indicates a source does not support the requested operation. Callers should branch with errors.Is(err, ErrNotSupported) and degrade gracefully (hide the action, show a notice) rather than treat it as a failure.
Functions ¶
func TypeLabelOf ¶ added in v1.21.0
TypeLabelOf returns src's self-reported kind ("directory"/"manifest"/ "api" for custom sources, "built-in" for NexusMods/CurseForge), falling back to "unknown" when src implements no TypeLabeler. Mirrors CapabilitiesOf's optional-interface pattern; the fallback is unreachable in production (every real source implements TypeLabeler), reachable only by bare test doubles.
Types ¶
type AuthInstructionsProvider ¶ added in v1.21.0
type AuthInstructionsProvider interface{ AuthInstructions() string }
AuthInstructionsProvider supplies human setup steps for obtaining a key. Absent: generic instructions naming the env var.
type Capabilities ¶ added in v1.6.0
type Capabilities struct {
Search bool
Dependencies bool
Updates bool
Auth bool
// Versions: the source CAN carry per-file Version strings usable for
// exact version->file resolution (#96). Advisory, not a guarantee:
// resolution itself degrades dynamically per mod - a file list with no
// version data yields ErrNotSupported even when this is true (see
// core.ResolveVersionFiles).
Versions bool
}
Capabilities reports which optional operations a source supports.
func CapabilitiesOf ¶ added in v1.6.0
func CapabilitiesOf(src ModSource) Capabilities
CapabilitiesOf returns src's capabilities. Sources that do not implement CapabilityReporter are assumed fully capable — a default kept for test doubles; production sources should implement CapabilityReporter explicitly rather than rely on this fallback.
type CapabilityReporter ¶ added in v1.6.0
type CapabilityReporter interface {
Capabilities() Capabilities
}
CapabilityReporter is implemented by sources that support only a subset of ModSource operations. Sources that do not implement it are assumed fully capable.
type DownloadHeaderProvider ¶ added in v1.7.0
DownloadHeaderProvider is implemented by sources whose file downloads need extra HTTP headers (e.g. header-mode API-key auth on a manifest source). Service.DownloadModToCache consults it with the resolved download URL so the source can scope credentials (e.g. same-origin only). A nil map means no extra headers.
type EnvKeyProvider ¶ added in v1.21.0
type EnvKeyProvider interface{ EnvKey() string }
EnvKeyProvider names the environment variable consulted for this source's API key. Absent: the derived LMM_<ID>_API_KEY convention applies.
type GameCatalog ¶ added in v1.21.0
GameCatalog lists the games a source knows about, for interactive game-creation flows. Absent: manual identifier entry.
type GameEntry ¶ added in v1.21.0
type GameEntry struct{ ID, Name, Slug string }
GameEntry is one game known to a source's catalog, for interactive game-creation flows.
type KeyValidator ¶ added in v1.21.0
KeyValidator performs a live API-key check at auth-login time. Absent: keys are stored and validated on first use.
type MergeCompiler ¶ added in v1.28.0
type MergeCompiler interface {
// ValidateSource parses/validates sourceFilePath (the retained,
// not-yet-merged source archive) without compiling anything - called at
// ingest time (download/import) so a malformed archive fails loud
// immediately rather than at the next merge.
ValidateSource(sourceFilePath string) error
// MergeCompile applies every entry in sources, in order (profile load
// order), against the base artifact's tables, and writes the merged
// result to outputPath. Returns non-fatal warnings (e.g. same-path
// asset collisions - last-applied wins) alongside a nil error; a nil
// error with warnings is still a fully-written, deployable artifact.
// Convertible-kind sources that cannot be converted are skipped per-mod
// and reported in failed (#221) - only native-source errors and I/O
// failures are fatal.
MergeCompile(ctx context.Context, baseArtifactPath string, sources []MergeSource, outputPath string) (warnings []string, failed []MergeFailure, err error)
// ResolveBaseArtifact locates the installed game's base artifact - the
// input every merge applies against (Icarus: the game's own
// Content/Data/data.pak). Errors when the artifact cannot be found
// under the game's install path.
ResolveBaseArtifact(game *domain.Game) (string, error)
// FingerprintBase returns an opaque fingerprint of the base artifact at
// baseArtifactPath: cheap to compute, changing exactly when the base
// content changes. Core stores it in merge fingerprints to detect a
// game-update-invalidated merge; it never interprets the value.
FingerprintBase(baseArtifactPath string) (string, error)
// IsNativeMergeSource reports whether fileName names this source's
// NATIVE merge-source format (Icarus: a ".exmodz" archive) - the diff
// format MergeCompile consumes directly, with no other valid
// interpretation at ingest. Pure format test, the mirror of
// IsConvertibleArtifact - core owns the DeployCompile policy gates and
// routes native files into validate+retain instead of extract/copy.
IsNativeMergeSource(fileName string) bool
// IsConvertibleArtifact reports whether fileName names a raw, prebuilt
// game artifact this source can convert into a merge source (#221;
// Icarus: a ".pak" file). Pure format test - core owns the
// DeployCompile/ConvertPaks policy gates that decide whether such a
// file actually enters the merge-convert pipeline.
IsConvertibleArtifact(fileName string) bool
// ClassifyMergeSource maps a retained-source identity - a fileID, an
// imported archive's filename, or a Kind string previously recorded on
// a merge fingerprint - to the source-defined kind string core
// round-trips (MergeSource.Kind, fingerprint entries) and whether that
// kind is a convertible raw artifact (subject to the ConvertPaks
// opt-out and per-mod conversion outcomes) as opposed to the source's
// native mergeable format. Must accept the empty string (legacy
// fingerprints recorded no Kind) and classify it as the native kind.
ClassifyMergeSource(id string) (kind string, convertible bool)
// MergedArtifactName names the single merged output artifact core
// deploys into the game's mod directory. The name is a deploy contract:
// it must stay stable across merges (core stats/replaces it by name),
// and any load-order significance it carries (Icarus: sorts last so it
// wins) is entirely the source's concern.
MergedArtifactName() string
// MergedArtifactLabel is the user-facing display name for the merged
// artifact's synthetic mod row (verify/update output).
MergedArtifactLabel() string
// RestoredArtifactName names the deployable raw-fallback copy core
// synthesizes when healing a prune-damaged cache entry whose original
// artifact name is unrecoverable (#250; Icarus: "<modID>_P.pak").
// Deterministic per mod - the same mod must always restore to the same
// name, since the name is on-disk state existing installs depend on.
// Core passes a path-safe (Base'd) modID and uses the result as a
// filename within the mod's own cache entry.
RestoredArtifactName(modID string) string
}
MergeCompiler is implemented by sources whose compile-eligible files must be merged across every enabled mod into ONE profile-level artifact rather than compiled per-mod (#197: Icarus's cross-mod table merge - a whole-pak last-wins deploy would silently drop one mod's table rows whenever two mods patch the same table). Replaces #196's Compiler interface, which this source no longer implements: there is no more per-mod compiled artifact to produce.
This interface is the complete contract a DeployCompile game must implement (#256): the merge operations (ValidateSource, MergeCompile) plus the format vocabulary core needs to orchestrate them without knowing the game's artifact format itself - where the base artifact lives (ResolveBaseArtifact), how to fingerprint it (FingerprintBase), which files are the source's native merge format (IsNativeMergeSource), which are convertible raw artifacts (IsConvertibleArtifact, ClassifyMergeSource), what the merged output is called (MergedArtifactName, MergedArtifactLabel), and what a healed raw-fallback copy is called (RestoredArtifactName). A second compile-mode game is a new source package implementing these methods plus one registration line; internal/core never changes.
type MergeFailure ¶ added in v1.30.0
MergeFailure records one source that could not participate in a merge (#221: an irreconcilable pak). The merge itself still succeeds - the failed mod is skipped and falls back to raw deploy; core uses this list to reconcile cache manifests and record outcomes in the fingerprint.
type MergeSource ¶ added in v1.28.0
type MergeSource struct {
ModRef string // "sourceID:modID" - machine identity (MergeFailure, ownership tracking)
ModName string // display name preferred over ModRef in user-facing warnings; may be empty
SourcePath string // the retained source archive to read (native diff, or a convertible raw artifact - #221)
Kind string // source-defined kind from ClassifyMergeSource; empty means the source's native kind (#256)
}
MergeSource identifies one mod's contribution to a merge, in the order it must be applied (profile load order).
type ModSource ¶
type ModSource interface {
// Identity
ID() string
Name() string
// Authentication
AuthURL() string
ExchangeToken(ctx context.Context, code string) (*Token, error)
// Discovery
Search(ctx context.Context, query SearchQuery) (SearchResult, error)
GetMod(ctx context.Context, gameID, modID string) (*domain.Mod, error)
GetDependencies(ctx context.Context, mod *domain.Mod) ([]domain.ModReference, error)
// Downloads
GetModFiles(ctx context.Context, mod *domain.Mod) ([]domain.DownloadableFile, error)
GetDownloadURL(ctx context.Context, mod *domain.Mod, fileID string) (string, error)
// Updates
CheckUpdates(ctx context.Context, installed []domain.InstalledMod) ([]domain.Update, error)
}
ModSource is the interface for mod repositories
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry manages available mod sources
type SearchQuery ¶
type SearchQuery struct {
GameID string
Query string
Category string // Optional category filter (source-specific: ID or name)
Tags []string // Optional tag filters (source-specific)
Page int
PageSize int
}
SearchQuery contains parameters for searching mods.
type SearchResult ¶ added in v1.3.0
type SearchResult struct {
Mods []domain.Mod
TotalCount int // Total results available (0 if unknown)
Page int
PageSize int
}
SearchResult contains paginated search results.
type TypeLabeler ¶ added in v1.21.0
type TypeLabeler interface{ TypeLabel() string }
TypeLabeler names the source's kind for listings (directory/manifest/api/ built-in). Absent: "unknown".
Directories
¶
| Path | Synopsis |
|---|---|
|
Package custom implements user-defined mod sources configured declaratively via YAML files in <configDir>/sources/.
|
Package custom implements user-defined mod sources configured declaratively via YAML files in <configDir>/sources/. |
|
metadata
Package metadata extracts mod metadata from well-known files inside a mod directory (e.g.
|
Package metadata extracts mod metadata from well-known files inside a mod directory (e.g. |
|
Package httpclient is a thin JSON HTTP client used by mod-source SDKs (NexusMods, CurseForge, ...).
|
Package httpclient is a thin JSON HTTP client used by mod-source SDKs (NexusMods, CurseForge, ...). |