@atproto/bsky 0.0.201 → 0.0.203

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 (126) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/api/age-assurance/const.d.ts.map +1 -1
  3. package/dist/api/age-assurance/const.js +20 -0
  4. package/dist/api/age-assurance/const.js.map +1 -1
  5. package/dist/api/app/bsky/ageassurance/begin.d.ts.map +1 -1
  6. package/dist/api/app/bsky/ageassurance/begin.js +15 -8
  7. package/dist/api/app/bsky/ageassurance/begin.js.map +1 -1
  8. package/dist/api/app/bsky/contact/dismissMatch.d.ts.map +1 -1
  9. package/dist/api/app/bsky/contact/dismissMatch.js +2 -3
  10. package/dist/api/app/bsky/contact/dismissMatch.js.map +1 -1
  11. package/dist/api/app/bsky/contact/getMatches.js +2 -3
  12. package/dist/api/app/bsky/contact/getMatches.js.map +1 -1
  13. package/dist/api/app/bsky/contact/getSyncStatus.d.ts.map +1 -1
  14. package/dist/api/app/bsky/contact/getSyncStatus.js +2 -3
  15. package/dist/api/app/bsky/contact/getSyncStatus.js.map +1 -1
  16. package/dist/api/app/bsky/contact/importContacts.js +2 -3
  17. package/dist/api/app/bsky/contact/importContacts.js.map +1 -1
  18. package/dist/api/app/bsky/contact/removeData.d.ts.map +1 -1
  19. package/dist/api/app/bsky/contact/removeData.js +2 -3
  20. package/dist/api/app/bsky/contact/removeData.js.map +1 -1
  21. package/dist/api/app/bsky/contact/sendNotification.d.ts.map +1 -1
  22. package/dist/api/app/bsky/contact/sendNotification.js.map +1 -1
  23. package/dist/api/app/bsky/contact/startPhoneVerification.d.ts.map +1 -1
  24. package/dist/api/app/bsky/contact/startPhoneVerification.js +2 -3
  25. package/dist/api/app/bsky/contact/startPhoneVerification.js.map +1 -1
  26. package/dist/api/app/bsky/contact/util.d.ts +7 -0
  27. package/dist/api/app/bsky/contact/util.d.ts.map +1 -1
  28. package/dist/api/app/bsky/contact/util.js +68 -0
  29. package/dist/api/app/bsky/contact/util.js.map +1 -1
  30. package/dist/api/app/bsky/contact/verifyPhone.d.ts.map +1 -1
  31. package/dist/api/app/bsky/contact/verifyPhone.js +2 -3
  32. package/dist/api/app/bsky/contact/verifyPhone.js.map +1 -1
  33. package/dist/api/index.d.ts +1 -0
  34. package/dist/api/index.d.ts.map +1 -1
  35. package/dist/api/index.js +4 -1
  36. package/dist/api/index.js.map +1 -1
  37. package/dist/api/sitemap.d.ts +4 -0
  38. package/dist/api/sitemap.d.ts.map +1 -0
  39. package/dist/api/sitemap.js +67 -0
  40. package/dist/api/sitemap.js.map +1 -0
  41. package/dist/data-plane/server/routes/index.d.ts.map +1 -1
  42. package/dist/data-plane/server/routes/index.js +2 -0
  43. package/dist/data-plane/server/routes/index.js.map +1 -1
  44. package/dist/data-plane/server/routes/profile.d.ts.map +1 -1
  45. package/dist/data-plane/server/routes/profile.js +10 -8
  46. package/dist/data-plane/server/routes/profile.js.map +1 -1
  47. package/dist/data-plane/server/routes/sitemap.d.ts +5 -0
  48. package/dist/data-plane/server/routes/sitemap.d.ts.map +1 -0
  49. package/dist/data-plane/server/routes/sitemap.js +38 -0
  50. package/dist/data-plane/server/routes/sitemap.js.map +1 -0
  51. package/dist/hydration/actor.js +1 -1
  52. package/dist/hydration/actor.js.map +1 -1
  53. package/dist/index.d.ts.map +1 -1
  54. package/dist/index.js +3 -0
  55. package/dist/index.js.map +1 -1
  56. package/dist/lexicon/lexicons.d.ts +100 -46
  57. package/dist/lexicon/lexicons.d.ts.map +1 -1
  58. package/dist/lexicon/lexicons.js +67 -22
  59. package/dist/lexicon/lexicons.js.map +1 -1
  60. package/dist/lexicon/types/app/bsky/contact/dismissMatch.d.ts +1 -1
  61. package/dist/lexicon/types/app/bsky/contact/dismissMatch.d.ts.map +1 -1
  62. package/dist/lexicon/types/app/bsky/contact/dismissMatch.js.map +1 -1
  63. package/dist/lexicon/types/app/bsky/contact/getMatches.d.ts +1 -1
  64. package/dist/lexicon/types/app/bsky/contact/getMatches.d.ts.map +1 -1
  65. package/dist/lexicon/types/app/bsky/contact/getMatches.js.map +1 -1
  66. package/dist/lexicon/types/app/bsky/contact/getSyncStatus.d.ts +1 -1
  67. package/dist/lexicon/types/app/bsky/contact/getSyncStatus.d.ts.map +1 -1
  68. package/dist/lexicon/types/app/bsky/contact/getSyncStatus.js.map +1 -1
  69. package/dist/lexicon/types/app/bsky/contact/importContacts.d.ts +1 -1
  70. package/dist/lexicon/types/app/bsky/contact/importContacts.d.ts.map +1 -1
  71. package/dist/lexicon/types/app/bsky/contact/importContacts.js.map +1 -1
  72. package/dist/lexicon/types/app/bsky/contact/removeData.d.ts +1 -1
  73. package/dist/lexicon/types/app/bsky/contact/removeData.d.ts.map +1 -1
  74. package/dist/lexicon/types/app/bsky/contact/removeData.js.map +1 -1
  75. package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.d.ts +1 -1
  76. package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.d.ts.map +1 -1
  77. package/dist/lexicon/types/app/bsky/contact/startPhoneVerification.js.map +1 -1
  78. package/dist/lexicon/types/app/bsky/contact/verifyPhone.d.ts +1 -1
  79. package/dist/lexicon/types/app/bsky/contact/verifyPhone.d.ts.map +1 -1
  80. package/dist/lexicon/types/app/bsky/contact/verifyPhone.js.map +1 -1
  81. package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts +1 -1
  82. package/dist/lexicon/types/app/bsky/notification/listNotifications.d.ts.map +1 -1
  83. package/dist/lexicon/types/app/bsky/notification/listNotifications.js.map +1 -1
  84. package/dist/proto/bsky_connect.d.ts +21 -1
  85. package/dist/proto/bsky_connect.d.ts.map +1 -1
  86. package/dist/proto/bsky_connect.js +20 -0
  87. package/dist/proto/bsky_connect.js.map +1 -1
  88. package/dist/proto/bsky_pb.d.ts +97 -0
  89. package/dist/proto/bsky_pb.d.ts.map +1 -1
  90. package/dist/proto/bsky_pb.js +256 -5
  91. package/dist/proto/bsky_pb.js.map +1 -1
  92. package/package.json +7 -7
  93. package/proto/bsky.proto +31 -0
  94. package/src/api/age-assurance/const.ts +20 -0
  95. package/src/api/app/bsky/ageassurance/begin.ts +21 -11
  96. package/src/api/app/bsky/contact/dismissMatch.ts +7 -6
  97. package/src/api/app/bsky/contact/getMatches.ts +8 -7
  98. package/src/api/app/bsky/contact/getSyncStatus.ts +6 -5
  99. package/src/api/app/bsky/contact/importContacts.ts +8 -7
  100. package/src/api/app/bsky/contact/removeData.ts +6 -5
  101. package/src/api/app/bsky/contact/sendNotification.ts +2 -1
  102. package/src/api/app/bsky/contact/startPhoneVerification.ts +7 -6
  103. package/src/api/app/bsky/contact/util.ts +80 -1
  104. package/src/api/app/bsky/contact/verifyPhone.ts +8 -7
  105. package/src/api/index.ts +4 -0
  106. package/src/api/sitemap.ts +76 -0
  107. package/src/data-plane/server/routes/index.ts +2 -0
  108. package/src/data-plane/server/routes/profile.ts +8 -6
  109. package/src/data-plane/server/routes/sitemap.ts +43 -0
  110. package/src/hydration/actor.ts +1 -1
  111. package/src/index.ts +6 -1
  112. package/src/lexicon/lexicons.ts +67 -22
  113. package/src/lexicon/types/app/bsky/contact/dismissMatch.ts +1 -1
  114. package/src/lexicon/types/app/bsky/contact/getMatches.ts +1 -1
  115. package/src/lexicon/types/app/bsky/contact/getSyncStatus.ts +1 -1
  116. package/src/lexicon/types/app/bsky/contact/importContacts.ts +6 -1
  117. package/src/lexicon/types/app/bsky/contact/removeData.ts +1 -1
  118. package/src/lexicon/types/app/bsky/contact/startPhoneVerification.ts +1 -1
  119. package/src/lexicon/types/app/bsky/contact/verifyPhone.ts +6 -1
  120. package/src/lexicon/types/app/bsky/notification/listNotifications.ts +1 -0
  121. package/src/proto/bsky_connect.ts +21 -1
  122. package/src/proto/bsky_pb.ts +188 -0
  123. package/tests/sitemap.test.ts +75 -0
  124. package/tests/views/age-assurance-v2.test.ts +51 -0
  125. package/tsconfig.build.tsbuildinfo +1 -1
  126. package/tsconfig.tests.tsbuildinfo +1 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @atproto/bsky
2
2
 
3
+ ## 0.0.203
4
+
5
+ ### Patch Changes
6
+
7
+ - [#4460](https://github.com/bluesky-social/atproto/pull/4460) [`dd0fe8d`](https://github.com/bluesky-social/atproto/commit/dd0fe8d5e74e19b2cb37aa6a307b88f1f6bd1c9c) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Add Age Assurance config for Tennessee
8
+
9
+ ## 0.0.202
10
+
11
+ ### Patch Changes
12
+
13
+ - [#4441](https://github.com/bluesky-social/atproto/pull/4441) [`45928bf`](https://github.com/bluesky-social/atproto/commit/45928bfcd6d220216078d5106f134fc3a81f564b) Thanks [@estrattonbailey](https://github.com/estrattonbailey)! - Fix optimistic response from `ageassurance.begin()`, retain existing `status` and `access` values if they exist.
14
+
3
15
  ## 0.0.201
4
16
 
5
17
  ### Patch Changes
@@ -1 +1 @@
1
- {"version":3,"file":"const.d.ts","sourceRoot":"","sources":["../../../src/api/age-assurance/const.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EAExB,MAAM,cAAc,CAAA;AAErB;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,EAAE,uBAAuB,CAAC,MAgI1D,CAAA"}
1
+ {"version":3,"file":"const.d.ts","sourceRoot":"","sources":["../../../src/api/age-assurance/const.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,uBAAuB,EAExB,MAAM,cAAc,CAAA;AAErB;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,EAAE,uBAAuB,CAAC,MAoJ1D,CAAA"}
@@ -137,6 +137,26 @@ exports.AGE_ASSURANCE_CONFIG = {
137
137
  },
138
138
  ],
139
139
  },
140
+ {
141
+ countryCode: 'US',
142
+ regionCode: 'TN',
143
+ rules: [
144
+ {
145
+ $type: api_1.ageAssuranceRuleIDs.IfAssuredOverAge,
146
+ age: 18,
147
+ access: 'full',
148
+ },
149
+ {
150
+ $type: api_1.ageAssuranceRuleIDs.IfDeclaredOverAge,
151
+ age: 18,
152
+ access: 'full',
153
+ },
154
+ {
155
+ $type: api_1.ageAssuranceRuleIDs.Default,
156
+ access: 'none',
157
+ },
158
+ ],
159
+ },
140
160
  ],
141
161
  };
142
162
  //# sourceMappingURL=const.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"const.js","sourceRoot":"","sources":["../../../src/api/age-assurance/const.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AppBskyAgeassuranceDefs,\n ageAssuranceRuleIDs as ids,\n} from '@atproto/api'\n\n/**\n * Age assurance configuration defining rules for various regions.\n *\n * NOTE: These rules are matched in order, and the first matching rule\n * determines the access level granted.\n *\n * NOTE: all regions MUST have a default rule as the last rule.\n */\nexport const AGE_ASSURANCE_CONFIG: AppBskyAgeassuranceDefs.Config = {\n regions: [\n {\n countryCode: 'GB',\n regionCode: undefined,\n rules: [\n {\n $type: ids.IfAssuredOverAge,\n age: 18,\n access: 'full',\n },\n {\n $type: ids.IfDeclaredOverAge,\n age: 13,\n access: 'safe',\n },\n {\n $type: ids.Default,\n access: 'none',\n },\n ],\n },\n {\n countryCode: 'AU',\n regionCode: undefined,\n rules: [\n {\n $type: ids.IfAccountNewerThan,\n date: '2025-12-10T00:00:00Z',\n access: 'none',\n },\n {\n $type: ids.IfAssuredOverAge,\n age: 18,\n access: 'full',\n },\n {\n $type: ids.IfAssuredOverAge,\n age: 16,\n access: 'safe',\n },\n {\n $type: ids.IfDeclaredOverAge,\n age: 16,\n access: 'safe',\n },\n {\n $type: ids.Default,\n access: 'none',\n },\n ],\n },\n {\n countryCode: 'US',\n regionCode: 'SD',\n rules: [\n {\n $type: ids.IfAssuredOverAge,\n age: 18,\n access: 'full',\n },\n {\n $type: ids.IfDeclaredOverAge,\n age: 13,\n access: 'safe',\n },\n {\n $type: ids.Default,\n access: 'none',\n },\n ],\n },\n {\n countryCode: 'US',\n regionCode: 'WY',\n rules: [\n {\n $type: ids.IfAssuredOverAge,\n age: 18,\n access: 'full',\n },\n {\n $type: ids.IfDeclaredOverAge,\n age: 13,\n access: 'safe',\n },\n {\n $type: ids.Default,\n access: 'none',\n },\n ],\n },\n {\n countryCode: 'US',\n regionCode: 'OH',\n rules: [\n {\n $type: ids.IfAssuredOverAge,\n age: 18,\n access: 'full',\n },\n {\n $type: ids.IfDeclaredOverAge,\n age: 13,\n access: 'safe',\n },\n {\n $type: ids.Default,\n access: 'none',\n },\n ],\n },\n {\n countryCode: 'US',\n regionCode: 'MS',\n rules: [\n {\n $type: ids.IfAssuredOverAge,\n age: 18,\n access: 'full',\n },\n {\n $type: ids.Default,\n access: 'none',\n },\n ],\n },\n ],\n}\n"]}
1
+ {"version":3,"file":"const.js","sourceRoot":"","sources":["../../../src/api/age-assurance/const.ts"],"names":[],"mappings":";;;AAAA,sCAGqB;AAErB;;;;;;;GAOG;AACU,QAAA,oBAAoB,GAAmC;IAClE,OAAO,EAAE;QACP;YACE,WAAW,EAAE,IAAI;YACjB,UAAU,EAAE,SAAS;YACrB,KAAK,EAAE;gBACL;oBACE,KAAK,EAAE,yBAAG,CAAC,gBAAgB;oBAC3B,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE,MAAM;iBACf;gBACD;oBACE,KAAK,EAAE,yBAAG,CAAC,iBAAiB;oBAC5B,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE,MAAM;iBACf;gBACD;oBACE,KAAK,EAAE,yBAAG,CAAC,OAAO;oBAClB,MAAM,EAAE,MAAM;iBACf;aACF;SACF;QACD;YACE,WAAW,EAAE,IAAI;YACjB,UAAU,EAAE,SAAS;YACrB,KAAK,EAAE;gBACL;oBACE,KAAK,EAAE,yBAAG,CAAC,kBAAkB;oBAC7B,IAAI,EAAE,sBAAsB;oBAC5B,MAAM,EAAE,MAAM;iBACf;gBACD;oBACE,KAAK,EAAE,yBAAG,CAAC,gBAAgB;oBAC3B,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE,MAAM;iBACf;gBACD;oBACE,KAAK,EAAE,yBAAG,CAAC,gBAAgB;oBAC3B,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE,MAAM;iBACf;gBACD;oBACE,KAAK,EAAE,yBAAG,CAAC,iBAAiB;oBAC5B,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE,MAAM;iBACf;gBACD;oBACE,KAAK,EAAE,yBAAG,CAAC,OAAO;oBAClB,MAAM,EAAE,MAAM;iBACf;aACF;SACF;QACD;YACE,WAAW,EAAE,IAAI;YACjB,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE;gBACL;oBACE,KAAK,EAAE,yBAAG,CAAC,gBAAgB;oBAC3B,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE,MAAM;iBACf;gBACD;oBACE,KAAK,EAAE,yBAAG,CAAC,iBAAiB;oBAC5B,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE,MAAM;iBACf;gBACD;oBACE,KAAK,EAAE,yBAAG,CAAC,OAAO;oBAClB,MAAM,EAAE,MAAM;iBACf;aACF;SACF;QACD;YACE,WAAW,EAAE,IAAI;YACjB,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE;gBACL;oBACE,KAAK,EAAE,yBAAG,CAAC,gBAAgB;oBAC3B,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE,MAAM;iBACf;gBACD;oBACE,KAAK,EAAE,yBAAG,CAAC,iBAAiB;oBAC5B,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE,MAAM;iBACf;gBACD;oBACE,KAAK,EAAE,yBAAG,CAAC,OAAO;oBAClB,MAAM,EAAE,MAAM;iBACf;aACF;SACF;QACD;YACE,WAAW,EAAE,IAAI;YACjB,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE;gBACL;oBACE,KAAK,EAAE,yBAAG,CAAC,gBAAgB;oBAC3B,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE,MAAM;iBACf;gBACD;oBACE,KAAK,EAAE,yBAAG,CAAC,iBAAiB;oBAC5B,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE,MAAM;iBACf;gBACD;oBACE,KAAK,EAAE,yBAAG,CAAC,OAAO;oBAClB,MAAM,EAAE,MAAM;iBACf;aACF;SACF;QACD;YACE,WAAW,EAAE,IAAI;YACjB,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE;gBACL;oBACE,KAAK,EAAE,yBAAG,CAAC,gBAAgB;oBAC3B,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE,MAAM;iBACf;gBACD;oBACE,KAAK,EAAE,yBAAG,CAAC,OAAO;oBAClB,MAAM,EAAE,MAAM;iBACf;aACF;SACF;QACD;YACE,WAAW,EAAE,IAAI;YACjB,UAAU,EAAE,IAAI;YAChB,KAAK,EAAE;gBACL;oBACE,KAAK,EAAE,yBAAG,CAAC,gBAAgB;oBAC3B,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE,MAAM;iBACf;gBACD;oBACE,KAAK,EAAE,yBAAG,CAAC,iBAAiB;oBAC5B,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE,MAAM;iBACf;gBACD;oBACE,KAAK,EAAE,yBAAG,CAAC,OAAO;oBAClB,MAAM,EAAE,MAAM;iBACf;aACF;SACF;KACF;CACF,CAAA","sourcesContent":["import {\n AppBskyAgeassuranceDefs,\n ageAssuranceRuleIDs as ids,\n} from '@atproto/api'\n\n/**\n * Age assurance configuration defining rules for various regions.\n *\n * NOTE: These rules are matched in order, and the first matching rule\n * determines the access level granted.\n *\n * NOTE: all regions MUST have a default rule as the last rule.\n */\nexport const AGE_ASSURANCE_CONFIG: AppBskyAgeassuranceDefs.Config = {\n regions: [\n {\n countryCode: 'GB',\n regionCode: undefined,\n rules: [\n {\n $type: ids.IfAssuredOverAge,\n age: 18,\n access: 'full',\n },\n {\n $type: ids.IfDeclaredOverAge,\n age: 13,\n access: 'safe',\n },\n {\n $type: ids.Default,\n access: 'none',\n },\n ],\n },\n {\n countryCode: 'AU',\n regionCode: undefined,\n rules: [\n {\n $type: ids.IfAccountNewerThan,\n date: '2025-12-10T00:00:00Z',\n access: 'none',\n },\n {\n $type: ids.IfAssuredOverAge,\n age: 18,\n access: 'full',\n },\n {\n $type: ids.IfAssuredOverAge,\n age: 16,\n access: 'safe',\n },\n {\n $type: ids.IfDeclaredOverAge,\n age: 16,\n access: 'safe',\n },\n {\n $type: ids.Default,\n access: 'none',\n },\n ],\n },\n {\n countryCode: 'US',\n regionCode: 'SD',\n rules: [\n {\n $type: ids.IfAssuredOverAge,\n age: 18,\n access: 'full',\n },\n {\n $type: ids.IfDeclaredOverAge,\n age: 13,\n access: 'safe',\n },\n {\n $type: ids.Default,\n access: 'none',\n },\n ],\n },\n {\n countryCode: 'US',\n regionCode: 'WY',\n rules: [\n {\n $type: ids.IfAssuredOverAge,\n age: 18,\n access: 'full',\n },\n {\n $type: ids.IfDeclaredOverAge,\n age: 13,\n access: 'safe',\n },\n {\n $type: ids.Default,\n access: 'none',\n },\n ],\n },\n {\n countryCode: 'US',\n regionCode: 'OH',\n rules: [\n {\n $type: ids.IfAssuredOverAge,\n age: 18,\n access: 'full',\n },\n {\n $type: ids.IfDeclaredOverAge,\n age: 13,\n access: 'safe',\n },\n {\n $type: ids.Default,\n access: 'none',\n },\n ],\n },\n {\n countryCode: 'US',\n regionCode: 'MS',\n rules: [\n {\n $type: ids.IfAssuredOverAge,\n age: 18,\n access: 'full',\n },\n {\n $type: ids.Default,\n access: 'none',\n },\n ],\n },\n {\n countryCode: 'US',\n regionCode: 'TN',\n rules: [\n {\n $type: ids.IfAssuredOverAge,\n age: 18,\n access: 'full',\n },\n {\n $type: ids.IfDeclaredOverAge,\n age: 18,\n access: 'full',\n },\n {\n $type: ids.Default,\n access: 'none',\n },\n ],\n },\n ],\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"begin.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/ageassurance/begin.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAkB5C,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAwGvD"}
1
+ {"version":3,"file":"begin.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/ageassurance/begin.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAkB5C,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAkHvD"}
@@ -25,10 +25,10 @@ function default_1(server, ctx) {
25
25
  }
26
26
  const actorDid = auth.credentials.iss;
27
27
  const actorInfo = await getAgeVerificationState(ctx, actorDid);
28
- if (actorInfo?.ageAssuranceStatus) {
29
- if (actorInfo.ageAssuranceStatus.status === 'blocked') {
30
- throw new xrpc_server_1.InvalidRequestError(`Cannot initiate age assurance flow from current state: ${actorInfo.ageAssuranceStatus.status}`, 'InvalidInitiation');
31
- }
28
+ const existingStatus = actorInfo?.ageAssuranceStatus?.status;
29
+ const existingAccess = actorInfo?.ageAssuranceStatus?.access;
30
+ if (existingStatus === 'blocked') {
31
+ throw new xrpc_server_1.InvalidRequestError(`Cannot initiate age assurance flow from current state: ${existingStatus}`, 'InvalidInitiation');
32
32
  }
33
33
  const attemptId = node_crypto_1.default.randomUUID();
34
34
  const { email, language, countryCode, regionCode } = validateInput(input.body);
@@ -82,14 +82,21 @@ function default_1(server, ctx) {
82
82
  language,
83
83
  });
84
84
  }
85
+ // If we have existing status/access for this region, retain it.
86
+ const nextStatus = existingStatus && existingStatus !== 'unknown'
87
+ ? existingStatus
88
+ : 'pending';
89
+ const nextAccess = existingAccess && existingAccess !== 'unknown'
90
+ ? existingAccess
91
+ : 'unknown';
85
92
  const event = await (0, stash_1.createEvent)(ctx, actorDid, {
86
93
  attemptId,
87
94
  email,
88
95
  // Assumes `app.set('trust proxy', ...)` configured with `true` or specific values.
89
96
  initIp: req.ip,
90
97
  initUa: (0, util_2.getClientUa)(req),
91
- status: 'pending',
92
- access: 'unknown',
98
+ status: nextStatus,
99
+ access: nextAccess,
93
100
  countryCode,
94
101
  regionCode,
95
102
  });
@@ -97,8 +104,8 @@ function default_1(server, ctx) {
97
104
  encoding: 'application/json',
98
105
  body: {
99
106
  lastInitiatedAt: event.createdAt,
100
- status: 'pending',
101
- access: 'unknown',
107
+ status: nextStatus,
108
+ access: nextAccess,
102
109
  },
103
110
  };
104
111
  },
@@ -1 +1 @@
1
- {"version":3,"file":"begin.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/ageassurance/begin.ts"],"names":[],"mappings":";;;;;AA2BA,4BAwGC;AAnID,8DAAgC;AAChC,2CAA4C;AAC5C,6EAA+D;AAC/D,sCAA0D;AAC1D,sDAG6B;AAI7B,+CAAsD;AAEtD,wDAAmE;AACnE,4DAGyC;AACzC,kFAIoD;AACpD,wDAA0D;AAC1D,sDAAkE;AAClE,4CAA+C;AAE/C,mBAAyB,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC;QACjC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,QAAQ;QAC/B,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE;YACtC,IAAI,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;gBACnB,MAAM,IAAI,uCAAyB,CACjC,0DAA0D,CAC3D,CAAA;YACH,CAAC;YAED,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;YACrC,MAAM,SAAS,GAAG,MAAM,uBAAuB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;YAE9D,IAAI,SAAS,EAAE,kBAAkB,EAAE,CAAC;gBAClC,IAAI,SAAS,CAAC,kBAAkB,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBACtD,MAAM,IAAI,iCAAmB,CAC3B,0DAA0D,SAAS,CAAC,kBAAkB,CAAC,MAAM,EAAE,EAC/F,mBAAmB,CACpB,CAAA;gBACH,CAAC;YACH,CAAC;YAED,MAAM,SAAS,GAAG,qBAAM,CAAC,UAAU,EAAE,CAAA;YACrC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,aAAa,CAChE,KAAK,CAAC,IAAI,CACX,CAAA;YAED,IAAI,eAAuB,CAAA;YAC3B,IAAI,CAAC;gBACH,eAAe,GAAG,IAAA,gDAA6B,EAAC;oBAC9C,OAAO,EAAE,4CAAyB,CAAC,EAAE;oBACrC,QAAQ;oBACR,SAAS;oBACT,WAAW;oBACX,UAAU;iBACX,CAAC,CAAA;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,GAAG,YAAY,kDAA+B,EAAE,CAAC;oBACnD,mBAAG,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;oBACzC,MAAM,IAAI,iCAAmB,CAC3B,mDAAmD,EACnD,YAAY,CACb,CAAA;gBACH,CAAC;gBACD,MAAM,GAAG,CAAA;YACX,CAAC;YAED;;;;eAIG;YACH,MAAM,MAAM,GAAG,IAAA,iCAA2B,EAAC,4BAAoB,EAAE;gBAC/D,WAAW;gBACX,UAAU;aACX,CAAC,CAAA;YACF,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM,OAAO,GAAG,8CAA8C,CAAA;gBAC9D,mBAAG,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,OAAO,CAAC,CAAA;gBACzD,MAAM,IAAI,iCAAmB,CAAC,OAAO,EAAE,oBAAoB,CAAC,CAAA;YAC9D,CAAC;YAED,MAAM,QAAQ,GAAG,IAAA,2BAAoB,EAAC,WAAW,EAAE,UAAU,CAAC,CAAA;YAE9D,IAAI,wBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC7C,sBAAsB;gBACtB,MAAM,GAAG,CAAC,SAAS,CAAC,wBAAwB,CAAC;oBAC3C,QAAQ;oBACR,KAAK;oBACL,eAAe;oBACf,QAAQ;iBACT,CAAC,CAAA;YACJ,CAAC;iBAAM,CAAC;gBACN,yEAAyE;gBACzE,MAAM,GAAG,CAAC,SAAS,CAAC,0BAA0B,CAAC;oBAC7C,QAAQ;oBACR,KAAK;oBACL,eAAe;oBACf,QAAQ;iBACT,CAAC,CAAA;YACJ,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,IAAA,mBAAW,EAAC,GAAG,EAAE,QAAQ,EAAE;gBAC7C,SAAS;gBACT,KAAK;gBACL,mFAAmF;gBACnF,MAAM,EAAE,GAAG,CAAC,EAAE;gBACd,MAAM,EAAE,IAAA,kBAAW,EAAC,GAAG,CAAC;gBACxB,MAAM,EAAE,SAAS;gBACjB,MAAM,EAAE,SAAS;gBACjB,WAAW;gBACX,UAAU;aACX,CAAC,CAAA;YAEF,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE;oBACJ,eAAe,EAAE,KAAK,CAAC,SAAS;oBAChC,MAAM,EAAE,SAAS;oBACjB,MAAM,EAAE,SAAS;iBAClB;aACF,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAe;IAC9D,IAAI,CAAC,IAAA,sBAAY,EAAC,KAAK,CAAC,IAAI,IAAA,+CAAiB,EAAC,KAAK,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,iCAAmB,CAC3B,oEAAoE,EACpE,cAAc,CACf,CAAA;IACH,CAAC;IAED,OAAO;QACL,KAAK;QACL,QAAQ,EAAE,+BAAuB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI;QACjE,GAAG,IAAI;KACR,CAAA;AACH,CAAC;AAED,KAAK,UAAU,uBAAuB,CACpC,GAAe,EACf,QAAgB;IAEhB,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,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC","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 (actorInfo.ageAssuranceStatus.status === 'blocked') {\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"]}
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 const existingStatus = actorInfo?.ageAssuranceStatus?.status\n const existingAccess = actorInfo?.ageAssuranceStatus?.access\n\n if (existingStatus === 'blocked') {\n throw new InvalidRequestError(\n `Cannot initiate age assurance flow from current state: ${existingStatus}`,\n 'InvalidInitiation',\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 // If we have existing status/access for this region, retain it.\n const nextStatus =\n existingStatus && existingStatus !== 'unknown'\n ? existingStatus\n : 'pending'\n const nextAccess =\n existingAccess && existingAccess !== 'unknown'\n ? existingAccess\n : 'unknown'\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: nextStatus,\n access: nextAccess,\n countryCode,\n regionCode,\n })\n\n return {\n encoding: 'application/json',\n body: {\n lastInitiatedAt: event.createdAt,\n status: nextStatus,\n access: nextAccess,\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"]}
@@ -1 +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"}
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,QAoBvD"}
@@ -8,11 +8,10 @@ function default_1(server, ctx) {
8
8
  handler: async ({ input, auth }) => {
9
9
  (0, util_1.assertRolodexOrThrowUnimplemented)(ctx);
10
10
  const actor = auth.credentials.iss;
11
- // TODO: Error handling.
12
- await ctx.rolodexClient.dismissMatch({
11
+ await (0, util_1.callRolodexClient)(ctx.rolodexClient.dismissMatch({
13
12
  actor,
14
13
  subject: input.body.subject,
15
- });
14
+ }));
16
15
  return {
17
16
  encoding: 'application/json',
18
17
  body: {},
@@ -1 +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"]}
1
+ {"version":3,"file":"dismissMatch.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/dismissMatch.ts"],"names":[],"mappings":";;AAIA,4BAoBC;AAtBD,iCAA6E;AAE7E,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,MAAM,IAAA,wBAAiB,EACrB,GAAG,CAAC,aAAa,CAAC,YAAY,CAAC;gBAC7B,KAAK;gBACL,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,OAAO;aAC5B,CAAC,CACH,CAAA;YAED,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, callRolodexClient } 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 await callRolodexClient(\n ctx.rolodexClient.dismissMatch({\n actor,\n subject: input.body.subject,\n }),\n )\n\n return {\n encoding: 'application/json',\n body: {},\n }\n },\n })\n}\n"]}
@@ -27,12 +27,11 @@ function default_1(server, ctx) {
27
27
  const skeleton = async (input) => {
28
28
  const { params, ctx } = input;
29
29
  const actor = params.hydrateCtx.viewer;
30
- // TODO: Error handling.
31
- const { cursor, subjects } = await ctx.rolodexClient.getMatches({
30
+ const { cursor, subjects } = await (0, util_1.callRolodexClient)(ctx.rolodexClient.getMatches({
32
31
  actor: params.hydrateCtx.viewer,
33
32
  limit: params.limit,
34
33
  cursor: params.cursor,
35
- });
34
+ }));
36
35
  return {
37
36
  actor,
38
37
  subjects,
@@ -1 +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"]}
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, callRolodexClient } 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 const { cursor, subjects } = await callRolodexClient(\n ctx.rolodexClient.getMatches({\n actor: params.hydrateCtx.viewer,\n limit: params.limit,\n cursor: params.cursor,\n }),\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"]}
@@ -1 +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"}
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,QA8BvD"}
@@ -8,10 +8,9 @@ function default_1(server, ctx) {
8
8
  handler: async ({ auth }) => {
9
9
  (0, util_1.assertRolodexOrThrowUnimplemented)(ctx);
10
10
  const actor = auth.credentials.iss;
11
- // TODO: Error handling.
12
- const res = await ctx.rolodexClient.getSyncStatus({
11
+ const res = await (0, util_1.callRolodexClient)(ctx.rolodexClient.getSyncStatus({
13
12
  actor,
14
- });
13
+ }));
15
14
  let syncStatus;
16
15
  if (res.status && res.status.syncedAt) {
17
16
  const syncedAt = res.status?.syncedAt?.toDate().toISOString();
@@ -1 +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"]}
1
+ {"version":3,"file":"getSyncStatus.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/getSyncStatus.ts"],"names":[],"mappings":";;AAKA,4BA8BC;AAhCD,iCAA6E;AAE7E,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,MAAM,GAAG,GAAG,MAAM,IAAA,wBAAiB,EACjC,GAAG,CAAC,aAAa,CAAC,aAAa,CAAC;gBAC9B,KAAK;aACN,CAAC,CACH,CAAA;YAED,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, callRolodexClient } 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 const res = await callRolodexClient(\n ctx.rolodexClient.getSyncStatus({\n actor,\n }),\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"]}
@@ -28,12 +28,11 @@ function default_1(server, ctx) {
28
28
  const skeleton = async (input) => {
29
29
  const { params, ctx } = input;
30
30
  const actor = params.hydrateCtx.viewer;
31
- // TODO: Error handling.
32
- const { matches } = await ctx.rolodexClient.importContacts({
31
+ const { matches } = await (0, util_1.callRolodexClient)(ctx.rolodexClient.importContacts({
33
32
  actor: params.hydrateCtx.viewer,
34
33
  contacts: params.contacts,
35
34
  token: params.token,
36
- });
35
+ }));
37
36
  return {
38
37
  actor,
39
38
  matches,
@@ -1 +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"]}
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, callRolodexClient } 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 const { matches } = await callRolodexClient(\n ctx.rolodexClient.importContacts({\n actor: params.hydrateCtx.viewer,\n contacts: params.contacts,\n token: params.token,\n }),\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"]}
@@ -1 +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"}
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,QAmBvD"}
@@ -8,10 +8,9 @@ function default_1(server, ctx) {
8
8
  handler: async ({ auth }) => {
9
9
  (0, util_1.assertRolodexOrThrowUnimplemented)(ctx);
10
10
  const actor = auth.credentials.iss;
11
- // TODO: Error handling.
12
- await ctx.rolodexClient.removeData({
11
+ await (0, util_1.callRolodexClient)(ctx.rolodexClient.removeData({
13
12
  actor,
14
- });
13
+ }));
15
14
  return {
16
15
  encoding: 'application/json',
17
16
  body: {},
@@ -1 +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"]}
1
+ {"version":3,"file":"removeData.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/removeData.ts"],"names":[],"mappings":";;AAIA,4BAmBC;AArBD,iCAA6E;AAE7E,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,MAAM,IAAA,wBAAiB,EACrB,GAAG,CAAC,aAAa,CAAC,UAAU,CAAC;gBAC3B,KAAK;aACN,CAAC,CACH,CAAA;YAED,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, callRolodexClient } 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 await callRolodexClient(\n ctx.rolodexClient.removeData({\n actor,\n }),\n )\n\n return {\n encoding: 'application/json',\n body: {},\n }\n },\n })\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"sendNotification.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/sendNotification.ts"],"names":[],"mappings":"AACA,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,QAyBvD"}
1
+ {"version":3,"file":"sendNotification.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/sendNotification.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAK5C,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,QAyBvD"}
@@ -1 +1 @@
1
- {"version":3,"file":"sendNotification.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/sendNotification.ts"],"names":[],"mappings":";;AAMA,4BAyBC;AA/BD,4CAAqC;AAGrC,6CAA8C;AAC9C,iCAA0D;AAE1D,mBAAyB,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC;QACvC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,IAAI;QAC3B,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;YAC3B,2HAA2H;YAC3H,IAAA,wCAAiC,EAAC,GAAG,CAAC,CAAA;YAEtC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,CAAA;YAE/B,MAAM,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC;gBAC3B,QAAQ,EAAE,IAAI;gBACd,SAAS,EAAE,kBAAU,CAAC,8BAA8B;gBACpD,OAAO,EAAE;oBACP,IAAI;oBACJ,EAAE;iBACH;gBACD,GAAG,EAAE,YAAG,CAAC,OAAO,EAAE;aACnB,CAAC,CAAA;YAEF,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,EAAE;aACT,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { TID } from '@atproto/common'\nimport { AppContext } from '../../../../context'\nimport { Server } from '../../../../lexicon'\nimport { Namespaces } from '../../../../stash'\nimport { assertRolodexOrThrowUnimplemented } from './util'\n\nexport default function (server: Server, ctx: AppContext) {\n server.app.bsky.contact.sendNotification({\n auth: ctx.authVerifier.role,\n handler: async ({ input }) => {\n // Assert rolodex even though we don't call it, it is a proxy to whether the app is configured with contact import support.\n assertRolodexOrThrowUnimplemented(ctx)\n\n const { from, to } = input.body\n\n await ctx.stashClient.create({\n actorDid: from,\n namespace: Namespaces.AppBskyContactDefsNotification,\n payload: {\n from,\n to,\n },\n key: TID.nextStr(),\n })\n\n return {\n encoding: 'application/json',\n body: {},\n }\n },\n })\n}\n"]}
1
+ {"version":3,"file":"sendNotification.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/sendNotification.ts"],"names":[],"mappings":";;AAOA,4BAyBC;AAhCD,4CAAqC;AAIrC,6CAA8C;AAC9C,iCAA0D;AAE1D,mBAAyB,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC;QACvC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC,IAAI;QAC3B,OAAO,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;YAC3B,2HAA2H;YAC3H,IAAA,wCAAiC,EAAC,GAAG,CAAC,CAAA;YAEtC,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,IAAI,CAAA;YAE/B,MAAM,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC;gBAC3B,QAAQ,EAAE,IAAI;gBACd,SAAS,EAAE,kBAAU,CAAC,8BAA8B;gBACpD,OAAO,EAAE;oBACP,IAAI;oBACJ,EAAE;iBACoB;gBACxB,GAAG,EAAE,YAAG,CAAC,OAAO,EAAE;aACnB,CAAC,CAAA;YAEF,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE,EAAE;aACT,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { TID } from '@atproto/common'\nimport { AppContext } from '../../../../context'\nimport { Server } from '../../../../lexicon'\nimport { Notification } from '../../../../lexicon/types/app/bsky/contact/defs'\nimport { Namespaces } from '../../../../stash'\nimport { assertRolodexOrThrowUnimplemented } from './util'\n\nexport default function (server: Server, ctx: AppContext) {\n server.app.bsky.contact.sendNotification({\n auth: ctx.authVerifier.role,\n handler: async ({ input }) => {\n // Assert rolodex even though we don't call it, it is a proxy to whether the app is configured with contact import support.\n assertRolodexOrThrowUnimplemented(ctx)\n\n const { from, to } = input.body\n\n await ctx.stashClient.create({\n actorDid: from,\n namespace: Namespaces.AppBskyContactDefsNotification,\n payload: {\n from,\n to,\n } satisfies Notification,\n key: TID.nextStr(),\n })\n\n return {\n encoding: 'application/json',\n body: {},\n }\n },\n })\n}\n"]}
@@ -1 +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"}
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,QAoBvD"}
@@ -8,11 +8,10 @@ function default_1(server, ctx) {
8
8
  handler: async ({ auth, input }) => {
9
9
  (0, util_1.assertRolodexOrThrowUnimplemented)(ctx);
10
10
  const actor = auth.credentials.iss;
11
- // TODO: Error handling.
12
- await ctx.rolodexClient.startPhoneVerification({
11
+ await (0, util_1.callRolodexClient)(ctx.rolodexClient.startPhoneVerification({
13
12
  actor,
14
13
  phone: input.body.phone,
15
- });
14
+ }));
16
15
  return {
17
16
  encoding: 'application/json',
18
17
  body: {},
@@ -1 +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"]}
1
+ {"version":3,"file":"startPhoneVerification.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/startPhoneVerification.ts"],"names":[],"mappings":";;AAIA,4BAoBC;AAtBD,iCAA6E;AAE7E,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,MAAM,IAAA,wBAAiB,EACrB,GAAG,CAAC,aAAa,CAAC,sBAAsB,CAAC;gBACvC,KAAK;gBACL,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK;aACxB,CAAC,CACH,CAAA;YAED,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, callRolodexClient } 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 await callRolodexClient(\n ctx.rolodexClient.startPhoneVerification({\n actor,\n phone: input.body.phone,\n }),\n )\n\n return {\n encoding: 'application/json',\n body: {},\n }\n },\n })\n}\n"]}
@@ -3,4 +3,11 @@ import { RolodexClient } from '../../../../rolodex';
3
3
  export declare function assertRolodexOrThrowUnimplemented(ctx: AppContext): asserts ctx is AppContext & {
4
4
  rolodexClient: RolodexClient;
5
5
  };
6
+ /**
7
+ * Helper to call Rolodex client methods and translate RPC errors to XRPC
8
+ * errors.
9
+ *
10
+ * These `reason` values need to stay in sync with the Rolodex service
11
+ */
12
+ export declare function callRolodexClient<T>(caller: T): Promise<T>;
6
13
  //# sourceMappingURL=util.d.ts.map
@@ -1 +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"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/util.ts"],"names":[],"mappings":"AAMA,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;AAgCD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,cAoCnD"}
@@ -1,10 +1,78 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.assertRolodexOrThrowUnimplemented = assertRolodexOrThrowUnimplemented;
4
+ exports.callRolodexClient = callRolodexClient;
5
+ const connect_1 = require("@connectrpc/connect");
4
6
  const xrpc_server_1 = require("@atproto/xrpc-server");
5
7
  function assertRolodexOrThrowUnimplemented(ctx) {
6
8
  if (!ctx.rolodexClient) {
7
9
  throw new xrpc_server_1.MethodNotImplementedError('This service is not configured to support contact imports.');
8
10
  }
9
11
  }
12
+ /**
13
+ * Converts UPPERCASE_ERROR from Rolodex to PascalCase for XRPC.
14
+ */
15
+ function convertErrorName(reason) {
16
+ switch (reason) {
17
+ case 'INVALID_DID':
18
+ return 'InvalidDid';
19
+ case 'INVALID_LIMIT':
20
+ return 'InvalidLimit';
21
+ case 'INVALID_CURSOR':
22
+ return 'InvalidCursor';
23
+ case 'INVALID_CONTACTS':
24
+ return 'InvalidContacts';
25
+ case 'TOO_MANY_CONTACTS':
26
+ return 'TooManyContacts';
27
+ case 'INVALID_TOKEN':
28
+ return 'InvalidToken';
29
+ case 'RATE_LIMIT_EXCEEDED':
30
+ return 'RateLimitExceeded';
31
+ case 'INVALID_PHONE':
32
+ return 'InvalidPhone';
33
+ case 'INVALID_CODE':
34
+ return 'InvalidCode';
35
+ case 'INTERNAL_ERROR':
36
+ return 'InternalError';
37
+ default:
38
+ return reason;
39
+ }
40
+ }
41
+ /**
42
+ * Helper to call Rolodex client methods and translate RPC errors to XRPC
43
+ * errors.
44
+ *
45
+ * These `reason` values need to stay in sync with the Rolodex service
46
+ */
47
+ async function callRolodexClient(caller) {
48
+ try {
49
+ return await caller;
50
+ }
51
+ catch (e) {
52
+ // might be something we want to handle
53
+ if (e instanceof connect_1.ConnectError) {
54
+ /**
55
+ * https://connectrpc.com/docs/protocol#error-end-stream
56
+ */
57
+ const details = e.details?.at(0);
58
+ const reason = details?.debug?.reason; // e.g. INVALID_DID
59
+ // Handle known error reasons
60
+ if (reason) {
61
+ const errorName = convertErrorName(reason);
62
+ // NOTE: Don't leak e.message to the response.
63
+ if (reason === 'INTERNAL_ERROR') {
64
+ throw new xrpc_server_1.InternalServerError('Upstream error', errorName, {
65
+ cause: e,
66
+ });
67
+ }
68
+ else {
69
+ throw new xrpc_server_1.InvalidRequestError('An error occurred', errorName, {
70
+ cause: e,
71
+ });
72
+ }
73
+ }
74
+ }
75
+ throw e;
76
+ }
77
+ }
10
78
  //# sourceMappingURL=util.js.map
@@ -1 +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"]}
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/util.ts"],"names":[],"mappings":";;AASA,8EAQC;AAsCD,8CAoCC;AA3FD,iDAAkD;AAClD,sDAI6B;AAI7B,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;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,MAAc;IACtC,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,aAAa;YAChB,OAAO,YAAY,CAAA;QACrB,KAAK,eAAe;YAClB,OAAO,cAAc,CAAA;QACvB,KAAK,gBAAgB;YACnB,OAAO,eAAe,CAAA;QACxB,KAAK,kBAAkB;YACrB,OAAO,iBAAiB,CAAA;QAC1B,KAAK,mBAAmB;YACtB,OAAO,iBAAiB,CAAA;QAC1B,KAAK,eAAe;YAClB,OAAO,cAAc,CAAA;QACvB,KAAK,qBAAqB;YACxB,OAAO,mBAAmB,CAAA;QAC5B,KAAK,eAAe;YAClB,OAAO,cAAc,CAAA;QACvB,KAAK,cAAc;YACjB,OAAO,aAAa,CAAA;QACtB,KAAK,gBAAgB;YACnB,OAAO,eAAe,CAAA;QACxB;YACE,OAAO,MAAM,CAAA;IACjB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACI,KAAK,UAAU,iBAAiB,CAAI,MAAS;IAClD,IAAI,CAAC;QACH,OAAO,MAAM,MAAM,CAAA;IACrB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,uCAAuC;QACvC,IAAI,CAAC,YAAY,sBAAY,EAAE,CAAC;YAC9B;;eAEG;YACH,MAAM,OAAO,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAOlB,CAAA;YACb,MAAM,MAAM,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,CAAA,CAAC,mBAAmB;YACzD,6BAA6B;YAC7B,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAA;gBAC1C,8CAA8C;gBAE9C,IAAI,MAAM,KAAK,gBAAgB,EAAE,CAAC;oBAChC,MAAM,IAAI,iCAAmB,CAAC,gBAAgB,EAAE,SAAS,EAAE;wBACzD,KAAK,EAAE,CAAC;qBACT,CAAC,CAAA;gBACJ,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,iCAAmB,CAAC,mBAAmB,EAAE,SAAS,EAAE;wBAC5D,KAAK,EAAE,CAAC;qBACT,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QACD,MAAM,CAAC,CAAA;IACT,CAAC;AACH,CAAC","sourcesContent":["import { ConnectError } from '@connectrpc/connect'\nimport {\n InternalServerError,\n InvalidRequestError,\n MethodNotImplementedError,\n} 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\n/**\n * Converts UPPERCASE_ERROR from Rolodex to PascalCase for XRPC.\n */\nfunction convertErrorName(reason: string): string {\n switch (reason) {\n case 'INVALID_DID':\n return 'InvalidDid'\n case 'INVALID_LIMIT':\n return 'InvalidLimit'\n case 'INVALID_CURSOR':\n return 'InvalidCursor'\n case 'INVALID_CONTACTS':\n return 'InvalidContacts'\n case 'TOO_MANY_CONTACTS':\n return 'TooManyContacts'\n case 'INVALID_TOKEN':\n return 'InvalidToken'\n case 'RATE_LIMIT_EXCEEDED':\n return 'RateLimitExceeded'\n case 'INVALID_PHONE':\n return 'InvalidPhone'\n case 'INVALID_CODE':\n return 'InvalidCode'\n case 'INTERNAL_ERROR':\n return 'InternalError'\n default:\n return reason\n }\n}\n\n/**\n * Helper to call Rolodex client methods and translate RPC errors to XRPC\n * errors.\n *\n * These `reason` values need to stay in sync with the Rolodex service\n */\nexport async function callRolodexClient<T>(caller: T) {\n try {\n return await caller\n } catch (e) {\n // might be something we want to handle\n if (e instanceof ConnectError) {\n /**\n * https://connectrpc.com/docs/protocol#error-end-stream\n */\n const details = e.details?.at(0) as\n | {\n debug: {\n reason: string\n message: string\n }\n }\n | undefined\n const reason = details?.debug?.reason // e.g. INVALID_DID\n // Handle known error reasons\n if (reason) {\n const errorName = convertErrorName(reason)\n // NOTE: Don't leak e.message to the response.\n\n if (reason === 'INTERNAL_ERROR') {\n throw new InternalServerError('Upstream error', errorName, {\n cause: e,\n })\n } else {\n throw new InvalidRequestError('An error occurred', errorName, {\n cause: e,\n })\n }\n }\n }\n throw e\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"verifyPhone.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/verifyPhone.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,QAsBvD"}
1
+ {"version":3,"file":"verifyPhone.d.ts","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/verifyPhone.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,QAuBvD"}
@@ -8,12 +8,11 @@ function default_1(server, ctx) {
8
8
  handler: async ({ auth, input }) => {
9
9
  (0, util_1.assertRolodexOrThrowUnimplemented)(ctx);
10
10
  const actor = auth.credentials.iss;
11
- // TODO: Error handling.
12
- const res = await ctx.rolodexClient.verifyPhone({
11
+ const res = await (0, util_1.callRolodexClient)(ctx.rolodexClient.verifyPhone({
13
12
  actor,
14
13
  verificationCode: input.body.code,
15
14
  phone: input.body.phone,
16
- });
15
+ }));
17
16
  return {
18
17
  encoding: 'application/json',
19
18
  body: {
@@ -1 +1 @@
1
- {"version":3,"file":"verifyPhone.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/verifyPhone.ts"],"names":[],"mappings":";;AAIA,4BAsBC;AAxBD,iCAA0D;AAE1D,mBAAyB,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;QAClC,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,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,WAAW,CAAC;gBAC9C,KAAK;gBACL,gBAAgB,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI;gBACjC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK;aACxB,CAAC,CAAA;YAEF,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE;oBACJ,KAAK,EAAE,GAAG,CAAC,KAAK;iBACjB;aACF,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.verifyPhone({\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 const res = await ctx.rolodexClient.verifyPhone({\n actor,\n verificationCode: input.body.code,\n phone: input.body.phone,\n })\n\n return {\n encoding: 'application/json',\n body: {\n token: res.token,\n },\n }\n },\n })\n}\n"]}
1
+ {"version":3,"file":"verifyPhone.js","sourceRoot":"","sources":["../../../../../src/api/app/bsky/contact/verifyPhone.ts"],"names":[],"mappings":";;AAIA,4BAuBC;AAzBD,iCAA6E;AAE7E,mBAAyB,MAAc,EAAE,GAAe;IACtD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC;QAClC,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,MAAM,GAAG,GAAG,MAAM,IAAA,wBAAiB,EACjC,GAAG,CAAC,aAAa,CAAC,WAAW,CAAC;gBAC5B,KAAK;gBACL,gBAAgB,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI;gBACjC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK;aACxB,CAAC,CACH,CAAA;YAED,OAAO;gBACL,QAAQ,EAAE,kBAAkB;gBAC5B,IAAI,EAAE;oBACJ,KAAK,EAAE,GAAG,CAAC,KAAK;iBACjB;aACF,CAAA;QACH,CAAC;KACF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { AppContext } from '../../../../context'\nimport { Server } from '../../../../lexicon'\nimport { assertRolodexOrThrowUnimplemented, callRolodexClient } from './util'\n\nexport default function (server: Server, ctx: AppContext) {\n server.app.bsky.contact.verifyPhone({\n auth: ctx.authVerifier.standard,\n handler: async ({ auth, input }) => {\n assertRolodexOrThrowUnimplemented(ctx)\n\n const actor = auth.credentials.iss\n const res = await callRolodexClient(\n ctx.rolodexClient.verifyPhone({\n actor,\n verificationCode: input.body.code,\n phone: input.body.phone,\n }),\n )\n\n return {\n encoding: 'application/json',\n body: {\n token: res.token,\n },\n }\n },\n })\n}\n"]}
@@ -4,5 +4,6 @@ export * as health from './health';
4
4
  export * as wellKnown from './well-known';
5
5
  export * as blobResolver from './blob-resolver';
6
6
  export * as external from './external';
7
+ export * as sitemap from './sitemap';
7
8
  export default function (server: Server, ctx: AppContext): Server;
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAwFnC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAA;AAElC,OAAO,KAAK,SAAS,MAAM,cAAc,CAAA;AAEzC,OAAO,KAAK,YAAY,MAAM,iBAAiB,CAAA;AAE/C,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAA;AAEtC,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,UA0FvD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAyFnC,OAAO,KAAK,MAAM,MAAM,UAAU,CAAA;AAElC,OAAO,KAAK,SAAS,MAAM,cAAc,CAAA;AAEzC,OAAO,KAAK,YAAY,MAAM,iBAAiB,CAAA;AAE/C,OAAO,KAAK,QAAQ,MAAM,YAAY,CAAA;AAEtC,OAAO,KAAK,OAAO,MAAM,WAAW,CAAA;AAEpC,MAAM,CAAC,OAAO,WAAW,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,UA2FvD"}