- Dork schema with Validate() mirroring provider YAML pattern - go:embed loader tolerating empty definitions tree - Registry with List/Get/Stats/ListBySource/ListByCategory - Executor interface + Runner dispatch + ErrSourceNotImplemented - Placeholder definitions/.gitkeep and repo-root dorks/.gitkeep - Full unit test coverage for registry, validation, and runner dispatch
93 lines
2.5 KiB
Go
93 lines
2.5 KiB
Go
package dorks
|
|
|
|
import "fmt"
|
|
|
|
// Registry is the in-memory store of loaded dork definitions. It is built
|
|
// once at startup (via NewRegistry) and is safe for concurrent reads.
|
|
type Registry struct {
|
|
dorks []Dork
|
|
byID map[string]int
|
|
bySource map[string][]int
|
|
byCategory map[string][]int
|
|
}
|
|
|
|
// NewRegistry loads every embedded dork YAML file, validates them, and
|
|
// returns a ready-to-query Registry. An empty definitions tree is tolerated
|
|
// and yields an empty (but non-nil) Registry.
|
|
func NewRegistry() (*Registry, error) {
|
|
ds, err := loadDorks()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("loading dorks: %w", err)
|
|
}
|
|
return NewRegistryFromDorks(ds), nil
|
|
}
|
|
|
|
// NewRegistryFromDorks builds a Registry from an explicit slice of dorks
|
|
// without touching the embedded filesystem. Intended for tests.
|
|
func NewRegistryFromDorks(ds []Dork) *Registry {
|
|
r := &Registry{
|
|
dorks: make([]Dork, len(ds)),
|
|
byID: make(map[string]int, len(ds)),
|
|
bySource: make(map[string][]int),
|
|
byCategory: make(map[string][]int),
|
|
}
|
|
copy(r.dorks, ds)
|
|
for i, d := range r.dorks {
|
|
r.byID[d.ID] = i
|
|
r.bySource[d.Source] = append(r.bySource[d.Source], i)
|
|
r.byCategory[d.Category] = append(r.byCategory[d.Category], i)
|
|
}
|
|
return r
|
|
}
|
|
|
|
// List returns all loaded dorks. The returned slice must not be mutated.
|
|
func (r *Registry) List() []Dork {
|
|
return r.dorks
|
|
}
|
|
|
|
// Get returns the dork with the given id and a boolean indicating whether it
|
|
// was found.
|
|
func (r *Registry) Get(id string) (Dork, bool) {
|
|
idx, ok := r.byID[id]
|
|
if !ok {
|
|
return Dork{}, false
|
|
}
|
|
return r.dorks[idx], true
|
|
}
|
|
|
|
// ListBySource returns every dork declared for the given source.
|
|
func (r *Registry) ListBySource(source string) []Dork {
|
|
idxs := r.bySource[source]
|
|
out := make([]Dork, 0, len(idxs))
|
|
for _, i := range idxs {
|
|
out = append(out, r.dorks[i])
|
|
}
|
|
return out
|
|
}
|
|
|
|
// ListByCategory returns every dork tagged with the given category.
|
|
func (r *Registry) ListByCategory(category string) []Dork {
|
|
idxs := r.byCategory[category]
|
|
out := make([]Dork, 0, len(idxs))
|
|
for _, i := range idxs {
|
|
out = append(out, r.dorks[i])
|
|
}
|
|
return out
|
|
}
|
|
|
|
// Stats returns aggregate counts grouped by source and category.
|
|
func (r *Registry) Stats() Stats {
|
|
s := Stats{
|
|
Total: len(r.dorks),
|
|
BySource: make(map[string]int, len(r.bySource)),
|
|
ByCategory: make(map[string]int, len(r.byCategory)),
|
|
}
|
|
for src, idxs := range r.bySource {
|
|
s.BySource[src] = len(idxs)
|
|
}
|
|
for cat, idxs := range r.byCategory {
|
|
s.ByCategory[cat] = len(idxs)
|
|
}
|
|
return s
|
|
}
|