@atproto/bsky 0.0.185 → 0.0.187

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.
Files changed (44) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts +4 -0
  3. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts.map +1 -0
  4. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js +101 -0
  5. package/dist/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js.map +1 -0
  6. package/dist/api/index.d.ts.map +1 -1
  7. package/dist/api/index.js +2 -0
  8. package/dist/api/index.js.map +1 -1
  9. package/dist/lexicon/index.d.ts +4 -0
  10. package/dist/lexicon/index.d.ts.map +1 -1
  11. package/dist/lexicon/index.js +8 -0
  12. package/dist/lexicon/index.js.map +1 -1
  13. package/dist/lexicon/lexicons.d.ts +170 -0
  14. package/dist/lexicon/lexicons.d.ts.map +1 -1
  15. package/dist/lexicon/lexicons.js +87 -0
  16. package/dist/lexicon/lexicons.js.map +1 -1
  17. package/dist/lexicon/types/app/bsky/actor/defs.d.ts +2 -0
  18. package/dist/lexicon/types/app/bsky/actor/defs.d.ts.map +1 -1
  19. package/dist/lexicon/types/app/bsky/actor/defs.js.map +1 -1
  20. package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts +22 -0
  21. package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.d.ts.map +1 -0
  22. package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js +7 -0
  23. package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.js.map +1 -0
  24. package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.d.ts +23 -0
  25. package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.d.ts.map +1 -0
  26. package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.js +7 -0
  27. package/dist/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.js.map +1 -0
  28. package/dist/util.d.ts.map +1 -1
  29. package/dist/util.js +3 -1
  30. package/dist/util.js.map +1 -1
  31. package/dist/views/index.d.ts.map +1 -1
  32. package/dist/views/index.js +1 -1
  33. package/dist/views/index.js.map +1 -1
  34. package/package.json +8 -8
  35. package/src/api/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.ts +152 -0
  36. package/src/api/index.ts +2 -0
  37. package/src/lexicon/index.ts +26 -0
  38. package/src/lexicon/lexicons.ts +91 -0
  39. package/src/lexicon/types/app/bsky/actor/defs.ts +2 -0
  40. package/src/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacks.ts +40 -0
  41. package/src/lexicon/types/app/bsky/unspecced/getOnboardingSuggestedStarterPacksSkeleton.ts +41 -0
  42. package/src/util.ts +3 -1
  43. package/src/views/index.ts +1 -1
  44. package/tsconfig.build.tsbuildinfo +1 -1
@@ -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)
@@ -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,
@@ -31,6 +31,9 @@ export const schemaDict = {
31
31
  maxGraphemes: 64,
32
32
  maxLength: 640,
33
33
  },
34
+ pronouns: {
35
+ type: 'string',
36
+ },
34
37
  avatar: {
35
38
  type: 'string',
36
39
  format: 'uri',
@@ -81,6 +84,9 @@ export const schemaDict = {
81
84
  maxGraphemes: 64,
82
85
  maxLength: 640,
83
86
  },
87
+ pronouns: {
88
+ type: 'string',
89
+ },
84
90
  description: {
85
91
  type: 'string',
86
92
  maxGraphemes: 256,
@@ -6628,6 +6634,87 @@ export const schemaDict = {
6628
6634
  },
6629
6635
  },
6630
6636
  },
6637
+ AppBskyUnspeccedGetOnboardingSuggestedStarterPacks: {
6638
+ lexicon: 1,
6639
+ id: 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks',
6640
+ defs: {
6641
+ main: {
6642
+ type: 'query',
6643
+ description: 'Get a list of suggested starterpacks for onboarding',
6644
+ parameters: {
6645
+ type: 'params',
6646
+ properties: {
6647
+ limit: {
6648
+ type: 'integer',
6649
+ minimum: 1,
6650
+ maximum: 25,
6651
+ default: 10,
6652
+ },
6653
+ },
6654
+ },
6655
+ output: {
6656
+ encoding: 'application/json',
6657
+ schema: {
6658
+ type: 'object',
6659
+ required: ['starterPacks'],
6660
+ properties: {
6661
+ starterPacks: {
6662
+ type: 'array',
6663
+ items: {
6664
+ type: 'ref',
6665
+ ref: 'lex:app.bsky.graph.defs#starterPackView',
6666
+ },
6667
+ },
6668
+ },
6669
+ },
6670
+ },
6671
+ },
6672
+ },
6673
+ },
6674
+ AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton: {
6675
+ lexicon: 1,
6676
+ id: 'app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton',
6677
+ defs: {
6678
+ main: {
6679
+ type: 'query',
6680
+ description:
6681
+ 'Get a skeleton of suggested starterpacks for onboarding. Intended to be called and hydrated by app.bsky.unspecced.getOnboardingSuggestedStarterPacks',
6682
+ parameters: {
6683
+ type: 'params',
6684
+ properties: {
6685
+ viewer: {
6686
+ type: 'string',
6687
+ format: 'did',
6688
+ description:
6689
+ 'DID of the account making the request (not included for public/unauthenticated queries).',
6690
+ },
6691
+ limit: {
6692
+ type: 'integer',
6693
+ minimum: 1,
6694
+ maximum: 25,
6695
+ default: 10,
6696
+ },
6697
+ },
6698
+ },
6699
+ output: {
6700
+ encoding: 'application/json',
6701
+ schema: {
6702
+ type: 'object',
6703
+ required: ['starterPacks'],
6704
+ properties: {
6705
+ starterPacks: {
6706
+ type: 'array',
6707
+ items: {
6708
+ type: 'string',
6709
+ format: 'at-uri',
6710
+ },
6711
+ },
6712
+ },
6713
+ },
6714
+ },
6715
+ },
6716
+ },
6717
+ },
6631
6718
  AppBskyUnspeccedGetPopularFeedGenerators: {
6632
6719
  lexicon: 1,
6633
6720
  id: 'app.bsky.unspecced.getPopularFeedGenerators',
@@ -13979,6 +14066,10 @@ export const ids = {
13979
14066
  AppBskyUnspeccedGetAgeAssuranceState:
13980
14067
  'app.bsky.unspecced.getAgeAssuranceState',
13981
14068
  AppBskyUnspeccedGetConfig: 'app.bsky.unspecced.getConfig',
14069
+ AppBskyUnspeccedGetOnboardingSuggestedStarterPacks:
14070
+ 'app.bsky.unspecced.getOnboardingSuggestedStarterPacks',
14071
+ AppBskyUnspeccedGetOnboardingSuggestedStarterPacksSkeleton:
14072
+ 'app.bsky.unspecced.getOnboardingSuggestedStarterPacksSkeleton',
13982
14073
  AppBskyUnspeccedGetPopularFeedGenerators:
13983
14074
  'app.bsky.unspecced.getPopularFeedGenerators',
13984
14075
  AppBskyUnspeccedGetPostThreadOtherV2:
@@ -26,6 +26,7 @@ export interface ProfileViewBasic {
26
26
  did: string
27
27
  handle: string
28
28
  displayName?: string
29
+ pronouns?: string
29
30
  avatar?: string
30
31
  associated?: ProfileAssociated
31
32
  viewer?: ViewerState
@@ -50,6 +51,7 @@ export interface ProfileView {
50
51
  did: string
51
52
  handle: string
52
53
  displayName?: string
54
+ pronouns?: string
53
55
  description?: string
54
56
  avatar?: string
55
57
  associated?: ProfileAssociated
@@ -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
- if (!header) return null
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)
@@ -265,7 +265,6 @@ export class Views {
265
265
 
266
266
  return {
267
267
  ...baseView,
268
- pronouns: actor.profile?.pronouns,
269
268
  website: this.profileWebsite(did, state),
270
269
  viewer: baseView.viewer
271
270
  ? {
@@ -345,6 +344,7 @@ export class Views {
345
344
  did,
346
345
  handle: actor.handle ?? INVALID_HANDLE,
347
346
  displayName: actor.profile?.displayName,
347
+ pronouns: actor.profile?.pronouns,
348
348
  avatar: actor.profile?.avatar
349
349
  ? this.imgUriBuilder.getPresetUri(
350
350
  'avatar',