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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package pds
import (
"fmt"
"net/http"
"github.com/bluesky-social/indigo/atproto/syntax"
"github.com/johnandersen777/socialweb-computer-kcp/internal/kit/httpjson"
)
type latestCommitOutput struct {
CID string `json:"cid"`
Rev string `json:"rev"`
}
type repoStatusOutput struct {
DID string `json:"did"`
Active bool `json:"active"`
Status string `json:"status,omitempty"`
Rev string `json:"rev,omitempty"`
}
func (s *Server) handleGetRepo(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
didRaw := r.URL.Query().Get("did")
did, err := syntax.ParseDID(didRaw)
if err != nil {
writeXRPCError(w, http.StatusBadRequest, "InvalidRequest", "did is required")
return
}
var since *syntax.TID
if rawSince := r.URL.Query().Get("since"); rawSince != "" {
rev, err := syntax.ParseTID(rawSince)
if err != nil {
writeXRPCError(w, http.StatusBadRequest, "InvalidRequest", "invalid since")
return
}
since = &rev
}
carBytes, err := s.repos.CAR(ctx, did, since)
if err != nil {
s.repoError(w, err)
return
}
w.Header().Set("Content-Type", "application/vnd.ipld.car")
w.Header().Set("Content-Length", fmt.Sprintf("%d", len(carBytes)))
w.WriteHeader(http.StatusOK)
_, _ = w.Write(carBytes)
}
func (s *Server) handleGetLatestCommit(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
did, err := syntax.ParseDID(r.URL.Query().Get("did"))
if err != nil {
writeXRPCError(w, http.StatusBadRequest, "InvalidRequest", "did is required")
return
}
head, err := s.repos.Head(ctx, did)
if err != nil {
s.repoError(w, err)
return
}
httpjson.Write(w, http.StatusOK, latestCommitOutput{CID: head.CID.String(), Rev: head.Rev.String()})
}
func (s *Server) handleGetRepoStatus(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
did, err := syntax.ParseDID(r.URL.Query().Get("did"))
if err != nil {
writeXRPCError(w, http.StatusBadRequest, "InvalidRequest", "did is required")
return
}
head, err := s.repos.Head(ctx, did)
if err != nil {
s.repoError(w, err)
return
}
httpjson.Write(w, http.StatusOK, repoStatusOutput{DID: did.String(), Active: true, Rev: head.Rev.String()})
}
func (s *Server) handleSyncGetRecord(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
query := r.URL.Query()
did, err := syntax.ParseDID(query.Get("did"))
if err != nil {
writeXRPCError(w, http.StatusBadRequest, "InvalidRequest", "did is required")
return
}
collection, err := syntax.ParseNSID(query.Get("collection"))
if err != nil {
writeXRPCError(w, http.StatusBadRequest, "InvalidRequest", "invalid collection")
return
}
rkey, err := syntax.ParseRecordKey(query.Get("rkey"))
if err != nil {
writeXRPCError(w, http.StatusBadRequest, "InvalidRequest", "invalid rkey")
return
}
rec, err := s.repos.GetRecord(ctx, did, collection, rkey)
if err != nil {
s.repoError(w, err)
return
}
httpjson.Write(w, http.StatusOK, recordView{
URI: fmt.Sprintf("at://%s/%s/%s", did, collection, rkey),
CID: rec.CID.String(),
Value: rec.Value,
})
}