@atproto/bsky 0.0.147 → 0.0.149

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 (148) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE.txt +1 -1
  3. package/dist/api/app/bsky/feed/getListFeed.js +1 -1
  4. package/dist/api/app/bsky/feed/getListFeed.js.map +1 -1
  5. package/dist/api/app/bsky/graph/getFollowers.js +1 -1
  6. package/dist/api/app/bsky/graph/getFollowers.js.map +1 -1
  7. package/dist/api/app/bsky/graph/getFollows.js +1 -1
  8. package/dist/api/app/bsky/graph/getFollows.js.map +1 -1
  9. package/dist/api/app/bsky/graph/getList.js +1 -1
  10. package/dist/api/app/bsky/graph/getList.js.map +1 -1
  11. package/dist/api/app/bsky/unspecced/getConfig.d.ts.map +1 -1
  12. package/dist/api/app/bsky/unspecced/getConfig.js +1 -0
  13. package/dist/api/app/bsky/unspecced/getConfig.js.map +1 -1
  14. package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js +1 -1
  15. package/dist/api/app/bsky/unspecced/getSuggestedStarterPacks.js.map +1 -1
  16. package/dist/api/app/bsky/unspecced/getSuggestedUsers.js +1 -1
  17. package/dist/api/app/bsky/unspecced/getSuggestedUsers.js.map +1 -1
  18. package/dist/api/app/bsky/unspecced/getTrends.js +1 -1
  19. package/dist/api/app/bsky/unspecced/getTrends.js.map +1 -1
  20. package/dist/api/com/atproto/identity/resolveHandle.d.ts.map +1 -1
  21. package/dist/api/com/atproto/identity/resolveHandle.js +3 -13
  22. package/dist/api/com/atproto/identity/resolveHandle.js.map +1 -1
  23. package/dist/api/health.js +1 -1
  24. package/dist/api/health.js.map +1 -1
  25. package/dist/api/well-known.d.ts.map +1 -1
  26. package/dist/api/well-known.js +4 -1
  27. package/dist/api/well-known.js.map +1 -1
  28. package/dist/config.d.ts +7 -0
  29. package/dist/config.d.ts.map +1 -1
  30. package/dist/config.js +28 -0
  31. package/dist/config.js.map +1 -1
  32. package/dist/data-plane/server/background.js +1 -1
  33. package/dist/data-plane/server/background.js.map +1 -1
  34. package/dist/data-plane/server/indexing/index.d.ts +2 -0
  35. package/dist/data-plane/server/indexing/index.d.ts.map +1 -1
  36. package/dist/data-plane/server/indexing/index.js +2 -0
  37. package/dist/data-plane/server/indexing/index.js.map +1 -1
  38. package/dist/data-plane/server/indexing/plugins/status.d.ts +7 -0
  39. package/dist/data-plane/server/indexing/plugins/status.d.ts.map +1 -0
  40. package/dist/data-plane/server/indexing/plugins/status.js +73 -0
  41. package/dist/data-plane/server/indexing/plugins/status.js.map +1 -0
  42. package/dist/data-plane/server/routes/index.d.ts.map +1 -1
  43. package/dist/data-plane/server/routes/index.js +0 -2
  44. package/dist/data-plane/server/routes/index.js.map +1 -1
  45. package/dist/data-plane/server/routes/profile.d.ts.map +1 -1
  46. package/dist/data-plane/server/routes/profile.js +8 -1
  47. package/dist/data-plane/server/routes/profile.js.map +1 -1
  48. package/dist/data-plane/server/routes/records.d.ts.map +1 -1
  49. package/dist/data-plane/server/routes/records.js +1 -0
  50. package/dist/data-plane/server/routes/records.js.map +1 -1
  51. package/dist/error.js +1 -1
  52. package/dist/error.js.map +1 -1
  53. package/dist/hydration/actor.d.ts +8 -1
  54. package/dist/hydration/actor.d.ts.map +1 -1
  55. package/dist/hydration/actor.js +18 -2
  56. package/dist/hydration/actor.js.map +1 -1
  57. package/dist/hydration/feed.d.ts +2 -2
  58. package/dist/hydration/feed.d.ts.map +1 -1
  59. package/dist/hydration/feed.js +10 -4
  60. package/dist/hydration/feed.js.map +1 -1
  61. package/dist/hydration/hydrator.d.ts +4 -3
  62. package/dist/hydration/hydrator.d.ts.map +1 -1
  63. package/dist/hydration/hydrator.js +47 -22
  64. package/dist/hydration/hydrator.js.map +1 -1
  65. package/dist/hydration/label.d.ts +1 -1
  66. package/dist/hydration/label.d.ts.map +1 -1
  67. package/dist/hydration/label.js +5 -2
  68. package/dist/hydration/label.js.map +1 -1
  69. package/dist/image/server.js +1 -1
  70. package/dist/image/server.js.map +1 -1
  71. package/dist/lexicon/index.d.ts +5 -2
  72. package/dist/lexicon/index.d.ts.map +1 -1
  73. package/dist/lexicon/index.js +8 -5
  74. package/dist/lexicon/index.js.map +1 -1
  75. package/dist/lexicon/lexicons.d.ts +288 -82
  76. package/dist/lexicon/lexicons.d.ts.map +1 -1
  77. package/dist/lexicon/lexicons.js +146 -42
  78. package/dist/lexicon/lexicons.js.map +1 -1
  79. package/dist/lexicon/types/app/bsky/actor/defs.d.ts +21 -0
  80. package/dist/lexicon/types/app/bsky/actor/defs.d.ts.map +1 -1
  81. package/dist/lexicon/types/app/bsky/actor/defs.js +9 -0
  82. package/dist/lexicon/types/app/bsky/actor/defs.js.map +1 -1
  83. package/dist/lexicon/types/app/bsky/actor/status.d.ts +23 -0
  84. package/dist/lexicon/types/app/bsky/actor/status.d.ts.map +1 -0
  85. package/dist/lexicon/types/app/bsky/actor/status.js +19 -0
  86. package/dist/lexicon/types/app/bsky/actor/status.js.map +1 -0
  87. package/dist/lexicon/types/app/bsky/unspecced/getConfig.d.ts +9 -0
  88. package/dist/lexicon/types/app/bsky/unspecced/getConfig.d.ts.map +1 -1
  89. package/dist/lexicon/types/app/bsky/unspecced/getConfig.js +9 -0
  90. package/dist/lexicon/types/app/bsky/unspecced/getConfig.js.map +1 -1
  91. package/dist/proto/bsky_connect.d.ts +10 -12
  92. package/dist/proto/bsky_connect.d.ts.map +1 -1
  93. package/dist/proto/bsky_connect.js +9 -11
  94. package/dist/proto/bsky_connect.js.map +1 -1
  95. package/dist/proto/bsky_pb.d.ts +58 -37
  96. package/dist/proto/bsky_pb.d.ts.map +1 -1
  97. package/dist/proto/bsky_pb.js +189 -115
  98. package/dist/proto/bsky_pb.js.map +1 -1
  99. package/dist/views/index.d.ts +2 -1
  100. package/dist/views/index.d.ts.map +1 -1
  101. package/dist/views/index.js +37 -10
  102. package/dist/views/index.js.map +1 -1
  103. package/package.json +13 -13
  104. package/proto/bsky.proto +16 -17
  105. package/src/api/app/bsky/feed/getListFeed.ts +1 -1
  106. package/src/api/app/bsky/graph/getFollowers.ts +4 -1
  107. package/src/api/app/bsky/graph/getFollows.ts +4 -1
  108. package/src/api/app/bsky/graph/getList.ts +1 -1
  109. package/src/api/app/bsky/unspecced/getConfig.ts +1 -0
  110. package/src/api/app/bsky/unspecced/getSuggestedStarterPacks.ts +1 -1
  111. package/src/api/app/bsky/unspecced/getSuggestedUsers.ts +1 -1
  112. package/src/api/app/bsky/unspecced/getTrends.ts +1 -1
  113. package/src/api/com/atproto/identity/resolveHandle.ts +3 -16
  114. package/src/api/health.ts +1 -1
  115. package/src/api/well-known.ts +4 -1
  116. package/src/config.ts +39 -0
  117. package/src/data-plane/server/background.ts +1 -1
  118. package/src/data-plane/server/indexing/index.ts +3 -0
  119. package/src/data-plane/server/indexing/plugins/status.ts +61 -0
  120. package/src/data-plane/server/routes/index.ts +0 -2
  121. package/src/data-plane/server/routes/profile.ts +43 -27
  122. package/src/data-plane/server/routes/records.ts +1 -0
  123. package/src/error.ts +1 -1
  124. package/src/hydration/actor.ts +27 -2
  125. package/src/hydration/feed.ts +16 -4
  126. package/src/hydration/hydrator.ts +64 -21
  127. package/src/hydration/label.ts +8 -2
  128. package/src/image/server.ts +1 -1
  129. package/src/lexicon/index.ts +12 -9
  130. package/src/lexicon/lexicons.ts +151 -43
  131. package/src/lexicon/types/app/bsky/actor/defs.ts +26 -0
  132. package/src/lexicon/types/app/bsky/actor/status.ts +40 -0
  133. package/src/lexicon/types/app/bsky/unspecced/getConfig.ts +17 -0
  134. package/src/proto/bsky_connect.ts +11 -13
  135. package/src/proto/bsky_pb.ts +173 -119
  136. package/src/views/index.ts +47 -11
  137. package/tests/views/__snapshots__/profile.test.ts.snap +60 -0
  138. package/tests/views/__snapshots__/thread.test.ts.snap +203 -11
  139. package/tests/views/get-config.test.ts +66 -0
  140. package/tests/views/profile.test.ts +189 -1
  141. package/tests/views/thread.test.ts +134 -2
  142. package/tsconfig.build.tsbuildinfo +1 -1
  143. package/tsconfig.tests.tsbuildinfo +1 -1
  144. package/dist/data-plane/server/routes/posts.d.ts +0 -6
  145. package/dist/data-plane/server/routes/posts.d.ts.map +0 -1
  146. package/dist/data-plane/server/routes/posts.js +0 -20
  147. package/dist/data-plane/server/routes/posts.js.map +0 -1
  148. package/src/data-plane/server/routes/posts.ts +0 -21
@@ -1,6 +1,6 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`pds thread views fetches ancestors 1`] = `
3
+ exports[`appview thread views fetches ancestors 1`] = `
4
4
  Object {
5
5
  "$type": "app.bsky.feed.defs#threadViewPost",
6
6
  "parent": Object {
@@ -210,7 +210,7 @@ Object {
210
210
  }
211
211
  `;
212
212
 
213
- exports[`pds thread views fetches deep post thread 1`] = `
213
+ exports[`appview thread views fetches deep post thread 1`] = `
214
214
  Object {
215
215
  "$type": "app.bsky.feed.defs#threadViewPost",
216
216
  "post": Object {
@@ -470,7 +470,7 @@ Object {
470
470
  }
471
471
  `;
472
472
 
473
- exports[`pds thread views fetches shallow post thread 1`] = `
473
+ exports[`appview thread views fetches shallow post thread 1`] = `
474
474
  Object {
475
475
  "$type": "app.bsky.feed.defs#threadViewPost",
476
476
  "post": Object {
@@ -661,7 +661,7 @@ Object {
661
661
  }
662
662
  `;
663
663
 
664
- exports[`pds thread views fetches thread with handle in uri 1`] = `
664
+ exports[`appview thread views fetches thread with handle in uri 1`] = `
665
665
  Object {
666
666
  "$type": "app.bsky.feed.defs#threadViewPost",
667
667
  "post": Object {
@@ -852,7 +852,7 @@ Object {
852
852
  }
853
853
  `;
854
854
 
855
- exports[`pds thread views handles deleted posts correctly 1`] = `
855
+ exports[`appview thread views handles deleted posts correctly 1`] = `
856
856
  Object {
857
857
  "$type": "app.bsky.feed.defs#threadViewPost",
858
858
  "post": Object {
@@ -1019,7 +1019,7 @@ Object {
1019
1019
  }
1020
1020
  `;
1021
1021
 
1022
- exports[`pds thread views handles deleted posts correctly 2`] = `
1022
+ exports[`appview thread views handles deleted posts correctly 2`] = `
1023
1023
  Object {
1024
1024
  "$type": "app.bsky.feed.defs#threadViewPost",
1025
1025
  "post": Object {
@@ -1075,7 +1075,7 @@ Object {
1075
1075
  }
1076
1076
  `;
1077
1077
 
1078
- exports[`pds thread views handles deleted posts correctly 3`] = `
1078
+ exports[`appview thread views handles deleted posts correctly 3`] = `
1079
1079
  Object {
1080
1080
  "$type": "app.bsky.feed.defs#threadViewPost",
1081
1081
  "parent": Object {
@@ -1146,7 +1146,199 @@ Object {
1146
1146
  }
1147
1147
  `;
1148
1148
 
1149
- exports[`pds thread views takedown blocks ancestors by actor 1`] = `
1149
+ exports[`appview thread views listblock doesn't apply listblock if list was taken down by private takedown 1`] = `
1150
+ Object {
1151
+ "$type": "app.bsky.feed.defs#blockedPost",
1152
+ "author": Object {
1153
+ "did": "user(0)",
1154
+ "viewer": Object {
1155
+ "blockedBy": true,
1156
+ },
1157
+ },
1158
+ "blocked": true,
1159
+ "uri": "record(0)",
1160
+ }
1161
+ `;
1162
+
1163
+ exports[`appview thread views listblock doesn't apply listblock if list was taken down by private takedown 2`] = `
1164
+ Object {
1165
+ "$type": "app.bsky.feed.defs#threadViewPost",
1166
+ "parent": Object {
1167
+ "$type": "app.bsky.feed.defs#threadViewPost",
1168
+ "post": Object {
1169
+ "author": Object {
1170
+ "did": "user(2)",
1171
+ "handle": "carol.test",
1172
+ "labels": Array [],
1173
+ "viewer": Object {
1174
+ "blockedBy": false,
1175
+ "muted": false,
1176
+ },
1177
+ },
1178
+ "cid": "cids(2)",
1179
+ "indexedAt": "1970-01-01T00:00:00.000Z",
1180
+ "labels": Array [],
1181
+ "likeCount": 0,
1182
+ "quoteCount": 0,
1183
+ "record": Object {
1184
+ "$type": "app.bsky.feed.post",
1185
+ "createdAt": "1970-01-01T00:00:00.000Z",
1186
+ "text": "I'm carol",
1187
+ },
1188
+ "replyCount": 1,
1189
+ "repostCount": 0,
1190
+ "uri": "record(2)",
1191
+ "viewer": Object {
1192
+ "embeddingDisabled": false,
1193
+ "threadMuted": false,
1194
+ },
1195
+ },
1196
+ "threadContext": Object {},
1197
+ },
1198
+ "post": Object {
1199
+ "author": Object {
1200
+ "avatar": "https://bsky.public.url/img/avatar/plain/user(1)/cids(1)@jpeg",
1201
+ "createdAt": "1970-01-01T00:00:00.000Z",
1202
+ "did": "user(0)",
1203
+ "displayName": "bobby",
1204
+ "handle": "bob.test",
1205
+ "labels": Array [],
1206
+ "viewer": Object {
1207
+ "blockedBy": false,
1208
+ "followedBy": "record(1)",
1209
+ "muted": false,
1210
+ },
1211
+ },
1212
+ "cid": "cids(0)",
1213
+ "indexedAt": "1970-01-01T00:00:00.000Z",
1214
+ "labels": Array [],
1215
+ "likeCount": 0,
1216
+ "quoteCount": 0,
1217
+ "record": Object {
1218
+ "$type": "app.bsky.feed.post",
1219
+ "createdAt": "1970-01-01T00:00:00.000Z",
1220
+ "reply": Object {
1221
+ "parent": Object {
1222
+ "cid": "cids(2)",
1223
+ "uri": "record(2)",
1224
+ },
1225
+ "root": Object {
1226
+ "cid": "cids(2)",
1227
+ "uri": "record(2)",
1228
+ },
1229
+ },
1230
+ "text": "hi carol",
1231
+ },
1232
+ "replyCount": 0,
1233
+ "repostCount": 0,
1234
+ "uri": "record(0)",
1235
+ "viewer": Object {
1236
+ "embeddingDisabled": false,
1237
+ "threadMuted": false,
1238
+ },
1239
+ },
1240
+ "replies": Array [],
1241
+ "threadContext": Object {},
1242
+ }
1243
+ `;
1244
+
1245
+ exports[`appview thread views listblock doesn't apply listblock if list was taken down by takedown label 1`] = `
1246
+ Object {
1247
+ "$type": "app.bsky.feed.defs#blockedPost",
1248
+ "author": Object {
1249
+ "did": "user(0)",
1250
+ "viewer": Object {
1251
+ "blockedBy": true,
1252
+ },
1253
+ },
1254
+ "blocked": true,
1255
+ "uri": "record(0)",
1256
+ }
1257
+ `;
1258
+
1259
+ exports[`appview thread views listblock doesn't apply listblock if list was taken down by takedown label 2`] = `
1260
+ Object {
1261
+ "$type": "app.bsky.feed.defs#threadViewPost",
1262
+ "parent": Object {
1263
+ "$type": "app.bsky.feed.defs#threadViewPost",
1264
+ "post": Object {
1265
+ "author": Object {
1266
+ "did": "user(2)",
1267
+ "handle": "carol.test",
1268
+ "labels": Array [],
1269
+ "viewer": Object {
1270
+ "blockedBy": false,
1271
+ "muted": false,
1272
+ },
1273
+ },
1274
+ "cid": "cids(2)",
1275
+ "indexedAt": "1970-01-01T00:00:00.000Z",
1276
+ "labels": Array [],
1277
+ "likeCount": 0,
1278
+ "quoteCount": 0,
1279
+ "record": Object {
1280
+ "$type": "app.bsky.feed.post",
1281
+ "createdAt": "1970-01-01T00:00:00.000Z",
1282
+ "text": "I'm carol",
1283
+ },
1284
+ "replyCount": 1,
1285
+ "repostCount": 0,
1286
+ "uri": "record(2)",
1287
+ "viewer": Object {
1288
+ "embeddingDisabled": false,
1289
+ "threadMuted": false,
1290
+ },
1291
+ },
1292
+ "threadContext": Object {},
1293
+ },
1294
+ "post": Object {
1295
+ "author": Object {
1296
+ "avatar": "https://bsky.public.url/img/avatar/plain/user(1)/cids(1)@jpeg",
1297
+ "createdAt": "1970-01-01T00:00:00.000Z",
1298
+ "did": "user(0)",
1299
+ "displayName": "bobby",
1300
+ "handle": "bob.test",
1301
+ "labels": Array [],
1302
+ "viewer": Object {
1303
+ "blockedBy": false,
1304
+ "followedBy": "record(1)",
1305
+ "muted": false,
1306
+ },
1307
+ },
1308
+ "cid": "cids(0)",
1309
+ "indexedAt": "1970-01-01T00:00:00.000Z",
1310
+ "labels": Array [],
1311
+ "likeCount": 0,
1312
+ "quoteCount": 0,
1313
+ "record": Object {
1314
+ "$type": "app.bsky.feed.post",
1315
+ "createdAt": "1970-01-01T00:00:00.000Z",
1316
+ "reply": Object {
1317
+ "parent": Object {
1318
+ "cid": "cids(2)",
1319
+ "uri": "record(2)",
1320
+ },
1321
+ "root": Object {
1322
+ "cid": "cids(2)",
1323
+ "uri": "record(2)",
1324
+ },
1325
+ },
1326
+ "text": "hi carol",
1327
+ },
1328
+ "replyCount": 0,
1329
+ "repostCount": 0,
1330
+ "uri": "record(0)",
1331
+ "viewer": Object {
1332
+ "embeddingDisabled": false,
1333
+ "threadMuted": false,
1334
+ },
1335
+ },
1336
+ "replies": Array [],
1337
+ "threadContext": Object {},
1338
+ }
1339
+ `;
1340
+
1341
+ exports[`appview thread views takedown blocks ancestors by actor 1`] = `
1150
1342
  Object {
1151
1343
  "$type": "app.bsky.feed.defs#threadViewPost",
1152
1344
  "parent": Object {
@@ -1220,7 +1412,7 @@ Object {
1220
1412
  }
1221
1413
  `;
1222
1414
 
1223
- exports[`pds thread views takedown blocks ancestors by record 1`] = `
1415
+ exports[`appview thread views takedown blocks ancestors by record 1`] = `
1224
1416
  Object {
1225
1417
  "$type": "app.bsky.feed.defs#threadViewPost",
1226
1418
  "parent": Object {
@@ -1294,7 +1486,7 @@ Object {
1294
1486
  }
1295
1487
  `;
1296
1488
 
1297
- exports[`pds thread views takedown blocks replies by actor 1`] = `
1489
+ exports[`appview thread views takedown blocks replies by actor 1`] = `
1298
1490
  Object {
1299
1491
  "$type": "app.bsky.feed.defs#threadViewPost",
1300
1492
  "post": Object {
@@ -1508,7 +1700,7 @@ Object {
1508
1700
  }
1509
1701
  `;
1510
1702
 
1511
- exports[`pds thread views takedown blocks replies by record 1`] = `
1703
+ exports[`appview thread views takedown blocks replies by record 1`] = `
1512
1704
  Object {
1513
1705
  "$type": "app.bsky.feed.defs#threadViewPost",
1514
1706
  "post": Object {
@@ -0,0 +1,66 @@
1
+ import AtpAgent from '@atproto/api'
2
+ import { TestNetwork } from '@atproto/dev-env'
3
+
4
+ describe('get config', () => {
5
+ describe('when live now is NOT configured', () => {
6
+ let network: TestNetwork
7
+ let agent: AtpAgent
8
+
9
+ beforeAll(async () => {
10
+ network = await TestNetwork.create({
11
+ dbPostgresSchema: 'bsky_tests_live_now_config_off',
12
+ })
13
+ agent = network.bsky.getClient()
14
+
15
+ await network.processAll()
16
+ })
17
+
18
+ afterAll(async () => {
19
+ await network.close()
20
+ })
21
+
22
+ it('omits the live now config', async () => {
23
+ const res = await agent.app.bsky.unspecced.getConfig()
24
+
25
+ expect(res.data).not.toHaveProperty('liveNow')
26
+ })
27
+ })
28
+
29
+ describe('when live now is configured', () => {
30
+ const liveNowConfig = [
31
+ {
32
+ did: 'did:plc:asdf123',
33
+ domains: ['example.com', 'atproto.com'],
34
+ },
35
+ {
36
+ did: 'did:plc:sdfg234',
37
+ domains: ['example.com'],
38
+ },
39
+ ]
40
+
41
+ let network: TestNetwork
42
+ let agent: AtpAgent
43
+
44
+ beforeAll(async () => {
45
+ network = await TestNetwork.create({
46
+ dbPostgresSchema: 'bsky_tests_live_now_config_on',
47
+ bsky: {
48
+ liveNowConfig,
49
+ },
50
+ })
51
+ agent = network.bsky.getClient()
52
+
53
+ await network.processAll()
54
+ })
55
+
56
+ afterAll(async () => {
57
+ await network.close()
58
+ })
59
+
60
+ it(`returns the config`, async () => {
61
+ const res = await agent.app.bsky.unspecced.getConfig()
62
+
63
+ expect(res.data.liveNow).toEqual(liveNowConfig)
64
+ })
65
+ })
66
+ })
@@ -1,5 +1,7 @@
1
+ import assert from 'node:assert'
1
2
  import fs from 'node:fs/promises'
2
- import { AtpAgent } from '@atproto/api'
3
+ import { AppBskyEmbedExternal, AtpAgent } from '@atproto/api'
4
+ import { HOUR, MINUTE } from '@atproto/common'
3
5
  import { SeedClient, TestNetwork, basicSeed } from '@atproto/dev-env'
4
6
  import { ids } from '../../src/lexicon/lexicons'
5
7
  import { forSnapshot, stripViewer } from '../_util'
@@ -225,6 +227,192 @@ describe('pds profile views', () => {
225
227
  })
226
228
  })
227
229
 
230
+ describe('status', () => {
231
+ const embed: AppBskyEmbedExternal.Main = {
232
+ $type: 'app.bsky.embed.external',
233
+ external: {
234
+ uri: 'https://example.com',
235
+ title: 'TestImage',
236
+ description: 'testLink',
237
+ },
238
+ }
239
+
240
+ it(`omits status if doesn't exist`, async () => {
241
+ const { data } = await agent.api.app.bsky.actor.getProfile(
242
+ { actor: alice },
243
+ {
244
+ headers: await network.serviceHeaders(
245
+ alice,
246
+ ids.AppBskyActorGetProfile,
247
+ ),
248
+ },
249
+ )
250
+ expect(data.status).toBeUndefined()
251
+ })
252
+
253
+ it('returns active status when within the duration', async () => {
254
+ await sc.agent.com.atproto.repo.createRecord(
255
+ {
256
+ repo: alice,
257
+ collection: ids.AppBskyActorStatus,
258
+ rkey: 'self',
259
+ record: {
260
+ status: 'app.bsky.actor.status#live',
261
+ embed,
262
+ durationMinutes: 10,
263
+ createdAt: new Date().toISOString(),
264
+ },
265
+ },
266
+ {
267
+ headers: sc.getHeaders(alice),
268
+ encoding: 'application/json',
269
+ },
270
+ )
271
+ await network.processAll()
272
+
273
+ const { data } = await agent.api.app.bsky.actor.getProfile(
274
+ { actor: alice },
275
+ {
276
+ headers: await network.serviceHeaders(
277
+ alice,
278
+ ids.AppBskyActorGetProfile,
279
+ ),
280
+ },
281
+ )
282
+ expect(forSnapshot(data.status)).toMatchSnapshot()
283
+ })
284
+
285
+ it('limits the minimum duration', async () => {
286
+ await sc.agent.com.atproto.repo.putRecord(
287
+ {
288
+ repo: alice,
289
+ collection: ids.AppBskyActorStatus,
290
+ rkey: 'self',
291
+ record: {
292
+ status: 'app.bsky.actor.status#live',
293
+ embed,
294
+ durationMinutes: 1,
295
+ createdAt: new Date().toISOString(),
296
+ },
297
+ },
298
+ {
299
+ headers: sc.getHeaders(alice),
300
+ encoding: 'application/json',
301
+ },
302
+ )
303
+ await network.processAll()
304
+
305
+ const { data } = await agent.api.app.bsky.actor.getProfile(
306
+ { actor: alice },
307
+ {
308
+ headers: await network.serviceHeaders(
309
+ alice,
310
+ ids.AppBskyActorGetProfile,
311
+ ),
312
+ },
313
+ )
314
+
315
+ assert(data.status)
316
+ const createdAt = new Date(data.status.record.createdAt as string)
317
+ const expiresAt = new Date(data.status.expiresAt as string)
318
+ expect(expiresAt.getTime() - createdAt.getTime()).toBe(5 * MINUTE)
319
+ })
320
+
321
+ it('limits the maximum duration', async () => {
322
+ await sc.agent.com.atproto.repo.putRecord(
323
+ {
324
+ repo: alice,
325
+ collection: ids.AppBskyActorStatus,
326
+ rkey: 'self',
327
+ record: {
328
+ status: 'app.bsky.actor.status#live',
329
+ embed,
330
+ durationMinutes: 1_440, // 1 day in minutes
331
+ createdAt: new Date().toISOString(),
332
+ },
333
+ },
334
+ {
335
+ headers: sc.getHeaders(alice),
336
+ encoding: 'application/json',
337
+ },
338
+ )
339
+ await network.processAll()
340
+
341
+ const { data } = await agent.api.app.bsky.actor.getProfile(
342
+ { actor: alice },
343
+ {
344
+ headers: await network.serviceHeaders(
345
+ alice,
346
+ ids.AppBskyActorGetProfile,
347
+ ),
348
+ },
349
+ )
350
+
351
+ assert(data.status)
352
+ const createdAt = new Date(data.status.record.createdAt as string)
353
+ const expiresAt = new Date(data.status.expiresAt as string)
354
+ expect(expiresAt.getTime() - createdAt.getTime()).toBe(4 * HOUR)
355
+ })
356
+
357
+ describe('when outside the duration', () => {
358
+ const now = '2021-01-01T01:00:00.000Z'
359
+ const nowPlus15M = '2021-01-01T01:15:00.000Z'
360
+
361
+ beforeAll(() => {
362
+ jest.useFakeTimers({
363
+ doNotFake: [
364
+ 'nextTick',
365
+ 'performance',
366
+ 'setImmediate',
367
+ 'setInterval',
368
+ 'setTimeout',
369
+ ],
370
+ })
371
+ jest.setSystemTime(new Date(now))
372
+ })
373
+
374
+ afterAll(async () => {
375
+ jest.useRealTimers()
376
+ })
377
+
378
+ it('returns inactive status', async () => {
379
+ await sc.agent.com.atproto.repo.putRecord(
380
+ {
381
+ repo: alice,
382
+ collection: ids.AppBskyActorStatus,
383
+ rkey: 'self',
384
+ record: {
385
+ status: 'app.bsky.actor.status#live',
386
+ embed,
387
+ durationMinutes: 10,
388
+ createdAt: new Date().toISOString(),
389
+ },
390
+ },
391
+ {
392
+ headers: sc.getHeaders(alice),
393
+ encoding: 'application/json',
394
+ },
395
+ )
396
+ await network.processAll()
397
+
398
+ jest.setSystemTime(new Date(nowPlus15M))
399
+
400
+ const { data } = await agent.api.app.bsky.actor.getProfile(
401
+ { actor: alice },
402
+ {
403
+ headers: await network.serviceHeaders(
404
+ alice,
405
+ ids.AppBskyActorGetProfile,
406
+ ),
407
+ },
408
+ )
409
+
410
+ // Doesn't need `forSnapshot` because the dates are already mocked.
411
+ expect(data.status).toMatchSnapshot()
412
+ })
413
+ })
414
+ })
415
+
228
416
  async function updateProfile(did: string, record: Record<string, unknown>) {
229
417
  return await pdsAgent.api.com.atproto.repo.putRecord(
230
418
  {