+1
-1
atproto/lexicon/resolve.go
+1
-1
atproto/lexicon/resolve.go
···
16
16
//
17
17
// The current implementation uses a naive 'getRepo' fetch to the relevant PDS instance, without validating MST proof chain.
18
18
//
19
-
// Calling code should usually use ResolvingCatalog, which handles basing caching.
19
+
// Calling code should usually use ResolvingCatalog, which handles basic caching and validation of the Lexicon language itself.
20
20
func ResolveLexiconData(ctx context.Context, dir identity.Directory, nsid syntax.NSID) (map[string]any, error) {
21
21
22
22
baseDir := identity.BaseDirectory{}
+20
-14
atproto/lexicon/resolving_catalog.go
+20
-14
atproto/lexicon/resolving_catalog.go
···
4
4
"context"
5
5
"encoding/json"
6
6
"fmt"
7
-
"net"
8
-
"time"
7
+
"strings"
9
8
10
9
"github.com/bluesky-social/indigo/atproto/identity"
11
10
"github.com/bluesky-social/indigo/atproto/syntax"
···
14
13
// Catalog which supplements an in-memory BaseCatalog with live resolution from the network
15
14
type ResolvingCatalog struct {
16
15
Base BaseCatalog
17
-
Resolver net.Resolver
18
16
Directory identity.Directory
19
17
}
20
18
21
-
// TODO: maybe this should take a base catalog as an arg?
22
19
func NewResolvingCatalog() ResolvingCatalog {
23
20
return ResolvingCatalog{
24
-
Base: NewBaseCatalog(),
25
-
Resolver: net.Resolver{
26
-
Dial: func(ctx context.Context, network, address string) (net.Conn, error) {
27
-
d := net.Dialer{Timeout: time.Second * 5}
28
-
return d.DialContext(ctx, network, address)
29
-
},
30
-
},
21
+
Base: NewBaseCatalog(),
31
22
Directory: identity.DefaultDirectory(),
32
23
}
33
24
}
34
25
35
26
func (rc *ResolvingCatalog) Resolve(ref string) (*Schema, error) {
36
-
// TODO: not passed through!
27
+
// NOTE: not passed through!
37
28
ctx := context.Background()
38
29
39
30
if ref == "" {
40
31
return nil, fmt.Errorf("tried to resolve empty string name")
41
32
}
42
33
43
-
// TODO: split on '#'
44
-
nsid, err := syntax.ParseNSID(ref)
34
+
// first try existing catalog
35
+
schema, err := rc.Base.Resolve(ref)
36
+
if nil == err { // no error: found a hit
37
+
return schema, nil
38
+
}
39
+
40
+
// split any ref from the end '#'
41
+
parts := strings.SplitN(ref, "#", 2)
42
+
nsid, err := syntax.ParseNSID(parts[0])
45
43
if err != nil {
46
44
return nil, err
47
45
}
···
60
58
if err = json.Unmarshal(recordJSON, &sf); err != nil {
61
59
return nil, err
62
60
}
61
+
62
+
if sf.Lexicon != 1 {
63
+
return nil, fmt.Errorf("unsupported lexicon language version: %d", sf.Lexicon)
64
+
}
65
+
if sf.ID != nsid.String() {
66
+
return nil, fmt.Errorf("lexicon ID does not match NSID: %s != %s", sf.ID, nsid)
67
+
}
63
68
if err = rc.Base.AddSchemaFile(sf); err != nil {
64
69
return nil, err
65
70
}
66
71
72
+
// re-resolving from the raw ref ensures that fragments are handled
67
73
return rc.Base.Resolve(ref)
68
74
}