@atproto/bsky 0.0.198 → 0.0.200

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 (279) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/api/age-assurance/const.d.ts +11 -0
  3. package/dist/api/age-assurance/const.d.ts.map +1 -0
  4. package/dist/api/age-assurance/const.js +142 -0
  5. package/dist/api/age-assurance/const.js.map +1 -0
  6. package/dist/api/age-assurance/index.d.ts +4 -0
  7. package/dist/api/age-assurance/index.d.ts.map +1 -0
  8. package/dist/api/age-assurance/index.js +24 -0
  9. package/dist/api/age-assurance/index.js.map +1 -0
  10. package/dist/api/age-assurance/kws/age-verified.d.ts +109 -0
  11. package/dist/api/age-assurance/kws/age-verified.d.ts.map +1 -0
  12. package/dist/api/age-assurance/kws/age-verified.js +63 -0
  13. package/dist/api/age-assurance/kws/age-verified.js.map +1 -0
  14. package/dist/api/age-assurance/kws/const.d.ts +13 -0
  15. package/dist/api/age-assurance/kws/const.d.ts.map +1 -0
  16. package/dist/api/age-assurance/kws/const.js +36 -0
  17. package/dist/api/age-assurance/kws/const.js.map +1 -0
  18. package/dist/api/age-assurance/kws/external-payload.d.ts +75 -0
  19. package/dist/api/age-assurance/kws/external-payload.d.ts.map +1 -0
  20. package/dist/api/age-assurance/kws/external-payload.js +124 -0
  21. package/dist/api/age-assurance/kws/external-payload.js.map +1 -0
  22. package/dist/api/age-assurance/kws/external-payload.test.d.ts +2 -0
  23. package/dist/api/age-assurance/kws/external-payload.test.d.ts.map +1 -0
  24. package/dist/api/age-assurance/kws/external-payload.test.js +65 -0
  25. package/dist/api/age-assurance/kws/external-payload.test.js.map +1 -0
  26. package/dist/api/age-assurance/redirects/kws-age-verified.d.ts +4 -0
  27. package/dist/api/age-assurance/redirects/kws-age-verified.d.ts.map +1 -0
  28. package/dist/api/age-assurance/redirects/kws-age-verified.js +76 -0
  29. package/dist/api/age-assurance/redirects/kws-age-verified.js.map +1 -0
  30. package/dist/api/age-assurance/stash.d.ts +4 -0
  31. package/dist/api/age-assurance/stash.d.ts.map +1 -0
  32. package/dist/api/age-assurance/stash.js +19 -0
  33. package/dist/api/age-assurance/stash.js.map +1 -0
  34. package/dist/api/age-assurance/types.d.ts +10 -0
  35. package/dist/api/age-assurance/types.d.ts.map +1 -0
  36. package/dist/api/age-assurance/types.js +3 -0
  37. package/dist/api/age-assurance/types.js.map +1 -0
  38. package/dist/api/age-assurance/util.d.ts +15 -0
  39. package/dist/api/age-assurance/util.d.ts.map +1 -0
  40. package/dist/api/age-assurance/util.js +54 -0
  41. package/dist/api/age-assurance/util.js.map +1 -0
  42. package/dist/api/age-assurance/webhooks/kws-age-verified.d.ts +4 -0
  43. package/dist/api/age-assurance/webhooks/kws-age-verified.d.ts.map +1 -0
  44. package/dist/api/age-assurance/webhooks/kws-age-verified.js +63 -0
  45. package/dist/api/age-assurance/webhooks/kws-age-verified.js.map +1 -0
  46. package/dist/api/app/bsky/ageassurance/begin.d.ts +4 -0
  47. package/dist/api/app/bsky/ageassurance/begin.d.ts.map +1 -0
  48. package/dist/api/app/bsky/ageassurance/begin.js +131 -0
  49. package/dist/api/app/bsky/ageassurance/begin.js.map +1 -0
  50. package/dist/api/app/bsky/ageassurance/getConfig.d.ts +4 -0
  51. package/dist/api/app/bsky/ageassurance/getConfig.d.ts.map +1 -0
  52. package/dist/api/app/bsky/ageassurance/getConfig.js +16 -0
  53. package/dist/api/app/bsky/ageassurance/getConfig.js.map +1 -0
  54. package/dist/api/app/bsky/ageassurance/getState.d.ts +4 -0
  55. package/dist/api/app/bsky/ageassurance/getState.d.ts.map +1 -0
  56. package/dist/api/app/bsky/ageassurance/getState.js +42 -0
  57. package/dist/api/app/bsky/ageassurance/getState.js.map +1 -0
  58. package/dist/api/app/bsky/contact/dismissMatch.d.ts +4 -0
  59. package/dist/api/app/bsky/contact/dismissMatch.d.ts.map +1 -0
  60. package/dist/api/app/bsky/contact/dismissMatch.js +23 -0
  61. package/dist/api/app/bsky/contact/dismissMatch.js.map +1 -0
  62. package/dist/api/app/bsky/contact/getMatches.d.ts +4 -0
  63. package/dist/api/app/bsky/contact/getMatches.d.ts.map +1 -0
  64. package/dist/api/app/bsky/contact/getMatches.js +59 -0
  65. package/dist/api/app/bsky/contact/getMatches.js.map +1 -0
  66. package/dist/api/app/bsky/contact/getSyncStatus.d.ts +4 -0
  67. package/dist/api/app/bsky/contact/getSyncStatus.d.ts.map +1 -0
  68. package/dist/api/app/bsky/contact/getSyncStatus.js +32 -0
  69. package/dist/api/app/bsky/contact/getSyncStatus.js.map +1 -0
  70. package/dist/api/app/bsky/contact/importContacts.d.ts +4 -0
  71. package/dist/api/app/bsky/contact/importContacts.d.ts.map +1 -0
  72. package/dist/api/app/bsky/contact/importContacts.js +62 -0
  73. package/dist/api/app/bsky/contact/importContacts.js.map +1 -0
  74. package/dist/api/app/bsky/contact/removeData.d.ts +4 -0
  75. package/dist/api/app/bsky/contact/removeData.d.ts.map +1 -0
  76. package/dist/api/app/bsky/contact/removeData.js +22 -0
  77. package/dist/api/app/bsky/contact/removeData.js.map +1 -0
  78. package/dist/api/app/bsky/contact/startPhoneVerification.d.ts +4 -0
  79. package/dist/api/app/bsky/contact/startPhoneVerification.d.ts.map +1 -0
  80. package/dist/api/app/bsky/contact/startPhoneVerification.js +23 -0
  81. package/dist/api/app/bsky/contact/startPhoneVerification.js.map +1 -0
  82. package/dist/api/app/bsky/contact/util.d.ts +6 -0
  83. package/dist/api/app/bsky/contact/util.d.ts.map +1 -0
  84. package/dist/api/app/bsky/contact/util.js +10 -0
  85. package/dist/api/app/bsky/contact/util.js.map +1 -0
  86. package/dist/api/app/bsky/contact/verifyPhone.d.ts +4 -0
  87. package/dist/api/app/bsky/contact/verifyPhone.d.ts.map +1 -0
  88. package/dist/api/app/bsky/contact/verifyPhone.js +26 -0
  89. package/dist/api/app/bsky/contact/verifyPhone.js.map +1 -0
  90. package/dist/api/app/bsky/graph/getRelationships.d.ts.map +1 -1
  91. package/dist/api/app/bsky/graph/getRelationships.js +4 -0
  92. package/dist/api/app/bsky/graph/getRelationships.js.map +1 -1
  93. package/dist/api/external.d.ts.map +1 -1
  94. package/dist/api/external.js +2 -0
  95. package/dist/api/external.js.map +1 -1
  96. package/dist/api/index.d.ts.map +1 -1
  97. package/dist/api/index.js +22 -2
  98. package/dist/api/index.js.map +1 -1
  99. package/dist/api/kws/api.d.ts.map +1 -1
  100. package/dist/api/kws/api.js +44 -26
  101. package/dist/api/kws/api.js.map +1 -1
  102. package/dist/api/kws/index.d.ts.map +1 -1
  103. package/dist/api/kws/index.js +3 -1
  104. package/dist/api/kws/index.js.map +1 -1
  105. package/dist/api/kws/webhook.d.ts +3 -1
  106. package/dist/api/kws/webhook.d.ts.map +1 -1
  107. package/dist/api/kws/webhook.js +48 -20
  108. package/dist/api/kws/webhook.js.map +1 -1
  109. package/dist/config.d.ts +22 -0
  110. package/dist/config.d.ts.map +1 -1
  111. package/dist/config.js +31 -2
  112. package/dist/config.js.map +1 -1
  113. package/dist/context.d.ts +3 -0
  114. package/dist/context.d.ts.map +1 -1
  115. package/dist/context.js +3 -0
  116. package/dist/context.js.map +1 -1
  117. package/dist/data-plane/bsync/index.d.ts.map +1 -1
  118. package/dist/data-plane/bsync/index.js +22 -0
  119. package/dist/data-plane/bsync/index.js.map +1 -1
  120. package/dist/data-plane/server/db/migrations/20251120T004738098Z-update-actor-age-assurance-v2.d.ts +4 -0
  121. package/dist/data-plane/server/db/migrations/20251120T004738098Z-update-actor-age-assurance-v2.d.ts.map +1 -0
  122. package/dist/data-plane/server/db/migrations/20251120T004738098Z-update-actor-age-assurance-v2.js +30 -0
  123. package/dist/data-plane/server/db/migrations/20251120T004738098Z-update-actor-age-assurance-v2.js.map +1 -0
  124. package/dist/data-plane/server/db/migrations/index.d.ts +1 -0
  125. package/dist/data-plane/server/db/migrations/index.d.ts.map +1 -1
  126. package/dist/data-plane/server/db/migrations/index.js +2 -1
  127. package/dist/data-plane/server/db/migrations/index.js.map +1 -1
  128. package/dist/data-plane/server/db/pagination.d.ts +3 -3
  129. package/dist/data-plane/server/db/tables/actor.d.ts +3 -0
  130. package/dist/data-plane/server/db/tables/actor.d.ts.map +1 -1
  131. package/dist/data-plane/server/db/tables/actor.js.map +1 -1
  132. package/dist/data-plane/server/routes/profile.d.ts.map +1 -1
  133. package/dist/data-plane/server/routes/profile.js +13 -1
  134. package/dist/data-plane/server/routes/profile.js.map +1 -1
  135. package/dist/hydration/actor.js +1 -1
  136. package/dist/hydration/actor.js.map +1 -1
  137. package/dist/hydration/hydrator.js +1 -1
  138. package/dist/hydration/hydrator.js.map +1 -1
  139. package/dist/index.d.ts.map +1 -1
  140. package/dist/index.js +12 -0
  141. package/dist/index.js.map +1 -1
  142. package/dist/kws.d.ts +35 -0
  143. package/dist/kws.d.ts.map +1 -1
  144. package/dist/kws.js +54 -0
  145. package/dist/kws.js.map +1 -1
  146. package/dist/lexicon/index.d.ts +19 -0
  147. package/dist/lexicon/index.d.ts.map +1 -1
  148. package/dist/lexicon/index.js +48 -1
  149. package/dist/lexicon/index.js.map +1 -1
  150. package/dist/lexicon/lexicons.d.ts +664 -0
  151. package/dist/lexicon/lexicons.d.ts.map +1 -1
  152. package/dist/lexicon/lexicons.js +354 -0
  153. package/dist/lexicon/lexicons.js.map +1 -1
  154. package/dist/lexicon/types/app/bsky/contact/defs.d.ts +24 -0
  155. package/dist/lexicon/types/app/bsky/contact/defs.d.ts.map +1 -0
  156. package/dist/lexicon/types/app/bsky/contact/defs.js +25 -0
  157. package/dist/lexicon/types/app/bsky/contact/defs.js.map +1 -0
  158. package/dist/lexicon/types/app/bsky/contact/dismissMatch.d.ts +25 -0
  159. package/dist/lexicon/types/app/bsky/contact/dismissMatch.d.ts.map +1 -0
  160. package/dist/lexicon/types/app/bsky/contact/dismissMatch.js +7 -0
  161. package/dist/lexicon/types/app/bsky/contact/dismissMatch.js.map +1 -0
  162. package/dist/lexicon/types/app/bsky/contact/getMatches.d.ts +25 -0
  163. package/dist/lexicon/types/app/bsky/contact/getMatches.d.ts.map +1 -0
  164. package/dist/lexicon/types/app/bsky/contact/getMatches.js +7 -0
  165. package/dist/lexicon/types/app/bsky/contact/getMatches.js.map +1 -0
  166. package/dist/lexicon/types/app/bsky/contact/getSyncStatus.d.ts +21 -0
  167. package/dist/lexicon/types/app/bsky/contact/getSyncStatus.d.ts.map +1 -0
  168. package/dist/lexicon/types/app/bsky/contact/getSyncStatus.js +7 -0
  169. package/dist/lexicon/types/app/bsky/contact/getSyncStatus.js.map +1 -0
  170. package/dist/lexicon/types/app/bsky/contact/importContacts.d.ts +30 -0
  171. package/dist/lexicon/types/app/bsky/contact/importContacts.d.ts.map +1 -0
  172. package/dist/lexicon/types/app/bsky/contact/importContacts.js +7 -0
  173. package/dist/lexicon/types/app/bsky/contact/importContacts.js.map +1 -0
  174. package/dist/lexicon/types/app/bsky/contact/removeData.d.ts +23 -0
  175. package/dist/lexicon/types/app/bsky/contact/removeData.d.ts.map +1 -0
  176. package/dist/lexicon/types/app/bsky/contact/removeData.js +7 -0
  177. package/dist/lexicon/types/app/bsky/contact/removeData.js.map +1 -0
  178. package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.d.ts +25 -0
  179. package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.d.ts.map +1 -0
  180. package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.js +7 -0
  181. package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.js.map +1 -0
  182. package/dist/lexicon/types/app/bsky/contact/verifyPhone.d.ts +29 -0
  183. package/dist/lexicon/types/app/bsky/contact/verifyPhone.d.ts.map +1 -0
  184. package/dist/lexicon/types/app/bsky/contact/verifyPhone.js +7 -0
  185. package/dist/lexicon/types/app/bsky/contact/verifyPhone.js.map +1 -0
  186. package/dist/lexicon/types/app/bsky/graph/defs.d.ts +8 -0
  187. package/dist/lexicon/types/app/bsky/graph/defs.d.ts.map +1 -1
  188. package/dist/lexicon/types/app/bsky/graph/defs.js.map +1 -1
  189. package/dist/logger.d.ts +1 -0
  190. package/dist/logger.d.ts.map +1 -1
  191. package/dist/logger.js +2 -1
  192. package/dist/logger.js.map +1 -1
  193. package/dist/proto/bsky_pb.d.ts +4 -0
  194. package/dist/proto/bsky_pb.d.ts.map +1 -1
  195. package/dist/proto/bsky_pb.js +10 -0
  196. package/dist/proto/bsky_pb.js.map +1 -1
  197. package/dist/proto/rolodex_connect.d.ts +83 -0
  198. package/dist/proto/rolodex_connect.d.ts.map +1 -0
  199. package/dist/proto/rolodex_connect.js +90 -0
  200. package/dist/proto/rolodex_connect.js.map +1 -0
  201. package/dist/proto/rolodex_pb.d.ts +363 -0
  202. package/dist/proto/rolodex_pb.d.ts.map +1 -0
  203. package/dist/proto/rolodex_pb.js +1032 -0
  204. package/dist/proto/rolodex_pb.js.map +1 -0
  205. package/dist/rolodex.d.ts +9 -0
  206. package/dist/rolodex.d.ts.map +1 -0
  207. package/dist/rolodex.js +25 -0
  208. package/dist/rolodex.js.map +1 -0
  209. package/dist/stash.d.ts +1 -0
  210. package/dist/stash.d.ts.map +1 -1
  211. package/dist/stash.js +1 -0
  212. package/dist/stash.js.map +1 -1
  213. package/dist/util/uris.d.ts +2 -2
  214. package/dist/util/uris.d.ts.map +1 -1
  215. package/package.json +16 -15
  216. package/proto/bsky.proto +1 -0
  217. package/proto/rolodex.proto +116 -0
  218. package/src/api/age-assurance/const.ts +142 -0
  219. package/src/api/age-assurance/index.ts +34 -0
  220. package/src/api/age-assurance/kws/age-verified.ts +75 -0
  221. package/src/api/age-assurance/kws/const.ts +33 -0
  222. package/src/api/age-assurance/kws/external-payload.test.ts +72 -0
  223. package/src/api/age-assurance/kws/external-payload.ts +149 -0
  224. package/src/api/age-assurance/redirects/kws-age-verified.ts +107 -0
  225. package/src/api/age-assurance/stash.ts +22 -0
  226. package/src/api/age-assurance/types.ts +10 -0
  227. package/src/api/age-assurance/util.ts +66 -0
  228. package/src/api/age-assurance/webhooks/kws-age-verified.ts +75 -0
  229. package/src/api/app/bsky/ageassurance/begin.ts +167 -0
  230. package/src/api/app/bsky/ageassurance/getConfig.ts +15 -0
  231. package/src/api/app/bsky/ageassurance/getState.ts +53 -0
  232. package/src/api/app/bsky/contact/dismissMatch.ts +24 -0
  233. package/src/api/app/bsky/contact/getMatches.ts +111 -0
  234. package/src/api/app/bsky/contact/getSyncStatus.ts +35 -0
  235. package/src/api/app/bsky/contact/importContacts.ts +118 -0
  236. package/src/api/app/bsky/contact/removeData.ts +23 -0
  237. package/src/api/app/bsky/contact/startPhoneVerification.ts +24 -0
  238. package/src/api/app/bsky/contact/util.ts +13 -0
  239. package/src/api/app/bsky/contact/verifyPhone.ts +27 -0
  240. package/src/api/app/bsky/graph/getRelationships.ts +4 -0
  241. package/src/api/external.ts +2 -0
  242. package/src/api/index.ts +20 -0
  243. package/src/api/kws/api.ts +55 -34
  244. package/src/api/kws/index.ts +7 -1
  245. package/src/api/kws/webhook.ts +57 -34
  246. package/src/config.ts +53 -2
  247. package/src/context.ts +6 -0
  248. package/src/data-plane/bsync/index.ts +31 -0
  249. package/src/data-plane/server/db/migrations/20251120T004738098Z-update-actor-age-assurance-v2.ts +28 -0
  250. package/src/data-plane/server/db/migrations/index.ts +1 -0
  251. package/src/data-plane/server/db/tables/actor.ts +3 -0
  252. package/src/data-plane/server/routes/profile.ts +12 -1
  253. package/src/hydration/actor.ts +1 -1
  254. package/src/hydration/hydrator.ts +1 -1
  255. package/src/index.ts +13 -0
  256. package/src/kws.ts +81 -0
  257. package/src/lexicon/index.ts +101 -0
  258. package/src/lexicon/lexicons.ts +375 -0
  259. package/src/lexicon/types/app/bsky/contact/defs.ts +52 -0
  260. package/src/lexicon/types/app/bsky/contact/dismissMatch.ts +43 -0
  261. package/src/lexicon/types/app/bsky/contact/getMatches.ts +43 -0
  262. package/src/lexicon/types/app/bsky/contact/getSyncStatus.ts +39 -0
  263. package/src/lexicon/types/app/bsky/contact/importContacts.ts +49 -0
  264. package/src/lexicon/types/app/bsky/contact/removeData.ts +40 -0
  265. package/src/lexicon/types/app/bsky/contact/startPhoneVerification.ts +43 -0
  266. package/src/lexicon/types/app/bsky/contact/verifyPhone.ts +48 -0
  267. package/src/lexicon/types/app/bsky/graph/defs.ts +8 -0
  268. package/src/logger.ts +2 -0
  269. package/src/proto/bsky_pb.ts +6 -0
  270. package/src/proto/rolodex_connect.ts +89 -0
  271. package/src/proto/rolodex_pb.ts +746 -0
  272. package/src/rolodex.ts +42 -0
  273. package/src/stash.ts +3 -0
  274. package/tests/views/__snapshots__/profile.test.ts.snap +103 -0
  275. package/tests/views/age-assurance-v2.test.ts +745 -0
  276. package/tests/views/age-assurance.test.ts +2 -0
  277. package/tests/views/profile.test.ts +39 -0
  278. package/tsconfig.build.tsbuildinfo +1 -1
  279. package/tsconfig.tests.tsbuildinfo +1 -1
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.default = default_1;
7
+ const node_crypto_1 = __importDefault(require("node:crypto"));
8
+ const address_1 = require("@hapi/address");
9
+ const disposable_email_domains_js_1 = require("disposable-email-domains-js");
10
+ const api_1 = require("@atproto/api");
11
+ const xrpc_server_1 = require("@atproto/xrpc-server");
12
+ const logger_1 = require("../../../../logger");
13
+ const const_1 = require("../../../age-assurance/const");
14
+ const const_2 = require("../../../age-assurance/kws/const");
15
+ const external_payload_1 = require("../../../age-assurance/kws/external-payload");
16
+ const stash_1 = require("../../../age-assurance/stash");
17
+ const util_1 = require("../../../age-assurance/util");
18
+ const util_2 = require("../../../kws/util");
19
+ function default_1(server, ctx) {
20
+ server.app.bsky.ageassurance.begin({
21
+ auth: ctx.authVerifier.standard,
22
+ handler: async ({ auth, input, req }) => {
23
+ if (!ctx.kwsClient) {
24
+ throw new xrpc_server_1.MethodNotImplementedError('This service is not configured to support age assurance.');
25
+ }
26
+ const actorDid = auth.credentials.iss;
27
+ const actorInfo = await getAgeVerificationState(ctx, actorDid);
28
+ if (actorInfo?.ageAssuranceStatus) {
29
+ if (actorInfo.ageAssuranceStatus.status !== 'unknown' &&
30
+ actorInfo.ageAssuranceStatus.status !== 'pending') {
31
+ throw new xrpc_server_1.InvalidRequestError(`Cannot initiate age assurance flow from current state: ${actorInfo.ageAssuranceStatus.status}`, 'InvalidInitiation');
32
+ }
33
+ }
34
+ const attemptId = node_crypto_1.default.randomUUID();
35
+ const { email, language, countryCode, regionCode } = validateInput(input.body);
36
+ let externalPayload;
37
+ try {
38
+ externalPayload = (0, external_payload_1.serializeKWSExternalPayloadV2)({
39
+ version: external_payload_1.KWSExternalPayloadVersion.V2,
40
+ actorDid,
41
+ attemptId,
42
+ countryCode,
43
+ regionCode,
44
+ });
45
+ }
46
+ catch (err) {
47
+ if (err instanceof external_payload_1.KWSExternalPayloadTooLargeError) {
48
+ logger_1.httpLogger.error({ err, actorDid }, err.message);
49
+ throw new xrpc_server_1.InvalidRequestError('Age Assurance flow failed because DID is too long', 'DidTooLong');
50
+ }
51
+ throw err;
52
+ }
53
+ /*
54
+ * Determine if age assurance config exists for this region. The calling
55
+ * application should already have checked for this, so this is just a
56
+ * safeguard.
57
+ */
58
+ const region = (0, api_1.getAgeAssuranceRegionConfig)(const_1.AGE_ASSURANCE_CONFIG, {
59
+ countryCode,
60
+ regionCode,
61
+ });
62
+ if (!region) {
63
+ const message = 'Age Assurance is not required in this region';
64
+ logger_1.httpLogger.error({ actorDid, countryCode, regionCode }, message);
65
+ throw new xrpc_server_1.InvalidRequestError(message, 'RegionNotSupported');
66
+ }
67
+ const location = (0, util_1.createLocationString)(countryCode, regionCode);
68
+ if (const_2.KWS_V2_COUNTRIES.has(region.countryCode)) {
69
+ // `age-verified` flow
70
+ await ctx.kwsClient.sendAgeVerifiedFlowEmail({
71
+ location,
72
+ email,
73
+ externalPayload,
74
+ language,
75
+ });
76
+ }
77
+ else {
78
+ // `adult-verified` flow is what we've been using prior to `age-verified`
79
+ await ctx.kwsClient.sendAdultVerifiedFlowEmail({
80
+ location,
81
+ email,
82
+ externalPayload,
83
+ language,
84
+ });
85
+ }
86
+ const event = await (0, stash_1.createEvent)(ctx, actorDid, {
87
+ attemptId,
88
+ email,
89
+ // Assumes `app.set('trust proxy', ...)` configured with `true` or specific values.
90
+ initIp: req.ip,
91
+ initUa: (0, util_2.getClientUa)(req),
92
+ status: 'pending',
93
+ access: 'unknown',
94
+ countryCode,
95
+ regionCode,
96
+ });
97
+ return {
98
+ encoding: 'application/json',
99
+ body: {
100
+ lastInitiatedAt: event.createdAt,
101
+ status: 'pending',
102
+ access: 'unknown',
103
+ },
104
+ };
105
+ },
106
+ });
107
+ }
108
+ function validateInput({ email, language, ...rest }) {
109
+ if (!(0, address_1.isEmailValid)(email) || (0, disposable_email_domains_js_1.isDisposableEmail)(email)) {
110
+ throw new xrpc_server_1.InvalidRequestError('This email address is not supported, please use a different email.', 'InvalidEmail');
111
+ }
112
+ return {
113
+ email,
114
+ language: const_2.KWS_SUPPORTED_LANGUAGES.has(language) ? language : 'en',
115
+ ...rest,
116
+ };
117
+ }
118
+ async function getAgeVerificationState(ctx, actorDid) {
119
+ try {
120
+ const res = await ctx.dataplane.getActors({
121
+ dids: [actorDid],
122
+ returnAgeAssuranceForDids: [actorDid],
123
+ skipCacheForDids: [actorDid],
124
+ });
125
+ return res.actors[0];
126
+ }
127
+ catch (err) {
128
+ return undefined;
129
+ }
130
+ }
131
+ //# sourceMappingURL=begin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"begin.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/ageassurance/begin.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from 'node:crypto'\nimport { isEmailValid } from '@hapi/address'\nimport { isDisposableEmail } from 'disposable-email-domains-js'\nimport { getAgeAssuranceRegionConfig } from '@atproto/api'\nimport {\n InvalidRequestError,\n MethodNotImplementedError,\n} from '@atproto/xrpc-server'\nimport { AppContext } from '../../../../context'\nimport { Server } from '../../../../lexicon'\nimport { InputSchema } from '../../../../lexicon/types/app/bsky/ageassurance/begin'\nimport { httpLogger as log } from '../../../../logger'\nimport { ActorInfo } from '../../../../proto/bsky_pb'\nimport { AGE_ASSURANCE_CONFIG } from '../../../age-assurance/const'\nimport {\n KWS_SUPPORTED_LANGUAGES,\n KWS_V2_COUNTRIES,\n} from '../../../age-assurance/kws/const'\nimport {\n KWSExternalPayloadTooLargeError,\n KWSExternalPayloadVersion,\n serializeKWSExternalPayloadV2,\n} from '../../../age-assurance/kws/external-payload'\nimport { createEvent } from '../../../age-assurance/stash'\nimport { createLocationString } from '../../../age-assurance/util'\nimport { getClientUa } from '../../../kws/util'\n\nexport default function (server: Server, ctx: AppContext) {\n server.app.bsky.ageassurance.begin({\n auth: ctx.authVerifier.standard,\n handler: async ({ auth, input, req }) => {\n if (!ctx.kwsClient) {\n throw new MethodNotImplementedError(\n 'This service is not configured to support age assurance.',\n )\n }\n\n const actorDid = auth.credentials.iss\n const actorInfo = await getAgeVerificationState(ctx, actorDid)\n\n if (actorInfo?.ageAssuranceStatus) {\n if (\n actorInfo.ageAssuranceStatus.status !== 'unknown' &&\n actorInfo.ageAssuranceStatus.status !== 'pending'\n ) {\n throw new InvalidRequestError(\n `Cannot initiate age assurance flow from current state: ${actorInfo.ageAssuranceStatus.status}`,\n 'InvalidInitiation',\n )\n }\n }\n\n const attemptId = crypto.randomUUID()\n const { email, language, countryCode, regionCode } = validateInput(\n input.body,\n )\n\n let externalPayload: string\n try {\n externalPayload = serializeKWSExternalPayloadV2({\n version: KWSExternalPayloadVersion.V2,\n actorDid,\n attemptId,\n countryCode,\n regionCode,\n })\n } catch (err) {\n if (err instanceof KWSExternalPayloadTooLargeError) {\n log.error({ err, actorDid }, err.message)\n throw new InvalidRequestError(\n 'Age Assurance flow failed because DID is too long',\n 'DidTooLong',\n )\n }\n throw err\n }\n\n /*\n * Determine if age assurance config exists for this region. The calling\n * application should already have checked for this, so this is just a\n * safeguard.\n */\n const region = getAgeAssuranceRegionConfig(AGE_ASSURANCE_CONFIG, {\n countryCode,\n regionCode,\n })\n if (!region) {\n const message = 'Age Assurance is not required in this region'\n log.error({ actorDid, countryCode, regionCode }, message)\n throw new InvalidRequestError(message, 'RegionNotSupported')\n }\n\n const location = createLocationString(countryCode, regionCode)\n\n if (KWS_V2_COUNTRIES.has(region.countryCode)) {\n // `age-verified` flow\n await ctx.kwsClient.sendAgeVerifiedFlowEmail({\n location,\n email,\n externalPayload,\n language,\n })\n } else {\n // `adult-verified` flow is what we've been using prior to `age-verified`\n await ctx.kwsClient.sendAdultVerifiedFlowEmail({\n location,\n email,\n externalPayload,\n language,\n })\n }\n\n const event = await createEvent(ctx, actorDid, {\n attemptId,\n email,\n // Assumes `app.set('trust proxy', ...)` configured with `true` or specific values.\n initIp: req.ip,\n initUa: getClientUa(req),\n status: 'pending',\n access: 'unknown',\n countryCode,\n regionCode,\n })\n\n return {\n encoding: 'application/json',\n body: {\n lastInitiatedAt: event.createdAt,\n status: 'pending',\n access: 'unknown',\n },\n }\n },\n })\n}\n\nfunction validateInput({ email, language, ...rest }: InputSchema): InputSchema {\n if (!isEmailValid(email) || isDisposableEmail(email)) {\n throw new InvalidRequestError(\n 'This email address is not supported, please use a different email.',\n 'InvalidEmail',\n )\n }\n\n return {\n email,\n language: KWS_SUPPORTED_LANGUAGES.has(language) ? language : 'en',\n ...rest,\n }\n}\n\nasync function getAgeVerificationState(\n ctx: AppContext,\n actorDid: string,\n): Promise<ActorInfo | undefined> {\n try {\n const res = await ctx.dataplane.getActors({\n dids: [actorDid],\n returnAgeAssuranceForDids: [actorDid],\n skipCacheForDids: [actorDid],\n })\n\n return res.actors[0]\n } catch (err) {\n return undefined\n }\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import { AppContext } from '../../../../context';
2
+ import { Server } from '../../../../lexicon';
3
+ export default function (server: Server, ctx: AppContext): void;
4
+ //# sourceMappingURL=getConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getConfig.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/ageassurance/getConfig.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAE5C,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAUvD"}
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const const_1 = require("../../../../api/age-assurance/const");
5
+ function default_1(server, ctx) {
6
+ server.app.bsky.ageassurance.getConfig({
7
+ auth: ctx.authVerifier.standardOptional,
8
+ handler: async () => {
9
+ return {
10
+ encoding: 'application/json',
11
+ body: const_1.AGE_ASSURANCE_CONFIG,
12
+ };
13
+ },
14
+ });
15
+ }
16
+ //# sourceMappingURL=getConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getConfig.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/ageassurance/getConfig.ts"],"names":[],"mappings":";;AAIA,4BAUC;AAdD,+DAA0E;AAI1E,mBAAyB,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC;QACrC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,gBAAgB;QACvC,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,4BAAoB;aAC3B,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { AGE_ASSURANCE_CONFIG } from '../../../../api/age-assurance/const'\nimport { AppContext } from '../../../../context'\nimport { Server } from '../../../../lexicon'\n\nexport default function (server: Server, ctx: AppContext) {\n server.app.bsky.ageassurance.getConfig({\n auth: ctx.authVerifier.standardOptional,\n handler: async () => {\n return {\n encoding: 'application/json',\n body: AGE_ASSURANCE_CONFIG,\n }\n },\n })\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import { AppContext } from '../../../../context';
2
+ import { Server } from '../../../../lexicon';
3
+ export default function (server: Server, ctx: AppContext): void;
4
+ //# sourceMappingURL=getState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getState.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/ageassurance/getState.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAG5C,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA0BvD"}
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const xrpc_server_1 = require("@atproto/xrpc-server");
5
+ function default_1(server, ctx) {
6
+ server.app.bsky.ageassurance.getState({
7
+ auth: ctx.authVerifier.standard,
8
+ handler: async ({ auth }) => {
9
+ const viewer = auth.credentials.iss;
10
+ const actor = await getActorInfo(ctx, viewer);
11
+ return {
12
+ encoding: 'application/json',
13
+ body: {
14
+ state: {
15
+ lastInitiatedAt: actor.ageAssuranceStatus?.lastInitiatedAt
16
+ ?.toDate()
17
+ .toISOString() || undefined,
18
+ status: actor.ageAssuranceStatus?.status || 'unknown',
19
+ access: actor.ageAssuranceStatus?.access || 'unknown',
20
+ },
21
+ metadata: {
22
+ accountCreatedAt: actor.createdAt?.toDate().toISOString() || undefined,
23
+ },
24
+ },
25
+ };
26
+ },
27
+ });
28
+ }
29
+ const getActorInfo = async (ctx, actorDid) => {
30
+ try {
31
+ const res = await ctx.dataplane.getActors({
32
+ dids: [actorDid],
33
+ returnAgeAssuranceForDids: [actorDid],
34
+ skipCacheForDids: [actorDid],
35
+ });
36
+ return res.actors[0];
37
+ }
38
+ catch (err) {
39
+ throw new xrpc_server_1.UpstreamFailureError('Cannot get current age assurance state', 'GetAgeAssuranceStateFailed', { cause: err });
40
+ }
41
+ };
42
+ //# sourceMappingURL=getState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getState.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/ageassurance/getState.ts"],"names":[],"mappings":";;AAKA,4BA0BC;AA/BD,sDAA2D;AAK3D,mBAAyB,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC;QACpC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,QAAQ;QAC/B,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;YAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YACnC,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,CAAA;YAE7C,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE;oBACJ,KAAK,EAAE;wBACL,eAAe,EACb,KAAK,CAAC,kBAAkB,EAAE,eAAe;4BACvC,EAAE,MAAM,EAAE;6BACT,WAAW,EAAE,IAAI,SAAS;wBAC/B,MAAM,EAAE,KAAK,CAAC,kBAAkB,EAAE,MAAM,IAAI,SAAS;wBACrD,MAAM,EAAE,KAAK,CAAC,kBAAkB,EAAE,MAAM,IAAI,SAAS;qBACtD;oBACD,QAAQ,EAAE;wBACR,gBAAgB,EACd,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,WAAW,EAAE,IAAI,SAAS;qBACvD;iBACF;aACF,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,YAAY,GAAG,KAAK,EACxB,GAAe,EACf,QAAgB,EACI,EAAE;IACtB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,SAAS,CAAC;YACxC,IAAI,EAAE,CAAC,QAAQ,CAAC;YAChB,yBAAyB,EAAE,CAAC,QAAQ,CAAC;YACrC,gBAAgB,EAAE,CAAC,QAAQ,CAAC;SAC7B,CAAC,CAAA;QAEF,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IACtB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,kCAAoB,CAC5B,wCAAwC,EACxC,4BAA4B,EAC5B,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAA;IACH,CAAC;AACH,CAAC,CAAA","sourcesContent":["import { UpstreamFailureError } from '@atproto/xrpc-server'\nimport { AppContext } from '../../../../context'\nimport { Server } from '../../../../lexicon'\nimport { ActorInfo } from '../../../../proto/bsky_pb'\n\nexport default function (server: Server, ctx: AppContext) {\n server.app.bsky.ageassurance.getState({\n auth: ctx.authVerifier.standard,\n handler: async ({ auth }) => {\n const viewer = auth.credentials.iss\n const actor = await getActorInfo(ctx, viewer)\n\n return {\n encoding: 'application/json',\n body: {\n state: {\n lastInitiatedAt:\n actor.ageAssuranceStatus?.lastInitiatedAt\n ?.toDate()\n .toISOString() || undefined,\n status: actor.ageAssuranceStatus?.status || 'unknown',\n access: actor.ageAssuranceStatus?.access || 'unknown',\n },\n metadata: {\n accountCreatedAt:\n actor.createdAt?.toDate().toISOString() || undefined,\n },\n },\n }\n },\n })\n}\n\nconst getActorInfo = async (\n ctx: AppContext,\n actorDid: string,\n): Promise<ActorInfo> => {\n try {\n const res = await ctx.dataplane.getActors({\n dids: [actorDid],\n returnAgeAssuranceForDids: [actorDid],\n skipCacheForDids: [actorDid],\n })\n\n return res.actors[0]\n } catch (err) {\n throw new UpstreamFailureError(\n 'Cannot get current age assurance state',\n 'GetAgeAssuranceStateFailed',\n { cause: err },\n )\n }\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import { AppContext } from '../../../../context';
2
+ import { Server } from '../../../../lexicon';
3
+ export default function (server: Server, ctx: AppContext): void;
4
+ //# sourceMappingURL=dismissMatch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dismissMatch.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/dismissMatch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAG5C,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAmBvD"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const util_1 = require("./util");
5
+ function default_1(server, ctx) {
6
+ server.app.bsky.contact.dismissMatch({
7
+ auth: ctx.authVerifier.standard,
8
+ handler: async ({ input, auth }) => {
9
+ (0, util_1.assertRolodexOrThrowUnimplemented)(ctx);
10
+ const actor = auth.credentials.iss;
11
+ // TODO: Error handling.
12
+ await ctx.rolodexClient.dismissMatch({
13
+ actor,
14
+ subject: input.body.subject,
15
+ });
16
+ return {
17
+ encoding: 'application/json',
18
+ body: {},
19
+ };
20
+ },
21
+ });
22
+ }
23
+ //# sourceMappingURL=dismissMatch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dismissMatch.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/dismissMatch.ts"],"names":[],"mappings":";;AAIA,4BAmBC;AArBD,iCAA0D;AAE1D,mBAAyB,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC;QACnC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,QAAQ;QAC/B,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE;YACjC,IAAA,wCAAiC,EAAC,GAAG,CAAC,CAAA;YAEtC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YAClC,wBAAwB;YACxB,MAAM,GAAG,CAAC,aAAa,CAAC,YAAY,CAAC;gBACnC,KAAK;gBACL,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO;aAC5B,CAAC,CAAA;YAEF,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,EAAE;aACT,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { AppContext } from '../../../../context'\nimport { Server } from '../../../../lexicon'\nimport { assertRolodexOrThrowUnimplemented } from './util'\n\nexport default function (server: Server, ctx: AppContext) {\n server.app.bsky.contact.dismissMatch({\n auth: ctx.authVerifier.standard,\n handler: async ({ input, auth }) => {\n assertRolodexOrThrowUnimplemented(ctx)\n\n const actor = auth.credentials.iss\n // TODO: Error handling.\n await ctx.rolodexClient.dismissMatch({\n actor,\n subject: input.body.subject,\n })\n\n return {\n encoding: 'application/json',\n body: {},\n }\n },\n })\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import { AppContext } from '../../../../context';
2
+ import { Server } from '../../../../lexicon';
3
+ export default function (server: Server, ctx: AppContext): void;
4
+ //# sourceMappingURL=getMatches.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getMatches.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/getMatches.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAMhD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAW5C,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAyBvD"}
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const common_1 = require("@atproto/common");
5
+ const pipeline_1 = require("../../../../pipeline");
6
+ const util_1 = require("./util");
7
+ function default_1(server, ctx) {
8
+ const getMatches = (0, pipeline_1.createPipeline)(skeleton, hydration, noBlocks, presentation);
9
+ server.app.bsky.contact.getMatches({
10
+ auth: ctx.authVerifier.standard,
11
+ handler: async ({ params, auth, req }) => {
12
+ (0, util_1.assertRolodexOrThrowUnimplemented)(ctx);
13
+ const viewer = auth.credentials.iss;
14
+ const labelers = ctx.reqLabelers(req);
15
+ const hydrateCtx = await ctx.hydrator.createContext({
16
+ labelers,
17
+ viewer,
18
+ });
19
+ const result = await getMatches({ ...params, hydrateCtx: hydrateCtx.copy({ viewer }) }, ctx);
20
+ return {
21
+ encoding: 'application/json',
22
+ body: result,
23
+ };
24
+ },
25
+ });
26
+ }
27
+ const skeleton = async (input) => {
28
+ const { params, ctx } = input;
29
+ const actor = params.hydrateCtx.viewer;
30
+ // TODO: Error handling.
31
+ const { cursor, subjects } = await ctx.rolodexClient.getMatches({
32
+ actor: params.hydrateCtx.viewer,
33
+ limit: params.limit,
34
+ cursor: params.cursor,
35
+ });
36
+ return {
37
+ actor,
38
+ subjects,
39
+ cursor: cursor || undefined,
40
+ };
41
+ };
42
+ const hydration = async (input) => {
43
+ const { ctx, params, skeleton } = input;
44
+ const { subjects } = skeleton;
45
+ return ctx.hydrator.hydrateProfiles(subjects, params.hydrateCtx);
46
+ };
47
+ const noBlocks = (inputs) => {
48
+ const { ctx, skeleton, hydration } = inputs;
49
+ skeleton.subjects = skeleton.subjects.filter((subject) => {
50
+ return !ctx.views.viewerBlockExists(subject, hydration);
51
+ });
52
+ return skeleton;
53
+ };
54
+ const presentation = (input) => {
55
+ const { ctx, skeleton, hydration } = input;
56
+ const matches = (0, common_1.mapDefined)(skeleton.subjects, (did) => ctx.views.profile(did, hydration));
57
+ return { matches };
58
+ };
59
+ //# sourceMappingURL=getMatches.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getMatches.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/getMatches.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport { AppContext } from '../../../../context'\nimport {\n HydrateCtx,\n HydrationState,\n Hydrator,\n} from '../../../../hydration/hydrator'\nimport { Server } from '../../../../lexicon'\nimport { QueryParams } from '../../../../lexicon/types/app/bsky/contact/getMatches'\nimport {\n HydrationFnInput,\n SkeletonFnInput,\n createPipeline,\n} from '../../../../pipeline'\nimport { RolodexClient } from '../../../../rolodex'\nimport { Views } from '../../../../views'\nimport { assertRolodexOrThrowUnimplemented } from './util'\n\nexport default function (server: Server, ctx: AppContext) {\n const getMatches = createPipeline(skeleton, hydration, noBlocks, presentation)\n server.app.bsky.contact.getMatches({\n auth: ctx.authVerifier.standard,\n handler: async ({ params, auth, req }) => {\n assertRolodexOrThrowUnimplemented(ctx)\n\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n })\n\n const result = await getMatches(\n { ...params, hydrateCtx: hydrateCtx.copy({ viewer }) },\n ctx,\n )\n\n return {\n encoding: 'application/json',\n body: result,\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n const actor = params.hydrateCtx.viewer\n // TODO: Error handling.\n const { cursor, subjects } = await ctx.rolodexClient.getMatches({\n actor: params.hydrateCtx.viewer,\n limit: params.limit,\n cursor: params.cursor,\n })\n return {\n actor,\n subjects,\n cursor: cursor || undefined,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { subjects } = skeleton\n return ctx.hydrator.hydrateProfiles(subjects, params.hydrateCtx)\n}\n\nconst noBlocks = (inputs: {\n ctx: Context\n skeleton: SkeletonState\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = inputs\n skeleton.subjects = skeleton.subjects.filter((subject) => {\n return !ctx.views.viewerBlockExists(subject, hydration)\n })\n return skeleton\n}\n\nconst presentation = (input: {\n ctx: Context\n params: Params\n skeleton: SkeletonState\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = input\n const matches = mapDefined(skeleton.subjects, (did) =>\n ctx.views.profile(did, hydration),\n )\n return { matches }\n}\n\ntype Context = {\n hydrator: Hydrator\n rolodexClient: RolodexClient\n views: Views\n}\n\ntype Params = QueryParams & {\n hydrateCtx: HydrateCtx & { viewer: string }\n}\n\ntype SkeletonState = {\n actor: string\n subjects: string[]\n cursor?: string\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import { AppContext } from '../../../../context';
2
+ import { Server } from '../../../../lexicon';
3
+ export default function (server: Server, ctx: AppContext): void;
4
+ //# sourceMappingURL=getSyncStatus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getSyncStatus.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/getSyncStatus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAI5C,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA6BvD"}
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const util_1 = require("./util");
5
+ function default_1(server, ctx) {
6
+ server.app.bsky.contact.getSyncStatus({
7
+ auth: ctx.authVerifier.standard,
8
+ handler: async ({ auth }) => {
9
+ (0, util_1.assertRolodexOrThrowUnimplemented)(ctx);
10
+ const actor = auth.credentials.iss;
11
+ // TODO: Error handling.
12
+ const res = await ctx.rolodexClient.getSyncStatus({
13
+ actor,
14
+ });
15
+ let syncStatus;
16
+ if (res.status && res.status.syncedAt) {
17
+ const syncedAt = res.status?.syncedAt?.toDate().toISOString();
18
+ syncStatus = {
19
+ matchesCount: res.status.matchesCount,
20
+ syncedAt,
21
+ };
22
+ }
23
+ return {
24
+ encoding: 'application/json',
25
+ body: {
26
+ syncStatus,
27
+ },
28
+ };
29
+ },
30
+ });
31
+ }
32
+ //# sourceMappingURL=getSyncStatus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getSyncStatus.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/getSyncStatus.ts"],"names":[],"mappings":";;AAKA,4BA6BC;AA/BD,iCAA0D;AAE1D,mBAAyB,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC;QACpC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,QAAQ;QAC/B,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;YAC1B,IAAA,wCAAiC,EAAC,GAAG,CAAC,CAAA;YAEtC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YAClC,wBAAwB;YACxB,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,aAAa,CAAC;gBAChD,KAAK;aACN,CAAC,CAAA;YAEF,IAAI,UAAkC,CAAA;YACtC,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACtC,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,WAAW,EAAE,CAAA;gBAC7D,UAAU,GAAG;oBACX,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,YAAY;oBACrC,QAAQ;iBACT,CAAA;YACH,CAAC;YAED,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE;oBACJ,UAAU;iBACX;aACF,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { AppContext } from '../../../../context'\nimport { Server } from '../../../../lexicon'\nimport { SyncStatus } from '../../../../lexicon/types/app/bsky/contact/defs'\nimport { assertRolodexOrThrowUnimplemented } from './util'\n\nexport default function (server: Server, ctx: AppContext) {\n server.app.bsky.contact.getSyncStatus({\n auth: ctx.authVerifier.standard,\n handler: async ({ auth }) => {\n assertRolodexOrThrowUnimplemented(ctx)\n\n const actor = auth.credentials.iss\n // TODO: Error handling.\n const res = await ctx.rolodexClient.getSyncStatus({\n actor,\n })\n\n let syncStatus: SyncStatus | undefined\n if (res.status && res.status.syncedAt) {\n const syncedAt = res.status?.syncedAt?.toDate().toISOString()\n syncStatus = {\n matchesCount: res.status.matchesCount,\n syncedAt,\n }\n }\n\n return {\n encoding: 'application/json',\n body: {\n syncStatus,\n },\n }\n },\n })\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import { AppContext } from '../../../../context';
2
+ import { Server } from '../../../../lexicon';
3
+ export default function (server: Server, ctx: AppContext): void;
4
+ //# sourceMappingURL=importContacts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"importContacts.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/importContacts.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAMhD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAc5C,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QA8BvD"}
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const common_1 = require("@atproto/common");
5
+ const pipeline_1 = require("../../../../pipeline");
6
+ const util_1 = require("./util");
7
+ function default_1(server, ctx) {
8
+ const importContacts = (0, pipeline_1.createPipeline)(skeleton, hydration, pipeline_1.noRules, //
9
+ presentation);
10
+ server.app.bsky.contact.importContacts({
11
+ auth: ctx.authVerifier.standard,
12
+ handler: async ({ input, auth, req }) => {
13
+ (0, util_1.assertRolodexOrThrowUnimplemented)(ctx);
14
+ const viewer = auth.credentials.iss;
15
+ const labelers = ctx.reqLabelers(req);
16
+ const hydrateCtx = await ctx.hydrator.createContext({
17
+ labelers,
18
+ viewer,
19
+ });
20
+ const result = await importContacts({ ...input.body, hydrateCtx: hydrateCtx.copy({ viewer }) }, ctx);
21
+ return {
22
+ encoding: 'application/json',
23
+ body: result,
24
+ };
25
+ },
26
+ });
27
+ }
28
+ const skeleton = async (input) => {
29
+ const { params, ctx } = input;
30
+ const actor = params.hydrateCtx.viewer;
31
+ // TODO: Error handling.
32
+ const { matches } = await ctx.rolodexClient.importContacts({
33
+ actor: params.hydrateCtx.viewer,
34
+ contacts: params.contacts,
35
+ token: params.token,
36
+ });
37
+ return {
38
+ actor,
39
+ matches,
40
+ };
41
+ };
42
+ const hydration = async (input) => {
43
+ const { ctx, params, skeleton } = input;
44
+ const { matches } = skeleton;
45
+ const subjects = matches.map((m) => m.subject);
46
+ return ctx.hydrator.hydrateProfiles(subjects, params.hydrateCtx);
47
+ };
48
+ const presentation = (input) => {
49
+ const { ctx, skeleton, hydration } = input;
50
+ const matchesAndContactIndexes = (0, common_1.mapDefined)(skeleton.matches, ({ subject, inputIndex }) => {
51
+ const profile = ctx.views.profile(subject, hydration);
52
+ if (!profile) {
53
+ return undefined;
54
+ }
55
+ return {
56
+ contactIndex: inputIndex,
57
+ match: profile,
58
+ };
59
+ });
60
+ return { matchesAndContactIndexes };
61
+ };
62
+ //# sourceMappingURL=importContacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"importContacts.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/importContacts.ts"],"names":[],"mappings":"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","sourcesContent":["import { mapDefined } from '@atproto/common'\nimport { AppContext } from '../../../../context'\nimport {\n HydrateCtx,\n HydrationState,\n Hydrator,\n} from '../../../../hydration/hydrator'\nimport { Server } from '../../../../lexicon'\nimport { MatchAndContactIndex } from '../../../../lexicon/types/app/bsky/contact/defs'\nimport { InputSchema } from '../../../../lexicon/types/app/bsky/contact/importContacts'\nimport {\n HydrationFnInput,\n SkeletonFnInput,\n createPipeline,\n noRules,\n} from '../../../../pipeline'\nimport { ImportContactsMatch } from '../../../../proto/rolodex_pb'\nimport { RolodexClient } from '../../../../rolodex'\nimport { Views } from '../../../../views'\nimport { assertRolodexOrThrowUnimplemented } from './util'\n\nexport default function (server: Server, ctx: AppContext) {\n const importContacts = createPipeline(\n skeleton,\n hydration,\n noRules, //\n presentation,\n )\n server.app.bsky.contact.importContacts({\n auth: ctx.authVerifier.standard,\n handler: async ({ input, auth, req }) => {\n assertRolodexOrThrowUnimplemented(ctx)\n\n const viewer = auth.credentials.iss\n const labelers = ctx.reqLabelers(req)\n const hydrateCtx = await ctx.hydrator.createContext({\n labelers,\n viewer,\n })\n\n const result = await importContacts(\n { ...input.body, hydrateCtx: hydrateCtx.copy({ viewer }) },\n ctx,\n )\n\n return {\n encoding: 'application/json',\n body: result,\n }\n },\n })\n}\n\nconst skeleton = async (\n input: SkeletonFnInput<Context, Params>,\n): Promise<SkeletonState> => {\n const { params, ctx } = input\n const actor = params.hydrateCtx.viewer\n // TODO: Error handling.\n const { matches } = await ctx.rolodexClient.importContacts({\n actor: params.hydrateCtx.viewer,\n contacts: params.contacts,\n token: params.token,\n })\n return {\n actor,\n matches,\n }\n}\n\nconst hydration = async (\n input: HydrationFnInput<Context, Params, SkeletonState>,\n) => {\n const { ctx, params, skeleton } = input\n const { matches } = skeleton\n const subjects = matches.map((m) => m.subject)\n return ctx.hydrator.hydrateProfiles(subjects, params.hydrateCtx)\n}\n\nconst presentation = (input: {\n ctx: Context\n params: Params\n skeleton: SkeletonState\n hydration: HydrationState\n}) => {\n const { ctx, skeleton, hydration } = input\n const matchesAndContactIndexes = mapDefined(\n skeleton.matches,\n ({ subject, inputIndex }): MatchAndContactIndex | undefined => {\n const profile = ctx.views.profile(subject, hydration)\n\n if (!profile) {\n return undefined\n }\n\n return {\n contactIndex: inputIndex,\n match: profile,\n }\n },\n )\n return { matchesAndContactIndexes }\n}\n\ntype Context = {\n hydrator: Hydrator\n rolodexClient: RolodexClient\n views: Views\n}\n\ntype Params = InputSchema & {\n hydrateCtx: HydrateCtx & { viewer: string }\n}\n\ntype SkeletonState = {\n actor: string\n matches: ImportContactsMatch[]\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import { AppContext } from '../../../../context';
2
+ import { Server } from '../../../../lexicon';
3
+ export default function (server: Server, ctx: AppContext): void;
4
+ //# sourceMappingURL=removeData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"removeData.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/removeData.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAG5C,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAkBvD"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const util_1 = require("./util");
5
+ function default_1(server, ctx) {
6
+ server.app.bsky.contact.removeData({
7
+ auth: ctx.authVerifier.standard,
8
+ handler: async ({ auth }) => {
9
+ (0, util_1.assertRolodexOrThrowUnimplemented)(ctx);
10
+ const actor = auth.credentials.iss;
11
+ // TODO: Error handling.
12
+ await ctx.rolodexClient.removeData({
13
+ actor,
14
+ });
15
+ return {
16
+ encoding: 'application/json',
17
+ body: {},
18
+ };
19
+ },
20
+ });
21
+ }
22
+ //# sourceMappingURL=removeData.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"removeData.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/removeData.ts"],"names":[],"mappings":";;AAIA,4BAkBC;AApBD,iCAA0D;AAE1D,mBAAyB,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;QACjC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,QAAQ;QAC/B,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;YAC1B,IAAA,wCAAiC,EAAC,GAAG,CAAC,CAAA;YAEtC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YAClC,wBAAwB;YACxB,MAAM,GAAG,CAAC,aAAa,CAAC,UAAU,CAAC;gBACjC,KAAK;aACN,CAAC,CAAA;YAEF,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,EAAE;aACT,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { AppContext } from '../../../../context'\nimport { Server } from '../../../../lexicon'\nimport { assertRolodexOrThrowUnimplemented } from './util'\n\nexport default function (server: Server, ctx: AppContext) {\n server.app.bsky.contact.removeData({\n auth: ctx.authVerifier.standard,\n handler: async ({ auth }) => {\n assertRolodexOrThrowUnimplemented(ctx)\n\n const actor = auth.credentials.iss\n // TODO: Error handling.\n await ctx.rolodexClient.removeData({\n actor,\n })\n\n return {\n encoding: 'application/json',\n body: {},\n }\n },\n })\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import { AppContext } from '../../../../context';
2
+ import { Server } from '../../../../lexicon';
3
+ export default function (server: Server, ctx: AppContext): void;
4
+ //# sourceMappingURL=startPhoneVerification.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startPhoneVerification.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/startPhoneVerification.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAG5C,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAmBvD"}
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.default = default_1;
4
+ const util_1 = require("./util");
5
+ function default_1(server, ctx) {
6
+ server.app.bsky.contact.startPhoneVerification({
7
+ auth: ctx.authVerifier.standard,
8
+ handler: async ({ auth, input }) => {
9
+ (0, util_1.assertRolodexOrThrowUnimplemented)(ctx);
10
+ const actor = auth.credentials.iss;
11
+ // TODO: Error handling.
12
+ await ctx.rolodexClient.startPhoneVerification({
13
+ actor,
14
+ phone: input.body.phone,
15
+ });
16
+ return {
17
+ encoding: 'application/json',
18
+ body: {},
19
+ };
20
+ },
21
+ });
22
+ }
23
+ //# sourceMappingURL=startPhoneVerification.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startPhoneVerification.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/startPhoneVerification.ts"],"names":[],"mappings":";;AAIA,4BAmBC;AArBD,iCAA0D;AAE1D,mBAAyB,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC;QAC7C,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,QAAQ;QAC/B,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE;YACjC,IAAA,wCAAiC,EAAC,GAAG,CAAC,CAAA;YAEtC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YAClC,wBAAwB;YACxB,MAAM,GAAG,CAAC,aAAa,CAAC,sBAAsB,CAAC;gBAC7C,KAAK;gBACL,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK;aACxB,CAAC,CAAA;YAEF,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,EAAE;aACT,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { AppContext } from '../../../../context'\nimport { Server } from '../../../../lexicon'\nimport { assertRolodexOrThrowUnimplemented } from './util'\n\nexport default function (server: Server, ctx: AppContext) {\n server.app.bsky.contact.startPhoneVerification({\n auth: ctx.authVerifier.standard,\n handler: async ({ auth, input }) => {\n assertRolodexOrThrowUnimplemented(ctx)\n\n const actor = auth.credentials.iss\n // TODO: Error handling.\n await ctx.rolodexClient.startPhoneVerification({\n actor,\n phone: input.body.phone,\n })\n\n return {\n encoding: 'application/json',\n body: {},\n }\n },\n })\n}\n"]}
@@ -0,0 +1,6 @@
1
+ import { AppContext } from '../../../..';
2
+ import { RolodexClient } from '../../../../rolodex';
3
+ export declare function assertRolodexOrThrowUnimplemented(ctx: AppContext): asserts ctx is AppContext & {
4
+ rolodexClient: RolodexClient;
5
+ };
6
+ //# sourceMappingURL=util.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/util.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAEnD,wBAAgB,iCAAiC,CAC/C,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,GAAG,IAAI,UAAU,GAAG;IAAE,aAAa,EAAE,aAAa,CAAA;CAAE,CAM9D"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertRolodexOrThrowUnimplemented = assertRolodexOrThrowUnimplemented;
4
+ const xrpc_server_1 = require("@atproto/xrpc-server");
5
+ function assertRolodexOrThrowUnimplemented(ctx) {
6
+ if (!ctx.rolodexClient) {
7
+ throw new xrpc_server_1.MethodNotImplementedError('This service is not configured to support contact imports.');
8
+ }
9
+ }
10
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/util.ts"],"names":[],"mappings":";;AAIA,8EAQC;AAZD,sDAAgE;AAIhE,SAAgB,iCAAiC,CAC/C,GAAe;IAEf,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QACvB,MAAM,IAAI,uCAAyB,CACjC,4DAA4D,CAC7D,CAAA;IACH,CAAC;AACH,CAAC","sourcesContent":["import { MethodNotImplementedError } from '@atproto/xrpc-server'\nimport { AppContext } from '../../../..'\nimport { RolodexClient } from '../../../../rolodex'\n\nexport function assertRolodexOrThrowUnimplemented(\n ctx: AppContext,\n): asserts ctx is AppContext & { rolodexClient: RolodexClient } {\n if (!ctx.rolodexClient) {\n throw new MethodNotImplementedError(\n 'This service is not configured to support contact imports.',\n )\n }\n}\n"]}
@@ -0,0 +1,4 @@
1
+ import { AppContext } from '../../../../context';
2
+ import { Server } from '../../../../lexicon';
3
+ export default function (server: Server, ctx: AppContext): void;
4
+ //# sourceMappingURL=verifyPhone.d.ts.map