@atproto/api 0.4.4 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -0
- package/definitions/labels.json +212 -0
- package/definitions/locale/en/label-groups.json +38 -0
- package/definitions/locale/en/labels.json +366 -0
- package/definitions/locale/en/proposed-label-groups.json +38 -0
- package/definitions/locale/en/proposed-labels.json +632 -0
- package/definitions/moderation-behaviors.d.ts +48 -0
- package/definitions/post-moderation-behaviors.json +879 -0
- package/definitions/profile-moderation-behaviors.json +447 -0
- package/definitions/proposed-labels.json +326 -0
- package/dist/client/index.d.ts +3 -0
- package/dist/client/lexicons.d.ts +27 -1
- package/dist/client/types/app/bsky/actor/updateProfile.d.ts +3 -10
- package/dist/client/types/app/bsky/{feed/getBookmarkedFeeds.d.ts → graph/getListBlocks.d.ts} +2 -2
- package/dist/client/types/app/bsky/graph/listblock.d.ts +8 -0
- package/dist/client/types/app/bsky/{feed/unbookmarkFeed.d.ts → graph/subscribeMuteList.d.ts} +1 -1
- package/dist/client/types/app/bsky/{feed/bookmarkFeed.d.ts → graph/unsubscribeMuteList.d.ts} +1 -1
- package/dist/{src/client/types/app/bsky/notification/updateSeen.d.ts → client/types/app/bsky/unspecced/applyLabels.d.ts} +2 -1
- package/dist/helpers/bsky.d.ts +20 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +1401 -12
- package/dist/index.js.map +4 -4
- package/dist/mixins/bsky.d.ts +23 -0
- package/dist/moderation/accumulator.d.ts +14 -0
- package/dist/moderation/const/label-groups.d.ts +2 -0
- package/dist/moderation/const/labels.d.ts +2 -0
- package/dist/moderation/index.d.ts +44 -0
- package/dist/moderation/subjects/account.d.ts +3 -0
- package/dist/moderation/subjects/feed-generator.d.ts +2 -0
- package/dist/moderation/subjects/post.d.ts +2 -0
- package/dist/moderation/subjects/profile.d.ts +3 -0
- package/dist/moderation/subjects/quoted-post.d.ts +6 -0
- package/dist/moderation/subjects/user-list.d.ts +2 -0
- package/dist/moderation/types.d.ts +97 -0
- package/dist/moderation/util.d.ts +12 -0
- package/dist/rich-text/sanitize.d.ts +4 -0
- package/docs/labels.md +522 -0
- package/docs/moderation-behaviors/posts.md +1919 -0
- package/docs/moderation-behaviors/profiles.md +907 -0
- package/docs/moderation.md +144 -0
- package/package.json +6 -4
- package/scripts/code/label-groups.mjs +68 -0
- package/scripts/code/labels.mjs +68 -0
- package/scripts/docs/labels.mjs +164 -0
- package/scripts/docs/post-moderation-behaviors.mjs +122 -0
- package/scripts/docs/profile-moderation-behaviors.mjs +122 -0
- package/scripts/generate-code.mjs +4 -0
- package/scripts/generate-docs.mjs +5 -0
- package/src/client/index.ts +13 -0
- package/src/client/lexicons.ts +29 -3
- package/src/client/types/app/bsky/unspecced/applyLabels.ts +33 -0
- package/src/client/types/com/atproto/admin/enableAccountInvites.ts +1 -1
- package/src/client/types/com/atproto/moderation/defs.ts +1 -1
- package/src/index.ts +4 -0
- package/src/moderation/accumulator.ts +181 -0
- package/src/moderation/const/label-groups.ts +143 -0
- package/src/moderation/const/labels.ts +798 -0
- package/src/moderation/index.ts +343 -0
- package/src/moderation/subjects/account.ts +40 -0
- package/src/moderation/subjects/feed-generator.ts +13 -0
- package/src/moderation/subjects/post.ts +23 -0
- package/src/moderation/subjects/profile.ts +31 -0
- package/src/moderation/subjects/quoted-post.ts +62 -0
- package/src/moderation/subjects/user-list.ts +13 -0
- package/src/moderation/types.ts +141 -0
- package/src/moderation/util.ts +98 -0
- package/tests/post-moderation.test.ts +46 -0
- package/tests/profile-moderation.test.ts +46 -0
- package/tests/util/index.ts +176 -0
- package/tests/util/moderation-behavior.ts +180 -0
- package/dist/client/types/app/bsky/actor/searchActor.d.ts +0 -22
- package/dist/client/types/app/bsky/actor/searchActorTypeahead.d.ts +0 -20
- package/dist/client/types/com/atproto/admin/getInviteCodeUsage.d.ts +0 -29
- package/dist/client/types/com/atproto/repo/importRepo.d.ts +0 -19
- package/dist/client/types/com/atproto/repo/uploadRepo.d.ts +0 -19
- package/dist/client/types/com/atproto/server/getUserInviteCodes.d.ts +0 -31
- package/dist/src/client/index.d.ts +0 -462
- package/dist/src/client/lexicons.d.ts +0 -2910
- package/dist/src/client/schemas.d.ts +0 -17
- package/dist/src/client/types/app/bsky/actor/createScene.d.ts +0 -32
- package/dist/src/client/types/app/bsky/actor/getProfile.d.ts +0 -36
- package/dist/src/client/types/app/bsky/actor/getSuggestions.d.ts +0 -36
- package/dist/src/client/types/app/bsky/actor/profile.d.ts +0 -15
- package/dist/src/client/types/app/bsky/actor/ref.d.ts +0 -14
- package/dist/src/client/types/app/bsky/actor/search.d.ts +0 -32
- package/dist/src/client/types/app/bsky/actor/searchTypeahead.d.ts +0 -28
- package/dist/src/client/types/app/bsky/actor/updateProfile.d.ts +0 -48
- package/dist/src/client/types/app/bsky/badge.d.ts +0 -22
- package/dist/src/client/types/app/bsky/badgeAccept.d.ts +0 -11
- package/dist/src/client/types/app/bsky/badgeOffer.d.ts +0 -11
- package/dist/src/client/types/app/bsky/declaration.d.ts +0 -6
- package/dist/src/client/types/app/bsky/embed/external.d.ts +0 -26
- package/dist/src/client/types/app/bsky/embed/images.d.ts +0 -23
- package/dist/src/client/types/app/bsky/feed/embed.d.ts +0 -36
- package/dist/src/client/types/app/bsky/feed/feedViewPost.d.ts +0 -26
- package/dist/src/client/types/app/bsky/feed/getAuthorFeed.d.ts +0 -22
- package/dist/src/client/types/app/bsky/feed/getPostThread.d.ts +0 -43
- package/dist/src/client/types/app/bsky/feed/getRepostedBy.d.ts +0 -35
- package/dist/src/client/types/app/bsky/feed/getTimeline.d.ts +0 -22
- package/dist/src/client/types/app/bsky/feed/getVotes.d.ts +0 -33
- package/dist/src/client/types/app/bsky/feed/mediaEmbed.d.ts +0 -18
- package/dist/src/client/types/app/bsky/feed/post.d.ts +0 -54
- package/dist/src/client/types/app/bsky/feed/repost.d.ts +0 -6
- package/dist/src/client/types/app/bsky/feed/setVote.d.ts +0 -25
- package/dist/src/client/types/app/bsky/feed/trend.d.ts +0 -6
- package/dist/src/client/types/app/bsky/feed/vote.d.ts +0 -7
- package/dist/src/client/types/app/bsky/follow.d.ts +0 -9
- package/dist/src/client/types/app/bsky/getAuthorFeed.d.ts +0 -56
- package/dist/src/client/types/app/bsky/getBadgeMembers.d.ts +0 -29
- package/dist/src/client/types/app/bsky/getHomeFeed.d.ts +0 -56
- package/dist/src/client/types/app/bsky/getLikedBy.d.ts +0 -29
- package/dist/src/client/types/app/bsky/getNotificationCount.d.ts +0 -16
- package/dist/src/client/types/app/bsky/getNotifications.d.ts +0 -33
- package/dist/src/client/types/app/bsky/getPostThread.d.ts +0 -55
- package/dist/src/client/types/app/bsky/getProfile.d.ts +0 -26
- package/dist/src/client/types/app/bsky/getRepostedBy.d.ts +0 -29
- package/dist/src/client/types/app/bsky/getTimeline.d.ts +0 -56
- package/dist/src/client/types/app/bsky/getUserFollowers.d.ts +0 -31
- package/dist/src/client/types/app/bsky/getUserFollows.d.ts +0 -31
- package/dist/src/client/types/app/bsky/getUsersSearch.d.ts +0 -26
- package/dist/src/client/types/app/bsky/getUsersTypeahead.d.ts +0 -22
- package/dist/src/client/types/app/bsky/graph/assertCreator.d.ts +0 -1
- package/dist/src/client/types/app/bsky/graph/assertMember.d.ts +0 -1
- package/dist/src/client/types/app/bsky/graph/assertion.d.ts +0 -7
- package/dist/src/client/types/app/bsky/graph/confirmation.d.ts +0 -8
- package/dist/src/client/types/app/bsky/graph/follow.d.ts +0 -6
- package/dist/src/client/types/app/bsky/graph/getAssertions.d.ts +0 -43
- package/dist/src/client/types/app/bsky/graph/getFollowers.d.ts +0 -34
- package/dist/src/client/types/app/bsky/graph/getFollows.d.ts +0 -33
- package/dist/src/client/types/app/bsky/graph/getMembers.d.ts +0 -33
- package/dist/src/client/types/app/bsky/graph/getMemberships.d.ts +0 -33
- package/dist/src/client/types/app/bsky/invite.d.ts +0 -10
- package/dist/src/client/types/app/bsky/inviteAccept.d.ts +0 -14
- package/dist/src/client/types/app/bsky/like.d.ts +0 -10
- package/dist/src/client/types/app/bsky/mediaEmbed.d.ts +0 -15
- package/dist/src/client/types/app/bsky/notification/getCount.d.ts +0 -17
- package/dist/src/client/types/app/bsky/notification/list.d.ts +0 -32
- package/dist/src/client/types/app/bsky/post.d.ts +0 -23
- package/dist/src/client/types/app/bsky/postNotificationsSeen.d.ts +0 -20
- package/dist/src/client/types/app/bsky/profile.d.ts +0 -5
- package/dist/src/client/types/app/bsky/repost.d.ts +0 -10
- package/dist/src/client/types/app/bsky/system/actorScene.d.ts +0 -1
- package/dist/src/client/types/app/bsky/system/actorUser.d.ts +0 -1
- package/dist/src/client/types/app/bsky/system/declRef.d.ts +0 -5
- package/dist/src/client/types/app/bsky/system/declaration.d.ts +0 -4
- package/dist/src/client/types/app/bsky/updateProfile.d.ts +0 -23
- package/dist/src/client/types/com/atproto/account/create.d.ts +0 -41
- package/dist/src/client/types/com/atproto/account/createInviteCode.d.ts +0 -22
- package/dist/src/client/types/com/atproto/account/delete.d.ts +0 -13
- package/dist/src/client/types/com/atproto/account/get.d.ts +0 -12
- package/dist/src/client/types/com/atproto/account/requestPasswordReset.d.ts +0 -17
- package/dist/src/client/types/com/atproto/account/resetPassword.d.ts +0 -24
- package/dist/src/client/types/com/atproto/blob/upload.d.ts +0 -19
- package/dist/src/client/types/com/atproto/createAccount.d.ts +0 -40
- package/dist/src/client/types/com/atproto/createInviteCode.d.ts +0 -20
- package/dist/src/client/types/com/atproto/createSession.d.ts +0 -24
- package/dist/src/client/types/com/atproto/data/uploadFile.d.ts +0 -19
- package/dist/src/client/types/com/atproto/deleteAccount.d.ts +0 -20
- package/dist/src/client/types/com/atproto/deleteSession.d.ts +0 -17
- package/dist/src/client/types/com/atproto/getAccount.d.ts +0 -16
- package/dist/src/client/types/com/atproto/getAccountsConfig.d.ts +0 -17
- package/dist/src/client/types/com/atproto/getSession.d.ts +0 -17
- package/dist/src/client/types/com/atproto/handle/resolve.d.ts +0 -18
- package/dist/src/client/types/com/atproto/refreshSession.d.ts +0 -20
- package/dist/src/client/types/com/atproto/repo/batchWrite.d.ts +0 -39
- package/dist/src/client/types/com/atproto/repo/createRecord.d.ts +0 -26
- package/dist/src/client/types/com/atproto/repo/deleteRecord.d.ts +0 -19
- package/dist/src/client/types/com/atproto/repo/describe.d.ts +0 -22
- package/dist/src/client/types/com/atproto/repo/getRecord.d.ts +0 -23
- package/dist/src/client/types/com/atproto/repo/listRecords.d.ts +0 -30
- package/dist/src/client/types/com/atproto/repo/putRecord.d.ts +0 -27
- package/dist/src/client/types/com/atproto/repo/strongRef.d.ts +0 -5
- package/dist/src/client/types/com/atproto/repoBatchWrite.d.ts +0 -36
- package/dist/src/client/types/com/atproto/repoCreateRecord.d.ts +0 -24
- package/dist/src/client/types/com/atproto/repoDeleteRecord.d.ts +0 -18
- package/dist/src/client/types/com/atproto/repoDescribe.d.ts +0 -21
- package/dist/src/client/types/com/atproto/repoGetRecord.d.ts +0 -22
- package/dist/src/client/types/com/atproto/repoListRecords.d.ts +0 -27
- package/dist/src/client/types/com/atproto/repoPutRecord.d.ts +0 -25
- package/dist/src/client/types/com/atproto/requestAccountPasswordReset.d.ts +0 -19
- package/dist/src/client/types/com/atproto/resetAccountPassword.d.ts +0 -26
- package/dist/src/client/types/com/atproto/resolveHandle.d.ts +0 -17
- package/dist/src/client/types/com/atproto/resolveName.d.ts +0 -17
- package/dist/src/client/types/com/atproto/server/getAccountsConfig.d.ts +0 -24
- package/dist/src/client/types/com/atproto/session/create.d.ts +0 -26
- package/dist/src/client/types/com/atproto/session/delete.d.ts +0 -13
- package/dist/src/client/types/com/atproto/session/get.d.ts +0 -18
- package/dist/src/client/types/com/atproto/session/refresh.d.ts +0 -21
- package/dist/src/client/types/com/atproto/sync/getRepo.d.ts +0 -15
- package/dist/src/client/types/com/atproto/sync/getRoot.d.ts +0 -18
- package/dist/src/client/types/com/atproto/sync/updateRepo.d.ts +0 -15
- package/dist/src/client/types/com/atproto/syncGetRepo.d.ts +0 -15
- package/dist/src/client/types/com/atproto/syncGetRoot.d.ts +0 -17
- package/dist/src/client/types/com/atproto/syncUpdateRepo.d.ts +0 -15
- package/dist/src/index.d.ts +0 -4
- package/dist/src/schemas.d.ts +0 -19
- package/dist/src/session.d.ts +0 -42
- package/dist/src/types/app/bsky/acceptedBadge.d.ts +0 -10
- package/dist/src/types/app/bsky/badge.d.ts +0 -22
- package/dist/src/types/app/bsky/badgeAccept.d.ts +0 -11
- package/dist/src/types/app/bsky/badgeOffer.d.ts +0 -11
- package/dist/src/types/app/bsky/declaration.d.ts +0 -6
- package/dist/src/types/app/bsky/follow.d.ts +0 -9
- package/dist/src/types/app/bsky/getAuthorFeed.d.ts +0 -56
- package/dist/src/types/app/bsky/getBadgeMembers.d.ts +0 -29
- package/dist/src/types/app/bsky/getHomeFeed.d.ts +0 -56
- package/dist/src/types/app/bsky/getLikedBy.d.ts +0 -29
- package/dist/src/types/app/bsky/getNotificationCount.d.ts +0 -16
- package/dist/src/types/app/bsky/getNotifications.d.ts +0 -33
- package/dist/src/types/app/bsky/getPostThread.d.ts +0 -55
- package/dist/src/types/app/bsky/getProfile.d.ts +0 -42
- package/dist/src/types/app/bsky/getRepostedBy.d.ts +0 -29
- package/dist/src/types/app/bsky/getUserFollowers.d.ts +0 -31
- package/dist/src/types/app/bsky/getUserFollows.d.ts +0 -31
- package/dist/src/types/app/bsky/getUsersSearch.d.ts +0 -26
- package/dist/src/types/app/bsky/getUsersTypeahead.d.ts +0 -22
- package/dist/src/types/app/bsky/invite.d.ts +0 -10
- package/dist/src/types/app/bsky/inviteAccept.d.ts +0 -14
- package/dist/src/types/app/bsky/like.d.ts +0 -10
- package/dist/src/types/app/bsky/mediaEmbed.d.ts +0 -15
- package/dist/src/types/app/bsky/post.d.ts +0 -23
- package/dist/src/types/app/bsky/postNotificationsSeen.d.ts +0 -19
- package/dist/src/types/app/bsky/profile.d.ts +0 -11
- package/dist/src/types/app/bsky/repost.d.ts +0 -10
- package/dist/src/types/app/bsky/updateProfile.d.ts +0 -27
- package/dist/src/types/com/atproto/createAccount.d.ts +0 -39
- package/dist/src/types/com/atproto/createInviteCode.d.ts +0 -19
- package/dist/src/types/com/atproto/createSession.d.ts +0 -23
- package/dist/src/types/com/atproto/deleteAccount.d.ts +0 -19
- package/dist/src/types/com/atproto/deleteSession.d.ts +0 -16
- package/dist/src/types/com/atproto/getAccount.d.ts +0 -19
- package/dist/src/types/com/atproto/getAccountsConfig.d.ts +0 -17
- package/dist/src/types/com/atproto/getSession.d.ts +0 -17
- package/dist/src/types/com/atproto/refreshSession.d.ts +0 -19
- package/dist/src/types/com/atproto/repoBatchWrite.d.ts +0 -35
- package/dist/src/types/com/atproto/repoCreateRecord.d.ts +0 -23
- package/dist/src/types/com/atproto/repoDeleteRecord.d.ts +0 -15
- package/dist/src/types/com/atproto/repoDescribe.d.ts +0 -21
- package/dist/src/types/com/atproto/repoGetRecord.d.ts +0 -22
- package/dist/src/types/com/atproto/repoListRecords.d.ts +0 -27
- package/dist/src/types/com/atproto/repoPutRecord.d.ts +0 -24
- package/dist/src/types/com/atproto/requestAccountPasswordReset.d.ts +0 -18
- package/dist/src/types/com/atproto/resetAccountPassword.d.ts +0 -25
- package/dist/src/types/com/atproto/resolveName.d.ts +0 -17
- package/dist/src/types/com/atproto/syncGetRepo.d.ts +0 -15
- package/dist/src/types/com/atproto/syncGetRoot.d.ts +0 -17
- package/dist/src/types/com/atproto/syncUpdateRepo.d.ts +0 -14
- package/dist/src/types/todo/adx/createAccount.d.ts +0 -36
- package/dist/src/types/todo/adx/createInviteCode.d.ts +0 -19
- package/dist/src/types/todo/adx/createSession.d.ts +0 -22
- package/dist/src/types/todo/adx/deleteAccount.d.ts +0 -19
- package/dist/src/types/todo/adx/deleteSession.d.ts +0 -19
- package/dist/src/types/todo/adx/getAccount.d.ts +0 -19
- package/dist/src/types/todo/adx/getAccountsConfig.d.ts +0 -17
- package/dist/src/types/todo/adx/getSession.d.ts +0 -17
- package/dist/src/types/todo/adx/repoBatchWrite.d.ts +0 -34
- package/dist/src/types/todo/adx/repoCreateRecord.d.ts +0 -22
- package/dist/src/types/todo/adx/repoDeleteRecord.d.ts +0 -15
- package/dist/src/types/todo/adx/repoDescribe.d.ts +0 -21
- package/dist/src/types/todo/adx/repoGetRecord.d.ts +0 -20
- package/dist/src/types/todo/adx/repoListRecords.d.ts +0 -25
- package/dist/src/types/todo/adx/repoPutRecord.d.ts +0 -23
- package/dist/src/types/todo/adx/requestAccountPasswordReset.d.ts +0 -18
- package/dist/src/types/todo/adx/resetAccountPassword.d.ts +0 -25
- package/dist/src/types/todo/adx/resolveName.d.ts +0 -17
- package/dist/src/types/todo/adx/syncGetRepo.d.ts +0 -15
- package/dist/src/types/todo/adx/syncGetRoot.d.ts +0 -17
- package/dist/src/types/todo/adx/syncUpdateRepo.d.ts +0 -14
- package/dist/src/types/todo/social/badge.d.ts +0 -23
- package/dist/src/types/todo/social/follow.d.ts +0 -5
- package/dist/src/types/todo/social/getAuthorFeed.d.ts +0 -55
- package/dist/src/types/todo/social/getFeed.d.ts +0 -55
- package/dist/src/types/todo/social/getHomeFeed.d.ts +0 -55
- package/dist/src/types/todo/social/getLikedBy.d.ts +0 -26
- package/dist/src/types/todo/social/getNotificationCount.d.ts +0 -16
- package/dist/src/types/todo/social/getNotifications.d.ts +0 -31
- package/dist/src/types/todo/social/getPostThread.d.ts +0 -54
- package/dist/src/types/todo/social/getProfile.d.ts +0 -40
- package/dist/src/types/todo/social/getRepostedBy.d.ts +0 -26
- package/dist/src/types/todo/social/getUserFollowers.d.ts +0 -30
- package/dist/src/types/todo/social/getUserFollows.d.ts +0 -30
- package/dist/src/types/todo/social/like.d.ts +0 -5
- package/dist/src/types/todo/social/mediaEmbed.d.ts +0 -15
- package/dist/src/types/todo/social/post.d.ts +0 -18
- package/dist/src/types/todo/social/postNotificationsSeen.d.ts +0 -19
- package/dist/src/types/todo/social/profile.d.ts +0 -10
- package/dist/src/types/todo/social/repost.d.ts +0 -5
- package/dist/tsconfig.build.tsbuildinfo +0 -1
- package/tests/_util.ts +0 -26
- package/tsconfig.build.tsbuildinfo +0 -1
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Moderation API
|
|
2
|
+
|
|
3
|
+
Applying the moderation system is a challenging task, but we've done our best to simplify it for you. The Moderation API helps handle a wide range of tasks, including:
|
|
4
|
+
|
|
5
|
+
- User muting (including mutelists)
|
|
6
|
+
- User blocking
|
|
7
|
+
- Moderator labeling
|
|
8
|
+
|
|
9
|
+
For more information, see the [Moderation Documentation](./docs/moderation.md) or the associated [Labels Reference](./docs/labels.md).
|
|
10
|
+
|
|
11
|
+
Additional docs:
|
|
12
|
+
|
|
13
|
+
- [Labels Reference](./labels.md)
|
|
14
|
+
- [Post Moderation Behaviors](./moderation-behaviors/posts.md)
|
|
15
|
+
- [Profile Moderation Behaviors](./moderation-behaviors/profiles.md)
|
|
16
|
+
|
|
17
|
+
## Configuration
|
|
18
|
+
|
|
19
|
+
Every moderation function takes a set of options which look like this:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
{
|
|
23
|
+
// the logged-in user's DID
|
|
24
|
+
userDid: 'did:plc:1234...',
|
|
25
|
+
|
|
26
|
+
// is adult content allowed?
|
|
27
|
+
adultContentEnabled: true,
|
|
28
|
+
|
|
29
|
+
// the user's labeler settings
|
|
30
|
+
labelerSettings: [
|
|
31
|
+
{
|
|
32
|
+
labeler: {
|
|
33
|
+
did: '...',
|
|
34
|
+
displayName: 'My mod service'
|
|
35
|
+
},
|
|
36
|
+
settings: {
|
|
37
|
+
porn: 'hide',
|
|
38
|
+
sexual: 'warn',
|
|
39
|
+
nudity: 'ignore',
|
|
40
|
+
// ...
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
This should match the following interfaces:
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
interface ModerationOpts {
|
|
51
|
+
userDid: string
|
|
52
|
+
adultContentEnabled: boolean
|
|
53
|
+
labelerSettings: LabelerSettings[]
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface Labeler {
|
|
57
|
+
did: string
|
|
58
|
+
displayName: string
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
type LabelPreference = 'ignore' | 'warn' | 'hide'
|
|
62
|
+
|
|
63
|
+
interface LabelerSettings {
|
|
64
|
+
labeler: Labeler
|
|
65
|
+
settings: Record<string, LabelPreference>
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Posts
|
|
70
|
+
|
|
71
|
+
Applications need to produce the [Post Moderation Behaviors](./moderation-behaviors/posts.md) using the `moderatePost()` API.
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import {moderatePost} from '@atproto/api'
|
|
75
|
+
|
|
76
|
+
const postMod = moderatePost(postView, getOpts())
|
|
77
|
+
|
|
78
|
+
if (postMod.content.filter) {
|
|
79
|
+
// dont render in feeds or similar
|
|
80
|
+
// in contexts where this is disruptive (eg threads) you should ignore this and instead check blur
|
|
81
|
+
}
|
|
82
|
+
if (postMod.content.blur) {
|
|
83
|
+
// render the whole object behind a cover (use postMod.content.cause to explain)
|
|
84
|
+
if (postMod.content.noOverride) {
|
|
85
|
+
// do not allow the cover the be removed
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (postMod.content.alert) {
|
|
89
|
+
// render a warning on the content (use postMod.content.cause to explain)
|
|
90
|
+
}
|
|
91
|
+
if (postMod.embed.blur) {
|
|
92
|
+
// render the embedded media behind a cover (use postMod.embed.cause to explain)
|
|
93
|
+
if (postMod.embed.noOverride) {
|
|
94
|
+
// do not allow the cover the be removed
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
if (postMod.embed.alert) {
|
|
98
|
+
// render a warning on the embedded media (use postMod.embed.cause to explain)
|
|
99
|
+
}
|
|
100
|
+
if (postMod.avatar.blur) {
|
|
101
|
+
// render the avatar behind a cover
|
|
102
|
+
}
|
|
103
|
+
if (postMod.avatar.alert) {
|
|
104
|
+
// render an alert on the avatar
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Profiles
|
|
109
|
+
|
|
110
|
+
Applications need to produce the [Profile Moderation Behaviors](./moderation-behaviors/profiles.md) using the `moderateProfile()` API.
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import {moderateProfile} from '@atproto/api'
|
|
114
|
+
|
|
115
|
+
const profileMod = moderateProfile(profileView, getOpts())
|
|
116
|
+
|
|
117
|
+
if (profileMod.acount.filter) {
|
|
118
|
+
// dont render in discovery
|
|
119
|
+
}
|
|
120
|
+
if (profileMod.account.blur) {
|
|
121
|
+
// render the whole account behind a cover (use profileMod.account.cause to explain)
|
|
122
|
+
if (profileMod.account.noOverride) {
|
|
123
|
+
// do not allow the cover the be removed
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (profileMod.account.alert) {
|
|
127
|
+
// render a warning on the account (use profileMod.account.cause to explain)
|
|
128
|
+
}
|
|
129
|
+
if (profileMod.profile.blur) {
|
|
130
|
+
// render the profile information (display name, bio) behind a cover
|
|
131
|
+
if (profileMod.profile.noOverride) {
|
|
132
|
+
// do not allow the cover the be removed
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (profileMod.profile.alert) {
|
|
136
|
+
// render a warning on the profile (use profileMod.profile.cause to explain)
|
|
137
|
+
}
|
|
138
|
+
if (profileMod.avatar.blur) {
|
|
139
|
+
// render the avatar behind a cover
|
|
140
|
+
}
|
|
141
|
+
if (profileMod.avatar.alert) {
|
|
142
|
+
// render an alert on the avatar
|
|
143
|
+
}
|
|
144
|
+
```
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atproto/api",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"main": "
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"main": "src/index.ts",
|
|
5
5
|
"scripts": {
|
|
6
|
-
"codegen": "lex gen-api ./src/client ../../lexicons/com/atproto/*/* ../../lexicons/app/bsky/*/*",
|
|
6
|
+
"codegen": "yarn docgen && node ./scripts/generate-code.mjs && lex gen-api ./src/client ../../lexicons/com/atproto/*/* ../../lexicons/app/bsky/*/*",
|
|
7
|
+
"docgen": "node ./scripts/generate-docs.mjs",
|
|
7
8
|
"build": "node ./build.js",
|
|
8
9
|
"postbuild": "tsc --build tsconfig.build.json",
|
|
9
10
|
"update-main-to-dist": "node ./update-pkg.js --update-main-to-dist",
|
|
@@ -29,6 +30,7 @@
|
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
|
31
32
|
"@atproto/lex-cli": "*",
|
|
32
|
-
"@atproto/pds": "*"
|
|
33
|
+
"@atproto/pds": "*",
|
|
34
|
+
"common-tags": "^1.8.2"
|
|
33
35
|
}
|
|
34
36
|
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import * as url from 'url'
|
|
2
|
+
import { readFileSync, writeFileSync } from 'fs'
|
|
3
|
+
import { join } from 'path'
|
|
4
|
+
import * as prettier from 'prettier'
|
|
5
|
+
|
|
6
|
+
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
|
7
|
+
|
|
8
|
+
const labelsDef = JSON.parse(
|
|
9
|
+
readFileSync(
|
|
10
|
+
join(__dirname, '..', '..', 'definitions', 'labels.json'),
|
|
11
|
+
'utf8',
|
|
12
|
+
),
|
|
13
|
+
)
|
|
14
|
+
const labelGroupsEn = JSON.parse(
|
|
15
|
+
readFileSync(
|
|
16
|
+
join(
|
|
17
|
+
__dirname,
|
|
18
|
+
'..',
|
|
19
|
+
'..',
|
|
20
|
+
'definitions',
|
|
21
|
+
'locale',
|
|
22
|
+
'en',
|
|
23
|
+
'label-groups.json',
|
|
24
|
+
),
|
|
25
|
+
'utf8',
|
|
26
|
+
),
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
writeFileSync(
|
|
30
|
+
join(__dirname, '..', '..', 'src', 'moderation', 'const', 'label-groups.ts'),
|
|
31
|
+
await gen(),
|
|
32
|
+
'utf8',
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
async function gen() {
|
|
36
|
+
return prettier.format(
|
|
37
|
+
`/** this doc is generated by ./scripts/code/labels.mjs **/
|
|
38
|
+
import {LabelGroupDefinitionMap} from '../types'
|
|
39
|
+
import {LABELS} from './labels'
|
|
40
|
+
|
|
41
|
+
export const LABEL_GROUPS: LabelGroupDefinitionMap = {
|
|
42
|
+
${genDefMap()}
|
|
43
|
+
}
|
|
44
|
+
`,
|
|
45
|
+
{ semi: false, parser: 'babel', singleQuote: true },
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function genDefMap() {
|
|
50
|
+
const lines = []
|
|
51
|
+
for (const group of labelsDef) {
|
|
52
|
+
lines.push(`"${group.id}": {`)
|
|
53
|
+
lines.push(` id: "${group.id}",`)
|
|
54
|
+
lines.push(` configurable: ${group.configurable ? true : false},`)
|
|
55
|
+
lines.push(
|
|
56
|
+
` labels: [${group.labels
|
|
57
|
+
.map((label) => `LABELS["${label.id}"]`)
|
|
58
|
+
.join(', ')}],`,
|
|
59
|
+
)
|
|
60
|
+
lines.push(
|
|
61
|
+
` strings: {settings: {en: ${JSON.stringify(labelGroupsEn[group.id])}}}`,
|
|
62
|
+
)
|
|
63
|
+
lines.push(`},`)
|
|
64
|
+
}
|
|
65
|
+
return lines.join('\n')
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export {}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import * as url from 'url'
|
|
2
|
+
import { readFileSync, writeFileSync } from 'fs'
|
|
3
|
+
import { join } from 'path'
|
|
4
|
+
import * as prettier from 'prettier'
|
|
5
|
+
|
|
6
|
+
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
|
7
|
+
|
|
8
|
+
const labelsDef = JSON.parse(
|
|
9
|
+
readFileSync(
|
|
10
|
+
join(__dirname, '..', '..', 'definitions', 'labels.json'),
|
|
11
|
+
'utf8',
|
|
12
|
+
),
|
|
13
|
+
)
|
|
14
|
+
const labelsEn = JSON.parse(
|
|
15
|
+
readFileSync(
|
|
16
|
+
join(__dirname, '..', '..', 'definitions', 'locale', 'en', 'labels.json'),
|
|
17
|
+
'utf8',
|
|
18
|
+
),
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
writeFileSync(
|
|
22
|
+
join(__dirname, '..', '..', 'src', 'moderation', 'const', 'labels.ts'),
|
|
23
|
+
await gen(),
|
|
24
|
+
'utf8',
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
async function gen() {
|
|
28
|
+
return prettier.format(
|
|
29
|
+
`/** this doc is generated by ./scripts/code/labels.mjs **/
|
|
30
|
+
import {LabelDefinitionMap} from '../types'
|
|
31
|
+
|
|
32
|
+
export const LABELS: LabelDefinitionMap = ${JSON.stringify(
|
|
33
|
+
genDefMap(),
|
|
34
|
+
null,
|
|
35
|
+
2,
|
|
36
|
+
)}
|
|
37
|
+
`,
|
|
38
|
+
{ semi: false, parser: 'babel', singleQuote: true },
|
|
39
|
+
)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function genDefMap() {
|
|
43
|
+
const labels = {}
|
|
44
|
+
for (const group of labelsDef) {
|
|
45
|
+
for (const label of group.labels) {
|
|
46
|
+
labels[label.id] = {
|
|
47
|
+
...label,
|
|
48
|
+
groupId: group.id,
|
|
49
|
+
configurable: group.configurable,
|
|
50
|
+
strings: {
|
|
51
|
+
settings: getLabelStrings(label.id, 'settings'),
|
|
52
|
+
account: getLabelStrings(label.id, 'account'),
|
|
53
|
+
content: getLabelStrings(label.id, 'content'),
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return labels
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function getLabelStrings(id, type) {
|
|
62
|
+
if (labelsEn[id] && labelsEn[id][type]) {
|
|
63
|
+
return { en: labelsEn[id][type] }
|
|
64
|
+
}
|
|
65
|
+
throw new Error('Label strings not found for ' + id)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export {}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import * as url from 'url'
|
|
2
|
+
import { readFileSync, writeFileSync } from 'fs'
|
|
3
|
+
import { join } from 'path'
|
|
4
|
+
import { stripIndent } from 'common-tags'
|
|
5
|
+
|
|
6
|
+
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
|
7
|
+
|
|
8
|
+
const labelsDef = JSON.parse(
|
|
9
|
+
readFileSync(
|
|
10
|
+
join(__dirname, '..', '..', 'definitions', 'labels.json'),
|
|
11
|
+
'utf8',
|
|
12
|
+
),
|
|
13
|
+
)
|
|
14
|
+
const labelGroupsEn = JSON.parse(
|
|
15
|
+
readFileSync(
|
|
16
|
+
join(
|
|
17
|
+
__dirname,
|
|
18
|
+
'..',
|
|
19
|
+
'..',
|
|
20
|
+
'definitions',
|
|
21
|
+
'locale',
|
|
22
|
+
'en',
|
|
23
|
+
'label-groups.json',
|
|
24
|
+
),
|
|
25
|
+
'utf8',
|
|
26
|
+
),
|
|
27
|
+
)
|
|
28
|
+
const labelsEn = JSON.parse(
|
|
29
|
+
readFileSync(
|
|
30
|
+
join(__dirname, '..', '..', 'definitions', 'locale', 'en', 'labels.json'),
|
|
31
|
+
'utf8',
|
|
32
|
+
),
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
writeFileSync(join(__dirname, '..', '..', 'docs', 'labels.md'), doc(), 'utf8')
|
|
36
|
+
|
|
37
|
+
function doc() {
|
|
38
|
+
return stripIndent`
|
|
39
|
+
<!-- this doc is generated by ./scripts/docs/labels.mjs -->
|
|
40
|
+
|
|
41
|
+
# Labels
|
|
42
|
+
|
|
43
|
+
This document is a reference for the labels used in the SDK.
|
|
44
|
+
|
|
45
|
+
**⚠️ Note**: These labels are still in development and may change over time. Not all are currently in use.
|
|
46
|
+
|
|
47
|
+
## Key
|
|
48
|
+
|
|
49
|
+
### Label Preferences
|
|
50
|
+
|
|
51
|
+
The possible client interpretations for a label.
|
|
52
|
+
|
|
53
|
+
- <code>ignore</code> Do nothing with the label.
|
|
54
|
+
- <code>warn</code> Provide some form of warning on the content (see "On Warn" behavior).
|
|
55
|
+
- <code>hide</code> Remove the content from feeds and apply the warning when directly viewed.
|
|
56
|
+
|
|
57
|
+
Each label specifies which preferences it can support. If a label is not configurable, it must have only own supported preference.
|
|
58
|
+
|
|
59
|
+
### Configurable?
|
|
60
|
+
|
|
61
|
+
Non-configurable labels cannot have their preference changed by the user.
|
|
62
|
+
|
|
63
|
+
### Flags
|
|
64
|
+
|
|
65
|
+
Additional behaviors which a label can adopt.
|
|
66
|
+
|
|
67
|
+
- <code>no-override</code> The user cannot click through any covering of content created by the label.
|
|
68
|
+
- <code>adult</code> The user must have adult content enabled to configure the label. If adult content is not enabled, the label must adopt the strictest preference.
|
|
69
|
+
|
|
70
|
+
### On Warn
|
|
71
|
+
|
|
72
|
+
The kind of UI behavior used when a warning must be applied.
|
|
73
|
+
|
|
74
|
+
- <code>blur</code> Hide all of the content behind an interstitial.
|
|
75
|
+
- <code>blur-media</code> Hide only the media within the content (ie images) behind an interstitial.
|
|
76
|
+
- <code>alert</code> Display a descriptive warning but do not hide the content.
|
|
77
|
+
- <code>null</code> Do nothing.
|
|
78
|
+
|
|
79
|
+
## Label Behaviors
|
|
80
|
+
|
|
81
|
+
<table>
|
|
82
|
+
<tr>
|
|
83
|
+
<th>ID</th>
|
|
84
|
+
<th>Group</th>
|
|
85
|
+
<th>Preferences</th>
|
|
86
|
+
<th>Configurable</th>
|
|
87
|
+
<th>Flags</th>
|
|
88
|
+
<th>On Warn</th>
|
|
89
|
+
</tr>
|
|
90
|
+
${labelsRef()}
|
|
91
|
+
</table>
|
|
92
|
+
|
|
93
|
+
## Label Group Descriptions
|
|
94
|
+
|
|
95
|
+
<table>
|
|
96
|
+
<tr>
|
|
97
|
+
<th>ID</th>
|
|
98
|
+
<th>Description</th>
|
|
99
|
+
</tr>
|
|
100
|
+
${labelGroupsDesc()}
|
|
101
|
+
</table>
|
|
102
|
+
|
|
103
|
+
## Label Descriptions
|
|
104
|
+
|
|
105
|
+
<table>
|
|
106
|
+
<tr>
|
|
107
|
+
<th>ID</th>
|
|
108
|
+
<th>Description</th>
|
|
109
|
+
</tr>
|
|
110
|
+
${labelsDesc()}
|
|
111
|
+
</table>
|
|
112
|
+
`
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function labelsRef() {
|
|
116
|
+
const lines = []
|
|
117
|
+
for (const group of labelsDef) {
|
|
118
|
+
for (const label of group.labels) {
|
|
119
|
+
lines.push(stripIndent`
|
|
120
|
+
<tr>
|
|
121
|
+
<td>${label.id}</td>
|
|
122
|
+
<td>${group.id}</td>
|
|
123
|
+
<td>${label.preferences.join(', ')}</td>
|
|
124
|
+
<td>${group.configurable ? '✅' : '❌'}</td>
|
|
125
|
+
<td>${label.flags.join(', ')}</td>
|
|
126
|
+
<td>${label.onwarn}</td>
|
|
127
|
+
</tr>
|
|
128
|
+
`)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return lines.join('\n')
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function labelGroupsDesc() {
|
|
135
|
+
const lines = []
|
|
136
|
+
for (const id in labelGroupsEn) {
|
|
137
|
+
lines.push(stripIndent`
|
|
138
|
+
<tr>
|
|
139
|
+
<td>${id}</td>
|
|
140
|
+
<td><code>general</code><br><strong>${labelGroupsEn[id].name}</strong><br>${labelGroupsEn[id].description}</td>
|
|
141
|
+
</tr>
|
|
142
|
+
`)
|
|
143
|
+
}
|
|
144
|
+
return lines.join('\n')
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function labelsDesc() {
|
|
148
|
+
const lines = []
|
|
149
|
+
for (const id in labelsEn) {
|
|
150
|
+
lines.push(stripIndent`
|
|
151
|
+
<tr>
|
|
152
|
+
<td>${id}</td>
|
|
153
|
+
<td>
|
|
154
|
+
<code>general</code><br><strong>${labelsEn[id].settings.name}</strong><br>${labelsEn[id].settings.description}<br><br>
|
|
155
|
+
<code>on an account</code><br><strong>${labelsEn[id].account.name}</strong><br>${labelsEn[id].account.description}<br><br>
|
|
156
|
+
<code>on content</code><br><strong>${labelsEn[id].content.name}</strong><br>${labelsEn[id].content.description}<br><br>
|
|
157
|
+
</td>
|
|
158
|
+
</tr>
|
|
159
|
+
`)
|
|
160
|
+
}
|
|
161
|
+
return lines.join('\n')
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export {}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import * as url from 'url'
|
|
2
|
+
import { readFileSync, writeFileSync } from 'fs'
|
|
3
|
+
import { join } from 'path'
|
|
4
|
+
import { stripIndents } from 'common-tags'
|
|
5
|
+
|
|
6
|
+
const __dirname = url.fileURLToPath(new URL('.', import.meta.url))
|
|
7
|
+
|
|
8
|
+
const postModerationBehaviorsDef = JSON.parse(
|
|
9
|
+
readFileSync(
|
|
10
|
+
join(
|
|
11
|
+
__dirname,
|
|
12
|
+
'..',
|
|
13
|
+
'..',
|
|
14
|
+
'definitions',
|
|
15
|
+
'post-moderation-behaviors.json',
|
|
16
|
+
),
|
|
17
|
+
'utf8',
|
|
18
|
+
),
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
writeFileSync(
|
|
22
|
+
join(__dirname, '..', '..', 'docs', 'moderation-behaviors', 'posts.md'),
|
|
23
|
+
posts(),
|
|
24
|
+
'utf8',
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
function posts() {
|
|
28
|
+
let lastTitle = 'NULL'
|
|
29
|
+
return stripIndents`
|
|
30
|
+
<!-- this doc is generated by ./scripts/docs/post-moderation-behaviors.mjs -->
|
|
31
|
+
|
|
32
|
+
# Post moderation behaviors
|
|
33
|
+
|
|
34
|
+
This document is a reference for the expected behaviors for a post in the application based on some given scenarios. The <code>moderatePost()</code> command condense down to the following yes or no decisions:
|
|
35
|
+
|
|
36
|
+
- <code>res.content.filter</code> Do not show the post in feeds.
|
|
37
|
+
- <code>res.content.blur</code> Put the post behind a warning cover.
|
|
38
|
+
- <code>res.content.noOverride</code> Do not allow the post's blur cover to be lifted.
|
|
39
|
+
- <code>res.content.alert</code> Add a warning to the post but do not cover it.
|
|
40
|
+
- <code>res.avatar.blur</code> Put the avatar behind a cover.
|
|
41
|
+
- <code>res.avatar.noOverride</code> Do not allow the avatars's blur cover to be lifted.
|
|
42
|
+
- <code>res.avatar.alert</code> Put a warning icon on the avatar.
|
|
43
|
+
- <code>res.embed.blur</code> Put the embed content (media, quote post) behind a warning cover.
|
|
44
|
+
- <code>res.embed.noOverride</code> Do not allow the embed's blur cover to be lifted.
|
|
45
|
+
- <code>res.embed.alert</code> Put a warning on the embed content (media, quote post).
|
|
46
|
+
|
|
47
|
+
Key:
|
|
48
|
+
|
|
49
|
+
- ❌ = Filter Content
|
|
50
|
+
- 🚫 = Blur (no-override)
|
|
51
|
+
- ✋ = Blur
|
|
52
|
+
- 🪧 = Alert
|
|
53
|
+
|
|
54
|
+
## Scenarios
|
|
55
|
+
|
|
56
|
+
<table>
|
|
57
|
+
${Array.from(Object.entries(postModerationBehaviorsDef.scenarios))
|
|
58
|
+
.map(([title, scenario], i) => {
|
|
59
|
+
const str = `
|
|
60
|
+
${title.indexOf(lastTitle) === -1 ? postTableHead() : ''}
|
|
61
|
+
${scenarioSection(title, scenario)}
|
|
62
|
+
`
|
|
63
|
+
lastTitle = title.slice(0, 10)
|
|
64
|
+
return str
|
|
65
|
+
})
|
|
66
|
+
.join('\n\n')}
|
|
67
|
+
</table>
|
|
68
|
+
`
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function postTableHead() {
|
|
72
|
+
return `<tr><th>Scenario</th><th>Filter</th><th>Content</th><th>Avatar</th><th>Embed</th></tr>`
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function scenarioSection(title, scenario) {
|
|
76
|
+
return stripIndents`
|
|
77
|
+
<tr>
|
|
78
|
+
<td><strong>${title}</strong></td>
|
|
79
|
+
<td>
|
|
80
|
+
${filter(scenario.behaviors.content?.filter)}
|
|
81
|
+
</td>
|
|
82
|
+
<td>
|
|
83
|
+
${blur(
|
|
84
|
+
scenario.behaviors.content?.blur,
|
|
85
|
+
scenario.behaviors.content?.noOverride,
|
|
86
|
+
)}
|
|
87
|
+
${alert(scenario.behaviors.content?.alert)}
|
|
88
|
+
</td>
|
|
89
|
+
<td>
|
|
90
|
+
${blur(
|
|
91
|
+
scenario.behaviors.avatar?.blur,
|
|
92
|
+
scenario.behaviors.avatar?.noOverride,
|
|
93
|
+
)}
|
|
94
|
+
${alert(scenario.behaviors.avatar?.alert)}
|
|
95
|
+
</td>
|
|
96
|
+
<td>
|
|
97
|
+
${blur(
|
|
98
|
+
scenario.behaviors.embed?.blur,
|
|
99
|
+
scenario.behaviors.embed?.noOverride,
|
|
100
|
+
)}
|
|
101
|
+
${alert(scenario.behaviors.embed?.alert)}
|
|
102
|
+
</td>
|
|
103
|
+
</tr>
|
|
104
|
+
`
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function filter(val) {
|
|
108
|
+
return val ? '❌' : ''
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function blur(val, noOverride) {
|
|
112
|
+
if (val) {
|
|
113
|
+
return noOverride ? '🚫' : '✋'
|
|
114
|
+
}
|
|
115
|
+
return ''
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function alert(val) {
|
|
119
|
+
return val ? '🪧' : ''
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export {}
|