mirror of
https://github.com/router-for-me/CLIProxyAPI.git
synced 2026-07-01 14:24:29 +08:00
173 lines
6.1 KiB
Go
173 lines
6.1 KiB
Go
// Package pluginstore exposes plugin registry and artifact installation helpers
|
|
// for embedders such as CLIProxyAPIHome.
|
|
package pluginstore
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
internalpluginstore "github.com/router-for-me/CLIProxyAPI/v7/internal/pluginstore"
|
|
)
|
|
|
|
const (
|
|
DefaultRegistryURL = internalpluginstore.DefaultRegistryURL
|
|
DefaultSourceID = internalpluginstore.DefaultSourceID
|
|
DefaultSourceName = internalpluginstore.DefaultSourceName
|
|
SchemaVersion = internalpluginstore.SchemaVersion
|
|
)
|
|
|
|
type Source = internalpluginstore.Source
|
|
type Registry = internalpluginstore.Registry
|
|
type Plugin = internalpluginstore.Plugin
|
|
type Release = internalpluginstore.Release
|
|
type ReleaseAsset = internalpluginstore.ReleaseAsset
|
|
type InstallOptions = internalpluginstore.InstallOptions
|
|
type InstallResult = internalpluginstore.InstallResult
|
|
|
|
type HTTPDoer interface {
|
|
Do(*http.Request) (*http.Response, error)
|
|
}
|
|
|
|
var ErrLoadedPluginLocked = internalpluginstore.ErrLoadedPluginLocked
|
|
|
|
type Client struct {
|
|
inner internalpluginstore.Client
|
|
}
|
|
|
|
type Manifest struct {
|
|
ID string `yaml:"id,omitempty" json:"id,omitempty"`
|
|
Name string `yaml:"name,omitempty" json:"name,omitempty"`
|
|
Description string `yaml:"description,omitempty" json:"description,omitempty"`
|
|
Author string `yaml:"author,omitempty" json:"author,omitempty"`
|
|
Version string `yaml:"version,omitempty" json:"version,omitempty"`
|
|
ReleaseTag string `yaml:"release-tag,omitempty" json:"release_tag,omitempty"`
|
|
Repository string `yaml:"repository,omitempty" json:"repository,omitempty"`
|
|
Logo string `yaml:"logo,omitempty" json:"logo,omitempty"`
|
|
Homepage string `yaml:"homepage,omitempty" json:"homepage,omitempty"`
|
|
License string `yaml:"license,omitempty" json:"license,omitempty"`
|
|
Tags []string `yaml:"tags,omitempty" json:"tags,omitempty"`
|
|
SourceID string `yaml:"source-id,omitempty" json:"source_id,omitempty"`
|
|
SourceName string `yaml:"source-name,omitempty" json:"source_name,omitempty"`
|
|
SourceURL string `yaml:"source-url,omitempty" json:"source_url,omitempty"`
|
|
}
|
|
|
|
func NewClient(httpClient HTTPDoer, registryURL string) Client {
|
|
return Client{inner: internalpluginstore.Client{
|
|
HTTPClient: httpClient,
|
|
RegistryURL: strings.TrimSpace(registryURL),
|
|
}}
|
|
}
|
|
|
|
func DefaultSource() Source {
|
|
return internalpluginstore.DefaultSource()
|
|
}
|
|
|
|
func NormalizeSources(registryURLs []string) ([]Source, error) {
|
|
return internalpluginstore.NormalizeSources(registryURLs)
|
|
}
|
|
|
|
func SourceID(registryURL string) string {
|
|
return internalpluginstore.SourceID(registryURL)
|
|
}
|
|
|
|
func ValidatePlugin(plugin Plugin) error {
|
|
return internalpluginstore.ValidatePlugin(plugin)
|
|
}
|
|
|
|
func UpdateAvailable(installed, latest string) bool {
|
|
return internalpluginstore.UpdateAvailable(installed, latest)
|
|
}
|
|
|
|
func ReleaseVersion(release Release) (string, error) {
|
|
return internalpluginstore.ReleaseVersion(release)
|
|
}
|
|
|
|
func ManifestFromRelease(source Source, plugin Plugin, release Release) (Manifest, error) {
|
|
version, errVersion := internalpluginstore.ReleaseVersion(release)
|
|
if errVersion != nil {
|
|
return Manifest{}, errVersion
|
|
}
|
|
return Manifest{
|
|
ID: strings.TrimSpace(plugin.ID),
|
|
Name: strings.TrimSpace(plugin.Name),
|
|
Description: strings.TrimSpace(plugin.Description),
|
|
Author: strings.TrimSpace(plugin.Author),
|
|
Version: version,
|
|
ReleaseTag: strings.TrimSpace(release.TagName),
|
|
Repository: strings.TrimSpace(plugin.Repository),
|
|
Logo: strings.TrimSpace(plugin.Logo),
|
|
Homepage: strings.TrimSpace(plugin.Homepage),
|
|
License: strings.TrimSpace(plugin.License),
|
|
Tags: append([]string(nil), plugin.Tags...),
|
|
SourceID: strings.TrimSpace(source.ID),
|
|
SourceName: strings.TrimSpace(source.Name),
|
|
SourceURL: strings.TrimSpace(source.URL),
|
|
}, nil
|
|
}
|
|
|
|
func (m Manifest) Plugin() Plugin {
|
|
return Plugin{
|
|
ID: strings.TrimSpace(m.ID),
|
|
Name: strings.TrimSpace(m.Name),
|
|
Description: strings.TrimSpace(m.Description),
|
|
Author: strings.TrimSpace(m.Author),
|
|
Version: strings.TrimSpace(m.Version),
|
|
Repository: strings.TrimSpace(m.Repository),
|
|
Logo: strings.TrimSpace(m.Logo),
|
|
Homepage: strings.TrimSpace(m.Homepage),
|
|
License: strings.TrimSpace(m.License),
|
|
Tags: append([]string(nil), m.Tags...),
|
|
}
|
|
}
|
|
|
|
func (m Manifest) Validate() error {
|
|
version := strings.TrimSpace(m.Version)
|
|
if version == "" {
|
|
return fmt.Errorf("missing required field version")
|
|
}
|
|
releaseTag := strings.TrimSpace(m.ReleaseTag)
|
|
if releaseTag == "" {
|
|
return fmt.Errorf("missing required field release-tag")
|
|
}
|
|
if errValidate := internalpluginstore.ValidatePlugin(m.Plugin()); errValidate != nil {
|
|
return errValidate
|
|
}
|
|
releaseVersion, errVersion := internalpluginstore.ReleaseVersion(internalpluginstore.Release{TagName: releaseTag})
|
|
if errVersion != nil {
|
|
return errVersion
|
|
}
|
|
if releaseVersion != version {
|
|
return fmt.Errorf("release-tag %q resolves version %q, want %q", releaseTag, releaseVersion, version)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (c Client) FetchRegistry(ctx context.Context) (Registry, error) {
|
|
return c.inner.FetchRegistry(ctx)
|
|
}
|
|
|
|
func (c Client) FetchLatestRelease(ctx context.Context, plugin Plugin) (Release, error) {
|
|
return c.inner.FetchLatestRelease(ctx, plugin)
|
|
}
|
|
|
|
func (c Client) FetchReleaseByTag(ctx context.Context, plugin Plugin, tag string) (Release, error) {
|
|
return c.inner.FetchReleaseByTag(ctx, plugin, tag)
|
|
}
|
|
|
|
func (c Client) Install(ctx context.Context, plugin Plugin, options InstallOptions) (InstallResult, error) {
|
|
return c.inner.Install(ctx, plugin, options)
|
|
}
|
|
|
|
func (c Client) InstallVersion(ctx context.Context, plugin Plugin, releaseTag string, version string, options InstallOptions) (InstallResult, error) {
|
|
return c.inner.InstallVersion(ctx, plugin, releaseTag, version, options)
|
|
}
|
|
|
|
func (c Client) InstallManifest(ctx context.Context, manifest Manifest, options InstallOptions) (InstallResult, error) {
|
|
if errValidate := manifest.Validate(); errValidate != nil {
|
|
return InstallResult{}, errValidate
|
|
}
|
|
return c.InstallVersion(ctx, manifest.Plugin(), manifest.ReleaseTag, manifest.Version, options)
|
|
}
|