@atproto/pds 0.4.32 → 0.4.34

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 (63) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/actor-store/preference/reader.d.ts +2 -1
  3. package/dist/actor-store/preference/reader.d.ts.map +1 -1
  4. package/dist/actor-store/preference/reader.js +3 -1
  5. package/dist/actor-store/preference/reader.js.map +1 -1
  6. package/dist/actor-store/preference/transactor.d.ts +2 -1
  7. package/dist/actor-store/preference/transactor.d.ts.map +1 -1
  8. package/dist/actor-store/preference/transactor.js +7 -1
  9. package/dist/actor-store/preference/transactor.js.map +1 -1
  10. package/dist/actor-store/preference/util.d.ts +3 -0
  11. package/dist/actor-store/preference/util.d.ts.map +1 -0
  12. package/dist/actor-store/preference/util.js +12 -0
  13. package/dist/actor-store/preference/util.js.map +1 -0
  14. package/dist/api/app/bsky/actor/getPreferences.d.ts.map +1 -1
  15. package/dist/api/app/bsky/actor/getPreferences.js +1 -6
  16. package/dist/api/app/bsky/actor/getPreferences.js.map +1 -1
  17. package/dist/api/app/bsky/actor/putPreferences.d.ts.map +1 -1
  18. package/dist/api/app/bsky/actor/putPreferences.js +1 -1
  19. package/dist/api/app/bsky/actor/putPreferences.js.map +1 -1
  20. package/dist/lexicon/index.d.ts +6 -0
  21. package/dist/lexicon/index.d.ts.map +1 -1
  22. package/dist/lexicon/index.js +12 -0
  23. package/dist/lexicon/index.js.map +1 -1
  24. package/dist/lexicon/lexicons.d.ts +127 -0
  25. package/dist/lexicon/lexicons.d.ts.map +1 -1
  26. package/dist/lexicon/lexicons.js +127 -0
  27. package/dist/lexicon/lexicons.js.map +1 -1
  28. package/dist/lexicon/types/app/bsky/actor/defs.d.ts +9 -0
  29. package/dist/lexicon/types/app/bsky/actor/defs.d.ts.map +1 -1
  30. package/dist/lexicon/types/app/bsky/actor/defs.js +11 -1
  31. package/dist/lexicon/types/app/bsky/actor/defs.js.map +1 -1
  32. package/dist/lexicon/types/app/bsky/feed/defs.d.ts +1 -0
  33. package/dist/lexicon/types/app/bsky/feed/defs.d.ts.map +1 -1
  34. package/dist/lexicon/types/app/bsky/feed/defs.js.map +1 -1
  35. package/dist/lexicon/types/app/bsky/graph/getKnownFollowers.d.ts +40 -0
  36. package/dist/lexicon/types/app/bsky/graph/getKnownFollowers.d.ts.map +1 -0
  37. package/dist/lexicon/types/app/bsky/graph/getKnownFollowers.js +3 -0
  38. package/dist/lexicon/types/app/bsky/graph/getKnownFollowers.js.map +1 -0
  39. package/dist/lexicon/types/app/bsky/graph/muteThread.d.ts +29 -0
  40. package/dist/lexicon/types/app/bsky/graph/muteThread.d.ts.map +1 -0
  41. package/dist/lexicon/types/app/bsky/graph/muteThread.js +3 -0
  42. package/dist/lexicon/types/app/bsky/graph/muteThread.js.map +1 -0
  43. package/dist/lexicon/types/app/bsky/graph/unmuteThread.d.ts +29 -0
  44. package/dist/lexicon/types/app/bsky/graph/unmuteThread.d.ts.map +1 -0
  45. package/dist/lexicon/types/app/bsky/graph/unmuteThread.js +3 -0
  46. package/dist/lexicon/types/app/bsky/graph/unmuteThread.js.map +1 -0
  47. package/package.json +4 -4
  48. package/src/actor-store/preference/reader.ts +7 -1
  49. package/src/actor-store/preference/transactor.ts +10 -0
  50. package/src/actor-store/preference/util.ts +8 -0
  51. package/src/api/app/bsky/actor/getPreferences.ts +2 -9
  52. package/src/api/app/bsky/actor/putPreferences.ts +5 -1
  53. package/src/lexicon/index.ts +36 -0
  54. package/src/lexicon/lexicons.ts +129 -0
  55. package/src/lexicon/types/app/bsky/actor/defs.ts +20 -0
  56. package/src/lexicon/types/app/bsky/feed/defs.ts +1 -0
  57. package/src/lexicon/types/app/bsky/graph/getKnownFollowers.ts +50 -0
  58. package/src/lexicon/types/app/bsky/graph/muteThread.ts +38 -0
  59. package/src/lexicon/types/app/bsky/graph/unmuteThread.ts +38 -0
  60. package/tests/handle-validation.test.ts +1 -1
  61. package/tests/preferences.test.ts +67 -1
  62. package/tests/proxied/__snapshots__/feedgen.test.ts.snap +4 -1
  63. package/tests/proxied/__snapshots__/views.test.ts.snap +193 -42
@@ -4107,6 +4107,29 @@ export const schemaDict = {
4107
4107
  type: 'string',
4108
4108
  format: 'at-uri',
4109
4109
  },
4110
+ knownFollowers: {
4111
+ type: 'ref',
4112
+ ref: 'lex:app.bsky.actor.defs#knownFollowers',
4113
+ },
4114
+ },
4115
+ },
4116
+ knownFollowers: {
4117
+ type: 'object',
4118
+ description: "The subject's followers whom you also follow",
4119
+ required: ['count', 'followers'],
4120
+ properties: {
4121
+ count: {
4122
+ type: 'integer',
4123
+ },
4124
+ followers: {
4125
+ type: 'array',
4126
+ minLength: 0,
4127
+ maxLength: 5,
4128
+ items: {
4129
+ type: 'ref',
4130
+ ref: 'lex:app.bsky.actor.defs#profileViewBasic',
4131
+ },
4132
+ },
4110
4133
  },
4111
4134
  },
4112
4135
  preferences: {
@@ -5079,6 +5102,9 @@ export const schemaDict = {
5079
5102
  type: 'string',
5080
5103
  format: 'at-uri',
5081
5104
  },
5105
+ threadMuted: {
5106
+ type: 'boolean',
5107
+ },
5082
5108
  replyDisabled: {
5083
5109
  type: 'boolean',
5084
5110
  },
@@ -7101,6 +7127,59 @@ export const schemaDict = {
7101
7127
  },
7102
7128
  },
7103
7129
  },
7130
+ AppBskyGraphGetKnownFollowers: {
7131
+ lexicon: 1,
7132
+ id: 'app.bsky.graph.getKnownFollowers',
7133
+ defs: {
7134
+ main: {
7135
+ type: 'query',
7136
+ description:
7137
+ 'Enumerates accounts which follow a specified account (actor) and are followed by the viewer.',
7138
+ parameters: {
7139
+ type: 'params',
7140
+ required: ['actor'],
7141
+ properties: {
7142
+ actor: {
7143
+ type: 'string',
7144
+ format: 'at-identifier',
7145
+ },
7146
+ limit: {
7147
+ type: 'integer',
7148
+ minimum: 1,
7149
+ maximum: 100,
7150
+ default: 50,
7151
+ },
7152
+ cursor: {
7153
+ type: 'string',
7154
+ },
7155
+ },
7156
+ },
7157
+ output: {
7158
+ encoding: 'application/json',
7159
+ schema: {
7160
+ type: 'object',
7161
+ required: ['subject', 'followers'],
7162
+ properties: {
7163
+ subject: {
7164
+ type: 'ref',
7165
+ ref: 'lex:app.bsky.actor.defs#profileView',
7166
+ },
7167
+ cursor: {
7168
+ type: 'string',
7169
+ },
7170
+ followers: {
7171
+ type: 'array',
7172
+ items: {
7173
+ type: 'ref',
7174
+ ref: 'lex:app.bsky.actor.defs#profileView',
7175
+ },
7176
+ },
7177
+ },
7178
+ },
7179
+ },
7180
+ },
7181
+ },
7182
+ },
7104
7183
  AppBskyGraphGetList: {
7105
7184
  lexicon: 1,
7106
7185
  id: 'app.bsky.graph.getList',
@@ -7599,6 +7678,30 @@ export const schemaDict = {
7599
7678
  },
7600
7679
  },
7601
7680
  },
7681
+ AppBskyGraphMuteThread: {
7682
+ lexicon: 1,
7683
+ id: 'app.bsky.graph.muteThread',
7684
+ defs: {
7685
+ main: {
7686
+ type: 'procedure',
7687
+ description:
7688
+ 'Mutes a thread preventing notifications from the thread and any of its children. Mutes are private in Bluesky. Requires auth.',
7689
+ input: {
7690
+ encoding: 'application/json',
7691
+ schema: {
7692
+ type: 'object',
7693
+ required: ['root'],
7694
+ properties: {
7695
+ root: {
7696
+ type: 'string',
7697
+ format: 'at-uri',
7698
+ },
7699
+ },
7700
+ },
7701
+ },
7702
+ },
7703
+ },
7704
+ },
7602
7705
  AppBskyGraphUnmuteActor: {
7603
7706
  lexicon: 1,
7604
7707
  id: 'app.bsky.graph.unmuteActor',
@@ -7645,6 +7748,29 @@ export const schemaDict = {
7645
7748
  },
7646
7749
  },
7647
7750
  },
7751
+ AppBskyGraphUnmuteThread: {
7752
+ lexicon: 1,
7753
+ id: 'app.bsky.graph.unmuteThread',
7754
+ defs: {
7755
+ main: {
7756
+ type: 'procedure',
7757
+ description: 'Unmutes the specified thread. Requires auth.',
7758
+ input: {
7759
+ encoding: 'application/json',
7760
+ schema: {
7761
+ type: 'object',
7762
+ required: ['root'],
7763
+ properties: {
7764
+ root: {
7765
+ type: 'string',
7766
+ format: 'at-uri',
7767
+ },
7768
+ },
7769
+ },
7770
+ },
7771
+ },
7772
+ },
7773
+ },
7648
7774
  AppBskyLabelerDefs: {
7649
7775
  lexicon: 1,
7650
7776
  id: 'app.bsky.labeler.defs',
@@ -11015,6 +11141,7 @@ export const ids = {
11015
11141
  AppBskyGraphGetBlocks: 'app.bsky.graph.getBlocks',
11016
11142
  AppBskyGraphGetFollowers: 'app.bsky.graph.getFollowers',
11017
11143
  AppBskyGraphGetFollows: 'app.bsky.graph.getFollows',
11144
+ AppBskyGraphGetKnownFollowers: 'app.bsky.graph.getKnownFollowers',
11018
11145
  AppBskyGraphGetList: 'app.bsky.graph.getList',
11019
11146
  AppBskyGraphGetListBlocks: 'app.bsky.graph.getListBlocks',
11020
11147
  AppBskyGraphGetListMutes: 'app.bsky.graph.getListMutes',
@@ -11028,8 +11155,10 @@ export const ids = {
11028
11155
  AppBskyGraphListitem: 'app.bsky.graph.listitem',
11029
11156
  AppBskyGraphMuteActor: 'app.bsky.graph.muteActor',
11030
11157
  AppBskyGraphMuteActorList: 'app.bsky.graph.muteActorList',
11158
+ AppBskyGraphMuteThread: 'app.bsky.graph.muteThread',
11031
11159
  AppBskyGraphUnmuteActor: 'app.bsky.graph.unmuteActor',
11032
11160
  AppBskyGraphUnmuteActorList: 'app.bsky.graph.unmuteActorList',
11161
+ AppBskyGraphUnmuteThread: 'app.bsky.graph.unmuteThread',
11033
11162
  AppBskyLabelerDefs: 'app.bsky.labeler.defs',
11034
11163
  AppBskyLabelerGetServices: 'app.bsky.labeler.getServices',
11035
11164
  AppBskyLabelerService: 'app.bsky.labeler.service',
@@ -133,6 +133,7 @@ export interface ViewerState {
133
133
  blockingByList?: AppBskyGraphDefs.ListViewBasic
134
134
  following?: string
135
135
  followedBy?: string
136
+ knownFollowers?: KnownFollowers
136
137
  [k: string]: unknown
137
138
  }
138
139
 
@@ -148,6 +149,25 @@ export function validateViewerState(v: unknown): ValidationResult {
148
149
  return lexicons.validate('app.bsky.actor.defs#viewerState', v)
149
150
  }
150
151
 
152
+ /** The subject's followers whom you also follow */
153
+ export interface KnownFollowers {
154
+ count: number
155
+ followers: ProfileViewBasic[]
156
+ [k: string]: unknown
157
+ }
158
+
159
+ export function isKnownFollowers(v: unknown): v is KnownFollowers {
160
+ return (
161
+ isObj(v) &&
162
+ hasProp(v, '$type') &&
163
+ v.$type === 'app.bsky.actor.defs#knownFollowers'
164
+ )
165
+ }
166
+
167
+ export function validateKnownFollowers(v: unknown): ValidationResult {
168
+ return lexicons.validate('app.bsky.actor.defs#knownFollowers', v)
169
+ }
170
+
151
171
  export type Preferences = (
152
172
  | AdultContentPref
153
173
  | ContentLabelPref
@@ -49,6 +49,7 @@ export function validatePostView(v: unknown): ValidationResult {
49
49
  export interface ViewerState {
50
50
  repost?: string
51
51
  like?: string
52
+ threadMuted?: boolean
52
53
  replyDisabled?: boolean
53
54
  [k: string]: unknown
54
55
  }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * GENERATED CODE - DO NOT MODIFY
3
+ */
4
+ import express from 'express'
5
+ import { ValidationResult, BlobRef } from '@atproto/lexicon'
6
+ import { lexicons } from '../../../../lexicons'
7
+ import { isObj, hasProp } from '../../../../util'
8
+ import { CID } from 'multiformats/cid'
9
+ import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
10
+ import * as AppBskyActorDefs from '../actor/defs'
11
+
12
+ export interface QueryParams {
13
+ actor: string
14
+ limit: number
15
+ cursor?: string
16
+ }
17
+
18
+ export type InputSchema = undefined
19
+
20
+ export interface OutputSchema {
21
+ subject: AppBskyActorDefs.ProfileView
22
+ cursor?: string
23
+ followers: AppBskyActorDefs.ProfileView[]
24
+ [k: string]: unknown
25
+ }
26
+
27
+ export type HandlerInput = undefined
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 | HandlerPipeThrough
41
+ export type HandlerReqCtx<HA extends HandlerAuth = never> = {
42
+ auth: HA
43
+ params: QueryParams
44
+ input: HandlerInput
45
+ req: express.Request
46
+ res: express.Response
47
+ }
48
+ export type Handler<HA extends HandlerAuth = never> = (
49
+ ctx: HandlerReqCtx<HA>,
50
+ ) => Promise<HandlerOutput> | HandlerOutput
@@ -0,0 +1,38 @@
1
+ /**
2
+ * GENERATED CODE - DO NOT MODIFY
3
+ */
4
+ import express from 'express'
5
+ import { ValidationResult, BlobRef } from '@atproto/lexicon'
6
+ import { lexicons } from '../../../../lexicons'
7
+ import { isObj, hasProp } from '../../../../util'
8
+ import { CID } from 'multiformats/cid'
9
+ import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
10
+
11
+ export interface QueryParams {}
12
+
13
+ export interface InputSchema {
14
+ root: string
15
+ [k: string]: unknown
16
+ }
17
+
18
+ export interface HandlerInput {
19
+ encoding: 'application/json'
20
+ body: InputSchema
21
+ }
22
+
23
+ export interface HandlerError {
24
+ status: number
25
+ message?: string
26
+ }
27
+
28
+ export type HandlerOutput = HandlerError | void
29
+ export type HandlerReqCtx<HA extends HandlerAuth = never> = {
30
+ auth: HA
31
+ params: QueryParams
32
+ input: HandlerInput
33
+ req: express.Request
34
+ res: express.Response
35
+ }
36
+ export type Handler<HA extends HandlerAuth = never> = (
37
+ ctx: HandlerReqCtx<HA>,
38
+ ) => Promise<HandlerOutput> | HandlerOutput
@@ -0,0 +1,38 @@
1
+ /**
2
+ * GENERATED CODE - DO NOT MODIFY
3
+ */
4
+ import express from 'express'
5
+ import { ValidationResult, BlobRef } from '@atproto/lexicon'
6
+ import { lexicons } from '../../../../lexicons'
7
+ import { isObj, hasProp } from '../../../../util'
8
+ import { CID } from 'multiformats/cid'
9
+ import { HandlerAuth, HandlerPipeThrough } from '@atproto/xrpc-server'
10
+
11
+ export interface QueryParams {}
12
+
13
+ export interface InputSchema {
14
+ root: string
15
+ [k: string]: unknown
16
+ }
17
+
18
+ export interface HandlerInput {
19
+ encoding: 'application/json'
20
+ body: InputSchema
21
+ }
22
+
23
+ export interface HandlerError {
24
+ status: number
25
+ message?: string
26
+ }
27
+
28
+ export type HandlerOutput = HandlerError | void
29
+ export type HandlerReqCtx<HA extends HandlerAuth = never> = {
30
+ auth: HA
31
+ params: QueryParams
32
+ input: HandlerInput
33
+ req: express.Request
34
+ res: express.Response
35
+ }
36
+ export type Handler<HA extends HandlerAuth = never> = (
37
+ ctx: HandlerReqCtx<HA>,
38
+ ) => Promise<HandlerOutput> | HandlerOutput
@@ -34,7 +34,7 @@ describe('handle validation', () => {
34
34
  const expectThrow = (handle: string, err: string) => {
35
35
  expect(() => ensureHandleServiceConstraints(handle, domains)).toThrow(err)
36
36
  }
37
- const expectNotThrow = (handle: string, memo: string) => {
37
+ const expectNotThrow = (handle: string, _memo: string) => {
38
38
  expect(() =>
39
39
  ensureHandleServiceConstraints(handle, domains),
40
40
  ).not.toThrow()
@@ -1,11 +1,13 @@
1
1
  import { TestNetworkNoAppView, SeedClient } from '@atproto/dev-env'
2
2
  import AtpAgent from '@atproto/api'
3
3
  import usersSeed from './seeds/users'
4
+ import { AuthScope } from '../dist/auth-verifier'
4
5
 
5
6
  describe('user preferences', () => {
6
7
  let network: TestNetworkNoAppView
7
8
  let agent: AtpAgent
8
9
  let sc: SeedClient
10
+ let appPassHeaders: { authorization: string }
9
11
 
10
12
  beforeAll(async () => {
11
13
  network = await TestNetworkNoAppView.create({
@@ -14,6 +16,16 @@ describe('user preferences', () => {
14
16
  agent = network.pds.getClient()
15
17
  sc = network.getSeedClient()
16
18
  await usersSeed(sc)
19
+ const appPass = await network.pds.ctx.accountManager.createAppPassword(
20
+ sc.dids.alice,
21
+ 'test app pass',
22
+ false,
23
+ )
24
+ const res = await agent.com.atproto.server.createSession({
25
+ identifier: sc.dids.alice,
26
+ password: appPass.password,
27
+ })
28
+ appPassHeaders = { authorization: `Bearer ${res.data.accessJwt}` }
17
29
  })
18
30
 
19
31
  afterAll(async () => {
@@ -46,6 +58,7 @@ describe('user preferences', () => {
46
58
  store.pref.putPreferences(
47
59
  [{ $type: 'com.atproto.server.defs#unknown' }],
48
60
  'com.atproto',
61
+ AuthScope.Access,
49
62
  ),
50
63
  )
51
64
  const { data } = await agent.api.app.bsky.actor.getPreferences(
@@ -96,7 +109,7 @@ describe('user preferences', () => {
96
109
  // Ensure other prefs were not clobbered
97
110
  const otherPrefs = await network.pds.ctx.actorStore.read(
98
111
  sc.dids.alice,
99
- (store) => store.pref.getPreferences('com.atproto'),
112
+ (store) => store.pref.getPreferences('com.atproto', AuthScope.Access),
100
113
  )
101
114
  expect(otherPrefs).toEqual([{ $type: 'com.atproto.server.defs#unknown' }])
102
115
  })
@@ -178,4 +191,57 @@ describe('user preferences', () => {
178
191
  'Input/preferences/1 must be an object which includes the "$type" property',
179
192
  )
180
193
  })
194
+
195
+ it('does not read permissioned preferences with an app password', async () => {
196
+ await agent.api.app.bsky.actor.putPreferences(
197
+ {
198
+ preferences: [
199
+ {
200
+ $type: 'app.bsky.actor.defs#personalDetailsPref',
201
+ birthDate: new Date().toISOString(),
202
+ },
203
+ ],
204
+ },
205
+ { headers: sc.getHeaders(sc.dids.alice), encoding: 'application/json' },
206
+ )
207
+ const res = await agent.api.app.bsky.actor.getPreferences(
208
+ {},
209
+ { headers: appPassHeaders },
210
+ )
211
+ expect(res.data.preferences).toEqual([])
212
+ })
213
+
214
+ it('does not write permissioned preferences with an app password', async () => {
215
+ const tryPut = agent.api.app.bsky.actor.putPreferences(
216
+ {
217
+ preferences: [
218
+ {
219
+ $type: 'app.bsky.actor.defs#personalDetailsPref',
220
+ birthDate: new Date().toISOString(),
221
+ },
222
+ ],
223
+ },
224
+ { headers: appPassHeaders, encoding: 'application/json' },
225
+ )
226
+ await expect(tryPut).rejects.toThrow(
227
+ /Do not have authorization to set preferences/,
228
+ )
229
+ })
230
+
231
+ it('does not remove permissioned preferences with an app password', async () => {
232
+ await agent.api.app.bsky.actor.putPreferences(
233
+ {
234
+ preferences: [],
235
+ },
236
+ { headers: appPassHeaders, encoding: 'application/json' },
237
+ )
238
+ const res = await agent.api.app.bsky.actor.getPreferences(
239
+ {},
240
+ { headers: sc.getHeaders(sc.dids.alice) },
241
+ )
242
+ const scopedPref = res.data.preferences.find(
243
+ (pref) => pref.$type === 'app.bsky.actor.defs#personalDetailsPref',
244
+ )
245
+ expect(scopedPref).toBeDefined()
246
+ })
181
247
  })
@@ -59,7 +59,9 @@ Object {
59
59
  "replyCount": 0,
60
60
  "repostCount": 0,
61
61
  "uri": "record(0)",
62
- "viewer": Object {},
62
+ "viewer": Object {
63
+ "threadMuted": false,
64
+ },
63
65
  },
64
66
  },
65
67
  Object {
@@ -178,6 +180,7 @@ Object {
178
180
  "uri": "record(2)",
179
181
  "viewer": Object {
180
182
  "like": "record(8)",
183
+ "threadMuted": false,
181
184
  },
182
185
  },
183
186
  },