diff options
Diffstat (limited to 'shared/models')
26 files changed, 157 insertions, 110 deletions
diff --git a/shared/models/activitypub/activity.ts b/shared/models/activitypub/activity.ts index 31b9e4673..5b4ce214a 100644 --- a/shared/models/activitypub/activity.ts +++ b/shared/models/activitypub/activity.ts | |||
@@ -1,12 +1,12 @@ | |||
1 | import { ActivityPubActor } from './activitypub-actor' | 1 | import { ActivityPubActor } from './activitypub-actor' |
2 | import { ActivityPubSignature } from './activitypub-signature' | 2 | import { ActivityPubSignature } from './activitypub-signature' |
3 | import { CacheFileObject, VideoTorrentObject, ActivityFlagReasonObject } from './objects' | 3 | import { ActivityFlagReasonObject, CacheFileObject, VideoTorrentObject } from './objects' |
4 | import { AbuseObject } from './objects/abuse-object' | ||
4 | import { DislikeObject } from './objects/dislike-object' | 5 | import { DislikeObject } from './objects/dislike-object' |
5 | import { VideoAbuseObject } from './objects/video-abuse-object' | ||
6 | import { VideoCommentObject } from './objects/video-comment-object' | ||
7 | import { ViewObject } from './objects/view-object' | ||
8 | import { APObject } from './objects/object.model' | 6 | import { APObject } from './objects/object.model' |
9 | import { PlaylistObject } from './objects/playlist-object' | 7 | import { PlaylistObject } from './objects/playlist-object' |
8 | import { VideoCommentObject } from './objects/video-comment-object' | ||
9 | import { ViewObject } from './objects/view-object' | ||
10 | 10 | ||
11 | export type Activity = | 11 | export type Activity = |
12 | ActivityCreate | | 12 | ActivityCreate | |
@@ -53,7 +53,7 @@ export interface BaseActivity { | |||
53 | 53 | ||
54 | export interface ActivityCreate extends BaseActivity { | 54 | export interface ActivityCreate extends BaseActivity { |
55 | type: 'Create' | 55 | type: 'Create' |
56 | object: VideoTorrentObject | VideoAbuseObject | ViewObject | DislikeObject | VideoCommentObject | CacheFileObject | PlaylistObject | 56 | object: VideoTorrentObject | AbuseObject | ViewObject | DislikeObject | VideoCommentObject | CacheFileObject | PlaylistObject |
57 | } | 57 | } |
58 | 58 | ||
59 | export interface ActivityUpdate extends BaseActivity { | 59 | export interface ActivityUpdate extends BaseActivity { |
diff --git a/shared/models/activitypub/objects/video-abuse-object.ts b/shared/models/activitypub/objects/abuse-object.ts index 73add8ef4..ad45cc064 100644 --- a/shared/models/activitypub/objects/video-abuse-object.ts +++ b/shared/models/activitypub/objects/abuse-object.ts | |||
@@ -1,10 +1,12 @@ | |||
1 | import { ActivityFlagReasonObject } from './common-objects' | 1 | import { ActivityFlagReasonObject } from './common-objects' |
2 | 2 | ||
3 | export interface VideoAbuseObject { | 3 | export interface AbuseObject { |
4 | type: 'Flag' | 4 | type: 'Flag' |
5 | content: string | 5 | content: string |
6 | object: string | string[] | 6 | object: string | string[] |
7 | |||
7 | tag?: ActivityFlagReasonObject[] | 8 | tag?: ActivityFlagReasonObject[] |
9 | |||
8 | startAt?: number | 10 | startAt?: number |
9 | endAt?: number | 11 | endAt?: number |
10 | } | 12 | } |
diff --git a/shared/models/activitypub/objects/common-objects.ts b/shared/models/activitypub/objects/common-objects.ts index 096d422ea..711ce45f4 100644 --- a/shared/models/activitypub/objects/common-objects.ts +++ b/shared/models/activitypub/objects/common-objects.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | import { VideoAbusePredefinedReasonsString } from '@shared/models/videos' | 1 | import { AbusePredefinedReasonsString } from '@shared/models' |
2 | 2 | ||
3 | export interface ActivityIdentifierObject { | 3 | export interface ActivityIdentifierObject { |
4 | identifier: string | 4 | identifier: string |
@@ -85,7 +85,7 @@ export interface ActivityMentionObject { | |||
85 | 85 | ||
86 | export interface ActivityFlagReasonObject { | 86 | export interface ActivityFlagReasonObject { |
87 | type: 'Hashtag' | 87 | type: 'Hashtag' |
88 | name: VideoAbusePredefinedReasonsString | 88 | name: AbusePredefinedReasonsString |
89 | } | 89 | } |
90 | 90 | ||
91 | export type ActivityTagObject = | 91 | export type ActivityTagObject = |
diff --git a/shared/models/activitypub/objects/index.ts b/shared/models/activitypub/objects/index.ts index fba61e12f..a6a20e87a 100644 --- a/shared/models/activitypub/objects/index.ts +++ b/shared/models/activitypub/objects/index.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | export * from './abuse-object' | ||
1 | export * from './cache-file-object' | 2 | export * from './cache-file-object' |
2 | export * from './common-objects' | 3 | export * from './common-objects' |
3 | export * from './video-abuse-object' | 4 | export * from './dislike-object' |
4 | export * from './video-torrent-object' | 5 | export * from './video-torrent-object' |
5 | export * from './view-object' | 6 | export * from './view-object' |
6 | export * from './dislike-object' | ||
diff --git a/shared/models/index.ts b/shared/models/index.ts index 3d4bdedde..a68f57148 100644 --- a/shared/models/index.ts +++ b/shared/models/index.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | export * from './activitypub' | 1 | export * from './activitypub' |
2 | export * from './actors' | 2 | export * from './actors' |
3 | export * from './avatars' | 3 | export * from './avatars' |
4 | export * from './blocklist' | 4 | export * from './moderation' |
5 | export * from './bulk' | 5 | export * from './bulk' |
6 | export * from './redundancy' | 6 | export * from './redundancy' |
7 | export * from './users' | 7 | export * from './users' |
@@ -14,4 +14,3 @@ export * from './search' | |||
14 | export * from './server' | 14 | export * from './server' |
15 | export * from './oauth-client-local.model' | 15 | export * from './oauth-client-local.model' |
16 | export * from './result-list.model' | 16 | export * from './result-list.model' |
17 | export * from './server/server-config.model' | ||
diff --git a/shared/models/moderation/abuse/abuse-create.model.ts b/shared/models/moderation/abuse/abuse-create.model.ts new file mode 100644 index 000000000..c0d04e46d --- /dev/null +++ b/shared/models/moderation/abuse/abuse-create.model.ts | |||
@@ -0,0 +1,26 @@ | |||
1 | import { AbusePredefinedReasonsString } from './abuse-reason.model' | ||
2 | |||
3 | export interface AbuseCreate { | ||
4 | accountId: number | ||
5 | |||
6 | reason: string | ||
7 | predefinedReasons?: AbusePredefinedReasonsString[] | ||
8 | |||
9 | video?: { | ||
10 | id: number | ||
11 | startAt?: number | ||
12 | endAt?: number | ||
13 | } | ||
14 | |||
15 | comment?: { | ||
16 | id: number | ||
17 | } | ||
18 | } | ||
19 | |||
20 | // FIXME: deprecated in 2.3. Remove it | ||
21 | export interface VideoAbuseCreate { | ||
22 | reason: string | ||
23 | predefinedReasons?: AbusePredefinedReasonsString[] | ||
24 | startAt?: number | ||
25 | endAt?: number | ||
26 | } | ||
diff --git a/shared/models/moderation/abuse/abuse-filter.ts b/shared/models/moderation/abuse/abuse-filter.ts new file mode 100644 index 000000000..03303bbab --- /dev/null +++ b/shared/models/moderation/abuse/abuse-filter.ts | |||
@@ -0,0 +1 @@ | |||
export type AbuseFilter = 'video' | 'comment' | |||
diff --git a/shared/models/moderation/abuse/abuse-reason.model.ts b/shared/models/moderation/abuse/abuse-reason.model.ts new file mode 100644 index 000000000..36875969d --- /dev/null +++ b/shared/models/moderation/abuse/abuse-reason.model.ts | |||
@@ -0,0 +1,33 @@ | |||
1 | export enum AbusePredefinedReasons { | ||
2 | VIOLENT_OR_REPULSIVE = 1, | ||
3 | HATEFUL_OR_ABUSIVE, | ||
4 | SPAM_OR_MISLEADING, | ||
5 | PRIVACY, | ||
6 | RIGHTS, | ||
7 | SERVER_RULES, | ||
8 | THUMBNAILS, | ||
9 | CAPTIONS | ||
10 | } | ||
11 | |||
12 | export type AbusePredefinedReasonsString = | ||
13 | 'violentOrRepulsive' | | ||
14 | 'hatefulOrAbusive' | | ||
15 | 'spamOrMisleading' | | ||
16 | 'privacy' | | ||
17 | 'rights' | | ||
18 | 'serverRules' | | ||
19 | 'thumbnails' | | ||
20 | 'captions' | ||
21 | |||
22 | export const abusePredefinedReasonsMap: { | ||
23 | [key in AbusePredefinedReasonsString]: AbusePredefinedReasons | ||
24 | } = { | ||
25 | violentOrRepulsive: AbusePredefinedReasons.VIOLENT_OR_REPULSIVE, | ||
26 | hatefulOrAbusive: AbusePredefinedReasons.HATEFUL_OR_ABUSIVE, | ||
27 | spamOrMisleading: AbusePredefinedReasons.SPAM_OR_MISLEADING, | ||
28 | privacy: AbusePredefinedReasons.PRIVACY, | ||
29 | rights: AbusePredefinedReasons.RIGHTS, | ||
30 | serverRules: AbusePredefinedReasons.SERVER_RULES, | ||
31 | thumbnails: AbusePredefinedReasons.THUMBNAILS, | ||
32 | captions: AbusePredefinedReasons.CAPTIONS | ||
33 | } | ||
diff --git a/shared/models/videos/abuse/video-abuse-state.model.ts b/shared/models/moderation/abuse/abuse-state.model.ts index 529f034bd..b00cccad8 100644 --- a/shared/models/videos/abuse/video-abuse-state.model.ts +++ b/shared/models/moderation/abuse/abuse-state.model.ts | |||
@@ -1,4 +1,4 @@ | |||
1 | export enum VideoAbuseState { | 1 | export enum AbuseState { |
2 | PENDING = 1, | 2 | PENDING = 1, |
3 | REJECTED = 2, | 3 | REJECTED = 2, |
4 | ACCEPTED = 3 | 4 | ACCEPTED = 3 |
diff --git a/shared/models/moderation/abuse/abuse-update.model.ts b/shared/models/moderation/abuse/abuse-update.model.ts new file mode 100644 index 000000000..4360fe7ac --- /dev/null +++ b/shared/models/moderation/abuse/abuse-update.model.ts | |||
@@ -0,0 +1,7 @@ | |||
1 | import { AbuseState } from './abuse-state.model' | ||
2 | |||
3 | export interface AbuseUpdate { | ||
4 | moderationComment?: string | ||
5 | |||
6 | state?: AbuseState | ||
7 | } | ||
diff --git a/shared/models/moderation/abuse/abuse-video-is.type.ts b/shared/models/moderation/abuse/abuse-video-is.type.ts new file mode 100644 index 000000000..74937f3b9 --- /dev/null +++ b/shared/models/moderation/abuse/abuse-video-is.type.ts | |||
@@ -0,0 +1 @@ | |||
export type AbuseVideoIs = 'deleted' | 'blacklisted' | |||
diff --git a/shared/models/moderation/abuse/abuse.model.ts b/shared/models/moderation/abuse/abuse.model.ts new file mode 100644 index 000000000..9ff150c4a --- /dev/null +++ b/shared/models/moderation/abuse/abuse.model.ts | |||
@@ -0,0 +1,53 @@ | |||
1 | import { Account } from '../../actors/account.model' | ||
2 | import { AbuseState } from './abuse-state.model' | ||
3 | import { AbusePredefinedReasonsString } from './abuse-reason.model' | ||
4 | import { VideoConstant } from '../../videos/video-constant.model' | ||
5 | import { VideoChannel } from '../../videos/channel/video-channel.model' | ||
6 | |||
7 | export interface VideoAbuse { | ||
8 | id: number | ||
9 | name: string | ||
10 | uuid: string | ||
11 | nsfw: boolean | ||
12 | deleted: boolean | ||
13 | blacklisted: boolean | ||
14 | |||
15 | startAt: number | null | ||
16 | endAt: number | null | ||
17 | |||
18 | thumbnailPath?: string | ||
19 | channel?: VideoChannel | ||
20 | } | ||
21 | |||
22 | export interface VideoCommentAbuse { | ||
23 | id: number | ||
24 | account?: Account | ||
25 | text: string | ||
26 | deleted: boolean | ||
27 | } | ||
28 | |||
29 | export interface Abuse { | ||
30 | id: number | ||
31 | reason: string | ||
32 | predefinedReasons?: AbusePredefinedReasonsString[] | ||
33 | reporterAccount: Account | ||
34 | |||
35 | state: VideoConstant<AbuseState> | ||
36 | moderationComment?: string | ||
37 | |||
38 | video?: VideoAbuse | ||
39 | comment?: VideoCommentAbuse | ||
40 | |||
41 | createdAt: Date | ||
42 | updatedAt: Date | ||
43 | |||
44 | // FIXME: deprecated in 2.3, remove this | ||
45 | startAt: null | ||
46 | endAt: null | ||
47 | |||
48 | count?: number | ||
49 | nth?: number | ||
50 | |||
51 | countReportsForReporter?: number | ||
52 | countReportsForReportee?: number | ||
53 | } | ||
diff --git a/shared/models/moderation/abuse/index.ts b/shared/models/moderation/abuse/index.ts new file mode 100644 index 000000000..32a6b4e6c --- /dev/null +++ b/shared/models/moderation/abuse/index.ts | |||
@@ -0,0 +1,6 @@ | |||
1 | export * from './abuse-create.model' | ||
2 | export * from './abuse-reason.model' | ||
3 | export * from './abuse-state.model' | ||
4 | export * from './abuse-update.model' | ||
5 | export * from './abuse-video-is.type' | ||
6 | export * from './abuse.model' | ||
diff --git a/shared/models/blocklist/account-block.model.ts b/shared/models/moderation/account-block.model.ts index a942ed614..a942ed614 100644 --- a/shared/models/blocklist/account-block.model.ts +++ b/shared/models/moderation/account-block.model.ts | |||
diff --git a/shared/models/blocklist/index.ts b/shared/models/moderation/index.ts index fc7873270..8b6042e97 100644 --- a/shared/models/blocklist/index.ts +++ b/shared/models/moderation/index.ts | |||
@@ -1,2 +1,3 @@ | |||
1 | export * from './abuse' | ||
1 | export * from './account-block.model' | 2 | export * from './account-block.model' |
2 | export * from './server-block.model' | 3 | export * from './server-block.model' |
diff --git a/shared/models/blocklist/server-block.model.ts b/shared/models/moderation/server-block.model.ts index a8b8af0b7..a8b8af0b7 100644 --- a/shared/models/blocklist/server-block.model.ts +++ b/shared/models/moderation/server-block.model.ts | |||
diff --git a/shared/models/users/user-notification.model.ts b/shared/models/users/user-notification.model.ts index e9be1ca7f..39090f5a1 100644 --- a/shared/models/users/user-notification.model.ts +++ b/shared/models/users/user-notification.model.ts | |||
@@ -64,9 +64,20 @@ export interface UserNotification { | |||
64 | video: VideoInfo | 64 | video: VideoInfo |
65 | } | 65 | } |
66 | 66 | ||
67 | videoAbuse?: { | 67 | abuse?: { |
68 | id: number | 68 | id: number |
69 | video: VideoInfo | 69 | |
70 | video?: VideoInfo | ||
71 | |||
72 | comment?: { | ||
73 | threadId: number | ||
74 | |||
75 | video: { | ||
76 | uuid: string | ||
77 | } | ||
78 | } | ||
79 | |||
80 | account?: ActorInfo | ||
70 | } | 81 | } |
71 | 82 | ||
72 | videoBlacklist?: { | 83 | videoBlacklist?: { |
diff --git a/shared/models/users/user-right.enum.ts b/shared/models/users/user-right.enum.ts index 2f88a65de..4a7ae4373 100644 --- a/shared/models/users/user-right.enum.ts +++ b/shared/models/users/user-right.enum.ts | |||
@@ -11,7 +11,7 @@ export enum UserRight { | |||
11 | 11 | ||
12 | MANAGE_SERVER_REDUNDANCY, | 12 | MANAGE_SERVER_REDUNDANCY, |
13 | 13 | ||
14 | MANAGE_VIDEO_ABUSES, | 14 | MANAGE_ABUSES, |
15 | 15 | ||
16 | MANAGE_JOBS, | 16 | MANAGE_JOBS, |
17 | 17 | ||
diff --git a/shared/models/users/user-role.ts b/shared/models/users/user-role.ts index 2b08b5850..772988c0c 100644 --- a/shared/models/users/user-role.ts +++ b/shared/models/users/user-role.ts | |||
@@ -20,7 +20,7 @@ const userRoleRights: { [ id in UserRole ]: UserRight[] } = { | |||
20 | 20 | ||
21 | [UserRole.MODERATOR]: [ | 21 | [UserRole.MODERATOR]: [ |
22 | UserRight.MANAGE_VIDEO_BLACKLIST, | 22 | UserRight.MANAGE_VIDEO_BLACKLIST, |
23 | UserRight.MANAGE_VIDEO_ABUSES, | 23 | UserRight.MANAGE_ABUSES, |
24 | UserRight.REMOVE_ANY_VIDEO, | 24 | UserRight.REMOVE_ANY_VIDEO, |
25 | UserRight.REMOVE_ANY_VIDEO_CHANNEL, | 25 | UserRight.REMOVE_ANY_VIDEO_CHANNEL, |
26 | UserRight.REMOVE_ANY_VIDEO_PLAYLIST, | 26 | UserRight.REMOVE_ANY_VIDEO_PLAYLIST, |
diff --git a/shared/models/videos/abuse/index.ts b/shared/models/videos/abuse/index.ts deleted file mode 100644 index f70bc736f..000000000 --- a/shared/models/videos/abuse/index.ts +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | export * from './video-abuse-create.model' | ||
2 | export * from './video-abuse-reason.model' | ||
3 | export * from './video-abuse-state.model' | ||
4 | export * from './video-abuse-update.model' | ||
5 | export * from './video-abuse-video-is.type' | ||
6 | export * from './video-abuse.model' | ||
diff --git a/shared/models/videos/abuse/video-abuse-create.model.ts b/shared/models/videos/abuse/video-abuse-create.model.ts deleted file mode 100644 index c93cb8b2c..000000000 --- a/shared/models/videos/abuse/video-abuse-create.model.ts +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | import { VideoAbusePredefinedReasonsString } from './video-abuse-reason.model' | ||
2 | |||
3 | export interface VideoAbuseCreate { | ||
4 | reason: string | ||
5 | predefinedReasons?: VideoAbusePredefinedReasonsString[] | ||
6 | startAt?: number | ||
7 | endAt?: number | ||
8 | } | ||
diff --git a/shared/models/videos/abuse/video-abuse-reason.model.ts b/shared/models/videos/abuse/video-abuse-reason.model.ts deleted file mode 100644 index 9064f0c1a..000000000 --- a/shared/models/videos/abuse/video-abuse-reason.model.ts +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | export enum VideoAbusePredefinedReasons { | ||
2 | VIOLENT_OR_REPULSIVE = 1, | ||
3 | HATEFUL_OR_ABUSIVE, | ||
4 | SPAM_OR_MISLEADING, | ||
5 | PRIVACY, | ||
6 | RIGHTS, | ||
7 | SERVER_RULES, | ||
8 | THUMBNAILS, | ||
9 | CAPTIONS | ||
10 | } | ||
11 | |||
12 | export type VideoAbusePredefinedReasonsString = | ||
13 | 'violentOrRepulsive' | | ||
14 | 'hatefulOrAbusive' | | ||
15 | 'spamOrMisleading' | | ||
16 | 'privacy' | | ||
17 | 'rights' | | ||
18 | 'serverRules' | | ||
19 | 'thumbnails' | | ||
20 | 'captions' | ||
21 | |||
22 | export const videoAbusePredefinedReasonsMap: { | ||
23 | [key in VideoAbusePredefinedReasonsString]: VideoAbusePredefinedReasons | ||
24 | } = { | ||
25 | violentOrRepulsive: VideoAbusePredefinedReasons.VIOLENT_OR_REPULSIVE, | ||
26 | hatefulOrAbusive: VideoAbusePredefinedReasons.HATEFUL_OR_ABUSIVE, | ||
27 | spamOrMisleading: VideoAbusePredefinedReasons.SPAM_OR_MISLEADING, | ||
28 | privacy: VideoAbusePredefinedReasons.PRIVACY, | ||
29 | rights: VideoAbusePredefinedReasons.RIGHTS, | ||
30 | serverRules: VideoAbusePredefinedReasons.SERVER_RULES, | ||
31 | thumbnails: VideoAbusePredefinedReasons.THUMBNAILS, | ||
32 | captions: VideoAbusePredefinedReasons.CAPTIONS | ||
33 | } | ||
diff --git a/shared/models/videos/abuse/video-abuse-update.model.ts b/shared/models/videos/abuse/video-abuse-update.model.ts deleted file mode 100644 index 9b32aae48..000000000 --- a/shared/models/videos/abuse/video-abuse-update.model.ts +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | import { VideoAbuseState } from './video-abuse-state.model' | ||
2 | |||
3 | export interface VideoAbuseUpdate { | ||
4 | moderationComment?: string | ||
5 | state?: VideoAbuseState | ||
6 | } | ||
diff --git a/shared/models/videos/abuse/video-abuse-video-is.type.ts b/shared/models/videos/abuse/video-abuse-video-is.type.ts deleted file mode 100644 index e86018993..000000000 --- a/shared/models/videos/abuse/video-abuse-video-is.type.ts +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | export type VideoAbuseVideoIs = 'deleted' | 'blacklisted' | ||
diff --git a/shared/models/videos/abuse/video-abuse.model.ts b/shared/models/videos/abuse/video-abuse.model.ts deleted file mode 100644 index 38605dcac..000000000 --- a/shared/models/videos/abuse/video-abuse.model.ts +++ /dev/null | |||
@@ -1,38 +0,0 @@ | |||
1 | import { Account } from '../../actors/index' | ||
2 | import { VideoConstant } from '../video-constant.model' | ||
3 | import { VideoAbuseState } from './video-abuse-state.model' | ||
4 | import { VideoChannel } from '../channel/video-channel.model' | ||
5 | import { VideoAbusePredefinedReasonsString } from './video-abuse-reason.model' | ||
6 | |||
7 | export interface VideoAbuse { | ||
8 | id: number | ||
9 | reason: string | ||
10 | predefinedReasons?: VideoAbusePredefinedReasonsString[] | ||
11 | reporterAccount: Account | ||
12 | |||
13 | state: VideoConstant<VideoAbuseState> | ||
14 | moderationComment?: string | ||
15 | |||
16 | video: { | ||
17 | id: number | ||
18 | name: string | ||
19 | uuid: string | ||
20 | nsfw: boolean | ||
21 | deleted: boolean | ||
22 | blacklisted: boolean | ||
23 | thumbnailPath?: string | ||
24 | channel?: VideoChannel | ||
25 | } | ||
26 | |||
27 | createdAt: Date | ||
28 | updatedAt: Date | ||
29 | |||
30 | startAt: number | ||
31 | endAt: number | ||
32 | |||
33 | count?: number | ||
34 | nth?: number | ||
35 | |||
36 | countReportsForReporter?: number | ||
37 | countReportsForReportee?: number | ||
38 | } | ||
diff --git a/shared/models/videos/index.ts b/shared/models/videos/index.ts index e1d96b40a..20b9638ab 100644 --- a/shared/models/videos/index.ts +++ b/shared/models/videos/index.ts | |||
@@ -1,4 +1,3 @@ | |||
1 | export * from './abuse' | ||
2 | export * from './blacklist' | 1 | export * from './blacklist' |
3 | export * from './caption' | 2 | export * from './caption' |
4 | export * from './channel' | 3 | export * from './channel' |