package contracts import ( "embed" "encoding/json" "fmt" "path" "strings" ) // Files contains pinned upstream schemas and the active local contract versions. // Runtime code never reads a checkout or resolves schema refs online. // //go:embed upstream local/v0.1 local/v0.2 local/v0.3 local/v0.4 local/*.json var Files embed.FS const SourceCommit = "v1" // ReadCurrent reads the sole active project-local contract, with no fallback // to a historical bundle if a name is missing or invalid. func ReadCurrent(name string) ([]byte, error) { switch name { case "config-read.schema.json", "task-discovery.schema.json", "mq.schema.json", "mq-topology.json", "manifest.json": return Files.ReadFile(path.Join("local", name)) default: return nil, fmt.Errorf("invalid current contract %q", name) } } func ReadLocal(version, name string) ([]byte, error) { if (version != "v0.1" && version != "v0.2" && version != "v0.3" && version != "v0.4") || name == "" || path.Base(name) != name || !strings.HasSuffix(name, ".schema.json") { return nil, fmt.Errorf("invalid project-local schema %q/%q", version, name) } return Files.ReadFile(path.Join("local", version, name)) } func Read(name string) ([]byte, error) { return Files.ReadFile(path.Join("upstream", SourceCommit, name)) } func ReadJSON(name string, dst any) error { data, err := Read(name) if err != nil { return fmt.Errorf("read contract %s: %w", name, err) } if err := json.Unmarshal(data, dst); err != nil { return fmt.Errorf("decode contract %s: %w", name, err) } return nil }