@atproto/api 0.15.13 → 0.15.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/client/index.d.ts +6 -0
  3. package/dist/client/index.d.ts.map +1 -1
  4. package/dist/client/index.js +12 -4
  5. package/dist/client/index.js.map +1 -1
  6. package/dist/client/lexicons.d.ts +418 -0
  7. package/dist/client/lexicons.d.ts.map +1 -1
  8. package/dist/client/lexicons.js +225 -0
  9. package/dist/client/lexicons.js.map +1 -1
  10. package/dist/client/types/app/bsky/notification/defs.d.ts +40 -0
  11. package/dist/client/types/app/bsky/notification/defs.d.ts.map +1 -1
  12. package/dist/client/types/app/bsky/notification/defs.js +36 -0
  13. package/dist/client/types/app/bsky/notification/defs.js.map +1 -1
  14. package/dist/client/types/app/bsky/notification/getPreferences.d.ts +22 -0
  15. package/dist/client/types/app/bsky/notification/getPreferences.d.ts.map +1 -0
  16. package/dist/client/types/app/bsky/notification/getPreferences.js +11 -0
  17. package/dist/client/types/app/bsky/notification/getPreferences.js.map +1 -0
  18. package/dist/client/types/app/bsky/notification/putPreferencesV2.d.ts +38 -0
  19. package/dist/client/types/app/bsky/notification/putPreferencesV2.d.ts.map +1 -0
  20. package/dist/client/types/app/bsky/notification/putPreferencesV2.js +11 -0
  21. package/dist/client/types/app/bsky/notification/putPreferencesV2.js.map +1 -0
  22. package/dist/moderation/decision.d.ts +2 -1
  23. package/dist/moderation/decision.d.ts.map +1 -1
  24. package/dist/moderation/decision.js +3 -2
  25. package/dist/moderation/decision.js.map +1 -1
  26. package/dist/moderation/index.d.ts +1 -1
  27. package/dist/moderation/index.d.ts.map +1 -1
  28. package/dist/moderation/index.js +2 -1
  29. package/dist/moderation/index.js.map +1 -1
  30. package/dist/moderation/mutewords.d.ts +22 -2
  31. package/dist/moderation/mutewords.d.ts.map +1 -1
  32. package/dist/moderation/mutewords.js +63 -25
  33. package/dist/moderation/mutewords.js.map +1 -1
  34. package/dist/moderation/subjects/post.js +49 -39
  35. package/dist/moderation/subjects/post.js.map +1 -1
  36. package/dist/moderation/types.d.ts +2 -0
  37. package/dist/moderation/types.d.ts.map +1 -1
  38. package/dist/moderation/types.js.map +1 -1
  39. package/package.json +1 -1
  40. package/src/client/index.ts +28 -0
  41. package/src/client/lexicons.ts +227 -0
  42. package/src/client/types/app/bsky/notification/defs.ts +76 -0
  43. package/src/client/types/app/bsky/notification/getPreferences.ts +40 -0
  44. package/src/client/types/app/bsky/notification/putPreferencesV2.ts +56 -0
  45. package/src/moderation/decision.ts +4 -2
  46. package/src/moderation/index.ts +1 -1
  47. package/src/moderation/mutewords.ts +88 -26
  48. package/src/moderation/subjects/post.ts +104 -115
  49. package/src/moderation/types.ts +2 -0
  50. package/tests/moderation-mutewords.test.ts +153 -112
  51. package/tsconfig.build.tsbuildinfo +1 -1
@@ -8,7 +8,7 @@ import {
8
8
  } from '../../client'
9
9
  import { $Typed } from '../../client/util'
10
10
  import { ModerationDecision } from '../decision'
11
- import { hasMutedWord } from '../mutewords'
11
+ import { MuteWordMatch, matchMuteWords } from '../mutewords'
12
12
  import { ModerationOpts, ModerationSubjectPost } from '../types'
13
13
  import { decideAccount } from './account'
14
14
  import { decideProfile } from './profile'
@@ -40,7 +40,7 @@ function decideSubject(
40
40
  }
41
41
  acc.addHidden(checkHiddenPost(subject, opts.prefs.hiddenPosts))
42
42
  if (!acc.isMe) {
43
- acc.addMutedWord(checkMutedWords(subject, opts.prefs.mutedWords))
43
+ acc.addMutedWord(matchAllMuteWords(subject, opts.prefs.mutedWords))
44
44
  }
45
45
 
46
46
  return acc
@@ -160,44 +160,43 @@ function checkHiddenPost(
160
160
  return false
161
161
  }
162
162
 
163
- function checkMutedWords(
163
+ function matchAllMuteWords(
164
164
  subject: ModerationSubjectPost,
165
165
  mutedWords: AppBskyActorDefs.MutedWord[] | undefined,
166
- ) {
166
+ ): MuteWordMatch[] | undefined {
167
167
  if (!mutedWords?.length) {
168
- return false
168
+ return
169
169
  }
170
170
 
171
171
  const postAuthor = subject.author
172
172
 
173
173
  if (AppBskyFeedPost.isRecord(subject.record)) {
174
174
  const post = subject.record as AppBskyFeedPost.Record
175
+
176
+ const matches = matchMuteWords({
177
+ mutedWords,
178
+ text: post.text,
179
+ facets: post.facets,
180
+ outlineTags: post.tags,
181
+ languages: post.langs,
182
+ actor: postAuthor,
183
+ })
175
184
  // post text
176
- if (
177
- hasMutedWord({
178
- mutedWords,
179
- text: post.text,
180
- facets: post.facets,
181
- outlineTags: post.tags,
182
- languages: post.langs,
183
- actor: postAuthor,
184
- })
185
- ) {
186
- return true
185
+ if (matches) {
186
+ return matches
187
187
  }
188
188
 
189
189
  if (post.embed && AppBskyEmbedImages.isMain(post.embed)) {
190
190
  // post images
191
191
  for (const image of post.embed.images) {
192
- if (
193
- hasMutedWord({
194
- mutedWords,
195
- text: image.alt,
196
- languages: post.langs,
197
- actor: postAuthor,
198
- })
199
- ) {
200
- return true
192
+ const matches = matchMuteWords({
193
+ mutedWords,
194
+ text: image.alt,
195
+ languages: post.langs,
196
+ actor: postAuthor,
197
+ })
198
+ if (matches) {
199
+ return matches
201
200
  }
202
201
  }
203
202
  }
@@ -214,33 +213,31 @@ function checkMutedWords(
214
213
  if (AppBskyFeedPost.isRecord(embed.record.value)) {
215
214
  const embeddedPost = embed.record.value as AppBskyFeedPost.Record
216
215
  const embedAuthor = embed.record.author
216
+ const matches = matchMuteWords({
217
+ mutedWords,
218
+ text: embeddedPost.text,
219
+ facets: embeddedPost.facets,
220
+ outlineTags: embeddedPost.tags,
221
+ languages: embeddedPost.langs,
222
+ actor: embedAuthor,
223
+ })
217
224
 
218
225
  // quoted post text
219
- if (
220
- hasMutedWord({
221
- mutedWords,
222
- text: embeddedPost.text,
223
- facets: embeddedPost.facets,
224
- outlineTags: embeddedPost.tags,
225
- languages: embeddedPost.langs,
226
- actor: embedAuthor,
227
- })
228
- ) {
229
- return true
226
+ if (matches) {
227
+ return matches
230
228
  }
231
229
 
232
230
  // quoted post's images
233
231
  if (AppBskyEmbedImages.isMain(embeddedPost.embed)) {
234
232
  for (const image of embeddedPost.embed.images) {
235
- if (
236
- hasMutedWord({
237
- mutedWords,
238
- text: image.alt,
239
- languages: embeddedPost.langs,
240
- actor: embedAuthor,
241
- })
242
- ) {
243
- return true
233
+ const matches = matchMuteWords({
234
+ mutedWords,
235
+ text: image.alt,
236
+ languages: embeddedPost.langs,
237
+ actor: embedAuthor,
238
+ })
239
+ if (matches) {
240
+ return matches
244
241
  }
245
242
  }
246
243
  }
@@ -248,15 +245,14 @@ function checkMutedWords(
248
245
  // quoted post's link card
249
246
  if (AppBskyEmbedExternal.isMain(embeddedPost.embed)) {
250
247
  const { external } = embeddedPost.embed
251
- if (
252
- hasMutedWord({
253
- mutedWords,
254
- text: external.title + ' ' + external.description,
255
- languages: [],
256
- actor: embedAuthor,
257
- })
258
- ) {
259
- return true
248
+ const matches = matchMuteWords({
249
+ mutedWords,
250
+ text: external.title + ' ' + external.description,
251
+ languages: [],
252
+ actor: embedAuthor,
253
+ })
254
+ if (matches) {
255
+ return matches
260
256
  }
261
257
  }
262
258
 
@@ -264,32 +260,30 @@ function checkMutedWords(
264
260
  // quoted post's link card when it did a quote + media
265
261
  if (AppBskyEmbedExternal.isMain(embeddedPost.embed.media)) {
266
262
  const { external } = embeddedPost.embed.media
267
- if (
268
- hasMutedWord({
269
- mutedWords,
270
- text: external.title + ' ' + external.description,
271
- languages: [],
272
- actor: embedAuthor,
273
- })
274
- ) {
275
- return true
263
+ const matches = matchMuteWords({
264
+ mutedWords,
265
+ text: external.title + ' ' + external.description,
266
+ languages: [],
267
+ actor: embedAuthor,
268
+ })
269
+ if (matches) {
270
+ return matches
276
271
  }
277
272
  }
278
273
 
279
274
  // quoted post's images when it did a quote + media
280
275
  if (AppBskyEmbedImages.isMain(embeddedPost.embed.media)) {
281
276
  for (const image of embeddedPost.embed.media.images) {
282
- if (
283
- hasMutedWord({
284
- mutedWords,
285
- text: image.alt,
286
- languages: AppBskyFeedPost.isRecord(embeddedPost.record)
287
- ? embeddedPost.langs
288
- : [],
289
- actor: embedAuthor,
290
- })
291
- ) {
292
- return true
277
+ const matches = matchMuteWords({
278
+ mutedWords,
279
+ text: image.alt,
280
+ languages: AppBskyFeedPost.isRecord(embeddedPost.record)
281
+ ? embeddedPost.langs
282
+ : [],
283
+ actor: embedAuthor,
284
+ })
285
+ if (matches) {
286
+ return matches
293
287
  }
294
288
  }
295
289
  }
@@ -299,15 +293,14 @@ function checkMutedWords(
299
293
  // link card
300
294
  else if (AppBskyEmbedExternal.isView(embed)) {
301
295
  const { external } = embed
302
- if (
303
- hasMutedWord({
304
- mutedWords,
305
- text: external.title + ' ' + external.description,
306
- languages: [],
307
- actor: postAuthor,
308
- })
309
- ) {
310
- return true
296
+ const matches = matchMuteWords({
297
+ mutedWords,
298
+ text: external.title + ' ' + external.description,
299
+ languages: [],
300
+ actor: postAuthor,
301
+ })
302
+ if (matches) {
303
+ return matches
311
304
  }
312
305
  }
313
306
  // quote post with media
@@ -320,52 +313,48 @@ function checkMutedWords(
320
313
  // quoted post text
321
314
  if (AppBskyFeedPost.isRecord(embed.record.record.value)) {
322
315
  const post = embed.record.record.value as AppBskyFeedPost.Record
323
- if (
324
- hasMutedWord({
325
- mutedWords,
326
- text: post.text,
327
- facets: post.facets,
328
- outlineTags: post.tags,
329
- languages: post.langs,
330
- actor: embedAuthor,
331
- })
332
- ) {
333
- return true
316
+ const matches = matchMuteWords({
317
+ mutedWords,
318
+ text: post.text,
319
+ facets: post.facets,
320
+ outlineTags: post.tags,
321
+ languages: post.langs,
322
+ actor: embedAuthor,
323
+ })
324
+ if (matches) {
325
+ return matches
334
326
  }
335
327
  }
336
328
 
337
329
  // quoted post images
338
330
  if (AppBskyEmbedImages.isView(embed.media)) {
339
331
  for (const image of embed.media.images) {
340
- if (
341
- hasMutedWord({
342
- mutedWords,
343
- text: image.alt,
344
- languages: AppBskyFeedPost.isRecord(subject.record)
345
- ? (subject.record as AppBskyFeedPost.Record).langs
346
- : [],
347
- actor: embedAuthor,
348
- })
349
- ) {
350
- return true
332
+ const matches = matchMuteWords({
333
+ mutedWords,
334
+ text: image.alt,
335
+ languages: AppBskyFeedPost.isRecord(subject.record)
336
+ ? (subject.record as AppBskyFeedPost.Record).langs
337
+ : [],
338
+ actor: embedAuthor,
339
+ })
340
+ if (matches) {
341
+ return matches
351
342
  }
352
343
  }
353
344
  }
354
345
 
355
346
  if (AppBskyEmbedExternal.isView(embed.media)) {
356
347
  const { external } = embed.media
357
- if (
358
- hasMutedWord({
359
- mutedWords,
360
- text: external.title + ' ' + external.description,
361
- languages: [],
362
- actor: embedAuthor,
363
- })
364
- ) {
365
- return true
348
+ const matches = matchMuteWords({
349
+ mutedWords,
350
+ text: external.title + ' ' + external.description,
351
+ languages: [],
352
+ actor: embedAuthor,
353
+ })
354
+ if (matches) {
355
+ return matches
366
356
  }
367
357
  }
368
358
  }
369
359
  }
370
- return false
371
360
  }
@@ -7,6 +7,7 @@ import {
7
7
  ComAtprotoLabelDefs,
8
8
  } from '../client/index'
9
9
  import { KnownLabelValue } from './const/labels'
10
+ import { MuteWordMatch } from './mutewords'
10
11
 
11
12
  // syntax
12
13
  // =
@@ -158,6 +159,7 @@ export type ModerationCause =
158
159
  source: ModerationCauseSource
159
160
  priority: 6
160
161
  downgraded?: boolean
162
+ matches: MuteWordMatch[]
161
163
  }
162
164
  | {
163
165
  type: 'hidden'