@atproto/api 0.20.8 → 0.20.10
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.
- package/CHANGELOG.md +14 -0
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/lexicons.d.ts +240 -24
- package/dist/client/lexicons.d.ts.map +1 -1
- package/dist/client/lexicons.js +121 -6
- package/dist/client/lexicons.js.map +1 -1
- package/dist/client/types/app/bsky/draft/defs.d.ts +10 -0
- package/dist/client/types/app/bsky/draft/defs.d.ts.map +1 -1
- package/dist/client/types/app/bsky/draft/defs.js +7 -0
- package/dist/client/types/app/bsky/draft/defs.js.map +1 -1
- package/dist/client/types/app/bsky/embed/gallery.d.ts +45 -0
- package/dist/client/types/app/bsky/embed/gallery.d.ts.map +1 -0
- package/dist/client/types/app/bsky/embed/gallery.js +33 -0
- package/dist/client/types/app/bsky/embed/gallery.js.map +1 -0
- package/dist/client/types/app/bsky/embed/record.d.ts +2 -1
- package/dist/client/types/app/bsky/embed/record.d.ts.map +1 -1
- package/dist/client/types/app/bsky/embed/record.js.map +1 -1
- package/dist/client/types/app/bsky/embed/recordWithMedia.d.ts +3 -2
- package/dist/client/types/app/bsky/embed/recordWithMedia.d.ts.map +1 -1
- package/dist/client/types/app/bsky/embed/recordWithMedia.js.map +1 -1
- package/dist/client/types/app/bsky/feed/defs.d.ts +2 -1
- package/dist/client/types/app/bsky/feed/defs.d.ts.map +1 -1
- package/dist/client/types/app/bsky/feed/defs.js.map +1 -1
- package/dist/client/types/app/bsky/feed/post.d.ts +2 -1
- package/dist/client/types/app/bsky/feed/post.d.ts.map +1 -1
- package/dist/client/types/app/bsky/feed/post.js.map +1 -1
- package/dist/client/types/chat/bsky/group/defs.d.ts +5 -1
- package/dist/client/types/chat/bsky/group/defs.d.ts.map +1 -1
- package/dist/client/types/chat/bsky/group/defs.js.map +1 -1
- package/dist/moderation/subjects/post.d.ts.map +1 -1
- package/dist/moderation/subjects/post.js +69 -1
- package/dist/moderation/subjects/post.js.map +1 -1
- package/package.json +4 -4
- package/src/moderation/subjects/post.ts +73 -0
- package/tests/moderation-mutewords.test.ts +178 -1
- package/tsconfig.build.json +2 -2
- package/tsconfig.build.tsbuildinfo +1 -1
- package/tsconfig.json +2 -2
- package/tsconfig.tests.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defs.js","sourceRoot":"","sources":["../../../../../../src/client/types/chat/bsky/group/defs.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,IAAI,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,EAEL,QAAQ,IAAI,SAAS,GAEtB,MAAM,qBAAqB,CAAA;AAI5B,MAAM,QAAQ,GAAG,SAAS,EACxB,QAAQ,GAAG,SAAS,CAAA;AACtB,MAAM,EAAE,GAAG,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"defs.js","sourceRoot":"","sources":["../../../../../../src/client/types/chat/bsky/group/defs.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,IAAI,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,EAEL,QAAQ,IAAI,SAAS,GAEtB,MAAM,qBAAqB,CAAA;AAI5B,MAAM,QAAQ,GAAG,SAAS,EACxB,QAAQ,GAAG,SAAS,CAAA;AACtB,MAAM,EAAE,GAAG,sBAAsB,CAAA;AAejC,MAAM,gBAAgB,GAAG,cAAc,CAAA;AAEvC,MAAM,UAAU,cAAc,CAAI,CAAI;IACpC,OAAO,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,gBAAgB,CAAC,CAAA;AAC1C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAI,CAAI;IAC1C,OAAO,QAAQ,CAAmB,CAAC,EAAE,EAAE,EAAE,gBAAgB,CAAC,CAAA;AAC5D,CAAC;AAkBD,MAAM,uBAAuB,GAAG,qBAAqB,CAAA;AAErD,MAAM,UAAU,qBAAqB,CAAI,CAAI;IAC3C,OAAO,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,uBAAuB,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAI,CAAI;IACjD,OAAO,QAAQ,CAA0B,CAAC,EAAE,EAAE,EAAE,uBAAuB,CAAC,CAAA;AAC1E,CAAC;AAOD,MAAM,uBAAuB,GAAG,qBAAqB,CAAA;AAErD,MAAM,UAAU,qBAAqB,CAAI,CAAI;IAC3C,OAAO,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,uBAAuB,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAI,CAAI;IACjD,OAAO,QAAQ,CAA0B,CAAC,EAAE,EAAE,EAAE,uBAAuB,CAAC,CAAA;AAC1E,CAAC;AAUD,MAAM,mBAAmB,GAAG,iBAAiB,CAAA;AAE7C,MAAM,UAAU,iBAAiB,CAAI,CAAI;IACvC,OAAO,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,mBAAmB,CAAC,CAAA;AAC7C,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAI,CAAI;IAC7C,OAAO,QAAQ,CAAsB,CAAC,EAAE,EAAE,EAAE,mBAAmB,CAAC,CAAA;AAClE,CAAC;AAaD,MAAM,wBAAwB,GAAG,sBAAsB,CAAA;AAEvD,MAAM,UAAU,sBAAsB,CAAI,CAAI;IAC5C,OAAO,QAAQ,CAAC,CAAC,EAAE,EAAE,EAAE,wBAAwB,CAAC,CAAA;AAClD,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAI,CAAI;IAClD,OAAO,QAAQ,CAA2B,CAAC,EAAE,EAAE,EAAE,wBAAwB,CAAC,CAAA;AAC5E,CAAC","sourcesContent":["/**\n * GENERATED CODE - DO NOT MODIFY\n */\nimport { type ValidationResult, BlobRef } from '@atproto/lexicon'\nimport { CID } from 'multiformats/cid'\nimport { validate as _validate } from '../../../../lexicons.js'\nimport {\n type $Typed,\n is$typed as _is$typed,\n type OmitKey,\n} from '../../../../util.js'\nimport type * as ChatBskyActorDefs from '../actor/defs.js'\nimport type * as ChatBskyConvoDefs from '../convo/defs.js'\n\nconst is$typed = _is$typed,\n validate = _validate\nconst id = 'chat.bsky.group.defs'\n\nexport type LinkEnabledStatus = 'enabled' | 'disabled' | (string & {})\nexport type JoinRule = 'anyone' | 'followedByOwner' | (string & {})\n\n/** Join link view to be used within a group view, so the convo is surrounding, not specified inside this view. */\nexport interface JoinLinkView {\n $type?: 'chat.bsky.group.defs#joinLinkView'\n code: string\n enabledStatus: LinkEnabledStatus\n requireApproval: boolean\n joinRule: JoinRule\n createdAt: string\n}\n\nconst hashJoinLinkView = 'joinLinkView'\n\nexport function isJoinLinkView<V>(v: V) {\n return is$typed(v, id, hashJoinLinkView)\n}\n\nexport function validateJoinLinkView<V>(v: V) {\n return validate<JoinLinkView & V>(v, id, hashJoinLinkView)\n}\n\n/** Preview that can be shown in feeds, including to unauthenticated viewers. */\nexport interface JoinLinkPreviewView {\n $type?: 'chat.bsky.group.defs#joinLinkPreviewView'\n convoId: string\n code: string\n name: string\n owner: ChatBskyActorDefs.ProfileViewBasic\n memberCount: number\n memberLimit: number\n requireApproval: boolean\n joinRule: JoinRule\n enabledStatus: LinkEnabledStatus\n convo?: ChatBskyConvoDefs.ConvoView\n viewer?: JoinLinkViewerState\n}\n\nconst hashJoinLinkPreviewView = 'joinLinkPreviewView'\n\nexport function isJoinLinkPreviewView<V>(v: V) {\n return is$typed(v, id, hashJoinLinkPreviewView)\n}\n\nexport function validateJoinLinkPreviewView<V>(v: V) {\n return validate<JoinLinkPreviewView & V>(v, id, hashJoinLinkPreviewView)\n}\n\nexport interface JoinLinkViewerState {\n $type?: 'chat.bsky.group.defs#joinLinkViewerState'\n requestedAt?: string\n}\n\nconst hashJoinLinkViewerState = 'joinLinkViewerState'\n\nexport function isJoinLinkViewerState<V>(v: V) {\n return is$typed(v, id, hashJoinLinkViewerState)\n}\n\nexport function validateJoinLinkViewerState<V>(v: V) {\n return validate<JoinLinkViewerState & V>(v, id, hashJoinLinkViewerState)\n}\n\n/** A join request from the perspective of the group owner. */\nexport interface JoinRequestView {\n $type?: 'chat.bsky.group.defs#joinRequestView'\n convoId: string\n requestedBy: ChatBskyActorDefs.ProfileViewBasic\n requestedAt: string\n}\n\nconst hashJoinRequestView = 'joinRequestView'\n\nexport function isJoinRequestView<V>(v: V) {\n return is$typed(v, id, hashJoinRequestView)\n}\n\nexport function validateJoinRequestView<V>(v: V) {\n return validate<JoinRequestView & V>(v, id, hashJoinRequestView)\n}\n\n/** A join request from the perspective of the requester, including enough group context to render the request in a list (e.g. group name, owner, member count). */\nexport interface JoinRequestConvoView {\n $type?: 'chat.bsky.group.defs#joinRequestConvoView'\n convoId: string\n name: string\n owner: ChatBskyActorDefs.ProfileViewBasic\n memberCount: number\n memberLimit: number\n viewer: JoinLinkViewerState\n}\n\nconst hashJoinRequestConvoView = 'joinRequestConvoView'\n\nexport function isJoinRequestConvoView<V>(v: V) {\n return is$typed(v, id, hashJoinRequestConvoView)\n}\n\nexport function validateJoinRequestConvoView<V>(v: V) {\n return validate<JoinRequestConvoView & V>(v, id, hashJoinRequestConvoView)\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"post.d.ts","sourceRoot":"","sources":["../../../src/moderation/subjects/post.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"post.d.ts","sourceRoot":"","sources":["../../../src/moderation/subjects/post.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AAEnD,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAInE,wBAAgB,UAAU,CACxB,OAAO,EAAE,qBAAqB,EAC9B,IAAI,EAAE,cAAc,GACnB,kBAAkB,CAOpB"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AppBskyEmbedExternal, AppBskyEmbedImages, AppBskyEmbedRecord, AppBskyEmbedRecordWithMedia, AppBskyFeedPost, } from '../../client/index.js';
|
|
1
|
+
import { AppBskyEmbedExternal, AppBskyEmbedGallery, AppBskyEmbedImages, AppBskyEmbedRecord, AppBskyEmbedRecordWithMedia, AppBskyFeedPost, } from '../../client/index.js';
|
|
2
2
|
import { ModerationDecision } from '../decision.js';
|
|
3
3
|
import { matchMuteWords } from '../mutewords.js';
|
|
4
4
|
import { decideAccount } from './account.js';
|
|
@@ -136,6 +136,22 @@ function matchAllMuteWords(subject, mutedWords) {
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
}
|
|
139
|
+
if (post.embed && AppBskyEmbedGallery.isMain(post.embed)) {
|
|
140
|
+
// post gallery items
|
|
141
|
+
for (const item of post.embed.items) {
|
|
142
|
+
if (AppBskyEmbedGallery.isImage(item)) {
|
|
143
|
+
const matches = matchMuteWords({
|
|
144
|
+
mutedWords,
|
|
145
|
+
text: item.alt,
|
|
146
|
+
languages: post.langs,
|
|
147
|
+
actor: postAuthor,
|
|
148
|
+
});
|
|
149
|
+
if (matches) {
|
|
150
|
+
return matches;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
139
155
|
}
|
|
140
156
|
const { embed } = subject;
|
|
141
157
|
if (embed) {
|
|
@@ -172,6 +188,22 @@ function matchAllMuteWords(subject, mutedWords) {
|
|
|
172
188
|
}
|
|
173
189
|
}
|
|
174
190
|
}
|
|
191
|
+
// quoted post's gallery
|
|
192
|
+
if (AppBskyEmbedGallery.isMain(embeddedPost.embed)) {
|
|
193
|
+
for (const item of embeddedPost.embed.items) {
|
|
194
|
+
if (AppBskyEmbedGallery.isImage(item)) {
|
|
195
|
+
const matches = matchMuteWords({
|
|
196
|
+
mutedWords,
|
|
197
|
+
text: item.alt,
|
|
198
|
+
languages: embeddedPost.langs,
|
|
199
|
+
actor: embedAuthor,
|
|
200
|
+
});
|
|
201
|
+
if (matches) {
|
|
202
|
+
return matches;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
175
207
|
// quoted post's link card
|
|
176
208
|
if (AppBskyEmbedExternal.isMain(embeddedPost.embed)) {
|
|
177
209
|
const { external } = embeddedPost.embed;
|
|
@@ -215,6 +247,24 @@ function matchAllMuteWords(subject, mutedWords) {
|
|
|
215
247
|
}
|
|
216
248
|
}
|
|
217
249
|
}
|
|
250
|
+
// quoted post's gallery when it did a quote + media
|
|
251
|
+
if (AppBskyEmbedGallery.isMain(embeddedPost.embed.media)) {
|
|
252
|
+
for (const item of embeddedPost.embed.media.items) {
|
|
253
|
+
if (AppBskyEmbedGallery.isImage(item)) {
|
|
254
|
+
const matches = matchMuteWords({
|
|
255
|
+
mutedWords,
|
|
256
|
+
text: item.alt,
|
|
257
|
+
languages: AppBskyFeedPost.isRecord(embeddedPost.record)
|
|
258
|
+
? embeddedPost.langs
|
|
259
|
+
: [],
|
|
260
|
+
actor: embedAuthor,
|
|
261
|
+
});
|
|
262
|
+
if (matches) {
|
|
263
|
+
return matches;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
218
268
|
}
|
|
219
269
|
}
|
|
220
270
|
}
|
|
@@ -266,6 +316,24 @@ function matchAllMuteWords(subject, mutedWords) {
|
|
|
266
316
|
}
|
|
267
317
|
}
|
|
268
318
|
}
|
|
319
|
+
// quoted post gallery
|
|
320
|
+
if (AppBskyEmbedGallery.isView(embed.media)) {
|
|
321
|
+
for (const item of embed.media.items) {
|
|
322
|
+
if (AppBskyEmbedGallery.isViewImage(item)) {
|
|
323
|
+
const matches = matchMuteWords({
|
|
324
|
+
mutedWords,
|
|
325
|
+
text: item.alt,
|
|
326
|
+
languages: AppBskyFeedPost.isRecord(subject.record)
|
|
327
|
+
? subject.record.langs
|
|
328
|
+
: [],
|
|
329
|
+
actor: embedAuthor,
|
|
330
|
+
});
|
|
331
|
+
if (matches) {
|
|
332
|
+
return matches;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
}
|
|
269
337
|
if (AppBskyEmbedExternal.isView(embed.media)) {
|
|
270
338
|
const { external } = embed.media;
|
|
271
339
|
const matches = matchMuteWords({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"post.js","sourceRoot":"","sources":["../../../src/moderation/subjects/post.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,2BAA2B,EAC3B,eAAe,GAChB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAA;AACnD,OAAO,EAAiB,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAE/D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAE5C,MAAM,UAAU,UAAU,CACxB,OAA8B,EAC9B,IAAoB;IAEpB,OAAO,kBAAkB,CAAC,KAAK,CAC7B,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,EAC5B,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,SAAS,EAAE,EAC7C,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,EACnC,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CACpC,CAAA;AACH,CAAC;AAED,SAAS,aAAa,CACpB,OAA8B,EAC9B,IAAoB;IAEpB,MAAM,GAAG,GAAG,IAAI,kBAAkB,EAAE,CAAA;IAEpC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAC9B,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK,IAAI,CAAC,OAAO,CAAC,CAAA;IAChD,IAAI,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnC,GAAG,CAAC,QAAQ,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IACD,GAAG,CAAC,SAAS,CAAC,eAAe,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAA;IAC/D,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACd,GAAG,CAAC,YAAY,CAAC,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAA;IACrE,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,WAAW,CAClB,KAIqB,EACrB,IAAoB;IAEpB,IAAI,KAAK,EAAE,CAAC;QACV,IACE,CAAC,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC;YAC/B,2BAA2B,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5C,kBAAkB,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,EAC7C,CAAC;YACD,aAAa;YACb,OAAO,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QAC7C,CAAC;aAAM,IACL,2BAA2B,CAAC,MAAM,CAAC,KAAK,CAAC;YACzC,kBAAkB,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EACpD,CAAC;YACD,yBAAyB;YACzB,OAAO,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QACpD,CAAC;aAAM,IACL,CAAC,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC;YAC/B,2BAA2B,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5C,kBAAkB,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,EAC9C,CAAC;YACD,qBAAqB;YACrB,OAAO,uBAAuB,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QACpD,CAAC;aAAM,IACL,2BAA2B,CAAC,MAAM,CAAC,KAAK,CAAC;YACzC,kBAAkB,CAAC,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EACrD,CAAC;YACD,iCAAiC;YACjC,OAAO,uBAAuB,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QAC3D,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,SAAS,gBAAgB,CACvB,OAAsC,EACtC,IAAoB;IAEpB,MAAM,GAAG,GAAG,IAAI,kBAAkB,EAAE,CAAA;IACpC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAC9B,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK,IAAI,CAAC,OAAO,CAAC,CAAA;IAChD,IAAI,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnC,GAAG,CAAC,QAAQ,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IACD,OAAO,kBAAkB,CAAC,KAAK,CAC7B,GAAG,EACH,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,EACnC,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CACpC,CAAA;AACH,CAAC;AAED,SAAS,uBAAuB,CAC9B,OAAuC,EACvC,IAAoB;IAEpB,MAAM,GAAG,GAAG,IAAI,kBAAkB,EAAE,CAAA;IACpC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;IAC9B,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,KAAK,IAAI,CAAC,OAAO,CAAC,CAAA;IAChD,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;QACjC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC;YACvC,GAAG,CAAC,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;QACxD,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;QAC5C,CAAC;IACH,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC;QACpC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,CAAC;YAC1C,GAAG,CAAC,iBAAiB,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAA;QAC9D,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;QAClD,CAAC;IACH,CAAC;IACD,GAAG,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAClD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,eAAe,CACtB,OAA8B,EAC9B,WAAiC;IAEjC,IAAI,CAAC,WAAW,EAAE,MAAM,EAAE,CAAC;QACzB,OAAO,KAAK,CAAA;IACd,CAAC;IACD,IAAI,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACtC,OAAO,IAAI,CAAA;IACb,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,IACE,kBAAkB,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;YACxC,kBAAkB,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;YACrD,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAC9C,CAAC;YACD,OAAO,IAAI,CAAA;QACb,CAAC;QACD,IACE,2BAA2B,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;YACjD,kBAAkB,CAAC,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;YAC5D,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EACrD,CAAC;YACD,OAAO,IAAI,CAAA;QACb,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,SAAS,iBAAiB,CACxB,OAA8B,EAC9B,UAAoD;IAEpD,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,CAAC;QACxB,OAAM;IACR,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAA;IAEjC,IAAI,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,GAAG,OAAO,CAAC,MAAgC,CAAA;QAErD,MAAM,OAAO,GAAG,cAAc,CAAC;YAC7B,UAAU;YACV,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,WAAW,EAAE,IAAI,CAAC,IAAI;YACtB,SAAS,EAAE,IAAI,CAAC,KAAK;YACrB,KAAK,EAAE,UAAU;SAClB,CAAC,CAAA;QACF,YAAY;QACZ,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,OAAO,CAAA;QAChB,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,IAAI,kBAAkB,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACxD,cAAc;YACd,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACtC,MAAM,OAAO,GAAG,cAAc,CAAC;oBAC7B,UAAU;oBACV,IAAI,EAAE,KAAK,CAAC,GAAG;oBACf,SAAS,EAAE,IAAI,CAAC,KAAK;oBACrB,KAAK,EAAE,UAAU;iBAClB,CAAC,CAAA;gBACF,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO,OAAO,CAAA;gBAChB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;IACzB,IAAI,KAAK,EAAE,CAAC;QACV,aAAa;QACb,IACE,CAAC,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC;YAC/B,2BAA2B,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC5C,kBAAkB,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,EAC7C,CAAC;YACD,IAAI,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBACjD,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC,KAA+B,CAAA;gBACjE,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAA;gBACvC,MAAM,OAAO,GAAG,cAAc,CAAC;oBAC7B,UAAU;oBACV,IAAI,EAAE,YAAY,CAAC,IAAI;oBACvB,MAAM,EAAE,YAAY,CAAC,MAAM;oBAC3B,WAAW,EAAE,YAAY,CAAC,IAAI;oBAC9B,SAAS,EAAE,YAAY,CAAC,KAAK;oBAC7B,KAAK,EAAE,WAAW;iBACnB,CAAC,CAAA;gBAEF,mBAAmB;gBACnB,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO,OAAO,CAAA;gBAChB,CAAC;gBAED,uBAAuB;gBACvB,IAAI,kBAAkB,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;oBAClD,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;wBAC9C,MAAM,OAAO,GAAG,cAAc,CAAC;4BAC7B,UAAU;4BACV,IAAI,EAAE,KAAK,CAAC,GAAG;4BACf,SAAS,EAAE,YAAY,CAAC,KAAK;4BAC7B,KAAK,EAAE,WAAW;yBACnB,CAAC,CAAA;wBACF,IAAI,OAAO,EAAE,CAAC;4BACZ,OAAO,OAAO,CAAA;wBAChB,CAAC;oBACH,CAAC;gBACH,CAAC;gBAED,0BAA0B;gBAC1B,IAAI,oBAAoB,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;oBACpD,MAAM,EAAE,QAAQ,EAAE,GAAG,YAAY,CAAC,KAAK,CAAA;oBACvC,MAAM,OAAO,GAAG,cAAc,CAAC;wBAC7B,UAAU;wBACV,IAAI,EAAE,QAAQ,CAAC,KAAK,GAAG,GAAG,GAAG,QAAQ,CAAC,WAAW;wBACjD,SAAS,EAAE,EAAE;wBACb,KAAK,EAAE,WAAW;qBACnB,CAAC,CAAA;oBACF,IAAI,OAAO,EAAE,CAAC;wBACZ,OAAO,OAAO,CAAA;oBAChB,CAAC;gBACH,CAAC;gBAED,IAAI,2BAA2B,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC3D,sDAAsD;oBACtD,IAAI,oBAAoB,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;wBAC1D,MAAM,EAAE,QAAQ,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,KAAK,CAAA;wBAC7C,MAAM,OAAO,GAAG,cAAc,CAAC;4BAC7B,UAAU;4BACV,IAAI,EAAE,QAAQ,CAAC,KAAK,GAAG,GAAG,GAAG,QAAQ,CAAC,WAAW;4BACjD,SAAS,EAAE,EAAE;4BACb,KAAK,EAAE,WAAW;yBACnB,CAAC,CAAA;wBACF,IAAI,OAAO,EAAE,CAAC;4BACZ,OAAO,OAAO,CAAA;wBAChB,CAAC;oBACH,CAAC;oBAED,mDAAmD;oBACnD,IAAI,kBAAkB,CAAC,MAAM,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;wBACxD,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;4BACpD,MAAM,OAAO,GAAG,cAAc,CAAC;gCAC7B,UAAU;gCACV,IAAI,EAAE,KAAK,CAAC,GAAG;gCACf,SAAS,EAAE,eAAe,CAAC,QAAQ,CAAC,YAAY,CAAC,MAAM,CAAC;oCACtD,CAAC,CAAC,YAAY,CAAC,KAAK;oCACpB,CAAC,CAAC,EAAE;gCACN,KAAK,EAAE,WAAW;6BACnB,CAAC,CAAA;4BACF,IAAI,OAAO,EAAE,CAAC;gCACZ,OAAO,OAAO,CAAA;4BAChB,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,YAAY;aACP,IAAI,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5C,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAA;YAC1B,MAAM,OAAO,GAAG,cAAc,CAAC;gBAC7B,UAAU;gBACV,IAAI,EAAE,QAAQ,CAAC,KAAK,GAAG,GAAG,GAAG,QAAQ,CAAC,WAAW;gBACjD,SAAS,EAAE,EAAE;gBACb,KAAK,EAAE,UAAU;aAClB,CAAC,CAAA;YACF,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,OAAO,CAAA;YAChB,CAAC;QACH,CAAC;QACD,wBAAwB;aACnB,IACH,2BAA2B,CAAC,MAAM,CAAC,KAAK,CAAC;YACzC,kBAAkB,CAAC,YAAY,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EACpD,CAAC;YACD,MAAM,WAAW,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAA;YAE9C,mBAAmB;YACnB,IAAI,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxD,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,KAA+B,CAAA;gBAChE,MAAM,OAAO,GAAG,cAAc,CAAC;oBAC7B,UAAU;oBACV,IAAI,EAAE,IAAI,CAAC,IAAI;oBACf,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,WAAW,EAAE,IAAI,CAAC,IAAI;oBACtB,SAAS,EAAE,IAAI,CAAC,KAAK;oBACrB,KAAK,EAAE,WAAW;iBACnB,CAAC,CAAA;gBACF,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO,OAAO,CAAA;gBAChB,CAAC;YACH,CAAC;YAED,qBAAqB;YACrB,IAAI,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC3C,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;oBACvC,MAAM,OAAO,GAAG,cAAc,CAAC;wBAC7B,UAAU;wBACV,IAAI,EAAE,KAAK,CAAC,GAAG;wBACf,SAAS,EAAE,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC;4BACjD,CAAC,CAAE,OAAO,CAAC,MAAiC,CAAC,KAAK;4BAClD,CAAC,CAAC,EAAE;wBACN,KAAK,EAAE,WAAW;qBACnB,CAAC,CAAA;oBACF,IAAI,OAAO,EAAE,CAAC;wBACZ,OAAO,OAAO,CAAA;oBAChB,CAAC;gBACH,CAAC;YACH,CAAC;YAED,IAAI,oBAAoB,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC7C,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC,KAAK,CAAA;gBAChC,MAAM,OAAO,GAAG,cAAc,CAAC;oBAC7B,UAAU;oBACV,IAAI,EAAE,QAAQ,CAAC,KAAK,GAAG,GAAG,GAAG,QAAQ,CAAC,WAAW;oBACjD,SAAS,EAAE,EAAE;oBACb,KAAK,EAAE,WAAW;iBACnB,CAAC,CAAA;gBACF,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO,OAAO,CAAA;gBAChB,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC","sourcesContent":["import {\n AppBskyActorDefs,\n AppBskyEmbedExternal,\n AppBskyEmbedImages,\n AppBskyEmbedRecord,\n AppBskyEmbedRecordWithMedia,\n AppBskyFeedPost,\n} from '../../client/index.js'\nimport { $Typed } from '../../client/util.js'\nimport { ModerationDecision } from '../decision.js'\nimport { MuteWordMatch, matchMuteWords } from '../mutewords.js'\nimport { ModerationOpts, ModerationSubjectPost } from '../types.js'\nimport { decideAccount } from './account.js'\nimport { decideProfile } from './profile.js'\n\nexport function decidePost(\n subject: ModerationSubjectPost,\n opts: ModerationOpts,\n): ModerationDecision {\n return ModerationDecision.merge(\n decideSubject(subject, opts),\n decideEmbed(subject.embed, opts)?.downgrade(),\n decideAccount(subject.author, opts),\n decideProfile(subject.author, opts),\n )\n}\n\nfunction decideSubject(\n subject: ModerationSubjectPost,\n opts: ModerationOpts,\n): ModerationDecision {\n const acc = new ModerationDecision()\n\n acc.setDid(subject.author.did)\n acc.setIsMe(subject.author.did === opts.userDid)\n if (subject.labels?.length) {\n for (const label of subject.labels) {\n acc.addLabel('content', label, opts)\n }\n }\n acc.addHidden(checkHiddenPost(subject, opts.prefs.hiddenPosts))\n if (!acc.isMe) {\n acc.addMutedWord(matchAllMuteWords(subject, opts.prefs.mutedWords))\n }\n\n return acc\n}\n\nfunction decideEmbed(\n embed:\n | undefined\n | $Typed<AppBskyEmbedRecord.View>\n | $Typed<AppBskyEmbedRecordWithMedia.View>\n | { $type: string },\n opts: ModerationOpts,\n) {\n if (embed) {\n if (\n (AppBskyEmbedRecord.isView(embed) ||\n AppBskyEmbedRecordWithMedia.isView(embed)) &&\n AppBskyEmbedRecord.isViewRecord(embed.record)\n ) {\n // quote post\n return decideQuotedPost(embed.record, opts)\n } else if (\n AppBskyEmbedRecordWithMedia.isView(embed) &&\n AppBskyEmbedRecord.isViewRecord(embed.record.record)\n ) {\n // quoted post with media\n return decideQuotedPost(embed.record.record, opts)\n } else if (\n (AppBskyEmbedRecord.isView(embed) ||\n AppBskyEmbedRecordWithMedia.isView(embed)) &&\n AppBskyEmbedRecord.isViewBlocked(embed.record)\n ) {\n // blocked quote post\n return decideBlockedQuotedPost(embed.record, opts)\n } else if (\n AppBskyEmbedRecordWithMedia.isView(embed) &&\n AppBskyEmbedRecord.isViewBlocked(embed.record.record)\n ) {\n // blocked quoted post with media\n return decideBlockedQuotedPost(embed.record.record, opts)\n }\n }\n\n return undefined\n}\n\nfunction decideQuotedPost(\n subject: AppBskyEmbedRecord.ViewRecord,\n opts: ModerationOpts,\n) {\n const acc = new ModerationDecision()\n acc.setDid(subject.author.did)\n acc.setIsMe(subject.author.did === opts.userDid)\n if (subject.labels?.length) {\n for (const label of subject.labels) {\n acc.addLabel('content', label, opts)\n }\n }\n return ModerationDecision.merge(\n acc,\n decideAccount(subject.author, opts),\n decideProfile(subject.author, opts),\n )\n}\n\nfunction decideBlockedQuotedPost(\n subject: AppBskyEmbedRecord.ViewBlocked,\n opts: ModerationOpts,\n) {\n const acc = new ModerationDecision()\n acc.setDid(subject.author.did)\n acc.setIsMe(subject.author.did === opts.userDid)\n if (subject.author.viewer?.muted) {\n if (subject.author.viewer?.mutedByList) {\n acc.addMutedByList(subject.author.viewer?.mutedByList)\n } else {\n acc.addMuted(subject.author.viewer?.muted)\n }\n }\n if (subject.author.viewer?.blocking) {\n if (subject.author.viewer?.blockingByList) {\n acc.addBlockingByList(subject.author.viewer?.blockingByList)\n } else {\n acc.addBlocking(subject.author.viewer?.blocking)\n }\n }\n acc.addBlockedBy(subject.author.viewer?.blockedBy)\n return acc\n}\n\nfunction checkHiddenPost(\n subject: ModerationSubjectPost,\n hiddenPosts: string[] | undefined,\n) {\n if (!hiddenPosts?.length) {\n return false\n }\n if (hiddenPosts.includes(subject.uri)) {\n return true\n }\n if (subject.embed) {\n if (\n AppBskyEmbedRecord.isView(subject.embed) &&\n AppBskyEmbedRecord.isViewRecord(subject.embed.record) &&\n hiddenPosts.includes(subject.embed.record.uri)\n ) {\n return true\n }\n if (\n AppBskyEmbedRecordWithMedia.isView(subject.embed) &&\n AppBskyEmbedRecord.isViewRecord(subject.embed.record.record) &&\n hiddenPosts.includes(subject.embed.record.record.uri)\n ) {\n return true\n }\n }\n return false\n}\n\nfunction matchAllMuteWords(\n subject: ModerationSubjectPost,\n mutedWords: AppBskyActorDefs.MutedWord[] | undefined,\n): MuteWordMatch[] | undefined {\n if (!mutedWords?.length) {\n return\n }\n\n const postAuthor = subject.author\n\n if (AppBskyFeedPost.isRecord(subject.record)) {\n const post = subject.record as AppBskyFeedPost.Record\n\n const matches = matchMuteWords({\n mutedWords,\n text: post.text,\n facets: post.facets,\n outlineTags: post.tags,\n languages: post.langs,\n actor: postAuthor,\n })\n // post text\n if (matches) {\n return matches\n }\n\n if (post.embed && AppBskyEmbedImages.isMain(post.embed)) {\n // post images\n for (const image of post.embed.images) {\n const matches = matchMuteWords({\n mutedWords,\n text: image.alt,\n languages: post.langs,\n actor: postAuthor,\n })\n if (matches) {\n return matches\n }\n }\n }\n }\n\n const { embed } = subject\n if (embed) {\n // quote post\n if (\n (AppBskyEmbedRecord.isView(embed) ||\n AppBskyEmbedRecordWithMedia.isView(embed)) &&\n AppBskyEmbedRecord.isViewRecord(embed.record)\n ) {\n if (AppBskyFeedPost.isRecord(embed.record.value)) {\n const embeddedPost = embed.record.value as AppBskyFeedPost.Record\n const embedAuthor = embed.record.author\n const matches = matchMuteWords({\n mutedWords,\n text: embeddedPost.text,\n facets: embeddedPost.facets,\n outlineTags: embeddedPost.tags,\n languages: embeddedPost.langs,\n actor: embedAuthor,\n })\n\n // quoted post text\n if (matches) {\n return matches\n }\n\n // quoted post's images\n if (AppBskyEmbedImages.isMain(embeddedPost.embed)) {\n for (const image of embeddedPost.embed.images) {\n const matches = matchMuteWords({\n mutedWords,\n text: image.alt,\n languages: embeddedPost.langs,\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n }\n\n // quoted post's link card\n if (AppBskyEmbedExternal.isMain(embeddedPost.embed)) {\n const { external } = embeddedPost.embed\n const matches = matchMuteWords({\n mutedWords,\n text: external.title + ' ' + external.description,\n languages: [],\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n\n if (AppBskyEmbedRecordWithMedia.isMain(embeddedPost.embed)) {\n // quoted post's link card when it did a quote + media\n if (AppBskyEmbedExternal.isMain(embeddedPost.embed.media)) {\n const { external } = embeddedPost.embed.media\n const matches = matchMuteWords({\n mutedWords,\n text: external.title + ' ' + external.description,\n languages: [],\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n\n // quoted post's images when it did a quote + media\n if (AppBskyEmbedImages.isMain(embeddedPost.embed.media)) {\n for (const image of embeddedPost.embed.media.images) {\n const matches = matchMuteWords({\n mutedWords,\n text: image.alt,\n languages: AppBskyFeedPost.isRecord(embeddedPost.record)\n ? embeddedPost.langs\n : [],\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n }\n }\n }\n }\n // link card\n else if (AppBskyEmbedExternal.isView(embed)) {\n const { external } = embed\n const matches = matchMuteWords({\n mutedWords,\n text: external.title + ' ' + external.description,\n languages: [],\n actor: postAuthor,\n })\n if (matches) {\n return matches\n }\n }\n // quote post with media\n else if (\n AppBskyEmbedRecordWithMedia.isView(embed) &&\n AppBskyEmbedRecord.isViewRecord(embed.record.record)\n ) {\n const embedAuthor = embed.record.record.author\n\n // quoted post text\n if (AppBskyFeedPost.isRecord(embed.record.record.value)) {\n const post = embed.record.record.value as AppBskyFeedPost.Record\n const matches = matchMuteWords({\n mutedWords,\n text: post.text,\n facets: post.facets,\n outlineTags: post.tags,\n languages: post.langs,\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n\n // quoted post images\n if (AppBskyEmbedImages.isView(embed.media)) {\n for (const image of embed.media.images) {\n const matches = matchMuteWords({\n mutedWords,\n text: image.alt,\n languages: AppBskyFeedPost.isRecord(subject.record)\n ? (subject.record as AppBskyFeedPost.Record).langs\n : [],\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n }\n\n if (AppBskyEmbedExternal.isView(embed.media)) {\n const { external } = embed.media\n const matches = matchMuteWords({\n mutedWords,\n text: external.title + ' ' + external.description,\n languages: [],\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"post.js","sourceRoot":"","sources":["../../../src/moderation/subjects/post.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n AppBskyActorDefs,\n AppBskyEmbedExternal,\n AppBskyEmbedGallery,\n AppBskyEmbedImages,\n AppBskyEmbedRecord,\n AppBskyEmbedRecordWithMedia,\n AppBskyFeedPost,\n} from '../../client/index.js'\nimport { $Typed } from '../../client/util.js'\nimport { ModerationDecision } from '../decision.js'\nimport { MuteWordMatch, matchMuteWords } from '../mutewords.js'\nimport { ModerationOpts, ModerationSubjectPost } from '../types.js'\nimport { decideAccount } from './account.js'\nimport { decideProfile } from './profile.js'\n\nexport function decidePost(\n subject: ModerationSubjectPost,\n opts: ModerationOpts,\n): ModerationDecision {\n return ModerationDecision.merge(\n decideSubject(subject, opts),\n decideEmbed(subject.embed, opts)?.downgrade(),\n decideAccount(subject.author, opts),\n decideProfile(subject.author, opts),\n )\n}\n\nfunction decideSubject(\n subject: ModerationSubjectPost,\n opts: ModerationOpts,\n): ModerationDecision {\n const acc = new ModerationDecision()\n\n acc.setDid(subject.author.did)\n acc.setIsMe(subject.author.did === opts.userDid)\n if (subject.labels?.length) {\n for (const label of subject.labels) {\n acc.addLabel('content', label, opts)\n }\n }\n acc.addHidden(checkHiddenPost(subject, opts.prefs.hiddenPosts))\n if (!acc.isMe) {\n acc.addMutedWord(matchAllMuteWords(subject, opts.prefs.mutedWords))\n }\n\n return acc\n}\n\nfunction decideEmbed(\n embed:\n | undefined\n | $Typed<AppBskyEmbedRecord.View>\n | $Typed<AppBskyEmbedRecordWithMedia.View>\n | { $type: string },\n opts: ModerationOpts,\n) {\n if (embed) {\n if (\n (AppBskyEmbedRecord.isView(embed) ||\n AppBskyEmbedRecordWithMedia.isView(embed)) &&\n AppBskyEmbedRecord.isViewRecord(embed.record)\n ) {\n // quote post\n return decideQuotedPost(embed.record, opts)\n } else if (\n AppBskyEmbedRecordWithMedia.isView(embed) &&\n AppBskyEmbedRecord.isViewRecord(embed.record.record)\n ) {\n // quoted post with media\n return decideQuotedPost(embed.record.record, opts)\n } else if (\n (AppBskyEmbedRecord.isView(embed) ||\n AppBskyEmbedRecordWithMedia.isView(embed)) &&\n AppBskyEmbedRecord.isViewBlocked(embed.record)\n ) {\n // blocked quote post\n return decideBlockedQuotedPost(embed.record, opts)\n } else if (\n AppBskyEmbedRecordWithMedia.isView(embed) &&\n AppBskyEmbedRecord.isViewBlocked(embed.record.record)\n ) {\n // blocked quoted post with media\n return decideBlockedQuotedPost(embed.record.record, opts)\n }\n }\n\n return undefined\n}\n\nfunction decideQuotedPost(\n subject: AppBskyEmbedRecord.ViewRecord,\n opts: ModerationOpts,\n) {\n const acc = new ModerationDecision()\n acc.setDid(subject.author.did)\n acc.setIsMe(subject.author.did === opts.userDid)\n if (subject.labels?.length) {\n for (const label of subject.labels) {\n acc.addLabel('content', label, opts)\n }\n }\n return ModerationDecision.merge(\n acc,\n decideAccount(subject.author, opts),\n decideProfile(subject.author, opts),\n )\n}\n\nfunction decideBlockedQuotedPost(\n subject: AppBskyEmbedRecord.ViewBlocked,\n opts: ModerationOpts,\n) {\n const acc = new ModerationDecision()\n acc.setDid(subject.author.did)\n acc.setIsMe(subject.author.did === opts.userDid)\n if (subject.author.viewer?.muted) {\n if (subject.author.viewer?.mutedByList) {\n acc.addMutedByList(subject.author.viewer?.mutedByList)\n } else {\n acc.addMuted(subject.author.viewer?.muted)\n }\n }\n if (subject.author.viewer?.blocking) {\n if (subject.author.viewer?.blockingByList) {\n acc.addBlockingByList(subject.author.viewer?.blockingByList)\n } else {\n acc.addBlocking(subject.author.viewer?.blocking)\n }\n }\n acc.addBlockedBy(subject.author.viewer?.blockedBy)\n return acc\n}\n\nfunction checkHiddenPost(\n subject: ModerationSubjectPost,\n hiddenPosts: string[] | undefined,\n) {\n if (!hiddenPosts?.length) {\n return false\n }\n if (hiddenPosts.includes(subject.uri)) {\n return true\n }\n if (subject.embed) {\n if (\n AppBskyEmbedRecord.isView(subject.embed) &&\n AppBskyEmbedRecord.isViewRecord(subject.embed.record) &&\n hiddenPosts.includes(subject.embed.record.uri)\n ) {\n return true\n }\n if (\n AppBskyEmbedRecordWithMedia.isView(subject.embed) &&\n AppBskyEmbedRecord.isViewRecord(subject.embed.record.record) &&\n hiddenPosts.includes(subject.embed.record.record.uri)\n ) {\n return true\n }\n }\n return false\n}\n\nfunction matchAllMuteWords(\n subject: ModerationSubjectPost,\n mutedWords: AppBskyActorDefs.MutedWord[] | undefined,\n): MuteWordMatch[] | undefined {\n if (!mutedWords?.length) {\n return\n }\n\n const postAuthor = subject.author\n\n if (AppBskyFeedPost.isRecord(subject.record)) {\n const post = subject.record as AppBskyFeedPost.Record\n\n const matches = matchMuteWords({\n mutedWords,\n text: post.text,\n facets: post.facets,\n outlineTags: post.tags,\n languages: post.langs,\n actor: postAuthor,\n })\n // post text\n if (matches) {\n return matches\n }\n\n if (post.embed && AppBskyEmbedImages.isMain(post.embed)) {\n // post images\n for (const image of post.embed.images) {\n const matches = matchMuteWords({\n mutedWords,\n text: image.alt,\n languages: post.langs,\n actor: postAuthor,\n })\n if (matches) {\n return matches\n }\n }\n }\n\n if (post.embed && AppBskyEmbedGallery.isMain(post.embed)) {\n // post gallery items\n for (const item of post.embed.items) {\n if (AppBskyEmbedGallery.isImage(item)) {\n const matches = matchMuteWords({\n mutedWords,\n text: item.alt,\n languages: post.langs,\n actor: postAuthor,\n })\n if (matches) {\n return matches\n }\n }\n }\n }\n }\n\n const { embed } = subject\n if (embed) {\n // quote post\n if (\n (AppBskyEmbedRecord.isView(embed) ||\n AppBskyEmbedRecordWithMedia.isView(embed)) &&\n AppBskyEmbedRecord.isViewRecord(embed.record)\n ) {\n if (AppBskyFeedPost.isRecord(embed.record.value)) {\n const embeddedPost = embed.record.value as AppBskyFeedPost.Record\n const embedAuthor = embed.record.author\n const matches = matchMuteWords({\n mutedWords,\n text: embeddedPost.text,\n facets: embeddedPost.facets,\n outlineTags: embeddedPost.tags,\n languages: embeddedPost.langs,\n actor: embedAuthor,\n })\n\n // quoted post text\n if (matches) {\n return matches\n }\n\n // quoted post's images\n if (AppBskyEmbedImages.isMain(embeddedPost.embed)) {\n for (const image of embeddedPost.embed.images) {\n const matches = matchMuteWords({\n mutedWords,\n text: image.alt,\n languages: embeddedPost.langs,\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n }\n\n // quoted post's gallery\n if (AppBskyEmbedGallery.isMain(embeddedPost.embed)) {\n for (const item of embeddedPost.embed.items) {\n if (AppBskyEmbedGallery.isImage(item)) {\n const matches = matchMuteWords({\n mutedWords,\n text: item.alt,\n languages: embeddedPost.langs,\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n }\n }\n\n // quoted post's link card\n if (AppBskyEmbedExternal.isMain(embeddedPost.embed)) {\n const { external } = embeddedPost.embed\n const matches = matchMuteWords({\n mutedWords,\n text: external.title + ' ' + external.description,\n languages: [],\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n\n if (AppBskyEmbedRecordWithMedia.isMain(embeddedPost.embed)) {\n // quoted post's link card when it did a quote + media\n if (AppBskyEmbedExternal.isMain(embeddedPost.embed.media)) {\n const { external } = embeddedPost.embed.media\n const matches = matchMuteWords({\n mutedWords,\n text: external.title + ' ' + external.description,\n languages: [],\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n\n // quoted post's images when it did a quote + media\n if (AppBskyEmbedImages.isMain(embeddedPost.embed.media)) {\n for (const image of embeddedPost.embed.media.images) {\n const matches = matchMuteWords({\n mutedWords,\n text: image.alt,\n languages: AppBskyFeedPost.isRecord(embeddedPost.record)\n ? embeddedPost.langs\n : [],\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n }\n\n // quoted post's gallery when it did a quote + media\n if (AppBskyEmbedGallery.isMain(embeddedPost.embed.media)) {\n for (const item of embeddedPost.embed.media.items) {\n if (AppBskyEmbedGallery.isImage(item)) {\n const matches = matchMuteWords({\n mutedWords,\n text: item.alt,\n languages: AppBskyFeedPost.isRecord(embeddedPost.record)\n ? embeddedPost.langs\n : [],\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n }\n }\n }\n }\n }\n // link card\n else if (AppBskyEmbedExternal.isView(embed)) {\n const { external } = embed\n const matches = matchMuteWords({\n mutedWords,\n text: external.title + ' ' + external.description,\n languages: [],\n actor: postAuthor,\n })\n if (matches) {\n return matches\n }\n }\n // quote post with media\n else if (\n AppBskyEmbedRecordWithMedia.isView(embed) &&\n AppBskyEmbedRecord.isViewRecord(embed.record.record)\n ) {\n const embedAuthor = embed.record.record.author\n\n // quoted post text\n if (AppBskyFeedPost.isRecord(embed.record.record.value)) {\n const post = embed.record.record.value as AppBskyFeedPost.Record\n const matches = matchMuteWords({\n mutedWords,\n text: post.text,\n facets: post.facets,\n outlineTags: post.tags,\n languages: post.langs,\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n\n // quoted post images\n if (AppBskyEmbedImages.isView(embed.media)) {\n for (const image of embed.media.images) {\n const matches = matchMuteWords({\n mutedWords,\n text: image.alt,\n languages: AppBskyFeedPost.isRecord(subject.record)\n ? (subject.record as AppBskyFeedPost.Record).langs\n : [],\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n }\n\n // quoted post gallery\n if (AppBskyEmbedGallery.isView(embed.media)) {\n for (const item of embed.media.items) {\n if (AppBskyEmbedGallery.isViewImage(item)) {\n const matches = matchMuteWords({\n mutedWords,\n text: item.alt,\n languages: AppBskyFeedPost.isRecord(subject.record)\n ? (subject.record as AppBskyFeedPost.Record).langs\n : [],\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n }\n }\n\n if (AppBskyEmbedExternal.isView(embed.media)) {\n const { external } = embed.media\n const matches = matchMuteWords({\n mutedWords,\n text: external.title + ' ' + external.description,\n languages: [],\n actor: embedAuthor,\n })\n if (matches) {\n return matches\n }\n }\n }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/api",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.10",
|
|
4
4
|
"engines": {
|
|
5
5
|
"node": ">=22"
|
|
6
6
|
},
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
"multiformats": "^13.0.0",
|
|
23
23
|
"tlds": "^1.234.0",
|
|
24
24
|
"zod": "^3.23.8",
|
|
25
|
-
"@atproto/
|
|
26
|
-
"@atproto/xrpc": "^0.8.0",
|
|
25
|
+
"@atproto/common-web": "^0.5.0",
|
|
27
26
|
"@atproto/lexicon": "^0.7.1",
|
|
28
|
-
"@atproto/
|
|
27
|
+
"@atproto/xrpc": "^0.8.0",
|
|
28
|
+
"@atproto/syntax": "^0.6.1"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@jest/globals": "^28.1.3",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AppBskyActorDefs,
|
|
3
3
|
AppBskyEmbedExternal,
|
|
4
|
+
AppBskyEmbedGallery,
|
|
4
5
|
AppBskyEmbedImages,
|
|
5
6
|
AppBskyEmbedRecord,
|
|
6
7
|
AppBskyEmbedRecordWithMedia,
|
|
@@ -200,6 +201,23 @@ function matchAllMuteWords(
|
|
|
200
201
|
}
|
|
201
202
|
}
|
|
202
203
|
}
|
|
204
|
+
|
|
205
|
+
if (post.embed && AppBskyEmbedGallery.isMain(post.embed)) {
|
|
206
|
+
// post gallery items
|
|
207
|
+
for (const item of post.embed.items) {
|
|
208
|
+
if (AppBskyEmbedGallery.isImage(item)) {
|
|
209
|
+
const matches = matchMuteWords({
|
|
210
|
+
mutedWords,
|
|
211
|
+
text: item.alt,
|
|
212
|
+
languages: post.langs,
|
|
213
|
+
actor: postAuthor,
|
|
214
|
+
})
|
|
215
|
+
if (matches) {
|
|
216
|
+
return matches
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
203
221
|
}
|
|
204
222
|
|
|
205
223
|
const { embed } = subject
|
|
@@ -242,6 +260,23 @@ function matchAllMuteWords(
|
|
|
242
260
|
}
|
|
243
261
|
}
|
|
244
262
|
|
|
263
|
+
// quoted post's gallery
|
|
264
|
+
if (AppBskyEmbedGallery.isMain(embeddedPost.embed)) {
|
|
265
|
+
for (const item of embeddedPost.embed.items) {
|
|
266
|
+
if (AppBskyEmbedGallery.isImage(item)) {
|
|
267
|
+
const matches = matchMuteWords({
|
|
268
|
+
mutedWords,
|
|
269
|
+
text: item.alt,
|
|
270
|
+
languages: embeddedPost.langs,
|
|
271
|
+
actor: embedAuthor,
|
|
272
|
+
})
|
|
273
|
+
if (matches) {
|
|
274
|
+
return matches
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
245
280
|
// quoted post's link card
|
|
246
281
|
if (AppBskyEmbedExternal.isMain(embeddedPost.embed)) {
|
|
247
282
|
const { external } = embeddedPost.embed
|
|
@@ -287,6 +322,25 @@ function matchAllMuteWords(
|
|
|
287
322
|
}
|
|
288
323
|
}
|
|
289
324
|
}
|
|
325
|
+
|
|
326
|
+
// quoted post's gallery when it did a quote + media
|
|
327
|
+
if (AppBskyEmbedGallery.isMain(embeddedPost.embed.media)) {
|
|
328
|
+
for (const item of embeddedPost.embed.media.items) {
|
|
329
|
+
if (AppBskyEmbedGallery.isImage(item)) {
|
|
330
|
+
const matches = matchMuteWords({
|
|
331
|
+
mutedWords,
|
|
332
|
+
text: item.alt,
|
|
333
|
+
languages: AppBskyFeedPost.isRecord(embeddedPost.record)
|
|
334
|
+
? embeddedPost.langs
|
|
335
|
+
: [],
|
|
336
|
+
actor: embedAuthor,
|
|
337
|
+
})
|
|
338
|
+
if (matches) {
|
|
339
|
+
return matches
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
290
344
|
}
|
|
291
345
|
}
|
|
292
346
|
}
|
|
@@ -343,6 +397,25 @@ function matchAllMuteWords(
|
|
|
343
397
|
}
|
|
344
398
|
}
|
|
345
399
|
|
|
400
|
+
// quoted post gallery
|
|
401
|
+
if (AppBskyEmbedGallery.isView(embed.media)) {
|
|
402
|
+
for (const item of embed.media.items) {
|
|
403
|
+
if (AppBskyEmbedGallery.isViewImage(item)) {
|
|
404
|
+
const matches = matchMuteWords({
|
|
405
|
+
mutedWords,
|
|
406
|
+
text: item.alt,
|
|
407
|
+
languages: AppBskyFeedPost.isRecord(subject.record)
|
|
408
|
+
? (subject.record as AppBskyFeedPost.Record).langs
|
|
409
|
+
: [],
|
|
410
|
+
actor: embedAuthor,
|
|
411
|
+
})
|
|
412
|
+
if (matches) {
|
|
413
|
+
return matches
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
|
|
346
419
|
if (AppBskyEmbedExternal.isView(embed.media)) {
|
|
347
420
|
const { external } = embed.media
|
|
348
421
|
const matches = matchMuteWords({
|
|
@@ -1,5 +1,60 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $Typed } from '../src/client/util.js'
|
|
2
|
+
import {
|
|
3
|
+
AppBskyEmbedGallery,
|
|
4
|
+
AppBskyEmbedRecord,
|
|
5
|
+
AppBskyEmbedRecordWithMedia,
|
|
6
|
+
AppBskyFeedPost,
|
|
7
|
+
BlobRef,
|
|
8
|
+
RichText,
|
|
9
|
+
mock,
|
|
10
|
+
moderatePost,
|
|
11
|
+
} from '../src/index.js'
|
|
2
12
|
import { matchMuteWords } from '../src/moderation/mutewords.js'
|
|
13
|
+
import { ModerationOpts } from '../src/moderation/types.js'
|
|
14
|
+
|
|
15
|
+
const FAKE_CID = 'bafyreiclp443lavogvhj3d2ob2cxbfuscni2k5jk7bebjzg7khl3esabwq'
|
|
16
|
+
|
|
17
|
+
const fakeBlob = (): BlobRef =>
|
|
18
|
+
new BlobRef({ '/': FAKE_CID } as any, 'image/jpeg', 1234)
|
|
19
|
+
|
|
20
|
+
const galleryRecord = (alts: string[]): $Typed<AppBskyEmbedGallery.Main> => ({
|
|
21
|
+
$type: 'app.bsky.embed.gallery',
|
|
22
|
+
items: alts.map(
|
|
23
|
+
(alt): $Typed<AppBskyEmbedGallery.Image> => ({
|
|
24
|
+
$type: 'app.bsky.embed.gallery#image',
|
|
25
|
+
image: fakeBlob(),
|
|
26
|
+
alt,
|
|
27
|
+
aspectRatio: { width: 4, height: 3 },
|
|
28
|
+
}),
|
|
29
|
+
),
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const galleryView = (alts: string[]): $Typed<AppBskyEmbedGallery.View> => ({
|
|
33
|
+
$type: 'app.bsky.embed.gallery#view',
|
|
34
|
+
items: alts.map(
|
|
35
|
+
(alt): $Typed<AppBskyEmbedGallery.ViewImage> => ({
|
|
36
|
+
$type: 'app.bsky.embed.gallery#viewImage',
|
|
37
|
+
thumbnail: 'https://example.test/thumb.jpg',
|
|
38
|
+
fullsize: 'https://example.test/full.jpg',
|
|
39
|
+
alt,
|
|
40
|
+
aspectRatio: { width: 4, height: 3 },
|
|
41
|
+
}),
|
|
42
|
+
),
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
const galleryMuteOpts = (): ModerationOpts => ({
|
|
46
|
+
userDid: 'did:web:alice.test',
|
|
47
|
+
prefs: {
|
|
48
|
+
adultContentEnabled: false,
|
|
49
|
+
labels: {},
|
|
50
|
+
labelers: [],
|
|
51
|
+
mutedWords: [
|
|
52
|
+
{ value: 'badword', targets: ['content'], actorTarget: 'all' },
|
|
53
|
+
],
|
|
54
|
+
hiddenPosts: [],
|
|
55
|
+
},
|
|
56
|
+
labelDefs: {},
|
|
57
|
+
})
|
|
3
58
|
|
|
4
59
|
describe(`matchMuteWords`, () => {
|
|
5
60
|
describe(`tags`, () => {
|
|
@@ -1119,4 +1174,126 @@ describe(`matchMuteWords`, () => {
|
|
|
1119
1174
|
])
|
|
1120
1175
|
})
|
|
1121
1176
|
})
|
|
1177
|
+
|
|
1178
|
+
describe(`gallery embed alt text`, () => {
|
|
1179
|
+
const bob = mock.profileViewBasic({
|
|
1180
|
+
handle: 'bob.test',
|
|
1181
|
+
displayName: 'Bob',
|
|
1182
|
+
})
|
|
1183
|
+
const carol = mock.profileViewBasic({
|
|
1184
|
+
handle: 'carol.test',
|
|
1185
|
+
displayName: 'Carol',
|
|
1186
|
+
})
|
|
1187
|
+
|
|
1188
|
+
it(`matches alt text on a directly-attached gallery embed`, () => {
|
|
1189
|
+
const res = moderatePost(
|
|
1190
|
+
mock.postView({
|
|
1191
|
+
record: mock.post({
|
|
1192
|
+
text: 'innocent text',
|
|
1193
|
+
embed: galleryRecord(['fine', 'this contains badword here']),
|
|
1194
|
+
}),
|
|
1195
|
+
author: bob,
|
|
1196
|
+
labels: [],
|
|
1197
|
+
}),
|
|
1198
|
+
galleryMuteOpts(),
|
|
1199
|
+
)
|
|
1200
|
+
expect(res.causes.find((c) => c.type === 'mute-word')).toBeDefined()
|
|
1201
|
+
})
|
|
1202
|
+
|
|
1203
|
+
it(`does not match when no item alt contains a muted word`, () => {
|
|
1204
|
+
const res = moderatePost(
|
|
1205
|
+
mock.postView({
|
|
1206
|
+
record: mock.post({
|
|
1207
|
+
text: 'innocent text',
|
|
1208
|
+
embed: galleryRecord(['nothing here', 'still nothing']),
|
|
1209
|
+
}),
|
|
1210
|
+
author: bob,
|
|
1211
|
+
labels: [],
|
|
1212
|
+
}),
|
|
1213
|
+
galleryMuteOpts(),
|
|
1214
|
+
)
|
|
1215
|
+
expect(res.causes.find((c) => c.type === 'mute-word')).toBeUndefined()
|
|
1216
|
+
})
|
|
1217
|
+
|
|
1218
|
+
it(`matches alt text inside a quoted record's gallery`, () => {
|
|
1219
|
+
const quoted: AppBskyFeedPost.Record = mock.post({
|
|
1220
|
+
text: 'inside quoted',
|
|
1221
|
+
embed: galleryRecord(['contains badword inside']),
|
|
1222
|
+
})
|
|
1223
|
+
const res = moderatePost(
|
|
1224
|
+
mock.postView({
|
|
1225
|
+
record: mock.post({ text: 'outer post' }),
|
|
1226
|
+
embed: mock.embedRecordView({
|
|
1227
|
+
record: quoted,
|
|
1228
|
+
author: carol,
|
|
1229
|
+
labels: [],
|
|
1230
|
+
}),
|
|
1231
|
+
author: bob,
|
|
1232
|
+
labels: [],
|
|
1233
|
+
}),
|
|
1234
|
+
galleryMuteOpts(),
|
|
1235
|
+
)
|
|
1236
|
+
expect(res.causes.find((c) => c.type === 'mute-word')).toBeDefined()
|
|
1237
|
+
})
|
|
1238
|
+
|
|
1239
|
+
it(`matches alt text on a quoted record's recordWithMedia gallery`, () => {
|
|
1240
|
+
const quotedRecord: AppBskyFeedPost.Record = mock.post({
|
|
1241
|
+
text: 'inside quoted record-with-media',
|
|
1242
|
+
embed: {
|
|
1243
|
+
$type: 'app.bsky.embed.recordWithMedia',
|
|
1244
|
+
record: {
|
|
1245
|
+
$type: 'app.bsky.embed.record',
|
|
1246
|
+
record: {
|
|
1247
|
+
uri: 'at://did:web:dave.test/app.bsky.feed.post/inner',
|
|
1248
|
+
cid: FAKE_CID,
|
|
1249
|
+
},
|
|
1250
|
+
} satisfies $Typed<AppBskyEmbedRecord.Main>,
|
|
1251
|
+
media: galleryRecord(['contains badword in nested gallery']),
|
|
1252
|
+
} satisfies $Typed<AppBskyEmbedRecordWithMedia.Main>,
|
|
1253
|
+
})
|
|
1254
|
+
const res = moderatePost(
|
|
1255
|
+
mock.postView({
|
|
1256
|
+
record: mock.post({ text: 'outer post' }),
|
|
1257
|
+
embed: mock.embedRecordView({
|
|
1258
|
+
record: quotedRecord,
|
|
1259
|
+
author: carol,
|
|
1260
|
+
labels: [],
|
|
1261
|
+
}),
|
|
1262
|
+
author: bob,
|
|
1263
|
+
labels: [],
|
|
1264
|
+
}),
|
|
1265
|
+
galleryMuteOpts(),
|
|
1266
|
+
)
|
|
1267
|
+
expect(res.causes.find((c) => c.type === 'mute-word')).toBeDefined()
|
|
1268
|
+
})
|
|
1269
|
+
|
|
1270
|
+
it(`matches alt text on the view-side recordWithMedia gallery`, () => {
|
|
1271
|
+
const recordWithMediaView: $Typed<AppBskyEmbedRecordWithMedia.View> = {
|
|
1272
|
+
$type: 'app.bsky.embed.recordWithMedia#view',
|
|
1273
|
+
record: {
|
|
1274
|
+
$type: 'app.bsky.embed.record#view',
|
|
1275
|
+
record: {
|
|
1276
|
+
$type: 'app.bsky.embed.record#viewRecord',
|
|
1277
|
+
uri: 'at://did:web:dave.test/app.bsky.feed.post/inner',
|
|
1278
|
+
cid: FAKE_CID,
|
|
1279
|
+
author: carol,
|
|
1280
|
+
value: mock.post({ text: 'inner content' }),
|
|
1281
|
+
labels: [],
|
|
1282
|
+
indexedAt: new Date().toISOString(),
|
|
1283
|
+
},
|
|
1284
|
+
},
|
|
1285
|
+
media: galleryView(['contains badword on view side']),
|
|
1286
|
+
}
|
|
1287
|
+
const res = moderatePost(
|
|
1288
|
+
mock.postView({
|
|
1289
|
+
record: mock.post({ text: 'outer post' }),
|
|
1290
|
+
embed: recordWithMediaView,
|
|
1291
|
+
author: bob,
|
|
1292
|
+
labels: [],
|
|
1293
|
+
}),
|
|
1294
|
+
galleryMuteOpts(),
|
|
1295
|
+
)
|
|
1296
|
+
expect(res.causes.find((c) => c.type === 'mute-word')).toBeDefined()
|
|
1297
|
+
})
|
|
1298
|
+
})
|
|
1122
1299
|
})
|