@atproto/bsky 0.0.150 → 0.0.151

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 (58) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/dist/data-plane/server/db/migrations/20250526T023712742Z-like-repost-via.d.ts +4 -0
  3. package/dist/data-plane/server/db/migrations/20250526T023712742Z-like-repost-via.d.ts.map +1 -0
  4. package/dist/data-plane/server/db/migrations/20250526T023712742Z-like-repost-via.js +17 -0
  5. package/dist/data-plane/server/db/migrations/20250526T023712742Z-like-repost-via.js.map +1 -0
  6. package/dist/data-plane/server/db/migrations/index.d.ts +1 -0
  7. package/dist/data-plane/server/db/migrations/index.d.ts.map +1 -1
  8. package/dist/data-plane/server/db/migrations/index.js +2 -1
  9. package/dist/data-plane/server/db/migrations/index.js.map +1 -1
  10. package/dist/data-plane/server/db/tables/like.d.ts +2 -0
  11. package/dist/data-plane/server/db/tables/like.d.ts.map +1 -1
  12. package/dist/data-plane/server/db/tables/repost.d.ts +2 -0
  13. package/dist/data-plane/server/db/tables/repost.d.ts.map +1 -1
  14. package/dist/data-plane/server/indexing/plugins/like.d.ts.map +1 -1
  15. package/dist/data-plane/server/indexing/plugins/like.js +32 -9
  16. package/dist/data-plane/server/indexing/plugins/like.js.map +1 -1
  17. package/dist/data-plane/server/indexing/plugins/repost.d.ts.map +1 -1
  18. package/dist/data-plane/server/indexing/plugins/repost.js +32 -9
  19. package/dist/data-plane/server/indexing/plugins/repost.js.map +1 -1
  20. package/dist/lexicon/lexicons.d.ts +38 -6
  21. package/dist/lexicon/lexicons.d.ts.map +1 -1
  22. package/dist/lexicon/lexicons.js +20 -2
  23. package/dist/lexicon/lexicons.js.map +1 -1
  24. package/dist/lexicon/types/app/bsky/feed/defs.d.ts +2 -0
  25. package/dist/lexicon/types/app/bsky/feed/defs.d.ts.map +1 -1
  26. package/dist/lexicon/types/app/bsky/feed/defs.js.map +1 -1
  27. package/dist/lexicon/types/app/bsky/feed/like.d.ts +1 -0
  28. package/dist/lexicon/types/app/bsky/feed/like.d.ts.map +1 -1
  29. package/dist/lexicon/types/app/bsky/feed/like.js.map +1 -1
  30. package/dist/lexicon/types/app/bsky/feed/repost.d.ts +1 -0
  31. package/dist/lexicon/types/app/bsky/feed/repost.d.ts.map +1 -1
  32. package/dist/lexicon/types/app/bsky/feed/repost.js.map +1 -1
  33. package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts +2 -2
  34. package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts.map +1 -1
  35. package/dist/lexicon/types/app/bsky/notification/listNotifications.js.map +1 -1
  36. package/dist/views/index.d.ts +1 -1
  37. package/dist/views/index.d.ts.map +1 -1
  38. package/dist/views/index.js +5 -2
  39. package/dist/views/index.js.map +1 -1
  40. package/package.json +4 -4
  41. package/src/data-plane/server/db/migrations/20250526T023712742Z-like-repost-via.ts +17 -0
  42. package/src/data-plane/server/db/migrations/index.ts +1 -0
  43. package/src/data-plane/server/db/tables/like.ts +2 -0
  44. package/src/data-plane/server/db/tables/repost.ts +2 -0
  45. package/src/data-plane/server/indexing/plugins/like.ts +39 -9
  46. package/src/data-plane/server/indexing/plugins/repost.ts +38 -9
  47. package/src/lexicon/lexicons.ts +20 -2
  48. package/src/lexicon/types/app/bsky/feed/defs.ts +2 -0
  49. package/src/lexicon/types/app/bsky/feed/like.ts +1 -0
  50. package/src/lexicon/types/app/bsky/feed/repost.ts +1 -0
  51. package/src/lexicon/types/app/bsky/notification/listNotifications.ts +3 -1
  52. package/src/views/index.ts +5 -2
  53. package/tests/__snapshots__/feed-generation.test.ts.snap +2 -0
  54. package/tests/views/__snapshots__/author-feed.test.ts.snap +30 -24
  55. package/tests/views/__snapshots__/notifications.test.ts.snap +1164 -229
  56. package/tests/views/__snapshots__/timeline.test.ts.snap +398 -376
  57. package/tests/views/notifications.test.ts +177 -0
  58. package/tsconfig.build.tsbuildinfo +1 -1
@@ -1,4 +1,4 @@
1
- import { Selectable } from 'kysely'
1
+ import { Insertable, Selectable } from 'kysely'
2
2
  import { CID } from 'multiformats/cid'
3
3
  import { AtUri, normalizeDatetimeAlways } from '@atproto/syntax'
4
4
  import * as lex from '../../../../lexicon/lexicons'
@@ -6,10 +6,12 @@ import * as Repost from '../../../../lexicon/types/app/bsky/feed/repost'
6
6
  import { BackgroundQueue } from '../../background'
7
7
  import { Database } from '../../db'
8
8
  import { DatabaseSchema, DatabaseSchemaType } from '../../db/database-schema'
9
+ import { Notification } from '../../db/tables/notification'
9
10
  import { countAll, excluded } from '../../db/util'
10
11
  import { RecordProcessor } from '../processor'
11
12
 
12
13
  const lexId = lex.ids.AppBskyFeedRepost
14
+ type Notif = Insertable<Notification>
13
15
  type IndexedRepost = Selectable<DatabaseSchemaType['repost']>
14
16
 
15
17
  const insertFn = async (
@@ -25,6 +27,8 @@ const insertFn = async (
25
27
  creator: uri.host,
26
28
  subject: obj.subject.uri,
27
29
  subjectCid: obj.subject.cid,
30
+ via: obj.via?.uri,
31
+ viaCid: obj.via?.cid,
28
32
  createdAt: normalizeDatetimeAlways(obj.createdAt),
29
33
  indexedAt: timestamp,
30
34
  }
@@ -72,20 +76,45 @@ const findDuplicate = async (
72
76
  const notifsForInsert = (obj: IndexedRepost) => {
73
77
  const subjectUri = new AtUri(obj.subject)
74
78
  // prevent self-notifications
75
- const isSelf = subjectUri.host === obj.creator
76
- return isSelf
77
- ? []
78
- : [
79
+ const isRepostFromSubjectUser = subjectUri.host === obj.creator
80
+ if (isRepostFromSubjectUser) {
81
+ return []
82
+ }
83
+
84
+ const notifs: Notif[] = [
85
+ // Notification to the author of the reposted record.
86
+ {
87
+ did: subjectUri.host,
88
+ author: obj.creator,
89
+ recordUri: obj.uri,
90
+ recordCid: obj.cid,
91
+ reason: 'repost' as const,
92
+ reasonSubject: subjectUri.toString(),
93
+ sortAt: obj.sortAt,
94
+ },
95
+ ]
96
+
97
+ if (obj.via) {
98
+ const viaUri = new AtUri(obj.via)
99
+ const isRepostFromViaSubjectUser = viaUri.host === obj.creator
100
+ // prevent self-notifications
101
+ if (!isRepostFromViaSubjectUser) {
102
+ notifs.push(
103
+ // Notification to the reposter via whose repost the repost was made.
79
104
  {
80
- did: subjectUri.host,
105
+ did: viaUri.host,
81
106
  author: obj.creator,
82
107
  recordUri: obj.uri,
83
108
  recordCid: obj.cid,
84
- reason: 'repost' as const,
85
- reasonSubject: subjectUri.toString(),
109
+ reason: 'repost-via-repost' as const,
110
+ reasonSubject: viaUri.toString(),
86
111
  sortAt: obj.sortAt,
87
112
  },
88
- ]
113
+ )
114
+ }
115
+ }
116
+
117
+ return notifs
89
118
  }
90
119
 
91
120
  const deleteFn = async (
@@ -6265,6 +6265,14 @@ export const schemaDict = {
6265
6265
  type: 'ref',
6266
6266
  ref: 'lex:app.bsky.actor.defs#profileViewBasic',
6267
6267
  },
6268
+ uri: {
6269
+ type: 'string',
6270
+ format: 'at-uri',
6271
+ },
6272
+ cid: {
6273
+ type: 'string',
6274
+ format: 'cid',
6275
+ },
6268
6276
  indexedAt: {
6269
6277
  type: 'string',
6270
6278
  format: 'datetime',
@@ -7576,6 +7584,10 @@ export const schemaDict = {
7576
7584
  type: 'string',
7577
7585
  format: 'datetime',
7578
7586
  },
7587
+ via: {
7588
+ type: 'ref',
7589
+ ref: 'lex:com.atproto.repo.strongRef',
7590
+ },
7579
7591
  },
7580
7592
  },
7581
7593
  },
@@ -7790,6 +7802,10 @@ export const schemaDict = {
7790
7802
  type: 'string',
7791
7803
  format: 'datetime',
7792
7804
  },
7805
+ via: {
7806
+ type: 'ref',
7807
+ ref: 'lex:com.atproto.repo.strongRef',
7808
+ },
7793
7809
  },
7794
7810
  },
7795
7811
  },
@@ -7802,7 +7818,7 @@ export const schemaDict = {
7802
7818
  main: {
7803
7819
  type: 'query',
7804
7820
  description:
7805
- 'Find posts matching search criteria, returning views of those posts.',
7821
+ 'Find posts matching search criteria, returning views of those posts. Note that this API endpoint may require authentication (eg, not public) for some service providers and implementations.',
7806
7822
  parameters: {
7807
7823
  type: 'params',
7808
7824
  required: ['q'],
@@ -9845,7 +9861,7 @@ export const schemaDict = {
9845
9861
  reason: {
9846
9862
  type: 'string',
9847
9863
  description:
9848
- "Expected values are 'like', 'repost', 'follow', 'mention', 'reply', 'quote', 'starterpack-joined', 'verified', and 'unverified'.",
9864
+ 'The reason why this notification was delivered - e.g. your post was liked, or you received a new follower.',
9849
9865
  knownValues: [
9850
9866
  'like',
9851
9867
  'repost',
@@ -9856,6 +9872,8 @@ export const schemaDict = {
9856
9872
  'starterpack-joined',
9857
9873
  'verified',
9858
9874
  'unverified',
9875
+ 'like-via-repost',
9876
+ 'repost-via-repost',
9859
9877
  ],
9860
9878
  },
9861
9879
  reasonSubject: {
@@ -142,6 +142,8 @@ export function validateReplyRef<V>(v: V) {
142
142
  export interface ReasonRepost {
143
143
  $type?: 'app.bsky.feed.defs#reasonRepost'
144
144
  by: AppBskyActorDefs.ProfileViewBasic
145
+ uri?: string
146
+ cid?: string
145
147
  indexedAt: string
146
148
  }
147
149
 
@@ -19,6 +19,7 @@ export interface Record {
19
19
  $type: 'app.bsky.feed.like'
20
20
  subject: ComAtprotoRepoStrongRef.Main
21
21
  createdAt: string
22
+ via?: ComAtprotoRepoStrongRef.Main
22
23
  [k: string]: unknown
23
24
  }
24
25
 
@@ -19,6 +19,7 @@ export interface Record {
19
19
  $type: 'app.bsky.feed.repost'
20
20
  subject: ComAtprotoRepoStrongRef.Main
21
21
  createdAt: string
22
+ via?: ComAtprotoRepoStrongRef.Main
22
23
  [k: string]: unknown
23
24
  }
24
25
 
@@ -67,7 +67,7 @@ export interface Notification {
67
67
  uri: string
68
68
  cid: string
69
69
  author: AppBskyActorDefs.ProfileView
70
- /** Expected values are 'like', 'repost', 'follow', 'mention', 'reply', 'quote', 'starterpack-joined', 'verified', and 'unverified'. */
70
+ /** The reason why this notification was delivered - e.g. your post was liked, or you received a new follower. */
71
71
  reason:
72
72
  | 'like'
73
73
  | 'repost'
@@ -78,6 +78,8 @@ export interface Notification {
78
78
  | 'starterpack-joined'
79
79
  | 'verified'
80
80
  | 'unverified'
81
+ | 'like-via-repost'
82
+ | 'repost-via-repost'
81
83
  | (string & {})
82
84
  reasonSubject?: string
83
85
  record: { [_ in string]: unknown }
@@ -868,7 +868,7 @@ export class Views {
868
868
  const repost = state.reposts?.get(item.repost.uri)
869
869
  if (!repost) return
870
870
  if (repost.record.subject.uri !== item.post.uri) return
871
- reason = this.reasonRepost(creatorFromUri(item.repost.uri), repost, state)
871
+ reason = this.reasonRepost(item.repost.uri, repost, state)
872
872
  if (!reason) return
873
873
  }
874
874
  const post = this.post(item.post.uri, state)
@@ -958,15 +958,18 @@ export class Views {
958
958
  }
959
959
 
960
960
  reasonRepost(
961
- creatorDid: string,
961
+ uri: string,
962
962
  repost: Repost,
963
963
  state: HydrationState,
964
964
  ): $Typed<ReasonRepost> | undefined {
965
+ const creatorDid = creatorFromUri(uri)
965
966
  const creator = this.profileBasic(creatorDid, state)
966
967
  if (!creator) return
967
968
  return {
968
969
  $type: 'app.bsky.feed.defs#reasonRepost',
969
970
  by: creator,
971
+ uri,
972
+ cid: repost.cid,
970
973
  indexedAt: this.indexedAt(repost).toISOString(),
971
974
  }
972
975
  }
@@ -1147,7 +1147,9 @@ Array [
1147
1147
  "muted": false,
1148
1148
  },
1149
1149
  },
1150
+ "cid": "cids(10)",
1150
1151
  "indexedAt": "1970-01-01T00:00:00.000Z",
1152
+ "uri": "record(13)",
1151
1153
  },
1152
1154
  "reqId": "req-id-abc-def-ghi",
1153
1155
  },
@@ -971,7 +971,9 @@ Array [
971
971
  "muted": false,
972
972
  },
973
973
  },
974
+ "cid": "cids(6)",
974
975
  "indexedAt": "1970-01-01T00:00:00.000Z",
976
+ "uri": "record(4)",
975
977
  },
976
978
  },
977
979
  Object {
@@ -985,7 +987,7 @@ Array [
985
987
  "muted": false,
986
988
  },
987
989
  },
988
- "cid": "cids(6)",
990
+ "cid": "cids(7)",
989
991
  "indexedAt": "1970-01-01T00:00:00.000Z",
990
992
  "labels": Array [],
991
993
  "likeCount": 0,
@@ -995,11 +997,11 @@ Array [
995
997
  "createdAt": "1970-01-01T00:00:00.000Z",
996
998
  "reply": Object {
997
999
  "parent": Object {
998
- "cid": "cids(7)",
1000
+ "cid": "cids(8)",
999
1001
  "uri": "record(6)",
1000
1002
  },
1001
1003
  "root": Object {
1002
- "cid": "cids(7)",
1004
+ "cid": "cids(8)",
1003
1005
  "uri": "record(6)",
1004
1006
  },
1005
1007
  },
@@ -1024,14 +1026,14 @@ Array [
1024
1026
  "handle": "alice.test",
1025
1027
  "labels": Array [
1026
1028
  Object {
1027
- "cid": "cids(8)",
1029
+ "cid": "cids(9)",
1028
1030
  "cts": "1970-01-01T00:00:00.000Z",
1029
1031
  "src": "user(1)",
1030
1032
  "uri": "record(9)",
1031
1033
  "val": "self-label-a",
1032
1034
  },
1033
1035
  Object {
1034
- "cid": "cids(8)",
1036
+ "cid": "cids(9)",
1035
1037
  "cts": "1970-01-01T00:00:00.000Z",
1036
1038
  "src": "user(1)",
1037
1039
  "uri": "record(9)",
@@ -1045,7 +1047,7 @@ Array [
1045
1047
  "muted": false,
1046
1048
  },
1047
1049
  },
1048
- "cid": "cids(7)",
1050
+ "cid": "cids(8)",
1049
1051
  "indexedAt": "1970-01-01T00:00:00.000Z",
1050
1052
  "labels": Array [],
1051
1053
  "likeCount": 3,
@@ -1074,14 +1076,14 @@ Array [
1074
1076
  "handle": "alice.test",
1075
1077
  "labels": Array [
1076
1078
  Object {
1077
- "cid": "cids(8)",
1079
+ "cid": "cids(9)",
1078
1080
  "cts": "1970-01-01T00:00:00.000Z",
1079
1081
  "src": "user(1)",
1080
1082
  "uri": "record(9)",
1081
1083
  "val": "self-label-a",
1082
1084
  },
1083
1085
  Object {
1084
- "cid": "cids(8)",
1086
+ "cid": "cids(9)",
1085
1087
  "cts": "1970-01-01T00:00:00.000Z",
1086
1088
  "src": "user(1)",
1087
1089
  "uri": "record(9)",
@@ -1095,7 +1097,7 @@ Array [
1095
1097
  "muted": false,
1096
1098
  },
1097
1099
  },
1098
- "cid": "cids(7)",
1100
+ "cid": "cids(8)",
1099
1101
  "indexedAt": "1970-01-01T00:00:00.000Z",
1100
1102
  "labels": Array [],
1101
1103
  "likeCount": 3,
@@ -1316,7 +1318,9 @@ Array [
1316
1318
  "muted": false,
1317
1319
  },
1318
1320
  },
1321
+ "cid": "cids(5)",
1319
1322
  "indexedAt": "1970-01-01T00:00:00.000Z",
1323
+ "uri": "record(5)",
1320
1324
  },
1321
1325
  "reply": Object {
1322
1326
  "grandparentAuthor": Object {
@@ -1368,8 +1372,8 @@ Array [
1368
1372
  "images": Array [
1369
1373
  Object {
1370
1374
  "alt": "../dev-env/assets/key-landscape-small.jpg",
1371
- "fullsize": "https://bsky.public.url/img/feed_fullsize/plain/user(4)/cids(5)@jpeg",
1372
- "thumb": "https://bsky.public.url/img/feed_thumbnail/plain/user(4)/cids(5)@jpeg",
1375
+ "fullsize": "https://bsky.public.url/img/feed_fullsize/plain/user(4)/cids(6)@jpeg",
1376
+ "thumb": "https://bsky.public.url/img/feed_thumbnail/plain/user(4)/cids(6)@jpeg",
1373
1377
  },
1374
1378
  ],
1375
1379
  },
@@ -1404,7 +1408,7 @@ Array [
1404
1408
  "$type": "blob",
1405
1409
  "mimeType": "image/jpeg",
1406
1410
  "ref": Object {
1407
- "$link": "cids(5)",
1411
+ "$link": "cids(6)",
1408
1412
  },
1409
1413
  "size": 4114,
1410
1414
  },
@@ -1549,7 +1553,9 @@ Array [
1549
1553
  "muted": false,
1550
1554
  },
1551
1555
  },
1556
+ "cid": "cids(7)",
1552
1557
  "indexedAt": "1970-01-01T00:00:00.000Z",
1558
+ "uri": "record(6)",
1553
1559
  },
1554
1560
  },
1555
1561
  Object {
@@ -1568,7 +1574,7 @@ Array [
1568
1574
  "muted": false,
1569
1575
  },
1570
1576
  },
1571
- "cid": "cids(6)",
1577
+ "cid": "cids(8)",
1572
1578
  "embed": Object {
1573
1579
  "$type": "app.bsky.embed.record#view",
1574
1580
  "record": Object {
@@ -1582,7 +1588,7 @@ Array [
1582
1588
  "muted": false,
1583
1589
  },
1584
1590
  },
1585
- "cid": "cids(7)",
1591
+ "cid": "cids(9)",
1586
1592
  "embeds": Array [
1587
1593
  Object {
1588
1594
  "$type": "app.bsky.embed.recordWithMedia#view",
@@ -1591,13 +1597,13 @@ Array [
1591
1597
  "images": Array [
1592
1598
  Object {
1593
1599
  "alt": "../dev-env/assets/key-landscape-small.jpg",
1594
- "fullsize": "https://bsky.public.url/img/feed_fullsize/plain/user(6)/cids(5)@jpeg",
1595
- "thumb": "https://bsky.public.url/img/feed_thumbnail/plain/user(6)/cids(5)@jpeg",
1600
+ "fullsize": "https://bsky.public.url/img/feed_fullsize/plain/user(6)/cids(6)@jpeg",
1601
+ "thumb": "https://bsky.public.url/img/feed_thumbnail/plain/user(6)/cids(6)@jpeg",
1596
1602
  },
1597
1603
  Object {
1598
1604
  "alt": "../dev-env/assets/key-alt.jpg",
1599
- "fullsize": "https://bsky.public.url/img/feed_fullsize/plain/user(6)/cids(8)@jpeg",
1600
- "thumb": "https://bsky.public.url/img/feed_thumbnail/plain/user(6)/cids(8)@jpeg",
1605
+ "fullsize": "https://bsky.public.url/img/feed_fullsize/plain/user(6)/cids(10)@jpeg",
1606
+ "thumb": "https://bsky.public.url/img/feed_thumbnail/plain/user(6)/cids(10)@jpeg",
1601
1607
  },
1602
1608
  ],
1603
1609
  },
@@ -1617,7 +1623,7 @@ Array [
1617
1623
  "muted": false,
1618
1624
  },
1619
1625
  },
1620
- "cid": "cids(9)",
1626
+ "cid": "cids(11)",
1621
1627
  "indexedAt": "1970-01-01T00:00:00.000Z",
1622
1628
  "labels": Array [],
1623
1629
  "likeCount": 0,
@@ -1659,7 +1665,7 @@ Array [
1659
1665
  "$type": "blob",
1660
1666
  "mimeType": "image/jpeg",
1661
1667
  "ref": Object {
1662
- "$link": "cids(5)",
1668
+ "$link": "cids(6)",
1663
1669
  },
1664
1670
  "size": 4114,
1665
1671
  },
@@ -1670,7 +1676,7 @@ Array [
1670
1676
  "$type": "blob",
1671
1677
  "mimeType": "image/jpeg",
1672
1678
  "ref": Object {
1673
- "$link": "cids(8)",
1679
+ "$link": "cids(10)",
1674
1680
  },
1675
1681
  "size": 12736,
1676
1682
  },
@@ -1679,7 +1685,7 @@ Array [
1679
1685
  },
1680
1686
  "record": Object {
1681
1687
  "record": Object {
1682
- "cid": "cids(9)",
1688
+ "cid": "cids(11)",
1683
1689
  "uri": "record(11)",
1684
1690
  },
1685
1691
  },
@@ -1698,7 +1704,7 @@ Array [
1698
1704
  "embed": Object {
1699
1705
  "$type": "app.bsky.embed.record",
1700
1706
  "record": Object {
1701
- "cid": "cids(7)",
1707
+ "cid": "cids(9)",
1702
1708
  "uri": "record(10)",
1703
1709
  },
1704
1710
  },
@@ -1743,7 +1749,7 @@ Array [
1743
1749
  "muted": false,
1744
1750
  },
1745
1751
  },
1746
- "cid": "cids(10)",
1752
+ "cid": "cids(12)",
1747
1753
  "indexedAt": "1970-01-01T00:00:00.000Z",
1748
1754
  "labels": Array [],
1749
1755
  "likeCount": 0,