@atproto/bsky 0.0.224 → 0.0.225
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/dist/api/app/bsky/actor/getProfile.d.ts.map +1 -1
- package/dist/api/app/bsky/actor/getProfile.js +2 -1
- package/dist/api/app/bsky/actor/getProfile.js.map +1 -1
- package/dist/api/app/bsky/actor/getProfiles.d.ts.map +1 -1
- package/dist/api/app/bsky/actor/getProfiles.js +2 -1
- package/dist/api/app/bsky/actor/getProfiles.js.map +1 -1
- package/dist/api/app/bsky/actor/searchActors.d.ts.map +1 -1
- package/dist/api/app/bsky/actor/searchActors.js +2 -1
- package/dist/api/app/bsky/actor/searchActors.js.map +1 -1
- package/dist/api/app/bsky/feed/getAuthorFeed.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getAuthorFeed.js +2 -1
- package/dist/api/app/bsky/feed/getAuthorFeed.js.map +1 -1
- package/dist/api/app/bsky/feed/getLikes.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getLikes.js +2 -1
- package/dist/api/app/bsky/feed/getLikes.js.map +1 -1
- package/dist/api/app/bsky/feed/getPostThread.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getPostThread.js +2 -1
- package/dist/api/app/bsky/feed/getPostThread.js.map +1 -1
- package/dist/api/app/bsky/feed/getQuotes.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getQuotes.js +2 -1
- package/dist/api/app/bsky/feed/getQuotes.js.map +1 -1
- package/dist/api/app/bsky/feed/getRepostedBy.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/getRepostedBy.js +2 -1
- package/dist/api/app/bsky/feed/getRepostedBy.js.map +1 -1
- package/dist/api/app/bsky/feed/searchPosts.d.ts.map +1 -1
- package/dist/api/app/bsky/feed/searchPosts.js +2 -1
- package/dist/api/app/bsky/feed/searchPosts.js.map +1 -1
- package/dist/api/app/bsky/graph/getActorStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getActorStarterPacks.js +2 -1
- package/dist/api/app/bsky/graph/getActorStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/graph/getFollowers.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getFollowers.js +2 -1
- package/dist/api/app/bsky/graph/getFollowers.js.map +1 -1
- package/dist/api/app/bsky/graph/getFollows.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getFollows.js +2 -1
- package/dist/api/app/bsky/graph/getFollows.js.map +1 -1
- package/dist/api/app/bsky/graph/getList.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getList.js +2 -1
- package/dist/api/app/bsky/graph/getList.js.map +1 -1
- package/dist/api/app/bsky/graph/getLists.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getLists.js +2 -1
- package/dist/api/app/bsky/graph/getLists.js.map +1 -1
- package/dist/api/app/bsky/graph/getStarterPack.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getStarterPack.js +2 -1
- package/dist/api/app/bsky/graph/getStarterPack.js.map +1 -1
- package/dist/api/app/bsky/graph/getStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/getStarterPacks.js +2 -1
- package/dist/api/app/bsky/graph/getStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/graph/searchStarterPacks.d.ts.map +1 -1
- package/dist/api/app/bsky/graph/searchStarterPacks.js +2 -1
- package/dist/api/app/bsky/graph/searchStarterPacks.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.js +2 -1
- package/dist/api/app/bsky/unspecced/getPostThreadOtherV2.js.map +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadV2.d.ts.map +1 -1
- package/dist/api/app/bsky/unspecced/getPostThreadV2.js +2 -1
- package/dist/api/app/bsky/unspecced/getPostThreadV2.js.map +1 -1
- package/dist/auth-verifier.d.ts +1 -0
- package/dist/auth-verifier.d.ts.map +1 -1
- package/dist/auth-verifier.js +1 -0
- package/dist/auth-verifier.js.map +1 -1
- package/dist/data-plane/server/indexing/plugins/feed-generator.js +2 -1
- package/dist/data-plane/server/indexing/plugins/feed-generator.js.map +1 -1
- package/dist/data-plane/server/indexing/plugins/list.js +2 -1
- package/dist/data-plane/server/indexing/plugins/list.js.map +1 -1
- package/dist/data-plane/server/indexing/plugins/post.js +3 -3
- package/dist/data-plane/server/indexing/plugins/post.js.map +1 -1
- package/dist/data-plane/server/indexing/plugins/profile.js +3 -2
- package/dist/data-plane/server/indexing/plugins/profile.js.map +1 -1
- package/dist/hydration/hydrator.d.ts +2 -0
- package/dist/hydration/hydrator.d.ts.map +1 -1
- package/dist/hydration/hydrator.js +8 -0
- package/dist/hydration/hydrator.js.map +1 -1
- package/dist/hydration/util.d.ts +13 -7
- package/dist/hydration/util.d.ts.map +1 -1
- package/dist/hydration/util.js +30 -10
- package/dist/hydration/util.js.map +1 -1
- package/dist/lexicons/app/bsky/actor/defs.defs.d.ts +1 -0
- package/dist/lexicons/app/bsky/actor/defs.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/actor/defs.defs.js +1 -0
- package/dist/lexicons/app/bsky/actor/defs.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/actor/profile.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/actor/profile.defs.js +2 -10
- package/dist/lexicons/app/bsky/actor/profile.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/embed/external.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/embed/external.defs.js +1 -1
- package/dist/lexicons/app/bsky/embed/external.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/embed/images.defs.d.ts +3 -0
- package/dist/lexicons/app/bsky/embed/images.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/embed/images.defs.js +1 -5
- package/dist/lexicons/app/bsky/embed/images.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/embed/video.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/embed/video.defs.js +2 -6
- package/dist/lexicons/app/bsky/embed/video.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/feed/generator.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/feed/generator.defs.js +1 -5
- package/dist/lexicons/app/bsky/feed/generator.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/graph/list.defs.d.ts.map +1 -1
- package/dist/lexicons/app/bsky/graph/list.defs.js +1 -5
- package/dist/lexicons/app/bsky/graph/list.defs.js.map +1 -1
- package/dist/lexicons/app/bsky/video/defs.defs.js +1 -1
- package/dist/lexicons/app/bsky/video/defs.defs.js.map +1 -1
- package/dist/lexicons/com/atproto/repo/uploadBlob.defs.d.ts +2 -6
- package/dist/lexicons/com/atproto/repo/uploadBlob.defs.d.ts.map +1 -1
- package/dist/lexicons/com/atproto/repo/uploadBlob.defs.js +1 -1
- package/dist/lexicons/com/atproto/repo/uploadBlob.defs.js.map +1 -1
- package/dist/views/index.d.ts.map +1 -1
- package/dist/views/index.js +13 -8
- package/dist/views/index.js.map +1 -1
- package/dist/views/util.d.ts +1 -2
- package/dist/views/util.d.ts.map +1 -1
- package/dist/views/util.js +1 -5
- package/dist/views/util.js.map +1 -1
- package/package.json +9 -9
- package/src/api/app/bsky/actor/getProfile.ts +3 -1
- package/src/api/app/bsky/actor/getProfiles.ts +3 -1
- package/src/api/app/bsky/actor/searchActors.ts +3 -1
- package/src/api/app/bsky/feed/getAuthorFeed.ts +3 -1
- package/src/api/app/bsky/feed/getLikes.ts +3 -1
- package/src/api/app/bsky/feed/getPostThread.ts +2 -1
- package/src/api/app/bsky/feed/getQuotes.ts +3 -1
- package/src/api/app/bsky/feed/getRepostedBy.ts +3 -1
- package/src/api/app/bsky/feed/searchPosts.ts +3 -1
- package/src/api/app/bsky/graph/getActorStarterPacks.ts +3 -1
- package/src/api/app/bsky/graph/getFollowers.ts +3 -1
- package/src/api/app/bsky/graph/getFollows.ts +3 -1
- package/src/api/app/bsky/graph/getList.ts +3 -1
- package/src/api/app/bsky/graph/getLists.ts +3 -1
- package/src/api/app/bsky/graph/getStarterPack.ts +3 -1
- package/src/api/app/bsky/graph/getStarterPacks.ts +3 -1
- package/src/api/app/bsky/graph/searchStarterPacks.ts +3 -1
- package/src/api/app/bsky/unspecced/getPostThreadOtherV2.ts +2 -1
- package/src/api/app/bsky/unspecced/getPostThreadV2.ts +2 -1
- package/src/auth-verifier.ts +1 -0
- package/src/data-plane/server/indexing/plugins/feed-generator.ts +2 -2
- package/src/data-plane/server/indexing/plugins/list.ts +2 -2
- package/src/data-plane/server/indexing/plugins/post.ts +4 -4
- package/src/data-plane/server/indexing/plugins/profile.ts +3 -3
- package/src/hydration/hydrator.ts +6 -0
- package/src/hydration/util.ts +40 -21
- package/src/views/index.ts +19 -15
- package/src/views/util.ts +1 -5
- package/tests/views/__snapshots__/profile.test.ts.snap +3 -0
- package/tests/views/blocks.test.ts +69 -0
- package/tests/views/profile.test.ts +77 -0
package/src/hydration/util.ts
CHANGED
|
@@ -2,19 +2,24 @@ import { Timestamp } from '@bufbuild/protobuf'
|
|
|
2
2
|
import {
|
|
3
3
|
AtUriString,
|
|
4
4
|
Cid,
|
|
5
|
-
|
|
5
|
+
InferInput,
|
|
6
|
+
InferOutput,
|
|
6
7
|
LexParseOptions,
|
|
7
8
|
LexValue,
|
|
8
9
|
RecordSchema,
|
|
9
10
|
Schema,
|
|
10
11
|
TypedLexMap,
|
|
11
12
|
ValidateOptions,
|
|
12
|
-
|
|
13
|
+
lexParseJsonBytes,
|
|
13
14
|
parseCidSafe,
|
|
14
15
|
} from '@atproto/lex'
|
|
15
16
|
import { AtUri } from '@atproto/syntax'
|
|
16
17
|
import { Record as RecordEntry } from '../proto/bsky_pb'
|
|
17
18
|
|
|
19
|
+
const PARSE_OPTIONS: LexParseOptions & ValidateOptions = {
|
|
20
|
+
strict: false,
|
|
21
|
+
}
|
|
22
|
+
|
|
18
23
|
export class HydrationMap<K, T> extends Map<K, T | null> implements Merges {
|
|
19
24
|
merge(map: HydrationMap<K, T>): this {
|
|
20
25
|
for (const [key, val] of map) {
|
|
@@ -28,8 +33,8 @@ export interface Merges {
|
|
|
28
33
|
merge<T extends this>(map: T): this
|
|
29
34
|
}
|
|
30
35
|
|
|
31
|
-
export type RecordInfo<T extends
|
|
32
|
-
record: T
|
|
36
|
+
export type RecordInfo<T extends TypedLexMap> = {
|
|
37
|
+
record: T
|
|
33
38
|
cid: string
|
|
34
39
|
sortedAt: Date
|
|
35
40
|
indexedAt: Date
|
|
@@ -70,17 +75,32 @@ export function parseRecord<TSchema extends RecordSchema>(
|
|
|
70
75
|
recordSchema: TSchema,
|
|
71
76
|
recordEntry: RecordEntry,
|
|
72
77
|
includeTakedowns: boolean,
|
|
73
|
-
): RecordInfo<
|
|
78
|
+
): RecordInfo<InferInput<TSchema>> | undefined {
|
|
74
79
|
if (!includeTakedowns && recordEntry.takenDown) {
|
|
75
80
|
return undefined
|
|
76
81
|
}
|
|
77
82
|
|
|
78
83
|
const cid = recordEntry.cid
|
|
79
|
-
if (!cid)
|
|
84
|
+
if (!cid) {
|
|
85
|
+
return undefined
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (recordEntry.record.byteLength === 0) {
|
|
89
|
+
return undefined
|
|
90
|
+
}
|
|
80
91
|
|
|
81
|
-
const record =
|
|
92
|
+
const record = lexParseJsonBytes(recordEntry.record, PARSE_OPTIONS)
|
|
82
93
|
if (!record) {
|
|
83
|
-
return
|
|
94
|
+
return undefined
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// @NOTE We cannot use parse mode here. We must return the original to ensure
|
|
98
|
+
// that the caller gets the same data as what is stored in the PDS (in case of
|
|
99
|
+
// records). This is important because the receiver of the data should be able
|
|
100
|
+
// to compute the right record CID.
|
|
101
|
+
|
|
102
|
+
if (!recordSchema.$matches(record, PARSE_OPTIONS)) {
|
|
103
|
+
return undefined
|
|
84
104
|
}
|
|
85
105
|
|
|
86
106
|
return {
|
|
@@ -92,23 +112,22 @@ export function parseRecord<TSchema extends RecordSchema>(
|
|
|
92
112
|
}
|
|
93
113
|
}
|
|
94
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Decodes binary data containing a JSON representation of a Lex value, and
|
|
117
|
+
* validates it against the provided schema, in parse mode (i.e., allowing
|
|
118
|
+
* coercion & defaults).
|
|
119
|
+
*
|
|
120
|
+
* Returns undefined if the input is empty (from dataplane's empty value
|
|
121
|
+
* convention), or if the validation fails.
|
|
122
|
+
*/
|
|
95
123
|
export const parseJsonBytes = <TSchema extends Schema<LexValue>>(
|
|
96
124
|
schema: TSchema,
|
|
97
125
|
bytes: Uint8Array | undefined,
|
|
98
|
-
|
|
99
|
-
): Infer<TSchema> | undefined => {
|
|
126
|
+
): InferOutput<TSchema> | undefined => {
|
|
100
127
|
if (!bytes || bytes.byteLength === 0) return undefined
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
bytes.buffer,
|
|
105
|
-
bytes.byteOffset,
|
|
106
|
-
bytes.byteLength,
|
|
107
|
-
)
|
|
108
|
-
const jsonString = jsonBuffer.toString('utf8')
|
|
109
|
-
|
|
110
|
-
const value = lexParse(jsonString, options)
|
|
111
|
-
return schema.ifMatches(value, options)
|
|
128
|
+
const value = lexParseJsonBytes(bytes, PARSE_OPTIONS)
|
|
129
|
+
const result = schema.safeParse(value, PARSE_OPTIONS)
|
|
130
|
+
return result.success ? result.value : undefined
|
|
112
131
|
}
|
|
113
132
|
|
|
114
133
|
export const parseString = <T extends string | undefined>(
|
package/src/views/index.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { HOUR, MINUTE, mapDefined } from '@atproto/common'
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
$Typed,
|
|
4
|
+
Un$Typed,
|
|
5
|
+
Unknown$TypedObject,
|
|
6
|
+
UriString,
|
|
7
|
+
getBlobCidString,
|
|
8
|
+
} from '@atproto/lex'
|
|
3
9
|
import {
|
|
4
10
|
AtUri,
|
|
5
11
|
AtUriString,
|
|
@@ -104,12 +110,7 @@ import {
|
|
|
104
110
|
isSelfLabelsType,
|
|
105
111
|
isVideoEmbedType,
|
|
106
112
|
} from './types.js'
|
|
107
|
-
import {
|
|
108
|
-
VideoUriBuilder,
|
|
109
|
-
cidFromBlobJson,
|
|
110
|
-
parsePostgate,
|
|
111
|
-
parseThreadGate,
|
|
112
|
-
} from './util'
|
|
113
|
+
import { VideoUriBuilder, parsePostgate, parseThreadGate } from './util'
|
|
113
114
|
|
|
114
115
|
const notificationDeletedRecord =
|
|
115
116
|
app.bsky.notification.defs.recordDeleted.$build({})
|
|
@@ -169,6 +170,7 @@ export class Views {
|
|
|
169
170
|
}
|
|
170
171
|
|
|
171
172
|
viewerBlockExists(did: DidString, state: HydrationState): boolean {
|
|
173
|
+
if (state.ctx?.skipViewerBlocks) return false
|
|
172
174
|
const viewer = state.profileViewers?.get(did)
|
|
173
175
|
if (!viewer) return false
|
|
174
176
|
return !!(
|
|
@@ -277,7 +279,7 @@ export class Views {
|
|
|
277
279
|
? this.imgUriBuilder.getPresetUri(
|
|
278
280
|
'banner',
|
|
279
281
|
did,
|
|
280
|
-
|
|
282
|
+
getBlobCidString(actor.profile.banner),
|
|
281
283
|
)
|
|
282
284
|
: undefined,
|
|
283
285
|
followersCount: profileAggs?.followers ?? 0,
|
|
@@ -356,7 +358,7 @@ export class Views {
|
|
|
356
358
|
? this.imgUriBuilder.getPresetUri(
|
|
357
359
|
'avatar',
|
|
358
360
|
did,
|
|
359
|
-
|
|
361
|
+
getBlobCidString(actor.profile.avatar),
|
|
360
362
|
)
|
|
361
363
|
: undefined,
|
|
362
364
|
// associated.feedgens and associated.lists info not necessarily included
|
|
@@ -576,6 +578,7 @@ export class Views {
|
|
|
576
578
|
}
|
|
577
579
|
|
|
578
580
|
const uri = AtUri.make(did, app.bsky.actor.status.$nsid, 'self').toString()
|
|
581
|
+
const labels = state.labels?.getBySubject(uri)
|
|
579
582
|
|
|
580
583
|
const minDuration = 5 * MINUTE
|
|
581
584
|
const maxDuration = 4 * HOUR
|
|
@@ -602,6 +605,7 @@ export class Views {
|
|
|
602
605
|
record.embed && isExternalEmbedType(record.embed)
|
|
603
606
|
? this.externalEmbed(did, record.embed)
|
|
604
607
|
: undefined,
|
|
608
|
+
labels,
|
|
605
609
|
expiresAt,
|
|
606
610
|
isActive,
|
|
607
611
|
}
|
|
@@ -672,7 +676,7 @@ export class Views {
|
|
|
672
676
|
? this.imgUriBuilder.getPresetUri(
|
|
673
677
|
'avatar',
|
|
674
678
|
creator,
|
|
675
|
-
|
|
679
|
+
getBlobCidString(list.record.avatar),
|
|
676
680
|
)
|
|
677
681
|
: undefined,
|
|
678
682
|
listItemCount: listAgg?.listItems ?? 0,
|
|
@@ -916,7 +920,7 @@ export class Views {
|
|
|
916
920
|
? this.imgUriBuilder.getPresetUri(
|
|
917
921
|
'avatar',
|
|
918
922
|
creatorDid,
|
|
919
|
-
|
|
923
|
+
getBlobCidString(feedgen.record.avatar),
|
|
920
924
|
)
|
|
921
925
|
: undefined,
|
|
922
926
|
likeCount: aggs?.likes ?? 0,
|
|
@@ -2076,12 +2080,12 @@ export class Views {
|
|
|
2076
2080
|
thumb: this.imgUriBuilder.getPresetUri(
|
|
2077
2081
|
'feed_thumbnail',
|
|
2078
2082
|
did,
|
|
2079
|
-
|
|
2083
|
+
getBlobCidString(img.image),
|
|
2080
2084
|
),
|
|
2081
2085
|
fullsize: this.imgUriBuilder.getPresetUri(
|
|
2082
2086
|
'feed_fullsize',
|
|
2083
2087
|
did,
|
|
2084
|
-
|
|
2088
|
+
getBlobCidString(img.image),
|
|
2085
2089
|
),
|
|
2086
2090
|
alt: img.alt,
|
|
2087
2091
|
aspectRatio: img.aspectRatio,
|
|
@@ -2092,7 +2096,7 @@ export class Views {
|
|
|
2092
2096
|
}
|
|
2093
2097
|
|
|
2094
2098
|
videoEmbed(did: DidString, embed: VideoEmbed): $Typed<VideoEmbedView> {
|
|
2095
|
-
const cid =
|
|
2099
|
+
const cid = getBlobCidString(embed.video)
|
|
2096
2100
|
return app.bsky.embed.video.view.$build({
|
|
2097
2101
|
cid,
|
|
2098
2102
|
playlist: this.videoUriBuilder.playlist({ did, cid }),
|
|
@@ -2117,7 +2121,7 @@ export class Views {
|
|
|
2117
2121
|
? this.imgUriBuilder.getPresetUri(
|
|
2118
2122
|
'feed_thumbnail',
|
|
2119
2123
|
did,
|
|
2120
|
-
|
|
2124
|
+
getBlobCidString(thumb),
|
|
2121
2125
|
)
|
|
2122
2126
|
: undefined,
|
|
2123
2127
|
},
|
package/src/views/util.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as util from 'node:util'
|
|
2
|
-
import { AtUriString,
|
|
2
|
+
import { AtUriString, DidString, UriString } from '@atproto/lex'
|
|
3
3
|
import {
|
|
4
4
|
GateRecord,
|
|
5
5
|
PostRecord,
|
|
@@ -59,10 +59,6 @@ type ParsedThreadGate = {
|
|
|
59
59
|
allowListUris?: AtUriString[]
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
export const cidFromBlobJson = (json: BlobRef): string => {
|
|
63
|
-
return json.ref.toString()
|
|
64
|
-
}
|
|
65
|
-
|
|
66
62
|
export const parsePostgate = ({
|
|
67
63
|
gate,
|
|
68
64
|
viewerDid,
|
|
@@ -722,6 +722,7 @@ Object {
|
|
|
722
722
|
"expiresAt": "1970-01-01T00:00:00.000Z",
|
|
723
723
|
"isActive": true,
|
|
724
724
|
"isDisabled": false,
|
|
725
|
+
"labels": Array [],
|
|
725
726
|
"record": Object {
|
|
726
727
|
"$type": "app.bsky.actor.status",
|
|
727
728
|
"createdAt": "1970-01-01T00:00:00.000Z",
|
|
@@ -755,6 +756,7 @@ Object {
|
|
|
755
756
|
"expiresAt": "1970-01-01T00:00:00.000Z",
|
|
756
757
|
"isActive": false,
|
|
757
758
|
"isDisabled": false,
|
|
759
|
+
"labels": Array [],
|
|
758
760
|
"record": Object {
|
|
759
761
|
"$type": "app.bsky.actor.status",
|
|
760
762
|
"createdAt": "1970-01-01T00:00:00.000Z",
|
|
@@ -788,6 +790,7 @@ Object {
|
|
|
788
790
|
"expiresAt": "1970-01-01T00:00:00.000Z",
|
|
789
791
|
"isActive": true,
|
|
790
792
|
"isDisabled": true,
|
|
793
|
+
"labels": Array [],
|
|
791
794
|
"record": Object {
|
|
792
795
|
"$type": "app.bsky.actor.status",
|
|
793
796
|
"createdAt": "1970-01-01T00:00:00.000Z",
|
|
@@ -817,4 +817,73 @@ describe('pds views with blocking', () => {
|
|
|
817
817
|
expect(knownFollowers?.count).toBe(1)
|
|
818
818
|
expect(knownFollowers?.followers).toHaveLength(0)
|
|
819
819
|
})
|
|
820
|
+
|
|
821
|
+
describe('mod service sees through blocks', () => {
|
|
822
|
+
let modServiceDid: string
|
|
823
|
+
|
|
824
|
+
beforeAll(async () => {
|
|
825
|
+
modServiceDid = network.bsky.ctx.cfg.modServiceDid
|
|
826
|
+
// alice blocks the mod service
|
|
827
|
+
await pdsAgent.app.bsky.graph.block.create(
|
|
828
|
+
{ repo: alice },
|
|
829
|
+
{ createdAt: new Date().toISOString(), subject: modServiceDid },
|
|
830
|
+
sc.getHeaders(alice),
|
|
831
|
+
)
|
|
832
|
+
await network.processAll()
|
|
833
|
+
})
|
|
834
|
+
|
|
835
|
+
it('mod service viewer preserves block state on getProfile', async () => {
|
|
836
|
+
// alice blocked the mod service, mod service views alice's profile
|
|
837
|
+
const res = await agent.app.bsky.actor.getProfile(
|
|
838
|
+
{ actor: alice },
|
|
839
|
+
{
|
|
840
|
+
headers: await network.serviceHeaders(
|
|
841
|
+
modServiceDid,
|
|
842
|
+
ids.AppBskyActorGetProfile,
|
|
843
|
+
),
|
|
844
|
+
},
|
|
845
|
+
)
|
|
846
|
+
// block state is still present on the viewer
|
|
847
|
+
expect(res.data.viewer?.blockedBy).toBe(true)
|
|
848
|
+
expect(res.data.viewer?.blocking).toBeUndefined()
|
|
849
|
+
})
|
|
850
|
+
|
|
851
|
+
it('mod service sees through blocks on getPostThread', async () => {
|
|
852
|
+
// alice has posts; mod service should see them even though alice blocked mod service
|
|
853
|
+
const { data } = await agent.app.bsky.feed.getPostThread(
|
|
854
|
+
{ depth: 1, uri: sc.posts[alice][0].ref.uriStr },
|
|
855
|
+
{
|
|
856
|
+
headers: await network.serviceHeaders(
|
|
857
|
+
modServiceDid,
|
|
858
|
+
ids.AppBskyFeedGetPostThread,
|
|
859
|
+
),
|
|
860
|
+
},
|
|
861
|
+
)
|
|
862
|
+
assertIsThreadViewPost(data.thread)
|
|
863
|
+
expect(data.thread.post.uri).toBe(sc.posts[alice][0].ref.uriStr)
|
|
864
|
+
})
|
|
865
|
+
|
|
866
|
+
it('mod service sees through blocks on getPostThreadV2', async () => {
|
|
867
|
+
const { data } = await agent.app.bsky.unspecced.getPostThreadV2(
|
|
868
|
+
{ anchor: sc.posts[alice][0].ref.uriStr },
|
|
869
|
+
{
|
|
870
|
+
headers: await network.serviceHeaders(
|
|
871
|
+
modServiceDid,
|
|
872
|
+
ids.AppBskyUnspeccedGetPostThreadV2,
|
|
873
|
+
),
|
|
874
|
+
},
|
|
875
|
+
)
|
|
876
|
+
expect(data.thread).toEqual(
|
|
877
|
+
expect.arrayContaining([
|
|
878
|
+
expect.objectContaining({
|
|
879
|
+
uri: sc.posts[alice][0].ref.uriStr,
|
|
880
|
+
depth: 0,
|
|
881
|
+
value: expect.objectContaining({
|
|
882
|
+
$type: 'app.bsky.unspecced.defs#threadItemPost',
|
|
883
|
+
}),
|
|
884
|
+
}),
|
|
885
|
+
]),
|
|
886
|
+
)
|
|
887
|
+
})
|
|
888
|
+
})
|
|
820
889
|
})
|
|
@@ -16,6 +16,7 @@ describe('pds profile views', () => {
|
|
|
16
16
|
let agent: AtpAgent
|
|
17
17
|
let pdsAgent: AtpAgent
|
|
18
18
|
let sc: SeedClient
|
|
19
|
+
let labelerDid: string
|
|
19
20
|
|
|
20
21
|
// account dids, for convenience
|
|
21
22
|
let alice: string
|
|
@@ -32,6 +33,7 @@ describe('pds profile views', () => {
|
|
|
32
33
|
agent = network.bsky.getAgent()
|
|
33
34
|
pdsAgent = network.pds.getAgent()
|
|
34
35
|
sc = network.getSeedClient()
|
|
36
|
+
labelerDid = network.bsky.ctx.cfg.labelsFromIssuerDids[0]
|
|
35
37
|
await basicSeed(sc)
|
|
36
38
|
|
|
37
39
|
await sc.createAccount('eve', {
|
|
@@ -499,6 +501,60 @@ describe('pds profile views', () => {
|
|
|
499
501
|
})
|
|
500
502
|
})
|
|
501
503
|
|
|
504
|
+
describe('labeled', () => {
|
|
505
|
+
beforeAll(async () => {
|
|
506
|
+
const res = await sc.agent.com.atproto.repo.putRecord(
|
|
507
|
+
{
|
|
508
|
+
repo: alice,
|
|
509
|
+
collection: ids.AppBskyActorStatus,
|
|
510
|
+
rkey: 'self',
|
|
511
|
+
record: {
|
|
512
|
+
status: 'app.bsky.actor.status#live',
|
|
513
|
+
embed,
|
|
514
|
+
durationMinutes: 10,
|
|
515
|
+
createdAt: new Date().toISOString(),
|
|
516
|
+
},
|
|
517
|
+
},
|
|
518
|
+
{
|
|
519
|
+
headers: sc.getHeaders(alice),
|
|
520
|
+
encoding: 'application/json',
|
|
521
|
+
},
|
|
522
|
+
)
|
|
523
|
+
await network.processAll()
|
|
524
|
+
|
|
525
|
+
await createLabel({
|
|
526
|
+
src: labelerDid,
|
|
527
|
+
uri: res.data.uri,
|
|
528
|
+
cid: res.data.cid,
|
|
529
|
+
val: 'spam',
|
|
530
|
+
})
|
|
531
|
+
await network.processAll()
|
|
532
|
+
})
|
|
533
|
+
|
|
534
|
+
it('returns labels on statusView', async () => {
|
|
535
|
+
const { data } = await agent.api.app.bsky.actor.getProfile(
|
|
536
|
+
{ actor: alice },
|
|
537
|
+
{
|
|
538
|
+
headers: {
|
|
539
|
+
'atproto-accept-labelers': labelerDid,
|
|
540
|
+
...(await network.serviceHeaders(
|
|
541
|
+
bob,
|
|
542
|
+
ids.AppBskyActorGetProfile,
|
|
543
|
+
)),
|
|
544
|
+
},
|
|
545
|
+
},
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
expect(data.status?.labels).toBeDefined()
|
|
549
|
+
expect(data.status?.labels?.length).toBe(1)
|
|
550
|
+
expect(data.status?.labels?.at(0)?.val).toBe('spam')
|
|
551
|
+
})
|
|
552
|
+
})
|
|
553
|
+
|
|
554
|
+
/*
|
|
555
|
+
* THIS ONE MUST BE LAST, since a takedown of a `self` rkey record prevents
|
|
556
|
+
* subsequent hydrations of that record.
|
|
557
|
+
*/
|
|
502
558
|
describe('when taken down', () => {
|
|
503
559
|
beforeAll(async () => {
|
|
504
560
|
const res = await sc.agent.com.atproto.repo.putRecord(
|
|
@@ -655,4 +711,25 @@ describe('pds profile views', () => {
|
|
|
655
711
|
{ headers: sc.getHeaders(did), encoding: 'application/json' },
|
|
656
712
|
)
|
|
657
713
|
}
|
|
714
|
+
|
|
715
|
+
const createLabel = async (opts: {
|
|
716
|
+
src?: string
|
|
717
|
+
uri: string
|
|
718
|
+
cid: string
|
|
719
|
+
val: string
|
|
720
|
+
exp?: string
|
|
721
|
+
}) => {
|
|
722
|
+
await network.bsky.db.db
|
|
723
|
+
.insertInto('label')
|
|
724
|
+
.values({
|
|
725
|
+
uri: opts.uri,
|
|
726
|
+
cid: opts.cid,
|
|
727
|
+
val: opts.val,
|
|
728
|
+
cts: new Date().toISOString(),
|
|
729
|
+
exp: opts.exp ?? null,
|
|
730
|
+
neg: false,
|
|
731
|
+
src: opts.src ?? labelerDid,
|
|
732
|
+
})
|
|
733
|
+
.execute()
|
|
734
|
+
}
|
|
658
735
|
})
|