package knotcompat import ( "encoding/json" "io" lexutil "github.com/bluesky-social/indigo/lex/util" "tangled.org/core/api/tangled" ) func Collaborator(r *tangled.RepoCollaborator) *lexutil.LexiconTypeDecoder { return &lexutil.LexiconTypeDecoder{Val: &collaboratorWrapper{inner: r}} } func Pull(r *tangled.RepoPull) *lexutil.LexiconTypeDecoder { return &lexutil.LexiconTypeDecoder{Val: &pullWrapper{inner: r}} } type collaboratorWrapper struct { LexiconTypeID string `cborgen:"$type,const=sh.tangled.repo.collaborator"` inner *tangled.RepoCollaborator } func (c *collaboratorWrapper) MarshalJSON() ([]byte, error) { c.inner.LexiconTypeID = "sh.tangled.repo.collaborator" return marshalWithRepoDidShadow(c.inner, false) } func (c *collaboratorWrapper) MarshalCBOR(w io.Writer) error { return c.inner.MarshalCBOR(w) } type pullWrapper struct { LexiconTypeID string `cborgen:"$type,const=sh.tangled.repo.pull"` inner *tangled.RepoPull } func (c *pullWrapper) MarshalJSON() ([]byte, error) { c.inner.LexiconTypeID = "sh.tangled.repo.pull" return marshalWithRepoDidShadow(c.inner, true) } func (c *pullWrapper) MarshalCBOR(w io.Writer) error { return c.inner.MarshalCBOR(w) } func marshalWithRepoDidShadow(inner any, nestedTarget bool) ([]byte, error) { raw, err := json.Marshal(inner) if err != nil { return nil, err } var top map[string]json.RawMessage if err := json.Unmarshal(raw, &top); err != nil { return raw, nil } if nestedTarget { injectIntoNested(top, "target") injectIntoNested(top, "source") } else { addRepoDidShadow(top) } return json.Marshal(top) } func injectIntoNested(parent map[string]json.RawMessage, key string) { raw, ok := parent[key] if !ok { return } var nested map[string]json.RawMessage if err := json.Unmarshal(raw, &nested); err != nil { return } addRepoDidShadow(nested) if reb, err := json.Marshal(nested); err == nil { parent[key] = reb } } func addRepoDidShadow(m map[string]json.RawMessage) { if _, has := m["repoDid"]; has { return } if v, ok := m["repo"]; ok { m["repoDid"] = v } }