@atproto/bsky 0.0.37 → 0.0.38
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 +14 -0
- package/dist/api/app/bsky/feed/getAuthorFeed.d.ts +2 -3
- package/dist/api/app/bsky/feed/getListFeed.d.ts +2 -2
- package/dist/api/app/bsky/feed/getTimeline.d.ts +4 -2
- package/dist/api/app/bsky/labeler/getServices.d.ts +3 -0
- package/dist/api/util.d.ts +9 -2
- package/dist/auth-verifier.d.ts +1 -1
- package/dist/context.d.ts +3 -0
- package/dist/data-plane/server/db/database-schema.d.ts +2 -2
- package/dist/data-plane/server/db/migrations/20240226T225725627Z-labelers.d.ts +3 -0
- package/dist/data-plane/server/db/migrations/index.d.ts +1 -0
- package/dist/data-plane/server/db/tables/labeler.d.ts +13 -0
- package/dist/data-plane/server/indexing/index.d.ts +2 -0
- package/dist/data-plane/server/indexing/plugins/labeler.d.ts +10 -0
- package/dist/data-plane/server/util.d.ts +6 -6
- package/dist/hydration/actor.d.ts +3 -0
- package/dist/hydration/hydrator.d.ts +27 -22
- package/dist/hydration/label.d.ts +23 -9
- package/dist/index.js +4068 -4641
- package/dist/index.js.map +3 -3
- package/dist/lexicon/index.d.ts +7 -27
- package/dist/lexicon/lexicons.d.ts +507 -1467
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts +23 -1
- package/dist/lexicon/types/app/bsky/embed/record.d.ts +2 -1
- package/dist/lexicon/types/app/bsky/feed/defs.d.ts +1 -0
- package/dist/lexicon/types/app/bsky/graph/defs.d.ts +3 -0
- package/dist/lexicon/types/app/bsky/labeler/defs.d.ts +41 -0
- package/dist/lexicon/types/{com/atproto/admin/searchRepos.d.ts → app/bsky/labeler/getServices.d.ts} +7 -7
- package/dist/lexicon/types/app/bsky/labeler/service.d.ts +14 -0
- package/dist/lexicon/types/com/atproto/admin/defs.d.ts +0 -304
- package/dist/lexicon/types/com/atproto/label/defs.d.ts +23 -0
- package/dist/proto/bsky_connect.d.ts +7 -1
- package/dist/proto/bsky_pb.d.ts +25 -0
- package/dist/util.d.ts +7 -0
- package/dist/views/index.d.ts +3 -0
- package/dist/views/types.d.ts +2 -1
- package/package.json +14 -13
- package/proto/bsky.proto +12 -0
- package/src/api/app/bsky/actor/getProfile.ts +21 -17
- package/src/api/app/bsky/actor/getProfiles.ts +16 -7
- package/src/api/app/bsky/actor/getSuggestions.ts +18 -13
- package/src/api/app/bsky/actor/searchActors.ts +9 -5
- package/src/api/app/bsky/actor/searchActorsTypeahead.ts +12 -5
- package/src/api/app/bsky/feed/getActorFeeds.ts +16 -6
- package/src/api/app/bsky/feed/getActorLikes.ts +18 -8
- package/src/api/app/bsky/feed/getAuthorFeed.ts +18 -19
- package/src/api/app/bsky/feed/getFeed.ts +14 -7
- package/src/api/app/bsky/feed/getFeedGenerator.ts +8 -2
- package/src/api/app/bsky/feed/getFeedGenerators.ts +16 -5
- package/src/api/app/bsky/feed/getLikes.ts +13 -6
- package/src/api/app/bsky/feed/getListFeed.ts +13 -7
- package/src/api/app/bsky/feed/getPostThread.ts +15 -8
- package/src/api/app/bsky/feed/getPosts.ts +14 -5
- package/src/api/app/bsky/feed/getRepostedBy.ts +13 -6
- package/src/api/app/bsky/feed/getSuggestedFeeds.ts +8 -2
- package/src/api/app/bsky/feed/getTimeline.ts +14 -8
- package/src/api/app/bsky/feed/searchPosts.ts +9 -5
- package/src/api/app/bsky/graph/getBlocks.ts +10 -9
- package/src/api/app/bsky/graph/getFollowers.ts +23 -15
- package/src/api/app/bsky/graph/getFollows.ts +23 -15
- package/src/api/app/bsky/graph/getList.ts +14 -8
- package/src/api/app/bsky/graph/getListBlocks.ts +10 -7
- package/src/api/app/bsky/graph/getListMutes.ts +10 -7
- package/src/api/app/bsky/graph/getLists.ts +9 -7
- package/src/api/app/bsky/graph/getMutes.ts +10 -8
- package/src/api/app/bsky/graph/getSuggestedFollowsByActor.ts +10 -7
- package/src/api/app/bsky/graph/muteActor.ts +1 -1
- package/src/api/app/bsky/labeler/getServices.ts +46 -0
- package/src/api/app/bsky/notification/listNotifications.ts +12 -8
- package/src/api/app/bsky/unspecced/getPopularFeedGenerators.ts +6 -3
- package/src/api/com/atproto/admin/getAccountInfos.ts +10 -3
- package/src/api/index.ts +2 -0
- package/src/api/util.ts +19 -4
- package/src/auth-verifier.ts +2 -2
- package/src/context.ts +20 -0
- package/src/data-plane/server/db/database-schema.ts +4 -4
- package/src/data-plane/server/db/migrations/20240226T225725627Z-labelers.ts +27 -0
- package/src/data-plane/server/db/migrations/index.ts +1 -0
- package/src/data-plane/server/db/tables/labeler.ts +16 -0
- package/src/data-plane/server/indexing/index.ts +4 -0
- package/src/data-plane/server/indexing/plugins/labeler.ts +77 -0
- package/src/data-plane/server/routes/interactions.ts +17 -1
- package/src/data-plane/server/routes/profile.ts +15 -1
- package/src/data-plane/server/routes/records.ts +1 -0
- package/src/hydration/actor.ts +6 -0
- package/src/hydration/hydrator.ts +171 -97
- package/src/hydration/label.ts +106 -20
- package/src/index.ts +1 -3
- package/src/lexicon/index.ts +22 -137
- package/src/lexicon/lexicons.ts +502 -1598
- package/src/lexicon/types/app/bsky/actor/defs.ts +57 -1
- package/src/lexicon/types/app/bsky/embed/record.ts +2 -0
- package/src/lexicon/types/app/bsky/feed/defs.ts +1 -0
- package/src/lexicon/types/app/bsky/graph/defs.ts +3 -0
- package/src/lexicon/types/app/bsky/labeler/defs.ts +93 -0
- package/src/lexicon/types/{com/atproto/admin/searchRepos.ts → app/bsky/labeler/getServices.ts} +8 -8
- package/src/lexicon/types/app/bsky/labeler/service.ts +31 -0
- package/src/lexicon/types/com/atproto/admin/defs.ts +0 -694
- package/src/lexicon/types/com/atproto/label/defs.ts +78 -0
- package/src/proto/bsky_connect.ts +11 -0
- package/src/proto/bsky_pb.ts +146 -0
- package/src/util.ts +44 -0
- package/src/views/index.ts +76 -7
- package/src/views/types.ts +6 -3
- package/tests/__snapshots__/feed-generation.test.ts.snap +12 -0
- package/tests/_util.ts +21 -0
- package/tests/data-plane/__snapshots__/indexing.test.ts.snap +20 -0
- package/tests/label-hydration.test.ts +162 -0
- package/tests/views/__snapshots__/block-lists.test.ts.snap +7 -0
- package/tests/views/__snapshots__/labeler-service.test.ts.snap +160 -0
- package/tests/views/__snapshots__/mute-lists.test.ts.snap +10 -0
- package/tests/views/__snapshots__/profile.test.ts.snap +40 -0
- package/tests/views/__snapshots__/threadgating.test.ts.snap +2 -0
- package/tests/views/labeler-service.test.ts +156 -0
- package/tests/views/takedown-labels.test.ts +133 -0
- package/tests/views/timeline.test.ts +7 -2
- package/dist/data-plane/server/db/tables/moderation.d.ts +0 -42
- package/dist/lexicon/types/com/atproto/admin/createCommunicationTemplate.d.ts +0 -37
- package/dist/lexicon/types/com/atproto/admin/deleteCommunicationTemplate.d.ts +0 -25
- package/dist/lexicon/types/com/atproto/admin/emitModerationEvent.d.ts +0 -45
- package/dist/lexicon/types/com/atproto/admin/getModerationEvent.d.ts +0 -29
- package/dist/lexicon/types/com/atproto/admin/getRecord.d.ts +0 -31
- package/dist/lexicon/types/com/atproto/admin/getRepo.d.ts +0 -30
- package/dist/lexicon/types/com/atproto/admin/listCommunicationTemplates.d.ts +0 -31
- package/dist/lexicon/types/com/atproto/admin/queryModerationEvents.d.ts +0 -48
- package/dist/lexicon/types/com/atproto/admin/queryModerationStatuses.d.ts +0 -50
- package/dist/lexicon/types/com/atproto/admin/updateCommunicationTemplate.d.ts +0 -39
- package/src/data-plane/server/db/tables/moderation.ts +0 -59
- package/src/lexicon/types/com/atproto/admin/createCommunicationTemplate.ts +0 -54
- package/src/lexicon/types/com/atproto/admin/deleteCommunicationTemplate.ts +0 -38
- package/src/lexicon/types/com/atproto/admin/emitModerationEvent.ts +0 -67
- package/src/lexicon/types/com/atproto/admin/getModerationEvent.ts +0 -41
- package/src/lexicon/types/com/atproto/admin/getRecord.ts +0 -43
- package/src/lexicon/types/com/atproto/admin/getRepo.ts +0 -42
- package/src/lexicon/types/com/atproto/admin/listCommunicationTemplates.ts +0 -44
- package/src/lexicon/types/com/atproto/admin/queryModerationEvents.ts +0 -73
- package/src/lexicon/types/com/atproto/admin/queryModerationStatuses.ts +0 -74
- package/src/lexicon/types/com/atproto/admin/updateCommunicationTemplate.ts +0 -57
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
SkeletonFnInput,
|
|
20
20
|
createPipeline,
|
|
21
21
|
} from '../../../../pipeline'
|
|
22
|
+
import { HydrateCtx } from '../../../../hydration/hydrator'
|
|
22
23
|
import { FeedItem } from '../../../../hydration/feed'
|
|
23
24
|
import { GetIdentityByDidResponse } from '../../../../proto/bsky_pb'
|
|
24
25
|
import {
|
|
@@ -27,6 +28,7 @@ import {
|
|
|
27
28
|
isDataplaneError,
|
|
28
29
|
unpackIdentityServices,
|
|
29
30
|
} from '../../../../data-plane'
|
|
31
|
+
import { resHeaders } from '../../../util'
|
|
30
32
|
|
|
31
33
|
export default function (server: Server, ctx: AppContext) {
|
|
32
34
|
const getFeed = createPipeline(
|
|
@@ -39,21 +41,26 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
39
41
|
auth: ctx.authVerifier.standardOptionalAnyAud,
|
|
40
42
|
handler: async ({ params, auth, req }) => {
|
|
41
43
|
const viewer = auth.credentials.iss
|
|
44
|
+
const labelers = ctx.reqLabelers(req)
|
|
45
|
+
const hydrateCtx = { labelers, viewer }
|
|
42
46
|
const headers = noUndefinedVals({
|
|
43
47
|
authorization: req.headers['authorization'],
|
|
44
48
|
'accept-language': req.headers['accept-language'],
|
|
45
49
|
})
|
|
46
50
|
// @NOTE feed cursors should not be affected by appview swap
|
|
47
|
-
const {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
const {
|
|
52
|
+
timerSkele,
|
|
53
|
+
timerHydr,
|
|
54
|
+
resHeaders: feedResHeaders,
|
|
55
|
+
...result
|
|
56
|
+
} = await getFeed({ ...params, hydrateCtx, headers }, ctx)
|
|
51
57
|
|
|
52
58
|
return {
|
|
53
59
|
encoding: 'application/json',
|
|
54
60
|
body: result,
|
|
55
61
|
headers: {
|
|
56
|
-
...(
|
|
62
|
+
...(feedResHeaders ?? {}),
|
|
63
|
+
...resHeaders({ labelers }),
|
|
57
64
|
'server-timing': serverTimingHeader([timerSkele, timerHydr]),
|
|
58
65
|
},
|
|
59
66
|
}
|
|
@@ -90,7 +97,7 @@ const hydration = async (
|
|
|
90
97
|
const timerHydr = new ServerTimer('hydr').start()
|
|
91
98
|
const hydration = await ctx.hydrator.hydrateFeedItems(
|
|
92
99
|
skeleton.items,
|
|
93
|
-
params.
|
|
100
|
+
params.hydrateCtx,
|
|
94
101
|
)
|
|
95
102
|
skeleton.timerHydr = timerHydr.stop()
|
|
96
103
|
return hydration
|
|
@@ -130,7 +137,7 @@ const presentation = (
|
|
|
130
137
|
type Context = AppContext
|
|
131
138
|
|
|
132
139
|
type Params = GetFeedParams & {
|
|
133
|
-
|
|
140
|
+
hydrateCtx: HydrateCtx
|
|
134
141
|
headers: Record<string, string>
|
|
135
142
|
}
|
|
136
143
|
|
|
@@ -8,15 +8,20 @@ import {
|
|
|
8
8
|
isDataplaneError,
|
|
9
9
|
unpackIdentityServices,
|
|
10
10
|
} from '../../../../data-plane'
|
|
11
|
+
import { resHeaders } from '../../../util'
|
|
11
12
|
|
|
12
13
|
export default function (server: Server, ctx: AppContext) {
|
|
13
14
|
server.app.bsky.feed.getFeedGenerator({
|
|
14
15
|
auth: ctx.authVerifier.standardOptional,
|
|
15
|
-
handler: async ({ params, auth }) => {
|
|
16
|
+
handler: async ({ params, auth, req }) => {
|
|
16
17
|
const { feed } = params
|
|
17
18
|
const viewer = auth.credentials.iss
|
|
19
|
+
const labelers = ctx.reqLabelers(req)
|
|
18
20
|
|
|
19
|
-
const hydration = await ctx.hydrator.hydrateFeedGens([feed],
|
|
21
|
+
const hydration = await ctx.hydrator.hydrateFeedGens([feed], {
|
|
22
|
+
viewer,
|
|
23
|
+
labelers,
|
|
24
|
+
})
|
|
20
25
|
const feedInfo = hydration.feedgens?.get(feed)
|
|
21
26
|
if (!feedInfo) {
|
|
22
27
|
throw new InvalidRequestError('could not find feed')
|
|
@@ -59,6 +64,7 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
59
64
|
isOnline: true,
|
|
60
65
|
isValid: true,
|
|
61
66
|
},
|
|
67
|
+
headers: resHeaders({ labelers }),
|
|
62
68
|
}
|
|
63
69
|
},
|
|
64
70
|
})
|
|
@@ -3,8 +3,13 @@ import { Server } from '../../../../lexicon'
|
|
|
3
3
|
import { QueryParams } from '../../../../lexicon/types/app/bsky/feed/getFeedGenerators'
|
|
4
4
|
import AppContext from '../../../../context'
|
|
5
5
|
import { createPipeline, noRules } from '../../../../pipeline'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
HydrateCtx,
|
|
8
|
+
HydrationState,
|
|
9
|
+
Hydrator,
|
|
10
|
+
} from '../../../../hydration/hydrator'
|
|
7
11
|
import { Views } from '../../../../views'
|
|
12
|
+
import { resHeaders } from '../../../util'
|
|
8
13
|
|
|
9
14
|
export default function (server: Server, ctx: AppContext) {
|
|
10
15
|
const getFeedGenerators = createPipeline(
|
|
@@ -15,12 +20,15 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
15
20
|
)
|
|
16
21
|
server.app.bsky.feed.getFeedGenerators({
|
|
17
22
|
auth: ctx.authVerifier.standardOptional,
|
|
18
|
-
handler: async ({ params, auth }) => {
|
|
23
|
+
handler: async ({ params, auth, req }) => {
|
|
19
24
|
const viewer = auth.credentials.iss
|
|
20
|
-
const
|
|
25
|
+
const labelers = ctx.reqLabelers(req)
|
|
26
|
+
const hydrateCtx = { labelers, viewer }
|
|
27
|
+
const view = await getFeedGenerators({ ...params, hydrateCtx }, ctx)
|
|
21
28
|
return {
|
|
22
29
|
encoding: 'application/json',
|
|
23
30
|
body: view,
|
|
31
|
+
headers: resHeaders({ labelers }),
|
|
24
32
|
}
|
|
25
33
|
},
|
|
26
34
|
})
|
|
@@ -38,7 +46,10 @@ const hydration = async (inputs: {
|
|
|
38
46
|
skeleton: Skeleton
|
|
39
47
|
}) => {
|
|
40
48
|
const { ctx, params, skeleton } = inputs
|
|
41
|
-
return await ctx.hydrator.hydrateFeedGens(
|
|
49
|
+
return await ctx.hydrator.hydrateFeedGens(
|
|
50
|
+
skeleton.feedUris,
|
|
51
|
+
params.hydrateCtx,
|
|
52
|
+
)
|
|
42
53
|
}
|
|
43
54
|
|
|
44
55
|
const presentation = (inputs: {
|
|
@@ -60,7 +71,7 @@ type Context = {
|
|
|
60
71
|
views: Views
|
|
61
72
|
}
|
|
62
73
|
|
|
63
|
-
type Params = QueryParams & {
|
|
74
|
+
type Params = QueryParams & { hydrateCtx: HydrateCtx }
|
|
64
75
|
|
|
65
76
|
type Skeleton = {
|
|
66
77
|
feedUris: string[]
|
|
@@ -4,23 +4,30 @@ import { Server } from '../../../../lexicon'
|
|
|
4
4
|
import { QueryParams } from '../../../../lexicon/types/app/bsky/feed/getLikes'
|
|
5
5
|
import AppContext from '../../../../context'
|
|
6
6
|
import { createPipeline } from '../../../../pipeline'
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
HydrateCtx,
|
|
9
|
+
HydrationState,
|
|
10
|
+
Hydrator,
|
|
11
|
+
} from '../../../../hydration/hydrator'
|
|
8
12
|
import { Views } from '../../../../views'
|
|
9
13
|
import { parseString } from '../../../../hydration/util'
|
|
10
14
|
import { creatorFromUri } from '../../../../views/util'
|
|
11
|
-
import { clearlyBadCursor } from '../../../util'
|
|
15
|
+
import { clearlyBadCursor, resHeaders } from '../../../util'
|
|
12
16
|
|
|
13
17
|
export default function (server: Server, ctx: AppContext) {
|
|
14
18
|
const getLikes = createPipeline(skeleton, hydration, noBlocks, presentation)
|
|
15
19
|
server.app.bsky.feed.getLikes({
|
|
16
20
|
auth: ctx.authVerifier.standardOptional,
|
|
17
|
-
handler: async ({ params, auth }) => {
|
|
21
|
+
handler: async ({ params, auth, req }) => {
|
|
18
22
|
const viewer = auth.credentials.iss
|
|
19
|
-
const
|
|
23
|
+
const labelers = ctx.reqLabelers(req)
|
|
24
|
+
const hydrateCtx = { labelers, viewer }
|
|
25
|
+
const result = await getLikes({ ...params, hydrateCtx }, ctx)
|
|
20
26
|
|
|
21
27
|
return {
|
|
22
28
|
encoding: 'application/json',
|
|
23
29
|
body: result,
|
|
30
|
+
headers: resHeaders({ labelers }),
|
|
24
31
|
}
|
|
25
32
|
},
|
|
26
33
|
})
|
|
@@ -51,7 +58,7 @@ const hydration = async (inputs: {
|
|
|
51
58
|
skeleton: Skeleton
|
|
52
59
|
}) => {
|
|
53
60
|
const { ctx, params, skeleton } = inputs
|
|
54
|
-
return await ctx.hydrator.hydrateLikes(skeleton.likes, params.
|
|
61
|
+
return await ctx.hydrator.hydrateLikes(skeleton.likes, params.hydrateCtx)
|
|
55
62
|
}
|
|
56
63
|
|
|
57
64
|
const noBlocks = (inputs: {
|
|
@@ -103,7 +110,7 @@ type Context = {
|
|
|
103
110
|
views: Views
|
|
104
111
|
}
|
|
105
112
|
|
|
106
|
-
type Params = QueryParams & {
|
|
113
|
+
type Params = QueryParams & { hydrateCtx: HydrateCtx }
|
|
107
114
|
|
|
108
115
|
type Skeleton = {
|
|
109
116
|
likes: string[]
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { Server } from '../../../../lexicon'
|
|
2
2
|
import { QueryParams } from '../../../../lexicon/types/app/bsky/feed/getListFeed'
|
|
3
3
|
import AppContext from '../../../../context'
|
|
4
|
-
import { clearlyBadCursor,
|
|
4
|
+
import { clearlyBadCursor, resHeaders } from '../../../util'
|
|
5
5
|
import { createPipeline } from '../../../../pipeline'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
HydrateCtx,
|
|
8
|
+
HydrationState,
|
|
9
|
+
Hydrator,
|
|
10
|
+
} from '../../../../hydration/hydrator'
|
|
7
11
|
import { Views } from '../../../../views'
|
|
8
12
|
import { DataPlaneClient } from '../../../../data-plane'
|
|
9
13
|
import { mapDefined } from '@atproto/common'
|
|
@@ -19,17 +23,19 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
19
23
|
)
|
|
20
24
|
server.app.bsky.feed.getListFeed({
|
|
21
25
|
auth: ctx.authVerifier.standardOptional,
|
|
22
|
-
handler: async ({ params, auth,
|
|
26
|
+
handler: async ({ params, auth, req }) => {
|
|
23
27
|
const viewer = auth.credentials.iss
|
|
28
|
+
const labelers = ctx.reqLabelers(req)
|
|
29
|
+
const hydrateCtx = { labelers, viewer }
|
|
24
30
|
|
|
25
|
-
const result = await getListFeed({ ...params,
|
|
31
|
+
const result = await getListFeed({ ...params, hydrateCtx }, ctx)
|
|
26
32
|
|
|
27
33
|
const repoRev = await ctx.hydrator.actor.getRepoRevSafe(viewer)
|
|
28
|
-
setRepoRev(res, repoRev)
|
|
29
34
|
|
|
30
35
|
return {
|
|
31
36
|
encoding: 'application/json',
|
|
32
37
|
body: result,
|
|
38
|
+
headers: resHeaders({ labelers, repoRev }),
|
|
33
39
|
}
|
|
34
40
|
},
|
|
35
41
|
})
|
|
@@ -65,7 +71,7 @@ const hydration = async (inputs: {
|
|
|
65
71
|
skeleton: Skeleton
|
|
66
72
|
}): Promise<HydrationState> => {
|
|
67
73
|
const { ctx, params, skeleton } = inputs
|
|
68
|
-
return ctx.hydrator.hydrateFeedItems(skeleton.items, params.
|
|
74
|
+
return ctx.hydrator.hydrateFeedItems(skeleton.items, params.hydrateCtx)
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
const noBlocksOrMutes = (inputs: {
|
|
@@ -104,7 +110,7 @@ type Context = {
|
|
|
104
110
|
dataplane: DataPlaneClient
|
|
105
111
|
}
|
|
106
112
|
|
|
107
|
-
type Params = QueryParams & {
|
|
113
|
+
type Params = QueryParams & { hydrateCtx: HydrateCtx }
|
|
108
114
|
|
|
109
115
|
type Skeleton = {
|
|
110
116
|
items: FeedItem[]
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
OutputSchema,
|
|
7
7
|
} from '../../../../lexicon/types/app/bsky/feed/getPostThread'
|
|
8
8
|
import AppContext from '../../../../context'
|
|
9
|
-
import {
|
|
9
|
+
import { ATPROTO_REPO_REV, resHeaders } from '../../../util'
|
|
10
10
|
import {
|
|
11
11
|
HydrationFnInput,
|
|
12
12
|
PresentationFnInput,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
createPipeline,
|
|
15
15
|
noRules,
|
|
16
16
|
} from '../../../../pipeline'
|
|
17
|
-
import { Hydrator } from '../../../../hydration/hydrator'
|
|
17
|
+
import { HydrateCtx, Hydrator } from '../../../../hydration/hydrator'
|
|
18
18
|
import { Views } from '../../../../views'
|
|
19
19
|
import { DataPlaneClient, isDataplaneError, Code } from '../../../../data-plane'
|
|
20
20
|
|
|
@@ -27,24 +27,31 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
27
27
|
)
|
|
28
28
|
server.app.bsky.feed.getPostThread({
|
|
29
29
|
auth: ctx.authVerifier.optionalStandardOrRole,
|
|
30
|
-
handler: async ({ params, auth, res }) => {
|
|
30
|
+
handler: async ({ params, auth, req, res }) => {
|
|
31
31
|
const { viewer } = ctx.authVerifier.parseCreds(auth)
|
|
32
|
+
const labelers = ctx.reqLabelers(req)
|
|
33
|
+
const hydrateCtx = { labelers, viewer }
|
|
32
34
|
|
|
33
35
|
let result: OutputSchema
|
|
34
36
|
try {
|
|
35
|
-
result = await getPostThread({ ...params,
|
|
37
|
+
result = await getPostThread({ ...params, hydrateCtx }, ctx)
|
|
36
38
|
} catch (err) {
|
|
37
39
|
const repoRev = await ctx.hydrator.actor.getRepoRevSafe(viewer)
|
|
38
|
-
|
|
40
|
+
if (repoRev) {
|
|
41
|
+
res.setHeader(ATPROTO_REPO_REV, repoRev)
|
|
42
|
+
}
|
|
39
43
|
throw err
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
const repoRev = await ctx.hydrator.actor.getRepoRevSafe(viewer)
|
|
43
|
-
setRepoRev(res, repoRev)
|
|
44
47
|
|
|
45
48
|
return {
|
|
46
49
|
encoding: 'application/json',
|
|
47
50
|
body: result,
|
|
51
|
+
headers: resHeaders({
|
|
52
|
+
repoRev,
|
|
53
|
+
labelers,
|
|
54
|
+
}),
|
|
48
55
|
}
|
|
49
56
|
},
|
|
50
57
|
})
|
|
@@ -80,7 +87,7 @@ const hydration = async (
|
|
|
80
87
|
const { ctx, params, skeleton } = inputs
|
|
81
88
|
return ctx.hydrator.hydrateThreadPosts(
|
|
82
89
|
skeleton.uris.map((uri) => ({ uri })),
|
|
83
|
-
params.
|
|
90
|
+
params.hydrateCtx,
|
|
84
91
|
)
|
|
85
92
|
}
|
|
86
93
|
|
|
@@ -105,7 +112,7 @@ type Context = {
|
|
|
105
112
|
views: Views
|
|
106
113
|
}
|
|
107
114
|
|
|
108
|
-
type Params = QueryParams & {
|
|
115
|
+
type Params = QueryParams & { hydrateCtx: HydrateCtx }
|
|
109
116
|
|
|
110
117
|
type Skeleton = {
|
|
111
118
|
anchor: string
|
|
@@ -3,21 +3,30 @@ import { Server } from '../../../../lexicon'
|
|
|
3
3
|
import { QueryParams } from '../../../../lexicon/types/app/bsky/feed/getPosts'
|
|
4
4
|
import AppContext from '../../../../context'
|
|
5
5
|
import { createPipeline } from '../../../../pipeline'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
HydrateCtx,
|
|
8
|
+
HydrationState,
|
|
9
|
+
Hydrator,
|
|
10
|
+
} from '../../../../hydration/hydrator'
|
|
7
11
|
import { Views } from '../../../../views'
|
|
8
12
|
import { creatorFromUri } from '../../../../views/util'
|
|
13
|
+
import { resHeaders } from '../../../util'
|
|
9
14
|
|
|
10
15
|
export default function (server: Server, ctx: AppContext) {
|
|
11
16
|
const getPosts = createPipeline(skeleton, hydration, noBlocks, presentation)
|
|
12
17
|
server.app.bsky.feed.getPosts({
|
|
13
18
|
auth: ctx.authVerifier.standardOptional,
|
|
14
|
-
handler: async ({ params, auth }) => {
|
|
19
|
+
handler: async ({ params, auth, req }) => {
|
|
15
20
|
const viewer = auth.credentials.iss
|
|
16
|
-
const
|
|
21
|
+
const labelers = ctx.reqLabelers(req)
|
|
22
|
+
const hydrateCtx = { labelers, viewer }
|
|
23
|
+
|
|
24
|
+
const results = await getPosts({ ...params, hydrateCtx }, ctx)
|
|
17
25
|
|
|
18
26
|
return {
|
|
19
27
|
encoding: 'application/json',
|
|
20
28
|
body: results,
|
|
29
|
+
headers: resHeaders({ labelers }),
|
|
21
30
|
}
|
|
22
31
|
},
|
|
23
32
|
})
|
|
@@ -35,7 +44,7 @@ const hydration = async (inputs: {
|
|
|
35
44
|
const { ctx, params, skeleton } = inputs
|
|
36
45
|
return ctx.hydrator.hydratePosts(
|
|
37
46
|
skeleton.posts.map((uri) => ({ uri })),
|
|
38
|
-
params.
|
|
47
|
+
params.hydrateCtx,
|
|
39
48
|
)
|
|
40
49
|
}
|
|
41
50
|
|
|
@@ -70,7 +79,7 @@ type Context = {
|
|
|
70
79
|
views: Views
|
|
71
80
|
}
|
|
72
81
|
|
|
73
|
-
type Params = QueryParams & {
|
|
82
|
+
type Params = QueryParams & { hydrateCtx: HydrateCtx }
|
|
74
83
|
|
|
75
84
|
type Skeleton = {
|
|
76
85
|
posts: string[]
|
|
@@ -3,11 +3,15 @@ import { Server } from '../../../../lexicon'
|
|
|
3
3
|
import { QueryParams } from '../../../../lexicon/types/app/bsky/feed/getRepostedBy'
|
|
4
4
|
import AppContext from '../../../../context'
|
|
5
5
|
import { createPipeline } from '../../../../pipeline'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
HydrateCtx,
|
|
8
|
+
HydrationState,
|
|
9
|
+
Hydrator,
|
|
10
|
+
} from '../../../../hydration/hydrator'
|
|
7
11
|
import { Views } from '../../../../views'
|
|
8
12
|
import { parseString } from '../../../../hydration/util'
|
|
9
13
|
import { creatorFromUri } from '../../../../views/util'
|
|
10
|
-
import { clearlyBadCursor } from '../../../util'
|
|
14
|
+
import { clearlyBadCursor, resHeaders } from '../../../util'
|
|
11
15
|
|
|
12
16
|
export default function (server: Server, ctx: AppContext) {
|
|
13
17
|
const getRepostedBy = createPipeline(
|
|
@@ -18,13 +22,16 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
18
22
|
)
|
|
19
23
|
server.app.bsky.feed.getRepostedBy({
|
|
20
24
|
auth: ctx.authVerifier.standardOptional,
|
|
21
|
-
handler: async ({ params, auth }) => {
|
|
25
|
+
handler: async ({ params, auth, req }) => {
|
|
22
26
|
const viewer = auth.credentials.iss
|
|
23
|
-
const
|
|
27
|
+
const labelers = ctx.reqLabelers(req)
|
|
28
|
+
const hydrateCtx = { labelers, viewer }
|
|
29
|
+
const result = await getRepostedBy({ ...params, hydrateCtx }, ctx)
|
|
24
30
|
|
|
25
31
|
return {
|
|
26
32
|
encoding: 'application/json',
|
|
27
33
|
body: result,
|
|
34
|
+
headers: resHeaders({ labelers }),
|
|
28
35
|
}
|
|
29
36
|
},
|
|
30
37
|
})
|
|
@@ -55,7 +62,7 @@ const hydration = async (inputs: {
|
|
|
55
62
|
skeleton: Skeleton
|
|
56
63
|
}) => {
|
|
57
64
|
const { ctx, params, skeleton } = inputs
|
|
58
|
-
return await ctx.hydrator.hydrateReposts(skeleton.reposts, params.
|
|
65
|
+
return await ctx.hydrator.hydrateReposts(skeleton.reposts, params.hydrateCtx)
|
|
59
66
|
}
|
|
60
67
|
|
|
61
68
|
const noBlocks = (inputs: {
|
|
@@ -99,7 +106,7 @@ type Context = {
|
|
|
99
106
|
views: Views
|
|
100
107
|
}
|
|
101
108
|
|
|
102
|
-
type Params = QueryParams & {
|
|
109
|
+
type Params = QueryParams & { hydrateCtx: HydrateCtx }
|
|
103
110
|
|
|
104
111
|
type Skeleton = {
|
|
105
112
|
reposts: string[]
|
|
@@ -2,12 +2,14 @@ import { mapDefined } from '@atproto/common'
|
|
|
2
2
|
import { Server } from '../../../../lexicon'
|
|
3
3
|
import AppContext from '../../../../context'
|
|
4
4
|
import { parseString } from '../../../../hydration/util'
|
|
5
|
+
import { resHeaders } from '../../../util'
|
|
5
6
|
|
|
6
7
|
export default function (server: Server, ctx: AppContext) {
|
|
7
8
|
server.app.bsky.feed.getSuggestedFeeds({
|
|
8
9
|
auth: ctx.authVerifier.standardOptional,
|
|
9
|
-
handler: async ({ auth, params }) => {
|
|
10
|
+
handler: async ({ auth, params, req }) => {
|
|
10
11
|
const viewer = auth.credentials.iss
|
|
12
|
+
const labelers = ctx.reqLabelers(req)
|
|
11
13
|
|
|
12
14
|
// @NOTE no need to coordinate the cursor for appview swap, as v1 doesn't use the cursor
|
|
13
15
|
const suggestedRes = await ctx.dataplane.getSuggestedFeeds({
|
|
@@ -16,7 +18,10 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
16
18
|
cursor: params.cursor,
|
|
17
19
|
})
|
|
18
20
|
const uris = suggestedRes.uris
|
|
19
|
-
const hydration = await ctx.hydrator.hydrateFeedGens(uris,
|
|
21
|
+
const hydration = await ctx.hydrator.hydrateFeedGens(uris, {
|
|
22
|
+
labelers,
|
|
23
|
+
viewer,
|
|
24
|
+
})
|
|
20
25
|
const feedViews = mapDefined(uris, (uri) =>
|
|
21
26
|
ctx.views.feedGenerator(uri, hydration),
|
|
22
27
|
)
|
|
@@ -27,6 +32,7 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
27
32
|
feeds: feedViews,
|
|
28
33
|
cursor: parseString(suggestedRes.cursor),
|
|
29
34
|
},
|
|
35
|
+
headers: resHeaders({ labelers }),
|
|
30
36
|
}
|
|
31
37
|
},
|
|
32
38
|
})
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { Server } from '../../../../lexicon'
|
|
2
2
|
import AppContext from '../../../../context'
|
|
3
3
|
import { QueryParams } from '../../../../lexicon/types/app/bsky/feed/getTimeline'
|
|
4
|
-
import { clearlyBadCursor,
|
|
4
|
+
import { clearlyBadCursor, resHeaders } from '../../../util'
|
|
5
5
|
import { createPipeline } from '../../../../pipeline'
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
HydrateCtx,
|
|
8
|
+
HydrationState,
|
|
9
|
+
Hydrator,
|
|
10
|
+
} from '../../../../hydration/hydrator'
|
|
7
11
|
import { Views } from '../../../../views'
|
|
8
12
|
import { DataPlaneClient } from '../../../../data-plane'
|
|
9
13
|
import { parseString } from '../../../../hydration/util'
|
|
@@ -19,17 +23,19 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
19
23
|
)
|
|
20
24
|
server.app.bsky.feed.getTimeline({
|
|
21
25
|
auth: ctx.authVerifier.standard,
|
|
22
|
-
handler: async ({ params, auth,
|
|
26
|
+
handler: async ({ params, auth, req }) => {
|
|
23
27
|
const viewer = auth.credentials.iss
|
|
28
|
+
const labelers = ctx.reqLabelers(req)
|
|
29
|
+
const hydrateCtx = { labelers, viewer }
|
|
24
30
|
|
|
25
|
-
const result = await getTimeline({ ...params,
|
|
31
|
+
const result = await getTimeline({ ...params, hydrateCtx }, ctx)
|
|
26
32
|
|
|
27
33
|
const repoRev = await ctx.hydrator.actor.getRepoRevSafe(viewer)
|
|
28
|
-
setRepoRev(res, repoRev)
|
|
29
34
|
|
|
30
35
|
return {
|
|
31
36
|
encoding: 'application/json',
|
|
32
37
|
body: result,
|
|
38
|
+
headers: resHeaders({ labelers, repoRev }),
|
|
33
39
|
}
|
|
34
40
|
},
|
|
35
41
|
})
|
|
@@ -44,7 +50,7 @@ export const skeleton = async (inputs: {
|
|
|
44
50
|
return { items: [] }
|
|
45
51
|
}
|
|
46
52
|
const res = await ctx.dataplane.getTimeline({
|
|
47
|
-
actorDid: params.viewer,
|
|
53
|
+
actorDid: params.hydrateCtx.viewer,
|
|
48
54
|
limit: params.limit,
|
|
49
55
|
cursor: params.cursor,
|
|
50
56
|
})
|
|
@@ -65,7 +71,7 @@ const hydration = async (inputs: {
|
|
|
65
71
|
skeleton: Skeleton
|
|
66
72
|
}): Promise<HydrationState> => {
|
|
67
73
|
const { ctx, params, skeleton } = inputs
|
|
68
|
-
return ctx.hydrator.hydrateFeedItems(skeleton.items, params.
|
|
74
|
+
return ctx.hydrator.hydrateFeedItems(skeleton.items, params.hydrateCtx)
|
|
69
75
|
}
|
|
70
76
|
|
|
71
77
|
const noBlocksOrMutes = (inputs: {
|
|
@@ -104,7 +110,7 @@ type Context = {
|
|
|
104
110
|
dataplane: DataPlaneClient
|
|
105
111
|
}
|
|
106
112
|
|
|
107
|
-
type Params = QueryParams & { viewer: string }
|
|
113
|
+
type Params = QueryParams & { hydrateCtx: HydrateCtx & { viewer: string } }
|
|
108
114
|
|
|
109
115
|
type Skeleton = {
|
|
110
116
|
items: FeedItem[]
|
|
@@ -10,11 +10,12 @@ import {
|
|
|
10
10
|
SkeletonFnInput,
|
|
11
11
|
createPipeline,
|
|
12
12
|
} from '../../../../pipeline'
|
|
13
|
-
import { Hydrator } from '../../../../hydration/hydrator'
|
|
13
|
+
import { HydrateCtx, Hydrator } from '../../../../hydration/hydrator'
|
|
14
14
|
import { Views } from '../../../../views'
|
|
15
15
|
import { DataPlaneClient } from '../../../../data-plane'
|
|
16
16
|
import { parseString } from '../../../../hydration/util'
|
|
17
17
|
import { creatorFromUri } from '../../../../views/util'
|
|
18
|
+
import { resHeaders } from '../../../util'
|
|
18
19
|
|
|
19
20
|
export default function (server: Server, ctx: AppContext) {
|
|
20
21
|
const searchPosts = createPipeline(
|
|
@@ -25,12 +26,15 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
25
26
|
)
|
|
26
27
|
server.app.bsky.feed.searchPosts({
|
|
27
28
|
auth: ctx.authVerifier.standardOptional,
|
|
28
|
-
handler: async ({ auth, params }) => {
|
|
29
|
+
handler: async ({ auth, params, req }) => {
|
|
29
30
|
const viewer = auth.credentials.iss
|
|
30
|
-
const
|
|
31
|
+
const labelers = ctx.reqLabelers(req)
|
|
32
|
+
const hydrateCtx = { labelers, viewer }
|
|
33
|
+
const results = await searchPosts({ ...params, hydrateCtx }, ctx)
|
|
31
34
|
return {
|
|
32
35
|
encoding: 'application/json',
|
|
33
36
|
body: results,
|
|
37
|
+
headers: resHeaders({ labelers }),
|
|
34
38
|
}
|
|
35
39
|
},
|
|
36
40
|
})
|
|
@@ -70,7 +74,7 @@ const hydration = async (
|
|
|
70
74
|
const { ctx, params, skeleton } = inputs
|
|
71
75
|
return ctx.hydrator.hydratePosts(
|
|
72
76
|
skeleton.posts.map((uri) => ({ uri })),
|
|
73
|
-
params.
|
|
77
|
+
params.hydrateCtx,
|
|
74
78
|
)
|
|
75
79
|
}
|
|
76
80
|
|
|
@@ -104,7 +108,7 @@ type Context = {
|
|
|
104
108
|
searchAgent?: AtpAgent
|
|
105
109
|
}
|
|
106
110
|
|
|
107
|
-
type Params = QueryParams & {
|
|
111
|
+
type Params = QueryParams & { hydrateCtx: HydrateCtx }
|
|
108
112
|
|
|
109
113
|
type Skeleton = {
|
|
110
114
|
posts: string[]
|
|
@@ -9,20 +9,23 @@ import {
|
|
|
9
9
|
PresentationFnInput,
|
|
10
10
|
SkeletonFnInput,
|
|
11
11
|
} from '../../../../pipeline'
|
|
12
|
-
import { Hydrator } from '../../../../hydration/hydrator'
|
|
12
|
+
import { HydrateCtx, Hydrator } from '../../../../hydration/hydrator'
|
|
13
13
|
import { Views } from '../../../../views'
|
|
14
|
-
import { clearlyBadCursor } from '../../../util'
|
|
14
|
+
import { clearlyBadCursor, resHeaders } from '../../../util'
|
|
15
15
|
|
|
16
16
|
export default function (server: Server, ctx: AppContext) {
|
|
17
17
|
const getBlocks = createPipeline(skeleton, hydration, noRules, presentation)
|
|
18
18
|
server.app.bsky.graph.getBlocks({
|
|
19
19
|
auth: ctx.authVerifier.standard,
|
|
20
|
-
handler: async ({ params, auth }) => {
|
|
20
|
+
handler: async ({ params, auth, req }) => {
|
|
21
21
|
const viewer = auth.credentials.iss
|
|
22
|
-
const
|
|
22
|
+
const labelers = ctx.reqLabelers(req)
|
|
23
|
+
const hydrateCtx = { labelers, viewer }
|
|
24
|
+
const result = await getBlocks({ ...params, hydrateCtx }, ctx)
|
|
23
25
|
return {
|
|
24
26
|
encoding: 'application/json',
|
|
25
27
|
body: result,
|
|
28
|
+
headers: resHeaders({ labelers }),
|
|
26
29
|
}
|
|
27
30
|
},
|
|
28
31
|
})
|
|
@@ -34,7 +37,7 @@ const skeleton = async (input: SkeletonFnInput<Context, Params>) => {
|
|
|
34
37
|
return { blockedDids: [] }
|
|
35
38
|
}
|
|
36
39
|
const { blockUris, cursor } = await ctx.hydrator.dataplane.getBlocks({
|
|
37
|
-
actorDid: params.viewer,
|
|
40
|
+
actorDid: params.hydrateCtx.viewer,
|
|
38
41
|
cursor: params.cursor,
|
|
39
42
|
limit: params.limit,
|
|
40
43
|
})
|
|
@@ -53,9 +56,7 @@ const hydration = async (
|
|
|
53
56
|
input: HydrationFnInput<Context, Params, SkeletonState>,
|
|
54
57
|
) => {
|
|
55
58
|
const { ctx, params, skeleton } = input
|
|
56
|
-
|
|
57
|
-
const { blockedDids } = skeleton
|
|
58
|
-
return ctx.hydrator.hydrateProfiles(blockedDids, viewer)
|
|
59
|
+
return ctx.hydrator.hydrateProfiles(skeleton.blockedDids, params.hydrateCtx)
|
|
59
60
|
}
|
|
60
61
|
|
|
61
62
|
const presentation = (
|
|
@@ -75,7 +76,7 @@ type Context = {
|
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
type Params = QueryParams & {
|
|
78
|
-
viewer: string
|
|
79
|
+
hydrateCtx: HydrateCtx & { viewer: string }
|
|
79
80
|
}
|
|
80
81
|
|
|
81
82
|
type SkeletonState = {
|