Monorepo for Tangled
tangled.org
1package knotcompat
2
3import (
4 "encoding/json"
5 "io"
6
7 lexutil "github.com/bluesky-social/indigo/lex/util"
8 "tangled.org/core/api/tangled"
9)
10
11func Collaborator(r *tangled.RepoCollaborator) *lexutil.LexiconTypeDecoder {
12 return &lexutil.LexiconTypeDecoder{Val: &collaboratorWrapper{inner: r}}
13}
14
15func Pull(r *tangled.RepoPull) *lexutil.LexiconTypeDecoder {
16 return &lexutil.LexiconTypeDecoder{Val: &pullWrapper{inner: r}}
17}
18
19type collaboratorWrapper struct {
20 LexiconTypeID string `cborgen:"$type,const=sh.tangled.repo.collaborator"`
21 inner *tangled.RepoCollaborator
22}
23
24func (c *collaboratorWrapper) MarshalJSON() ([]byte, error) {
25 c.inner.LexiconTypeID = "sh.tangled.repo.collaborator"
26 return marshalWithRepoDidShadow(c.inner, false)
27}
28
29func (c *collaboratorWrapper) MarshalCBOR(w io.Writer) error {
30 return c.inner.MarshalCBOR(w)
31}
32
33type pullWrapper struct {
34 LexiconTypeID string `cborgen:"$type,const=sh.tangled.repo.pull"`
35 inner *tangled.RepoPull
36}
37
38func (c *pullWrapper) MarshalJSON() ([]byte, error) {
39 c.inner.LexiconTypeID = "sh.tangled.repo.pull"
40 return marshalWithRepoDidShadow(c.inner, true)
41}
42
43func (c *pullWrapper) MarshalCBOR(w io.Writer) error {
44 return c.inner.MarshalCBOR(w)
45}
46
47func marshalWithRepoDidShadow(inner any, nestedTarget bool) ([]byte, error) {
48 raw, err := json.Marshal(inner)
49 if err != nil {
50 return nil, err
51 }
52 var top map[string]json.RawMessage
53 if err := json.Unmarshal(raw, &top); err != nil {
54 return raw, nil
55 }
56 if nestedTarget {
57 injectIntoNested(top, "target")
58 injectIntoNested(top, "source")
59 } else {
60 addRepoDidShadow(top)
61 }
62 return json.Marshal(top)
63}
64
65func injectIntoNested(parent map[string]json.RawMessage, key string) {
66 raw, ok := parent[key]
67 if !ok {
68 return
69 }
70 var nested map[string]json.RawMessage
71 if err := json.Unmarshal(raw, &nested); err != nil {
72 return
73 }
74 addRepoDidShadow(nested)
75 if reb, err := json.Marshal(nested); err == nil {
76 parent[key] = reb
77 }
78}
79
80func addRepoDidShadow(m map[string]json.RawMessage) {
81 if _, has := m["repoDid"]; has {
82 return
83 }
84 if v, ok := m["repo"]; ok {
85 m["repoDid"] = v
86 }
87}