A vibe coded tangled fork which supports pijul.
1package xrpc
2
3import (
4 "database/sql"
5 "encoding/json"
6 "errors"
7 "log/slog"
8 "net/http"
9 "time"
10
11 "github.com/bluesky-social/indigo/atproto/atclient"
12 "github.com/go-chi/chi/v5"
13 "tangled.org/core/api/tangled"
14 "tangled.org/core/idresolver"
15 "tangled.org/core/knotmirror/config"
16 "tangled.org/core/knotmirror/knotstream"
17 "tangled.org/core/log"
18)
19
20type Xrpc struct {
21 cfg *config.Config
22 db *sql.DB
23 resolver *idresolver.Resolver
24 ks *knotstream.KnotStream
25 logger *slog.Logger
26 httpClient *http.Client
27}
28
29func New(logger *slog.Logger, cfg *config.Config, db *sql.DB, resolver *idresolver.Resolver, ks *knotstream.KnotStream) *Xrpc {
30 return &Xrpc{
31 cfg: cfg,
32 db: db,
33 resolver: resolver,
34 ks: ks,
35 logger: log.SubLogger(logger, "xrpc"),
36 httpClient: &http.Client{
37 Timeout: 30 * time.Second,
38 },
39 }
40}
41
42func (x *Xrpc) Router() http.Handler {
43 r := chi.NewRouter()
44
45 r.Get("/"+tangled.GitTempGetArchiveNSID, x.GetArchive)
46 r.Get("/"+tangled.GitTempGetBlobNSID, x.GetBlob)
47 r.Get("/"+tangled.GitTempGetBranchNSID, x.GetBranch)
48 // r.Get("/"+tangled.GitTempGetCommitNSID, x.GetCommit) // todo
49 // r.Get("/"+tangled.GitTempGetDiffNSID, x.GetDiff) // todo
50 // r.Get("/"+tangled.GitTempGetEntityNSID, x.GetEntity) // todo
51 // r.Get("/"+tangled.GitTempGetHeadNSID, x.GetHead) // todo
52 r.Get("/"+tangled.GitTempGetTagNSID, x.GetTag) // using types.Response
53 r.Get("/"+tangled.GitTempGetTreeNSID, x.GetTree)
54 r.Get("/"+tangled.GitTempListBranchesNSID, x.ListBranches) // wip, unknown output
55 r.Get("/"+tangled.GitTempListCommitsNSID, x.ListCommits)
56 r.Get("/"+tangled.GitTempListLanguagesNSID, x.ListLanguages)
57 r.Get("/"+tangled.GitTempListTagsNSID, x.ListTags)
58 r.Post("/"+tangled.SyncRequestCrawlNSID, x.RequestCrawl)
59
60 return r
61}
62
63func writeJson(w http.ResponseWriter, status int, response any) error {
64 w.Header().Set("Content-Type", "application/json")
65 w.WriteHeader(status)
66 if err := json.NewEncoder(w).Encode(response); err != nil {
67 return err
68 }
69 return nil
70}
71
72func writeErr(w http.ResponseWriter, err error) error {
73 var apiErr *atclient.APIError
74 if errors.As(err, &apiErr) {
75 return writeJson(w, apiErr.StatusCode, atclient.ErrorBody{Name: apiErr.Name, Message: apiErr.Message})
76 }
77 return writeJson(w, http.StatusInternalServerError, atclient.ErrorBody{Name: "InternalServerError", Message: "internal server error"})
78}