@atproto/pds 0.5.12 → 0.5.15

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 (326) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/api/app/bsky/notification/index.d.ts.map +1 -1
  3. package/dist/api/app/bsky/notification/index.js +2 -0
  4. package/dist/api/app/bsky/notification/index.js.map +1 -1
  5. package/dist/api/app/bsky/notification/unregisterPush.d.ts +4 -0
  6. package/dist/api/app/bsky/notification/unregisterPush.d.ts.map +1 -0
  7. package/dist/api/app/bsky/notification/unregisterPush.js +48 -0
  8. package/dist/api/app/bsky/notification/unregisterPush.js.map +1 -0
  9. package/dist/lexicons/app/bsky/actor/defs.defs.d.ts +6 -0
  10. package/dist/lexicons/app/bsky/actor/defs.defs.d.ts.map +1 -1
  11. package/dist/lexicons/app/bsky/actor/defs.defs.js +1 -0
  12. package/dist/lexicons/app/bsky/actor/defs.defs.js.map +1 -1
  13. package/package.json +42 -38
  14. package/build.templates.cjs +0 -22
  15. package/example.env +0 -42
  16. package/jest.config.cjs +0 -27
  17. package/src/account-manager/account-manager.ts +0 -916
  18. package/src/account-manager/db/index.ts +0 -21
  19. package/src/account-manager/db/migrations/001-init.ts +0 -115
  20. package/src/account-manager/db/migrations/002-account-deactivation.ts +0 -17
  21. package/src/account-manager/db/migrations/003-privileged-app-passwords.ts +0 -12
  22. package/src/account-manager/db/migrations/004-oauth.ts +0 -122
  23. package/src/account-manager/db/migrations/005-oauth-account-management.ts +0 -136
  24. package/src/account-manager/db/migrations/006-oauth-permission-sets.ts +0 -20
  25. package/src/account-manager/db/migrations/007-lexicon-failures-index.ts +0 -14
  26. package/src/account-manager/db/migrations/index.ts +0 -17
  27. package/src/account-manager/db/schema/account-device.ts +0 -14
  28. package/src/account-manager/db/schema/account.ts +0 -16
  29. package/src/account-manager/db/schema/actor.ts +0 -17
  30. package/src/account-manager/db/schema/app-password.ts +0 -13
  31. package/src/account-manager/db/schema/authorization-request.ts +0 -30
  32. package/src/account-manager/db/schema/authorized-client.ts +0 -23
  33. package/src/account-manager/db/schema/device.ts +0 -18
  34. package/src/account-manager/db/schema/email-token.ts +0 -19
  35. package/src/account-manager/db/schema/index.ts +0 -43
  36. package/src/account-manager/db/schema/invite-code.ts +0 -24
  37. package/src/account-manager/db/schema/lexicon.ts +0 -15
  38. package/src/account-manager/db/schema/refresh-token.ts +0 -11
  39. package/src/account-manager/db/schema/repo-root.ts +0 -12
  40. package/src/account-manager/db/schema/token.ts +0 -38
  41. package/src/account-manager/db/schema/used-refresh-token.ts +0 -13
  42. package/src/account-manager/helpers/account-device.ts +0 -63
  43. package/src/account-manager/helpers/account.ts +0 -355
  44. package/src/account-manager/helpers/auth.ts +0 -222
  45. package/src/account-manager/helpers/authorization-request.ts +0 -90
  46. package/src/account-manager/helpers/authorized-client.ts +0 -75
  47. package/src/account-manager/helpers/device.ts +0 -47
  48. package/src/account-manager/helpers/email-token.ts +0 -87
  49. package/src/account-manager/helpers/invite.ts +0 -263
  50. package/src/account-manager/helpers/lexicon.ts +0 -67
  51. package/src/account-manager/helpers/password.ts +0 -136
  52. package/src/account-manager/helpers/repo.ts +0 -24
  53. package/src/account-manager/helpers/scrypt.ts +0 -53
  54. package/src/account-manager/helpers/token.ts +0 -158
  55. package/src/account-manager/helpers/used-refresh-token.ts +0 -30
  56. package/src/account-manager/oauth-store.ts +0 -880
  57. package/src/account-manager/scope-reference-getter.ts +0 -106
  58. package/src/actor-store/actor-store-reader.ts +0 -45
  59. package/src/actor-store/actor-store-resources.ts +0 -8
  60. package/src/actor-store/actor-store-transactor.ts +0 -31
  61. package/src/actor-store/actor-store-writer.ts +0 -17
  62. package/src/actor-store/actor-store.ts +0 -210
  63. package/src/actor-store/blob/reader.ts +0 -160
  64. package/src/actor-store/blob/transactor.ts +0 -383
  65. package/src/actor-store/db/index.ts +0 -20
  66. package/src/actor-store/db/migrations/001-init.ts +0 -105
  67. package/src/actor-store/db/migrations/index.ts +0 -5
  68. package/src/actor-store/db/schema/account-pref.ts +0 -11
  69. package/src/actor-store/db/schema/backlink.ts +0 -9
  70. package/src/actor-store/db/schema/blob.ts +0 -14
  71. package/src/actor-store/db/schema/index.ts +0 -23
  72. package/src/actor-store/db/schema/record-blob.ts +0 -8
  73. package/src/actor-store/db/schema/record.ts +0 -14
  74. package/src/actor-store/db/schema/repo-block.ts +0 -10
  75. package/src/actor-store/db/schema/repo-root.ts +0 -10
  76. package/src/actor-store/migrate.ts +0 -39
  77. package/src/actor-store/preference/reader.ts +0 -48
  78. package/src/actor-store/preference/transactor.ts +0 -55
  79. package/src/actor-store/preference/util.ts +0 -39
  80. package/src/actor-store/record/reader.ts +0 -374
  81. package/src/actor-store/record/transactor.ts +0 -111
  82. package/src/actor-store/repo/reader.ts +0 -31
  83. package/src/actor-store/repo/sql-repo-reader.ts +0 -150
  84. package/src/actor-store/repo/sql-repo-transactor.ts +0 -105
  85. package/src/actor-store/repo/transactor.ts +0 -227
  86. package/src/api/app/bsky/actor/getPreferences.ts +0 -57
  87. package/src/api/app/bsky/actor/getProfile.ts +0 -41
  88. package/src/api/app/bsky/actor/getProfiles.ts +0 -51
  89. package/src/api/app/bsky/actor/index.ts +0 -13
  90. package/src/api/app/bsky/actor/putPreferences.ts +0 -62
  91. package/src/api/app/bsky/feed/getActorLikes.ts +0 -63
  92. package/src/api/app/bsky/feed/getAuthorFeed.ts +0 -84
  93. package/src/api/app/bsky/feed/getFeed.ts +0 -47
  94. package/src/api/app/bsky/feed/getPostThread.ts +0 -251
  95. package/src/api/app/bsky/feed/getTimeline.ts +0 -50
  96. package/src/api/app/bsky/feed/index.ts +0 -15
  97. package/src/api/app/bsky/index.ts +0 -11
  98. package/src/api/app/bsky/notification/index.ts +0 -7
  99. package/src/api/app/bsky/notification/registerPush.ts +0 -71
  100. package/src/api/app/bsky/util/resolver.ts +0 -20
  101. package/src/api/com/atproto/admin/deleteAccount.ts +0 -22
  102. package/src/api/com/atproto/admin/disableAccountInvites.ts +0 -18
  103. package/src/api/com/atproto/admin/disableInviteCodes.ts +0 -21
  104. package/src/api/com/atproto/admin/enableAccountInvites.ts +0 -18
  105. package/src/api/com/atproto/admin/getAccountInfo.ts +0 -32
  106. package/src/api/com/atproto/admin/getAccountInfos.ts +0 -34
  107. package/src/api/com/atproto/admin/getInviteCodes.ts +0 -126
  108. package/src/api/com/atproto/admin/getSubjectStatus.ts +0 -76
  109. package/src/api/com/atproto/admin/index.ts +0 -31
  110. package/src/api/com/atproto/admin/sendEmail.ts +0 -47
  111. package/src/api/com/atproto/admin/updateAccountEmail.ts +0 -32
  112. package/src/api/com/atproto/admin/updateAccountHandle.ts +0 -47
  113. package/src/api/com/atproto/admin/updateAccountPassword.ts +0 -34
  114. package/src/api/com/atproto/admin/updateSubjectStatus.ts +0 -68
  115. package/src/api/com/atproto/admin/util.ts +0 -66
  116. package/src/api/com/atproto/identity/getRecommendedDidCredentials.ts +0 -50
  117. package/src/api/com/atproto/identity/index.ts +0 -17
  118. package/src/api/com/atproto/identity/requestPlcOperationSignature.ts +0 -59
  119. package/src/api/com/atproto/identity/resolveHandle.ts +0 -50
  120. package/src/api/com/atproto/identity/signPlcOperation.ts +0 -85
  121. package/src/api/com/atproto/identity/submitPlcOperation.ts +0 -65
  122. package/src/api/com/atproto/identity/updateHandle.ts +0 -66
  123. package/src/api/com/atproto/index.ts +0 -19
  124. package/src/api/com/atproto/moderation/createReport.ts +0 -41
  125. package/src/api/com/atproto/moderation/index.ts +0 -7
  126. package/src/api/com/atproto/repo/applyWrites.ts +0 -226
  127. package/src/api/com/atproto/repo/createRecord.ts +0 -143
  128. package/src/api/com/atproto/repo/deleteRecord.ts +0 -122
  129. package/src/api/com/atproto/repo/describeRepo.ts +0 -43
  130. package/src/api/com/atproto/repo/getRecord.ts +0 -40
  131. package/src/api/com/atproto/repo/importRepo.ts +0 -101
  132. package/src/api/com/atproto/repo/index.ts +0 -25
  133. package/src/api/com/atproto/repo/listMissingBlobs.ts +0 -29
  134. package/src/api/com/atproto/repo/listRecords.ts +0 -36
  135. package/src/api/com/atproto/repo/putRecord.ts +0 -211
  136. package/src/api/com/atproto/repo/uploadBlob.ts +0 -60
  137. package/src/api/com/atproto/server/activateAccount.ts +0 -37
  138. package/src/api/com/atproto/server/checkAccountStatus.ts +0 -51
  139. package/src/api/com/atproto/server/confirmEmail.ts +0 -39
  140. package/src/api/com/atproto/server/createAccount.ts +0 -327
  141. package/src/api/com/atproto/server/createAppPassword.ts +0 -53
  142. package/src/api/com/atproto/server/createInviteCode.ts +0 -38
  143. package/src/api/com/atproto/server/createInviteCodes.ts +0 -42
  144. package/src/api/com/atproto/server/createSession.ts +0 -97
  145. package/src/api/com/atproto/server/deactivateAccount.ts +0 -41
  146. package/src/api/com/atproto/server/deleteAccount.ts +0 -85
  147. package/src/api/com/atproto/server/deleteSession.ts +0 -23
  148. package/src/api/com/atproto/server/describeServer.ts +0 -29
  149. package/src/api/com/atproto/server/getAccountInviteCodes.ts +0 -142
  150. package/src/api/com/atproto/server/getServiceAuth.ts +0 -111
  151. package/src/api/com/atproto/server/getSession.ts +0 -80
  152. package/src/api/com/atproto/server/index.ts +0 -55
  153. package/src/api/com/atproto/server/listAppPasswords.ts +0 -45
  154. package/src/api/com/atproto/server/refreshSession.ts +0 -72
  155. package/src/api/com/atproto/server/requestAccountDelete.ts +0 -66
  156. package/src/api/com/atproto/server/requestEmailConfirmation.ts +0 -68
  157. package/src/api/com/atproto/server/requestEmailUpdate.ts +0 -86
  158. package/src/api/com/atproto/server/requestPasswordReset.ts +0 -52
  159. package/src/api/com/atproto/server/reserveSigningKey.ts +0 -15
  160. package/src/api/com/atproto/server/resetPassword.ts +0 -50
  161. package/src/api/com/atproto/server/revokeAppPassword.ts +0 -42
  162. package/src/api/com/atproto/server/updateEmail.ts +0 -52
  163. package/src/api/com/atproto/server/util.ts +0 -136
  164. package/src/api/com/atproto/sync/deprecated/getCheckout.ts +0 -27
  165. package/src/api/com/atproto/sync/deprecated/getHead.ts +0 -33
  166. package/src/api/com/atproto/sync/getBlob.ts +0 -61
  167. package/src/api/com/atproto/sync/getBlocks.ts +0 -37
  168. package/src/api/com/atproto/sync/getLatestCommit.ts +0 -33
  169. package/src/api/com/atproto/sync/getRecord.ts +0 -49
  170. package/src/api/com/atproto/sync/getRepo.ts +0 -75
  171. package/src/api/com/atproto/sync/getRepoStatus.ts +0 -34
  172. package/src/api/com/atproto/sync/index.ts +0 -27
  173. package/src/api/com/atproto/sync/listBlobs.ts +0 -33
  174. package/src/api/com/atproto/sync/listRepos.ts +0 -74
  175. package/src/api/com/atproto/sync/subscribeRepos.ts +0 -73
  176. package/src/api/com/atproto/sync/util.ts +0 -37
  177. package/src/api/com/atproto/temp/checkSignupQueue.ts +0 -34
  178. package/src/api/com/atproto/temp/index.ts +0 -7
  179. package/src/api/index.ts +0 -10
  180. package/src/api/proxy.ts +0 -44
  181. package/src/app-view.ts +0 -24
  182. package/src/auth-output.ts +0 -52
  183. package/src/auth-routes.ts +0 -64
  184. package/src/auth-scope.ts +0 -40
  185. package/src/auth-verifier.ts +0 -668
  186. package/src/background.ts +0 -65
  187. package/src/basic-routes.ts +0 -52
  188. package/src/bsky-app-view.ts +0 -33
  189. package/src/config/config.ts +0 -553
  190. package/src/config/env.ts +0 -167
  191. package/src/config/index.ts +0 -3
  192. package/src/config/secrets.ts +0 -54
  193. package/src/context.ts +0 -523
  194. package/src/crawlers.ts +0 -46
  195. package/src/db/cast.ts +0 -52
  196. package/src/db/db.ts +0 -140
  197. package/src/db/index.ts +0 -4
  198. package/src/db/migrator.ts +0 -40
  199. package/src/db/pagination.ts +0 -132
  200. package/src/db/tables/moderation.ts +0 -80
  201. package/src/db/util.ts +0 -108
  202. package/src/did-cache/db/index.ts +0 -21
  203. package/src/did-cache/db/migrations.ts +0 -17
  204. package/src/did-cache/db/schema.ts +0 -9
  205. package/src/did-cache/index.ts +0 -131
  206. package/src/disk-blobstore.ts +0 -172
  207. package/src/error.ts +0 -19
  208. package/src/handle/explicit-slurs.ts +0 -22
  209. package/src/handle/index.ts +0 -49
  210. package/src/handle/reserved.ts +0 -1059
  211. package/src/image/image-url-builder.ts +0 -16
  212. package/src/index.ts +0 -189
  213. package/src/lexicons.ts +0 -4
  214. package/src/logger.ts +0 -35
  215. package/src/mailer/index.ts +0 -111
  216. package/src/mailer/moderation.ts +0 -33
  217. package/src/mailer/templates/confirm-email.d.ts +0 -4
  218. package/src/mailer/templates/confirm-email.hbs +0 -158
  219. package/src/mailer/templates/delete-account.d.ts +0 -4
  220. package/src/mailer/templates/delete-account.hbs +0 -156
  221. package/src/mailer/templates/plc-operation.d.ts +0 -4
  222. package/src/mailer/templates/plc-operation.hbs +0 -153
  223. package/src/mailer/templates/reset-password.d.ts +0 -4
  224. package/src/mailer/templates/reset-password.hbs +0 -154
  225. package/src/mailer/templates/update-email.d.ts +0 -4
  226. package/src/mailer/templates/update-email.hbs +0 -153
  227. package/src/mailer/templates.ts +0 -17
  228. package/src/pipethrough.ts +0 -716
  229. package/src/rate-limits.ts +0 -59
  230. package/src/read-after-write/index.ts +0 -3
  231. package/src/read-after-write/types.ts +0 -35
  232. package/src/read-after-write/util.ts +0 -101
  233. package/src/read-after-write/viewer.ts +0 -290
  234. package/src/redis.ts +0 -25
  235. package/src/repo/index.ts +0 -2
  236. package/src/repo/prepare.ts +0 -266
  237. package/src/repo/types.ts +0 -65
  238. package/src/scripts/README.md +0 -40
  239. package/src/scripts/index.ts +0 -20
  240. package/src/scripts/publish-identity.ts +0 -60
  241. package/src/scripts/rebuild-repo.ts +0 -119
  242. package/src/scripts/rotate-keys.ts +0 -146
  243. package/src/scripts/sequencer-recovery/index.ts +0 -23
  244. package/src/scripts/sequencer-recovery/recoverer.ts +0 -297
  245. package/src/scripts/sequencer-recovery/recovery-db.ts +0 -65
  246. package/src/scripts/sequencer-recovery/repair-repos.ts +0 -49
  247. package/src/scripts/sequencer-recovery/user-queues.ts +0 -44
  248. package/src/scripts/util.ts +0 -7
  249. package/src/sequencer/db/index.ts +0 -21
  250. package/src/sequencer/db/migrations/001-init.ts +0 -35
  251. package/src/sequencer/db/migrations/index.ts +0 -5
  252. package/src/sequencer/db/schema.ts +0 -19
  253. package/src/sequencer/events.ts +0 -199
  254. package/src/sequencer/index.ts +0 -3
  255. package/src/sequencer/outbox.ts +0 -123
  256. package/src/sequencer/sequencer.ts +0 -290
  257. package/src/util/compression.ts +0 -16
  258. package/src/util/debug.ts +0 -10
  259. package/src/util/http.ts +0 -31
  260. package/src/util/types.ts +0 -7
  261. package/src/well-known.ts +0 -30
  262. package/test.env +0 -2
  263. package/tests/__snapshots__/takedown-appeal.test.ts.snap +0 -43
  264. package/tests/_oauth_client_assets_middleware.ts +0 -23
  265. package/tests/_puppeteer.ts +0 -147
  266. package/tests/_types.d.ts +0 -16
  267. package/tests/_util.ts +0 -191
  268. package/tests/account-deactivation.test.ts +0 -204
  269. package/tests/account-deletion.test.ts +0 -300
  270. package/tests/account-manager.test.ts +0 -462
  271. package/tests/account-migration.test.ts +0 -221
  272. package/tests/account-status.test.ts +0 -206
  273. package/tests/account.test.ts +0 -595
  274. package/tests/app-passwords.test.ts +0 -262
  275. package/tests/auth.test.ts +0 -405
  276. package/tests/blob-deletes.test.ts +0 -204
  277. package/tests/create-post.test.ts +0 -79
  278. package/tests/crud.test.ts +0 -1595
  279. package/tests/db.test.ts +0 -170
  280. package/tests/email-confirmation.test.ts +0 -227
  281. package/tests/entryway-mock.ts +0 -323
  282. package/tests/entryway.test.ts +0 -145
  283. package/tests/file-uploads.test.ts +0 -301
  284. package/tests/get-service-auth.test.ts +0 -81
  285. package/tests/handle-validation.test.ts +0 -56
  286. package/tests/handles.test.ts +0 -274
  287. package/tests/invite-codes.test.ts +0 -367
  288. package/tests/invites-admin.test.ts +0 -252
  289. package/tests/moderation.test.ts +0 -280
  290. package/tests/moderator-auth.test.ts +0 -177
  291. package/tests/oauth.test.ts +0 -334
  292. package/tests/plc-operations.test.ts +0 -239
  293. package/tests/preferences.test.ts +0 -352
  294. package/tests/proxied/__snapshots__/admin.test.ts.snap +0 -516
  295. package/tests/proxied/__snapshots__/feedgen.test.ts.snap +0 -215
  296. package/tests/proxied/__snapshots__/views.test.ts.snap +0 -4456
  297. package/tests/proxied/admin.test.ts +0 -340
  298. package/tests/proxied/feedgen.test.ts +0 -66
  299. package/tests/proxied/notif.test.ts +0 -85
  300. package/tests/proxied/procedures.test.ts +0 -175
  301. package/tests/proxied/proxy-catchall.test.ts +0 -256
  302. package/tests/proxied/proxy-header.test.ts +0 -239
  303. package/tests/proxied/proxy-oauth-aud.test.ts +0 -182
  304. package/tests/proxied/read-after-write.test.ts +0 -382
  305. package/tests/proxied/views.test.ts +0 -608
  306. package/tests/races.test.ts +0 -89
  307. package/tests/rate-limits.test.ts +0 -70
  308. package/tests/recovery.test.ts +0 -180
  309. package/tests/seeds/basic.ts +0 -165
  310. package/tests/seeds/follows.ts +0 -57
  311. package/tests/seeds/likes.ts +0 -14
  312. package/tests/seeds/reposts.ts +0 -18
  313. package/tests/seeds/thread.ts +0 -40
  314. package/tests/seeds/users-bulk.ts +0 -246
  315. package/tests/seeds/users.ts +0 -67
  316. package/tests/sequencer.test.ts +0 -251
  317. package/tests/server.test.ts +0 -151
  318. package/tests/sync/invertible-ops.test.ts +0 -99
  319. package/tests/sync/list.test.ts +0 -43
  320. package/tests/sync/subscribe-repos.test.ts +0 -672
  321. package/tests/sync/sync.test.ts +0 -316
  322. package/tests/takedown-appeal.test.ts +0 -166
  323. package/tsconfig.build.json +0 -9
  324. package/tsconfig.build.tsbuildinfo +0 -1
  325. package/tsconfig.json +0 -7
  326. package/tsconfig.tests.json +0 -8
@@ -1,150 +0,0 @@
1
- import { sql } from 'kysely'
2
- import { chunkArray } from '@atproto/common'
3
- import { Cid, parseCid } from '@atproto/lex-data'
4
- import {
5
- BlockMap,
6
- CarBlock,
7
- CidSet,
8
- ReadableBlockstore,
9
- writeCarStream,
10
- } from '@atproto/repo'
11
- import { countAll } from '../../db/index.js'
12
- import { ActorDb } from '../db/index.js'
13
-
14
- export class SqlRepoReader extends ReadableBlockstore {
15
- cache: BlockMap = new BlockMap()
16
-
17
- constructor(public db: ActorDb) {
18
- super()
19
- }
20
-
21
- async getRoot(): Promise<Cid> {
22
- const root = await this.getRootDetailed()
23
- return root.cid
24
- }
25
-
26
- async getRootDetailed(): Promise<{ cid: Cid; rev: string }> {
27
- const res = await this.db.db
28
- .selectFrom('repo_root')
29
- .select(['cid', 'rev'])
30
- .limit(1)
31
- .executeTakeFirstOrThrow()
32
- return {
33
- cid: parseCid(res.cid),
34
- rev: res.rev,
35
- }
36
- }
37
-
38
- async getBytes(cid: Cid): Promise<Uint8Array | null> {
39
- const cached = this.cache.get(cid)
40
- if (cached) return cached
41
- const found = await this.db.db
42
- .selectFrom('repo_block')
43
- .where('repo_block.cid', '=', cid.toString())
44
- .select('content')
45
- .executeTakeFirst()
46
- if (!found) return null
47
- this.cache.set(cid, found.content)
48
- return found.content
49
- }
50
-
51
- async has(cid: Cid): Promise<boolean> {
52
- const got = await this.getBytes(cid)
53
- return !!got
54
- }
55
-
56
- async getBlocks(cids: Cid[]): Promise<{ blocks: BlockMap; missing: Cid[] }> {
57
- const cached = this.cache.getMany(cids)
58
- if (cached.missing.length < 1) return cached
59
- const missing = new CidSet(cached.missing)
60
- const missingStr = cached.missing.map((c) => c.toString())
61
- const blocks = new BlockMap()
62
- for (const batch of chunkArray(missingStr, 500)) {
63
- const res = await this.db.db
64
- .selectFrom('repo_block')
65
- .where('repo_block.cid', 'in', batch)
66
- .select(['repo_block.cid as cid', 'repo_block.content as content'])
67
- .execute()
68
- for (const row of res) {
69
- const cid = parseCid(row.cid)
70
- blocks.set(cid, row.content)
71
- missing.delete(cid)
72
- }
73
- }
74
- this.cache.addMap(blocks)
75
- blocks.addMap(cached.blocks)
76
- return { blocks, missing: missing.toList() }
77
- }
78
-
79
- async getCarStream(since?: string) {
80
- const root = await this.getRoot()
81
- if (!root) {
82
- throw new RepoRootNotFoundError()
83
- }
84
- return writeCarStream(root, this.iterateCarBlocks(since))
85
- }
86
-
87
- async *iterateCarBlocks(since?: string): AsyncIterable<CarBlock> {
88
- let cursor: RevCursor | undefined = undefined
89
- // allow us to write to car while fetching the next page
90
- do {
91
- const res = await this.getBlockRange(since, cursor)
92
- for (const row of res) {
93
- yield {
94
- cid: parseCid(row.cid),
95
- bytes: row.content,
96
- }
97
- }
98
- const lastRow = res.at(-1)
99
- if (lastRow && lastRow.repoRev) {
100
- cursor = {
101
- cid: parseCid(lastRow.cid),
102
- rev: lastRow.repoRev,
103
- }
104
- } else {
105
- cursor = undefined
106
- }
107
- } while (cursor)
108
- }
109
-
110
- async getBlockRange(since?: string, cursor?: RevCursor) {
111
- const { ref } = this.db.db.dynamic
112
- let builder = this.db.db
113
- .selectFrom('repo_block')
114
- .select(['cid', 'repoRev', 'content'])
115
- .orderBy('repoRev', 'desc')
116
- .orderBy('cid', 'desc')
117
- .limit(500)
118
- if (cursor) {
119
- // use this syntax to ensure we hit the index
120
- builder = builder.where(
121
- sql<boolean>`((${ref('repoRev')}, ${ref('cid')}) < (${
122
- cursor.rev
123
- }, ${cursor.cid.toString()}))`,
124
- )
125
- }
126
- if (since) {
127
- builder = builder.where('repoRev', '>', since)
128
- }
129
- return builder.execute()
130
- }
131
-
132
- async countBlocks(): Promise<number> {
133
- const res = await this.db.db
134
- .selectFrom('repo_block')
135
- .select(countAll.as('count'))
136
- .executeTakeFirst()
137
- return res?.count ?? 0
138
- }
139
-
140
- async destroy(): Promise<void> {
141
- throw new Error('Destruction of SQL repo storage not allowed at runtime')
142
- }
143
- }
144
-
145
- type RevCursor = {
146
- cid: Cid
147
- rev: string
148
- }
149
-
150
- export class RepoRootNotFoundError extends Error {}
@@ -1,105 +0,0 @@
1
- import { chunkArray } from '@atproto/common'
2
- import { Cid, parseCid } from '@atproto/lex-data'
3
- import { BlockMap, CommitData, RepoStorage } from '@atproto/repo'
4
- import { ActorDb, RepoBlock } from '../db/index.js'
5
- import { SqlRepoReader } from './sql-repo-reader.js'
6
-
7
- export class SqlRepoTransactor extends SqlRepoReader implements RepoStorage {
8
- cache = new BlockMap()
9
- now: string
10
-
11
- constructor(
12
- public db: ActorDb,
13
- public did: string,
14
- now?: string,
15
- ) {
16
- super(db)
17
- this.now = now ?? new Date().toISOString()
18
- }
19
-
20
- // proactively cache all blocks from a particular commit (to prevent multiple roundtrips)
21
- async cacheRev(rev: string): Promise<void> {
22
- const res = await this.db.db
23
- .selectFrom('repo_block')
24
- .where('repoRev', '=', rev)
25
- .select(['repo_block.cid', 'repo_block.content'])
26
- .limit(15)
27
- .execute()
28
- for (const row of res) {
29
- this.cache.set(parseCid(row.cid), row.content)
30
- }
31
- }
32
-
33
- async putBlock(cid: Cid, block: Uint8Array, rev: string): Promise<void> {
34
- await this.db.db
35
- .insertInto('repo_block')
36
- .values({
37
- cid: cid.toString(),
38
- repoRev: rev,
39
- size: block.length,
40
- content: block,
41
- })
42
- .onConflict((oc) => oc.doNothing())
43
- .execute()
44
- this.cache.set(cid, block)
45
- }
46
-
47
- async putMany(toPut: BlockMap, rev: string): Promise<void> {
48
- const blocks: RepoBlock[] = Array.from(toPut, ([cid, bytes]) => ({
49
- cid: cid.toString(),
50
- repoRev: rev,
51
- size: bytes.length,
52
- content: bytes,
53
- }))
54
-
55
- for (const batch of chunkArray(blocks, 50)) {
56
- await this.db.db
57
- .insertInto('repo_block')
58
- .values(batch)
59
- .onConflict((oc) => oc.doNothing())
60
- .execute()
61
- }
62
- }
63
-
64
- async deleteMany(cids: Cid[]) {
65
- if (cids.length < 1) return
66
- const cidStrs = cids.map((c) => c.toString())
67
- await this.db.db
68
- .deleteFrom('repo_block')
69
- .where('cid', 'in', cidStrs)
70
- .execute()
71
- }
72
-
73
- async applyCommit(commit: CommitData, isCreate?: boolean) {
74
- await this.updateRoot(commit.cid, commit.rev, isCreate)
75
- await this.putMany(commit.newBlocks, commit.rev)
76
- await this.deleteMany(commit.removedCids.toList())
77
- }
78
-
79
- async updateRoot(cid: Cid, rev: string, isCreate = false): Promise<void> {
80
- if (isCreate) {
81
- await this.db.db
82
- .insertInto('repo_root')
83
- .values({
84
- did: this.did,
85
- cid: cid.toString(),
86
- rev: rev,
87
- indexedAt: this.now,
88
- })
89
- .execute()
90
- } else {
91
- await this.db.db
92
- .updateTable('repo_root')
93
- .set({
94
- cid: cid.toString(),
95
- rev: rev,
96
- indexedAt: this.now,
97
- })
98
- .execute()
99
- }
100
- }
101
-
102
- async destroy(): Promise<void> {
103
- throw new Error('Destruction of SQL repo storage not allowed at runtime')
104
- }
105
- }
@@ -1,227 +0,0 @@
1
- import * as crypto from '@atproto/crypto'
2
- import { Cid, parseCid } from '@atproto/lex-data'
3
- import { BlobStore, Repo, WriteOpAction, formatDataKey } from '@atproto/repo'
4
- import { AtUri } from '@atproto/syntax'
5
- import { InvalidRequestError } from '@atproto/xrpc-server'
6
- import { BackgroundQueue } from '../../background.js'
7
- import { createWriteToOp, writeToOp } from '../../repo/index.js'
8
- import {
9
- BadCommitSwapError,
10
- BadRecordSwapError,
11
- CommitDataWithOps,
12
- CommitOp,
13
- PreparedCreate,
14
- PreparedWrite,
15
- } from '../../repo/types.js'
16
- import { BlobTransactor } from '../blob/transactor.js'
17
- import { ActorDb } from '../db/index.js'
18
- import { RecordTransactor } from '../record/transactor.js'
19
- import { RepoReader } from './reader.js'
20
- import { SqlRepoTransactor } from './sql-repo-transactor.js'
21
-
22
- export class RepoTransactor extends RepoReader {
23
- blob: BlobTransactor
24
- record: RecordTransactor
25
- storage: SqlRepoTransactor
26
-
27
- constructor(
28
- public db: ActorDb,
29
- public blobstore: BlobStore,
30
- public did: string,
31
- public signingKey: crypto.Keypair,
32
- public backgroundQueue: BackgroundQueue,
33
- public now: string = new Date().toISOString(),
34
- ) {
35
- super(db, blobstore)
36
- this.blob = new BlobTransactor(db, blobstore, backgroundQueue)
37
- this.record = new RecordTransactor(db, blobstore)
38
- this.storage = new SqlRepoTransactor(db, did, now)
39
- }
40
-
41
- async maybeLoadRepo(): Promise<Repo | null> {
42
- const res = await this.db.db
43
- .selectFrom('repo_root')
44
- .select('cid')
45
- .limit(1)
46
- .executeTakeFirst()
47
- return res ? Repo.load(this.storage, parseCid(res.cid)) : null
48
- }
49
-
50
- async createRepo(writes: PreparedCreate[]): Promise<CommitDataWithOps> {
51
- this.db.assertTransaction()
52
- const commit = await Repo.formatInitCommit(
53
- this.storage,
54
- this.did,
55
- this.signingKey,
56
- writes.map(createWriteToOp),
57
- )
58
- await this.storage.applyCommit(commit, true)
59
- await this.indexWrites(writes, commit.rev)
60
- await this.blob.processWriteBlobs(commit.rev, writes)
61
-
62
- const ops = writes.map((w) => ({
63
- action: 'create' as const,
64
- path: formatDataKey(w.uri.collection, w.uri.rkey),
65
- cid: w.cid,
66
- }))
67
- return {
68
- ...commit,
69
- ops,
70
- prevData: null,
71
- }
72
- }
73
-
74
- async processWrites(
75
- writes: PreparedWrite[],
76
- swapCommitCid?: Cid,
77
- ): Promise<CommitDataWithOps> {
78
- this.db.assertTransaction()
79
- if (writes.length > 200) {
80
- throw new InvalidRequestError('Too many writes. Max: 200')
81
- }
82
-
83
- const commit = await this.formatCommit(writes, swapCommitCid)
84
- // Do not allow commits > 2MB
85
- if (commit.relevantBlocks.byteSize > 2000000) {
86
- throw new InvalidRequestError('Too many writes. Max event size: 2MB')
87
- }
88
-
89
- // persist the commit to repo storage
90
- await this.storage.applyCommit(commit)
91
- // & send to indexing
92
- await this.indexWrites(writes, commit.rev)
93
- // process blobs
94
- await this.blob.processWriteBlobs(commit.rev, writes)
95
-
96
- return commit
97
- }
98
-
99
- async formatCommit(
100
- writes: PreparedWrite[],
101
- swapCommit?: Cid,
102
- ): Promise<CommitDataWithOps> {
103
- // this is not in a txn, so this won't actually hold the lock,
104
- // we just check if it is currently held by another txn
105
- const currRoot = await this.storage.getRootDetailed()
106
- if (!currRoot) {
107
- throw new InvalidRequestError(`No repo root found for ${this.did}`)
108
- }
109
- if (swapCommit && !currRoot.cid.equals(swapCommit)) {
110
- throw new BadCommitSwapError(currRoot.cid)
111
- }
112
- // cache last commit since there's likely overlap
113
- await this.storage.cacheRev(currRoot.rev)
114
- const newRecordCids: Cid[] = []
115
- const delAndUpdateUris: AtUri[] = []
116
- const commitOps: CommitOp[] = []
117
- for (const write of writes) {
118
- const { action, uri, swapCid } = write
119
- if (action !== WriteOpAction.Delete) {
120
- newRecordCids.push(write.cid)
121
- }
122
- if (action !== WriteOpAction.Create) {
123
- delAndUpdateUris.push(uri)
124
- }
125
- const record = await this.record.getRecord(uri, null, true)
126
- const currRecord = record ? parseCid(record.cid) : null
127
-
128
- const op: CommitOp = {
129
- action,
130
- path: formatDataKey(uri.collection, uri.rkey),
131
- cid: write.action === WriteOpAction.Delete ? null : write.cid,
132
- }
133
- if (currRecord) {
134
- op.prev = currRecord
135
- }
136
- commitOps.push(op)
137
- if (swapCid !== undefined) {
138
- if (action === WriteOpAction.Create && swapCid !== null) {
139
- throw new BadRecordSwapError(currRecord) // There should be no current record for a create
140
- }
141
- if (action === WriteOpAction.Update && swapCid === null) {
142
- throw new BadRecordSwapError(currRecord) // There should be a current record for an update
143
- }
144
- if (action === WriteOpAction.Delete && swapCid === null) {
145
- throw new BadRecordSwapError(currRecord) // There should be a current record for a delete
146
- }
147
- if (
148
- // If we have either a current CID or a swap CID
149
- (currRecord || swapCid) &&
150
- // We make sure that both are provided and equal
151
- !(swapCid && currRecord && currRecord.equals(swapCid))
152
- ) {
153
- throw new BadRecordSwapError(currRecord)
154
- }
155
- }
156
- }
157
-
158
- const repo = await Repo.load(this.storage, currRoot.cid)
159
- const prevData = repo.commit.data
160
- const writeOps = writes.map(writeToOp)
161
- const commit = await repo.formatCommit(writeOps, this.signingKey)
162
-
163
- // find blocks that would be deleted but are referenced by another record
164
- const dupeRecordCids = await this.getDuplicateRecordCids(
165
- commit.removedCids.toList(),
166
- delAndUpdateUris,
167
- )
168
- for (const cid of dupeRecordCids) {
169
- commit.removedCids.delete(cid)
170
- }
171
-
172
- // find blocks that are relevant to ops but not included in diff
173
- // (for instance a record that was moved but cid stayed the same)
174
- const newRecordBlocks = commit.relevantBlocks.getMany(newRecordCids)
175
- if (newRecordBlocks.missing.length > 0) {
176
- const missingBlocks = await this.storage.getBlocks(
177
- newRecordBlocks.missing,
178
- )
179
- commit.relevantBlocks.addMap(missingBlocks.blocks)
180
- }
181
- return {
182
- ...commit,
183
- ops: commitOps,
184
- prevData,
185
- }
186
- }
187
-
188
- async indexWrites(writes: PreparedWrite[], rev: string) {
189
- this.db.assertTransaction()
190
-
191
- for (const write of writes) {
192
- if (
193
- write.action === WriteOpAction.Create ||
194
- write.action === WriteOpAction.Update
195
- ) {
196
- await this.record.indexRecord(
197
- write.uri,
198
- write.cid,
199
- write.record,
200
- write.action,
201
- rev,
202
- this.now,
203
- )
204
- } else if (write.action === WriteOpAction.Delete) {
205
- await this.record.deleteRecord(write.uri)
206
- }
207
- }
208
- }
209
-
210
- async getDuplicateRecordCids(
211
- cids: Cid[],
212
- touchedUris: AtUri[],
213
- ): Promise<Cid[]> {
214
- if (touchedUris.length === 0 || cids.length === 0) {
215
- return []
216
- }
217
- const cidStrs = cids.map((c) => c.toString())
218
- const uriStrs = touchedUris.map((u) => u.toString())
219
- const res = await this.db.db
220
- .selectFrom('record')
221
- .where('cid', 'in', cidStrs)
222
- .where('uri', 'not in', uriStrs)
223
- .select('cid')
224
- .execute()
225
- return res.map((row) => parseCid(row.cid))
226
- }
227
- }
@@ -1,57 +0,0 @@
1
- import { Server } from '@atproto/xrpc-server'
2
- import { AuthScope, isAccessFull } from '../../../../auth-scope.js'
3
- import { AppContext } from '../../../../context.js'
4
- import { app } from '../../../../lexicons/index.js'
5
- import {
6
- bareDidFromProxyTo,
7
- computeProxyTo,
8
- pipethrough,
9
- } from '../../../../pipethrough.js'
10
-
11
- export default function (server: Server, ctx: AppContext) {
12
- const { bskyAppView } = ctx
13
- if (!bskyAppView) return
14
-
15
- server.add(app.bsky.actor.getPreferences, {
16
- auth: ctx.authVerifier.authorization({
17
- additional: [AuthScope.Takendown],
18
- authorize: (permissions, { req }) => {
19
- const lxm = app.bsky.actor.getPreferences.$lxm
20
- const aud = computeProxyTo(ctx, req, lxm)
21
- permissions.assertRpc({ aud, lxm })
22
- },
23
- }),
24
- handler: async ({ auth, req }) => {
25
- const { did } = auth.credentials
26
-
27
- // If the request has a proxy header different from the bsky app view,
28
- // we need to proxy the request to the requested app view.
29
- // @TODO This behavior should not be implemented as part of the XRPC framework
30
- const lxm = app.bsky.actor.getPreferences.$lxm
31
- const aud = computeProxyTo(ctx, req, lxm)
32
- if (aud !== `${bskyAppView.did}#bsky_appview`) {
33
- // Phase 1 of service auth updates: outbound JWT keeps bare-DID aud.
34
- return pipethrough(ctx, req, {
35
- iss: did,
36
- aud: bareDidFromProxyTo(aud),
37
- lxm,
38
- })
39
- }
40
-
41
- const hasAccessFull =
42
- auth.credentials.type === 'access' &&
43
- isAccessFull(auth.credentials.scope)
44
-
45
- const preferences = await ctx.actorStore.read(did, (store) => {
46
- return store.pref.getPreferences('app.bsky', {
47
- hasAccessFull,
48
- })
49
- })
50
-
51
- return {
52
- encoding: 'application/json' as const,
53
- body: { preferences },
54
- }
55
- },
56
- })
57
- }
@@ -1,41 +0,0 @@
1
- import { Server } from '@atproto/xrpc-server'
2
- import { AppContext } from '../../../../context.js'
3
- import { app } from '../../../../lexicons/index.js'
4
- import { computeProxyTo } from '../../../../pipethrough.js'
5
- import {
6
- MungeFn,
7
- pipethroughReadAfterWrite,
8
- } from '../../../../read-after-write/index.js'
9
-
10
- export default function (server: Server, ctx: AppContext) {
11
- if (!ctx.bskyAppView) return
12
-
13
- server.add(app.bsky.actor.getProfile, {
14
- auth: ctx.authVerifier.authorization({
15
- authorize: (permissions, { req }) => {
16
- const lxm = app.bsky.actor.getProfile.$lxm
17
- const aud = computeProxyTo(ctx, req, lxm)
18
- permissions.assertRpc({ aud, lxm })
19
- },
20
- }),
21
- handler: async (reqCtx) => {
22
- return pipethroughReadAfterWrite(
23
- ctx,
24
- reqCtx,
25
- app.bsky.actor.getProfile,
26
- getProfileMunge,
27
- )
28
- },
29
- })
30
- }
31
-
32
- const getProfileMunge: MungeFn<app.bsky.actor.getProfile.$OutputBody> = async (
33
- localViewer,
34
- original,
35
- local,
36
- requester,
37
- ) => {
38
- if (!local.profile) return original
39
- if (original.did !== requester) return original
40
- return localViewer.updateProfileDetailed(original, local.profile.record)
41
- }
@@ -1,51 +0,0 @@
1
- import { Server } from '@atproto/xrpc-server'
2
- import { AppContext } from '../../../../context.js'
3
- import { app } from '../../../../lexicons/index.js'
4
- import { computeProxyTo } from '../../../../pipethrough.js'
5
- import {
6
- MungeFn,
7
- pipethroughReadAfterWrite,
8
- } from '../../../../read-after-write/index.js'
9
-
10
- export default function (server: Server, ctx: AppContext) {
11
- if (!ctx.bskyAppView) return
12
-
13
- server.add(app.bsky.actor.getProfiles, {
14
- auth: ctx.authVerifier.authorization({
15
- authorize: (permissions, { req }) => {
16
- const lxm = app.bsky.actor.getProfiles.$lxm
17
- const aud = computeProxyTo(ctx, req, lxm)
18
- permissions.assertRpc({ aud, lxm })
19
- },
20
- }),
21
- opts: {
22
- // @TODO remove after grace period has passed, behavior is non-standard.
23
- // temporarily added for compat w/ previous version of xrpc-server to avoid breakage of a few specified parties.
24
- paramsParseLoose: true,
25
- },
26
- handler: async (reqCtx) => {
27
- return pipethroughReadAfterWrite(
28
- ctx,
29
- reqCtx,
30
- app.bsky.actor.getProfiles,
31
- getProfilesMunge,
32
- )
33
- },
34
- })
35
- }
36
-
37
- const getProfilesMunge: MungeFn<
38
- app.bsky.actor.getProfiles.$OutputBody
39
- > = async (localViewer, original, local, requester) => {
40
- const localProf = local.profile
41
- if (!localProf) return original
42
-
43
- const profiles = original.profiles.map((prof) => {
44
- if (prof.did !== requester) return prof
45
- return localViewer.updateProfileDetailed(prof, localProf.record)
46
- })
47
- return {
48
- ...original,
49
- profiles,
50
- }
51
- }
@@ -1,13 +0,0 @@
1
- import { Server } from '@atproto/xrpc-server'
2
- import { AppContext } from '../../../../context.js'
3
- import getPreferences from './getPreferences.js'
4
- import getProfile from './getProfile.js'
5
- import getProfiles from './getProfiles.js'
6
- import putPreferences from './putPreferences.js'
7
-
8
- export default function (server: Server, ctx: AppContext) {
9
- getPreferences(server, ctx)
10
- getProfile(server, ctx)
11
- getProfiles(server, ctx)
12
- putPreferences(server, ctx)
13
- }