2026-03-30 00:54:20 +00:00
|
|
|
// SPDX-License-Identifier: EUPL-1.2
|
2026-03-29 23:59:48 +00:00
|
|
|
|
2026-03-06 13:20:12 +00:00
|
|
|
package marketplace
|
|
|
|
|
|
|
|
|
|
import (
|
2026-03-29 23:59:48 +00:00
|
|
|
json "dappco.re/go/core/scm/internal/ax/jsonx"
|
|
|
|
|
strings "dappco.re/go/core/scm/internal/ax/stringsx"
|
2026-03-16 20:37:25 +00:00
|
|
|
|
2026-04-01 05:41:05 +00:00
|
|
|
"dappco.re/go/core/io"
|
2026-03-21 23:54:23 +00:00
|
|
|
coreerr "dappco.re/go/core/log"
|
2026-03-06 13:20:12 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Module is a marketplace entry pointing to a module's Git repo.
|
|
|
|
|
type Module struct {
|
|
|
|
|
Code string `json:"code"`
|
|
|
|
|
Name string `json:"name"`
|
|
|
|
|
Repo string `json:"repo"`
|
|
|
|
|
SignKey string `json:"sign_key"`
|
|
|
|
|
Category string `json:"category"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Index is the root marketplace catalog.
|
|
|
|
|
type Index struct {
|
|
|
|
|
Version int `json:"version"`
|
|
|
|
|
Modules []Module `json:"modules"`
|
|
|
|
|
Categories []string `json:"categories"`
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ParseIndex decodes a marketplace index.json.
|
2026-03-30 14:11:15 +00:00
|
|
|
// Usage: ParseIndex(...)
|
2026-03-06 13:20:12 +00:00
|
|
|
func ParseIndex(data []byte) (*Index, error) {
|
|
|
|
|
var idx Index
|
|
|
|
|
if err := json.Unmarshal(data, &idx); err != nil {
|
2026-03-16 20:37:25 +00:00
|
|
|
return nil, coreerr.E("marketplace.ParseIndex", "unmarshal failed", err)
|
2026-03-06 13:20:12 +00:00
|
|
|
}
|
|
|
|
|
return &idx, nil
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-01 05:41:05 +00:00
|
|
|
// LoadIndex reads and parses a marketplace index.json from the given path.
|
|
|
|
|
// Usage: LoadIndex(...)
|
|
|
|
|
func LoadIndex(m io.Medium, path string) (*Index, error) {
|
|
|
|
|
data, err := m.Read(path)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, coreerr.E("marketplace.LoadIndex", "read failed", err)
|
|
|
|
|
}
|
|
|
|
|
return ParseIndex([]byte(data))
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-06 13:20:12 +00:00
|
|
|
// Search returns modules matching the query in code, name, or category.
|
2026-03-30 14:11:15 +00:00
|
|
|
// Usage: Search(...)
|
2026-03-06 13:20:12 +00:00
|
|
|
func (idx *Index) Search(query string) []Module {
|
|
|
|
|
q := strings.ToLower(query)
|
|
|
|
|
var results []Module
|
|
|
|
|
for _, m := range idx.Modules {
|
|
|
|
|
if strings.Contains(strings.ToLower(m.Code), q) ||
|
|
|
|
|
strings.Contains(strings.ToLower(m.Name), q) ||
|
|
|
|
|
strings.Contains(strings.ToLower(m.Category), q) {
|
|
|
|
|
results = append(results, m)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return results
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ByCategory returns all modules in the given category.
|
2026-03-30 14:11:15 +00:00
|
|
|
// Usage: ByCategory(...)
|
2026-03-06 13:20:12 +00:00
|
|
|
func (idx *Index) ByCategory(category string) []Module {
|
|
|
|
|
var results []Module
|
|
|
|
|
for _, m := range idx.Modules {
|
|
|
|
|
if m.Category == category {
|
|
|
|
|
results = append(results, m)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return results
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Find returns the module with the given code, or false if not found.
|
2026-03-30 14:11:15 +00:00
|
|
|
// Usage: Find(...)
|
2026-03-06 13:20:12 +00:00
|
|
|
func (idx *Index) Find(code string) (Module, bool) {
|
|
|
|
|
for _, m := range idx.Modules {
|
|
|
|
|
if m.Code == code {
|
|
|
|
|
return m, true
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return Module{}, false
|
|
|
|
|
}
|