@atproto/api 0.1.3 β†’ 0.2.0

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 (205) hide show
  1. package/README.md +179 -25
  2. package/build.js +2 -1
  3. package/dist/agent.d.ts +11 -6
  4. package/dist/bsky-agent.d.ts +43 -0
  5. package/dist/client/index.d.ts +117 -215
  6. package/dist/client/lexicons.d.ts +1440 -1401
  7. package/dist/client/types/app/bsky/actor/defs.d.ts +47 -0
  8. package/dist/client/types/app/bsky/actor/getProfile.d.ts +2 -2
  9. package/dist/client/types/app/bsky/actor/getProfiles.d.ts +2 -2
  10. package/dist/client/types/app/bsky/actor/getSuggestions.d.ts +2 -2
  11. package/dist/client/types/app/bsky/actor/profile.d.ts +4 -60
  12. package/dist/client/types/app/bsky/actor/searchActors.d.ts +22 -0
  13. package/dist/client/types/app/bsky/actor/searchActorsTypeahead.d.ts +20 -0
  14. package/dist/client/types/app/bsky/actor/updateProfile.d.ts +3 -10
  15. package/dist/client/types/app/bsky/embed/external.d.ts +9 -13
  16. package/dist/client/types/app/bsky/embed/images.d.ts +9 -13
  17. package/dist/client/types/app/bsky/embed/record.d.ts +21 -13
  18. package/dist/client/types/app/bsky/embed/recordWithMedia.d.ts +24 -0
  19. package/dist/client/types/app/bsky/feed/defs.d.ts +77 -0
  20. package/dist/client/types/app/bsky/feed/getAuthorFeed.d.ts +4 -4
  21. package/dist/client/types/app/bsky/feed/getLikes.d.ts +34 -0
  22. package/dist/client/types/app/bsky/feed/getPostThread.d.ts +2 -24
  23. package/dist/client/types/app/bsky/feed/getRepostedBy.d.ts +3 -3
  24. package/dist/client/types/app/bsky/feed/getTimeline.d.ts +3 -3
  25. package/dist/client/types/app/bsky/feed/like.d.ts +9 -0
  26. package/dist/client/types/app/bsky/feed/post.d.ts +4 -29
  27. package/dist/client/types/app/bsky/graph/follow.d.ts +1 -2
  28. package/dist/client/types/app/bsky/graph/getFollowers.d.ts +5 -5
  29. package/dist/client/types/app/bsky/graph/getFollows.d.ts +5 -5
  30. package/dist/client/types/app/bsky/graph/getMutes.d.ts +3 -3
  31. package/dist/client/types/app/bsky/graph/muteActor.d.ts +17 -0
  32. package/dist/client/types/app/bsky/graph/unmuteActor.d.ts +17 -0
  33. package/dist/client/types/app/bsky/notification/getUnreadCount.d.ts +17 -0
  34. package/dist/client/types/app/bsky/notification/listNotifications.d.ts +35 -0
  35. package/dist/client/types/app/bsky/richtext/facet.d.ts +30 -0
  36. package/dist/client/types/app/bsky/unspecced/getPopular.d.ts +21 -0
  37. package/dist/client/types/com/atproto/admin/defs.d.ts +181 -0
  38. package/dist/client/types/com/atproto/admin/getModerationAction.d.ts +2 -2
  39. package/dist/client/types/com/atproto/admin/getModerationActions.d.ts +3 -3
  40. package/dist/client/types/com/atproto/admin/getModerationReport.d.ts +2 -2
  41. package/dist/client/types/com/atproto/admin/getModerationReports.d.ts +3 -3
  42. package/dist/client/types/com/atproto/admin/getRecord.d.ts +2 -2
  43. package/dist/client/types/com/atproto/admin/getRepo.d.ts +2 -2
  44. package/dist/client/types/com/atproto/admin/resolveModerationReports.d.ts +2 -2
  45. package/dist/client/types/com/atproto/admin/reverseModerationAction.d.ts +2 -2
  46. package/dist/client/types/com/atproto/admin/searchRepos.d.ts +3 -3
  47. package/dist/client/types/com/atproto/admin/takeModerationAction.d.ts +5 -6
  48. package/dist/client/types/com/atproto/identity/resolveHandle.d.ts +18 -0
  49. package/dist/client/types/com/atproto/identity/updateHandle.d.ts +17 -0
  50. package/dist/client/types/com/atproto/moderation/createReport.d.ts +38 -0
  51. package/dist/client/types/com/atproto/moderation/defs.d.ts +3 -0
  52. package/dist/client/types/com/atproto/repo/applyWrites.d.ts +47 -0
  53. package/dist/client/types/com/atproto/repo/createRecord.d.ts +7 -2
  54. package/dist/client/types/com/atproto/repo/deleteRecord.d.ts +7 -2
  55. package/dist/client/types/com/atproto/repo/describeRepo.d.ts +22 -0
  56. package/dist/client/types/com/atproto/repo/getRecord.d.ts +1 -1
  57. package/dist/client/types/com/atproto/repo/listRecords.d.ts +3 -3
  58. package/dist/client/types/com/atproto/repo/putRecord.d.ts +7 -2
  59. package/dist/client/types/com/atproto/repo/uploadBlob.d.ts +20 -0
  60. package/dist/client/types/com/atproto/server/createAccount.d.ts +44 -0
  61. package/dist/client/types/com/atproto/server/createInviteCode.d.ts +22 -0
  62. package/dist/client/types/com/atproto/server/createSession.d.ts +29 -0
  63. package/dist/client/types/com/atproto/server/deleteAccount.d.ts +25 -0
  64. package/dist/client/types/com/atproto/server/deleteSession.d.ts +13 -0
  65. package/dist/client/types/com/atproto/server/describeServer.d.ts +27 -0
  66. package/dist/client/types/com/atproto/server/getSession.d.ts +18 -0
  67. package/dist/client/types/com/atproto/server/refreshSession.d.ts +24 -0
  68. package/dist/client/types/com/atproto/server/requestAccountDelete.d.ts +13 -0
  69. package/dist/client/types/com/atproto/server/requestPasswordReset.d.ts +17 -0
  70. package/dist/client/types/com/atproto/server/resetPassword.d.ts +24 -0
  71. package/dist/client/types/com/atproto/sync/getBlob.d.ts +15 -0
  72. package/dist/client/types/com/atproto/sync/listBlobs.d.ts +20 -0
  73. package/dist/client/types/com/atproto/sync/notifyOfUpdate.d.ts +1 -0
  74. package/dist/client/types/com/atproto/sync/requestCrawl.d.ts +1 -1
  75. package/dist/client/types/com/atproto/sync/subscribeAllRepos.d.ts +9 -1
  76. package/dist/client/types/com/atproto/sync/subscribeRepos.d.ts +58 -0
  77. package/dist/helpers/bsky.d.ts +20 -0
  78. package/dist/index.d.ts +6 -0
  79. package/dist/index.js +8046 -3649
  80. package/dist/index.js.map +4 -4
  81. package/dist/mixins/bsky.d.ts +23 -0
  82. package/dist/rich-text/detection.d.ts +4 -0
  83. package/dist/rich-text/rich-text.d.ts +39 -0
  84. package/dist/rich-text/sanitization.d.ts +4 -0
  85. package/dist/rich-text/sanitize.d.ts +4 -0
  86. package/dist/rich-text/unicode.d.ts +11 -0
  87. package/dist/types.d.ts +2 -2
  88. package/docs/rn-fetch-handler.ts +88 -0
  89. package/package.json +4 -1
  90. package/src/agent.ts +51 -15
  91. package/src/bsky-agent.ts +228 -0
  92. package/src/client/index.ts +330 -581
  93. package/src/client/lexicons.ts +1824 -1777
  94. package/src/client/types/app/bsky/actor/defs.ts +97 -0
  95. package/src/client/types/app/bsky/actor/getProfile.ts +4 -3
  96. package/src/client/types/app/bsky/actor/getProfiles.ts +4 -3
  97. package/src/client/types/app/bsky/actor/getSuggestions.ts +4 -3
  98. package/src/client/types/app/bsky/actor/profile.ts +5 -95
  99. package/src/client/types/app/bsky/actor/{searchTypeahead.ts β†’ searchActors.ts} +6 -3
  100. package/src/client/types/app/bsky/actor/{search.ts β†’ searchActorsTypeahead.ts} +4 -5
  101. package/src/client/types/app/bsky/embed/external.ts +14 -13
  102. package/src/client/types/app/bsky/embed/images.ts +14 -15
  103. package/src/client/types/app/bsky/embed/record.ts +32 -25
  104. package/src/client/types/app/bsky/embed/recordWithMedia.ts +53 -0
  105. package/src/client/types/app/bsky/feed/defs.ts +156 -0
  106. package/src/client/types/app/bsky/feed/getAuthorFeed.ts +6 -5
  107. package/src/client/types/app/bsky/feed/{getVotes.ts β†’ getLikes.ts} +11 -12
  108. package/src/client/types/app/bsky/feed/getPostThread.ts +5 -48
  109. package/src/client/types/app/bsky/feed/getRepostedBy.ts +5 -4
  110. package/src/client/types/app/bsky/feed/getTimeline.ts +5 -4
  111. package/src/client/types/app/bsky/feed/{vote.ts β†’ like.ts} +4 -4
  112. package/src/client/types/app/bsky/feed/post.ts +10 -52
  113. package/src/client/types/app/bsky/feed/repost.ts +2 -1
  114. package/src/client/types/app/bsky/graph/follow.ts +3 -3
  115. package/src/client/types/app/bsky/graph/getFollowers.ts +7 -6
  116. package/src/client/types/app/bsky/graph/getFollows.ts +7 -6
  117. package/src/client/types/app/bsky/graph/getMutes.ts +5 -4
  118. package/src/client/types/app/bsky/graph/{mute.ts β†’ muteActor.ts} +3 -2
  119. package/src/client/types/app/bsky/graph/{unmute.ts β†’ unmuteActor.ts} +3 -2
  120. package/src/client/types/app/bsky/notification/{getCount.ts β†’ getUnreadCount.ts} +2 -1
  121. package/src/client/types/app/bsky/notification/{list.ts β†’ listNotifications.ts} +13 -9
  122. package/src/client/types/app/bsky/notification/updateSeen.ts +2 -1
  123. package/src/client/types/app/bsky/richtext/facet.ts +81 -0
  124. package/src/client/types/app/bsky/unspecced/getPopular.ts +38 -0
  125. package/src/client/types/com/atproto/admin/defs.ts +366 -0
  126. package/src/client/types/com/atproto/admin/getModerationAction.ts +4 -3
  127. package/src/client/types/com/atproto/admin/getModerationActions.ts +5 -4
  128. package/src/client/types/com/atproto/admin/getModerationReport.ts +4 -3
  129. package/src/client/types/com/atproto/admin/getModerationReports.ts +5 -4
  130. package/src/client/types/com/atproto/admin/getRecord.ts +4 -3
  131. package/src/client/types/com/atproto/admin/getRepo.ts +4 -3
  132. package/src/client/types/com/atproto/admin/resolveModerationReports.ts +4 -3
  133. package/src/client/types/com/atproto/admin/reverseModerationAction.ts +4 -3
  134. package/src/client/types/com/atproto/admin/searchRepos.ts +5 -4
  135. package/src/client/types/com/atproto/admin/takeModerationAction.ts +10 -10
  136. package/src/client/types/com/atproto/{handle/resolve.ts β†’ identity/resolveHandle.ts} +2 -1
  137. package/src/client/types/com/atproto/{handle/update.ts β†’ identity/updateHandle.ts} +2 -1
  138. package/src/client/types/com/atproto/{report/create.ts β†’ moderation/createReport.ts} +10 -10
  139. package/src/client/types/com/atproto/moderation/defs.ts +17 -0
  140. package/src/client/types/com/atproto/repo/{batchWrite.ts β†’ applyWrites.ts} +21 -12
  141. package/src/client/types/com/atproto/repo/createRecord.ts +15 -3
  142. package/src/client/types/com/atproto/repo/deleteRecord.ts +15 -3
  143. package/src/client/types/com/atproto/repo/{describe.ts β†’ describeRepo.ts} +3 -2
  144. package/src/client/types/com/atproto/repo/getRecord.ts +4 -3
  145. package/src/client/types/com/atproto/repo/listRecords.ts +7 -6
  146. package/src/client/types/com/atproto/repo/putRecord.ts +18 -6
  147. package/src/client/types/com/atproto/repo/strongRef.ts +2 -1
  148. package/src/client/types/com/atproto/{blob/upload.ts β†’ repo/uploadBlob.ts} +3 -2
  149. package/src/client/types/com/atproto/{account/create.ts β†’ server/createAccount.ts} +9 -1
  150. package/src/client/types/com/atproto/{account β†’ server}/createInviteCode.ts +2 -1
  151. package/src/client/types/com/atproto/{session/create.ts β†’ server/createSession.ts} +2 -1
  152. package/src/client/types/com/atproto/{account/delete.ts β†’ server/deleteAccount.ts} +2 -1
  153. package/src/client/types/com/atproto/{account/requestDelete.ts β†’ server/deleteSession.ts} +2 -1
  154. package/src/client/types/com/atproto/server/{getAccountsConfig.ts β†’ describeServer.ts} +4 -3
  155. package/src/client/types/com/atproto/{session/get.ts β†’ server/getSession.ts} +2 -1
  156. package/src/client/types/com/atproto/{session/refresh.ts β†’ server/refreshSession.ts} +2 -1
  157. package/src/client/types/com/atproto/{session/delete.ts β†’ server/requestAccountDelete.ts} +2 -1
  158. package/src/client/types/com/atproto/{account β†’ server}/requestPasswordReset.ts +2 -1
  159. package/src/client/types/com/atproto/{account β†’ server}/resetPassword.ts +2 -1
  160. package/src/client/types/com/atproto/sync/getBlob.ts +33 -0
  161. package/src/client/types/com/atproto/sync/getBlocks.ts +2 -1
  162. package/src/client/types/com/atproto/sync/getCheckout.ts +2 -1
  163. package/src/client/types/com/atproto/sync/getCommitPath.ts +2 -1
  164. package/src/client/types/com/atproto/sync/getHead.ts +2 -1
  165. package/src/client/types/com/atproto/sync/getRecord.ts +2 -1
  166. package/src/client/types/com/atproto/sync/getRepo.ts +2 -1
  167. package/src/client/types/com/atproto/sync/listBlobs.ts +40 -0
  168. package/src/client/types/com/atproto/sync/notifyOfUpdate.ts +6 -2
  169. package/src/client/types/com/atproto/sync/requestCrawl.ts +3 -2
  170. package/src/client/types/com/atproto/sync/subscribeRepos.ts +131 -0
  171. package/src/index.ts +12 -0
  172. package/src/rich-text/detection.ts +83 -0
  173. package/src/rich-text/rich-text.ts +401 -0
  174. package/src/rich-text/sanitization.ts +40 -0
  175. package/src/rich-text/unicode.ts +47 -0
  176. package/src/types.ts +2 -2
  177. package/tests/agent.test.ts +10 -6
  178. package/tests/bsky-agent.test.ts +140 -0
  179. package/tests/errors.test.ts +4 -4
  180. package/tests/rich-text-detection.test.ts +229 -0
  181. package/tests/rich-text-sanitization.test.ts +211 -0
  182. package/tests/rich-text.test.ts +661 -0
  183. package/tsconfig.build.tsbuildinfo +1 -1
  184. package/src/client/types/app/bsky/actor/ref.ts +0 -64
  185. package/src/client/types/app/bsky/actor/updateProfile.ts +0 -71
  186. package/src/client/types/app/bsky/feed/feedViewPost.ts +0 -64
  187. package/src/client/types/app/bsky/feed/setVote.ts +0 -40
  188. package/src/client/types/app/bsky/graph/assertCreator.ts +0 -9
  189. package/src/client/types/app/bsky/graph/assertMember.ts +0 -9
  190. package/src/client/types/app/bsky/graph/assertion.ts +0 -27
  191. package/src/client/types/app/bsky/graph/confirmation.ts +0 -28
  192. package/src/client/types/app/bsky/system/actorUser.ts +0 -9
  193. package/src/client/types/app/bsky/system/declRef.ts +0 -26
  194. package/src/client/types/app/bsky/system/declaration.ts +0 -24
  195. package/src/client/types/com/atproto/account/get.ts +0 -26
  196. package/src/client/types/com/atproto/admin/blob.ts +0 -84
  197. package/src/client/types/com/atproto/admin/moderationAction.ts +0 -118
  198. package/src/client/types/com/atproto/admin/moderationReport.ts +0 -64
  199. package/src/client/types/com/atproto/admin/record.ts +0 -92
  200. package/src/client/types/com/atproto/admin/repo.ts +0 -103
  201. package/src/client/types/com/atproto/repo/recordRef.ts +0 -25
  202. package/src/client/types/com/atproto/repo/repoRef.ts +0 -24
  203. package/src/client/types/com/atproto/report/reasonType.ts +0 -16
  204. package/src/client/types/com/atproto/report/subject.ts +0 -66
  205. package/src/client/types/com/atproto/sync/subscribeAllRepos.ts +0 -7
@@ -3,7 +3,7 @@ import {
3
3
  runTestServer,
4
4
  TestServerInfo,
5
5
  } from '@atproto/pds/tests/_util'
6
- import { AtpAgent, ComAtprotoAccountCreate } from '..'
6
+ import { AtpAgent, ComAtprotoServerCreateAccount } from '..'
7
7
 
8
8
  describe('errors', () => {
9
9
  let server: TestServerInfo
@@ -23,13 +23,13 @@ describe('errors', () => {
23
23
  })
24
24
 
25
25
  it('constructs the correct error instance', async () => {
26
- const res = client.api.com.atproto.account.create({
27
- handle: 'admin',
26
+ const res = client.api.com.atproto.server.createAccount({
27
+ handle: 'admin.blah',
28
28
  email: 'admin@test.com',
29
29
  password: 'password',
30
30
  })
31
31
  await expect(res).rejects.toThrow(
32
- ComAtprotoAccountCreate.InvalidHandleError,
32
+ ComAtprotoServerCreateAccount.UnsupportedDomainError,
33
33
  )
34
34
  })
35
35
  })
@@ -0,0 +1,229 @@
1
+ import { AtpAgent, RichText, RichTextSegment } from '../src'
2
+
3
+ describe('detectFacets', () => {
4
+ const agent = new AtpAgent({ service: 'http://localhost' })
5
+ agent.resolveHandle = ({ handle }: { handle: string }) => {
6
+ return Promise.resolve({
7
+ success: true,
8
+ headers: {},
9
+ data: { did: 'did:fake:' + handle },
10
+ })
11
+ }
12
+
13
+ const inputs = [
14
+ 'no mention',
15
+ '@handle.com middle end',
16
+ 'start @handle.com end',
17
+ 'start middle @handle.com',
18
+ '@handle.com @handle.com @handle.com',
19
+ '@full123-chars.test',
20
+ 'not@right',
21
+ '@handle.com!@#$chars',
22
+ '@handle.com\n@handle.com',
23
+ 'parenthetical (@handle.com)',
24
+ 'πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§ @handle.com πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§',
25
+
26
+ 'start https://middle.com end',
27
+ 'start https://middle.com/foo/bar end',
28
+ 'start https://middle.com/foo/bar?baz=bux end',
29
+ 'start https://middle.com/foo/bar?baz=bux#hash end',
30
+ 'https://start.com/foo/bar?baz=bux#hash middle end',
31
+ 'start middle https://end.com/foo/bar?baz=bux#hash',
32
+ 'https://newline1.com\nhttps://newline2.com',
33
+ 'πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§ https://middle.com πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§',
34
+
35
+ 'start middle.com end',
36
+ 'start middle.com/foo/bar end',
37
+ 'start middle.com/foo/bar?baz=bux end',
38
+ 'start middle.com/foo/bar?baz=bux#hash end',
39
+ 'start.com/foo/bar?baz=bux#hash middle end',
40
+ 'start middle end.com/foo/bar?baz=bux#hash',
41
+ 'newline1.com\nnewline2.com',
42
+
43
+ 'not.. a..url ..here',
44
+ 'e.g.',
45
+ 'something-cool.jpg',
46
+ 'website.com.jpg',
47
+ 'e.g./foo',
48
+ 'website.com.jpg/foo',
49
+
50
+ 'Classic article https://socket3.wordpress.com/2018/02/03/designing-windows-95s-user-interface/',
51
+ 'Classic article https://socket3.wordpress.com/2018/02/03/designing-windows-95s-user-interface/ ',
52
+ 'https://foo.com https://bar.com/whatever https://baz.com',
53
+ 'punctuation https://foo.com, https://bar.com/whatever; https://baz.com.',
54
+ 'parenthentical (https://foo.com)',
55
+ 'except for https://foo.com/thing_(cool)',
56
+ ]
57
+ const outputs: string[][][] = [
58
+ [['no mention']],
59
+ [['@handle.com', 'did:fake:handle.com'], [' middle end']],
60
+ [['start '], ['@handle.com', 'did:fake:handle.com'], [' end']],
61
+ [['start middle '], ['@handle.com', 'did:fake:handle.com']],
62
+ [
63
+ ['@handle.com', 'did:fake:handle.com'],
64
+ [' '],
65
+ ['@handle.com', 'did:fake:handle.com'],
66
+ [' '],
67
+ ['@handle.com', 'did:fake:handle.com'],
68
+ ],
69
+ [['@full123-chars.test', 'did:fake:full123-chars.test']],
70
+ [['not@right']],
71
+ [['@handle.com', 'did:fake:handle.com'], ['!@#$chars']],
72
+ [
73
+ ['@handle.com', 'did:fake:handle.com'],
74
+ ['\n'],
75
+ ['@handle.com', 'did:fake:handle.com'],
76
+ ],
77
+ [['parenthetical ('], ['@handle.com', 'did:fake:handle.com'], [')']],
78
+ [['πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§ '], ['@handle.com', 'did:fake:handle.com'], [' πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§']],
79
+
80
+ [['start '], ['https://middle.com', 'https://middle.com'], [' end']],
81
+ [
82
+ ['start '],
83
+ ['https://middle.com/foo/bar', 'https://middle.com/foo/bar'],
84
+ [' end'],
85
+ ],
86
+ [
87
+ ['start '],
88
+ [
89
+ 'https://middle.com/foo/bar?baz=bux',
90
+ 'https://middle.com/foo/bar?baz=bux',
91
+ ],
92
+ [' end'],
93
+ ],
94
+ [
95
+ ['start '],
96
+ [
97
+ 'https://middle.com/foo/bar?baz=bux#hash',
98
+ 'https://middle.com/foo/bar?baz=bux#hash',
99
+ ],
100
+ [' end'],
101
+ ],
102
+ [
103
+ [
104
+ 'https://start.com/foo/bar?baz=bux#hash',
105
+ 'https://start.com/foo/bar?baz=bux#hash',
106
+ ],
107
+ [' middle end'],
108
+ ],
109
+ [
110
+ ['start middle '],
111
+ [
112
+ 'https://end.com/foo/bar?baz=bux#hash',
113
+ 'https://end.com/foo/bar?baz=bux#hash',
114
+ ],
115
+ ],
116
+ [
117
+ ['https://newline1.com', 'https://newline1.com'],
118
+ ['\n'],
119
+ ['https://newline2.com', 'https://newline2.com'],
120
+ ],
121
+ [['πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§ '], ['https://middle.com', 'https://middle.com'], [' πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§']],
122
+
123
+ [['start '], ['middle.com', 'https://middle.com'], [' end']],
124
+ [
125
+ ['start '],
126
+ ['middle.com/foo/bar', 'https://middle.com/foo/bar'],
127
+ [' end'],
128
+ ],
129
+ [
130
+ ['start '],
131
+ ['middle.com/foo/bar?baz=bux', 'https://middle.com/foo/bar?baz=bux'],
132
+ [' end'],
133
+ ],
134
+ [
135
+ ['start '],
136
+ [
137
+ 'middle.com/foo/bar?baz=bux#hash',
138
+ 'https://middle.com/foo/bar?baz=bux#hash',
139
+ ],
140
+ [' end'],
141
+ ],
142
+ [
143
+ [
144
+ 'start.com/foo/bar?baz=bux#hash',
145
+ 'https://start.com/foo/bar?baz=bux#hash',
146
+ ],
147
+ [' middle end'],
148
+ ],
149
+ [
150
+ ['start middle '],
151
+ ['end.com/foo/bar?baz=bux#hash', 'https://end.com/foo/bar?baz=bux#hash'],
152
+ ],
153
+ [
154
+ ['newline1.com', 'https://newline1.com'],
155
+ ['\n'],
156
+ ['newline2.com', 'https://newline2.com'],
157
+ ],
158
+
159
+ [['not.. a..url ..here']],
160
+ [['e.g.']],
161
+ [['something-cool.jpg']],
162
+ [['website.com.jpg']],
163
+ [['e.g./foo']],
164
+ [['website.com.jpg/foo']],
165
+
166
+ [
167
+ ['Classic article '],
168
+ [
169
+ 'https://socket3.wordpress.com/2018/02/03/designing-windows-95s-user-interface/',
170
+ 'https://socket3.wordpress.com/2018/02/03/designing-windows-95s-user-interface/',
171
+ ],
172
+ ],
173
+ [
174
+ ['Classic article '],
175
+ [
176
+ 'https://socket3.wordpress.com/2018/02/03/designing-windows-95s-user-interface/',
177
+ 'https://socket3.wordpress.com/2018/02/03/designing-windows-95s-user-interface/',
178
+ ],
179
+ [' '],
180
+ ],
181
+ [
182
+ ['https://foo.com', 'https://foo.com'],
183
+ [' '],
184
+ ['https://bar.com/whatever', 'https://bar.com/whatever'],
185
+ [' '],
186
+ ['https://baz.com', 'https://baz.com'],
187
+ ],
188
+ [
189
+ ['punctuation '],
190
+ ['https://foo.com', 'https://foo.com'],
191
+ [', '],
192
+ ['https://bar.com/whatever', 'https://bar.com/whatever'],
193
+ ['; '],
194
+ ['https://baz.com', 'https://baz.com'],
195
+ ['.'],
196
+ ],
197
+ [['parenthentical ('], ['https://foo.com', 'https://foo.com'], [')']],
198
+ [
199
+ ['except for '],
200
+ ['https://foo.com/thing_(cool)', 'https://foo.com/thing_(cool)'],
201
+ ],
202
+ ]
203
+ it('correctly handles a set of text inputs', async () => {
204
+ for (let i = 0; i < inputs.length; i++) {
205
+ const input = inputs[i]
206
+ const rt = new RichText({ text: input })
207
+ await rt.detectFacets(agent)
208
+ expect(Array.from(rt.segments(), segmentToOutput)).toEqual(outputs[i])
209
+ }
210
+ })
211
+ })
212
+
213
+ function segmentToOutput(segment: RichTextSegment): string[] {
214
+ if (segment.facet) {
215
+ return [
216
+ segment.text,
217
+ segment.facet?.features.map((f) => {
218
+ if (f.did) {
219
+ return String(f.did)
220
+ }
221
+ if (f.uri) {
222
+ return String(f.uri)
223
+ }
224
+ return undefined
225
+ })?.[0] || '',
226
+ ]
227
+ }
228
+ return [segment.text]
229
+ }
@@ -0,0 +1,211 @@
1
+ import { RichText, sanitizeRichText, Facet, UnicodeString } from '../src'
2
+
3
+ describe('sanitizeRichText: cleanNewlines', () => {
4
+ it('removes more than two consecutive new lines', () => {
5
+ const input = new RichText({
6
+ text: 'test\n\n\n\n\ntest\n\n\n\n\n\n\ntest\n\n\n\n\n\n\ntest\n\n\n\n\n\n\ntest',
7
+ })
8
+ const output = sanitizeRichText(input, { cleanNewlines: true })
9
+ expect(String(output.unicodeText)).toEqual(
10
+ 'test\n\ntest\n\ntest\n\ntest\n\ntest',
11
+ )
12
+ })
13
+
14
+ it('removes more than two consecutive new lines w/fat unicode', () => {
15
+ const input = new RichText({
16
+ text: 'testπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§\n\n\n\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\n\n\n\n\n\ntestπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§\n\n\n\n\n\n\ntest\n\n\n\n\n\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test',
17
+ })
18
+ const output = sanitizeRichText(input, { cleanNewlines: true })
19
+ expect(String(output.unicodeText)).toEqual(
20
+ 'testπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\ntestπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§\n\ntest\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test',
21
+ )
22
+ })
23
+
24
+ it('removes more than two consecutive new lines with spaces', () => {
25
+ const input = new RichText({
26
+ text: 'test\n\n\n\n\ntest\n \n \n \n \n\n\ntest\n\n\n\n\n\n\ntest\n\n\n\n\n \n\ntest',
27
+ })
28
+ const output = sanitizeRichText(input, { cleanNewlines: true })
29
+ expect(String(output.unicodeText)).toEqual(
30
+ 'test\n\ntest\n\ntest\n\ntest\n\ntest',
31
+ )
32
+ })
33
+
34
+ it('returns original string if there are no consecutive new lines', () => {
35
+ const input = new RichText({ text: 'test\n\ntest\n\ntest\n\ntest\n\ntest' })
36
+ const output = sanitizeRichText(input, { cleanNewlines: true })
37
+ expect(String(output.unicodeText)).toEqual(String(input.unicodeText))
38
+ })
39
+
40
+ it('returns original string if there are no new lines', () => {
41
+ const input = new RichText({ text: 'test test test test test' })
42
+ const output = sanitizeRichText(input, { cleanNewlines: true })
43
+ expect(String(output.unicodeText)).toEqual(String(input.unicodeText))
44
+ })
45
+
46
+ it('returns empty string if input is empty', () => {
47
+ const input = new RichText({ text: '' })
48
+ const output = sanitizeRichText(input, { cleanNewlines: true })
49
+ expect(String(output.unicodeText)).toEqual('')
50
+ })
51
+
52
+ it('works with different types of new line characters', () => {
53
+ const input = new RichText({
54
+ text: 'test\r\ntest\n\rtest\rtest\n\n\n\ntest\n\r \n \n \n \n\n\ntest',
55
+ })
56
+ const output = sanitizeRichText(input, { cleanNewlines: true })
57
+ expect(String(output.unicodeText)).toEqual(
58
+ 'test\r\ntest\n\rtest\rtest\n\ntest\n\ntest',
59
+ )
60
+ })
61
+
62
+ it('removes more than two consecutive new lines with zero width space', () => {
63
+ const input = new RichText({
64
+ text: 'test\n\n\n\n\ntest\n\u200B\u200B\n\n\n\ntest\n \u200B\u200B \n\n\n\ntest\n\n\n\n\n\n\ntest',
65
+ })
66
+ const output = sanitizeRichText(input, { cleanNewlines: true })
67
+ expect(String(output.unicodeText)).toEqual(
68
+ 'test\n\ntest\n\ntest\n\ntest\n\ntest',
69
+ )
70
+ })
71
+
72
+ it('removes more than two consecutive new lines with zero width non-joiner', () => {
73
+ const input = new RichText({
74
+ text: 'test\n\n\n\n\ntest\n\u200C\u200C\n\n\n\ntest\n \u200C\u200C \n\n\n\ntest\n\n\n\n\n\n\ntest',
75
+ })
76
+ const output = sanitizeRichText(input, { cleanNewlines: true })
77
+ expect(String(output.unicodeText)).toEqual(
78
+ 'test\n\ntest\n\ntest\n\ntest\n\ntest',
79
+ )
80
+ })
81
+
82
+ it('removes more than two consecutive new lines with zero width joiner', () => {
83
+ const input = new RichText({
84
+ text: 'test\n\n\n\n\ntest\n\u200D\u200D\n\n\n\ntest\n \u200D\u200D \n\n\n\ntest\n\n\n\n\n\n\ntest',
85
+ })
86
+ const output = sanitizeRichText(input, { cleanNewlines: true })
87
+ expect(String(output.unicodeText)).toEqual(
88
+ 'test\n\ntest\n\ntest\n\ntest\n\ntest',
89
+ )
90
+ })
91
+
92
+ it('removes more than two consecutive new lines with soft hyphen', () => {
93
+ const input = new RichText({
94
+ text: 'test\n\n\n\n\ntest\n\u00AD\u00AD\n\n\n\ntest\n \u00AD\u00AD \n\n\n\ntest\n\n\n\n\n\n\ntest',
95
+ })
96
+ const output = sanitizeRichText(input, { cleanNewlines: true })
97
+ expect(String(output.unicodeText)).toEqual(
98
+ 'test\n\ntest\n\ntest\n\ntest\n\ntest',
99
+ )
100
+ })
101
+
102
+ it('removes more than two consecutive new lines with word joiner', () => {
103
+ const input = new RichText({
104
+ text: 'test\n\n\n\n\ntest\n\u2060\u2060\n\n\n\ntest\n \u2060\u2060 \n\n\n\ntest\n\n\n\n\n\n\ntest',
105
+ })
106
+ const output = sanitizeRichText(input, { cleanNewlines: true })
107
+ expect(String(output.unicodeText)).toEqual(
108
+ 'test\n\ntest\n\ntest\n\ntest\n\ntest',
109
+ )
110
+ })
111
+ })
112
+
113
+ describe('sanitizeRichText w/facets: cleanNewlines', () => {
114
+ it('preserves entities as expected', () => {
115
+ const input = new RichText({
116
+ text: 'test\n\n\n\n\ntest\n\n\n\n\n\n\ntest\n\n\n\n\n\n\ntest\n\n\n\n\n\n\ntest',
117
+ facets: [
118
+ { index: { byteStart: 0, byteEnd: 13 }, features: [{ $type: '' }] },
119
+ { index: { byteStart: 13, byteEnd: 24 }, features: [{ $type: '' }] },
120
+ { index: { byteStart: 9, byteEnd: 15 }, features: [{ $type: '' }] },
121
+ { index: { byteStart: 4, byteEnd: 9 }, features: [{ $type: '' }] },
122
+ ],
123
+ })
124
+ const output = sanitizeRichText(input, { cleanNewlines: true })
125
+ expect(facetToStr(String(input.unicodeText), input.facets?.[0])).toEqual(
126
+ 'test\n\n\n\n\ntest',
127
+ )
128
+ expect(facetToStr(String(input.unicodeText), input.facets?.[1])).toEqual(
129
+ '\n\n\n\n\n',
130
+ )
131
+ expect(facetToStr(String(input.unicodeText), input.facets?.[2])).toEqual(
132
+ 'test\n\n',
133
+ )
134
+ expect(facetToStr(String(input.unicodeText), input.facets?.[3])).toEqual(
135
+ '\n\n\n\n\n\n\ntest',
136
+ )
137
+ expect(String(output.unicodeText)).toEqual(
138
+ 'test\n\ntest\n\ntest\n\ntest\n\ntest',
139
+ )
140
+ expect(facetToStr(String(output.unicodeText), output.facets?.[0])).toEqual(
141
+ 'test\n\ntest',
142
+ )
143
+ expect(facetToStr(String(output.unicodeText), output.facets?.[1])).toEqual(
144
+ 'test',
145
+ )
146
+ expect(facetToStr(String(output.unicodeText), output.facets?.[2])).toEqual(
147
+ 'test',
148
+ )
149
+ expect(output.facets?.[3]).toEqual(undefined)
150
+ })
151
+
152
+ it('preserves entities as expected w/fat unicode', () => {
153
+ const str = new UnicodeString(
154
+ 'πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\n\n\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\n\n\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\n\n\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\n\n\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\n\n\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\n\n\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\n\n\n\n',
155
+ )
156
+ let lastI = 0
157
+ const makeFacet = (match: string) => {
158
+ const i = str.utf16.indexOf(match, lastI)
159
+ lastI = i + match.length
160
+ const byteStart = str.utf16IndexToUtf8Index(i)
161
+ const byteEnd = byteStart + new UnicodeString(match).length
162
+ return {
163
+ index: { byteStart, byteEnd },
164
+ features: [{ $type: '' }],
165
+ }
166
+ }
167
+
168
+ const input = new RichText({
169
+ text: str.utf16,
170
+ facets: [
171
+ makeFacet('πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\n\n\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test'),
172
+ makeFacet('\n\n\n\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test'),
173
+ makeFacet('πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\n'),
174
+ makeFacet('\n\n'),
175
+ ],
176
+ })
177
+ const output = sanitizeRichText(input, { cleanNewlines: true })
178
+ expect(facetToStr(String(input.unicodeText), input.facets?.[0])).toEqual(
179
+ 'πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\n\n\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test',
180
+ )
181
+ expect(facetToStr(String(input.unicodeText), input.facets?.[1])).toEqual(
182
+ '\n\n\n\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test',
183
+ )
184
+ expect(facetToStr(String(input.unicodeText), input.facets?.[2])).toEqual(
185
+ 'πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\n',
186
+ )
187
+ expect(facetToStr(String(input.unicodeText), input.facets?.[3])).toEqual(
188
+ '\n\n',
189
+ )
190
+ expect(String(output.unicodeText)).toEqual(
191
+ 'πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\n',
192
+ )
193
+ expect(facetToStr(String(output.unicodeText), output.facets?.[0])).toEqual(
194
+ 'πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test\n\nπŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test',
195
+ )
196
+ expect(facetToStr(String(output.unicodeText), output.facets?.[1])).toEqual(
197
+ 'πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test',
198
+ )
199
+ expect(facetToStr(String(output.unicodeText), output.facets?.[2])).toEqual(
200
+ 'πŸ‘¨β€πŸ‘©β€πŸ‘§β€πŸ‘§test',
201
+ )
202
+ expect(output.facets?.[3]).toEqual(undefined)
203
+ })
204
+ })
205
+
206
+ function facetToStr(str: string, ent?: Facet) {
207
+ if (!ent) {
208
+ return ''
209
+ }
210
+ return new UnicodeString(str).slice(ent.index.byteStart, ent.index.byteEnd)
211
+ }