@jeongsu816/matrix-bot-sdk 0.0.0-stage → 0.8.1

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 (377) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +50 -2
  3. package/lib/AdminApis.d.ts +52 -0
  4. package/lib/AdminApis.js +29 -0
  5. package/lib/AdminApis.js.map +1 -0
  6. package/lib/DMs.d.ts +48 -0
  7. package/lib/DMs.js +160 -0
  8. package/lib/DMs.js.map +1 -0
  9. package/lib/IFilter.d.ts +7 -0
  10. package/lib/IFilter.js +3 -0
  11. package/lib/IFilter.js.map +1 -0
  12. package/lib/MatrixAuth.d.ts +45 -0
  13. package/lib/MatrixAuth.js +125 -0
  14. package/lib/MatrixAuth.js.map +1 -0
  15. package/lib/MatrixClient.d.ts +834 -0
  16. package/lib/MatrixClient.js +2268 -0
  17. package/lib/MatrixClient.js.map +1 -0
  18. package/lib/PantalaimonClient.d.ts +42 -0
  19. package/lib/PantalaimonClient.js +44 -0
  20. package/lib/PantalaimonClient.js.map +1 -0
  21. package/lib/SynapseAdminApis.d.ts +350 -0
  22. package/lib/SynapseAdminApis.js +244 -0
  23. package/lib/SynapseAdminApis.js.map +1 -0
  24. package/lib/SynchronousMatrixClient.d.ts +82 -0
  25. package/lib/SynchronousMatrixClient.js +130 -0
  26. package/lib/SynchronousMatrixClient.js.map +1 -0
  27. package/lib/UnstableApis.d.ts +43 -0
  28. package/lib/UnstableApis.js +74 -0
  29. package/lib/UnstableApis.js.map +1 -0
  30. package/lib/appservice/Appservice.d.ts +328 -0
  31. package/lib/appservice/Appservice.js +803 -0
  32. package/lib/appservice/Appservice.js.map +1 -0
  33. package/lib/appservice/Intent.d.ts +113 -0
  34. package/lib/appservice/Intent.js +363 -0
  35. package/lib/appservice/Intent.js.map +1 -0
  36. package/lib/appservice/MatrixBridge.d.ts +85 -0
  37. package/lib/appservice/MatrixBridge.js +111 -0
  38. package/lib/appservice/MatrixBridge.js.map +1 -0
  39. package/lib/appservice/UnstableAppserviceApis.d.ts +41 -0
  40. package/lib/appservice/UnstableAppserviceApis.js +62 -0
  41. package/lib/appservice/UnstableAppserviceApis.js.map +1 -0
  42. package/lib/appservice/http_responses.d.ts +77 -0
  43. package/lib/appservice/http_responses.js +3 -0
  44. package/lib/appservice/http_responses.js.map +1 -0
  45. package/lib/b64.d.ts +42 -0
  46. package/lib/b64.js +68 -0
  47. package/lib/b64.js.map +1 -0
  48. package/lib/e2ee/CrossSigningBootstrap.d.ts +73 -0
  49. package/lib/e2ee/CrossSigningBootstrap.js +86 -0
  50. package/lib/e2ee/CrossSigningBootstrap.js.map +1 -0
  51. package/lib/e2ee/CryptoClient.d.ts +163 -0
  52. package/lib/e2ee/CryptoClient.js +382 -0
  53. package/lib/e2ee/CryptoClient.js.map +1 -0
  54. package/lib/e2ee/ICryptoRoomInformation.d.ts +8 -0
  55. package/lib/e2ee/ICryptoRoomInformation.js +3 -0
  56. package/lib/e2ee/ICryptoRoomInformation.js.map +1 -0
  57. package/lib/e2ee/RoomTracker.d.ts +41 -0
  58. package/lib/e2ee/RoomTracker.js +96 -0
  59. package/lib/e2ee/RoomTracker.js.map +1 -0
  60. package/lib/e2ee/RustEngine.d.ts +149 -0
  61. package/lib/e2ee/RustEngine.js +467 -0
  62. package/lib/e2ee/RustEngine.js.map +1 -0
  63. package/lib/e2ee/decorators.d.ts +10 -0
  64. package/lib/e2ee/decorators.js +37 -0
  65. package/lib/e2ee/decorators.js.map +1 -0
  66. package/lib/helpers/MatrixEntity.d.ts +37 -0
  67. package/lib/helpers/MatrixEntity.js +67 -0
  68. package/lib/helpers/MatrixEntity.js.map +1 -0
  69. package/lib/helpers/MatrixGlob.d.ts +22 -0
  70. package/lib/helpers/MatrixGlob.js +35 -0
  71. package/lib/helpers/MatrixGlob.js.map +1 -0
  72. package/lib/helpers/MentionPill.d.ts +40 -0
  73. package/lib/helpers/MentionPill.js +91 -0
  74. package/lib/helpers/MentionPill.js.map +1 -0
  75. package/lib/helpers/Permalinks.d.ts +58 -0
  76. package/lib/helpers/Permalinks.js +73 -0
  77. package/lib/helpers/Permalinks.js.map +1 -0
  78. package/lib/helpers/ProfileCache.d.ts +48 -0
  79. package/lib/helpers/ProfileCache.js +114 -0
  80. package/lib/helpers/ProfileCache.js.map +1 -0
  81. package/lib/helpers/RichReply.d.ts +17 -0
  82. package/lib/helpers/RichReply.js +47 -0
  83. package/lib/helpers/RichReply.js.map +1 -0
  84. package/lib/helpers/UnpaddedBase64.d.ts +31 -0
  85. package/lib/helpers/UnpaddedBase64.js +45 -0
  86. package/lib/helpers/UnpaddedBase64.js.map +1 -0
  87. package/lib/http.d.ts +17 -0
  88. package/lib/http.js +147 -0
  89. package/lib/http.js.map +1 -0
  90. package/lib/identity/IdentityClient.d.ts +93 -0
  91. package/lib/identity/IdentityClient.js +248 -0
  92. package/lib/identity/IdentityClient.js.map +1 -0
  93. package/lib/index.d.ts +91 -0
  94. package/lib/index.js +125 -0
  95. package/lib/index.js.map +1 -0
  96. package/lib/logging/ConsoleLogger.d.ts +12 -0
  97. package/lib/logging/ConsoleLogger.js +28 -0
  98. package/lib/logging/ConsoleLogger.js.map +1 -0
  99. package/lib/logging/ILogger.d.ts +36 -0
  100. package/lib/logging/ILogger.js +3 -0
  101. package/lib/logging/ILogger.js.map +1 -0
  102. package/lib/logging/LogService.d.ts +100 -0
  103. package/lib/logging/LogService.js +169 -0
  104. package/lib/logging/LogService.js.map +1 -0
  105. package/lib/logging/RichConsoleLogger.d.ts +20 -0
  106. package/lib/logging/RichConsoleLogger.js +41 -0
  107. package/lib/logging/RichConsoleLogger.js.map +1 -0
  108. package/lib/metrics/IMetricListener.d.ts +52 -0
  109. package/lib/metrics/IMetricListener.js +3 -0
  110. package/lib/metrics/IMetricListener.js.map +1 -0
  111. package/lib/metrics/Metrics.d.ts +66 -0
  112. package/lib/metrics/Metrics.js +128 -0
  113. package/lib/metrics/Metrics.js.map +1 -0
  114. package/lib/metrics/contexts.d.ts +51 -0
  115. package/lib/metrics/contexts.js +3 -0
  116. package/lib/metrics/contexts.js.map +1 -0
  117. package/lib/metrics/decorators.d.ts +15 -0
  118. package/lib/metrics/decorators.js +92 -0
  119. package/lib/metrics/decorators.js.map +1 -0
  120. package/lib/metrics/names.d.ts +45 -0
  121. package/lib/metrics/names.js +49 -0
  122. package/lib/metrics/names.js.map +1 -0
  123. package/lib/mixins/AutojoinRoomsMixin.d.ts +10 -0
  124. package/lib/mixins/AutojoinRoomsMixin.js +25 -0
  125. package/lib/mixins/AutojoinRoomsMixin.js.map +1 -0
  126. package/lib/mixins/AutojoinUpgradedRoomsMixin.d.ts +10 -0
  127. package/lib/mixins/AutojoinUpgradedRoomsMixin.js +40 -0
  128. package/lib/mixins/AutojoinUpgradedRoomsMixin.js.map +1 -0
  129. package/lib/models/Account.d.ts +8 -0
  130. package/lib/models/Account.js +3 -0
  131. package/lib/models/Account.js.map +1 -0
  132. package/lib/models/CreateRoom.d.ts +125 -0
  133. package/lib/models/CreateRoom.js +3 -0
  134. package/lib/models/CreateRoom.js.map +1 -0
  135. package/lib/models/Crypto.d.ts +167 -0
  136. package/lib/models/Crypto.js +31 -0
  137. package/lib/models/Crypto.js.map +1 -0
  138. package/lib/models/EventContext.d.ts +19 -0
  139. package/lib/models/EventContext.js +3 -0
  140. package/lib/models/EventContext.js.map +1 -0
  141. package/lib/models/IdentityServerModels.d.ts +20 -0
  142. package/lib/models/IdentityServerModels.js +3 -0
  143. package/lib/models/IdentityServerModels.js.map +1 -0
  144. package/lib/models/MSC2176.d.ts +42 -0
  145. package/lib/models/MSC2176.js +3 -0
  146. package/lib/models/MSC2176.js.map +1 -0
  147. package/lib/models/MatrixError.d.ts +38 -0
  148. package/lib/models/MatrixError.js +30 -0
  149. package/lib/models/MatrixError.js.map +1 -0
  150. package/lib/models/MatrixProfile.d.ts +43 -0
  151. package/lib/models/MatrixProfile.js +43 -0
  152. package/lib/models/MatrixProfile.js.map +1 -0
  153. package/lib/models/OpenIDConnect.d.ts +10 -0
  154. package/lib/models/OpenIDConnect.js +3 -0
  155. package/lib/models/OpenIDConnect.js.map +1 -0
  156. package/lib/models/Policies.d.ts +25 -0
  157. package/lib/models/Policies.js +3 -0
  158. package/lib/models/Policies.js.map +1 -0
  159. package/lib/models/PowerLevelAction.d.ts +27 -0
  160. package/lib/models/PowerLevelAction.js +32 -0
  161. package/lib/models/PowerLevelAction.js.map +1 -0
  162. package/lib/models/PowerLevelBounds.d.ts +15 -0
  163. package/lib/models/PowerLevelBounds.js +3 -0
  164. package/lib/models/PowerLevelBounds.js.map +1 -0
  165. package/lib/models/Presence.d.ts +25 -0
  166. package/lib/models/Presence.js +38 -0
  167. package/lib/models/Presence.js.map +1 -0
  168. package/lib/models/ServerVersions.d.ts +8 -0
  169. package/lib/models/ServerVersions.js +3 -0
  170. package/lib/models/ServerVersions.js.map +1 -0
  171. package/lib/models/Spaces.d.ts +116 -0
  172. package/lib/models/Spaces.js +91 -0
  173. package/lib/models/Spaces.js.map +1 -0
  174. package/lib/models/Threepid.d.ts +8 -0
  175. package/lib/models/Threepid.js +3 -0
  176. package/lib/models/Threepid.js.map +1 -0
  177. package/lib/models/events/AliasesEvent.d.ts +27 -0
  178. package/lib/models/events/AliasesEvent.js +27 -0
  179. package/lib/models/events/AliasesEvent.js.map +1 -0
  180. package/lib/models/events/CanonicalAliasEvent.d.ts +23 -0
  181. package/lib/models/events/CanonicalAliasEvent.js +21 -0
  182. package/lib/models/events/CanonicalAliasEvent.js.map +1 -0
  183. package/lib/models/events/CreateEvent.d.ts +63 -0
  184. package/lib/models/events/CreateEvent.js +33 -0
  185. package/lib/models/events/CreateEvent.js.map +1 -0
  186. package/lib/models/events/EncryptedRoomEvent.d.ts +42 -0
  187. package/lib/models/events/EncryptedRoomEvent.js +28 -0
  188. package/lib/models/events/EncryptedRoomEvent.js.map +1 -0
  189. package/lib/models/events/EncryptionEvent.d.ts +47 -0
  190. package/lib/models/events/EncryptionEvent.js +42 -0
  191. package/lib/models/events/EncryptionEvent.js.map +1 -0
  192. package/lib/models/events/Event.d.ts +26 -0
  193. package/lib/models/events/Event.js +40 -0
  194. package/lib/models/events/Event.js.map +1 -0
  195. package/lib/models/events/EventKind.d.ts +15 -0
  196. package/lib/models/events/EventKind.js +20 -0
  197. package/lib/models/events/EventKind.js.map +1 -0
  198. package/lib/models/events/InvalidEventError.d.ts +14 -0
  199. package/lib/models/events/InvalidEventError.js +24 -0
  200. package/lib/models/events/InvalidEventError.js.map +1 -0
  201. package/lib/models/events/JoinRulesEvent.d.ts +29 -0
  202. package/lib/models/events/JoinRulesEvent.js +21 -0
  203. package/lib/models/events/JoinRulesEvent.js.map +1 -0
  204. package/lib/models/events/MembershipEvent.d.ts +54 -0
  205. package/lib/models/events/MembershipEvent.js +49 -0
  206. package/lib/models/events/MembershipEvent.js.map +1 -0
  207. package/lib/models/events/MessageEvent.d.ts +233 -0
  208. package/lib/models/events/MessageEvent.js +49 -0
  209. package/lib/models/events/MessageEvent.js.map +1 -0
  210. package/lib/models/events/PinnedEventsEvent.d.ts +23 -0
  211. package/lib/models/events/PinnedEventsEvent.js +21 -0
  212. package/lib/models/events/PinnedEventsEvent.js.map +1 -0
  213. package/lib/models/events/PowerLevelsEvent.d.ts +96 -0
  214. package/lib/models/events/PowerLevelsEvent.js +70 -0
  215. package/lib/models/events/PowerLevelsEvent.js.map +1 -0
  216. package/lib/models/events/PresenceEvent.d.ts +56 -0
  217. package/lib/models/events/PresenceEvent.js +21 -0
  218. package/lib/models/events/PresenceEvent.js.map +1 -0
  219. package/lib/models/events/RedactionEvent.d.ts +28 -0
  220. package/lib/models/events/RedactionEvent.js +36 -0
  221. package/lib/models/events/RedactionEvent.js.map +1 -0
  222. package/lib/models/events/RoomAvatarEvent.d.ts +28 -0
  223. package/lib/models/events/RoomAvatarEvent.js +21 -0
  224. package/lib/models/events/RoomAvatarEvent.js.map +1 -0
  225. package/lib/models/events/RoomEvent.d.ts +58 -0
  226. package/lib/models/events/RoomEvent.js +57 -0
  227. package/lib/models/events/RoomEvent.js.map +1 -0
  228. package/lib/models/events/RoomNameEvent.d.ts +20 -0
  229. package/lib/models/events/RoomNameEvent.js +21 -0
  230. package/lib/models/events/RoomNameEvent.js.map +1 -0
  231. package/lib/models/events/RoomTopicEvent.d.ts +20 -0
  232. package/lib/models/events/RoomTopicEvent.js +21 -0
  233. package/lib/models/events/RoomTopicEvent.js.map +1 -0
  234. package/lib/models/events/SpaceChildEvent.d.ts +53 -0
  235. package/lib/models/events/SpaceChildEvent.js +49 -0
  236. package/lib/models/events/SpaceChildEvent.js.map +1 -0
  237. package/lib/models/events/converter.d.ts +8 -0
  238. package/lib/models/events/converter.js +50 -0
  239. package/lib/models/events/converter.js.map +1 -0
  240. package/lib/models/unstable/MediaInfo.d.ts +16 -0
  241. package/lib/models/unstable/MediaInfo.js +3 -0
  242. package/lib/models/unstable/MediaInfo.js.map +1 -0
  243. package/lib/preprocessors/IPreprocessor.d.ts +22 -0
  244. package/lib/preprocessors/IPreprocessor.js +3 -0
  245. package/lib/preprocessors/IPreprocessor.js.map +1 -0
  246. package/lib/preprocessors/RichRepliesPreprocessor.d.ts +67 -0
  247. package/lib/preprocessors/RichRepliesPreprocessor.js +112 -0
  248. package/lib/preprocessors/RichRepliesPreprocessor.js.map +1 -0
  249. package/lib/request.d.ts +13 -0
  250. package/lib/request.js +23 -0
  251. package/lib/request.js.map +1 -0
  252. package/lib/simple-validation.d.ts +10 -0
  253. package/lib/simple-validation.js +30 -0
  254. package/lib/simple-validation.js.map +1 -0
  255. package/lib/storage/IAppserviceStorageProvider.d.ts +48 -0
  256. package/lib/storage/IAppserviceStorageProvider.js +3 -0
  257. package/lib/storage/IAppserviceStorageProvider.js.map +1 -0
  258. package/lib/storage/ICryptoStorageProvider.d.ts +32 -0
  259. package/lib/storage/ICryptoStorageProvider.js +3 -0
  260. package/lib/storage/ICryptoStorageProvider.js.map +1 -0
  261. package/lib/storage/IStorageProvider.d.ts +47 -0
  262. package/lib/storage/IStorageProvider.js +3 -0
  263. package/lib/storage/IStorageProvider.js.map +1 -0
  264. package/lib/storage/MemoryStorageProvider.d.ts +26 -0
  265. package/lib/storage/MemoryStorageProvider.js +55 -0
  266. package/lib/storage/MemoryStorageProvider.js.map +1 -0
  267. package/lib/storage/RustSdkCryptoStorageProvider.d.ts +38 -0
  268. package/lib/storage/RustSdkCryptoStorageProvider.js +69 -0
  269. package/lib/storage/RustSdkCryptoStorageProvider.js.map +1 -0
  270. package/lib/storage/SimpleFsStorageProvider.d.ts +31 -0
  271. package/lib/storage/SimpleFsStorageProvider.js +122 -0
  272. package/lib/storage/SimpleFsStorageProvider.js.map +1 -0
  273. package/lib/storage/SimplePostgresStorageProvider.d.ts +32 -0
  274. package/lib/storage/SimplePostgresStorageProvider.js +148 -0
  275. package/lib/storage/SimplePostgresStorageProvider.js.map +1 -0
  276. package/lib/strategies/AppserviceJoinRoomStrategy.d.ts +14 -0
  277. package/lib/strategies/AppserviceJoinRoomStrategy.js +54 -0
  278. package/lib/strategies/AppserviceJoinRoomStrategy.js.map +1 -0
  279. package/lib/strategies/JoinRoomStrategy.d.ts +11 -0
  280. package/lib/strategies/JoinRoomStrategy.js +44 -0
  281. package/lib/strategies/JoinRoomStrategy.js.map +1 -0
  282. package/package.json +136 -4
  283. package/src/AdminApis.ts +60 -0
  284. package/src/DMs.ts +164 -0
  285. package/src/IFilter.ts +7 -0
  286. package/src/MatrixAuth.ts +129 -0
  287. package/src/MatrixClient.ts +2046 -0
  288. package/src/PantalaimonClient.ts +62 -0
  289. package/src/SynapseAdminApis.ts +482 -0
  290. package/src/SynchronousMatrixClient.ts +129 -0
  291. package/src/UnstableApis.ts +75 -0
  292. package/src/appservice/Appservice.ts +1089 -0
  293. package/src/appservice/Intent.ts +342 -0
  294. package/src/appservice/MatrixBridge.ts +139 -0
  295. package/src/appservice/UnstableAppserviceApis.ts +63 -0
  296. package/src/appservice/http_responses.ts +77 -0
  297. package/src/b64.ts +63 -0
  298. package/src/e2ee/CrossSigningBootstrap.ts +141 -0
  299. package/src/e2ee/CryptoClient.ts +378 -0
  300. package/src/e2ee/ICryptoRoomInformation.ts +9 -0
  301. package/src/e2ee/RoomTracker.ts +99 -0
  302. package/src/e2ee/RustEngine.ts +580 -0
  303. package/src/e2ee/decorators.ts +38 -0
  304. package/src/helpers/MatrixEntity.ts +65 -0
  305. package/src/helpers/MatrixGlob.ts +38 -0
  306. package/src/helpers/MentionPill.ts +95 -0
  307. package/src/helpers/Permalinks.ts +101 -0
  308. package/src/helpers/ProfileCache.ts +119 -0
  309. package/src/helpers/RichReply.ts +46 -0
  310. package/src/helpers/UnpaddedBase64.ts +44 -0
  311. package/src/http.ts +166 -0
  312. package/src/identity/IdentityClient.ts +225 -0
  313. package/src/index.ts +125 -0
  314. package/src/logging/ConsoleLogger.ts +31 -0
  315. package/src/logging/ILogger.ts +40 -0
  316. package/src/logging/LogService.ts +167 -0
  317. package/src/logging/RichConsoleLogger.ts +70 -0
  318. package/src/metrics/IMetricListener.ts +57 -0
  319. package/src/metrics/Metrics.ts +134 -0
  320. package/src/metrics/contexts.ts +56 -0
  321. package/src/metrics/decorators.ts +94 -0
  322. package/src/metrics/names.ts +53 -0
  323. package/src/mixins/AutojoinRoomsMixin.ts +24 -0
  324. package/src/mixins/AutojoinUpgradedRoomsMixin.ts +37 -0
  325. package/src/models/Account.ts +8 -0
  326. package/src/models/CreateRoom.ts +144 -0
  327. package/src/models/Crypto.ts +188 -0
  328. package/src/models/EventContext.ts +23 -0
  329. package/src/models/IdentityServerModels.ts +18 -0
  330. package/src/models/MSC2176.ts +47 -0
  331. package/src/models/MatrixError.ts +39 -0
  332. package/src/models/MatrixProfile.ts +55 -0
  333. package/src/models/OpenIDConnect.ts +10 -0
  334. package/src/models/Policies.ts +28 -0
  335. package/src/models/PowerLevelAction.ts +31 -0
  336. package/src/models/PowerLevelBounds.ts +16 -0
  337. package/src/models/Presence.ts +38 -0
  338. package/src/models/ServerVersions.ts +8 -0
  339. package/src/models/Spaces.ts +167 -0
  340. package/src/models/Threepid.ts +8 -0
  341. package/src/models/events/AliasesEvent.ts +37 -0
  342. package/src/models/events/CanonicalAliasEvent.ts +30 -0
  343. package/src/models/events/CreateEvent.ts +82 -0
  344. package/src/models/events/EncryptedRoomEvent.ts +58 -0
  345. package/src/models/events/EncryptionEvent.ts +63 -0
  346. package/src/models/events/Event.ts +38 -0
  347. package/src/models/events/EventKind.ts +16 -0
  348. package/src/models/events/InvalidEventError.ts +19 -0
  349. package/src/models/events/JoinRulesEvent.ts +37 -0
  350. package/src/models/events/MembershipEvent.ts +77 -0
  351. package/src/models/events/MessageEvent.ts +292 -0
  352. package/src/models/events/PinnedEventsEvent.ts +30 -0
  353. package/src/models/events/PowerLevelsEvent.ts +135 -0
  354. package/src/models/events/PresenceEvent.ts +69 -0
  355. package/src/models/events/RedactionEvent.ts +44 -0
  356. package/src/models/events/RoomAvatarEvent.ts +36 -0
  357. package/src/models/events/RoomEvent.ts +83 -0
  358. package/src/models/events/RoomNameEvent.ts +27 -0
  359. package/src/models/events/RoomTopicEvent.ts +27 -0
  360. package/src/models/events/SpaceChildEvent.ts +74 -0
  361. package/src/models/events/_MissingEvents.md +35 -0
  362. package/src/models/events/converter.ts +47 -0
  363. package/src/models/unstable/MediaInfo.ts +16 -0
  364. package/src/preprocessors/IPreprocessor.ts +24 -0
  365. package/src/preprocessors/RichRepliesPreprocessor.ts +159 -0
  366. package/src/request.ts +21 -0
  367. package/src/simple-validation.ts +30 -0
  368. package/src/storage/IAppserviceStorageProvider.ts +54 -0
  369. package/src/storage/ICryptoStorageProvider.ts +36 -0
  370. package/src/storage/IStorageProvider.ts +53 -0
  371. package/src/storage/MemoryStorageProvider.ts +65 -0
  372. package/src/storage/RustSdkCryptoStorageProvider.ts +81 -0
  373. package/src/storage/SimpleFsStorageProvider.ts +142 -0
  374. package/src/storage/SimplePostgresStorageProvider.ts +168 -0
  375. package/src/strategies/AppserviceJoinRoomStrategy.ts +47 -0
  376. package/src/strategies/JoinRoomStrategy.ts +45 -0
  377. package/tsconfig.json +22 -0
@@ -0,0 +1,38 @@
1
+ import * as globToRegexp from "glob-to-regexp";
2
+
3
+ /**
4
+ * Represents a common Matrix glob. This is commonly used
5
+ * for server ACLs and similar functions.
6
+ * @category Utilities
7
+ */
8
+ export class MatrixGlob {
9
+ /**
10
+ * The regular expression which represents this glob.
11
+ */
12
+ public readonly regex: RegExp;
13
+
14
+ /**
15
+ * Creates a new Matrix Glob
16
+ * @param {string} glob The glob to convert. Eg: "*.example.org"
17
+ */
18
+ constructor(glob: string) {
19
+ const globRegex = globToRegexp(glob, {
20
+ extended: false,
21
+ globstar: false,
22
+ });
23
+
24
+ // We need to convert `?` manually because globToRegexp's extended mode
25
+ // does more than we want it to.
26
+ const replaced = globRegex.toString().replace(/\\\?/g, ".");
27
+ this.regex = new RegExp(replaced.substring(1, replaced.length - 1));
28
+ }
29
+
30
+ /**
31
+ * Tests the glob against a value, returning true if it matches.
32
+ * @param {string} val The value to test.
33
+ * @returns {boolean} True if the value matches the glob, false otherwise.
34
+ */
35
+ public test(val: string): boolean {
36
+ return this.regex.test(val);
37
+ }
38
+ }
@@ -0,0 +1,95 @@
1
+ import { MatrixClient } from "../MatrixClient";
2
+ import { Permalinks } from "./Permalinks";
3
+ import { extractRequestError, LogService } from "..";
4
+
5
+ /**
6
+ * Represents a system for generating a mention pill for an entity.
7
+ * @category Utilities
8
+ */
9
+ export class MentionPill {
10
+ private constructor(private entityPermalink: string, private displayName: string) {
11
+ }
12
+
13
+ /**
14
+ * The HTML component of the mention.
15
+ */
16
+ public get html(): string {
17
+ return `<a href="${this.entityPermalink}">${this.displayName}</a>`;
18
+ }
19
+
20
+ /**
21
+ * The plain text component of the mention.
22
+ */
23
+ public get text(): string {
24
+ return this.displayName;
25
+ }
26
+
27
+ /**
28
+ * Creates a new mention for a user in an optional room.
29
+ * @param {string} userId The user ID the mention is for.
30
+ * @param {String} inRoomId Optional room ID the user is being mentioned in, for the aesthetics of the mention.
31
+ * @param {MatrixClient} client Optional client for creating a more pleasing mention.
32
+ * @returns {Promise<MentionPill>} Resolves to the user's mention.
33
+ */
34
+ public static async forUser(userId: string, inRoomId: string = null, client: MatrixClient = null): Promise<MentionPill> {
35
+ const permalink = Permalinks.forUser(userId);
36
+
37
+ let displayName = userId;
38
+ try {
39
+ if (client) {
40
+ let profile = null;
41
+
42
+ if (inRoomId) {
43
+ profile = await client.getRoomStateEvent(inRoomId, "m.room.member", userId);
44
+ }
45
+ if (!profile) {
46
+ profile = await client.getUserProfile(userId);
47
+ }
48
+
49
+ if (profile['displayname']) {
50
+ displayName = profile['displayname'];
51
+ }
52
+ }
53
+ } catch (e) {
54
+ LogService.warn("MentionPill", "Error getting profile", extractRequestError(e));
55
+ }
56
+
57
+ return new MentionPill(permalink, displayName);
58
+ }
59
+
60
+ /**
61
+ * Creates a new mention for a room (not @room, but the room itself to be linked).
62
+ * @param {string} roomIdOrAlias The room ID or alias to mention.
63
+ * @param {MatrixClient} client Optional client for creating a more pleasing mention.
64
+ * @returns {Promise<MentionPill>} Resolves to the room's mention.
65
+ */
66
+ public static async forRoom(roomIdOrAlias: string, client: MatrixClient = null): Promise<MentionPill> {
67
+ let permalink = Permalinks.forRoom(roomIdOrAlias);
68
+ let displayProp = roomIdOrAlias;
69
+
70
+ try {
71
+ if (client) {
72
+ const roomId = await client.resolveRoom(roomIdOrAlias);
73
+ const canonicalAlias = await client.getRoomStateEvent(roomId, "m.room.canonical_alias", "");
74
+ if (canonicalAlias?.alias) {
75
+ displayProp = canonicalAlias.alias;
76
+ permalink = Permalinks.forRoom(displayProp);
77
+ }
78
+ }
79
+ } catch (e) {
80
+ LogService.warn("MentionPill", "Error getting room information", extractRequestError(e));
81
+ }
82
+
83
+ return new MentionPill(permalink, displayProp);
84
+ }
85
+
86
+ /**
87
+ * Creates a mention from static information.
88
+ * @param {string} userId The user ID the mention is for.
89
+ * @param {string} displayName The user's display name.
90
+ * @returns {MentionPill} The mention for the user.
91
+ */
92
+ public static withDisplayName(userId: string, displayName: string): MentionPill {
93
+ return new MentionPill(Permalinks.forUser(userId), displayName || userId);
94
+ }
95
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * The parts of a permalink.
3
+ * @see Permalinks
4
+ * @category Utilities
5
+ */
6
+ export interface PermalinkParts {
7
+ /**
8
+ * The room ID or alias the permalink references. May be undefined.
9
+ */
10
+ roomIdOrAlias: string;
11
+
12
+ /**
13
+ * The user ID the permalink references. May be undefined.
14
+ */
15
+ userId: string;
16
+
17
+ /**
18
+ * The event ID the permalink references. May be undefined.
19
+ */
20
+ eventId: string;
21
+
22
+ /**
23
+ * The servers the permalink is routed through. May be undefined or empty.
24
+ */
25
+ viaServers: string[];
26
+ }
27
+
28
+ /**
29
+ * Functions for handling permalinks
30
+ * @category Utilities
31
+ */
32
+ export class Permalinks {
33
+ private constructor() {
34
+ }
35
+
36
+ // TODO: Encode permalinks
37
+
38
+ private static encodeViaArgs(servers: string[]): string {
39
+ if (!servers || !servers.length) return "";
40
+
41
+ return `?via=${servers.join("&via=")}`;
42
+ }
43
+
44
+ /**
45
+ * Creates a room permalink.
46
+ * @param {string} roomIdOrAlias The room ID or alias to create a permalink for.
47
+ * @param {string[]} viaServers The servers to route the permalink through.
48
+ * @returns {string} A room permalink.
49
+ */
50
+ public static forRoom(roomIdOrAlias: string, viaServers: string[] = []): string {
51
+ return `https://matrix.to/#/${roomIdOrAlias}${Permalinks.encodeViaArgs(viaServers)}`;
52
+ }
53
+
54
+ /**
55
+ * Creates a user permalink.
56
+ * @param {string} userId The user ID to create a permalink for.
57
+ * @returns {string} A user permalink.
58
+ */
59
+ public static forUser(userId: string): string {
60
+ return `https://matrix.to/#/${userId}`;
61
+ }
62
+
63
+ /**
64
+ * Creates an event permalink.
65
+ * @param {string} roomIdOrAlias The room ID or alias to create a permalink in.
66
+ * @param {string} eventId The event ID to reference in the permalink.
67
+ * @param {string[]} viaServers The servers to route the permalink through.
68
+ * @returns {string} An event permalink.
69
+ */
70
+ public static forEvent(roomIdOrAlias: string, eventId: string, viaServers: string[] = []): string {
71
+ return `https://matrix.to/#/${roomIdOrAlias}/${eventId}${Permalinks.encodeViaArgs(viaServers)}`;
72
+ }
73
+
74
+ /**
75
+ * Parses a permalink URL into usable parts.
76
+ * @param {string} matrixTo The matrix.to URL to parse.
77
+ * @returns {PermalinkParts} The parts of the permalink.
78
+ */
79
+ public static parseUrl(matrixTo: string): PermalinkParts {
80
+ const matrixToRegexp = /^https:\/\/matrix\.to\/#\/(?<entity>[^/?]+)\/?(?<eventId>[^?]+)?(?<query>\?[^]*)?$/;
81
+
82
+ const url = matrixToRegexp.exec(matrixTo)?.groups;
83
+ if (!url) {
84
+ throw new Error("Not a valid matrix.to URL");
85
+ }
86
+
87
+ const entity = decodeURIComponent(url.entity);
88
+ if (entity[0] === '@') {
89
+ return { userId: entity, roomIdOrAlias: undefined, eventId: undefined, viaServers: undefined };
90
+ } else if (entity[0] === '#' || entity[0] === '!') {
91
+ return {
92
+ userId: undefined,
93
+ roomIdOrAlias: entity,
94
+ eventId: url.eventId && decodeURIComponent(url.eventId),
95
+ viaServers: new URLSearchParams(url.query).getAll('via'),
96
+ };
97
+ } else {
98
+ throw new Error("Unexpected entity");
99
+ }
100
+ }
101
+ }
@@ -0,0 +1,119 @@
1
+ import * as LRU from "lru-cache";
2
+
3
+ import { extractRequestError, LogService, MatrixClient, MatrixProfile } from "..";
4
+ import { MembershipEvent } from "../models/events/MembershipEvent";
5
+ import { Appservice } from "../appservice/Appservice";
6
+
7
+ type CacheKey = `${string}@${string | '<none>'}`;
8
+
9
+ /**
10
+ * Functions for avoiding calls to profile endpoints. Useful for bots when
11
+ * people are mentioned often or bridges which need profile information
12
+ * often.
13
+ * @category Utilities
14
+ */
15
+ export class ProfileCache {
16
+ private cache: LRU.LRUCache<CacheKey, MatrixProfile>;
17
+
18
+ /**
19
+ * Creates a new profile cache.
20
+ * @param {number} maxEntries The maximum number of entries to cache.
21
+ * @param {number} maxAgeMs The maximum age of an entry in milliseconds.
22
+ * @param {MatrixClient} client The client to use to get profile updates.
23
+ */
24
+ constructor(maxEntries: number, maxAgeMs: number, private client: MatrixClient) {
25
+ this.cache = new LRU.LRUCache({
26
+ max: maxEntries,
27
+ ttl: maxAgeMs,
28
+ });
29
+ }
30
+
31
+ private getCacheKey(userId: string, roomId: string | null): CacheKey {
32
+ return `${userId}@${roomId || '<none>'}`;
33
+ }
34
+
35
+ /**
36
+ * Watch for profile changes to cached entries with the provided client. The
37
+ * same client will also be used to update the user's profile in the cache.
38
+ * @param {MatrixClient} client The client to watch for profile changes with.
39
+ */
40
+ public watchWithClient(client: MatrixClient) {
41
+ client.on("room.event", async (roomId: string, event: string) => {
42
+ if (!event['state_key'] || !event['content'] || event['type'] !== 'm.room.member') return;
43
+ await this.tryUpdateProfile(roomId, new MembershipEvent(event), client);
44
+ });
45
+ }
46
+
47
+ /**
48
+ * Watch for profile changes to cached entries with the provided application
49
+ * service. The clientFn will be called to get the relevant client for any
50
+ * updates. If the clientFn is null, the appservice's bot user will be used.
51
+ * The clientFn takes two arguments: the user ID being updated and the room ID
52
+ * they are being updated in (shouldn't be null). The return value should be the
53
+ * MatrixClient to use, or null to use the appservice's bot client. The same
54
+ * client will be used to update the user's general profile, if that profile
55
+ * is cached.
56
+ * @param {Appservice} appservice The application service to watch for profile changes with.
57
+ * @param {Function} clientFn The function to use to acquire profile updates with. If null, the appservice's bot client will be used.
58
+ */
59
+ public watchWithAppservice(appservice: Appservice, clientFn: (userId: string, roomId: string) => MatrixClient = null) {
60
+ if (!clientFn) clientFn = () => appservice.botClient;
61
+ appservice.on("room.event", async (roomId: string, event: string) => {
62
+ if (!event['state_key'] || !event['content'] || event['type'] !== 'm.room.member') return;
63
+
64
+ const memberEvent = new MembershipEvent(event);
65
+ let client = clientFn(memberEvent.membershipFor, roomId);
66
+ if (!client) client = appservice.botClient;
67
+
68
+ await this.tryUpdateProfile(roomId, memberEvent, client);
69
+ });
70
+ }
71
+
72
+ /**
73
+ * Gets a profile for a user in optional room.
74
+ * @param {string} userId The user ID to get a profile for.
75
+ * @param {string|null} roomId Optional room ID to get a per-room profile for the user.
76
+ * @returns {Promise<MatrixProfile>} Resolves to the user's profile.
77
+ */
78
+ public async getUserProfile(userId: string, roomId: string = null): Promise<MatrixProfile> {
79
+ const cacheKey = this.getCacheKey(userId, roomId);
80
+ const cached = this.cache.get(cacheKey);
81
+ if (cached) return Promise.resolve(<MatrixProfile>cached);
82
+
83
+ const profile = await this.getUserProfileWith(userId, roomId, this.client);
84
+ this.cache.set(cacheKey, profile);
85
+ return profile;
86
+ }
87
+
88
+ private async getUserProfileWith(userId: string, roomId: string, client: MatrixClient): Promise<MatrixProfile> {
89
+ try {
90
+ if (roomId) {
91
+ const membership = await client.getRoomStateEvent(roomId, "m.room.member", userId);
92
+ return new MatrixProfile(userId, membership);
93
+ } else {
94
+ const profile = await client.getUserProfile(userId);
95
+ return new MatrixProfile(userId, profile);
96
+ }
97
+ } catch (e) {
98
+ LogService.warn("ProfileCache", "Non-fatal error getting user profile. They might not exist.");
99
+ LogService.warn("ProfileCache", extractRequestError(e));
100
+ return new MatrixProfile(userId, {});
101
+ }
102
+ }
103
+
104
+ private async tryUpdateProfile(roomId: string, memberEvent: MembershipEvent, client: MatrixClient) {
105
+ const roomCacheKey = this.getCacheKey(memberEvent.membershipFor, roomId);
106
+ const generalCacheKey = this.getCacheKey(memberEvent.membershipFor, null);
107
+
108
+ if (this.cache.has(roomCacheKey)) {
109
+ this.cache.set(roomCacheKey, new MatrixProfile(memberEvent.membershipFor, memberEvent.content));
110
+ }
111
+
112
+ // TODO: Try and figure out semantics for this updating.
113
+ // Large accounts could cause hammering on the profile endpoint, but hopefully it is cached by the server.
114
+ if (this.cache.has(generalCacheKey)) {
115
+ const profile = await this.getUserProfileWith(memberEvent.membershipFor, null, client);
116
+ this.cache.set(generalCacheKey, profile);
117
+ }
118
+ }
119
+ }
@@ -0,0 +1,46 @@
1
+ import * as sanitizeHtml from "sanitize-html";
2
+
3
+ /**
4
+ * Helper for creating rich replies.
5
+ * @category Utilities
6
+ */
7
+ export class RichReply {
8
+ private constructor() {
9
+ }
10
+
11
+ /**
12
+ * Generates the event content required to reply to the provided event with the
13
+ * provided text.
14
+ * @param {string} roomId the room ID the event being replied to resides in
15
+ * @param {any} event the event to reply to
16
+ * @param {string} withText the plain text to reply with
17
+ * @param {string} withHtml the HTML to reply with
18
+ * @returns {any} the content of the event representing the reply
19
+ */
20
+ public static createFor(roomId: string, event: any, withText: string, withHtml: string): any {
21
+ const originalBody = (event["content"] ? event["content"]["body"] : "") || "";
22
+ let originalHtml = (event["content"] ? event["content"]["formatted_body"] : "") || null;
23
+ if (originalHtml === null) {
24
+ originalHtml = sanitizeHtml(originalBody);
25
+ }
26
+
27
+ const fallbackText = "> <" + event["sender"] + "> " + originalBody.split("\n").join("\n> ");
28
+ const fallbackHtml = "<mx-reply><blockquote>"
29
+ + `<a href="https://matrix.to/#/${roomId}/${event["event_id"]}">In reply to</a> `
30
+ + `<a href="https://matrix.to/#/${event["sender"]}">${event["sender"]}</a>`
31
+ + "<br />" + originalHtml
32
+ + "</blockquote></mx-reply>";
33
+
34
+ return {
35
+ "m.relates_to": {
36
+ "m.in_reply_to": {
37
+ "event_id": event["event_id"],
38
+ },
39
+ },
40
+ "msgtype": "m.text", // for those who just want to send the reply as-is
41
+ "body": fallbackText + "\n\n" + withText,
42
+ "format": "org.matrix.custom.html",
43
+ "formatted_body": fallbackHtml + withHtml,
44
+ };
45
+ }
46
+ }
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Unpadded Base64 utilities for Matrix.
3
+ * @category Utilities
4
+ */
5
+ export class UnpaddedBase64 {
6
+ private constructor() {
7
+ }
8
+
9
+ /**
10
+ * Encodes a buffer to Unpadded Base64
11
+ * @param {Buffer} buf The buffer to encode.
12
+ * @returns {string} The Unpadded Base64 string
13
+ */
14
+ public static encodeBuffer(buf: Buffer): string {
15
+ return buf.toString('base64').replace(/[=]*$/g, '');
16
+ }
17
+
18
+ /**
19
+ * Encodes a string to Unpadded Base64
20
+ * @param {string} str The string to encode.
21
+ * @returns {string} The Unpadded Base64 string
22
+ */
23
+ public static encodeString(str: string): string {
24
+ return UnpaddedBase64.encodeBuffer(Buffer.from(str));
25
+ }
26
+
27
+ /**
28
+ * Encodes a buffer to Unpadded Base64 (URL Safe Edition)
29
+ * @param {Buffer} buf The buffer to encode.
30
+ * @returns {string} The Unpadded Base64 string
31
+ */
32
+ public static encodeBufferUrlSafe(buf: Buffer): string {
33
+ return UnpaddedBase64.encodeBuffer(buf).replace(/\+/g, '-').replace(/\//g, '_');
34
+ }
35
+
36
+ /**
37
+ * Encodes a string to Unpadded Base64 (URL Safe Edition)
38
+ * @param {string} str The string to encode.
39
+ * @returns {string} The Unpadded Base64 string
40
+ */
41
+ public static encodeStringUrlSafe(str: string): string {
42
+ return UnpaddedBase64.encodeBufferUrlSafe(Buffer.from(str));
43
+ }
44
+ }
package/src/http.ts ADDED
@@ -0,0 +1,166 @@
1
+ import { LogLevel, LogService } from "./logging/LogService";
2
+ import { getRequestFn } from "./request";
3
+ import { MatrixError } from "./models/MatrixError";
4
+
5
+ let lastRequestId = 0;
6
+
7
+ /**
8
+ * Performs a web request to a server.
9
+ * @category Unit testing
10
+ * @param {string} baseUrl The base URL to apply to the call.
11
+ * @param {"GET"|"POST"|"PUT"|"DELETE"} method The HTTP method to use in the request
12
+ * @param {string} endpoint The endpoint to call. For example: "/_matrix/client/v3/account/whoami"
13
+ * @param {any} qs The query string to send. Optional.
14
+ * @param {any} body The request body to send. Optional. Will be converted to JSON unless the type is a Buffer.
15
+ * @param {any} headers Additional headers to send in the request.
16
+ * @param {number} timeout The number of milliseconds to wait before timing out.
17
+ * @param {boolean} raw If true, the raw response will be returned instead of the response body.
18
+ * @param {string} contentType The content type to send. Only used if the `body` is a Buffer.
19
+ * @param {string} noEncoding Set to true to disable encoding, and return a Buffer. Defaults to false
20
+ * @returns {Promise<any>} Resolves to the response (body), rejected if a non-2xx status code was returned.
21
+ */
22
+ export async function doHttpRequest(
23
+ baseUrl: string,
24
+ method: "GET" | "POST" | "PUT" | "DELETE",
25
+ endpoint: string,
26
+ qs = null,
27
+ body = null,
28
+ headers = {},
29
+ timeout = 60000,
30
+ raw = false,
31
+ contentType = "application/json",
32
+ noEncoding = false,
33
+ ): Promise<any> {
34
+ if (!endpoint.startsWith('/')) {
35
+ endpoint = '/' + endpoint;
36
+ }
37
+
38
+ const requestId = ++lastRequestId;
39
+ const url = baseUrl + endpoint;
40
+
41
+ // This is logged at info so that when a request fails people can figure out which one.
42
+ LogService.debug("MatrixHttpClient", "(REQ-" + requestId + ")", method + " " + url);
43
+
44
+ // Don't log the request unless we're in debug mode. It can be large.
45
+ if (LogService.level.includes(LogLevel.TRACE)) {
46
+ if (qs) LogService.trace("MatrixHttpClient", "(REQ-" + requestId + ")", "qs = " + JSON.stringify(qs));
47
+ if (body && !Buffer.isBuffer(body)) LogService.trace("MatrixHttpClient", "(REQ-" + requestId + ")", "body = " + JSON.stringify(redactObjectForLogging(body)));
48
+ if (body && Buffer.isBuffer(body)) LogService.trace("MatrixHttpClient", "(REQ-" + requestId + ")", "body = <Buffer>");
49
+ }
50
+
51
+ const params: { uri: string, [k: string]: any } = {
52
+ uri: url,
53
+ method: method,
54
+ qs: qs,
55
+ // If this is undefined, then a string will be returned. If it's null, a Buffer will be returned.
56
+ encoding: noEncoding === false ? undefined : null,
57
+ useQuerystring: true,
58
+ qsStringifyOptions: {
59
+ options: { arrayFormat: 'repeat' },
60
+ },
61
+ timeout: timeout,
62
+ headers: headers,
63
+ // Enable KeepAlive for HTTP
64
+ forever: true,
65
+ };
66
+
67
+ if (body) {
68
+ if (Buffer.isBuffer(body)) {
69
+ params.headers["Content-Type"] = contentType;
70
+ params.body = body;
71
+ } else {
72
+ params.headers["Content-Type"] = "application/json";
73
+ params.body = JSON.stringify(body);
74
+ }
75
+ }
76
+
77
+ const { response, resBody } = await new Promise<{ response: any, resBody: any }>((resolve, reject) => {
78
+ getRequestFn()(params, (err, res, rBody) => {
79
+ if (err) {
80
+ LogService.error("MatrixHttpClient", "(REQ-" + requestId + ")", err);
81
+ reject(err);
82
+ return;
83
+ }
84
+
85
+ if (typeof (rBody) === 'string') {
86
+ try {
87
+ rBody = JSON.parse(rBody);
88
+ } catch (e) {
89
+ }
90
+ }
91
+
92
+ if (typeof (res.body) === 'string') {
93
+ try {
94
+ res.body = JSON.parse(res.body);
95
+ } catch (e) {
96
+ }
97
+ }
98
+
99
+ resolve({ response: res, resBody: rBody });
100
+ });
101
+ });
102
+
103
+ const respIsBuffer = (response.body instanceof Buffer);
104
+
105
+ // Check for errors.
106
+ const errBody = response.body || resBody;
107
+ if (typeof (errBody) === "object" && 'errcode' in errBody) {
108
+ const redactedBody = respIsBuffer ? '<Buffer>' : redactObjectForLogging(errBody);
109
+ LogService.error("MatrixHttpClient", "(REQ-" + requestId + ")", redactedBody);
110
+ throw new MatrixError(errBody, response.statusCode);
111
+ }
112
+
113
+ // Don't log the body unless we're in debug mode. They can be large.
114
+ if (LogService.level.includes(LogLevel.TRACE)) {
115
+ const redactedBody = respIsBuffer ? '<Buffer>' : redactObjectForLogging(response.body);
116
+ LogService.trace("MatrixHttpClient", "(REQ-" + requestId + " RESP-H" + response.statusCode + ")", redactedBody);
117
+ }
118
+
119
+ if (response.statusCode < 200 || response.statusCode >= 300) {
120
+ const redactedBody = respIsBuffer ? '<Buffer>' : redactObjectForLogging(response.body);
121
+ LogService.error("MatrixHttpClient", "(REQ-" + requestId + ")", redactedBody);
122
+ throw response;
123
+ }
124
+ return raw ? response : resBody;
125
+ }
126
+
127
+ export function redactObjectForLogging(input: any): any {
128
+ if (!input) return input;
129
+
130
+ const fieldsToRedact = [
131
+ 'access_token',
132
+ 'password',
133
+ 'new_password',
134
+ ];
135
+
136
+ const redactFn = (i) => {
137
+ if (!i) return i;
138
+
139
+ // Don't treat strings like arrays/objects
140
+ if (typeof i === 'string') return i;
141
+
142
+ if (Array.isArray(i)) {
143
+ const rebuilt = [];
144
+ for (const v of i) {
145
+ rebuilt.push(redactFn(v));
146
+ }
147
+ return rebuilt;
148
+ }
149
+
150
+ if (i instanceof Object) {
151
+ const rebuilt = {};
152
+ for (const key of Object.keys(i)) {
153
+ if (fieldsToRedact.includes(key)) {
154
+ rebuilt[key] = '<redacted>';
155
+ } else {
156
+ rebuilt[key] = redactFn(i[key]);
157
+ }
158
+ }
159
+ return rebuilt;
160
+ }
161
+
162
+ return i; // It's a primitive value
163
+ };
164
+
165
+ return redactFn(input);
166
+ }