add reviewedBy field
This commit is contained in:
@@ -32,6 +32,17 @@ type personOrOrg struct {
|
||||
Image string `json:"image,omitempty"`
|
||||
InteractionStat []interactionStat `json:"interactionStatistic,omitempty"`
|
||||
AgentInteractionStat []interactionStat `json:"agentInteractionStatistic,omitempty"`
|
||||
ReviewedBy []*verifier `json:"reviewedBy,omitempty"`
|
||||
}
|
||||
|
||||
// verifier is the schema.org Person shape emitted under Person.reviewedBy.
|
||||
// Narrower than personOrOrg: just enough to identify the verifying entity.
|
||||
type verifier struct {
|
||||
Type string `json:"@type"`
|
||||
Name string `json:"name,omitempty"`
|
||||
AlternateName string `json:"alternateName,omitempty"`
|
||||
Identifier string `json:"identifier,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
type sharedContent struct {
|
||||
@@ -91,6 +102,9 @@ const maxComments = 10
|
||||
// maxRecentPosts caps ProfilePage.hasPart[].
|
||||
const maxRecentPosts = 10
|
||||
|
||||
// maxReviewedBy caps Person.reviewedBy entries.
|
||||
const maxReviewedBy = 10
|
||||
|
||||
// authorFeedFetchLimit oversamples getAuthorFeed because posts_no_replies
|
||||
// still returns reposts; we drop those client-side. 3x is a safe margin.
|
||||
const authorFeedFetchLimit = 3 * maxRecentPosts
|
||||
@@ -226,6 +240,48 @@ func buildAuthor(author *appbsky.ActorDefs_ProfileViewBasic) *personOrOrg {
|
||||
return p
|
||||
}
|
||||
|
||||
// buildReviewedBy maps a profile's verifications to Person entries for
|
||||
// Person.reviewedBy. Skips !IsValid and missing Issuer; caps at
|
||||
// maxReviewedBy. URL falls back to DID-form when the verifier's handle is
|
||||
// missing or "handle.invalid".
|
||||
func buildReviewedBy(state *appbsky.ActorDefs_VerificationState) []*verifier {
|
||||
if state == nil || len(state.Verifications) == 0 {
|
||||
return nil
|
||||
}
|
||||
var out []*verifier
|
||||
for _, v := range state.Verifications {
|
||||
if v == nil || !v.IsValid || v.Issuer == "" {
|
||||
continue
|
||||
}
|
||||
if len(out) >= maxReviewedBy {
|
||||
break
|
||||
}
|
||||
entry := &verifier{
|
||||
Type: "Person",
|
||||
Identifier: v.Issuer,
|
||||
}
|
||||
var handle string
|
||||
if v.Handle != nil {
|
||||
handle = *v.Handle
|
||||
}
|
||||
if v.DisplayName != nil && *v.DisplayName != "" {
|
||||
entry.Name = *v.DisplayName
|
||||
if handle != "" && handle != "handle.invalid" {
|
||||
entry.AlternateName = "@" + handle
|
||||
}
|
||||
} else if handle != "" && handle != "handle.invalid" {
|
||||
entry.Name = "@" + handle
|
||||
}
|
||||
if url := bskyProfileURL(handle); url != "" {
|
||||
entry.URL = url
|
||||
} else {
|
||||
entry.URL = "https://bsky.app/profile/" + v.Issuer
|
||||
}
|
||||
out = append(out, entry)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// postHasHideLabel reports whether the post-view or self-labels include
|
||||
// any non-negated label in labelSet. Self-labels have no negation.
|
||||
func postHasHideLabel(pv *appbsky.FeedDefs_PostView, labelSet map[string]bool) bool {
|
||||
@@ -319,6 +375,13 @@ func buildPostNode(pv *appbsky.FeedDefs_PostView, replies []*appbsky.FeedDefs_Th
|
||||
InteractionStat: buildPostStats(pv),
|
||||
}
|
||||
|
||||
// Surface verifications on the post author only; replies do not.
|
||||
if node.Author != nil {
|
||||
if rb := buildReviewedBy(pv.Author.Verification); len(rb) > 0 {
|
||||
node.Author.ReviewedBy = rb
|
||||
}
|
||||
}
|
||||
|
||||
if pv.ReplyCount != nil {
|
||||
node.CommentCount = pv.ReplyCount
|
||||
} else {
|
||||
@@ -448,6 +511,9 @@ func buildProfileJSONLD(pv *appbsky.ActorDefs_ProfileViewDetailed, recentPosts [
|
||||
{Type: "InteractionCounter", InteractionType: "https://schema.org/FollowAction", UserInteractionCount: deref(pv.FollowsCount)},
|
||||
{Type: "InteractionCounter", InteractionType: "https://schema.org/WriteAction", UserInteractionCount: deref(pv.PostsCount)},
|
||||
}
|
||||
if rb := buildReviewedBy(pv.Verification); len(rb) > 0 {
|
||||
person.ReviewedBy = rb
|
||||
}
|
||||
|
||||
page := profilePage{
|
||||
Context: schemaOrgContext,
|
||||
|
||||
@@ -154,6 +154,48 @@ func withPostLabel(val string, neg bool) func(*appbsky.FeedDefs_PostView) {
|
||||
}
|
||||
}
|
||||
|
||||
// verifierSpec is a compact specifier for a verification entry in fixtures.
|
||||
type verifierSpec struct {
|
||||
issuer, handle, displayName string
|
||||
isValid bool
|
||||
}
|
||||
|
||||
// makeVerificationState builds a VerificationState from the supplied specs.
|
||||
func makeVerificationState(specs ...verifierSpec) *appbsky.ActorDefs_VerificationState {
|
||||
state := &appbsky.ActorDefs_VerificationState{
|
||||
VerifiedStatus: "valid",
|
||||
TrustedVerifierStatus: "none",
|
||||
}
|
||||
for _, s := range specs {
|
||||
v := &appbsky.ActorDefs_VerificationView{
|
||||
Issuer: s.issuer,
|
||||
IsValid: s.isValid,
|
||||
CreatedAt: "2024-01-01T00:00:00Z",
|
||||
Uri: "at://" + s.issuer + "/app.bsky.graph.verification/" + s.issuer,
|
||||
}
|
||||
if s.handle != "" {
|
||||
h := s.handle
|
||||
v.Handle = &h
|
||||
}
|
||||
if s.displayName != "" {
|
||||
d := s.displayName
|
||||
v.DisplayName = &d
|
||||
}
|
||||
state.Verifications = append(state.Verifications, v)
|
||||
}
|
||||
return state
|
||||
}
|
||||
|
||||
// withVerifications sets pv.Author.Verification.
|
||||
func withVerifications(state *appbsky.ActorDefs_VerificationState) func(*appbsky.FeedDefs_PostView) {
|
||||
return func(pv *appbsky.FeedDefs_PostView) {
|
||||
if pv.Author == nil {
|
||||
return
|
||||
}
|
||||
pv.Author.Verification = state
|
||||
}
|
||||
}
|
||||
|
||||
// unmarshalLD parses the JSON-LD blob produced by buildPostJSONLD.
|
||||
func unmarshalLD(t *testing.T, s string) map[string]any {
|
||||
t.Helper()
|
||||
@@ -776,3 +818,234 @@ func TestBuildPostJSONLD_ReplyAuthorHasIdentifier(t *testing.T) {
|
||||
t.Errorf("reply author identifier should be DID, got %v", auth["identifier"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildReviewedBy_NilAndEmpty(t *testing.T) {
|
||||
if got := buildReviewedBy(nil); got != nil {
|
||||
t.Errorf("nil state should yield nil, got %v", got)
|
||||
}
|
||||
empty := &appbsky.ActorDefs_VerificationState{}
|
||||
if got := buildReviewedBy(empty); got != nil {
|
||||
t.Errorf("empty Verifications should yield nil, got %v", got)
|
||||
}
|
||||
allInvalid := makeVerificationState(
|
||||
verifierSpec{issuer: "did:plc:v1", handle: "v1.example.com", displayName: "V One", isValid: false},
|
||||
verifierSpec{issuer: "did:plc:v2", handle: "v2.example.com", displayName: "V Two", isValid: false},
|
||||
)
|
||||
if got := buildReviewedBy(allInvalid); got != nil {
|
||||
t.Errorf("all-invalid state should yield nil, got %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildReviewedBy_FiltersInvalid(t *testing.T) {
|
||||
state := makeVerificationState(
|
||||
verifierSpec{issuer: "did:plc:v1", handle: "v1.example.com", displayName: "V One", isValid: true},
|
||||
verifierSpec{issuer: "did:plc:v2", handle: "v2.example.com", displayName: "V Two", isValid: false},
|
||||
verifierSpec{issuer: "did:plc:v3", handle: "v3.example.com", displayName: "V Three", isValid: true},
|
||||
verifierSpec{issuer: "", handle: "noid.example.com", displayName: "No Issuer", isValid: true},
|
||||
)
|
||||
got := buildReviewedBy(state)
|
||||
if len(got) != 2 {
|
||||
t.Fatalf("expected 2 valid verifiers, got %d: %v", len(got), got)
|
||||
}
|
||||
if got[0].Identifier != "did:plc:v1" {
|
||||
t.Errorf("FIFO order broken; first identifier = %q", got[0].Identifier)
|
||||
}
|
||||
if got[1].Identifier != "did:plc:v3" {
|
||||
t.Errorf("expected v3 at index 1, got %q", got[1].Identifier)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildReviewedBy_NameFallbacks(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
spec verifierSpec
|
||||
wantName, wantAlternateName, wantURL, wantIdentif string
|
||||
}{
|
||||
{
|
||||
name: "DisplayName + handle",
|
||||
spec: verifierSpec{issuer: "did:plc:v1", handle: "alice.example.com", displayName: "Alice Verifier", isValid: true},
|
||||
wantName: "Alice Verifier",
|
||||
wantAlternateName: "@alice.example.com",
|
||||
wantURL: "https://bsky.app/profile/alice.example.com",
|
||||
wantIdentif: "did:plc:v1",
|
||||
},
|
||||
{
|
||||
name: "handle only",
|
||||
spec: verifierSpec{issuer: "did:plc:v2", handle: "bob.example.com", isValid: true},
|
||||
wantName: "@bob.example.com",
|
||||
wantAlternateName: "",
|
||||
wantURL: "https://bsky.app/profile/bob.example.com",
|
||||
wantIdentif: "did:plc:v2",
|
||||
},
|
||||
{
|
||||
name: "DisplayName only (no handle)",
|
||||
spec: verifierSpec{issuer: "did:plc:v3", displayName: "Carol Verifier", isValid: true},
|
||||
wantName: "Carol Verifier",
|
||||
wantAlternateName: "",
|
||||
wantURL: "https://bsky.app/profile/did:plc:v3",
|
||||
wantIdentif: "did:plc:v3",
|
||||
},
|
||||
{
|
||||
name: "DisplayName + handle.invalid",
|
||||
spec: verifierSpec{issuer: "did:plc:v4", handle: "handle.invalid", displayName: "Dave Verifier", isValid: true},
|
||||
wantName: "Dave Verifier",
|
||||
wantAlternateName: "",
|
||||
wantURL: "https://bsky.app/profile/did:plc:v4",
|
||||
wantIdentif: "did:plc:v4",
|
||||
},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
got := buildReviewedBy(makeVerificationState(tc.spec))
|
||||
if len(got) != 1 {
|
||||
t.Fatalf("expected 1 entry, got %d", len(got))
|
||||
}
|
||||
v := got[0]
|
||||
if v.Type != "Person" {
|
||||
t.Errorf("@type = %q, want Person", v.Type)
|
||||
}
|
||||
if v.Name != tc.wantName {
|
||||
t.Errorf("name = %q, want %q", v.Name, tc.wantName)
|
||||
}
|
||||
if v.AlternateName != tc.wantAlternateName {
|
||||
t.Errorf("alternateName = %q, want %q", v.AlternateName, tc.wantAlternateName)
|
||||
}
|
||||
if v.URL != tc.wantURL {
|
||||
t.Errorf("url = %q, want %q", v.URL, tc.wantURL)
|
||||
}
|
||||
if v.Identifier != tc.wantIdentif {
|
||||
t.Errorf("identifier = %q, want %q", v.Identifier, tc.wantIdentif)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildReviewedBy_Cap(t *testing.T) {
|
||||
specs := make([]verifierSpec, 0, 12)
|
||||
for i := 0; i < 12; i++ {
|
||||
specs = append(specs, verifierSpec{
|
||||
issuer: fmt.Sprintf("did:plc:v%02d", i),
|
||||
handle: fmt.Sprintf("v%02d.example.com", i),
|
||||
displayName: fmt.Sprintf("V%02d", i),
|
||||
isValid: true,
|
||||
})
|
||||
}
|
||||
got := buildReviewedBy(makeVerificationState(specs...))
|
||||
if len(got) != maxReviewedBy {
|
||||
t.Errorf("expected cap at %d, got %d", maxReviewedBy, len(got))
|
||||
}
|
||||
if got[0].Identifier != "did:plc:v00" {
|
||||
t.Errorf("first kept entry should be v00, got %q", got[0].Identifier)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildPostJSONLD_AuthorReviewedBy(t *testing.T) {
|
||||
state := makeVerificationState(verifierSpec{
|
||||
issuer: "did:plc:verifier1",
|
||||
handle: "verifier.example.com",
|
||||
displayName: "Trusted Verifier",
|
||||
isValid: true,
|
||||
})
|
||||
pv := makePostView("alice.bsky.social", "did:plc:alice", "abc123", "hi",
|
||||
withVerifications(state))
|
||||
out, err := buildPostJSONLD(pv, nil, "u", hideEmbedLabels, hideReplyLabels)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
main := unmarshalLD(t, out)["mainEntity"].(map[string]any)
|
||||
auth := main["author"].(map[string]any)
|
||||
rb, ok := auth["reviewedBy"].([]any)
|
||||
if !ok {
|
||||
t.Fatalf("post author should have reviewedBy, got %v", auth["reviewedBy"])
|
||||
}
|
||||
if len(rb) != 1 {
|
||||
t.Fatalf("expected 1 verifier, got %d", len(rb))
|
||||
}
|
||||
v := rb[0].(map[string]any)
|
||||
if v["@type"] != "Person" {
|
||||
t.Errorf("verifier @type = %v, want Person", v["@type"])
|
||||
}
|
||||
if v["name"] != "Trusted Verifier" {
|
||||
t.Errorf("verifier name = %v", v["name"])
|
||||
}
|
||||
if v["identifier"] != "did:plc:verifier1" {
|
||||
t.Errorf("verifier identifier = %v", v["identifier"])
|
||||
}
|
||||
if v["url"] != "https://bsky.app/profile/verifier.example.com" {
|
||||
t.Errorf("verifier url = %v", v["url"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildPostJSONLD_ReplyAuthorNoReviewedBy(t *testing.T) {
|
||||
// Replies do not surface verifications even when the reply author
|
||||
// carries Verification.
|
||||
state := makeVerificationState(verifierSpec{
|
||||
issuer: "did:plc:verifier1",
|
||||
handle: "verifier.example.com",
|
||||
displayName: "Trusted Verifier",
|
||||
isValid: true,
|
||||
})
|
||||
pv := makePostView("alice.bsky.social", "did:plc:alice", "abc123", "main")
|
||||
reply := makePostView("bob.bsky.social", "did:plc:bob", "rep1", "hi",
|
||||
withVerifications(state))
|
||||
out, _ := buildPostJSONLD(pv, buildReplies(reply), "u", hideEmbedLabels, hideReplyLabels)
|
||||
main := unmarshalLD(t, out)["mainEntity"].(map[string]any)
|
||||
c := main["comment"].([]any)[0].(map[string]any)
|
||||
auth := c["author"].(map[string]any)
|
||||
if _, present := auth["reviewedBy"]; present {
|
||||
t.Errorf("reply author must not carry reviewedBy, got %v", auth["reviewedBy"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildProfileJSONLD_MainEntityReviewedBy(t *testing.T) {
|
||||
pv := newProfileViewDetailed()
|
||||
pv.Verification = makeVerificationState(verifierSpec{
|
||||
issuer: "did:plc:verifier1",
|
||||
handle: "verifier.example.com",
|
||||
displayName: "Trusted Verifier",
|
||||
isValid: true,
|
||||
})
|
||||
out, err := buildProfileJSONLD(pv, nil, hideEmbedLabels, hideReplyLabels)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
main := unmarshalLD(t, out)["mainEntity"].(map[string]any)
|
||||
rb, ok := main["reviewedBy"].([]any)
|
||||
if !ok {
|
||||
t.Fatalf("profile mainEntity should have reviewedBy, got %v", main["reviewedBy"])
|
||||
}
|
||||
v := rb[0].(map[string]any)
|
||||
if v["identifier"] != "did:plc:verifier1" {
|
||||
t.Errorf("verifier identifier = %v", v["identifier"])
|
||||
}
|
||||
if v["url"] != "https://bsky.app/profile/verifier.example.com" {
|
||||
t.Errorf("verifier url = %v", v["url"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildProfileJSONLD_HasPartAuthorReviewedBy(t *testing.T) {
|
||||
// Recent posts inherit verifications via their post-view Author.
|
||||
pv := newProfileViewDetailed()
|
||||
state := makeVerificationState(verifierSpec{
|
||||
issuer: "did:plc:verifier1",
|
||||
handle: "verifier.example.com",
|
||||
displayName: "Trusted Verifier",
|
||||
isValid: true,
|
||||
})
|
||||
post := makePostView("alice.bsky.social", "did:plc:alice", "rp1", "hi",
|
||||
withVerifications(state))
|
||||
out, _ := buildProfileJSONLD(pv, []*appbsky.FeedDefs_PostView{post}, hideEmbedLabels, hideReplyLabels)
|
||||
page := unmarshalLD(t, out)
|
||||
hp := page["hasPart"].([]any)
|
||||
if len(hp) != 1 {
|
||||
t.Fatalf("expected 1 hasPart entry, got %d", len(hp))
|
||||
}
|
||||
auth := hp[0].(map[string]any)["author"].(map[string]any)
|
||||
rb, ok := auth["reviewedBy"].([]any)
|
||||
if !ok || len(rb) != 1 {
|
||||
t.Fatalf("hasPart author should carry reviewedBy, got %v", auth["reviewedBy"])
|
||||
}
|
||||
if rb[0].(map[string]any)["identifier"] != "did:plc:verifier1" {
|
||||
t.Errorf("verifier identifier wrong: %v", rb[0])
|
||||
}
|
||||
}
|
||||
|
||||
+2
-5
@@ -3,7 +3,7 @@ module github.com/bluesky-social/social-app/bskyweb
|
||||
go 1.26
|
||||
|
||||
require (
|
||||
github.com/bluesky-social/indigo v0.0.0-20250729223159-573ae927246a
|
||||
github.com/bluesky-social/indigo v0.0.0-20260527160159-3b7634c713b8
|
||||
github.com/flosch/pongo2/v6 v6.0.0
|
||||
github.com/ipfs/go-log v1.0.5
|
||||
github.com/joho/godotenv v1.5.1
|
||||
@@ -18,11 +18,10 @@ require github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indir
|
||||
|
||||
require (
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 // indirect
|
||||
github.com/carlmjohnson/versioninfo v0.22.5 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect
|
||||
github.com/earthboundkid/versioninfo/v2 v2.24.1 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/go-logr/logr v1.4.1 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
@@ -32,7 +31,6 @@ require (
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.5 // indirect
|
||||
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
||||
github.com/hashicorp/golang-lru/arc/v2 v2.0.6 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/ipfs/bbloom v0.0.4 // indirect
|
||||
github.com/ipfs/go-block-format v0.2.0 // indirect
|
||||
@@ -82,7 +80,6 @@ require (
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e // indirect
|
||||
github.com/whyrusleeping/go-did v0.0.0-20230824162731-404d1707d5d6 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect
|
||||
gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect
|
||||
|
||||
+4
-10
@@ -2,12 +2,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bluesky-social/indigo v0.0.0-20250729223159-573ae927246a h1:S12KN45uIkRglMHC8PqD/Vsz0+u3KbIaBF/6rit8/Pg=
|
||||
github.com/bluesky-social/indigo v0.0.0-20250729223159-573ae927246a/go.mod h1:0XUyOCRtL4/OiyeqMTmr6RlVHQMDgw3LS7CfibuZR5Q=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874 h1:N7oVaKyGp8bttX0bfZGmcGkjz7DLQXhAn3DNd3T0ous=
|
||||
github.com/bradfitz/gomemcache v0.0.0-20230905024940-24af94b03874/go.mod h1:r5xuitiExdLAJ09PR7vBVENGvp4ZuTBeWTGtxuX3K+c=
|
||||
github.com/carlmjohnson/versioninfo v0.22.5 h1:O00sjOLUAFxYQjlN/bzYTuZiS0y6fWDQjMRvwtKgwwc=
|
||||
github.com/carlmjohnson/versioninfo v0.22.5/go.mod h1:QT9mph3wcVfISUKd0i9sZfVrPviHuSF+cUtLjm2WSf8=
|
||||
github.com/bluesky-social/indigo v0.0.0-20260527160159-3b7634c713b8 h1:heYuihJZQZMNij7+dKIEfApG10xrGnDV2rtKpvFyYYU=
|
||||
github.com/bluesky-social/indigo v0.0.0-20260527160159-3b7634c713b8/go.mod h1:JqQkz8lrOI6YZivP38GHmtVOTtzsNToITKj1gMpU5Jo=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
@@ -19,6 +15,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0=
|
||||
github.com/earthboundkid/versioninfo/v2 v2.24.1 h1:SJTMHaoUx3GzjjnUO1QzP3ZXK6Ee/nbWyCm58eY3oUg=
|
||||
github.com/earthboundkid/versioninfo/v2 v2.24.1/go.mod h1:VcWEooDEuyUJnMfbdTh0uFN4cfEIg+kHMuWB2CDCLjw=
|
||||
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
|
||||
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/flosch/pongo2/v6 v6.0.0 h1:lsGru8IAzHgIAw6H2m4PCyleO58I40ow6apih0WprMU=
|
||||
@@ -48,8 +46,6 @@ github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT
|
||||
github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
|
||||
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
|
||||
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/golang-lru/arc/v2 v2.0.6 h1:4NU7uP5vSoK6TbaMj3NtY478TTAWLso/vL1gpNrInHg=
|
||||
github.com/hashicorp/golang-lru/arc/v2 v2.0.6/go.mod h1:cfdDIX05DWvYV6/shsxDfa/OVcRieOt+q4FnM8x+Xno=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs=
|
||||
@@ -211,8 +207,6 @@ github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0 h1:GDDkbFiaK8jsSD
|
||||
github.com/warpfork/go-wish v0.0.0-20220906213052-39a1cc7a02d0/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw=
|
||||
github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e h1:28X54ciEwwUxyHn9yrZfl5ojgF4CBNLWX7LR0rvBkf4=
|
||||
github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so=
|
||||
github.com/whyrusleeping/go-did v0.0.0-20230824162731-404d1707d5d6 h1:yJ9/LwIGIk/c0CdoavpC9RNSGSruIspSZtxG3Nnldic=
|
||||
github.com/whyrusleeping/go-did v0.0.0-20230824162731-404d1707d5d6/go.mod h1:39U9RRVr4CKbXpXYopWn+FSH5s+vWu6+RmguSPWAq5s=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
|
||||
Reference in New Issue
Block a user