1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package remote
import (
"context"
"errors"
"fmt"
"net/http"
"github.com/bluesky-social/indigo/atproto/identity"
"github.com/bluesky-social/indigo/atproto/syntax"
commonv1 "github.com/johnandersen777/socialweb-computer-kcp/api/common/v1alpha1"
"github.com/johnandersen777/socialweb-computer-kcp/internal/atproto/pdsclient"
"github.com/johnandersen777/socialweb-computer-kcp/internal/contract/atprotorepo"
)
type NetworkConfig struct {
Directory identity.Directory
HTTP *http.Client
}
type Network struct {
directory identity.Directory
http *http.Client
}
var _ atprotorepo.RecordReader = (*Network)(nil)
func NewNetwork(cfg NetworkConfig) *Network {
return &Network{directory: cfg.Directory, http: cfg.HTTP}
}
func (n *Network) repo(ctx context.Context, raw string) (*Repo, error) {
if n.directory == nil {
return nil, errors.New("remote: the network reader has no identity directory")
}
did, err := syntax.ParseDID(raw)
if err != nil {
return nil, fmt.Errorf("remote: %q is not a DID: %w", raw, err)
}
ident, err := n.directory.LookupDID(ctx, did)
if err != nil {
return nil, fmt.Errorf("remote: resolving %s: %w", did, err)
}
endpoint := ident.PDSEndpoint()
if endpoint == "" {
return nil, fmt.Errorf("remote: the DID document of %s names no PDS", did)
}
client, err := pdsclient.NewRemote(pdsclient.RemoteConfig{BaseURL: endpoint, HTTPClient: n.http, Timeout: DefaultTimeout})
if err != nil {
return nil, err
}
return Wrap(client, did), nil
}
func (n *Network) GetRecord(ctx context.Context, repo, collection, rkey string) (atprotorepo.Record, error) {
r, err := n.repo(ctx, repo)
if err != nil {
return atprotorepo.Record{}, err
}
return r.GetRecord(ctx, repo, collection, rkey)
}
func (n *Network) ListRecords(ctx context.Context, repo, collection string, opts atprotorepo.ListOptions) (atprotorepo.ListPage, error) {
r, err := n.repo(ctx, repo)
if err != nil {
return atprotorepo.ListPage{}, err
}
return r.ListRecords(ctx, repo, collection, opts)
}
func (n *Network) Resolve(ctx context.Context, ref commonv1.StrongRef) (atprotorepo.Record, error) {
uri, err := syntax.ParseATURI(ref.URI)
if err != nil {
return atprotorepo.Record{}, fmt.Errorf("remote: the record uri %q: %w", ref.URI, err)
}
r, err := n.repo(ctx, uri.Authority().String())
if err != nil {
return atprotorepo.Record{}, err
}
return r.Resolve(ctx, ref)
}