@atproto/bsky 0.0.184 → 0.0.186
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 +16 -0
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts +4 -0
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts.map +1 -0
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js +101 -0
- package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js.map +1 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +2 -0
- package/dist/api/index.js.map +1 -1
- package/dist/lexicon/index.d.ts +4 -0
- package/dist/lexicon/index.d.ts.map +1 -1
- package/dist/lexicon/index.js +8 -0
- package/dist/lexicon/index.js.map +1 -1
- package/dist/lexicon/lexicons.d.ts +192 -0
- package/dist/lexicon/lexicons.d.ts.map +1 -1
- package/dist/lexicon/lexicons.js +98 -0
- package/dist/lexicon/lexicons.js.map +1 -1
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts +2 -0
- package/dist/lexicon/types/app/bsky/actor/defs.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/actor/defs.js.map +1 -1
- package/dist/lexicon/types/app/bsky/actor/profile.d.ts +3 -0
- package/dist/lexicon/types/app/bsky/actor/profile.d.ts.map +1 -1
- package/dist/lexicon/types/app/bsky/actor/profile.js.map +1 -1
- package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts +22 -0
- package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js +7 -0
- package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.d.ts +23 -0
- package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.d.ts.map +1 -0
- package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.js +7 -0
- package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.js.map +1 -0
- package/dist/util.d.ts.map +1 -1
- package/dist/util.js +3 -1
- package/dist/util.js.map +1 -1
- package/dist/views/index.d.ts +1 -0
- package/dist/views/index.d.ts.map +1 -1
- package/dist/views/index.js +11 -0
- package/dist/views/index.js.map +1 -1
- package/package.json +6 -6
- package/src/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.ts +152 -0
- package/src/api/index.ts +2 -0
- package/src/lexicon/index.ts +26 -0
- package/src/lexicon/lexicons.ts +102 -0
- package/src/lexicon/types/app/bsky/actor/defs.ts +2 -0
- package/src/lexicon/types/app/bsky/actor/profile.ts +3 -0
- package/src/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.ts +40 -0
- package/src/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.ts +41 -0
- package/src/util.ts +3 -1
- package/src/views/index.ts +12 -0
- package/tests/views/__snapshots__/profile.test.ts.snap +54 -0
- package/tests/views/profile.test.ts +43 -0
- package/tsconfig.build.tsbuildinfo +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/bsky",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.186",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Reference implementation of app.bsky App View (Bluesky API)",
|
|
6
6
|
"keywords": [
|
|
@@ -53,14 +53,14 @@
|
|
|
53
53
|
"zod": "3.23.8",
|
|
54
54
|
"@atproto-labs/fetch-node": "0.1.10",
|
|
55
55
|
"@atproto-labs/xrpc-utils": "0.0.22",
|
|
56
|
-
"@atproto/api": "^0.16.
|
|
56
|
+
"@atproto/api": "^0.16.11",
|
|
57
57
|
"@atproto/common": "^0.4.12",
|
|
58
58
|
"@atproto/crypto": "^0.4.4",
|
|
59
59
|
"@atproto/did": "^0.2.0",
|
|
60
60
|
"@atproto/identity": "^0.4.9",
|
|
61
61
|
"@atproto/lexicon": "^0.5.1",
|
|
62
|
-
"@atproto/repo": "^0.8.
|
|
63
|
-
"@atproto/sync": "^0.1.
|
|
62
|
+
"@atproto/repo": "^0.8.10",
|
|
63
|
+
"@atproto/sync": "^0.1.35",
|
|
64
64
|
"@atproto/syntax": "^0.4.1",
|
|
65
65
|
"@atproto/xrpc-server": "^0.9.5"
|
|
66
66
|
},
|
|
@@ -77,9 +77,9 @@
|
|
|
77
77
|
"jest": "^28.1.2",
|
|
78
78
|
"ts-node": "^10.8.2",
|
|
79
79
|
"typescript": "^5.6.3",
|
|
80
|
-
"@atproto/api": "^0.16.
|
|
80
|
+
"@atproto/api": "^0.16.11",
|
|
81
81
|
"@atproto/lex-cli": "^0.9.5",
|
|
82
|
-
"@atproto/pds": "^0.4.
|
|
82
|
+
"@atproto/pds": "^0.4.182",
|
|
83
83
|
"@atproto/xrpc": "^0.7.5"
|
|
84
84
|
},
|
|
85
85
|
"scripts": {
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import AtpAgent, { AtUri } from '@atproto/api'
|
|
2
|
+
import { dedupeStrs, mapDefined, noUndefinedVals } from '@atproto/common'
|
|
3
|
+
import { InternalServerError } from '@atproto/xrpc-server'
|
|
4
|
+
import { AppContext } from '../../../../context'
|
|
5
|
+
import {
|
|
6
|
+
HydrateCtx,
|
|
7
|
+
Hydrator,
|
|
8
|
+
mergeManyStates,
|
|
9
|
+
} from '../../../../hydration/hydrator'
|
|
10
|
+
import { Server } from '../../../../lexicon'
|
|
11
|
+
import { QueryParams } from '../../../../lexicon/types/app/bsky/unspecced/getTrendingTopics'
|
|
12
|
+
import {
|
|
13
|
+
HydrationFnInput,
|
|
14
|
+
PresentationFnInput,
|
|
15
|
+
RulesFnInput,
|
|
16
|
+
SkeletonFnInput,
|
|
17
|
+
createPipeline,
|
|
18
|
+
} from '../../../../pipeline'
|
|
19
|
+
import { Views } from '../../../../views'
|
|
20
|
+
|
|
21
|
+
export default function (server: Server, ctx: AppContext) {
|
|
22
|
+
const getOnboardingSuggestedStarterPacks = createPipeline(
|
|
23
|
+
skeleton,
|
|
24
|
+
hydration,
|
|
25
|
+
noBlocks,
|
|
26
|
+
presentation,
|
|
27
|
+
)
|
|
28
|
+
server.app.bsky.unspecced.getOnboardingSuggestedStarterPacks({
|
|
29
|
+
auth: ctx.authVerifier.standardOptional,
|
|
30
|
+
handler: async ({ auth, params, req }) => {
|
|
31
|
+
const viewer = auth.credentials.iss
|
|
32
|
+
const labelers = ctx.reqLabelers(req)
|
|
33
|
+
const hydrateCtx = await ctx.hydrator.createContext({ labelers, viewer })
|
|
34
|
+
const headers = noUndefinedVals({
|
|
35
|
+
'accept-language': req.headers['accept-language'],
|
|
36
|
+
'x-bsky-topics': Array.isArray(req.headers['x-bsky-topics'])
|
|
37
|
+
? req.headers['x-bsky-topics'].join(',')
|
|
38
|
+
: req.headers['x-bsky-topics'],
|
|
39
|
+
})
|
|
40
|
+
const { ...result } = await getOnboardingSuggestedStarterPacks(
|
|
41
|
+
{
|
|
42
|
+
...params,
|
|
43
|
+
viewer: viewer ?? undefined,
|
|
44
|
+
hydrateCtx: hydrateCtx.copy({ viewer }),
|
|
45
|
+
headers,
|
|
46
|
+
},
|
|
47
|
+
ctx,
|
|
48
|
+
)
|
|
49
|
+
return {
|
|
50
|
+
encoding: 'application/json',
|
|
51
|
+
body: result,
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
})
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const skeleton = async (input: SkeletonFnInput<Context, Params>) => {
|
|
58
|
+
const { params, ctx } = input
|
|
59
|
+
if (ctx.topicsAgent) {
|
|
60
|
+
const res =
|
|
61
|
+
await ctx.topicsAgent.app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton(
|
|
62
|
+
{
|
|
63
|
+
limit: params.limit,
|
|
64
|
+
viewer: params.viewer,
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
headers: params.headers,
|
|
68
|
+
},
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
return res.data
|
|
72
|
+
} else {
|
|
73
|
+
throw new InternalServerError('Topics agent not available')
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const hydration = async (
|
|
78
|
+
input: HydrationFnInput<Context, Params, SkeletonState>,
|
|
79
|
+
) => {
|
|
80
|
+
const { ctx, params, skeleton } = input
|
|
81
|
+
let dids: string[] = []
|
|
82
|
+
for (const uri of skeleton.starterPacks) {
|
|
83
|
+
let aturi: AtUri | undefined
|
|
84
|
+
try {
|
|
85
|
+
aturi = new AtUri(uri)
|
|
86
|
+
} catch {
|
|
87
|
+
continue
|
|
88
|
+
}
|
|
89
|
+
dids.push(aturi.hostname)
|
|
90
|
+
}
|
|
91
|
+
dids = dedupeStrs(dids)
|
|
92
|
+
const pairs: Map<string, string[]> = new Map()
|
|
93
|
+
if (params.viewer) {
|
|
94
|
+
pairs.set(params.viewer, dids)
|
|
95
|
+
}
|
|
96
|
+
const [starterPacksState, bidirectionalBlocks] = await Promise.all([
|
|
97
|
+
ctx.hydrator.hydrateStarterPacks(skeleton.starterPacks, params.hydrateCtx),
|
|
98
|
+
ctx.hydrator.hydrateBidirectionalBlocks(pairs, params.hydrateCtx),
|
|
99
|
+
])
|
|
100
|
+
|
|
101
|
+
return mergeManyStates(starterPacksState, { bidirectionalBlocks })
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const noBlocks = (input: RulesFnInput<Context, Params, SkeletonState>) => {
|
|
105
|
+
const { skeleton, params, hydration } = input
|
|
106
|
+
|
|
107
|
+
if (!params.viewer) {
|
|
108
|
+
return skeleton
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const blocks = hydration.bidirectionalBlocks?.get(params.viewer)
|
|
112
|
+
const filteredSkeleton: SkeletonState = {
|
|
113
|
+
starterPacks: skeleton.starterPacks.filter((uri) => {
|
|
114
|
+
let aturi: AtUri | undefined
|
|
115
|
+
try {
|
|
116
|
+
aturi = new AtUri(uri)
|
|
117
|
+
} catch {
|
|
118
|
+
return false
|
|
119
|
+
}
|
|
120
|
+
return !blocks?.get(aturi.hostname)
|
|
121
|
+
}),
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return filteredSkeleton
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const presentation = (
|
|
128
|
+
input: PresentationFnInput<Context, Params, SkeletonState>,
|
|
129
|
+
) => {
|
|
130
|
+
const { ctx, skeleton, hydration } = input
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
starterPacks: mapDefined(skeleton.starterPacks, (uri) =>
|
|
134
|
+
ctx.views.starterPack(uri, hydration),
|
|
135
|
+
),
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
type Context = {
|
|
140
|
+
hydrator: Hydrator
|
|
141
|
+
views: Views
|
|
142
|
+
topicsAgent: AtpAgent | undefined
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
type Params = QueryParams & {
|
|
146
|
+
hydrateCtx: HydrateCtx & { viewer: string | null }
|
|
147
|
+
headers: Record<string, string>
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
type SkeletonState = {
|
|
151
|
+
starterPacks: string[]
|
|
152
|
+
}
|
package/src/api/index.ts
CHANGED
|
@@ -58,6 +58,7 @@ import registerPush from './app/bsky/notification/registerPush'
|
|
|
58
58
|
import updateSeen from './app/bsky/notification/updateSeen'
|
|
59
59
|
import getAgeAssuranceState from './app/bsky/unspecced/getAgeAssuranceState'
|
|
60
60
|
import getConfig from './app/bsky/unspecced/getConfig'
|
|
61
|
+
import getOnboardingSuggestedStarterPacks from './app/bsky/unspecced/getOnboardingSuggestedStarterPacks'
|
|
61
62
|
import getPopularFeedGenerators from './app/bsky/unspecced/getPopularFeedGenerators'
|
|
62
63
|
import getPostThreadOtherV2 from './app/bsky/unspecced/getPostThreadOtherV2'
|
|
63
64
|
import getPostThreadV2 from './app/bsky/unspecced/getPostThreadV2'
|
|
@@ -133,6 +134,7 @@ export default function (server: Server, ctx: AppContext) {
|
|
|
133
134
|
getSuggestedFollowsByActor(server, ctx)
|
|
134
135
|
getTrendingTopics(server, ctx)
|
|
135
136
|
getTrends(server, ctx)
|
|
137
|
+
getOnboardingSuggestedStarterPacks(server, ctx)
|
|
136
138
|
getSuggestedStarterPacks(server, ctx)
|
|
137
139
|
getSuggestedUsers(server, ctx)
|
|
138
140
|
getUnspeccedSuggestedFeeds(server, ctx)
|
package/src/lexicon/index.ts
CHANGED
|
@@ -74,6 +74,8 @@ import * as AppBskyNotificationUnregisterPush from './types/app/bsky/notificatio
|
|
|
74
74
|
import * as AppBskyNotificationUpdateSeen from './types/app/bsky/notification/updateSeen.js'
|
|
75
75
|
import * as AppBskyUnspeccedGetAgeAssuranceState from './types/app/bsky/unspecced/getAgeAssuranceState.js'
|
|
76
76
|
import * as AppBskyUnspeccedGetConfig from './types/app/bsky/unspecced/getConfig.js'
|
|
77
|
+
import * as AppBskyUnspeccedGetOnboardingSuggestedStarterPacks from './types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js'
|
|
78
|
+
import * as AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton from './types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.js'
|
|
77
79
|
import * as AppBskyUnspeccedGetPopularFeedGenerators from './types/app/bsky/unspecced/getPopularFeedGenerators.js'
|
|
78
80
|
import * as AppBskyUnspeccedGetPostThreadOtherV2 from './types/app/bsky/unspecced/getPostThreadOtherV2.js'
|
|
79
81
|
import * as AppBskyUnspeccedGetPostThreadV2 from './types/app/bsky/unspecced/getPostThreadV2.js'
|
|
@@ -1132,6 +1134,30 @@ export class AppBskyUnspeccedNS {
|
|
|
1132
1134
|
return this._server.xrpc.method(nsid, cfg)
|
|
1133
1135
|
}
|
|
1134
1136
|
|
|
1137
|
+
getOnboardingSuggestedStarterPacks<A extends Auth = void>(
|
|
1138
|
+
cfg: MethodConfigOrHandler<
|
|
1139
|
+
A,
|
|
1140
|
+
AppBskyUnspeccedGetOnboardingSuggestedStarterPacks.QueryParams,
|
|
1141
|
+
AppBskyUnspeccedGetOnboardingSuggestedStarterPacks.HandlerInput,
|
|
1142
|
+
AppBskyUnspeccedGetOnboardingSuggestedStarterPacks.HandlerOutput
|
|
1143
|
+
>,
|
|
1144
|
+
) {
|
|
1145
|
+
const nsid = 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks' // @ts-ignore
|
|
1146
|
+
return this._server.xrpc.method(nsid, cfg)
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
getOnboardingSuggestedStarterPacksSkeleton<A extends Auth = void>(
|
|
1150
|
+
cfg: MethodConfigOrHandler<
|
|
1151
|
+
A,
|
|
1152
|
+
AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton.QueryParams,
|
|
1153
|
+
AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton.HandlerInput,
|
|
1154
|
+
AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton.HandlerOutput
|
|
1155
|
+
>,
|
|
1156
|
+
) {
|
|
1157
|
+
const nsid = 'app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton' // @ts-ignore
|
|
1158
|
+
return this._server.xrpc.method(nsid, cfg)
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1135
1161
|
getPopularFeedGenerators<A extends Auth = void>(
|
|
1136
1162
|
cfg: MethodConfigOrHandler<
|
|
1137
1163
|
A,
|
package/src/lexicon/lexicons.ts
CHANGED
|
@@ -145,6 +145,13 @@ export const schemaDict = {
|
|
|
145
145
|
maxGraphemes: 256,
|
|
146
146
|
maxLength: 2560,
|
|
147
147
|
},
|
|
148
|
+
pronouns: {
|
|
149
|
+
type: 'string',
|
|
150
|
+
},
|
|
151
|
+
website: {
|
|
152
|
+
type: 'string',
|
|
153
|
+
format: 'uri',
|
|
154
|
+
},
|
|
148
155
|
avatar: {
|
|
149
156
|
type: 'string',
|
|
150
157
|
format: 'uri',
|
|
@@ -964,6 +971,16 @@ export const schemaDict = {
|
|
|
964
971
|
maxGraphemes: 256,
|
|
965
972
|
maxLength: 2560,
|
|
966
973
|
},
|
|
974
|
+
pronouns: {
|
|
975
|
+
type: 'string',
|
|
976
|
+
description: 'Free-form pronouns text.',
|
|
977
|
+
maxGraphemes: 20,
|
|
978
|
+
maxLength: 200,
|
|
979
|
+
},
|
|
980
|
+
website: {
|
|
981
|
+
type: 'string',
|
|
982
|
+
format: 'uri',
|
|
983
|
+
},
|
|
967
984
|
avatar: {
|
|
968
985
|
type: 'blob',
|
|
969
986
|
description:
|
|
@@ -6611,6 +6628,87 @@ export const schemaDict = {
|
|
|
6611
6628
|
},
|
|
6612
6629
|
},
|
|
6613
6630
|
},
|
|
6631
|
+
AppBskyUnspeccedGetOnboardingSuggestedStarterPacks: {
|
|
6632
|
+
lexicon: 1,
|
|
6633
|
+
id: 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks',
|
|
6634
|
+
defs: {
|
|
6635
|
+
main: {
|
|
6636
|
+
type: 'query',
|
|
6637
|
+
description: 'Get a list of suggested starterpacks for onboarding',
|
|
6638
|
+
parameters: {
|
|
6639
|
+
type: 'params',
|
|
6640
|
+
properties: {
|
|
6641
|
+
limit: {
|
|
6642
|
+
type: 'integer',
|
|
6643
|
+
minimum: 1,
|
|
6644
|
+
maximum: 25,
|
|
6645
|
+
default: 10,
|
|
6646
|
+
},
|
|
6647
|
+
},
|
|
6648
|
+
},
|
|
6649
|
+
output: {
|
|
6650
|
+
encoding: 'application/json',
|
|
6651
|
+
schema: {
|
|
6652
|
+
type: 'object',
|
|
6653
|
+
required: ['starterPacks'],
|
|
6654
|
+
properties: {
|
|
6655
|
+
starterPacks: {
|
|
6656
|
+
type: 'array',
|
|
6657
|
+
items: {
|
|
6658
|
+
type: 'ref',
|
|
6659
|
+
ref: 'lex:app.bsky.graph.defs#starterPackView',
|
|
6660
|
+
},
|
|
6661
|
+
},
|
|
6662
|
+
},
|
|
6663
|
+
},
|
|
6664
|
+
},
|
|
6665
|
+
},
|
|
6666
|
+
},
|
|
6667
|
+
},
|
|
6668
|
+
AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton: {
|
|
6669
|
+
lexicon: 1,
|
|
6670
|
+
id: 'app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton',
|
|
6671
|
+
defs: {
|
|
6672
|
+
main: {
|
|
6673
|
+
type: 'query',
|
|
6674
|
+
description:
|
|
6675
|
+
'Get a skeleton of suggested starterpacks for onboarding. Intended to be called and hydrated by app.bsky.unspecced.getOnboardingSuggestedStarterPacks',
|
|
6676
|
+
parameters: {
|
|
6677
|
+
type: 'params',
|
|
6678
|
+
properties: {
|
|
6679
|
+
viewer: {
|
|
6680
|
+
type: 'string',
|
|
6681
|
+
format: 'did',
|
|
6682
|
+
description:
|
|
6683
|
+
'DID of the account making the request (not included for public/unauthenticated queries).',
|
|
6684
|
+
},
|
|
6685
|
+
limit: {
|
|
6686
|
+
type: 'integer',
|
|
6687
|
+
minimum: 1,
|
|
6688
|
+
maximum: 25,
|
|
6689
|
+
default: 10,
|
|
6690
|
+
},
|
|
6691
|
+
},
|
|
6692
|
+
},
|
|
6693
|
+
output: {
|
|
6694
|
+
encoding: 'application/json',
|
|
6695
|
+
schema: {
|
|
6696
|
+
type: 'object',
|
|
6697
|
+
required: ['starterPacks'],
|
|
6698
|
+
properties: {
|
|
6699
|
+
starterPacks: {
|
|
6700
|
+
type: 'array',
|
|
6701
|
+
items: {
|
|
6702
|
+
type: 'string',
|
|
6703
|
+
format: 'at-uri',
|
|
6704
|
+
},
|
|
6705
|
+
},
|
|
6706
|
+
},
|
|
6707
|
+
},
|
|
6708
|
+
},
|
|
6709
|
+
},
|
|
6710
|
+
},
|
|
6711
|
+
},
|
|
6614
6712
|
AppBskyUnspeccedGetPopularFeedGenerators: {
|
|
6615
6713
|
lexicon: 1,
|
|
6616
6714
|
id: 'app.bsky.unspecced.getPopularFeedGenerators',
|
|
@@ -13962,6 +14060,10 @@ export const ids = {
|
|
|
13962
14060
|
AppBskyUnspeccedGetAgeAssuranceState:
|
|
13963
14061
|
'app.bsky.unspecced.getAgeAssuranceState',
|
|
13964
14062
|
AppBskyUnspeccedGetConfig: 'app.bsky.unspecced.getConfig',
|
|
14063
|
+
AppBskyUnspeccedGetOnboardingSuggestedStarterPacks:
|
|
14064
|
+
'app.bsky.unspecced.getOnboardingSuggestedStarterPacks',
|
|
14065
|
+
AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton:
|
|
14066
|
+
'app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton',
|
|
13965
14067
|
AppBskyUnspeccedGetPopularFeedGenerators:
|
|
13966
14068
|
'app.bsky.unspecced.getPopularFeedGenerators',
|
|
13967
14069
|
AppBskyUnspeccedGetPostThreadOtherV2:
|
|
@@ -21,6 +21,9 @@ export interface Record {
|
|
|
21
21
|
displayName?: string
|
|
22
22
|
/** Free-form profile description text. */
|
|
23
23
|
description?: string
|
|
24
|
+
/** Free-form pronouns text. */
|
|
25
|
+
pronouns?: string
|
|
26
|
+
website?: string
|
|
24
27
|
/** Small image to be displayed next to posts from account. AKA, 'profile picture' */
|
|
25
28
|
avatar?: BlobRef
|
|
26
29
|
/** Larger horizontal image to display behind profile view. */
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
5
|
+
import { CID } from 'multiformats/cid'
|
|
6
|
+
import { validate as _validate } from '../../../../lexicons'
|
|
7
|
+
import {
|
|
8
|
+
type $Typed,
|
|
9
|
+
is$typed as _is$typed,
|
|
10
|
+
type OmitKey,
|
|
11
|
+
} from '../../../../util'
|
|
12
|
+
import type * as AppBskyGraphDefs from '../graph/defs.js'
|
|
13
|
+
|
|
14
|
+
const is$typed = _is$typed,
|
|
15
|
+
validate = _validate
|
|
16
|
+
const id = 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks'
|
|
17
|
+
|
|
18
|
+
export type QueryParams = {
|
|
19
|
+
limit: number
|
|
20
|
+
}
|
|
21
|
+
export type InputSchema = undefined
|
|
22
|
+
|
|
23
|
+
export interface OutputSchema {
|
|
24
|
+
starterPacks: AppBskyGraphDefs.StarterPackView[]
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type HandlerInput = void
|
|
28
|
+
|
|
29
|
+
export interface HandlerSuccess {
|
|
30
|
+
encoding: 'application/json'
|
|
31
|
+
body: OutputSchema
|
|
32
|
+
headers?: { [key: string]: string }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface HandlerError {
|
|
36
|
+
status: number
|
|
37
|
+
message?: string
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export type HandlerOutput = HandlerError | HandlerSuccess
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED CODE - DO NOT MODIFY
|
|
3
|
+
*/
|
|
4
|
+
import { type ValidationResult, BlobRef } from '@atproto/lexicon'
|
|
5
|
+
import { CID } from 'multiformats/cid'
|
|
6
|
+
import { validate as _validate } from '../../../../lexicons'
|
|
7
|
+
import {
|
|
8
|
+
type $Typed,
|
|
9
|
+
is$typed as _is$typed,
|
|
10
|
+
type OmitKey,
|
|
11
|
+
} from '../../../../util'
|
|
12
|
+
|
|
13
|
+
const is$typed = _is$typed,
|
|
14
|
+
validate = _validate
|
|
15
|
+
const id = 'app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton'
|
|
16
|
+
|
|
17
|
+
export type QueryParams = {
|
|
18
|
+
/** DID of the account making the request (not included for public/unauthenticated queries). */
|
|
19
|
+
viewer?: string
|
|
20
|
+
limit: number
|
|
21
|
+
}
|
|
22
|
+
export type InputSchema = undefined
|
|
23
|
+
|
|
24
|
+
export interface OutputSchema {
|
|
25
|
+
starterPacks: string[]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type HandlerInput = void
|
|
29
|
+
|
|
30
|
+
export interface HandlerSuccess {
|
|
31
|
+
encoding: 'application/json'
|
|
32
|
+
body: OutputSchema
|
|
33
|
+
headers?: { [key: string]: string }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface HandlerError {
|
|
37
|
+
status: number
|
|
38
|
+
message?: string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export type HandlerOutput = HandlerError | HandlerSuccess
|
package/src/util.ts
CHANGED
|
@@ -8,7 +8,9 @@ export type ParsedLabelers = {
|
|
|
8
8
|
export const parseLabelerHeader = (
|
|
9
9
|
header: string | undefined,
|
|
10
10
|
): ParsedLabelers | null => {
|
|
11
|
-
|
|
11
|
+
// An empty header is valid, so we shouldn't return null
|
|
12
|
+
// https://datatracker.ietf.org/doc/html/rfc7230#section-3.2
|
|
13
|
+
if (header === undefined) return null
|
|
12
14
|
const labelerDids = new Set<string>()
|
|
13
15
|
const redactDids = new Set<string>()
|
|
14
16
|
const parsed = parseList(header)
|
package/src/views/index.ts
CHANGED
|
@@ -265,6 +265,8 @@ export class Views {
|
|
|
265
265
|
|
|
266
266
|
return {
|
|
267
267
|
...baseView,
|
|
268
|
+
pronouns: actor.profile?.pronouns,
|
|
269
|
+
website: this.profileWebsite(did, state),
|
|
268
270
|
viewer: baseView.viewer
|
|
269
271
|
? {
|
|
270
272
|
...baseView.viewer,
|
|
@@ -444,6 +446,16 @@ export class Views {
|
|
|
444
446
|
return undefined
|
|
445
447
|
}
|
|
446
448
|
|
|
449
|
+
profileWebsite(did: string, state: HydrationState): string | undefined {
|
|
450
|
+
const actor = state.actors?.get(did)
|
|
451
|
+
if (!actor?.profile?.website) return
|
|
452
|
+
const { website } = actor.profile
|
|
453
|
+
|
|
454
|
+
// The record property accepts any URI, but we don't want
|
|
455
|
+
// to pass the client any schemes other than HTTPS.
|
|
456
|
+
return website.startsWith('https://') ? website : undefined
|
|
457
|
+
}
|
|
458
|
+
|
|
447
459
|
knownFollowers(
|
|
448
460
|
did: string,
|
|
449
461
|
state: HydrationState,
|
|
@@ -255,6 +255,60 @@ Array [
|
|
|
255
255
|
"muted": false,
|
|
256
256
|
},
|
|
257
257
|
},
|
|
258
|
+
Object {
|
|
259
|
+
"associated": Object {
|
|
260
|
+
"activitySubscription": Object {
|
|
261
|
+
"allowSubscriptions": "followers",
|
|
262
|
+
},
|
|
263
|
+
"feedgens": 0,
|
|
264
|
+
"labeler": false,
|
|
265
|
+
"lists": 0,
|
|
266
|
+
"starterPacks": 0,
|
|
267
|
+
},
|
|
268
|
+
"avatar": "https://bsky.public.url/img/avatar/plain/user(7)/cids(0)@jpeg",
|
|
269
|
+
"createdAt": "1970-01-01T00:00:00.000Z",
|
|
270
|
+
"description": "It's me, eve",
|
|
271
|
+
"did": "user(6)",
|
|
272
|
+
"displayName": "eve",
|
|
273
|
+
"followersCount": 0,
|
|
274
|
+
"followsCount": 0,
|
|
275
|
+
"handle": "eve.test",
|
|
276
|
+
"indexedAt": "1970-01-01T00:00:00.000Z",
|
|
277
|
+
"labels": Array [],
|
|
278
|
+
"postsCount": 0,
|
|
279
|
+
"pronouns": "They/them",
|
|
280
|
+
"viewer": Object {
|
|
281
|
+
"blockedBy": false,
|
|
282
|
+
"muted": false,
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
Object {
|
|
286
|
+
"associated": Object {
|
|
287
|
+
"activitySubscription": Object {
|
|
288
|
+
"allowSubscriptions": "followers",
|
|
289
|
+
},
|
|
290
|
+
"feedgens": 0,
|
|
291
|
+
"labeler": false,
|
|
292
|
+
"lists": 0,
|
|
293
|
+
"starterPacks": 0,
|
|
294
|
+
},
|
|
295
|
+
"avatar": "https://bsky.public.url/img/avatar/plain/user(9)/cids(0)@jpeg",
|
|
296
|
+
"createdAt": "1970-01-01T00:00:00.000Z",
|
|
297
|
+
"description": "It's me, frank",
|
|
298
|
+
"did": "user(8)",
|
|
299
|
+
"displayName": "frank",
|
|
300
|
+
"followersCount": 0,
|
|
301
|
+
"followsCount": 0,
|
|
302
|
+
"handle": "frank.test",
|
|
303
|
+
"indexedAt": "1970-01-01T00:00:00.000Z",
|
|
304
|
+
"labels": Array [],
|
|
305
|
+
"postsCount": 0,
|
|
306
|
+
"viewer": Object {
|
|
307
|
+
"blockedBy": false,
|
|
308
|
+
"muted": false,
|
|
309
|
+
},
|
|
310
|
+
"website": "https://frank.example.com",
|
|
311
|
+
},
|
|
258
312
|
]
|
|
259
313
|
`;
|
|
260
314
|
|
|
@@ -16,6 +16,8 @@ describe('pds profile views', () => {
|
|
|
16
16
|
let alice: string
|
|
17
17
|
let bob: string
|
|
18
18
|
let dan: string
|
|
19
|
+
let eve: string
|
|
20
|
+
let frank: string
|
|
19
21
|
|
|
20
22
|
beforeAll(async () => {
|
|
21
23
|
network = await TestNetwork.create({
|
|
@@ -25,10 +27,47 @@ describe('pds profile views', () => {
|
|
|
25
27
|
pdsAgent = network.pds.getClient()
|
|
26
28
|
sc = network.getSeedClient()
|
|
27
29
|
await basicSeed(sc)
|
|
30
|
+
|
|
31
|
+
await sc.createAccount('eve', {
|
|
32
|
+
handle: 'eve.test',
|
|
33
|
+
email: 'eve@test.com',
|
|
34
|
+
password: 'eve-pass',
|
|
35
|
+
})
|
|
36
|
+
await sc.createProfile(
|
|
37
|
+
sc.dids.eve,
|
|
38
|
+
'eve',
|
|
39
|
+
`It's me, eve`,
|
|
40
|
+
undefined,
|
|
41
|
+
undefined,
|
|
42
|
+
{
|
|
43
|
+
pronouns: 'They/them',
|
|
44
|
+
// Not allowing that to go through, even though is a valid URL.
|
|
45
|
+
website: 'wss://jetstream1.us-east.bsky.network',
|
|
46
|
+
},
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
await sc.createAccount('frank', {
|
|
50
|
+
handle: 'frank.test',
|
|
51
|
+
email: 'frank@test.com',
|
|
52
|
+
password: 'frank-pass',
|
|
53
|
+
})
|
|
54
|
+
await sc.createProfile(
|
|
55
|
+
sc.dids.frank,
|
|
56
|
+
'frank',
|
|
57
|
+
`It's me, frank`,
|
|
58
|
+
undefined,
|
|
59
|
+
undefined,
|
|
60
|
+
{
|
|
61
|
+
website: 'https://frank.example.com',
|
|
62
|
+
},
|
|
63
|
+
)
|
|
64
|
+
|
|
28
65
|
await network.processAll()
|
|
29
66
|
alice = sc.dids.alice
|
|
30
67
|
bob = sc.dids.bob
|
|
31
68
|
dan = sc.dids.dan
|
|
69
|
+
eve = sc.dids.eve
|
|
70
|
+
frank = sc.dids.frank
|
|
32
71
|
})
|
|
33
72
|
|
|
34
73
|
afterAll(async () => {
|
|
@@ -100,6 +139,8 @@ describe('pds profile views', () => {
|
|
|
100
139
|
'did:example:missing',
|
|
101
140
|
'carol.test',
|
|
102
141
|
dan,
|
|
142
|
+
eve,
|
|
143
|
+
frank,
|
|
103
144
|
'missing.test',
|
|
104
145
|
],
|
|
105
146
|
},
|
|
@@ -113,6 +154,8 @@ describe('pds profile views', () => {
|
|
|
113
154
|
'bob.test',
|
|
114
155
|
'carol.test',
|
|
115
156
|
'dan.test',
|
|
157
|
+
'eve.test',
|
|
158
|
+
'frank.test',
|
|
116
159
|
])
|
|
117
160
|
|
|
118
161
|
expect(forSnapshot(profiles)).toMatchSnapshot()
|