@atproto/api 0.6.10 → 0.6.12

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 (104) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +45 -36
  3. package/bench/agent.bench.ts +2 -2
  4. package/build.js +0 -8
  5. package/definitions/labels.json +7 -1
  6. package/definitions/locale/en/label-groups.json +1 -1
  7. package/definitions/locale/en/labels.json +15 -1
  8. package/definitions/locale/en/proposed-label-groups.json +1 -1
  9. package/definitions/locale/en/proposed-labels.json +1 -1
  10. package/definitions/post-moderation-behaviors.json +315 -231
  11. package/definitions/profile-moderation-behaviors.json +188 -117
  12. package/definitions/proposed-labels.json +1 -1
  13. package/dist/bsky-agent.d.ts +8 -0
  14. package/dist/client/lexicons.d.ts +33 -0
  15. package/dist/client/types/app/bsky/actor/createScene.d.ts +32 -0
  16. package/dist/client/types/app/bsky/actor/defs.d.ts +7 -1
  17. package/dist/client/types/app/bsky/actor/ref.d.ts +28 -0
  18. package/dist/client/types/app/bsky/actor/search.d.ts +22 -0
  19. package/dist/client/types/app/bsky/actor/searchTypeahead.d.ts +20 -0
  20. package/dist/client/types/app/bsky/actor/updateProfile.d.ts +40 -0
  21. package/dist/client/types/app/bsky/embed/images.d.ts +9 -0
  22. package/dist/client/types/app/bsky/feed/feedViewPost.d.ts +28 -0
  23. package/dist/client/types/app/bsky/feed/getVotes.d.ts +36 -0
  24. package/dist/client/types/app/bsky/feed/saveFeed.d.ts +17 -0
  25. package/dist/client/types/app/bsky/feed/setVote.d.ts +25 -0
  26. package/dist/client/types/app/bsky/feed/trend.d.ts +9 -0
  27. package/dist/client/types/app/bsky/feed/unsaveFeed.d.ts +17 -0
  28. package/dist/client/types/app/bsky/feed/vote.d.ts +10 -0
  29. package/dist/client/types/app/bsky/graph/assertCreator.d.ts +1 -0
  30. package/dist/client/types/app/bsky/graph/assertMember.d.ts +1 -0
  31. package/dist/client/types/app/bsky/graph/assertion.d.ts +10 -0
  32. package/dist/client/types/app/bsky/graph/confirmation.d.ts +11 -0
  33. package/dist/client/types/app/bsky/graph/getAssertions.d.ts +48 -0
  34. package/dist/client/types/app/bsky/{actor/getFeedSuggestions.d.ts → graph/getListBlocks.d.ts} +2 -2
  35. package/dist/client/types/app/bsky/graph/getMembers.d.ts +36 -0
  36. package/dist/client/types/app/bsky/graph/getMemberships.d.ts +36 -0
  37. package/dist/client/types/app/bsky/graph/listblock.d.ts +8 -0
  38. package/dist/client/types/app/bsky/graph/mute.d.ts +17 -0
  39. package/dist/client/types/app/bsky/graph/subscribeMuteList.d.ts +17 -0
  40. package/dist/client/types/app/bsky/graph/unmute.d.ts +17 -0
  41. package/dist/client/types/app/bsky/graph/unsubscribeMuteList.d.ts +17 -0
  42. package/dist/client/types/app/bsky/notification/getCount.d.ts +17 -0
  43. package/dist/client/types/app/bsky/notification/list.d.ts +35 -0
  44. package/dist/client/types/app/bsky/system/actorScene.d.ts +1 -0
  45. package/dist/client/types/app/bsky/system/actorUser.d.ts +1 -0
  46. package/dist/client/types/app/bsky/system/declRef.d.ts +8 -0
  47. package/dist/client/types/app/bsky/system/declaration.d.ts +7 -0
  48. package/dist/client/types/app/bsky/unspecced/registerPushNotification.d.ts +16 -0
  49. package/dist/client/types/com/atproto/account/create.d.ts +41 -0
  50. package/dist/client/types/com/atproto/account/createInviteCode.d.ts +22 -0
  51. package/dist/client/types/com/atproto/account/delete.d.ts +25 -0
  52. package/dist/client/types/com/atproto/account/get.d.ts +12 -0
  53. package/dist/client/types/com/atproto/account/requestDelete.d.ts +13 -0
  54. package/dist/client/types/com/atproto/account/requestPasswordReset.d.ts +17 -0
  55. package/dist/client/types/com/atproto/account/resetPassword.d.ts +24 -0
  56. package/dist/client/types/com/atproto/admin/blob.d.ts +37 -0
  57. package/dist/client/types/com/atproto/admin/moderationAction.d.ts +60 -0
  58. package/dist/client/types/com/atproto/admin/moderationReport.d.ts +37 -0
  59. package/dist/client/types/com/atproto/admin/rebaseRepo.d.ts +24 -0
  60. package/dist/client/types/com/atproto/admin/record.d.ts +43 -0
  61. package/dist/client/types/com/atproto/admin/repo.d.ts +45 -0
  62. package/dist/client/types/com/atproto/blob/upload.d.ts +19 -0
  63. package/dist/client/types/com/atproto/handle/resolve.d.ts +18 -0
  64. package/dist/client/types/com/atproto/handle/update.d.ts +17 -0
  65. package/dist/client/types/com/atproto/repo/batchWrite.d.ts +46 -0
  66. package/dist/client/types/com/atproto/repo/describe.d.ts +22 -0
  67. package/dist/client/types/com/atproto/repo/rebaseRepo.d.ts +24 -0
  68. package/dist/client/types/com/atproto/repo/recordRef.d.ts +8 -0
  69. package/dist/client/types/com/atproto/repo/repoRef.d.ts +7 -0
  70. package/dist/client/types/com/atproto/report/create.d.ts +39 -0
  71. package/dist/client/types/com/atproto/report/reasonType.d.ts +3 -0
  72. package/dist/client/types/com/atproto/report/subject.d.ts +23 -0
  73. package/dist/client/types/com/atproto/server/getAccountsConfig.d.ts +27 -0
  74. package/dist/client/types/com/atproto/session/create.d.ts +29 -0
  75. package/dist/client/types/com/atproto/session/delete.d.ts +13 -0
  76. package/dist/client/types/com/atproto/session/get.d.ts +18 -0
  77. package/dist/client/types/com/atproto/session/refresh.d.ts +24 -0
  78. package/dist/client/types/com/atproto/sync/getCommitPath.d.ts +20 -0
  79. package/dist/client/types/com/atproto/sync/getRoot.d.ts +18 -0
  80. package/dist/client/types/com/atproto/sync/subscribeAllRepos.d.ts +9 -0
  81. package/dist/client/types/com/atproto/sync/updateRepo.d.ts +15 -0
  82. package/dist/helpers/bsky.d.ts +20 -0
  83. package/dist/index.js +974 -1148
  84. package/dist/index.js.map +4 -4
  85. package/dist/mixins/bsky.d.ts +23 -0
  86. package/dist/rich-text/sanitize.d.ts +4 -0
  87. package/dist/session.d.ts +42 -0
  88. package/dist/types.d.ts +1 -0
  89. package/docs/labels.md +43 -27
  90. package/docs/moderation-behaviors/posts.md +13 -516
  91. package/docs/moderation-behaviors/profiles.md +14 -174
  92. package/docs/moderation.md +3 -3
  93. package/package.json +23 -23
  94. package/src/bsky-agent.ts +61 -11
  95. package/src/client/lexicons.ts +35 -0
  96. package/src/client/types/app/bsky/actor/defs.ts +19 -0
  97. package/src/client/types/app/bsky/embed/images.ts +21 -0
  98. package/src/moderation/const/label-groups.ts +1 -0
  99. package/src/moderation/const/labels.ts +30 -0
  100. package/src/types.ts +1 -0
  101. package/tests/bsky-agent.test.ts +182 -0
  102. package/tsconfig.build.json +1 -1
  103. package/update-pkg.js +0 -14
  104. /package/dist/client/types/app/bsky/feed/{getFeedSuggestions.d.ts → getSavedFeeds.d.ts} +0 -0
@@ -80,7 +80,7 @@ interface LabelerSettings {
80
80
  Applications need to produce the [Post Moderation Behaviors](./moderation-behaviors/posts.md) using the `moderatePost()` API.
81
81
 
82
82
  ```typescript
83
- import {moderatePost} from '@atproto/api'
83
+ import { moderatePost } from '@atproto/api'
84
84
 
85
85
  const postMod = moderatePost(postView, getOpts())
86
86
 
@@ -119,7 +119,7 @@ if (postMod.avatar.alert) {
119
119
  Applications need to produce the [Profile Moderation Behaviors](./moderation-behaviors/profiles.md) using the `moderateProfile()` API.
120
120
 
121
121
  ```typescript
122
- import {moderateProfile} from '@atproto/api'
122
+ import { moderateProfile } from '@atproto/api'
123
123
 
124
124
  const profileMod = moderateProfile(profileView, getOpts())
125
125
 
@@ -150,4 +150,4 @@ if (profileMod.avatar.blur) {
150
150
  if (profileMod.avatar.alert) {
151
151
  // render an alert on the avatar
152
152
  }
153
- ```
153
+ ```
package/package.json CHANGED
@@ -1,20 +1,7 @@
1
1
  {
2
2
  "name": "@atproto/api",
3
- "version": "0.6.10",
3
+ "version": "0.6.12",
4
4
  "main": "dist/index.js",
5
- "scripts": {
6
- "codegen": "yarn docgen && node ./scripts/generate-code.mjs && lex gen-api ./src/client ../../lexicons/com/atproto/*/* ../../lexicons/app/bsky/*/*",
7
- "docgen": "node ./scripts/generate-docs.mjs",
8
- "build": "node ./build.js",
9
- "postbuild": "tsc --build tsconfig.build.json",
10
- "update-main-to-dist": "node ./update-pkg.js --update-main-to-dist",
11
- "update-main-to-src": "node ./update-pkg.js --update-main-to-src",
12
- "prepublish": "npm run update-main-to-dist",
13
- "postpublish": "npm run update-main-to-src",
14
- "test": "jest",
15
- "bench": "jest --config jest.bench.config.js",
16
- "bench:profile": "node --inspect-brk ../../node_modules/.bin/jest --config jest.bench.config.js"
17
- },
18
5
  "license": "MIT",
19
6
  "repository": {
20
7
  "type": "git",
@@ -22,15 +9,28 @@
22
9
  "directory": "packages/api"
23
10
  },
24
11
  "dependencies": {
25
- "@atproto/common-web": "*",
26
- "@atproto/syntax": "*",
27
- "@atproto/xrpc": "*",
12
+ "multiformats": "^9.9.0",
28
13
  "tlds": "^1.234.0",
29
- "typed-emitter": "^2.1.0"
14
+ "typed-emitter": "^2.1.0",
15
+ "@atproto/common-web": "^0.2.0",
16
+ "@atproto/syntax": "^0.1.0",
17
+ "@atproto/lexicon": "^0.2.0",
18
+ "@atproto/xrpc": "^0.3.0"
30
19
  },
31
20
  "devDependencies": {
32
- "@atproto/lex-cli": "*",
33
- "@atproto/pds": "*",
34
- "common-tags": "^1.8.2"
35
- }
36
- }
21
+ "common-tags": "^1.8.2",
22
+ "@atproto/pds": "^0.1.12",
23
+ "@atproto/lex-cli": "^0.2.0"
24
+ },
25
+ "scripts": {
26
+ "codegen": "pnpm docgen && node ./scripts/generate-code.mjs && lex gen-api ./src/client ../../lexicons/com/atproto/*/* ../../lexicons/app/bsky/*/*",
27
+ "docgen": "node ./scripts/generate-docs.mjs",
28
+ "build": "node ./build.js",
29
+ "postbuild": "tsc --build tsconfig.build.json",
30
+ "update-main-to-dist": "node ../../update-main-to-dist.js packages/api",
31
+ "test": "jest",
32
+ "bench": "jest --config jest.bench.config.js",
33
+ "bench:profile": "node --inspect-brk ../../node_modules/.bin/jest --config jest.bench.config.js"
34
+ },
35
+ "types": "dist/index.d.ts"
36
+ }
package/src/bsky-agent.ts CHANGED
@@ -8,6 +8,15 @@ import {
8
8
  } from './client'
9
9
  import { BskyPreferences, BskyLabelPreference } from './types'
10
10
 
11
+ declare global {
12
+ interface Array<T> {
13
+ findLast(
14
+ predicate: (value: T, index: number, obj: T[]) => unknown,
15
+ thisArg?: any,
16
+ ): T
17
+ }
18
+ }
19
+
11
20
  export class BskyAgent extends AtpAgent {
12
21
  get app() {
13
22
  return this.api.app
@@ -247,6 +256,7 @@ export class BskyAgent extends AtpAgent {
247
256
  },
248
257
  adultContentEnabled: false,
249
258
  contentLabels: {},
259
+ birthDate: undefined,
250
260
  }
251
261
  const res = await this.app.bsky.actor.getPreferences({})
252
262
  for (const pref of res.data.preferences) {
@@ -272,6 +282,13 @@ export class BskyAgent extends AtpAgent {
272
282
  ) {
273
283
  prefs.feeds.saved = pref.saved
274
284
  prefs.feeds.pinned = pref.pinned
285
+ } else if (
286
+ AppBskyActorDefs.isPersonalDetailsPref(pref) &&
287
+ AppBskyActorDefs.validatePersonalDetailsPref(pref).success
288
+ ) {
289
+ if (pref.birthDate) {
290
+ prefs.birthDate = new Date(pref.birthDate)
291
+ }
275
292
  }
276
293
  }
277
294
  return prefs
@@ -314,20 +331,22 @@ export class BskyAgent extends AtpAgent {
314
331
 
315
332
  async setAdultContentEnabled(v: boolean) {
316
333
  await updatePreferences(this, (prefs: AppBskyActorDefs.Preferences) => {
317
- const existing = prefs.find(
334
+ let adultContentPref = prefs.findLast(
318
335
  (pref) =>
319
336
  AppBskyActorDefs.isAdultContentPref(pref) &&
320
337
  AppBskyActorDefs.validateAdultContentPref(pref).success,
321
338
  )
322
- if (existing) {
323
- existing.enabled = v
339
+ if (adultContentPref) {
340
+ adultContentPref.enabled = v
324
341
  } else {
325
- prefs.push({
342
+ adultContentPref = {
326
343
  $type: 'app.bsky.actor.defs#adultContentPref',
327
344
  enabled: v,
328
- })
345
+ }
329
346
  }
330
347
  return prefs
348
+ .filter((pref) => !AppBskyActorDefs.isAdultContentPref(pref))
349
+ .concat([adultContentPref])
331
350
  })
332
351
  }
333
352
 
@@ -338,22 +357,53 @@ export class BskyAgent extends AtpAgent {
338
357
  }
339
358
 
340
359
  await updatePreferences(this, (prefs: AppBskyActorDefs.Preferences) => {
341
- const existing = prefs.find(
360
+ let labelPref = prefs.findLast(
342
361
  (pref) =>
343
362
  AppBskyActorDefs.isContentLabelPref(pref) &&
344
363
  AppBskyActorDefs.validateAdultContentPref(pref).success &&
345
364
  pref.label === key,
346
365
  )
347
- if (existing) {
348
- existing.visibility = value
366
+ if (labelPref) {
367
+ labelPref.visibility = value
349
368
  } else {
350
- prefs.push({
369
+ labelPref = {
351
370
  $type: 'app.bsky.actor.defs#contentLabelPref',
352
371
  label: key,
353
372
  visibility: value,
354
- })
373
+ }
374
+ }
375
+ return prefs
376
+ .filter(
377
+ (pref) =>
378
+ !AppBskyActorDefs.isContentLabelPref(pref) || pref.label !== key,
379
+ )
380
+ .concat([labelPref])
381
+ })
382
+ }
383
+
384
+ async setPersonalDetails({
385
+ birthDate,
386
+ }: {
387
+ birthDate: string | Date | undefined
388
+ }) {
389
+ birthDate = birthDate instanceof Date ? birthDate.toISOString() : birthDate
390
+ await updatePreferences(this, (prefs: AppBskyActorDefs.Preferences) => {
391
+ let personalDetailsPref = prefs.findLast(
392
+ (pref) =>
393
+ AppBskyActorDefs.isPersonalDetailsPref(pref) &&
394
+ AppBskyActorDefs.validatePersonalDetailsPref(pref).success,
395
+ )
396
+ if (personalDetailsPref) {
397
+ personalDetailsPref.birthDate = birthDate
398
+ } else {
399
+ personalDetailsPref = {
400
+ $type: 'app.bsky.actor.defs#personalDetailsPref',
401
+ birthDate,
402
+ }
355
403
  }
356
404
  return prefs
405
+ .filter((pref) => !AppBskyActorDefs.isPersonalDetailsPref(pref))
406
+ .concat([personalDetailsPref])
357
407
  })
358
408
  }
359
409
  }
@@ -394,7 +444,7 @@ async function updateFeedPreferences(
394
444
  ): Promise<{ saved: string[]; pinned: string[] }> {
395
445
  let res
396
446
  await updatePreferences(agent, (prefs: AppBskyActorDefs.Preferences) => {
397
- let feedsPref = prefs.find(
447
+ let feedsPref = prefs.findLast(
398
448
  (pref) =>
399
449
  AppBskyActorDefs.isSavedFeedsPref(pref) &&
400
450
  AppBskyActorDefs.validateSavedFeedsPref(pref).success,
@@ -3714,6 +3714,7 @@ export const schemaDict = {
3714
3714
  'lex:app.bsky.actor.defs#adultContentPref',
3715
3715
  'lex:app.bsky.actor.defs#contentLabelPref',
3716
3716
  'lex:app.bsky.actor.defs#savedFeedsPref',
3717
+ 'lex:app.bsky.actor.defs#personalDetailsPref',
3717
3718
  ],
3718
3719
  },
3719
3720
  },
@@ -3760,6 +3761,16 @@ export const schemaDict = {
3760
3761
  },
3761
3762
  },
3762
3763
  },
3764
+ personalDetailsPref: {
3765
+ type: 'object',
3766
+ properties: {
3767
+ birthDate: {
3768
+ type: 'string',
3769
+ format: 'datetime',
3770
+ description: 'The birth date of the owner of the account.',
3771
+ },
3772
+ },
3773
+ },
3763
3774
  },
3764
3775
  },
3765
3776
  AppBskyActorGetPreferences: {
@@ -4145,6 +4156,26 @@ export const schemaDict = {
4145
4156
  alt: {
4146
4157
  type: 'string',
4147
4158
  },
4159
+ aspectRatio: {
4160
+ type: 'ref',
4161
+ ref: 'lex:app.bsky.embed.images#aspectRatio',
4162
+ },
4163
+ },
4164
+ },
4165
+ aspectRatio: {
4166
+ type: 'object',
4167
+ description:
4168
+ 'width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit.',
4169
+ required: ['width', 'height'],
4170
+ properties: {
4171
+ width: {
4172
+ type: 'integer',
4173
+ minimum: 1,
4174
+ },
4175
+ height: {
4176
+ type: 'integer',
4177
+ minimum: 1,
4178
+ },
4148
4179
  },
4149
4180
  },
4150
4181
  view: {
@@ -4174,6 +4205,10 @@ export const schemaDict = {
4174
4205
  alt: {
4175
4206
  type: 'string',
4176
4207
  },
4208
+ aspectRatio: {
4209
+ type: 'ref',
4210
+ ref: 'lex:app.bsky.embed.images#aspectRatio',
4211
+ },
4177
4212
  },
4178
4213
  },
4179
4214
  },
@@ -108,6 +108,7 @@ export type Preferences = (
108
108
  | AdultContentPref
109
109
  | ContentLabelPref
110
110
  | SavedFeedsPref
111
+ | PersonalDetailsPref
111
112
  | { $type: string; [k: string]: unknown }
112
113
  )[]
113
114
 
@@ -163,3 +164,21 @@ export function isSavedFeedsPref(v: unknown): v is SavedFeedsPref {
163
164
  export function validateSavedFeedsPref(v: unknown): ValidationResult {
164
165
  return lexicons.validate('app.bsky.actor.defs#savedFeedsPref', v)
165
166
  }
167
+
168
+ export interface PersonalDetailsPref {
169
+ /** The birth date of the owner of the account. */
170
+ birthDate?: string
171
+ [k: string]: unknown
172
+ }
173
+
174
+ export function isPersonalDetailsPref(v: unknown): v is PersonalDetailsPref {
175
+ return (
176
+ isObj(v) &&
177
+ hasProp(v, '$type') &&
178
+ v.$type === 'app.bsky.actor.defs#personalDetailsPref'
179
+ )
180
+ }
181
+
182
+ export function validatePersonalDetailsPref(v: unknown): ValidationResult {
183
+ return lexicons.validate('app.bsky.actor.defs#personalDetailsPref', v)
184
+ }
@@ -27,6 +27,7 @@ export function validateMain(v: unknown): ValidationResult {
27
27
  export interface Image {
28
28
  image: BlobRef
29
29
  alt: string
30
+ aspectRatio?: AspectRatio
30
31
  [k: string]: unknown
31
32
  }
32
33
 
@@ -40,6 +41,25 @@ export function validateImage(v: unknown): ValidationResult {
40
41
  return lexicons.validate('app.bsky.embed.images#image', v)
41
42
  }
42
43
 
44
+ /** width:height represents an aspect ratio. It may be approximate, and may not correspond to absolute dimensions in any given unit. */
45
+ export interface AspectRatio {
46
+ width: number
47
+ height: number
48
+ [k: string]: unknown
49
+ }
50
+
51
+ export function isAspectRatio(v: unknown): v is AspectRatio {
52
+ return (
53
+ isObj(v) &&
54
+ hasProp(v, '$type') &&
55
+ v.$type === 'app.bsky.embed.images#aspectRatio'
56
+ )
57
+ }
58
+
59
+ export function validateAspectRatio(v: unknown): ValidationResult {
60
+ return lexicons.validate('app.bsky.embed.images#aspectRatio', v)
61
+ }
62
+
43
63
  export interface View {
44
64
  images: ViewImage[]
45
65
  [k: string]: unknown
@@ -59,6 +79,7 @@ export interface ViewImage {
59
79
  thumb: string
60
80
  fullsize: string
61
81
  alt: string
82
+ aspectRatio?: AspectRatio
62
83
  [k: string]: unknown
63
84
  }
64
85
 
@@ -130,6 +130,7 @@ export const LABEL_GROUPS: LabelGroupDefinitionMap = {
130
130
  LABELS['net-abuse'],
131
131
  LABELS['impersonation'],
132
132
  LABELS['scam'],
133
+ LABELS['misleading'],
133
134
  ],
134
135
  strings: {
135
136
  settings: {
@@ -795,4 +795,34 @@ export const LABELS: LabelDefinitionMap = {
795
795
  },
796
796
  },
797
797
  },
798
+ misleading: {
799
+ id: 'misleading',
800
+ preferences: ['ignore', 'warn', 'hide'],
801
+ flags: [],
802
+ onwarn: 'alert',
803
+ groupId: 'misinfo',
804
+ configurable: true,
805
+ strings: {
806
+ settings: {
807
+ en: {
808
+ name: 'Misleading',
809
+ description: 'Accounts which share misleading information.',
810
+ },
811
+ },
812
+ account: {
813
+ en: {
814
+ name: 'Misleading',
815
+ description:
816
+ 'The moderators believe this account is spreading misleading information.',
817
+ },
818
+ },
819
+ content: {
820
+ en: {
821
+ name: 'Misleading',
822
+ description:
823
+ 'The moderators believe this account is spreading misleading information.',
824
+ },
825
+ },
826
+ },
827
+ },
798
828
  }
package/src/types.ts CHANGED
@@ -89,4 +89,5 @@ export interface BskyPreferences {
89
89
  }
90
90
  adultContentEnabled: boolean
91
91
  contentLabels: Record<string, BskyLabelPreference>
92
+ birthDate: Date | undefined
92
93
  }
@@ -215,6 +215,7 @@ describe('agent', () => {
215
215
  feeds: { pinned: undefined, saved: undefined },
216
216
  adultContentEnabled: false,
217
217
  contentLabels: {},
218
+ birthDate: undefined,
218
219
  })
219
220
 
220
221
  await agent.setAdultContentEnabled(true)
@@ -222,6 +223,7 @@ describe('agent', () => {
222
223
  feeds: { pinned: undefined, saved: undefined },
223
224
  adultContentEnabled: true,
224
225
  contentLabels: {},
226
+ birthDate: undefined,
225
227
  })
226
228
 
227
229
  await agent.setAdultContentEnabled(false)
@@ -229,6 +231,7 @@ describe('agent', () => {
229
231
  feeds: { pinned: undefined, saved: undefined },
230
232
  adultContentEnabled: false,
231
233
  contentLabels: {},
234
+ birthDate: undefined,
232
235
  })
233
236
 
234
237
  await agent.setContentLabelPref('impersonation', 'warn')
@@ -238,6 +241,7 @@ describe('agent', () => {
238
241
  contentLabels: {
239
242
  impersonation: 'warn',
240
243
  },
244
+ birthDate: undefined,
241
245
  })
242
246
 
243
247
  await agent.setContentLabelPref('spam', 'show') // will convert to 'ignore'
@@ -249,6 +253,7 @@ describe('agent', () => {
249
253
  impersonation: 'hide',
250
254
  spam: 'ignore',
251
255
  },
256
+ birthDate: undefined,
252
257
  })
253
258
 
254
259
  await agent.addSavedFeed('at://bob.com/app.bsky.feed.generator/fake')
@@ -262,6 +267,7 @@ describe('agent', () => {
262
267
  impersonation: 'hide',
263
268
  spam: 'ignore',
264
269
  },
270
+ birthDate: undefined,
265
271
  })
266
272
 
267
273
  await agent.addPinnedFeed('at://bob.com/app.bsky.feed.generator/fake')
@@ -275,6 +281,7 @@ describe('agent', () => {
275
281
  impersonation: 'hide',
276
282
  spam: 'ignore',
277
283
  },
284
+ birthDate: undefined,
278
285
  })
279
286
 
280
287
  await agent.removePinnedFeed('at://bob.com/app.bsky.feed.generator/fake')
@@ -288,6 +295,7 @@ describe('agent', () => {
288
295
  impersonation: 'hide',
289
296
  spam: 'ignore',
290
297
  },
298
+ birthDate: undefined,
291
299
  })
292
300
 
293
301
  await agent.removeSavedFeed('at://bob.com/app.bsky.feed.generator/fake')
@@ -301,6 +309,7 @@ describe('agent', () => {
301
309
  impersonation: 'hide',
302
310
  spam: 'ignore',
303
311
  },
312
+ birthDate: undefined,
304
313
  })
305
314
 
306
315
  await agent.addPinnedFeed('at://bob.com/app.bsky.feed.generator/fake')
@@ -314,6 +323,7 @@ describe('agent', () => {
314
323
  impersonation: 'hide',
315
324
  spam: 'ignore',
316
325
  },
326
+ birthDate: undefined,
317
327
  })
318
328
 
319
329
  await agent.addPinnedFeed('at://bob.com/app.bsky.feed.generator/fake2')
@@ -333,6 +343,7 @@ describe('agent', () => {
333
343
  impersonation: 'hide',
334
344
  spam: 'ignore',
335
345
  },
346
+ birthDate: undefined,
336
347
  })
337
348
 
338
349
  await agent.removeSavedFeed('at://bob.com/app.bsky.feed.generator/fake')
@@ -346,7 +357,178 @@ describe('agent', () => {
346
357
  impersonation: 'hide',
347
358
  spam: 'ignore',
348
359
  },
360
+ birthDate: undefined,
349
361
  })
362
+
363
+ await agent.setPersonalDetails({ birthDate: '2023-09-11T18:05:42.556Z' })
364
+ await expect(agent.getPreferences()).resolves.toStrictEqual({
365
+ feeds: {
366
+ pinned: ['at://bob.com/app.bsky.feed.generator/fake2'],
367
+ saved: ['at://bob.com/app.bsky.feed.generator/fake2'],
368
+ },
369
+ adultContentEnabled: false,
370
+ contentLabels: {
371
+ impersonation: 'hide',
372
+ spam: 'ignore',
373
+ },
374
+ birthDate: new Date('2023-09-11T18:05:42.556Z'),
375
+ })
376
+ })
377
+
378
+ it('resolves duplicates correctly', async () => {
379
+ const agent = new BskyAgent({ service: server.url })
380
+
381
+ await agent.createAccount({
382
+ handle: 'user6.test',
383
+ email: 'user6@test.com',
384
+ password: 'password',
385
+ })
386
+
387
+ await agent.app.bsky.actor.putPreferences({
388
+ preferences: [
389
+ {
390
+ $type: 'app.bsky.actor.defs#contentLabelPref',
391
+ label: 'nsfw',
392
+ visibility: 'show',
393
+ },
394
+ {
395
+ $type: 'app.bsky.actor.defs#contentLabelPref',
396
+ label: 'nsfw',
397
+ visibility: 'hide',
398
+ },
399
+ {
400
+ $type: 'app.bsky.actor.defs#contentLabelPref',
401
+ label: 'nsfw',
402
+ visibility: 'show',
403
+ },
404
+ {
405
+ $type: 'app.bsky.actor.defs#contentLabelPref',
406
+ label: 'nsfw',
407
+ visibility: 'warn',
408
+ },
409
+ {
410
+ $type: 'app.bsky.actor.defs#adultContentPref',
411
+ enabled: true,
412
+ },
413
+ {
414
+ $type: 'app.bsky.actor.defs#adultContentPref',
415
+ enabled: false,
416
+ },
417
+ {
418
+ $type: 'app.bsky.actor.defs#adultContentPref',
419
+ enabled: true,
420
+ },
421
+ {
422
+ $type: 'app.bsky.actor.defs#savedFeedsPref',
423
+ pinned: [
424
+ 'at://bob.com/app.bsky.feed.generator/fake',
425
+ 'at://bob.com/app.bsky.feed.generator/fake2',
426
+ ],
427
+ saved: [
428
+ 'at://bob.com/app.bsky.feed.generator/fake',
429
+ 'at://bob.com/app.bsky.feed.generator/fake2',
430
+ ],
431
+ },
432
+ {
433
+ $type: 'app.bsky.actor.defs#savedFeedsPref',
434
+ pinned: [],
435
+ saved: [],
436
+ },
437
+ {
438
+ $type: 'app.bsky.actor.defs#personalDetailsPref',
439
+ birthDate: '2023-09-11T18:05:42.556Z',
440
+ },
441
+ {
442
+ $type: 'app.bsky.actor.defs#personalDetailsPref',
443
+ birthDate: '2021-09-11T18:05:42.556Z',
444
+ },
445
+ ],
446
+ })
447
+ await expect(agent.getPreferences()).resolves.toStrictEqual({
448
+ feeds: {
449
+ pinned: [],
450
+ saved: [],
451
+ },
452
+ adultContentEnabled: true,
453
+ contentLabels: {
454
+ nsfw: 'warn',
455
+ },
456
+ birthDate: new Date('2021-09-11T18:05:42.556Z'),
457
+ })
458
+
459
+ await agent.setAdultContentEnabled(false)
460
+ await expect(agent.getPreferences()).resolves.toStrictEqual({
461
+ feeds: {
462
+ pinned: [],
463
+ saved: [],
464
+ },
465
+ adultContentEnabled: false,
466
+ contentLabels: {
467
+ nsfw: 'warn',
468
+ },
469
+ birthDate: new Date('2021-09-11T18:05:42.556Z'),
470
+ })
471
+
472
+ await agent.setContentLabelPref('nsfw', 'hide')
473
+ await expect(agent.getPreferences()).resolves.toStrictEqual({
474
+ feeds: {
475
+ pinned: [],
476
+ saved: [],
477
+ },
478
+ adultContentEnabled: false,
479
+ contentLabels: {
480
+ nsfw: 'hide',
481
+ },
482
+ birthDate: new Date('2021-09-11T18:05:42.556Z'),
483
+ })
484
+
485
+ await agent.addPinnedFeed('at://bob.com/app.bsky.feed.generator/fake')
486
+ await expect(agent.getPreferences()).resolves.toStrictEqual({
487
+ feeds: {
488
+ pinned: ['at://bob.com/app.bsky.feed.generator/fake'],
489
+ saved: ['at://bob.com/app.bsky.feed.generator/fake'],
490
+ },
491
+ adultContentEnabled: false,
492
+ contentLabels: {
493
+ nsfw: 'hide',
494
+ },
495
+ birthDate: new Date('2021-09-11T18:05:42.556Z'),
496
+ })
497
+
498
+ await agent.setPersonalDetails({ birthDate: '2023-09-11T18:05:42.556Z' })
499
+ await expect(agent.getPreferences()).resolves.toStrictEqual({
500
+ feeds: {
501
+ pinned: ['at://bob.com/app.bsky.feed.generator/fake'],
502
+ saved: ['at://bob.com/app.bsky.feed.generator/fake'],
503
+ },
504
+ adultContentEnabled: false,
505
+ contentLabels: {
506
+ nsfw: 'hide',
507
+ },
508
+ birthDate: new Date('2023-09-11T18:05:42.556Z'),
509
+ })
510
+
511
+ const res = await agent.app.bsky.actor.getPreferences()
512
+ await expect(res.data.preferences).toStrictEqual([
513
+ {
514
+ $type: 'app.bsky.actor.defs#adultContentPref',
515
+ enabled: false,
516
+ },
517
+ {
518
+ $type: 'app.bsky.actor.defs#contentLabelPref',
519
+ label: 'nsfw',
520
+ visibility: 'hide',
521
+ },
522
+ {
523
+ $type: 'app.bsky.actor.defs#savedFeedsPref',
524
+ pinned: ['at://bob.com/app.bsky.feed.generator/fake'],
525
+ saved: ['at://bob.com/app.bsky.feed.generator/fake'],
526
+ },
527
+ {
528
+ $type: 'app.bsky.actor.defs#personalDetailsPref',
529
+ birthDate: '2023-09-11T18:05:42.556Z',
530
+ },
531
+ ])
350
532
  })
351
533
  })
352
534
  })
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "extends": "./tsconfig.json",
3
3
  "exclude": ["**/*.spec.ts", "**/*.test.ts"]
4
- }
4
+ }
package/update-pkg.js DELETED
@@ -1,14 +0,0 @@
1
- const pkgJson = require('@npmcli/package-json')
2
-
3
- if (process.argv.includes('--update-main-to-dist')) {
4
- return pkgJson
5
- .load(__dirname)
6
- .then((pkg) => pkg.update({ main: 'dist/index.js' }))
7
- .then((pkg) => pkg.save())
8
- }
9
- if (process.argv.includes('--update-main-to-src')) {
10
- return pkgJson
11
- .load(__dirname)
12
- .then((pkg) => pkg.update({ main: 'src/index.ts' }))
13
- .then((pkg) => pkg.save())
14
- }