fishpi 0.1.21 → 0.1.23
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/lib/fishpi.min.js +1 -0
- package/lib/index.cjs +12 -13
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +0 -1
- package/lib/index.d.mts +0 -1
- package/lib/index.mjs +8 -6
- package/lib/index.mjs.map +1 -1
- package/package.json +2 -1
package/lib/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["FormData","NodeEventEmitter","ReconnectingWebSocket","ReconnectingWebSocket","ReconnectingWebSocket","ReconnectingWebSocket","FormData"],"sources":["../src/utils.ts","../src/types/article.ts","../src/types/breezemoon.ts","../src/types/chatroom.ts","../src/types/redpacket.ts","../src/types/user.ts","../src/types/finger.ts","../src/types/notice.ts","../src/types/index.ts","../src/ws.ts","../src/chatroom.ts","../src/notice.ts","../src/emoji.ts","../src/user.ts","../src/article.ts","../src/comment.ts","../src/chat.ts","../src/breezemoon.ts","../src/finger.ts","../src/index.ts"],"sourcesContent":["import { IMetal, Metal } from './';\nimport ws from 'ws';\nimport FormData from 'form-data';\nimport { EventEmitter as NodeEventEmitter } from 'events';\n\nlet domain = 'fishpi.cn';\n\nfunction setDomain(d: string) {\n domain = d;\n}\n\nasync function request(opt: any) {\n let { url, method = 'get', headers = {}, data } = opt;\n\n if (!isBrowse) {\n headers['User-Agent'] =\n `Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36`;\n headers['Referer'] = `https://${domain}/`;\n }\n\n let body = undefined;\n\n if (data instanceof FormData) {\n body = data;\n } else {\n body = JSON.stringify(data);\n }\n\n let options: any = {\n method,\n headers,\n body,\n };\n\n let rsp: any;\n try {\n rsp = fetch(`https://${domain}/${url}`, options)\n .then((res: Response) => res.text())\n .then((res: string) => {\n try {\n return JSON.parse(res);\n } catch (err) {\n return res;\n }\n });\n return rsp;\n } catch (err) {\n if ((err as any).response.status === 401) {\n return (err as any).response;\n }\n throw err;\n }\n}\n\nfunction analyzeMetalAttr(m: any): Metal {\n if (!m) return m;\n if (typeof m.attr != 'string') return m;\n let attr = m.attr.split('&');\n let src = m.attr;\n m.attr = { src };\n attr.forEach((a: string) => (m.attr[a.split('=')[0]] = a.split('=')[1]));\n m.url = `https://${domain}/gen?txt=${m.description}&url=${m.attr.src}`;\n m.icon = `https://${domain}/gen?txt=&${m.attr.src}`;\n return m;\n}\n\nfunction toMetal(sysMetal: string): Metal[] {\n try {\n let metal: { list: Array<any> } = JSON.parse(sysMetal);\n metal.list.forEach((m, i, list) => {\n list[i] = analyzeMetalAttr(m);\n });\n return metal.list;\n } catch (error) {\n return [];\n }\n}\n\nfunction clientToVia(client: string) {\n if (!client) return;\n const via = client.split('/');\n return { client: via[0], version: via[1] };\n}\n\nconst isBrowse = typeof window !== 'undefined';\n\nconst WebSocket = isBrowse ? window.WebSocket : ws.WebSocket;\n\n// 浏览器兼容的 EventEmitter\nclass BrowserEventEmitter {\n public listeners: Map<string, Function[]> = new Map();\n\n on(event: string, listener: Function) {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, []);\n }\n this.listeners.get(event)!.push(listener);\n return this;\n }\n\n off(event: string, listener: Function) {\n const listeners = this.listeners.get(event);\n if (listeners) {\n const index = listeners.indexOf(listener);\n if (index > -1) {\n listeners.splice(index, 1);\n }\n }\n return this;\n }\n\n once(event: string, listener: Function) {\n const onceListener = (...args: any[]) => {\n this.off(event, onceListener);\n listener(...args);\n };\n this.on(event, onceListener);\n return this;\n }\n\n emit(event: string, ...args: any[]) {\n const listeners = this.listeners.get(event);\n if (listeners) {\n listeners.forEach((listener) => listener(...args));\n }\n return this;\n }\n\n removeAllListeners(event?: string) {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n return this;\n }\n}\n\nconst EventEmitter = isBrowse ? BrowserEventEmitter : NodeEventEmitter;\n\nexport {\n request,\n domain,\n toMetal,\n analyzeMetalAttr,\n isBrowse,\n setDomain,\n clientToVia,\n WebSocket,\n EventEmitter,\n};\n","import { IMetal, Pagination } from '.';\n\n/**\n * 发帖信息\n */\nexport class ArticlePost implements IArticlePost {\n /**\n * 帖子标题\n */\n title: string = '';\n /**\n * 帖子内容\n */\n content: string = '';\n /**\n * 帖子标签\n */\n tags: string = '';\n /**\n * 是否允许评论\n */\n commentable: boolean = true;\n /**\n * 是否通知帖子关注者\n */\n isNotifyFollowers: boolean = false;\n /**\n * 帖子类型\n */\n type: ArticleType = ArticleType.Normal;\n /**\n * 是否在列表展示\n */\n isShowInList = true;\n /**\n * 打赏内容\n */\n rewardContent?: string;\n /**\n * 打赏积分\n */\n rewardPoint?: number;\n /**\n * 是否匿名\n */\n isAnonymous?: boolean;\n /**\n * 提问悬赏积分\n */\n offerPoint?: number;\n\n static from(article: IArticlePost) {\n return Object.assign(new ArticlePost(), article);\n }\n\n toJson() {\n return {\n articleTitle: this.title,\n articleContent: this.content,\n articleTags: this.tags,\n articleCommentable: this.commentable,\n articleNotifyFollowers: this.isNotifyFollowers,\n articleType: this.type,\n articleShowInList: this.isShowInList ? 1 : 0,\n articleRewardContent: this.rewardContent,\n articleRewardPoint: this.rewardPoint,\n articleAnonymous: this.isAnonymous,\n articleQnAOfferPoint: this.offerPoint,\n };\n }\n}\n\nexport class CommentPost implements ICommentPost {\n /**\n * 文章 Id\n */\n articleId: string = '';\n /**\n * 是否匿名评论\n */\n isAnonymous: boolean = false;\n /**\n * 评论是否公共可见\n */\n isVisible: boolean = true;\n /**\n * 评论内容\n */\n content: string = '';\n /**\n * 回复评论 Id\n */\n originalId?: string;\n\n static from(comment: ICommentPost) {\n return Object.assign(new CommentPost(), comment);\n }\n\n toJson() {\n return {\n articleId: this.articleId,\n commentAnonymous: this.isAnonymous ? 1 : 0,\n commentVisible: this.isVisible ? 1 : 0,\n commentContent: this.content,\n commentOriginalCommentId: this.originalId,\n };\n }\n}\n\n/**\n * 帖子类型\n */\nexport enum ArticleType {\n Normal,\n Private,\n Broadcast,\n Thought,\n Question = 5,\n}\n\n/**\n * 公开状态\n */\nexport enum PublicStatus {\n Public,\n Private,\n}\n\n/**\n * 投票状态,点赞与否\n */\nexport enum VoteStatus {\n /**\n * 未投票\n */\n normal = -1,\n /**\n * 点赞\n */\n up,\n /**\n * 点踩\n */\n down,\n}\n\n/**\n * 是否状态\n */\nexport enum YesNoStatus {\n Yes,\n No,\n}\n\n/**\n * 文章状态\n */\nexport enum ArticleStatus {\n /**\n * 正常\n */\n Normal,\n /**\n * 封禁\n */\n Ban,\n /**\n * 锁定\n */\n Lock,\n}\n\n/**\n * 帖子列表查询类型\n */\nexport enum ArticleListType {\n /**\n * 最近\n */\n Recent = '',\n /**\n * 热门\n */\n Hot = '/hot',\n /**\n * 点赞\n */\n Good = '/good',\n /**\n * 最近回复\n */\n Reply = '/reply',\n /**\n * 优选,需包含标签\n */\n Perfect = '/perfact',\n}\n\n/**\n * 点赞类型\n */\nexport enum VoteType {\n /**\n * 点赞\n */\n Voted,\n /**\n * 取消点赞\n */\n Unvote = -1,\n}\n\n/**\n * 发帖信息\n */\nexport interface IArticlePost {\n /**\n * 帖子标题\n */\n title: string;\n /**\n * 帖子内容\n */\n content: string;\n /**\n * 帖子标签\n */\n tags: string;\n /**\n * 帖子类型\n */\n type?: ArticleType;\n /**\n * 是否允许评论\n */\n commentable?: boolean;\n /**\n * 是否帖子关注者\n */\n isNotifyFollowers?: boolean;\n /**\n * 是否在列表展示\n */\n isShowInList?: boolean;\n /**\n * 打赏内容\n */\n rewardContent?: string;\n /**\n * 打赏积分\n */\n rewardPoint?: number;\n /**\n * 是否匿名\n */\n isAnonymous?: boolean;\n /**\n * 提问悬赏积分\n */\n offerPoint?: number;\n}\n\n/**\n * 文章标签\n */\nexport class ArticleTag {\n /**\n * 标签 id\n */\n oId: string = '';\n /**\n * 标签名\n */\n title: string = '';\n /**\n * 标签描述\n */\n description: string = '';\n /**\n * icon 地址\n */\n iconPath: string = '';\n /**\n * 标签地址\n */\n URI: string = '';\n /**\n * 标签自定义 CSS\n */\n CSS: string = '';\n /**\n * 反对数\n */\n badCnt: number = 0;\n /**\n * 标签回帖计数\n */\n commentCount: number = 0;\n /**\n * 关注数\n */\n followerCount: number = 0;\n /**\n * 点赞数\n */\n goodCnt: number = 0;\n /**\n * 引用计数\n */\n referenceCount: number = 0;\n /**\n * 标签相关链接计数\n */\n linkCount: number = 0;\n /**\n * 标签 SEO 描述\n */\n seoDesc: string = '';\n /**\n * 标签关键字\n */\n seoKeywords: string = '';\n /**\n * 标签 SEO 标题\n */\n seoTitle: string = '';\n /**\n * 标签广告内容\n */\n ad: string = '';\n /**\n * 是否展示广告\n */\n isShowSideAd = true;\n /**\n * 标签状态\n */\n status: 0 | 1 = 1;\n\n static from(tag: Record<string, any>) {\n const data = new ArticleTag();\n data.oId = tag.oId;\n data.title = tag.tagTitle;\n data.description = tag.tagDescription;\n data.iconPath = tag.tagIconPath;\n data.URI = tag.tagURI;\n data.CSS = tag.tagCSS;\n data.badCnt = tag.tagBadCnt;\n data.commentCount = tag.tagCommentCount;\n data.followerCount = tag.tagFollowerCount;\n data.goodCnt = tag.tagGoodCnt;\n data.referenceCount = tag.tagReferenceCount;\n data.linkCount = tag.tagLinkCount;\n data.seoDesc = tag.tagSeoDesc;\n data.seoKeywords = tag.tagSeoKeywords;\n data.seoTitle = tag.tagSeoTitle;\n data.ad = tag.tagAd;\n data.isShowSideAd = tag.tagShowSideAd == 1;\n data.status = tag.tagStatus;\n\n return data;\n }\n}\n\n/**\n * 文章作者信息\n */\nexport class Author {\n /**\n * 用户是否在线\n */\n online: boolean = false;\n /**\n * 用户在线时长\n */\n onlineMinute: number = 0;\n /**\n * 用户标签\n */\n tags: string = '';\n /**\n * 用户时区\n */\n timezone: string = '';\n /**\n * 用户个人主页\n */\n URL: string = '';\n /**\n * 最近发帖时间\n */\n latestArticleTime: number = 0;\n /**\n * 昵称\n */\n nickname: string = '';\n /**\n * 应用角色\n */\n appRole: number = 0;\n /**\n * 用户状态\n */\n status: number = 0;\n /**\n * 用户省份\n */\n province: string = '';\n /**\n * 用户当前连续签到计数\n */\n currentCheckinStreak: number = 0;\n /**\n * 用户编号\n */\n userNo: number = 0;\n /**\n * 用户头像\n */\n avatarURL: string = '';\n /**\n * 用户语言\n */\n language: string = '';\n /**\n * 用户消费积分\n */\n usedPoint: number = 0;\n /**\n * 用户积分\n */\n points: number = 0;\n /**\n * 用户回帖数量\n */\n commentCount: number = 0;\n /**\n * 用户个性签名\n */\n intro: string = '';\n /**\n * 用户 Id\n */\n oId: string = '';\n /**\n * 用户名\n */\n userName: string = '';\n /**\n * 文章数\n */\n articleCount: number = 0;\n /**\n * 用户角色\n */\n role: string = '';\n /**\n * 徽章\n */\n sysMetal?: IMetal[];\n /**\n * MBTI 性格类型\n */\n mbti: string = '';\n\n static from(user: Record<string, any>) {\n const data = new Author();\n data.online = user.userOnlineFlag;\n data.onlineMinute = user.onlineMinute;\n data.tags = user.userTags;\n data.timezone = user.userTimezone;\n data.URL = user.userURL;\n data.latestArticleTime = user.userLatestArticleTime;\n data.nickname = user.userNickname;\n data.appRole = user.userAppRole;\n data.status = user.userStatus;\n data.province = user.userProvince;\n data.currentCheckinStreak = user.userCurrentCheckinStreak;\n data.userNo = user.userNo;\n data.avatarURL = user.userAvatarURL;\n data.language = user.userLanguage;\n data.usedPoint = user.userUsedPoint;\n data.points = user.userPoint;\n data.commentCount = user.userCommentCount;\n data.intro = user.userIntro;\n data.oId = user.oId;\n data.userName = user.userName;\n data.articleCount = user.userArticleCount;\n data.role = user.userRole;\n if (user.sysMetal) data.sysMetal = user.sysMetal;\n data.mbti = user.mbti;\n\n return data;\n }\n}\n\n/**\n * 文章详情\n */\nexport class ArticleDetail {\n /**\n * 是否在列表展示\n */\n isShowInList: boolean = true;\n /**\n * 发布者Id\n */\n authorId: string = '';\n /**\n * 反对数\n */\n badCnt: number = 0;\n /**\n * 文章最后修改时间\n */\n latestCmtTime: string = '';\n /**\n * 赞同数\n */\n goodCnt: number = 0;\n /**\n * 悬赏积分\n */\n offerPoint: number = 0;\n /**\n * 文章首图缩略图\n */\n thumbnailURL: string = '';\n /**\n * 置顶序号\n */\n stickRemains: number = 0;\n /**\n * 发布时间简写\n */\n timeAgo: string = '';\n /**\n * 文章更新时间\n */\n updateTime: string = '';\n /**\n * 作者用户名\n */\n authorName: string = '';\n /**\n * 文章类型\n */\n type: ArticleType = ArticleType.Normal;\n /**\n * 是否悬赏\n */\n isOffered: boolean = false;\n /**\n * 文章创建时间字符串\n */\n createTime: string = '';\n /**\n * 文章浏览数\n */\n viewCount: number = 0;\n /**\n * 作者头像缩略图\n */\n authorThumbnail20: string = '';\n /**\n * 关注数\n */\n watchCnt: number = 0;\n /**\n * 文章预览内容\n */\n previewContent: string = '';\n /**\n * 文章标题\n */\n titleEmoj: string = '';\n /**\n * 文章标题\n */\n titleEmojUnicode: string = '';\n /**\n * 文章标题\n */\n title: string = '';\n /**\n * 作者头像缩略图\n */\n authorThumbnail48: string = '';\n /**\n * 收藏数\n */\n collectCnt: number = 0;\n /**\n * 文章最后评论者\n */\n latestCmter: string = '';\n /**\n * 文章标签\n */\n tagsContent: string = '';\n /**\n * 文章 id\n */\n oId: string = '';\n /**\n * 最后评论时间简写\n */\n cmtTimeAgo: string = '';\n /**\n * 是否置顶\n */\n stick: number = 0;\n /**\n * 文章标签信息\n */\n tags: ArticleTag[] = [];\n /**\n * 是否匿名\n */\n isAnonymous: boolean = false;\n /**\n * 文章感谢数\n */\n thankCnt: number = 0;\n /**\n * 文章状态\n */\n status: ArticleStatus = ArticleStatus.Normal;\n /**\n * 文章点击数\n */\n heat: number = 0;\n /**\n * 文章是否优选\n */\n isPerfect: boolean = false;\n /**\n * 作者头像缩略图\n */\n authorThumbnail210: string = '';\n /**\n * 文章固定链接\n */\n permalink: string = '';\n /**\n * 作者用户信息\n */\n author: Author = new Author();\n /**\n * 文章感谢数\n */\n thankedCnt?: number = 0;\n /**\n * 文章匿名浏览量\n */\n anonymousView?: number = 0;\n /**\n * 文章浏览量简写\n */\n viewCntDisplay?: string = '';\n /**\n * 文章是否启用评论\n */\n commentable?: boolean = true;\n /**\n * 是否已打赏\n */\n isRewarded?: boolean = false;\n /**\n * 打赏人数\n */\n rewardedCnt?: number = 0;\n /**\n * 文章打赏积分\n */\n rewardPoint?: number = 0;\n /**\n * 是否已收藏\n */\n isFollowing?: boolean = false;\n /**\n * 是否已关注\n */\n isWatching?: boolean = false;\n /**\n * 是否是我的文章\n */\n isMyArticle?: boolean = false;\n /**\n * 是否已感谢\n */\n isThanked?: boolean = false;\n /**\n * 文章音频地址\n */\n audioURL?: string = '';\n /**\n * 文章目录 HTML\n */\n tableOfContents?: string = '';\n /**\n * 文章内容 HTML\n */\n content?: string = '';\n /**\n * 文章内容 Markdown\n */\n originalContent?: string = '';\n /**\n * 文章首图\n */\n img1URL?: string = '';\n /**\n * 文章点赞状态\n */\n vote?: VoteStatus = VoteStatus.normal;\n /**\n * 作者签名\n */\n authorIntro?: string = '';\n /**\n * 发布城市\n */\n city?: string = '';\n /**\n * 作者首页地址\n */\n authorURL?: string = '';\n /**\n * 打赏内容\n */\n rewardContent?: string = '';\n /**\n * 评论分页信息\n */\n pagination?: Pagination;\n /**\n * 评论是否可见\n */\n discussionViewable: boolean = true;\n /**\n * 文章修改次数\n */\n revisionCount: number = 0;\n /**\n * 文章的评论\n */\n comments?: Array<ArticleComment>;\n /**\n * 文章最佳评论\n */\n niceComments?: Array<ArticleComment>;\n\n static from(post: Record<string, any>) {\n const data = new ArticleDetail();\n data.isShowInList = post.articleShowInList;\n data.authorId = post.articleAuthorId;\n data.badCnt = post.articleBadCnt;\n data.goodCnt = post.articleGoodCnt;\n data.offerPoint = post.articleQnAOfferPoint;\n data.thumbnailURL = post.articleThumbnailURL;\n data.stickRemains = post.articleStickRemains;\n data.timeAgo = post.timeAgo;\n data.updateTime = post.articleUpdateTimeStr;\n data.authorName = post.articleAuthorName;\n data.type = post.articleType;\n data.isOffered = post.articleQnAOfferPoint > 0;\n data.createTime = post.articleCreateTimeStr;\n data.viewCount = post.articleViewCount;\n data.authorThumbnail20 = post.articleAuthorThumbnailURL20;\n data.watchCnt = post.articleWatchCnt;\n data.previewContent = post.articlePreviewContent;\n data.titleEmoj = post.articleTitleEmoj;\n data.titleEmojUnicode = post.articleTitleEmojUnicode;\n data.title = post.articleTitle;\n data.authorThumbnail48 = post.articleAuthorThumbnailURL48;\n data.collectCnt = post.articleCollectCnt;\n data.latestCmter = post.articleLatestCmterName;\n data.tagsContent = post.articleTags;\n data.oId = post.oId;\n data.cmtTimeAgo = post.cmtTimeAgo;\n data.stick = post.articleStick;\n data.tags = post.articleTagObjs?.map((t: any) => ArticleTag.from(t)) || [];\n data.latestCmtTime = post.articleLatestCmtTimeStr;\n data.isAnonymous = post.articleAnonymous;\n data.thankCnt = post.articleThankCnt;\n data.status = post.articleStatus;\n data.heat = post.articleHeat;\n data.isPerfect = post.articlePerfect;\n data.authorThumbnail210 = post.articleAuthorThumbnailURL210;\n data.permalink = post.articlePermalink;\n if (post.articleAuthor) data.author = Author.from(post.articleAuthor);\n data.thankedCnt = post.thankedCnt;\n data.anonymousView = post.articleAnonymousView;\n data.viewCntDisplay = post.articleViewCntDisplayFormat;\n data.commentable = post.articleCommentable;\n data.isRewarded = post.rewarded;\n data.rewardedCnt = post.rewardedCnt;\n data.rewardPoint = post.articleRewardPoint;\n data.isFollowing = post.isFollowing;\n data.isWatching = post.isWatching;\n data.isMyArticle = post.isMyArticle;\n data.isThanked = post.thanked;\n data.audioURL = post.articleAudioURL;\n data.tableOfContents = post.articleToC;\n data.content = post.articleContent;\n data.originalContent = post.articleOriginalContent;\n data.img1URL = post.articleImg1URL;\n data.vote = post.articleVote;\n data.authorIntro = post.articleAuthorIntro;\n data.city = post.articleCity;\n data.authorURL = post.articleAuthorURL;\n data.rewardContent = post.articleRewardContent;\n if (post.pagination) data.pagination = Pagination.from(post.pagination);\n data.discussionViewable = post.discussionViewable;\n data.revisionCount = post.articleRevisionCount;\n data.comments = post.articleComments\n ? post.articleComments.map((c: any) => ArticleComment.from(c))\n : undefined;\n data.niceComments = post.articleNiceComments\n ? post.articleNiceComments.map((c: any) => ArticleComment.from(c))\n : undefined;\n return data;\n }\n}\n\n/**\n * 文章评论\n */\nexport class ArticleComment {\n /**\n * 是否优评\n */\n isNice: boolean = false;\n /**\n * 评论创建时间字符串\n */\n createTime: string = '';\n /**\n * 评论作者 id\n */\n authorId: string = '';\n /**\n * 评论分数\n */\n score: number = 0;\n /**\n * 评论作者头像\n */\n authorURL: string = '';\n /**\n * 评论状态\n */\n vote: VoteStatus = VoteStatus.normal;\n /**\n * 评论引用数\n */\n revisionCount: number = 0;\n /**\n * 评论经过时间\n */\n timeAgo: string = '';\n /**\n * 回复评论 id\n */\n originalId: string = '';\n /**\n * 徽章\n */\n sysMetal: IMetal[] = [];\n /**\n * 点赞数\n */\n goodCnt: number = 0;\n /**\n * 评论是否可见\n */\n visible: YesNoStatus = YesNoStatus.Yes;\n /**\n * 文章 id\n */\n articleId: string = '';\n /**\n * 评论感谢数\n */\n rewardedCnt: number = 0;\n /**\n * 评论地址\n */\n sharpURL: string = '';\n /**\n * 是否匿名\n */\n isAnonymous: boolean = false;\n /**\n * 评论回复数\n */\n replyCnt: number = 0;\n /**\n * 评论 id\n */\n oId: string = '';\n /**\n * 评论内容\n */\n content: string = '';\n /**\n * 评论状态\n */\n status: ArticleStatus = ArticleStatus.Normal;\n /**\n * 评论作者\n */\n commenter: Author = new Author();\n /**\n * 评论作者用户名\n */\n authorName: string = '';\n /**\n * 评论感谢数\n */\n thankCnt: number = 0;\n /**\n * 评论点踩数\n */\n badCnt: number = 0;\n /**\n * 是否已感谢\n */\n rewarded: boolean = false;\n /**\n * 评论作者头像\n */\n authorThumbnailURL: string = '';\n /**\n * 评论音频地址\n */\n audioURL: string = '';\n /**\n * 评论是否采纳,1 表示采纳\n */\n isOffered: boolean = false;\n\n static from(cmt: Record<string, any>) {\n const data = new ArticleComment();\n data.isNice = cmt.commentNice;\n data.createTime = cmt.commentCreateTimeStr;\n data.authorId = cmt.commentAuthorId;\n data.score = cmt.commentScore;\n data.authorURL = cmt.commentAuthorURL;\n data.vote = cmt.commentVote;\n data.revisionCount = cmt.commentRevisionCount;\n data.timeAgo = cmt.timeAgo;\n data.originalId = cmt.commentOriginalCommentId;\n if (cmt.sysMetal) data.sysMetal = cmt.sysMetal;\n data.goodCnt = cmt.commentGoodCnt;\n data.visible = cmt.commentVisible;\n data.articleId = cmt.commentOnArticleId;\n data.rewardedCnt = cmt.rewardedCnt;\n data.sharpURL = cmt.commentSharpURL;\n data.isAnonymous = cmt.commentAnonymous;\n data.replyCnt = cmt.commentReplyCnt;\n data.oId = cmt.oId;\n data.content = cmt.commentContent;\n data.status = cmt.commentStatus;\n if (cmt.commenter) data.commenter = Author.from(cmt.commenter);\n data.authorName = cmt.commentAuthorName;\n data.thankCnt = cmt.commentThankCnt;\n data.badCnt = cmt.commentBadCnt;\n data.rewarded = cmt.rewarded;\n data.authorThumbnailURL = cmt.commentAuthorThumbnailURL;\n data.audioURL = cmt.commentAudioURL;\n data.isOffered = cmt.commentQnAOffered == 1;\n return data;\n }\n}\n\n/**\n * 文章列表\n */\nexport class ArticleList {\n /**\n * 文章列表\n */\n articles: ArticleDetail[] = [];\n /**\n * 分页信息\n */\n pagination: Pagination = new Pagination();\n /**\n * 标签信息,仅查询标签下文章列表有效\n */\n tag?: ArticleTag;\n\n static from(list: Record<string, any>) {\n const data = new ArticleList();\n data.articles = list.articles.map((a: any) => ArticleDetail.from(a));\n data.pagination = Pagination.from(list.pagination);\n if (list.tag) data.tag = ArticleTag.from(list.tag);\n return data;\n }\n}\n\nexport interface ICommentPost {\n /**\n * 文章 Id\n */\n articleId: string;\n /**\n * 是否匿名评论\n */\n isAnonymous?: boolean;\n /**\n * 评论是否楼主可见\n */\n isVisible?: boolean;\n /**\n * 评论内容\n */\n content: string;\n /**\n * 回复评论 Id\n */\n originalId?: string;\n}\n\nexport interface IArticleHeat {\n articleId: string;\n heat: number;\n}\n","import { Pagination } from '.';\n\n/**\n * 清风明月内容\n */\nexport class BreezemoonContent {\n /**\n * 发布者用户名\n */\n authorName: string = '';\n /**\n * 最后更新时间\n */\n updatedAt: string = '';\n /**\n * 清风明月ID\n */\n oId: string = '';\n /**\n * 创建时间\n */\n createAt: string = '';\n /**\n * 发布者头像URL\n */\n authorThumbnail: string = '';\n /**\n * 发布时间\n */\n timeAgo: string = '';\n /**\n * 正文\n */\n content: string = '';\n /**\n * 发布城市(可能为空,请注意做判断)\n */\n city: string = '';\n\n static from(src: Record<string, any>): BreezemoonContent {\n const data = new BreezemoonContent();\n data.authorName = src.breezemoonAuthorName;\n data.updatedAt = src.breezemoonUpdated;\n data.oId = src.oId;\n data.createAt = src.breezemoonCreated;\n data.authorThumbnail = src.breezemoonAuthorThumbnailURL48;\n data.timeAgo = src.timeAgo;\n data.content = src.breezemoonContent;\n data.city = src.breezemoonCity;\n return data;\n }\n}\n\nexport class BreezemoonList {\n /**\n * 分页信息\n */\n pagination: Pagination = new Pagination();\n /**\n * 清风明月列表\n */\n breezemoons: BreezemoonContent[] = [];\n\n static from(src: Record<string, any>): BreezemoonList {\n const data = new BreezemoonList();\n data.pagination = src.pagination;\n data.breezemoons = src.breezemoons.map((b: any) => BreezemoonContent.from(b));\n return data;\n }\n}\n","import { IMetal, IRedPacketMessage } from '.';\n\nexport enum ClientType {\n /**\n * 网页端\n */\n Web = 'Web',\n /**\n * PC 端\n */\n PC = 'PC',\n /**\n * 移动端聊天室\n */\n Mobile = 'Mobile',\n /**\n * Windows 客户端\n */\n Windows = 'Windows',\n /**\n * macOS 客户端\n */\n macOS = 'macOS',\n /**\n * Linux 客户端\n */\n Linux = 'Linux',\n /**\n * iOS 客户端\n */\n iOS = 'iOS',\n /**\n * Android 客户端\n */\n Android = 'Android',\n /**\n * IDEA 插件\n */\n IDEA = 'IDEA',\n /**\n * Chrome 插件\n */\n Chrome = 'Chrome',\n /**\n * Edge 插件\n */\n Edge = 'Edge',\n /**\n * VSCode 插件\n */\n VSCode = 'VSCode',\n /**\n * Python 客户端\n */\n Python = 'Python',\n /**\n * Golang 客户端\n */\n Golang = 'Golang',\n /**\n * Rust 客户端\n */\n Rust = 'Rust',\n /**\n * Harmony App\n */\n Harmony = 'Harmony',\n /**\n * CLI 工具\n */\n CLI = 'CLI',\n /**\n * 鸽机器人\n */\n Bird = 'Bird',\n /**\n * 小冰机器人\n */\n IceNet = 'IceNet',\n /**\n * 凌机器人\n */\n ElvesOnline = 'ElvesOnline',\n /**\n * 其他插件\n */\n Other = 'Other',\n}\n\n/**\n * 聊天室消息来源\n */\nexport class ChatRoomSource implements IChatRoomSource {\n /**\n * 消息来源\n */\n client: ClientType | string = ClientType.Other;\n /**\n * 消息来源版本\n */\n version: string = 'latest';\n}\n\n/**\n * 历史消息类型\n */\nexport enum ChatContentType {\n /**\n * 原始 Markdown\n */\n Markdown = 'md',\n /**\n * 渲染 HTML\n */\n HTML = 'html',\n}\n\n/**\n * chatroom get 接口获取 oId 的相关消息类型\n */\nexport enum ChatMessageType {\n /**\n * 前后消息\n */\n Context = 0,\n /**\n * 前面的消息\n */\n Before = 1,\n /**\n * 后面的消息\n */\n After = 2,\n}\n\n/**\n * 聊天室消息类型\n */\nexport enum ChatRoomMessageType {\n /**\n * 在线用户\n */\n online = 'online',\n /**\n * 话题修改\n */\n discussChanged = 'discussChanged',\n /**\n * 消息撤回\n */\n revoke = 'revoke',\n /**\n * 消息\n */\n msg = 'msg',\n /**\n * 红包\n */\n redPacket = 'redPacket',\n /**\n * 红包状态\n */\n redPacketStatus = 'redPacketStatus',\n /**\n * 弹幕\n */\n barrager = 'barrager',\n /**\n * 自定义消息\n */\n custom = 'customMessage',\n}\n/**\n * 聊天室消息来源\n */\nexport interface IChatRoomSource {\n /**\n * 消息来源\n */\n client: ClientType | string;\n /**\n * 消息来源版本\n */\n version: string;\n}\n\n/**\n * 聊天室消息\n */\nexport interface IChatRoomMessage {\n /**\n * 消息 Id\n */\n oId: string;\n /**\n * 消息类型\n */\n type: string;\n /**\n * 发送者用户名\n */\n userName: string;\n /**\n * 用户昵称\n */\n userNickname: string;\n /**\n * 用户头像\n */\n userAvatarURL: string;\n /**\n * 用户徽章\n */\n sysMetal: IMetal[];\n /**\n * 消息来源\n */\n client: string;\n /**\n * 消息来源解析\n */\n via: IChatRoomSource;\n /**\n * 消息内容\n */\n content: string | IRedPacketMessage | IMusicMessage | IWeatherMessage;\n /**\n * Markdown 内容\n */\n md: string;\n /**\n * 发送时间\n */\n time: string;\n}\n\nexport type CustomMsg = string;\n\n/**\n * 弹幕消息\n */\nexport interface IBarragerMsg {\n /**\n * 用户名\n */\n userName: string;\n /**\n * 用户昵称\n */\n userNickname: string;\n /**\n * 弹幕内容\n */\n barragerContent: string;\n /**\n * 弹幕颜色\n */\n barragerColor: string;\n /**\n * 用户头像地址\n */\n userAvatarURL: string;\n /**\n * 用户头像地址 20x20\n */\n userAvatarURL20: string;\n /**\n * 用户头像地址 48x48\n */\n userAvatarURL48: string;\n /**\n * 用户头像地址 210x210\n */\n userAvatarURL210: string;\n}\n\n/**\n * 在线用户信息\n */\nexport interface IOnlineInfo {\n /**\n * 用户首页\n */\n homePage: string;\n /**\n * 用户头像\n */\n userAvatarURL: string;\n /**\n * 用户名\n */\n userName: string;\n}\n\n/**\n * 主题修改消息,主题内容\n */\nexport type DiscussMsg = string;\n\n/**\n * 撤回消息,被撤回消息的 oId\n */\nexport type RevokeMsg = string;\n\n/**\n * 聊天消息\n */\nexport interface IChatRoomMsg<T = string> {\n /**\n * 消息类型\n */\n type: string;\n /**\n * 消息 oId\n */\n oId: string;\n /**\n * 消息发送时间\n */\n time: string;\n /**\n * 用户 Id\n */\n userOId: string;\n /**\n * 发送者用户名\n */\n userName: string;\n /**\n * 发送者昵称\n */\n userNickname: string;\n /**\n * 发送者头像\n */\n userAvatarURL: string;\n /**\n * 消息内容\n */\n content: T;\n /**\n * 消息内容 Markdown\n */\n md: string;\n /**\n * 消息来源\n */\n client: string;\n /**\n * 消息来源解析\n */\n via: IChatRoomSource;\n}\n\ntype WeatherCode =\n | 'CLEAR_DAY'\n | 'CLEAR_NIGHT'\n | 'CLOUDY'\n | 'DUST'\n | 'FOG'\n | 'HEAVY_HAZE'\n | 'HEAVY_RAIN'\n | 'HEAVY_SNOW'\n | 'LIGHT_HAZE'\n | 'LIGHT_RAIN'\n | 'LIGHT_SNOW'\n | 'MODERATE_HAZE'\n | 'MODERATE_RAIN'\n | 'MODERATE_SNOW'\n | 'PARTLY_CLOUDY_DAY'\n | 'PARTLY_CLOUDY_NIGHT'\n | 'SAND'\n | 'STORM_RAIN'\n | 'STORM_SNOW'\n | 'WIND';\n\n/**\n * 聊天天气消息详情\n */\nexport interface IWeatherData {\n /**\n * 日期\n */\n date: string;\n /**\n * 天气代码\n */\n code: WeatherCode;\n /**\n * 最小气温\n */\n min: number;\n /**\n * 最大气温\n */\n max: number;\n}\n\n/**\n * 聊天天气消息\n */\nexport interface IWeatherMessage {\n /**\n * 城市\n */\n city: string;\n /**\n * 描述\n */\n description: string;\n /**\n * 最近几天天气数据\n */\n data: IWeatherData[];\n}\n\n/**\n * 聊天音乐消息\n */\nexport interface IMusicMessage {\n type: 'music';\n /**\n * 音乐源\n */\n source: string;\n /**\n * 封面地址\n */\n coverURL: string;\n /**\n * 歌曲名称\n */\n title: string;\n /**\n * 来源\n */\n from: string;\n}\n\n/**\n * 聊天室节点信息\n */\nexport interface IChatRoomNode {\n /**\n * 节点地址\n */\n node: string;\n /**\n * 名称\n */\n name: string;\n /**\n * 在线人数\n */\n online?: number;\n}\n\n/**\n * 聊天室节点详情\n */\nexport interface IChatRoomNodeInfo {\n /**\n * 推荐节点\n */\n recommend: IChatRoomNode;\n /**\n * 所有节点\n */\n avaliable: IChatRoomNode[];\n}\n","/**\n * 猜拳类型\n */\nexport enum GestureType {\n /**\n * 石头\n */\n Rock = 0,\n /**\n * 剪刀\n */\n Scissors = 1,\n /**\n * 布\n */\n Paper = 2,\n}\n\n/**\n * 红包类型\n */\nexport enum RedPacketType {\n /**\n * 拼手气\n */\n Random = 'random',\n /**\n * 平分\n */\n Average = 'average',\n /**\n * 专属\n */\n Specify = 'specify',\n /**\n * 心跳\n */\n Heartbeat = 'heartbeat',\n /**\n * 猜拳\n */\n RockPaperScissors = 'rockPaperScissors',\n}\n\n/**\n * 红包数据\n */\nexport class Redpacket implements IRedpacket {\n /**\n * 红包类型\n */\n type: RedPacketType = RedPacketType.Random;\n /**\n * 红包积分\n */\n money: number = 32;\n /**\n * 红包个数\n */\n count: number = 1;\n /**\n * 祝福语\n */\n msg: string = '摸鱼者,事竟成';\n /**\n * 接收者,专属红包有效\n */\n recivers?: Array<string>;\n /**\n * 出拳,猜拳红包有效\n */\n gesture?: GestureType;\n}\n\n/**\n * 红包数据\n */\nexport interface IRedpacket {\n /**\n * 红包类型\n */\n type: RedPacketType;\n /**\n * 红包积分\n */\n money: number;\n /**\n * 红包个数\n */\n count: number;\n /**\n * 祝福语\n */\n msg: string;\n /**\n * 接收者,专属红包有效\n */\n recivers?: Array<string>;\n /**\n * 出拳,猜拳红包有效\n */\n gesture?: GestureType;\n}\n\n/**\n * 红包领取者信息\n */\nexport interface IRedPacketGot {\n /**\n * 用户 id\n */\n userId: string;\n /**\n * 用户名\n */\n userName: string;\n /**\n * 用户头像\n */\n avatar: string;\n /**\n * 领取到的积分\n */\n userMoney: number;\n /**\n * 领取积分时间\n */\n time: string;\n}\n\n/**\n * 红包历史信息\n */\nexport interface IRedPacketMessage {\n /**\n * 消息类型,固定为 redPacket\n */\n msgType: string;\n /**\n * 红包数\n */\n count: number;\n /**\n * 领取数\n */\n got: number;\n /**\n * 内含积分\n */\n money: number;\n /**\n * 祝福语\n */\n msg: string;\n /**\n * 发送者 id\n */\n senderId: string;\n /**\n * 红包类型\n */\n type: RedPacketType;\n /**\n * 接收者,专属红包有效\n */\n recivers: string[];\n /**\n * 已领取者列表\n */\n who: IRedPacketGot[];\n}\n\n/**\n * 红包基本信息\n */\nexport interface IRedPacketBase {\n /**\n * 数量\n */\n count: number;\n /**\n * 猜拳类型\n */\n gesture?: GestureType;\n /**\n * 领取数\n */\n got: number;\n /**\n * 祝福语\n */\n msg: string;\n /**\n * 发送者用户名\n */\n userName: string;\n /**\n * 用户头像\n */\n userAvatarURL: string;\n}\n\n/**\n * 红包信息\n */\nexport interface IRedPacketInfo {\n /**\n * 红包基本信息\n */\n info: IRedPacketBase;\n /**\n * 接收者,专属红包有效\n */\n recivers: string[];\n /**\n * 已领取者列表\n */\n who: IRedPacketGot[];\n}\n\n/**\n * 红包状态信息\n */\nexport interface IRedPacketStatusMsg {\n /**\n * 对应红包消息 oId\n */\n oId: string;\n /**\n * 红包个数\n */\n count: number;\n /**\n * 已领取数量\n */\n got: number;\n /**\n * 发送者信息\n */\n whoGive: any;\n /**\n * 领取者信息\n */\n whoGot: any[];\n}\n","import { UserAppRole } from '.';\nimport { domain, toMetal } from '../utils';\n\nexport interface IUserLite {\n oId: string;\n userAvatarURL: string;\n userNickname: string;\n userName: string;\n}\n\n/**\n * 用户信息\n */\nexport class UserInfo {\n /**\n * 用户 id\n */\n oId: string = '';\n /**\n * 用户编号\n */\n userNo: string = '';\n /**\n * 用户名\n */\n userName: string = '';\n /**\n * 昵称\n */\n userNickname: string = '';\n /**\n * 首页地址\n */\n URL: string = '';\n /**\n * 所在城市\n */\n city: string = '';\n /**\n * 签名\n */\n intro: string = '';\n /**\n * 是否在线\n */\n online: boolean = false;\n /**\n * 用户积分\n */\n points: number = 0;\n /**\n * 用户组\n */\n role: string = '';\n /**\n * 角色\n */\n appRole: UserAppRole = UserAppRole.Hack;\n /**\n * 用户头像地址\n */\n avatar: string = '';\n /**\n * 用户卡片背景\n */\n cardBg: string = '';\n /**\n * 用户关注数\n */\n following: number = 0;\n /**\n * 用户被关注数\n */\n follower: number = 0;\n /**\n * 在线时长,单位分钟\n */\n onlineMinute: number = 0;\n /**\n * 是否已经关注,未登录则为 `hide`\n */\n canFollow: 'hide' | 'no' | 'yes' = 'hide';\n /**\n * 用户所有勋章列表,包含未佩戴\n */\n ownedMetal: Metal[] = [];\n\n /**\n * 用户勋章列表\n */\n sysMetal: Metal[] = [];\n /**\n * MBTI 性格类型\n */\n mbti: string = '';\n\n get name(): string {\n return this.userNickname ? `${this.userNickname}(${this.userName})` : this.userName;\n }\n\n static from(user: Record<string, any>) {\n const data = new UserInfo();\n data.oId = user.oId;\n data.userNo = user.userNo;\n data.userName = user.userName;\n data.userNickname = user.userNickname;\n data.URL = user.userURL;\n data.city = user.userCity;\n data.intro = user.userIntro;\n data.online = user.userOnlineFlag;\n data.points = user.userPoint;\n data.role = user.userRole;\n data.appRole = user.userAppRole;\n data.avatar = user.userAvatarURL;\n data.cardBg = user.cardBg;\n data.following = user.followingUserCount;\n data.follower = user.followerCount;\n data.onlineMinute = user.onlineMinute;\n data.canFollow = user.canFollow;\n data.ownedMetal = toMetal(user.allMetalOwned);\n data.sysMetal = toMetal(user.sysMetal);\n data.mbti = user.mbti;\n\n return data;\n }\n}\n\n/**\n * 徽章属性\n */\nexport class MetalAttr {\n /**\n * 徽标图地址\n */\n url: string = '';\n /**\n * 背景色\n */\n backcolor: string = '';\n /**\n * 文字颜色\n */\n fontcolor: string = '';\n /**\n * 版本号\n */\n ver: number = 0.1;\n /**\n * 缩放比例\n */\n scale: number = 0.79;\n\n toString() {\n return `url=${this.url}&backcolor=${this.backcolor}&fontcolor=${this.fontcolor}&ver=${this.ver}&scale=${this.scale}`;\n }\n}\n\n/**\n * 徽章基本信息\n */\nexport class MetalBase {\n /**\n * 徽章属性\n */\n attr: MetalAttr | string = new MetalAttr();\n /**\n * 徽章名\n */\n name: string = '';\n /**\n * 徽章描述\n */\n description: string = '';\n /**\n * 徽章数据\n */\n data: string = '';\n\n constructor(metal?: MetalBase) {\n if (!metal) {\n return;\n }\n this.attr = Object.assign(new MetalAttr(), metal.attr);\n this.name = metal.name;\n this.description = metal.description;\n this.data = metal.data;\n }\n\n toUrl(includeText: boolean = true) {\n let url = `https://${domain}/gen?txt=${this.name}&${this.attr.toString()}`;\n if (!includeText) {\n url = `https://${domain}/gen?txt=&${this.attr.toString()}`;\n }\n return url;\n }\n}\n\n/**\n * 徽章信息\n */\nexport class Metal extends MetalBase {\n /**\n * 完整徽章地址(含文字)\n */\n url?: string;\n /**\n * 徽章地址(不含文字)\n */\n icon?: string;\n /**\n * 是否佩戴\n */\n enable: boolean = true;\n}\n\nexport class AtUser {\n /**\n * 用户名\n */\n userName: string = '';\n /**\n * 用户头像\n */\n userAvatarURL: string = '';\n /**\n * 全小写用户名\n */\n userNameLowerCase: string = '';\n}\n\n/**\n * 徽章属性\n */\nexport interface IMetalAttr {\n /**\n * 徽标图地址\n */\n url: string;\n /**\n * 背景色\n */\n backcolor: string;\n /**\n * 文字颜色\n */\n fontcolor: string;\n}\n\n/**\n * 徽章基本信息\n */\nexport interface IMetalBase {\n /**\n * 徽章属性\n */\n attr: IMetalAttr | string;\n /**\n * 徽章名\n */\n name: string;\n /**\n * 徽章描述\n */\n description: string;\n /**\n * 徽章数据\n */\n data: string;\n}\n\n/**\n * 徽章信息\n */\nexport interface IMetal extends IMetalBase {\n /**\n * 完整徽章地址(含文字)\n */\n url?: string;\n /**\n * 徽章地址(不含文字)\n */\n icon?: string;\n /**\n * 是否佩戴\n */\n enable: boolean;\n}\n\nexport interface IAtUser {\n /**\n * 用户名\n */\n userName: string;\n /**\n * 用户头像\n */\n userAvatarURL: string;\n /**\n * 全小写用户名\n */\n userNameLowerCase: string;\n}\n\n/**\n * 更新用户信息参数\n */\nexport interface UserUpdateParams {\n /**\n * 昵称\n */\n userNickname?: string;\n /**\n * 用户标签,多个标签用逗号分隔\n */\n userTags?: string;\n /**\n * 个人主页 URL\n */\n userURL?: string;\n /**\n * 个人简介\n */\n userIntro?: string;\n /**\n * MBTI 性格类型(例如:ENFP)\n */\n mbti?: string;\n}\n","/**\n * 摸鱼大闯关信息\n */\nexport class MoFishGame implements IMoFishGame {\n userName = '';\n stage = '';\n time = 0;\n}\n\n/**\n * 用户背包物品类型\n */\nexport enum UserBagType {\n checkin1day,\n checkin2days,\n patchCheckinCard,\n metalTicket,\n}\n\n/**\n * 摸鱼大闯关信息\n */\nexport interface IMoFishGame {\n userName: string;\n stage: string;\n time: number;\n}\n\n/**\n * 用户 IP 信息\n */\nexport interface IUserIP {\n latestLoginIP: string;\n userId: string;\n}\n\n/**\n * 用户背包信息\n */\nexport interface IUserBag {\n /**\n * 免签卡\n */\n checkin1day: number;\n\n /**\n * 两日免签卡\n */\n checkin2days: number;\n\n /**\n * 补签卡\n */\n patchCheckinCard: number;\n\n /**\n * 摸鱼派一周年纪念勋章领取券\n */\n metalTicket: number;\n\n /**\n * 改名卡\n */\n nameCard: number;\n\n /**\n * 免签天数\n */\n sysCheckinRemain: number;\n}\n","import { DataType, ArticleTag } from '.';\n\n/**\n * 通知类型\n */\nexport enum NoticeType {\n /**\n * 积分\n */\n Point = 'point',\n /**\n * 评论\n */\n Comment = 'commented',\n /**\n * 回复\n */\n Reply = 'reply',\n /**\n * 提及我的\n */\n At = 'at',\n /**\n * 我关注的\n */\n Following = 'following',\n /**\n * 同城\n */\n Broadcast = 'broadcast',\n /**\n * 系统\n */\n System = 'sys-announce',\n}\n\n/**\n * 通知列表\n */\nexport type NoticeList = Array<\n INoticePoint | INoticeComment | INoticeReply | INoticeAt | INoticeArticle | INoticeSystem\n>;\n\n/**\n * 通知数\n */\nexport interface INoticeCount {\n /**\n * 用户是否启用 Web 通知\n */\n userNotifyStatus: boolean;\n /**\n * 未读通知数\n */\n unreadNotificationCnt: number;\n /**\n * 未读回复通知数\n */\n unreadReplyNotificationCnt: number;\n /**\n * 未读积分通知数\n */\n unreadPointNotificationCnt: number;\n /**\n * 未读 @ 通知数\n */\n unreadAtNotificationCnt: number;\n /**\n * 未读同城通知数\n */\n unreadBroadcastNotificationCnt: number;\n /**\n * 未读系统通知数\n */\n unreadSysAnnounceNotificationCnt: number;\n /**\n * 未读关注者通知数\n */\n unreadNewFollowerNotificationCnt: number;\n /**\n * 未读关注通知数\n */\n unreadFollowingNotificationCnt: number;\n /**\n * 未读评论通知数\n */\n unreadCommentedNotificationCnt: number;\n}\n\n/**\n * 积分通知\n */\nexport interface INoticePoint {\n /**\n * 通知 id\n */\n oId: string;\n /**\n * 数据 id\n */\n dataId: string;\n /**\n * 用户 id\n */\n userId: string;\n /**\n * 数据类型\n */\n dataType: DataType;\n /**\n * 通知描述\n */\n description: string;\n /**\n * 是否已读\n */\n hasRead: boolean;\n /**\n * 创建日期\n */\n createTime: string;\n}\n\n/**\n * 评论通知\n */\nexport interface INoticeComment {\n /**\n * 通知 id\n */\n oId: string;\n /**\n * 文章标题\n */\n commentArticleTitle: string;\n /**\n * 文章作者\n */\n commentAuthorName: string;\n /**\n * 作者头像\n */\n commentAuthorThumbnailURL: string;\n /**\n * 文章类型\n */\n commentArticleType: number;\n /**\n * 是否精选\n */\n commentArticlePerfect: number;\n /**\n * 评论内容\n */\n commentContent: string;\n /**\n * 评论地址\n */\n commentSharpURL: string;\n /**\n * 是否已读\n */\n hasRead: boolean;\n /**\n * 评论时间\n */\n commentCreateTime: string;\n}\n\n/**\n * 回帖通知\n */\nexport interface INoticeReply extends INoticeComment {\n /**\n * 文章 id\n */\n articleId: string;\n /**\n * 数据类型\n */\n dataType: DataType;\n}\n\n/**\n * 提到我通知\n */\nexport interface INoticeAt {\n /**\n * 通知 id\n */\n oId: string;\n /**\n * 数据 id\n */\n dataId: string;\n /**\n * 数据类型\n */\n dataType: DataType;\n /**\n * 用户名\n */\n userName: string;\n /**\n * 用户头像\n */\n thumbnailURL: string;\n /**\n * 通知内容\n */\n description: string;\n /**\n * 是否已读\n */\n hasRead: boolean;\n /**\n * 创建时间\n */\n createTime: string;\n}\n\n/**\n * 我关注的通知\n */\nexport interface INoticeArticle {\n /**\n * 通知 Id\n */\n oId: string;\n /**\n * 文章地址\n */\n url: string;\n /**\n * 数据类型\n */\n dataType: DataType;\n /**\n * 文章标题\n */\n articleTitle: string;\n /**\n * 作者\n */\n authorName: string;\n /**\n * 通知内容\n */\n content: string;\n /**\n * 是否评论\n */\n isComment: boolean;\n /**\n * 作者头像\n */\n thumbnailURL: string;\n /**\n * 文章评论数\n */\n articleCommentCount: number;\n /**\n * 是否精选\n */\n articlePerfect: number;\n /**\n * 文章标签列表\n */\n articleTagObjs: ArticleTag[];\n /**\n * 文章标签\n */\n articleTags: string;\n /**\n * 文章类型\n */\n articleType: number;\n /**\n * 是否已读\n */\n hasRead: boolean;\n /**\n * 通知创建时间\n */\n createTime: string;\n}\n\n/**\n * 系统通知数据\n */\nexport interface INoticeSystem {\n /**\n * 消息的 oId\n */\n oId: string;\n /**\n * 用户 Id\n */\n userId: string;\n /**\n * 数据 Id\n */\n dataId: string;\n /**\n * 数据类型\n */\n dataType: DataType;\n /**\n * 消息描述\n */\n description: string;\n /**\n * 是否已读\n */\n hasRead: boolean;\n /**\n * 创建日期\n */\n createTime: string;\n}\n\nexport enum NoticeCommandType {\n /** 刷新通知 */\n RefreshNotification = 'refreshNotification',\n /**\n * 聊天未读数刷新\n */\n ChatUnreadCountRefresh = 'chatUnreadCountRefresh',\n /**\n * 新的闲聊消息\n */\n NewIdleChatMessage = 'newIdleChatMessage',\n /**\n * 系统广播警告\n */\n WarnBroadcast = 'warnBroadcast',\n /**\n * 清风明月更新\n */\n bzUpdate = 'bzUpdate',\n}\n\n/**\n * 通知消息\n */\nexport interface INoticeCommand {\n /**\n * 通知类型\n */\n command: NoticeCommandType;\n}\n\n/**\n * 未读消息数\n */\nexport interface INoticeUnReadCount extends INoticeCommand {\n /**\n * 未读数\n */\n count: number;\n}\n\n/**\n * 私聊通知\n */\nexport interface INoticeIdleChat extends INoticeCommand {\n senderUserName: string;\n senderAvatar: string;\n preview: string;\n}\n\n/**\n * 系统广播\n */\nexport interface INoticeWarnBroadcast extends INoticeCommand {\n warnBroadcastText: string;\n who: string;\n}\n\n/**\n * 清风明月更新\n */\nexport interface INoticeBreezemoon extends INoticeCommand {\n /**\n * 发布者用户名\n */\n breezemoonAuthorName: string;\n /**\n * 发布者头像\n */\n breezemoonAuthorThumbnailURL48: string;\n /**\n * 内容\n */\n breezemoonContent: string;\n /**\n * 清风明月ID\n */\n oId: string;\n}\n","export * from './article';\nexport * from './breezemoon';\nexport * from './chat';\nexport * from './chatroom';\nexport * from './redpacket';\nexport * from './user';\nexport * from './finger';\nexport * from './notice';\n\n/**\n * 数据类型\n */\nexport enum DataType {\n /**\n * 文章\n */\n article = 0,\n\n /**\n * 评论\n */\n comment = 1,\n\n /**\n * @\n */\n at = 2,\n\n /**\n * 被评论\n */\n commented = 3,\n\n /**\n * 关注者\n */\n followingUser = 4,\n\n /**\n * 积分 - 充值\n */\n pointCharge = 5,\n\n /**\n * 积分 - 转账\n */\n pointTransfer = 6,\n\n /**\n * 积分 - 文章打赏\n */\n pointArticleReward = 7,\n\n /**\n * 积分 - 评论感谢\n */\n pointCommentThank = 8,\n\n /**\n * 同城广播\n */\n broadcast = 9,\n\n /**\n * 积分 - 交易\n */\n pointExchange = 10,\n\n /**\n * 积分 - 滥用扣除\n */\n abusePointDeduct = 11,\n\n /**\n * 积分 - 文章被感谢\n */\n pointArticleThank = 12,\n\n /**\n * 回复\n */\n reply = 13,\n\n /**\n * 使用邀请码\n */\n invitecodeUsed = 14,\n\n /**\n * 系统公告 - 文章\n */\n sysAnnounceArticle = 15,\n\n /**\n * 系统公告 - 新用户\n */\n sysAnnounceNewUser = 16,\n\n /**\n * 新的关注者\n */\n newFollower = 17,\n\n /**\n * 邀请链接\n */\n invitationLinkUsed = 18,\n\n /**\n * 系统通知 - 角色变化\n */\n sysAnnounceRoleChanged = 19,\n\n /**\n * 关注的文章更新\n */\n followingArticleUpdate = 20,\n\n /**\n * 关注的文章评论\n */\n followingArticleComment = 21,\n\n /**\n * 积分 - 文章优选\n */\n pointPerfectArticle = 22,\n\n /**\n * 文章新的被关注者\n */\n articleNewFollower = 23,\n\n /**\n * 文章新的关注者\n */\n articleNewWatcher = 24,\n\n /**\n * 评论点赞\n */\n commentVoteUp = 25,\n\n /**\n * 评论点踩\n */\n commentVoteDown = 26,\n\n /**\n * 文章被点赞\n */\n articleVoteUp = 27,\n\n /**\n * 文章被点踩\n */\n articleVoteDown = 28,\n\n /**\n * 积分 - 评论被接受\n */\n pointCommentAccept = 33,\n\n /**\n * 积分 - 举报处理\n */\n pointReportHandled = 36,\n\n /**\n * 聊天室 @\n */\n chatRoomAt = 38,\n\n /**\n * 专属红包提醒\n */\n redPacket = 39,\n}\n\n/**\n * 用户角色类型\n */\nexport enum UserAppRole {\n /**\n * 黑客\n */\n Hack = 0,\n /**\n * 画家\n */\n Artist = 1,\n}\n\n/**\n * 举报数据类型\n */\nexport enum ReportDataType {\n /**\n * 文章\n */\n article = 0,\n /**\n * 评论\n */\n comment = 1,\n /**\n * 用户\n */\n user = 2,\n /**\n * 聊天消息\n */\n chatroom = 3,\n}\n\n/**\n * 举报类型\n */\nexport enum ReportType {\n /**\n * 垃圾广告\n */\n advertise = 0,\n /**\n * 色情\n */\n porn = 1,\n /**\n * 违规\n */\n violate = 2,\n /**\n * 侵权\n */\n infringement = 3,\n /**\n * 人身攻击\n */\n attacks = 4,\n /**\n * 冒充他人账号\n */\n impersonate = 5,\n /**\n * 垃圾广告账号\n */\n advertisingAccount = 6,\n /**\n * 违规泄露个人信息\n */\n leakPrivacy = 7,\n /**\n * 其它\n */\n other = 8,\n}\n\n/**\n * 登录信息\n */\nexport class Account implements IAccount {\n /**\n * 用户名\n */\n username: string = '';\n /**\n * 密码\n */\n passwd: string = '';\n /**\n * 二次验证码,非必填\n */\n mfaCode?: string = '';\n}\n\n/**\n * 注册信息\n */\nexport class PreRegisterInfo implements IPreRegisterInfo {\n /**\n * 用户名\n */\n username: string = '';\n /**\n * 手机号\n */\n phone: string = '';\n /**\n * 邀请码\n */\n invitecode?: string;\n /**\n * 验证码\n */\n captcha: string = '';\n}\n\n/**\n * 注册信息\n */\nexport class RegisterInfo implements IRegisterInfo {\n /**\n * 用户角色\n */\n role: string = '';\n /**\n * 用户密码\n */\n passwd: string = '';\n /**\n * 用户 Id\n */\n userId: string = '';\n /**\n * 邀请人用户名\n */\n r?: string;\n}\n\n/**\n * 举报接口数据\n */\nexport class Report implements IReport {\n /**\n * 举报对象的 oId\n */\n reportDataId: string = '';\n /**\n * 举报数据的类型\n */\n reportDataType: ReportDataType = ReportDataType.article;\n /**\n * 举报的类型\n */\n reportType: ReportType = ReportType.advertise;\n /**\n * 举报的理由\n */\n reportMemo: string = '';\n}\n\n/**\n * 登录信息\n */\nexport interface IAccount {\n /**\n * 用户名\n */\n username: string;\n /**\n * 密码\n */\n passwd: string;\n /**\n * 二次验证码,非必填\n */\n mfaCode?: string;\n}\n\n/**\n * 注册信息\n */\nexport interface IPreRegisterInfo {\n /**\n * 用户名\n */\n username: string;\n /**\n * 手机号\n */\n phone: string;\n /**\n * 邀请码\n */\n invitecode?: string;\n /**\n * 验证码\n */\n captcha: string;\n}\n\n/**\n * 注册信息\n */\nexport interface IRegisterInfo {\n /**\n * 用户角色\n */\n role: string;\n /**\n * 用户密码\n */\n passwd: string;\n /**\n * 用户 Id\n */\n userId: string;\n /**\n * 邀请人用户名\n */\n r?: string;\n}\n\n/**\n * 上传文件响应\n */\nexport interface IUploadInfo {\n /**\n * 上传失败文件\n */\n errFiles: string[];\n /**\n * 上传成功文件\n */\n succMap: {\n /**\n * Key 是文件名,value 为地址\n */\n [key: string]: string;\n };\n}\n\n/**\n * VIP 信息\n */\nexport interface IUserVIP {\n /**\n * VIP Id\n */\n oId: string;\n /**\n * VIP 状态\n */\n state: number;\n /**\n * 用户 Id\n */\n userId: string;\n /**\n * 是否 VIP\n */\n jointVip: boolean;\n /**\n * 颜色\n */\n color: string;\n /**\n * 是否有下划线\n */\n underline: boolean;\n /**\n * 是否有金属质感\n */\n metal: boolean;\n /**\n * 是否自动签到\n */\n autoCheckin: number;\n /**\n * 是否加粗\n */\n bold: boolean;\n /**\n * 等级代码\n */\n lvCode: string;\n /**\n * 过期时间\n */\n expiresAt: number;\n /**\n * 创建时间\n */\n createdAt: number;\n /**\n * 更新时间\n */\n updatedAt: number;\n}\n\nexport class UserVIP implements IUserVIP {\n /**\n * VIP Id\n */\n oId: string = '';\n /**\n * VIP 状态\n */\n state: number = 0;\n /**\n * 用户 Id\n */\n userId: string = '';\n /**\n * 是否 VIP\n */\n jointVip: boolean = false;\n /**\n * 颜色\n */\n color: string = '';\n /**\n * 是否有下划线\n */\n underline: boolean = false;\n /**\n * 是否有金属质感\n */\n metal: boolean = false;\n /**\n * 是否自动签到\n */\n autoCheckin: number = 0;\n /**\n * 是否加粗\n */\n bold: boolean = false;\n /**\n * 等级代码\n */\n lvCode: string = '';\n /**\n * 过期时间\n */\n expiresAt: number = 0;\n /**\n * 创建时间\n */\n createdAt: number = 0;\n /**\n * 更新时间\n */\n updatedAt: number = 0;\n\n get isVip(): boolean {\n return this.state === 1 && this.expiresAt * 1000 >= Date.now();\n }\n\n get vipName(): string {\n if (!this.isVip) return '非会员';\n return this.lvCode.replace(/_YEAR/, '(包年)').replace(/_MONTH/, '(包月)');\n }\n\n get expireDate(): Date {\n return new Date(this.expiresAt);\n }\n\n get createDate(): Date {\n return new Date(this.createdAt);\n }\n\n get updateDate(): Date {\n return new Date(this.updatedAt);\n }\n\n static from(data: any): UserVIP {\n const vip = new UserVIP();\n vip.oId = data.oId || '';\n vip.state = data.state || 0;\n vip.userId = data.userId || '';\n vip.jointVip = data.config?.jointVip || false;\n vip.color = data.config?.color || '';\n vip.underline = data.config?.underline || false;\n vip.metal = data.config?.metal || false;\n vip.autoCheckin = data.config?.autoCheckin || 0;\n vip.bold = data.config?.bold || false;\n vip.lvCode = data.lvCode || '';\n vip.expiresAt = data.expiresAt || 0;\n vip.createdAt = data.createdAt || 0;\n vip.updatedAt = data.updatedAt || 0;\n return vip;\n }\n}\n\n/**\n * 举报接口数据\n */\nexport interface IReport {\n /**\n * 举报对象的 oId\n */\n reportDataId: string;\n /**\n * 举报数据的类型\n */\n reportDataType: ReportDataType;\n /**\n * 举报的类型\n */\n reportType: ReportType;\n /**\n * 举报的理由\n */\n reportMemo: string;\n}\n\n/**\n * 禁言用户信息\n */\nexport interface IMuteItem {\n /**\n * 解除禁言时间戳\n */\n time: number;\n /**\n * 用户头像\n */\n userAvatarURL: string;\n /**\n * 用户名\n */\n userName: string;\n /**\n * 用户昵称\n */\n userNickname: string;\n}\n\nexport interface ILog {\n /**\n * 操作时间\n */\n key1: string;\n /**\n * IP\n */\n key2: string;\n /**\n * 内容\n */\n data: string;\n /**\n * 是否公开\n */\n public: boolean;\n /**\n * 操作类型\n */\n key3: string;\n /**\n * 唯一标识\n */\n oId: string;\n /**\n * 类型\n */\n type: string;\n}\n\nexport class Pagination {\n /**\n * 分页数\n */\n pageCount = 0;\n /**\n * 建议分页页码\n */\n pageNums: number[] = [];\n\n static from(data: any) {\n const p = new Pagination();\n p.pageCount = data.paginationPageCount;\n p.pageNums = data.paginationPageNums;\n return p;\n }\n}\n","import ReconnectingWebSocket, {\n Options as ReconnectingWebSocketOptions,\n} from 'reconnecting-websocket';\nimport { WebSocket, EventEmitter } from './utils';\n\nexport interface IWebSocketEvent {\n /**\n * Websocket 打开\n */\n open: (event: Event) => void;\n /**\n * Websocket 关闭\n */\n close: (event: CloseEvent) => void;\n /**\n * Websocket 错误\n */\n error: (error: ErrorEvent) => void;\n}\n\nexport class WsEventBase<T> {\n emitter = new EventEmitter();\n ws: ReconnectingWebSocket | null = null;\n rwsOptions: ReconnectingWebSocketOptions = {\n minReconnectionDelay: 10000,\n maxReconnectionDelay: 600000,\n reconnectionDelayGrowFactor: 1.3,\n maxRetries: 100,\n connectionTimeout: 10000,\n };\n constructor() {}\n\n /**\n * 重连通知频道\n * @returns Websocket 连接对象\n */\n reconnect() {\n if (!this.ws) return this.connect();\n return new Promise((resolve) => {\n if (!this.ws || this.ws.readyState === WebSocket.CONNECTING) return;\n this.ws.reconnect();\n this.ws.onopen = (e) => {\n resolve(this.ws!);\n };\n });\n }\n\n /**\n * 连接 WebSocket 频道\n * @returns Websocket 连接对象\n */\n connect(reload = false): Promise<ReconnectingWebSocket> {\n return new Promise(async (resolve, reject) => {\n if (this.ws && !reload) return resolve(this.ws);\n if (this.ws) this.ws.close();\n return reject(new Error('请在子类中实现 connect 方法'));\n });\n }\n\n /**\n * WebSocket 监听\n * @param event WebSocket 事件\n * @param listener 监听器\n */\n on<K extends keyof T>(event: K, listener: T[K]) {\n if (this.ws == null || this.ws.readyState !== WebSocket.OPEN) {\n this.connect();\n }\n return this.emitter.on(event as string, listener as (...args: any[]) => void);\n }\n\n /**\n * 移除 WebSocket 监听\n * @param event WebSocket 事件\n * @param listener 监听器\n */\n off<K extends keyof T>(event?: K, listener?: T[K]) {\n if (!event) return this.emitter.removeAllListeners();\n if (!listener) return this.emitter.removeAllListeners(event as string);\n return this.emitter.off(event as string, listener as (...args: any[]) => void);\n }\n\n /**\n * WebSocket 单次监听\n * @param event WebSocket 事件\n * @param listener 监听器\n */\n once<K extends keyof T>(event: K, listener: T[K]) {\n return this.emitter.once(event as string, listener as (...args: any[]) => void);\n }\n\n /**\n * 清除 WebSocket 监听\n */\n clearListener(event?: keyof T) {\n this.emitter.removeAllListeners(event as string);\n }\n\n /**\n * 移除 WebSocket 消息监听函数\n * @param event WebSocket 事件\n * @param listener 监听器\n */\n removeListener<K extends keyof T>(event: K, listener: T[K]) {\n return this.off(event, listener);\n }\n\n /**\n * 添加 WebSocket 消息监听函数\n * @param event WebSocket 事件\n * @param listener 监听器\n */\n addListener<K extends keyof T>(event: K, listener: T[K]) {\n return this.on(event, listener);\n }\n}\n","import ReconnectingWebSocket from 'reconnecting-websocket';\nimport { request, domain, toMetal, clientToVia, WebSocket } from './utils';\nimport {\n ChatContentType,\n ChatMessageType,\n GestureType,\n Redpacket,\n ClientType,\n IOnlineInfo,\n DiscussMsg,\n RevokeMsg,\n IBarragerMsg,\n IChatRoomMsg,\n IRedPacketInfo,\n IMusicMessage,\n IWeatherMessage,\n IRedPacketStatusMsg,\n CustomMsg,\n IChatRoomMessage,\n IMuteItem,\n IChatRoomNodeInfo,\n IRedpacket,\n} from './';\nimport { IWebSocketEvent, WsEventBase } from './ws';\n\ninterface IChatRoomEvents extends IWebSocketEvent {\n /**\n * 在线用户变更\n * @param onlines 在线用户\n */\n online: (onlines: IOnlineInfo[]) => void;\n /**\n * 话题变更\n * @param discuss 话题\n */\n discuss: (discuss: DiscussMsg) => void;\n /**\n * 撤回消息\n * @param oId 被撤回消息 oId\n */\n revoke: (oId: RevokeMsg) => void;\n /**\n * 弹幕消息\n * @param barrage 弹幕消息内容\n */\n barrager: (barrage: IBarragerMsg) => void;\n /**\n * 聊天消息\n * @param msg 聊天消息内容\n */\n msg: (msg: IChatRoomMsg) => void;\n /**\n * 红包消息\n * @param redpacket 红包内容\n */\n redPacket: (redpacket: IChatRoomMsg<IRedpacket>) => void;\n /**\n * 音乐消息\n * @param music 音乐消息内容\n */\n music: (music: IChatRoomMsg<IMusicMessage>) => void;\n /**\n * 天气消息\n * @param weather 天气消息内容\n */\n weather: (weather: IChatRoomMsg<IWeatherMessage>) => void;\n /**\n * 红包领取\n * @param status 红包领取状态\n */\n redPacketStatus: (status: IRedPacketStatusMsg) => void;\n /**\n * 进出通知\n * @param msg 进出通知内容\n */\n custom: (msg: CustomMsg) => void;\n /**\n * 发送所有消息\n * @param type 消息类型\n * @param data 消息内容\n */\n all: (type: string, data: any) => void;\n}\n\nexport class ChatRoom extends WsEventBase<IChatRoomEvents> {\n private apiKey: string = '';\n private _discusse: string = '';\n private _onlines: IOnlineInfo[] = [];\n private wsTimer: NodeJS.Timeout | null = null;\n private client: ClientType | string = ClientType.Other;\n private version: string = 'Latest';\n\n constructor(token: string = '') {\n super();\n if (!token) {\n return;\n }\n this.apiKey = token;\n }\n\n /**\n * 当前在线人数列表,需要先调用 addListener 添加聊天室消息监听\n */\n get onlines() {\n return this._onlines;\n }\n\n /**\n * 当前聊天室话题,需要先调用 addListener 添加聊天室消息监听\n */\n get discusse() {\n return this._discusse;\n }\n\n /**\n * 設置当前聊天室话题\n */\n set discusse(val) {\n this.send(`[setdiscuss]${val}[/setdiscuss]`).catch(() => {});\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(apiKey: string) {\n this.apiKey = apiKey;\n this.redpacket.setToken(apiKey);\n }\n\n /**\n * 设置当前来源类型\n * @param client 来源类型\n * @param version 版本号\n */\n setVia(client: ClientType | string, version: string) {\n this.client = client;\n this.version = version;\n }\n\n /**\n * 查询聊天室历史消息\n * @param page 消息页码\n * @param type 消息内容类型,HTML 或 Raw,默认 HTML\n */\n async history(page = 1, type = ChatContentType.HTML): Promise<IChatRoomMessage[]> {\n try {\n let rsp = await request({\n url: `chat-room/more?page=${page}&type=${type}&apiKey=${this.apiKey}`,\n });\n\n if (rsp.code != 0) {\n throw new Error(rsp.msg);\n }\n\n if (!rsp.data) return rsp;\n (rsp.data as Array<any>).forEach((d, i, data) => {\n try {\n data[i].type = 'msg';\n data[i].md = data[i].content;\n data[i].via = clientToVia(data[i].client);\n data[i].sysMetal = toMetal(data[i].sysMetal);\n data[i].content = JSON.parse(d.content);\n if (data[i].content.recivers)\n data[i].content.recivers = JSON.parse(data[i].content.recivers);\n data[i].type = data[i].content.msgType;\n } catch (e) {}\n });\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取指定消息附近的聊天室消息\n * @param oId 消息 Id\n * @param mode 获取模式,context 上下文模式,after 之后模式\n * @param size 获取消息数量,默认 25,最大 100\n * @param type 获取消息类型,默认 HTML\n */\n async get({\n oId,\n mode = ChatMessageType.Context,\n size = 25,\n type = ChatContentType.HTML,\n }: {\n oId: string;\n mode?: ChatMessageType;\n size?: number;\n type?: ChatContentType;\n }): Promise<IChatRoomMessage[]> {\n try {\n let rsp = await request({\n url: `chat-room/getMessage?oId=${oId}&mode=${mode}&size=${size}&type=${type}&apiKey=${this.apiKey}`,\n });\n\n if (rsp.code != 0) {\n throw new Error(rsp.msg);\n }\n\n if (!rsp.data) return rsp;\n let content;\n (rsp.data as any[]).forEach((d, i, data) => {\n try {\n data[i].via = clientToVia(data[i].client);\n data[i].sysMetal = toMetal(data[i].sysMetal);\n content = JSON.parse(d.content);\n if (content.msgType !== 'redPacket') return rsp;\n if (content.recivers) content.recivers = JSON.parse(content.recivers);\n data[i].content = content;\n } catch (e) {}\n });\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 撤回消息,普通成员 24 小时内可撤回一条自己的消息,纪律委员/OP/管理员角色可以撤回任意人消息\n * @param oId 消息 Id\n */\n async revoke(oId: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `chat-room/revoke/${oId}`,\n method: 'delete',\n data: {\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 发送一条消息\n * @param msg 消息内容,支持 Markdown\n */\n async send(msg: string, clientType?: ClientType | string, version?: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `chat-room/send`,\n method: 'post',\n data: {\n content: msg,\n client: `${clientType || this.client}/${version || this.version}`,\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 发送一条弹幕\n * @param msg 消息内容,支持 Markdown\n * @param color 弹幕颜色\n */\n async barrage(msg: string, color: string = '#ffffff'): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `chat-room/send`,\n method: 'post',\n data: {\n content: `[barrager]{\\\"color\\\":\\\"${color}\\\",\\\"content\\\":\\\"${msg}\\\"}[/barrager]`,\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取弹幕发送价格\n * @returns 返回价格`cost`与单位`unit`\n */\n async barragePay(): Promise<{ cost: number; unit: string }> {\n let rsp;\n try {\n rsp = await request({\n url: `chat-room/barrager/get?apiKey=${this.apiKey}`,\n method: 'get',\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n // 解析格式如 \"5积分\" 的字符串\n const mat = rsp.data.match(/([-0-9]+)(.+)/);\n if (mat) {\n return {\n cost: parseInt(mat[1]),\n unit: mat[2],\n };\n }\n\n return {\n cost: 20,\n unit: '积分',\n };\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取禁言中成员列表(思过崖)\n */\n async mutes(): Promise<IMuteItem[]> {\n let rsp;\n try {\n rsp = await request({\n url: `chat-room/si-guo-list`,\n method: 'get',\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取消息原文(比如 Markdown)\n * @param oId 消息 Id\n */\n async raw(oId: string): Promise<string> {\n let rsp;\n try {\n rsp = await request({\n url: `cr/raw/${oId}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.replace(/<!--.*?-->/g, '');\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 红包接口对象\n */\n redpacket = new RedPacket(this, this.apiKey);\n\n /**\n * 获取聊天室节点\n * @returns 返回节点地址\n */\n async getNode(): Promise<IChatRoomNodeInfo> {\n let rsp: any;\n try {\n rsp = await request({\n url: `chat-room/node/get?apiKey=${this.apiKey}`,\n method: 'get',\n });\n\n if (rsp.code != 0) throw new Error('获取节点失败:' + rsp.msg);\n\n return {\n recommend: {\n node: rsp.data,\n name: rsp.msg,\n online: rsp.avaliable.find((n: any) => n.node === rsp.data)?.online || 0,\n },\n avaliable: rsp.avaliable,\n };\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 连接聊天室\n * @param url 聊天室节点地址\n * @param timeout 超时时间,单位为秒,默认为 10\n * @returns 返回 Open Event\n */\n async connect(reload?: boolean): Promise<ReconnectingWebSocket>;\n async connect(url?: string, timeout?: number): Promise<ReconnectingWebSocket>;\n async connect(urlOrReload?: string | boolean, timeout: number = 10) {\n return new Promise(async (resolve) => {\n let url: string = '';\n if (urlOrReload === undefined || urlOrReload === '' || urlOrReload === true) {\n url = await this.getNode()\n .then((rsp) => rsp.recommend.node)\n .catch(() => `wss://${domain}/chat-room-channel?apiKey=${this.apiKey}`);\n } else {\n url = urlOrReload as string;\n }\n if (!url.includes('apiKey=')) url += `${url.includes('?') ? '&' : '?'}apiKey=${this.apiKey}`;\n if (this.ws) return resolve(this.reconnect());\n this.ws = new ReconnectingWebSocket(url, [], {\n WebSocket,\n ...this.rwsOptions,\n connectionTimeout: 1000 * timeout,\n });\n\n this.ws.onopen = (e) => {\n if (this.wsTimer) {\n clearInterval(this.wsTimer);\n }\n this.wsTimer = setInterval(\n () => {\n this.ws?.send('-hb-');\n },\n 1000 * 60 * 3,\n );\n resolve(e);\n this.emitter.emit('open', e);\n };\n this.ws.onmessage = async (e) => {\n let msg = JSON.parse(e.data);\n let data: any | null = null;\n switch (msg.type) {\n case 'online': {\n this._onlines = msg.users;\n this._discusse = msg.discussing;\n data = this._onlines;\n break;\n }\n case 'discussChanged': {\n data = msg.newDiscuss;\n msg.type = 'discuss';\n break;\n }\n case 'revoke': {\n data = msg.oId;\n break;\n }\n case 'barrager': {\n let {\n barragerContent,\n userAvatarURL,\n userAvatarURL20,\n userNickname,\n barragerColor,\n userName,\n userAvatarURL210,\n userAvatarURL48,\n } = msg;\n data = {\n barragerContent,\n userAvatarURL,\n userAvatarURL20,\n userNickname,\n barragerColor,\n userName,\n userAvatarURL210,\n userAvatarURL48,\n };\n break;\n }\n case 'msg': {\n let { userOId, oId, time, userName, userNickname, userAvatarURL, content, md, client } =\n msg;\n try {\n let data = JSON.parse(content);\n if (['redPacket', 'music', 'weather'].includes(data.msgType)) {\n content = data;\n msg.type = data.msgType;\n }\n } catch (e) {}\n data = {\n type: msg.type,\n userOId,\n oId,\n time,\n userName,\n userNickname,\n userAvatarURL,\n content,\n md,\n client,\n via: clientToVia(client),\n };\n break;\n }\n case 'redPacketStatus': {\n let { oId, count, got, whoGive, whoGot } = msg;\n data = { oId, count, got, whoGive, whoGot };\n break;\n }\n case 'customMessage': {\n data = msg.message;\n msg.type = 'custom';\n break;\n }\n }\n this.emitter.emit(msg.type, data);\n this.emitter.emit('all', data);\n };\n this.ws.onerror = (e) => {\n this.emitter.emit('error', e);\n };\n this.ws.onclose = (e) => {\n this.emitter.emit('close', e);\n };\n });\n }\n}\n\nclass RedPacket {\n private chatroom: ChatRoom;\n private apiKey: string = '';\n\n constructor(chatroom: ChatRoom, apiKey: string) {\n this.chatroom = chatroom;\n this.apiKey = apiKey;\n }\n\n setToken(apiKey: string) {\n this.apiKey = apiKey;\n }\n\n /**\n * 打开一个红包\n * @param oId 红包消息 Id\n * @param gesture 猜拳类型\n */\n async open(oId: string, gesture?: GestureType): Promise<IRedPacketInfo> {\n let rsp;\n try {\n rsp = await request({\n url: `chat-room/red-packet/open`,\n method: 'post',\n data: {\n oId,\n gesture,\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 发送一个红包\n * @param redpacket 红包对象\n */\n async send(redpacket: Redpacket) {\n return await this.chatroom.send(`[redpacket]${JSON.stringify(redpacket)}[/redpacket]`);\n }\n}\n","import ReconnectingWebSocket from 'reconnecting-websocket';\nimport {\n INoticeBreezemoon,\n INoticeCount,\n INoticeIdleChat,\n INoticeUnReadCount,\n INoticeWarnBroadcast,\n NoticeList,\n NoticeType,\n} from './';\nimport { domain, request, WebSocket } from './utils';\nimport { IWebSocketEvent, WsEventBase } from './ws';\n\ninterface INoticeEvents extends IWebSocketEvent {\n /**\n * 清风明月更新\n * @param data 清风明月\n */\n bzUpdate: (data: INoticeBreezemoon) => void;\n /**\n * 未读消息数通知\n * @param data 未读消息数\n */\n refreshNotification: (data: INoticeUnReadCount) => void;\n /**\n * 聊天未读消息数通知\n * @param data 聊天未读消息数\n */\n chatUnreadCountRefresh: (data: INoticeUnReadCount) => void;\n /**\n * 新私聊消息通知\n * @param data 新私聊消息\n */\n newIdleChatMessage: (data: INoticeIdleChat) => void;\n /**\n * 警告广播消息通知\n * @param data 警告广播消息\n */\n warnBroadcast: (data: INoticeWarnBroadcast) => void;\n}\n\nexport class Notice extends WsEventBase<INoticeEvents> {\n private apiKey: string = '';\n\n constructor(token: string = '') {\n super();\n if (!token) {\n return;\n }\n this.apiKey = token;\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(token: string) {\n this.apiKey = token;\n }\n\n /**\n * 获取未读消息数\n */\n async count(): Promise<INoticeCount> {\n let rsp;\n try {\n rsp = await request({\n url: `notifications/unread/count?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code !== 0) throw new Error(rsp.msg);\n\n if (rsp.userNotifyStatus) rsp.userNotifyStatus = rsp.userNotifyStatus != 0;\n return rsp;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取消息列表\n * @param type 消息类型\n */\n async list(type: NoticeType): Promise<NoticeList> {\n let rsp;\n try {\n rsp = await request({\n url: `api/getNotifications?apiKey=${this.apiKey}&type=${type}`,\n });\n\n if (rsp.code !== 0) throw new Error(rsp.msg);\n\n rsp.data.forEach((n: any) => {\n if (!n.description && n.content) n.description = n.content;\n return n;\n });\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 已读指定类型消息\n * @param type 消息类型\n */\n async makeRead(type: NoticeType): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `notifications/make-read/${type}?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code !== 0) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 已读所有消息\n */\n async readAll(): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `notifications/all-read?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code !== 0) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 重连通知频道\n * @returns Websocket 连接对象\n */\n reconnect() {\n if (!this.ws) return this.connect();\n return new Promise((resolve) => {\n if (!this.ws) return;\n this.ws.reconnect();\n this.ws.onopen = (e) => {\n resolve(this.ws!);\n };\n });\n }\n\n /**\n * 连接用户私聊频道\n * @returns Websocket 连接对象\n */\n connect(reload = false): Promise<ReconnectingWebSocket> {\n return new Promise(async (resolve, reject) => {\n if (this.ws && !reload) return resolve(this.ws);\n if (this.ws) this.ws.close();\n if (!this.apiKey) return reject(new Error('请先设置 API Key'));\n this.ws = new ReconnectingWebSocket(\n `wss://${domain}/user-channel?apiKey=${this.apiKey}`,\n [],\n {\n WebSocket,\n connectionTimeout: 10000,\n maxRetries: 10,\n },\n );\n this.ws.onopen = (e) => {\n resolve(this.ws!);\n };\n this.ws.onmessage = async (e) => {\n let msg = JSON.parse(e.data);\n if (msg.command == 'bz-update') {\n msg = { ...msg.bz, command: 'bzUpdate' };\n }\n if (msg.command) {\n this.emitter.emit(msg.command, msg);\n }\n };\n this.ws.onerror = (e) => {\n this.emitter.emit('error', e);\n };\n this.ws.onclose = (e) => {\n this.emitter.emit('close', e);\n };\n });\n }\n}\n","import { request, domain } from './utils';\n\nexport class Emoji {\n private apiKey: string = '';\n private emojis: string[] = [];\n\n constructor(token: string = '') {\n if (!token) {\n return;\n }\n this.setToken(token);\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(token: string) {\n this.apiKey = token;\n if (token)\n this.get()\n .then((e) => (this.emojis = e))\n .catch(() => {});\n }\n\n get default() {\n return {\n doge: 'https://cdn.jsdelivr.net/npm/vditor@3.8.7/dist/images/emoji/doge.png',\n trollface: 'https://cdn.jsdelivr.net/npm/vditor@3.8.7/dist/images/emoji/trollface.png',\n huaji: 'https://cdn.jsdelivr.net/npm/vditor@3.8.7/dist/images/emoji/huaji.gif',\n octocat: 'https://cdn.jsdelivr.net/npm/vditor@3.8.7/dist/images/emoji/octocat.png',\n wulian: 'https://cdn.jsdelivr.net/npm/vditor@3.8.7/dist/images/emoji/wulian.png',\n smile: `https://file.${domain}/emoji/graphics/smile.png`,\n laughing: `https://file.${domain}/emoji/graphics/laughing.png`,\n blush: `https://file.${domain}/emoji/graphics/blush.png`,\n smiley: `https://file.${domain}/emoji/graphics/smiley.png`,\n relaxed: `https://file.${domain}/emoji/graphics/relaxed.png`,\n smirk: `https://file.${domain}/emoji/graphics/smirk.png`,\n heart_eyes: `https://file.${domain}/emoji/graphics/heart_eyes.png`,\n kissing_heart: `https://file.${domain}/emoji/graphics/kissing_heart.png`,\n kissing_closed_eyes: `https://file.${domain}/emoji/graphics/kissing_closed_eyes.png`,\n flushed: `https://file.${domain}/emoji/graphics/flushed.png`,\n relieved: `https://file.${domain}/emoji/graphics/relieved.png`,\n satisfied: `https://file.${domain}/emoji/graphics/satisfied.png`,\n grin: `https://file.${domain}/emoji/graphics/grin.png`,\n wink: `https://file.${domain}/emoji/graphics/wink.png`,\n stuck_out_tongue_winking_eye: `https://file.${domain}/emoji/graphics/stuck_out_tongue_winking_eye.png`,\n stuck_out_tongue_closed_eyes: `https://file.${domain}/emoji/graphics/stuck_out_tongue_closed_eyes.png`,\n grinning: `https://file.${domain}/emoji/graphics/grinning.png`,\n kissing: `https://file.${domain}/emoji/graphics/kissing.png`,\n kissing_smiling_eyes: `https://file.${domain}/emoji/graphics/kissing_smiling_eyes.png`,\n stuck_out_tongue: `https://file.${domain}/emoji/graphics/stuck_out_tongue.png`,\n sleeping: `https://file.${domain}/emoji/graphics/sleeping.png`,\n worried: `https://file.${domain}/emoji/graphics/worried.png`,\n frowning: `https://file.${domain}/emoji/graphics/frowning.png`,\n anguished: `https://file.${domain}/emoji/graphics/anguished.png`,\n open_mouth: `https://file.${domain}/emoji/graphics/open_mouth.png`,\n grimacing: `https://file.${domain}/emoji/graphics/grimacing.png`,\n confused: `https://file.${domain}/emoji/graphics/confused.png`,\n hushed: `https://file.${domain}/emoji/graphics/hushed.png`,\n expressionless: `https://file.${domain}/emoji/graphics/expressionless.png`,\n unamused: `https://file.${domain}/emoji/graphics/unamused.png`,\n sweat_smile: `https://file.${domain}/emoji/graphics/sweat_smile.png`,\n sweat: `https://file.${domain}/emoji/graphics/sweat.png`,\n disappointed_relieved: `https://file.${domain}/emoji/graphics/disappointed_relieved.png`,\n weary: `https://file.${domain}/emoji/graphics/weary.png`,\n pensive: `https://file.${domain}/emoji/graphics/pensive.png`,\n disappointed: `https://file.${domain}/emoji/graphics/disappointed.png`,\n confounded: `https://file.${domain}/emoji/graphics/confounded.png`,\n fearful: `https://file.${domain}/emoji/graphics/fearful.png`,\n cold_sweat: `https://file.${domain}/emoji/graphics/cold_sweat.png`,\n persevere: `https://file.${domain}/emoji/graphics/persevere.png`,\n cry: `https://file.${domain}/emoji/graphics/cry.png`,\n sob: `https://file.${domain}/emoji/graphics/sob.png`,\n joy: `https://file.${domain}/emoji/graphics/joy.png`,\n astonished: `https://file.${domain}/emoji/graphics/astonished.png`,\n scream: `https://file.${domain}/emoji/graphics/scream.png`,\n tired_face: `https://file.${domain}/emoji/graphics/tired_face.png`,\n angry: `https://file.${domain}/emoji/graphics/angry.png`,\n rage: `https://file.${domain}/emoji/graphics/rage.png`,\n triumph: `https://file.${domain}/emoji/graphics/triumph.png`,\n sleepy: `https://file.${domain}/emoji/graphics/sleepy.png`,\n yum: `https://file.${domain}/emoji/graphics/yum.png`,\n mask: `https://file.${domain}/emoji/graphics/mask.png`,\n sunglasses: `https://file.${domain}/emoji/graphics/sunglasses.png`,\n dizzy_face: `https://file.${domain}/emoji/graphics/dizzy_face.png`,\n imp: `https://file.${domain}/emoji/graphics/imp.png`,\n smiling_imp: `https://file.${domain}/emoji/graphics/smiling_imp.png`,\n neutral_face: `https://file.${domain}/emoji/graphics/neutral_face.png`,\n no_mouth: `https://file.${domain}/emoji/graphics/no_mouth.png`,\n innocent: `https://file.${domain}/emoji/graphics/innocent.png`,\n alien: `https://file.${domain}/emoji/graphics/alien.png`,\n yellow_heart: `https://file.${domain}/emoji/graphics/yellow_heart.png`,\n blue_heart: `https://file.${domain}/emoji/graphics/blue_heart.png`,\n purple_heart: `https://file.${domain}/emoji/graphics/purple_heart.png`,\n heart: `https://file.${domain}/emoji/graphics/heart.png`,\n green_heart: `https://file.${domain}/emoji/graphics/green_heart.png`,\n broken_heart: `https://file.${domain}/emoji/graphics/broken_heart.png`,\n heartbeat: `https://file.${domain}/emoji/graphics/heartbeat.png`,\n heartpulse: `https://file.${domain}/emoji/graphics/heartpulse.png`,\n two_hearts: `https://file.${domain}/emoji/graphics/two_hearts.png`,\n revolving_hearts: `https://file.${domain}/emoji/graphics/revolving_hearts.png`,\n cupid: `https://file.${domain}/emoji/graphics/cupid.png`,\n sparkling_heart: `https://file.${domain}/emoji/graphics/sparkling_heart.png`,\n sparkles: `https://file.${domain}/emoji/graphics/sparkles.png`,\n star: `https://file.${domain}/emoji/graphics/star.png`,\n star2: `https://file.${domain}/emoji/graphics/star2.png`,\n dizzy: `https://file.${domain}/emoji/graphics/dizzy.png`,\n boom: `https://file.${domain}/emoji/graphics/boom.png`,\n collision: `https://file.${domain}/emoji/graphics/collision.png`,\n anger: `https://file.${domain}/emoji/graphics/anger.png`,\n exclamation: `https://file.${domain}/emoji/graphics/exclamation.png`,\n question: `https://file.${domain}/emoji/graphics/question.png`,\n grey_exclamation: `https://file.${domain}/emoji/graphics/grey_exclamation.png`,\n grey_question: `https://file.${domain}/emoji/graphics/grey_question.png`,\n zzz: `https://file.${domain}/emoji/graphics/zzz.png`,\n dash: `https://file.${domain}/emoji/graphics/dash.png`,\n sweat_drops: `https://file.${domain}/emoji/graphics/sweat_drops.png`,\n notes: `https://file.${domain}/emoji/graphics/notes.png`,\n musical_note: `https://file.${domain}/emoji/graphics/musical_note.png`,\n fire: `https://file.${domain}/emoji/graphics/fire.png`,\n poop: `https://file.${domain}/emoji/graphics/poop.png`,\n '+1': `https://file.${domain}/emoji/graphics/%2B1.png`,\n thumbsup: `https://file.${domain}/emoji/graphics/thumbsup.png`,\n '-1': `https://file.${domain}/emoji/graphics/-1.png`,\n thumbsdown: `https://file.${domain}/emoji/graphics/thumbsdown.png`,\n ok_hand: `https://file.${domain}/emoji/graphics/ok_hand.png`,\n punch: `https://file.${domain}/emoji/graphics/punch.png`,\n facepunch: `https://file.${domain}/emoji/graphics/facepunch.png`,\n fist: `https://file.${domain}/emoji/graphics/fist.png`,\n v: `https://file.${domain}/emoji/graphics/v.png`,\n wave: `https://file.${domain}/emoji/graphics/wave.png`,\n hand: `https://file.${domain}/emoji/graphics/hand.png`,\n raised_hand: `https://file.${domain}/emoji/graphics/raised_hand.png`,\n open_hands: `https://file.${domain}/emoji/graphics/open_hands.png`,\n point_up: `https://file.${domain}/emoji/graphics/point_up.png`,\n point_down: `https://file.${domain}/emoji/graphics/point_down.png`,\n point_left: `https://file.${domain}/emoji/graphics/point_left.png`,\n point_right: `https://file.${domain}/emoji/graphics/point_right.png`,\n raised_hands: `https://file.${domain}/emoji/graphics/raised_hands.png`,\n pray: `https://file.${domain}/emoji/graphics/pray.png`,\n point_up_2: `https://file.${domain}/emoji/graphics/point_up_2.png`,\n clap: `https://file.${domain}/emoji/graphics/clap.png`,\n muscle: `https://file.${domain}/emoji/graphics/muscle.png`,\n couple: `https://file.${domain}/emoji/graphics/couple.png`,\n family: `https://file.${domain}/emoji/graphics/family.png`,\n two_men_holding_hands: `https://file.${domain}/emoji/graphics/two_men_holding_hands.png`,\n two_women_holding_hands: `https://file.${domain}/emoji/graphics/two_women_holding_hands.png`,\n dancer: `https://file.${domain}/emoji/graphics/dancer.png`,\n dancers: `https://file.${domain}/emoji/graphics/dancers.png`,\n ok_woman: `https://file.${domain}/emoji/graphics/ok_woman.png`,\n no_good: `https://file.${domain}/emoji/graphics/no_good.png`,\n information_desk_person: `https://file.${domain}/emoji/graphics/information_desk_person.png`,\n raising_hand: `https://file.${domain}/emoji/graphics/raising_hand.png`,\n bride_with_veil: `https://file.${domain}/emoji/graphics/bride_with_veil.png`,\n person_with_pouting_face: `https://file.${domain}/emoji/graphics/person_with_pouting_face.png`,\n person_frowning: `https://file.${domain}/emoji/graphics/person_frowning.png`,\n bow: `https://file.${domain}/emoji/graphics/bow.png`,\n couplekiss: `https://file.${domain}/emoji/graphics/couplekiss.png`,\n couple_with_heart: `https://file.${domain}/emoji/graphics/couple_with_heart.png`,\n massage: `https://file.${domain}/emoji/graphics/massage.png`,\n haircut: `https://file.${domain}/emoji/graphics/haircut.png`,\n nail_care: `https://file.${domain}/emoji/graphics/nail_care.png`,\n boy: `https://file.${domain}/emoji/graphics/boy.png`,\n girl: `https://file.${domain}/emoji/graphics/girl.png`,\n woman: `https://file.${domain}/emoji/graphics/woman.png`,\n man: `https://file.${domain}/emoji/graphics/man.png`,\n baby: `https://file.${domain}/emoji/graphics/baby.png`,\n older_woman: `https://file.${domain}/emoji/graphics/older_woman.png`,\n older_man: `https://file.${domain}/emoji/graphics/older_man.png`,\n person_with_blond_hair: `https://file.${domain}/emoji/graphics/person_with_blond_hair.png`,\n man_with_gua_pi_mao: `https://file.${domain}/emoji/graphics/man_with_gua_pi_mao.png`,\n man_with_turban: `https://file.${domain}/emoji/graphics/man_with_turban.png`,\n construction_worker: `https://file.${domain}/emoji/graphics/construction_worker.png`,\n cop: `https://file.${domain}/emoji/graphics/cop.png`,\n angel: `https://file.${domain}/emoji/graphics/angel.png`,\n princess: `https://file.${domain}/emoji/graphics/princess.png`,\n smiley_cat: `https://file.${domain}/emoji/graphics/smiley_cat.png`,\n smile_cat: `https://file.${domain}/emoji/graphics/smile_cat.png`,\n heart_eyes_cat: `https://file.${domain}/emoji/graphics/heart_eyes_cat.png`,\n kissing_cat: `https://file.${domain}/emoji/graphics/kissing_cat.png`,\n smirk_cat: `https://file.${domain}/emoji/graphics/smirk_cat.png`,\n scream_cat: `https://file.${domain}/emoji/graphics/scream_cat.png`,\n crying_cat_face: `https://file.${domain}/emoji/graphics/crying_cat_face.png`,\n joy_cat: `https://file.${domain}/emoji/graphics/joy_cat.png`,\n pouting_cat: `https://file.${domain}/emoji/graphics/pouting_cat.png`,\n japanese_ogre: `https://file.${domain}/emoji/graphics/japanese_ogre.png`,\n japanese_goblin: `https://file.${domain}/emoji/graphics/japanese_goblin.png`,\n see_no_evil: `https://file.${domain}/emoji/graphics/see_no_evil.png`,\n hear_no_evil: `https://file.${domain}/emoji/graphics/hear_no_evil.png`,\n speak_no_evil: `https://file.${domain}/emoji/graphics/speak_no_evil.png`,\n guardsman: `https://file.${domain}/emoji/graphics/guardsman.png`,\n skull: `https://file.${domain}/emoji/graphics/skull.png`,\n feet: `https://file.${domain}/emoji/graphics/feet.png`,\n lips: `https://file.${domain}/emoji/graphics/lips.png`,\n kiss: `https://file.${domain}/emoji/graphics/kiss.png`,\n droplet: `https://file.${domain}/emoji/graphics/droplet.png`,\n ear: `https://file.${domain}/emoji/graphics/ear.png`,\n eyes: `https://file.${domain}/emoji/graphics/eyes.png`,\n nose: `https://file.${domain}/emoji/graphics/nose.png`,\n tongue: `https://file.${domain}/emoji/graphics/tongue.png`,\n love_letter: `https://file.${domain}/emoji/graphics/love_letter.png`,\n bust_in_silhouette: `https://file.${domain}/emoji/graphics/bust_in_silhouette.png`,\n busts_in_silhouette: `https://file.${domain}/emoji/graphics/busts_in_silhouette.png`,\n speech_balloon: `https://file.${domain}/emoji/graphics/speech_balloon.png`,\n thought_balloon: `https://file.${domain}/emoji/graphics/thought_balloon.png`,\n };\n }\n\n async get(): Promise<string[]> {\n let rsp;\n try {\n rsp = await request({\n url: `api/cloud/get`,\n method: 'post',\n data: {\n gameId: 'emojis',\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n this.emojis = JSON.parse(rsp.data);\n return this.emojis.concat([]);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 设置表情包列表\n * @param data 所有表情包图像列表\n */\n async set(data: string[]) {\n let rsp;\n try {\n rsp = await request({\n url: `api/cloud/sync`,\n method: 'post',\n data: {\n gameId: 'emojis',\n data: JSON.stringify(data),\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp;\n } catch (e) {\n throw e;\n }\n }\n\n async append(url: string): Promise<string[]> {\n let emojis = this.emojis.length > 0 ? this.emojis : await this.get();\n if (emojis.indexOf(url) >= 0) throw new Error('表情包已存在');\n emojis.push(url);\n await this.set(emojis);\n this.emojis = emojis;\n return emojis.concat([]);\n }\n\n async remove(url: string): Promise<string[]> {\n let emojis = this.emojis.length > 0 ? this.emojis : await this.get();\n if (emojis.indexOf(url) < 0) return emojis;\n emojis.splice(emojis.indexOf(url), 1);\n await this.set(emojis);\n this.emojis = emojis;\n return emojis.concat([]);\n }\n\n async exists(url: string): Promise<Boolean> {\n let emojis = this.emojis.length > 0 ? this.emojis : await this.get();\n return emojis.indexOf(url) >= 0;\n }\n}\n","import { UserInfo, UserUpdateParams } from './';\nimport { request, toMetal } from './utils';\n\nexport class User {\n private apiKey: string = '';\n\n constructor(token: string = '') {\n if (!token) {\n return;\n }\n this.apiKey = token;\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(token: string) {\n this.apiKey = token;\n }\n\n /**\n * 返回登录账户信息,需要先登录或设置有效的 api key\n * @returns 用户信息\n */\n async info(): Promise<UserInfo> {\n try {\n let rsp = await request({\n url: `api/user?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n if (rsp.data) rsp.data.sysMetal = toMetal(rsp.data.sysMetal);\n\n return UserInfo.from(rsp.data);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询登录用户常用表情\n * @returns 常用表情列表\n */\n async emotions(): Promise<Array<string>> {\n let rsp;\n try {\n rsp = await request({\n url: `users/emotions?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n rsp.data = Object.keys(rsp.data);\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询登录用户当前活跃度,请求频率请控制在 30 ~ 60 秒一次\n * @returns 活跃度\n */\n async liveness(): Promise<number> {\n if (!this.apiKey) {\n return 0;\n }\n try {\n let rsp = await request({\n url: `user/liveness?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.liveness || 0;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 检查登录用户是否已经签到\n * @returns 是否已经签到\n */\n async isCheckIn(): Promise<boolean> {\n if (!this.apiKey) {\n return false;\n }\n try {\n let rsp = await request({\n url: `user/checkedIn?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.checkedIn || false;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 检查登录用户是否已经领取昨日活跃奖励\n * @returns 是否已经领取昨日活跃奖励\n */\n async isCollectedLiveness(): Promise<boolean> {\n if (!this.apiKey) {\n return false;\n }\n try {\n let rsp = await request({\n url: `api/activity/is-collected-liveness?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.isCollectedYesterdayLivenessReward || false;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 领取昨日活跃度奖励\n * @returns sum 领取的奖励积分\n */\n async rewardLiveness(): Promise<number> {\n if (!this.apiKey) {\n return 0;\n }\n try {\n let rsp = await request({\n url: `activity/yesterday-liveness-reward-api?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.sum || 0;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 转账\n * @param userName 转账目标用户名\n * @param amount 转账金额\n * @param memo 转账备注\n * @returns code 0 为成功,失败则有 msg\n */\n async transfer(userName: string, amount: number, memo: string): Promise<void> {\n try {\n let rsp = await request({\n method: 'POST',\n url: `point/transfer`,\n data: {\n apiKey: this.apiKey,\n userName,\n amount,\n memo,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 关注用户\n * @param followingId 用户id\n */\n async follow(followingId: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `follow/user`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n followingId,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 取消关注用户\n * @param followingId 用户id\n */\n async unfollow(followingId: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `unfollow/user`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n followingId,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 修改用户头像\n * @param userAvatarURL 用户头像地址\n */\n async updateUserAvatar(userAvatarURL: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `api/settings/avatar`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n userAvatarURL,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 修改用户信息\n * @param data 用户信息参数\n */\n async updateUserInfo(data: UserUpdateParams): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `api/settings/profiles`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n ...data,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n}\n","import { domain, request, WebSocket } from './utils';\nimport ReconnectingWebSocket from 'reconnecting-websocket';\nimport {\n ArticleListType,\n ArticlePost,\n ArticleType,\n ArticleDetail,\n ArticleList,\n VoteType,\n IArticlePost,\n IArticleHeat,\n ArticleComment,\n} from './';\nimport { IWebSocketEvent, WsEventBase } from './ws';\n\ninterface IArticleEvents extends IWebSocketEvent {\n heat: (msg: IArticleHeat) => void;\n comment: (msg: ArticleComment) => void;\n}\n\nexport class Article {\n private apiKey: string = '';\n private channels: { [key: string]: ArticleChannel } = {};\n\n constructor(token: string = '') {\n if (!token) {\n return;\n }\n this.apiKey = token;\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(token: string) {\n this.apiKey = token;\n }\n\n /**\n * 发布文章\n * @param data 文章信息\n * @returns 发布成功返回文章Id (articleId)\n */\n async post(data: IArticlePost): Promise<string> {\n let rsp;\n try {\n rsp = await request({\n url: `article`,\n method: 'post',\n data: {\n ...ArticlePost.from(data).toJson(),\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.articleId;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 更新文章\n * @param id 文章 Id\n * @param data 文章信息\n * @returns 更新成功返回文章Id (articleId)\n */\n async update(id: string, data: IArticlePost): Promise<string> {\n let rsp;\n try {\n rsp = await request({\n url: `article/${id}`,\n method: 'put',\n data: {\n ...ArticlePost.from(data).toJson(),\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.articleId;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询文章列表\n * @param type 查询类型\n * @param tag 指定查询标签,可选\n * @returns 文章列表\n */\n async list({\n type,\n page = 1,\n size = 20,\n tag,\n }: {\n type: ArticleListType;\n page?: number;\n size?: number;\n tag?: string;\n }): Promise<ArticleList> {\n let rsp;\n try {\n rsp = await request({\n url: `api/articles/${\n tag ? `tag/${tag}` : 'recent'\n }${type}?p=${page}&size=${size}&${this.apiKey ? `apiKey=${this.apiKey}` : ''}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return ArticleList.from(rsp.data);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询用户文章列表\n * @param userName 用户名\n * @param page 页码\n * @returns 文章列表\n */\n async userArticles({\n userName,\n page = 1,\n size = 20,\n }: {\n userName: string;\n page?: number;\n size?: number;\n }): Promise<ArticleList> {\n let rsp;\n try {\n rsp = await request({\n url: `api/user/${userName}/articles?p=${page}&size=${size}&${\n this.apiKey ? `apiKey=${this.apiKey}` : ''\n }`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return ArticleList.from(rsp.data);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取文章详情\n * @param id 文章id\n * @returns 文章详情\n */\n async detail(id: string, p = 1): Promise<ArticleDetail> {\n let rsp;\n try {\n rsp = await request({\n url: `api/article/${id}?apiKey=${this.apiKey}&p=${p}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return ArticleDetail.from(rsp.data.article);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 点赞/取消点赞文章\n * @param id 文章id\n * @param type 点赞类型\n * @returns 文章点赞状态\n */\n async vote(id: string, type: 'up' | 'down'): Promise<VoteType> {\n let rsp;\n try {\n rsp = await request({\n url: `vote/${type}/article`,\n method: 'post',\n data: {\n dataId: id,\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.type;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 感谢文章\n * @param id 文章id\n */\n async thank(id: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `article/thank?articleId=${id}`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 收藏文章\n * @param followingId 文章id\n */\n async follow(followingId: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `follow/article`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n followingId,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 取消收藏文章\n * @param followingId 文章id\n */\n async unfollow(followingId: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `unfollow/article`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n followingId,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 关注文章\n * @param followingId 文章id\n */\n async watch(followingId: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `follow/article-watch`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n followingId,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 取消关注文章\n * @param followingId 文章id\n */\n async unwatch(followingId: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `unfollow/article-watch`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n followingId,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 打赏文章\n * @param id 文章id\n */\n async reward(id: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `article/reward?articleId=${id}`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取文章在线人数\n * @param id 文章id\n */\n async heat(id: string): Promise<number> {\n let rsp;\n try {\n rsp = await request({\n url: `api/article/heat/${id}?apiKey=${this.apiKey}`,\n method: 'get',\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.articleHeat;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取帖子的Markdown原文\n * @param articleId 文章Id\n */\n async md(articleId: string): Promise<string> {\n let rsp;\n try {\n rsp = await request({\n url: `api/article/md/${articleId}?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp;\n } catch (e) {\n throw e;\n }\n }\n\n channel(id: string, type: ArticleType): ArticleChannel {\n if (!this.channels[id]) this.channels[id] = new ArticleChannel(this.apiKey, id, type);\n return this.channels[id];\n }\n}\n\nexport class ArticleChannel extends WsEventBase<IArticleEvents> {\n private apiKey: string = '';\n private id: string = '';\n private type: ArticleType = ArticleType.Normal;\n\n constructor(token: string, id: string, type: ArticleType) {\n super();\n if (!token) {\n return;\n }\n this.apiKey = token;\n }\n /**\n * 添加文章监听器\n * @param id 文章id\n * @param type 文章类型\n * @param callback 监听回调\n */\n async connect(reload?: boolean): Promise<ReconnectingWebSocket> {\n return new Promise(async (resolve, reject) => {\n if (this.ws && !reload) return resolve(this.ws);\n if (this.ws) this.ws.close();\n if (!this.apiKey) return reject(new Error('请先设置 API Key'));\n\n this.ws = new ReconnectingWebSocket(\n `wss://${domain}/article-channel?articleId=${this.id}&articleType=${this.type}&apiKey=${this.apiKey}`,\n [],\n {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n WebSocket,\n connectionTimeout: 10000,\n },\n );\n\n this.ws.onopen = (e) => {\n this.emitter.emit('open', e);\n };\n this.ws.onmessage = (ev: MessageEvent) => {\n let msg = JSON.parse(ev.data);\n let eventType = msg.type;\n if (eventType === 'articleHeat') {\n this.emitter.emit('heat', msg.data);\n } else {\n this.emitter.emit(msg.type, ArticleComment.from(msg.data));\n }\n };\n this.ws.onerror = (e) => {\n this.emitter.emit('error', e);\n };\n this.ws.onclose = (e) => {\n this.emitter.emit('close', e);\n };\n return this.ws;\n });\n }\n}\n","import { CommentPost, ICommentPost, VoteType } from './';\nimport { request } from './utils';\n\nexport class Comment {\n private apiKey: string = '';\n\n constructor(token: string = '') {\n if (!token) {\n return;\n }\n this.apiKey = token;\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(token: string) {\n this.apiKey = token;\n }\n\n /**\n * 发布评论\n * @param data 评论信息\n */\n async send(data: ICommentPost): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `comment`,\n method: 'post',\n data: {\n ...CommentPost.from(data).toJson(),\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 更新评论\n * @param id 评论 Id\n * @param data 评论信息\n */\n async update(id: string, data: ICommentPost): Promise<string> {\n let rsp;\n try {\n rsp = await request({\n url: `comment/${id}`,\n method: 'put',\n data: {\n ...CommentPost.from(data).toJson(),\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.commentContent;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 评论点赞\n * @param id 评论 Id\n * @param type 点赞类型\n */\n async vote(id: string, type: 'up' | 'down'): Promise<VoteType> {\n let rsp;\n try {\n rsp = await request({\n url: `vote/${type}/comment`,\n method: 'post',\n data: {\n dataId: id,\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.type;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 评论感谢\n * @param id 评论 Id\n */\n async thank(id: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `comment/thank`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n commentId: id,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 删除评论\n * @param id 评论 Id\n */\n async remove(id: string): Promise<string> {\n let rsp;\n try {\n rsp = await request({\n url: `comment/${id}/remove`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.commentId;\n } catch (e) {\n throw e;\n }\n }\n}\n","import ReconnectingWebSocket from 'reconnecting-websocket';\nimport { request, domain, WebSocket } from './utils';\nimport { IChatData, IChatQuery } from '.';\nimport { IWebSocketEvent, WsEventBase } from './ws';\n\ninterface IChatEvents extends IWebSocketEvent {\n /**\n * 私聊消息\n * @param msg 私聊消息内容\n */\n data: (msg: IChatData) => void;\n /**\n * 撤回消息\n * @param oId 消息 ID\n */\n revoke: (oId: string) => void;\n}\n\nclass ChatChannel extends WsEventBase<IChatEvents> {\n private apiKey: string = '';\n private user = '';\n\n constructor(user: string, apiKey: string) {\n super();\n this.apiKey = apiKey;\n this.user = user;\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(apiKey: string) {\n this.apiKey = apiKey;\n this.connect(true);\n }\n\n /**\n * 连接用户私聊频道\n * @returns Websocket 连接对象\n */\n connect(reload = false): Promise<ReconnectingWebSocket> {\n return new Promise(async (resolve, reject) => {\n if (this.ws && !reload) return resolve(this.ws);\n if (this.ws) this.ws.close();\n if (!this.user) return reject(new Error('请先设置私聊用户名'));\n if (!this.apiKey) return reject(new Error('请先设置 API Key'));\n this.ws = new ReconnectingWebSocket(\n `wss://${domain}/chat-channel?apiKey=${this.apiKey}&toUser=${this.user}`,\n [],\n {\n WebSocket,\n connectionTimeout: 10000,\n },\n );\n this.ws.onopen = (e) => {\n resolve(this.ws!);\n };\n this.ws.onmessage = async (e) => {\n let msg = JSON.parse(e.data);\n let type = 'data';\n if (msg.type == 'revoke') {\n type = 'revoke';\n msg = msg.data;\n }\n this.emitter.emit(type, msg);\n };\n this.ws.onerror = (e) => {\n this.emitter.emit('error', e);\n };\n this.ws.onclose = (e) => {\n this.emitter.emit('close', e);\n };\n });\n }\n\n async send(msg: string) {\n if (this.ws == null) {\n await this.connect();\n }\n if (this.user) this.ws?.send(msg);\n }\n\n close() {\n this.ws?.close();\n }\n\n /**\n * 获取用户私聊历史消息\n * @param param 消息参数\n * @returns 私聊消息列表\n */\n async get({ page = 1, size = 20, autoRead = true }: IChatQuery): Promise<IChatData[]> {\n if (!this.user) return [];\n try {\n let rsp = await request({\n url: `chat/get-message?apiKey=${this.apiKey}&toUser=${this.user}&page=${page}&pageSize=${size}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n if (autoRead) this.markRead();\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 标记用户消息已读\n * @param user 用户名\n * @returns 执行结果\n */\n async markRead(): Promise<void> {\n if (!this.user) return;\n try {\n let rsp = await request({\n url: `chat/mark-as-read?apiKey=${this.apiKey}&fromUser=${this.user}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n}\n\nexport class Chat {\n private apiKey: string = '';\n private chats: { [key: string]: ChatChannel } = {};\n\n constructor(token: string = '') {\n if (!token) {\n return;\n }\n this.apiKey = token;\n }\n\n /**\n * 获取私聊频道\n * @param user 私聊用户名\n * @returns 私聊频道\n */\n channel(user: string) {\n if (!this.chats[user]) this.chats[user] = new ChatChannel(user, this.apiKey);\n return this.chats[user];\n }\n\n /**\n * 关闭私聊频道\n * @param user 私聊用户名\n */\n close(user: string = '') {\n if (user) {\n this.chats[user]?.close();\n delete this.chats[user];\n return;\n }\n Object.values(this.chats).forEach((c) => c.close());\n this.chats = {};\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(apiKey: string) {\n this.apiKey = apiKey;\n Object.values(this.chats).forEach((c) => c.setToken(apiKey));\n }\n\n /**\n * 获取有私聊用户列表以及第一条消息\n * @returns 私聊消息列表\n */\n async list(): Promise<IChatData[]> {\n try {\n let rsp = await request({\n url: `chat/get-list?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取未读消息\n * @returns 未读消息列表\n */\n async unread(): Promise<IChatData> {\n try {\n let rsp = await request({\n url: `chat/has-unread?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 撤回私聊消息\n * @param msgId 消息 ID\n */\n async revoke(msgId: string): Promise<number> {\n try {\n let rsp = await request({\n url: `chat/revoke?apiKey=${this.apiKey}&oId=${msgId}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.result;\n } catch (e) {\n throw e;\n }\n }\n}\n","import { BreezemoonContent, BreezemoonList } from '.';\nimport { request } from './utils';\n\nexport class Breezemoon {\n private apiKey: string = '';\n\n constructor(token: string = '') {\n if (!token) {\n return;\n }\n this.apiKey = token;\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(token: string) {\n this.apiKey = token;\n }\n\n /**\n * 获取清风明月列表\n * @param page 消息页码\n * @param size 每页个数\n */\n async list(page = 1, size = 20): Promise<BreezemoonContent[]> {\n try {\n let rsp = await request({\n url: `api/breezemoons?p=${page}&size=${size}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.breezemoons.map((b: any) => BreezemoonContent.from(b));\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取用户清风明月列表\n * @param user 用户名\n * @param page 消息页码\n * @param size 每页个数\n */\n async listByUser(user: string, page = 1, size = 20): Promise<BreezemoonList> {\n try {\n let rsp = await request({\n url: `api/user/${user}/breezemoons?p=${page}&size=${size}&apiKey=${this.apiKey}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return BreezemoonList.from(rsp.data);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 发送清风明月\n * @param content 内容\n */\n async send(content: string): Promise<void> {\n try {\n let rsp = await request({\n url: `breezemoon`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n breezemoonContent: content,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n}\n","import { IUserBag, IUserIP, MetalBase } from './';\nimport { request } from './utils';\n\nexport class Finger {\n private goldFingerKey: string = '';\n\n constructor(key: string) {\n if (!key) {\n return;\n }\n this.goldFingerKey = key;\n }\n\n /**\n * 设置金手指\n * @param key 金手指密钥\n */\n setFinger(key: string) {\n this.goldFingerKey = key;\n }\n\n /**\n * 上传摸鱼大闯关关卡数据\n * @param userName: 用户在摸鱼派的用户名\n * @param stage: 关卡数\n * @param time: 通过此关时间(毫秒级时间戳)\n */\n async addMofishScore({\n userName,\n stage,\n time = new Date().getTime(),\n }: {\n userName: string;\n stage: string;\n time: number;\n }): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `api/games/mofish/score`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n stage,\n time,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询用户最近登录的IP地址\n * @param userName: 用户在摸鱼派的用户名\n */\n async queryLatestLoginIP(userName: string): Promise<IUserIP> {\n let rsp;\n try {\n rsp = await request({\n url: `user/query/latest-login-iP`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 添加勋章\n * @param userName: 用户在摸鱼派的用户名\n * @param metal: 勋章信息\n */\n async addMetal(userName: string, metal: MetalBase): Promise<void> {\n let rsp;\n metal = new MetalBase(metal);\n try {\n rsp = await request({\n url: `user/edit/give-metal`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n ...metal,\n attr: metal.attr.toString(),\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 删除勋章\n * @param userName: 用户在摸鱼派的用户名\n * @param name: 勋章名称\n */\n async deleteMetal(userName: string, name: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `user/edit/remove-metal`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n name,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 删除勋章By userId\n * @param userId: 用户在摸鱼派的用户ID\n * @param name: 勋章名称\n */\n async deleteMetalByUserId(userId: string, name: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `user/edit/remove-metal-by-user-id`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userId,\n name,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询用户背包\n * @param userName: 用户在摸鱼派的用户名\n */\n async queryUserBag(userName: string): Promise<IUserBag> {\n let rsp;\n try {\n rsp = await request({\n url: `user/query/items`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 调整用户背包\n * @param userName: 用户在摸鱼派的用户名\n * @param item: 物品名称\n * @param sum: 物品数量\n */\n async editUserBag(userName: string, item: string, sum: number): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `user/edit/items`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n item,\n sum,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 调整用户积分\n * @param userName: 用户在摸鱼派的用户名\n * @param point: 积分数量\n * @param memo: 备注\n */\n async editUserPoints(userName: string, point: number, memo: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `user/edit/points`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n point,\n memo,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询用户当前活跃度\n * @param userName: 用户在摸鱼派的用户名\n */\n async getLiveness(userName: string): Promise<number> {\n let rsp;\n try {\n rsp = await request({\n url: `user/liveness`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n },\n });\n\n if (rsp.code !== 0) throw new Error(rsp.msg);\n\n return rsp.liveness;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询用户昨日活跃度奖励\n * @param userName: 用户在摸鱼派的用户名\n */\n async getYesterDayLivenessReward(userName: string): Promise<number> {\n let rsp;\n try {\n rsp = await request({\n url: `activity/yesterday-liveness-reward-api`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n },\n });\n\n return rsp.sum;\n } catch (e) {\n throw e;\n }\n }\n}\n","import FormData from 'form-data';\nimport fs from 'fs';\nimport path from 'path';\nimport md5 from 'js-md5';\nimport { domain, isBrowse, request, setDomain, toMetal } from './utils';\nimport { ChatRoom, Notice, Emoji, User, Article, Comment, Chat, Breezemoon, Finger } from './';\nimport {\n IAtUser,\n ILog,\n IUploadInfo,\n IReport,\n UserInfo,\n Account,\n PreRegisterInfo,\n RegisterInfo,\n} from './';\nimport { IUserLite, UserVIP } from './types';\n\nexport class FishPi {\n /**\n * 请求 API 的 API Key\n */\n private apiKey: string = '';\n /**\n * 聊天室接口对象\n */\n readonly chatroom: ChatRoom = new ChatRoom();\n /**\n * 通知接口对象\n */\n readonly notice: Notice = new Notice();\n /**\n * 表情包接口对象\n */\n readonly emoji: Emoji = new Emoji();\n /**\n * 用户接口对象\n */\n readonly account: User = new User();\n /**\n * 文章接口对象\n */\n readonly article: Article = new Article();\n /**\n * 评论接口对象\n */\n readonly comment: Comment = new Comment();\n /**\n * 清风明月对象\n */\n readonly breezemoon: Breezemoon = new Breezemoon();\n /**\n * 私聊接口对象\n */\n readonly chat: Chat = new Chat();\n\n /**\n * 构造一个 API 请求对象\n * @param token 接口 API Key,没有可以传空\n */\n constructor(token: string = '') {\n if (!token) {\n return;\n }\n this.setToken(token);\n }\n\n get version() {\n return JSON.parse(fs.readFileSync(path.resolve(__dirname, '../package.json'), 'utf-8')).version;\n }\n\n async setToken(apiKey: string) {\n this.apiKey = apiKey;\n this.chatroom.setToken(this.apiKey);\n this.notice.setToken(this.apiKey);\n this.emoji.setToken(this.apiKey);\n this.account.setToken(this.apiKey);\n this.article.setToken(this.apiKey);\n this.comment.setToken(this.apiKey);\n this.breezemoon.setToken(this.apiKey);\n this.chat.setToken(this.apiKey);\n }\n\n async setDomain(domain: string) {\n setDomain(domain);\n }\n\n /**\n * 登录账号返回 API Key\n * @param data 用户账密\n */\n async login(data: Account): Promise<string> {\n try {\n let rsp = await request({\n url: 'api/getKey',\n method: 'post',\n data: {\n nameOrEmail: data.username,\n userPassword: md5(data.passwd),\n mfaCode: data.mfaCode,\n },\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n this.setToken(rsp.Key);\n\n return rsp.Key;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 预注册账号\n * @param data 用户信息\n * @returns\n */\n async preRegister(data: PreRegisterInfo): Promise<void> {\n try {\n let rsp = await request({\n url: 'register',\n method: 'post',\n data: {\n userName: data.username,\n userPhone: data.phone,\n invitecode: data.invitecode,\n captcha: data.captcha,\n },\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 验证手机验证码\n * @param code 验证码\n * @returns\n */\n async verify(code: string): Promise<number> {\n try {\n let rsp = await request({\n url: 'verify?code=' + code,\n method: 'get',\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n return rsp.userId;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 注册账号\n */\n async register(data: RegisterInfo): Promise<void> {\n try {\n let rsp = await request({\n url: `register2${data.r ? `?r=${data.r}` : ''}`,\n method: 'post',\n data: {\n userAppRole: data.role,\n userPassword: md5(data.passwd),\n userId: data.userId,\n },\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询指定用户信息\n * @param username 用户名\n */\n async user(username: string): Promise<UserInfo | undefined> {\n try {\n let rsp = await request({\n url: `user/${username}${this.apiKey ? `?apiKey=${this.apiKey}` : ''}`,\n });\n\n if (rsp.code && rsp.code !== 0) return;\n\n return UserInfo.from(rsp);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询指定用户积分\n * @param username 用户名\n * @returns 用户积分\n */\n async userPoints(username: string): Promise<number> {\n try {\n let rsp = await request({\n url: `user/${username}/point`,\n });\n\n if (rsp.code && rsp.code !== 0) return 0;\n\n return rsp.data.userPoint;\n } catch (e) {\n throw e;\n }\n }\n /**\n * 查询指定用户 oId 的用户信息\n */\n async userByoId(oId: string): Promise<IUserLite | undefined> {\n try {\n let rsp = await request({\n url: `api/user/getInfoById?userId=${oId}`,\n });\n\n if (rsp.code && rsp.code !== 0) return;\n\n return { ...rsp.data, oId };\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 用户名联想,通常用于 @ 列表\n * @param username 用户名\n */\n async names(name: string): Promise<IAtUser[]> {\n let rsp;\n try {\n rsp = await request({\n url: `users/names`,\n method: 'post',\n data: {\n name,\n },\n });\n\n return rsp.data || [];\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取最近注册的20个用户\n */\n async recentRegister(): Promise<{ userNickname: string; userName: string }[]> {\n let rsp;\n try {\n rsp = await request({\n url: `api/user/recentReg`,\n method: 'get',\n });\n\n return rsp.data || [];\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取用户 VIP 信息\n * @param userId 用户 oId\n */\n async vipInfo(userId: string): Promise<UserVIP> {\n let rsp;\n try {\n rsp = await request({\n url: `api/membership/${userId}`,\n method: 'get',\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n if (rsp.data.config) {\n rsp.data.config = JSON.parse(rsp.data.config);\n }\n\n return UserVIP.from(rsp.data);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 举报\n * @param data 举报信息\n */\n async report(data: IReport): Promise<void> {\n try {\n let rsp = await request({\n url: `report`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n ...data,\n },\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n return rsp;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取操作日志\n * @param page 页码\n * @param pageSize 每页数量\n */\n async log({ page = 1, pageSize = 30 }): Promise<ILog[]> {\n try {\n let rsp = await request({\n url: `/logs/more?page=${page}&pageSize=${pageSize}`,\n method: 'get',\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 上传文件\n * @param files 要上传的文件,如果是在 Node 使用,则传入文件路径数组,若是在浏览器使用,则传入文件对象数组。\n */\n async upload(files: Array<File | string>): Promise<IUploadInfo> {\n let data: any;\n\n if (isBrowse) {\n data = new FormData();\n files.forEach((f) => data.append('file[]', f));\n } else {\n data = new FormData();\n files.forEach((f) =>\n data.append('file[]', fs.readFileSync(f.toString()), path.basename(f.toString())),\n );\n }\n\n data.append('apiKey', this.apiKey);\n\n let rsp;\n try {\n rsp = await request({\n url: `upload`,\n method: 'post',\n data,\n headers: isBrowse ? undefined : data.getHeaders(),\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 生成登录认证地址\n * @param redirect 登录成功后跳转的地址\n */\n generateAuthURL(redirect: string): string {\n const redirectOrigin = new URL(redirect).origin;\n return `https://${domain}/openid/login?openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.mode=checkid_setup&openid.return_to=${encodeURIComponent(redirect)}&openid.realm=${encodeURIComponent(redirectOrigin)}&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select`;\n }\n\n /**\n * 校验登录回调\n * @param query 验证返回的地址 QueryString 参数\n * @returns 验证成功则返回用户简略信息,否则返回 undefined\n */\n async authVerify(query: Record<string, string>): Promise<IUserLite | undefined> {\n const openVerify = {\n 'openid.ns': 'http://specs.openid.net/auth/2.0',\n 'openid.mode': 'check_authentication',\n 'openid.op_endpoint': query['openid.op_endpoint'],\n 'openid.return_to': query['openid.return_to'],\n 'openid.identity': query['openid.identity'],\n 'openid.claimed_id': query['openid.claimed_id'],\n 'openid.response_nonce': query['openid.response_nonce'],\n 'openid.assoc_handle': query['openid.assoc_handle'],\n 'openid.sig': query['openid.sig'],\n };\n let rsp;\n try {\n rsp = await request({\n url: `openid/verify`,\n method: 'post',\n data: openVerify,\n });\n\n if (rsp.includes('is_valid:true')) {\n const claimed_id = query['openid.claimed_id']?.split('/').pop();\n if (!claimed_id) return;\n return await this.userByoId(claimed_id);\n } else {\n return;\n }\n } catch (e) {\n throw e;\n }\n }\n}\n\nexport * from './chatroom';\nexport * from './notice';\nexport * from './emoji';\nexport * from './user';\nexport * from './article';\nexport * from './comment';\nexport * from './chat';\nexport * from './breezemoon';\nexport * from './finger';\nexport * from './types';\n\nexport function FingerTo(key: string) {\n return new Finger(key);\n}\n\nexport default FishPi;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["NodeEventEmitter","ReconnectingWebSocket","ReconnectingWebSocket","ReconnectingWebSocket","ReconnectingWebSocket"],"sources":["../src/utils.ts","../src/types/article.ts","../src/types/breezemoon.ts","../src/types/chatroom.ts","../src/types/redpacket.ts","../src/types/user.ts","../src/types/finger.ts","../src/types/notice.ts","../src/types/index.ts","../src/ws.ts","../src/chatroom.ts","../src/notice.ts","../src/emoji.ts","../src/user.ts","../src/article.ts","../src/comment.ts","../src/chat.ts","../src/breezemoon.ts","../src/finger.ts","../src/index.ts"],"sourcesContent":["import { Metal } from './';\nimport ws from 'ws';\nimport { EventEmitter as NodeEventEmitter } from 'events';\n\nif (!globalThis.FormData) {\n import('form-data')\n .then((mod) => {\n (globalThis as any).FormData = mod.default;\n })\n .catch((err) => {\n console.error('Failed to load form-data module:', err);\n });\n}\n\nlet domain = 'fishpi.cn';\n\nfunction setDomain(d: string) {\n domain = d;\n}\n\nasync function request(opt: any) {\n let { url, method = 'get', headers = {}, data } = opt;\n\n if (!isBrowse) {\n headers['User-Agent'] =\n `Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36`;\n headers['Referer'] = `https://${domain}/`;\n }\n\n let body = undefined;\n\n if (data instanceof FormData) {\n body = data;\n } else {\n body = JSON.stringify(data);\n }\n\n let options: any = {\n method,\n headers,\n body,\n };\n\n let rsp: any;\n try {\n rsp = fetch(`https://${domain}/${url}`, options)\n .then((res: Response) => res.text())\n .then((res: string) => {\n try {\n return JSON.parse(res);\n } catch (err) {\n return res;\n }\n });\n return rsp;\n } catch (err) {\n if ((err as any).response.status === 401) {\n return (err as any).response;\n }\n throw err;\n }\n}\n\nfunction analyzeMetalAttr(m: any): Metal {\n if (!m) return m;\n if (typeof m.attr != 'string') return m;\n let attr = m.attr.split('&');\n let src = m.attr;\n m.attr = { src };\n attr.forEach((a: string) => (m.attr[a.split('=')[0]] = a.split('=')[1]));\n m.url = `https://${domain}/gen?txt=${m.description}&url=${m.attr.src}`;\n m.icon = `https://${domain}/gen?txt=&${m.attr.src}`;\n return m;\n}\n\nfunction toMetal(sysMetal: string): Metal[] {\n try {\n let metal: { list: Array<any> } = JSON.parse(sysMetal);\n metal.list.forEach((m, i, list) => {\n list[i] = analyzeMetalAttr(m);\n });\n return metal.list;\n } catch (error) {\n return [];\n }\n}\n\nfunction clientToVia(client: string) {\n if (!client) return;\n const via = client.split('/');\n return { client: via[0], version: via[1] };\n}\n\nconst isBrowse = typeof window !== 'undefined';\n\nconst WebSocket = isBrowse ? window.WebSocket : ws.WebSocket;\n\n// 浏览器兼容的 EventEmitter\nclass BrowserEventEmitter {\n public listeners: Map<string, Function[]> = new Map();\n\n on(event: string, listener: Function) {\n if (!this.listeners.has(event)) {\n this.listeners.set(event, []);\n }\n this.listeners.get(event)!.push(listener);\n return this;\n }\n\n off(event: string, listener: Function) {\n const listeners = this.listeners.get(event);\n if (listeners) {\n const index = listeners.indexOf(listener);\n if (index > -1) {\n listeners.splice(index, 1);\n }\n }\n return this;\n }\n\n once(event: string, listener: Function) {\n const onceListener = (...args: any[]) => {\n this.off(event, onceListener);\n listener(...args);\n };\n this.on(event, onceListener);\n return this;\n }\n\n emit(event: string, ...args: any[]) {\n const listeners = this.listeners.get(event);\n if (listeners) {\n listeners.forEach((listener) => listener(...args));\n }\n return this;\n }\n\n removeAllListeners(event?: string) {\n if (event) {\n this.listeners.delete(event);\n } else {\n this.listeners.clear();\n }\n return this;\n }\n}\n\nconst EventEmitter = isBrowse ? BrowserEventEmitter : NodeEventEmitter;\n\nexport {\n request,\n domain,\n toMetal,\n analyzeMetalAttr,\n isBrowse,\n setDomain,\n clientToVia,\n WebSocket,\n EventEmitter,\n};\n","import { IMetal, Pagination } from '.';\n\n/**\n * 发帖信息\n */\nexport class ArticlePost implements IArticlePost {\n /**\n * 帖子标题\n */\n title: string = '';\n /**\n * 帖子内容\n */\n content: string = '';\n /**\n * 帖子标签\n */\n tags: string = '';\n /**\n * 是否允许评论\n */\n commentable: boolean = true;\n /**\n * 是否通知帖子关注者\n */\n isNotifyFollowers: boolean = false;\n /**\n * 帖子类型\n */\n type: ArticleType = ArticleType.Normal;\n /**\n * 是否在列表展示\n */\n isShowInList = true;\n /**\n * 打赏内容\n */\n rewardContent?: string;\n /**\n * 打赏积分\n */\n rewardPoint?: number;\n /**\n * 是否匿名\n */\n isAnonymous?: boolean;\n /**\n * 提问悬赏积分\n */\n offerPoint?: number;\n\n static from(article: IArticlePost) {\n return Object.assign(new ArticlePost(), article);\n }\n\n toJson() {\n return {\n articleTitle: this.title,\n articleContent: this.content,\n articleTags: this.tags,\n articleCommentable: this.commentable,\n articleNotifyFollowers: this.isNotifyFollowers,\n articleType: this.type,\n articleShowInList: this.isShowInList ? 1 : 0,\n articleRewardContent: this.rewardContent,\n articleRewardPoint: this.rewardPoint,\n articleAnonymous: this.isAnonymous,\n articleQnAOfferPoint: this.offerPoint,\n };\n }\n}\n\nexport class CommentPost implements ICommentPost {\n /**\n * 文章 Id\n */\n articleId: string = '';\n /**\n * 是否匿名评论\n */\n isAnonymous: boolean = false;\n /**\n * 评论是否公共可见\n */\n isVisible: boolean = true;\n /**\n * 评论内容\n */\n content: string = '';\n /**\n * 回复评论 Id\n */\n originalId?: string;\n\n static from(comment: ICommentPost) {\n return Object.assign(new CommentPost(), comment);\n }\n\n toJson() {\n return {\n articleId: this.articleId,\n commentAnonymous: this.isAnonymous ? 1 : 0,\n commentVisible: this.isVisible ? 1 : 0,\n commentContent: this.content,\n commentOriginalCommentId: this.originalId,\n };\n }\n}\n\n/**\n * 帖子类型\n */\nexport enum ArticleType {\n Normal,\n Private,\n Broadcast,\n Thought,\n Question = 5,\n}\n\n/**\n * 公开状态\n */\nexport enum PublicStatus {\n Public,\n Private,\n}\n\n/**\n * 投票状态,点赞与否\n */\nexport enum VoteStatus {\n /**\n * 未投票\n */\n normal = -1,\n /**\n * 点赞\n */\n up,\n /**\n * 点踩\n */\n down,\n}\n\n/**\n * 是否状态\n */\nexport enum YesNoStatus {\n Yes,\n No,\n}\n\n/**\n * 文章状态\n */\nexport enum ArticleStatus {\n /**\n * 正常\n */\n Normal,\n /**\n * 封禁\n */\n Ban,\n /**\n * 锁定\n */\n Lock,\n}\n\n/**\n * 帖子列表查询类型\n */\nexport enum ArticleListType {\n /**\n * 最近\n */\n Recent = '',\n /**\n * 热门\n */\n Hot = '/hot',\n /**\n * 点赞\n */\n Good = '/good',\n /**\n * 最近回复\n */\n Reply = '/reply',\n /**\n * 优选,需包含标签\n */\n Perfect = '/perfact',\n}\n\n/**\n * 点赞类型\n */\nexport enum VoteType {\n /**\n * 点赞\n */\n Voted,\n /**\n * 取消点赞\n */\n Unvote = -1,\n}\n\n/**\n * 发帖信息\n */\nexport interface IArticlePost {\n /**\n * 帖子标题\n */\n title: string;\n /**\n * 帖子内容\n */\n content: string;\n /**\n * 帖子标签\n */\n tags: string;\n /**\n * 帖子类型\n */\n type?: ArticleType;\n /**\n * 是否允许评论\n */\n commentable?: boolean;\n /**\n * 是否帖子关注者\n */\n isNotifyFollowers?: boolean;\n /**\n * 是否在列表展示\n */\n isShowInList?: boolean;\n /**\n * 打赏内容\n */\n rewardContent?: string;\n /**\n * 打赏积分\n */\n rewardPoint?: number;\n /**\n * 是否匿名\n */\n isAnonymous?: boolean;\n /**\n * 提问悬赏积分\n */\n offerPoint?: number;\n}\n\n/**\n * 文章标签\n */\nexport class ArticleTag {\n /**\n * 标签 id\n */\n oId: string = '';\n /**\n * 标签名\n */\n title: string = '';\n /**\n * 标签描述\n */\n description: string = '';\n /**\n * icon 地址\n */\n iconPath: string = '';\n /**\n * 标签地址\n */\n URI: string = '';\n /**\n * 标签自定义 CSS\n */\n CSS: string = '';\n /**\n * 反对数\n */\n badCnt: number = 0;\n /**\n * 标签回帖计数\n */\n commentCount: number = 0;\n /**\n * 关注数\n */\n followerCount: number = 0;\n /**\n * 点赞数\n */\n goodCnt: number = 0;\n /**\n * 引用计数\n */\n referenceCount: number = 0;\n /**\n * 标签相关链接计数\n */\n linkCount: number = 0;\n /**\n * 标签 SEO 描述\n */\n seoDesc: string = '';\n /**\n * 标签关键字\n */\n seoKeywords: string = '';\n /**\n * 标签 SEO 标题\n */\n seoTitle: string = '';\n /**\n * 标签广告内容\n */\n ad: string = '';\n /**\n * 是否展示广告\n */\n isShowSideAd = true;\n /**\n * 标签状态\n */\n status: 0 | 1 = 1;\n\n static from(tag: Record<string, any>) {\n const data = new ArticleTag();\n data.oId = tag.oId;\n data.title = tag.tagTitle;\n data.description = tag.tagDescription;\n data.iconPath = tag.tagIconPath;\n data.URI = tag.tagURI;\n data.CSS = tag.tagCSS;\n data.badCnt = tag.tagBadCnt;\n data.commentCount = tag.tagCommentCount;\n data.followerCount = tag.tagFollowerCount;\n data.goodCnt = tag.tagGoodCnt;\n data.referenceCount = tag.tagReferenceCount;\n data.linkCount = tag.tagLinkCount;\n data.seoDesc = tag.tagSeoDesc;\n data.seoKeywords = tag.tagSeoKeywords;\n data.seoTitle = tag.tagSeoTitle;\n data.ad = tag.tagAd;\n data.isShowSideAd = tag.tagShowSideAd == 1;\n data.status = tag.tagStatus;\n\n return data;\n }\n}\n\n/**\n * 文章作者信息\n */\nexport class Author {\n /**\n * 用户是否在线\n */\n online: boolean = false;\n /**\n * 用户在线时长\n */\n onlineMinute: number = 0;\n /**\n * 用户标签\n */\n tags: string = '';\n /**\n * 用户时区\n */\n timezone: string = '';\n /**\n * 用户个人主页\n */\n URL: string = '';\n /**\n * 最近发帖时间\n */\n latestArticleTime: number = 0;\n /**\n * 昵称\n */\n nickname: string = '';\n /**\n * 应用角色\n */\n appRole: number = 0;\n /**\n * 用户状态\n */\n status: number = 0;\n /**\n * 用户省份\n */\n province: string = '';\n /**\n * 用户当前连续签到计数\n */\n currentCheckinStreak: number = 0;\n /**\n * 用户编号\n */\n userNo: number = 0;\n /**\n * 用户头像\n */\n avatarURL: string = '';\n /**\n * 用户语言\n */\n language: string = '';\n /**\n * 用户消费积分\n */\n usedPoint: number = 0;\n /**\n * 用户积分\n */\n points: number = 0;\n /**\n * 用户回帖数量\n */\n commentCount: number = 0;\n /**\n * 用户个性签名\n */\n intro: string = '';\n /**\n * 用户 Id\n */\n oId: string = '';\n /**\n * 用户名\n */\n userName: string = '';\n /**\n * 文章数\n */\n articleCount: number = 0;\n /**\n * 用户角色\n */\n role: string = '';\n /**\n * 徽章\n */\n sysMetal?: IMetal[];\n /**\n * MBTI 性格类型\n */\n mbti: string = '';\n\n static from(user: Record<string, any>) {\n const data = new Author();\n data.online = user.userOnlineFlag;\n data.onlineMinute = user.onlineMinute;\n data.tags = user.userTags;\n data.timezone = user.userTimezone;\n data.URL = user.userURL;\n data.latestArticleTime = user.userLatestArticleTime;\n data.nickname = user.userNickname;\n data.appRole = user.userAppRole;\n data.status = user.userStatus;\n data.province = user.userProvince;\n data.currentCheckinStreak = user.userCurrentCheckinStreak;\n data.userNo = user.userNo;\n data.avatarURL = user.userAvatarURL;\n data.language = user.userLanguage;\n data.usedPoint = user.userUsedPoint;\n data.points = user.userPoint;\n data.commentCount = user.userCommentCount;\n data.intro = user.userIntro;\n data.oId = user.oId;\n data.userName = user.userName;\n data.articleCount = user.userArticleCount;\n data.role = user.userRole;\n if (user.sysMetal) data.sysMetal = user.sysMetal;\n data.mbti = user.mbti;\n\n return data;\n }\n}\n\n/**\n * 文章详情\n */\nexport class ArticleDetail {\n /**\n * 是否在列表展示\n */\n isShowInList: boolean = true;\n /**\n * 发布者Id\n */\n authorId: string = '';\n /**\n * 反对数\n */\n badCnt: number = 0;\n /**\n * 文章最后修改时间\n */\n latestCmtTime: string = '';\n /**\n * 赞同数\n */\n goodCnt: number = 0;\n /**\n * 悬赏积分\n */\n offerPoint: number = 0;\n /**\n * 文章首图缩略图\n */\n thumbnailURL: string = '';\n /**\n * 置顶序号\n */\n stickRemains: number = 0;\n /**\n * 发布时间简写\n */\n timeAgo: string = '';\n /**\n * 文章更新时间\n */\n updateTime: string = '';\n /**\n * 作者用户名\n */\n authorName: string = '';\n /**\n * 文章类型\n */\n type: ArticleType = ArticleType.Normal;\n /**\n * 是否悬赏\n */\n isOffered: boolean = false;\n /**\n * 文章创建时间字符串\n */\n createTime: string = '';\n /**\n * 文章浏览数\n */\n viewCount: number = 0;\n /**\n * 作者头像缩略图\n */\n authorThumbnail20: string = '';\n /**\n * 关注数\n */\n watchCnt: number = 0;\n /**\n * 文章预览内容\n */\n previewContent: string = '';\n /**\n * 文章标题\n */\n titleEmoj: string = '';\n /**\n * 文章标题\n */\n titleEmojUnicode: string = '';\n /**\n * 文章标题\n */\n title: string = '';\n /**\n * 作者头像缩略图\n */\n authorThumbnail48: string = '';\n /**\n * 收藏数\n */\n collectCnt: number = 0;\n /**\n * 文章最后评论者\n */\n latestCmter: string = '';\n /**\n * 文章标签\n */\n tagsContent: string = '';\n /**\n * 文章 id\n */\n oId: string = '';\n /**\n * 最后评论时间简写\n */\n cmtTimeAgo: string = '';\n /**\n * 是否置顶\n */\n stick: number = 0;\n /**\n * 文章标签信息\n */\n tags: ArticleTag[] = [];\n /**\n * 是否匿名\n */\n isAnonymous: boolean = false;\n /**\n * 文章感谢数\n */\n thankCnt: number = 0;\n /**\n * 文章状态\n */\n status: ArticleStatus = ArticleStatus.Normal;\n /**\n * 文章点击数\n */\n heat: number = 0;\n /**\n * 文章是否优选\n */\n isPerfect: boolean = false;\n /**\n * 作者头像缩略图\n */\n authorThumbnail210: string = '';\n /**\n * 文章固定链接\n */\n permalink: string = '';\n /**\n * 作者用户信息\n */\n author: Author = new Author();\n /**\n * 文章感谢数\n */\n thankedCnt?: number = 0;\n /**\n * 文章匿名浏览量\n */\n anonymousView?: number = 0;\n /**\n * 文章浏览量简写\n */\n viewCntDisplay?: string = '';\n /**\n * 文章是否启用评论\n */\n commentable?: boolean = true;\n /**\n * 是否已打赏\n */\n isRewarded?: boolean = false;\n /**\n * 打赏人数\n */\n rewardedCnt?: number = 0;\n /**\n * 文章打赏积分\n */\n rewardPoint?: number = 0;\n /**\n * 是否已收藏\n */\n isFollowing?: boolean = false;\n /**\n * 是否已关注\n */\n isWatching?: boolean = false;\n /**\n * 是否是我的文章\n */\n isMyArticle?: boolean = false;\n /**\n * 是否已感谢\n */\n isThanked?: boolean = false;\n /**\n * 文章音频地址\n */\n audioURL?: string = '';\n /**\n * 文章目录 HTML\n */\n tableOfContents?: string = '';\n /**\n * 文章内容 HTML\n */\n content?: string = '';\n /**\n * 文章内容 Markdown\n */\n originalContent?: string = '';\n /**\n * 文章首图\n */\n img1URL?: string = '';\n /**\n * 文章点赞状态\n */\n vote?: VoteStatus = VoteStatus.normal;\n /**\n * 作者签名\n */\n authorIntro?: string = '';\n /**\n * 发布城市\n */\n city?: string = '';\n /**\n * 作者首页地址\n */\n authorURL?: string = '';\n /**\n * 打赏内容\n */\n rewardContent?: string = '';\n /**\n * 评论分页信息\n */\n pagination?: Pagination;\n /**\n * 评论是否可见\n */\n discussionViewable: boolean = true;\n /**\n * 文章修改次数\n */\n revisionCount: number = 0;\n /**\n * 文章的评论\n */\n comments?: Array<ArticleComment>;\n /**\n * 文章最佳评论\n */\n niceComments?: Array<ArticleComment>;\n\n static from(post: Record<string, any>) {\n const data = new ArticleDetail();\n data.isShowInList = post.articleShowInList;\n data.authorId = post.articleAuthorId;\n data.badCnt = post.articleBadCnt;\n data.goodCnt = post.articleGoodCnt;\n data.offerPoint = post.articleQnAOfferPoint;\n data.thumbnailURL = post.articleThumbnailURL;\n data.stickRemains = post.articleStickRemains;\n data.timeAgo = post.timeAgo;\n data.updateTime = post.articleUpdateTimeStr;\n data.authorName = post.articleAuthorName;\n data.type = post.articleType;\n data.isOffered = post.articleQnAOfferPoint > 0;\n data.createTime = post.articleCreateTimeStr;\n data.viewCount = post.articleViewCount;\n data.authorThumbnail20 = post.articleAuthorThumbnailURL20;\n data.watchCnt = post.articleWatchCnt;\n data.previewContent = post.articlePreviewContent;\n data.titleEmoj = post.articleTitleEmoj;\n data.titleEmojUnicode = post.articleTitleEmojUnicode;\n data.title = post.articleTitle;\n data.authorThumbnail48 = post.articleAuthorThumbnailURL48;\n data.collectCnt = post.articleCollectCnt;\n data.latestCmter = post.articleLatestCmterName;\n data.tagsContent = post.articleTags;\n data.oId = post.oId;\n data.cmtTimeAgo = post.cmtTimeAgo;\n data.stick = post.articleStick;\n data.tags = post.articleTagObjs?.map((t: any) => ArticleTag.from(t)) || [];\n data.latestCmtTime = post.articleLatestCmtTimeStr;\n data.isAnonymous = post.articleAnonymous;\n data.thankCnt = post.articleThankCnt;\n data.status = post.articleStatus;\n data.heat = post.articleHeat;\n data.isPerfect = post.articlePerfect;\n data.authorThumbnail210 = post.articleAuthorThumbnailURL210;\n data.permalink = post.articlePermalink;\n if (post.articleAuthor) data.author = Author.from(post.articleAuthor);\n data.thankedCnt = post.thankedCnt;\n data.anonymousView = post.articleAnonymousView;\n data.viewCntDisplay = post.articleViewCntDisplayFormat;\n data.commentable = post.articleCommentable;\n data.isRewarded = post.rewarded;\n data.rewardedCnt = post.rewardedCnt;\n data.rewardPoint = post.articleRewardPoint;\n data.isFollowing = post.isFollowing;\n data.isWatching = post.isWatching;\n data.isMyArticle = post.isMyArticle;\n data.isThanked = post.thanked;\n data.audioURL = post.articleAudioURL;\n data.tableOfContents = post.articleToC;\n data.content = post.articleContent;\n data.originalContent = post.articleOriginalContent;\n data.img1URL = post.articleImg1URL;\n data.vote = post.articleVote;\n data.authorIntro = post.articleAuthorIntro;\n data.city = post.articleCity;\n data.authorURL = post.articleAuthorURL;\n data.rewardContent = post.articleRewardContent;\n if (post.pagination) data.pagination = Pagination.from(post.pagination);\n data.discussionViewable = post.discussionViewable;\n data.revisionCount = post.articleRevisionCount;\n data.comments = post.articleComments\n ? post.articleComments.map((c: any) => ArticleComment.from(c))\n : undefined;\n data.niceComments = post.articleNiceComments\n ? post.articleNiceComments.map((c: any) => ArticleComment.from(c))\n : undefined;\n return data;\n }\n}\n\n/**\n * 文章评论\n */\nexport class ArticleComment {\n /**\n * 是否优评\n */\n isNice: boolean = false;\n /**\n * 评论创建时间字符串\n */\n createTime: string = '';\n /**\n * 评论作者 id\n */\n authorId: string = '';\n /**\n * 评论分数\n */\n score: number = 0;\n /**\n * 评论作者头像\n */\n authorURL: string = '';\n /**\n * 评论状态\n */\n vote: VoteStatus = VoteStatus.normal;\n /**\n * 评论引用数\n */\n revisionCount: number = 0;\n /**\n * 评论经过时间\n */\n timeAgo: string = '';\n /**\n * 回复评论 id\n */\n originalId: string = '';\n /**\n * 徽章\n */\n sysMetal: IMetal[] = [];\n /**\n * 点赞数\n */\n goodCnt: number = 0;\n /**\n * 评论是否可见\n */\n visible: YesNoStatus = YesNoStatus.Yes;\n /**\n * 文章 id\n */\n articleId: string = '';\n /**\n * 评论感谢数\n */\n rewardedCnt: number = 0;\n /**\n * 评论地址\n */\n sharpURL: string = '';\n /**\n * 是否匿名\n */\n isAnonymous: boolean = false;\n /**\n * 评论回复数\n */\n replyCnt: number = 0;\n /**\n * 评论 id\n */\n oId: string = '';\n /**\n * 评论内容\n */\n content: string = '';\n /**\n * 评论状态\n */\n status: ArticleStatus = ArticleStatus.Normal;\n /**\n * 评论作者\n */\n commenter: Author = new Author();\n /**\n * 评论作者用户名\n */\n authorName: string = '';\n /**\n * 评论感谢数\n */\n thankCnt: number = 0;\n /**\n * 评论点踩数\n */\n badCnt: number = 0;\n /**\n * 是否已感谢\n */\n rewarded: boolean = false;\n /**\n * 评论作者头像\n */\n authorThumbnailURL: string = '';\n /**\n * 评论音频地址\n */\n audioURL: string = '';\n /**\n * 评论是否采纳,1 表示采纳\n */\n isOffered: boolean = false;\n\n static from(cmt: Record<string, any>) {\n const data = new ArticleComment();\n data.isNice = cmt.commentNice;\n data.createTime = cmt.commentCreateTimeStr;\n data.authorId = cmt.commentAuthorId;\n data.score = cmt.commentScore;\n data.authorURL = cmt.commentAuthorURL;\n data.vote = cmt.commentVote;\n data.revisionCount = cmt.commentRevisionCount;\n data.timeAgo = cmt.timeAgo;\n data.originalId = cmt.commentOriginalCommentId;\n if (cmt.sysMetal) data.sysMetal = cmt.sysMetal;\n data.goodCnt = cmt.commentGoodCnt;\n data.visible = cmt.commentVisible;\n data.articleId = cmt.commentOnArticleId;\n data.rewardedCnt = cmt.rewardedCnt;\n data.sharpURL = cmt.commentSharpURL;\n data.isAnonymous = cmt.commentAnonymous;\n data.replyCnt = cmt.commentReplyCnt;\n data.oId = cmt.oId;\n data.content = cmt.commentContent;\n data.status = cmt.commentStatus;\n if (cmt.commenter) data.commenter = Author.from(cmt.commenter);\n data.authorName = cmt.commentAuthorName;\n data.thankCnt = cmt.commentThankCnt;\n data.badCnt = cmt.commentBadCnt;\n data.rewarded = cmt.rewarded;\n data.authorThumbnailURL = cmt.commentAuthorThumbnailURL;\n data.audioURL = cmt.commentAudioURL;\n data.isOffered = cmt.commentQnAOffered == 1;\n return data;\n }\n}\n\n/**\n * 文章列表\n */\nexport class ArticleList {\n /**\n * 文章列表\n */\n articles: ArticleDetail[] = [];\n /**\n * 分页信息\n */\n pagination: Pagination = new Pagination();\n /**\n * 标签信息,仅查询标签下文章列表有效\n */\n tag?: ArticleTag;\n\n static from(list: Record<string, any>) {\n const data = new ArticleList();\n data.articles = list.articles.map((a: any) => ArticleDetail.from(a));\n data.pagination = Pagination.from(list.pagination);\n if (list.tag) data.tag = ArticleTag.from(list.tag);\n return data;\n }\n}\n\nexport interface ICommentPost {\n /**\n * 文章 Id\n */\n articleId: string;\n /**\n * 是否匿名评论\n */\n isAnonymous?: boolean;\n /**\n * 评论是否楼主可见\n */\n isVisible?: boolean;\n /**\n * 评论内容\n */\n content: string;\n /**\n * 回复评论 Id\n */\n originalId?: string;\n}\n\nexport interface IArticleHeat {\n articleId: string;\n heat: number;\n}\n","import { Pagination } from '.';\n\n/**\n * 清风明月内容\n */\nexport class BreezemoonContent {\n /**\n * 发布者用户名\n */\n authorName: string = '';\n /**\n * 最后更新时间\n */\n updatedAt: string = '';\n /**\n * 清风明月ID\n */\n oId: string = '';\n /**\n * 创建时间\n */\n createAt: string = '';\n /**\n * 发布者头像URL\n */\n authorThumbnail: string = '';\n /**\n * 发布时间\n */\n timeAgo: string = '';\n /**\n * 正文\n */\n content: string = '';\n /**\n * 发布城市(可能为空,请注意做判断)\n */\n city: string = '';\n\n static from(src: Record<string, any>): BreezemoonContent {\n const data = new BreezemoonContent();\n data.authorName = src.breezemoonAuthorName;\n data.updatedAt = src.breezemoonUpdated;\n data.oId = src.oId;\n data.createAt = src.breezemoonCreated;\n data.authorThumbnail = src.breezemoonAuthorThumbnailURL48;\n data.timeAgo = src.timeAgo;\n data.content = src.breezemoonContent;\n data.city = src.breezemoonCity;\n return data;\n }\n}\n\nexport class BreezemoonList {\n /**\n * 分页信息\n */\n pagination: Pagination = new Pagination();\n /**\n * 清风明月列表\n */\n breezemoons: BreezemoonContent[] = [];\n\n static from(src: Record<string, any>): BreezemoonList {\n const data = new BreezemoonList();\n data.pagination = src.pagination;\n data.breezemoons = src.breezemoons.map((b: any) => BreezemoonContent.from(b));\n return data;\n }\n}\n","import { IMetal, IRedPacketMessage } from '.';\n\nexport enum ClientType {\n /**\n * 网页端\n */\n Web = 'Web',\n /**\n * PC 端\n */\n PC = 'PC',\n /**\n * 移动端聊天室\n */\n Mobile = 'Mobile',\n /**\n * Windows 客户端\n */\n Windows = 'Windows',\n /**\n * macOS 客户端\n */\n macOS = 'macOS',\n /**\n * Linux 客户端\n */\n Linux = 'Linux',\n /**\n * iOS 客户端\n */\n iOS = 'iOS',\n /**\n * Android 客户端\n */\n Android = 'Android',\n /**\n * IDEA 插件\n */\n IDEA = 'IDEA',\n /**\n * Chrome 插件\n */\n Chrome = 'Chrome',\n /**\n * Edge 插件\n */\n Edge = 'Edge',\n /**\n * VSCode 插件\n */\n VSCode = 'VSCode',\n /**\n * Python 客户端\n */\n Python = 'Python',\n /**\n * Golang 客户端\n */\n Golang = 'Golang',\n /**\n * Rust 客户端\n */\n Rust = 'Rust',\n /**\n * Harmony App\n */\n Harmony = 'Harmony',\n /**\n * CLI 工具\n */\n CLI = 'CLI',\n /**\n * 鸽机器人\n */\n Bird = 'Bird',\n /**\n * 小冰机器人\n */\n IceNet = 'IceNet',\n /**\n * 凌机器人\n */\n ElvesOnline = 'ElvesOnline',\n /**\n * 其他插件\n */\n Other = 'Other',\n}\n\n/**\n * 聊天室消息来源\n */\nexport class ChatRoomSource implements IChatRoomSource {\n /**\n * 消息来源\n */\n client: ClientType | string = ClientType.Other;\n /**\n * 消息来源版本\n */\n version: string = 'latest';\n}\n\n/**\n * 历史消息类型\n */\nexport enum ChatContentType {\n /**\n * 原始 Markdown\n */\n Markdown = 'md',\n /**\n * 渲染 HTML\n */\n HTML = 'html',\n}\n\n/**\n * chatroom get 接口获取 oId 的相关消息类型\n */\nexport enum ChatMessageType {\n /**\n * 前后消息\n */\n Context = 0,\n /**\n * 前面的消息\n */\n Before = 1,\n /**\n * 后面的消息\n */\n After = 2,\n}\n\n/**\n * 聊天室消息类型\n */\nexport enum ChatRoomMessageType {\n /**\n * 在线用户\n */\n online = 'online',\n /**\n * 话题修改\n */\n discussChanged = 'discussChanged',\n /**\n * 消息撤回\n */\n revoke = 'revoke',\n /**\n * 消息\n */\n msg = 'msg',\n /**\n * 红包\n */\n redPacket = 'redPacket',\n /**\n * 红包状态\n */\n redPacketStatus = 'redPacketStatus',\n /**\n * 弹幕\n */\n barrager = 'barrager',\n /**\n * 自定义消息\n */\n custom = 'customMessage',\n}\n/**\n * 聊天室消息来源\n */\nexport interface IChatRoomSource {\n /**\n * 消息来源\n */\n client: ClientType | string;\n /**\n * 消息来源版本\n */\n version: string;\n}\n\n/**\n * 聊天室消息\n */\nexport interface IChatRoomMessage {\n /**\n * 消息 Id\n */\n oId: string;\n /**\n * 消息类型\n */\n type: string;\n /**\n * 发送者用户名\n */\n userName: string;\n /**\n * 用户昵称\n */\n userNickname: string;\n /**\n * 用户头像\n */\n userAvatarURL: string;\n /**\n * 用户徽章\n */\n sysMetal: IMetal[];\n /**\n * 消息来源\n */\n client: string;\n /**\n * 消息来源解析\n */\n via: IChatRoomSource;\n /**\n * 消息内容\n */\n content: string | IRedPacketMessage | IMusicMessage | IWeatherMessage;\n /**\n * Markdown 内容\n */\n md: string;\n /**\n * 发送时间\n */\n time: string;\n}\n\nexport type CustomMsg = string;\n\n/**\n * 弹幕消息\n */\nexport interface IBarragerMsg {\n /**\n * 用户名\n */\n userName: string;\n /**\n * 用户昵称\n */\n userNickname: string;\n /**\n * 弹幕内容\n */\n barragerContent: string;\n /**\n * 弹幕颜色\n */\n barragerColor: string;\n /**\n * 用户头像地址\n */\n userAvatarURL: string;\n /**\n * 用户头像地址 20x20\n */\n userAvatarURL20: string;\n /**\n * 用户头像地址 48x48\n */\n userAvatarURL48: string;\n /**\n * 用户头像地址 210x210\n */\n userAvatarURL210: string;\n}\n\n/**\n * 在线用户信息\n */\nexport interface IOnlineInfo {\n /**\n * 用户首页\n */\n homePage: string;\n /**\n * 用户头像\n */\n userAvatarURL: string;\n /**\n * 用户名\n */\n userName: string;\n}\n\n/**\n * 主题修改消息,主题内容\n */\nexport type DiscussMsg = string;\n\n/**\n * 撤回消息,被撤回消息的 oId\n */\nexport type RevokeMsg = string;\n\n/**\n * 聊天消息\n */\nexport interface IChatRoomMsg<T = string> {\n /**\n * 消息类型\n */\n type: string;\n /**\n * 消息 oId\n */\n oId: string;\n /**\n * 消息发送时间\n */\n time: string;\n /**\n * 用户 Id\n */\n userOId: string;\n /**\n * 发送者用户名\n */\n userName: string;\n /**\n * 发送者昵称\n */\n userNickname: string;\n /**\n * 发送者头像\n */\n userAvatarURL: string;\n /**\n * 消息内容\n */\n content: T;\n /**\n * 消息内容 Markdown\n */\n md: string;\n /**\n * 消息来源\n */\n client: string;\n /**\n * 消息来源解析\n */\n via: IChatRoomSource;\n}\n\ntype WeatherCode =\n | 'CLEAR_DAY'\n | 'CLEAR_NIGHT'\n | 'CLOUDY'\n | 'DUST'\n | 'FOG'\n | 'HEAVY_HAZE'\n | 'HEAVY_RAIN'\n | 'HEAVY_SNOW'\n | 'LIGHT_HAZE'\n | 'LIGHT_RAIN'\n | 'LIGHT_SNOW'\n | 'MODERATE_HAZE'\n | 'MODERATE_RAIN'\n | 'MODERATE_SNOW'\n | 'PARTLY_CLOUDY_DAY'\n | 'PARTLY_CLOUDY_NIGHT'\n | 'SAND'\n | 'STORM_RAIN'\n | 'STORM_SNOW'\n | 'WIND';\n\n/**\n * 聊天天气消息详情\n */\nexport interface IWeatherData {\n /**\n * 日期\n */\n date: string;\n /**\n * 天气代码\n */\n code: WeatherCode;\n /**\n * 最小气温\n */\n min: number;\n /**\n * 最大气温\n */\n max: number;\n}\n\n/**\n * 聊天天气消息\n */\nexport interface IWeatherMessage {\n /**\n * 城市\n */\n city: string;\n /**\n * 描述\n */\n description: string;\n /**\n * 最近几天天气数据\n */\n data: IWeatherData[];\n}\n\n/**\n * 聊天音乐消息\n */\nexport interface IMusicMessage {\n type: 'music';\n /**\n * 音乐源\n */\n source: string;\n /**\n * 封面地址\n */\n coverURL: string;\n /**\n * 歌曲名称\n */\n title: string;\n /**\n * 来源\n */\n from: string;\n}\n\n/**\n * 聊天室节点信息\n */\nexport interface IChatRoomNode {\n /**\n * 节点地址\n */\n node: string;\n /**\n * 名称\n */\n name: string;\n /**\n * 在线人数\n */\n online?: number;\n}\n\n/**\n * 聊天室节点详情\n */\nexport interface IChatRoomNodeInfo {\n /**\n * 推荐节点\n */\n recommend: IChatRoomNode;\n /**\n * 所有节点\n */\n avaliable: IChatRoomNode[];\n}\n","/**\n * 猜拳类型\n */\nexport enum GestureType {\n /**\n * 石头\n */\n Rock = 0,\n /**\n * 剪刀\n */\n Scissors = 1,\n /**\n * 布\n */\n Paper = 2,\n}\n\n/**\n * 红包类型\n */\nexport enum RedPacketType {\n /**\n * 拼手气\n */\n Random = 'random',\n /**\n * 平分\n */\n Average = 'average',\n /**\n * 专属\n */\n Specify = 'specify',\n /**\n * 心跳\n */\n Heartbeat = 'heartbeat',\n /**\n * 猜拳\n */\n RockPaperScissors = 'rockPaperScissors',\n}\n\n/**\n * 红包数据\n */\nexport class Redpacket implements IRedpacket {\n /**\n * 红包类型\n */\n type: RedPacketType = RedPacketType.Random;\n /**\n * 红包积分\n */\n money: number = 32;\n /**\n * 红包个数\n */\n count: number = 1;\n /**\n * 祝福语\n */\n msg: string = '摸鱼者,事竟成';\n /**\n * 接收者,专属红包有效\n */\n recivers?: Array<string>;\n /**\n * 出拳,猜拳红包有效\n */\n gesture?: GestureType;\n}\n\n/**\n * 红包数据\n */\nexport interface IRedpacket {\n /**\n * 红包类型\n */\n type: RedPacketType;\n /**\n * 红包积分\n */\n money: number;\n /**\n * 红包个数\n */\n count: number;\n /**\n * 祝福语\n */\n msg: string;\n /**\n * 接收者,专属红包有效\n */\n recivers?: Array<string>;\n /**\n * 出拳,猜拳红包有效\n */\n gesture?: GestureType;\n}\n\n/**\n * 红包领取者信息\n */\nexport interface IRedPacketGot {\n /**\n * 用户 id\n */\n userId: string;\n /**\n * 用户名\n */\n userName: string;\n /**\n * 用户头像\n */\n avatar: string;\n /**\n * 领取到的积分\n */\n userMoney: number;\n /**\n * 领取积分时间\n */\n time: string;\n}\n\n/**\n * 红包历史信息\n */\nexport interface IRedPacketMessage {\n /**\n * 消息类型,固定为 redPacket\n */\n msgType: string;\n /**\n * 红包数\n */\n count: number;\n /**\n * 领取数\n */\n got: number;\n /**\n * 内含积分\n */\n money: number;\n /**\n * 祝福语\n */\n msg: string;\n /**\n * 发送者 id\n */\n senderId: string;\n /**\n * 红包类型\n */\n type: RedPacketType;\n /**\n * 接收者,专属红包有效\n */\n recivers: string[];\n /**\n * 已领取者列表\n */\n who: IRedPacketGot[];\n}\n\n/**\n * 红包基本信息\n */\nexport interface IRedPacketBase {\n /**\n * 数量\n */\n count: number;\n /**\n * 猜拳类型\n */\n gesture?: GestureType;\n /**\n * 领取数\n */\n got: number;\n /**\n * 祝福语\n */\n msg: string;\n /**\n * 发送者用户名\n */\n userName: string;\n /**\n * 用户头像\n */\n userAvatarURL: string;\n}\n\n/**\n * 红包信息\n */\nexport interface IRedPacketInfo {\n /**\n * 红包基本信息\n */\n info: IRedPacketBase;\n /**\n * 接收者,专属红包有效\n */\n recivers: string[];\n /**\n * 已领取者列表\n */\n who: IRedPacketGot[];\n}\n\n/**\n * 红包状态信息\n */\nexport interface IRedPacketStatusMsg {\n /**\n * 对应红包消息 oId\n */\n oId: string;\n /**\n * 红包个数\n */\n count: number;\n /**\n * 已领取数量\n */\n got: number;\n /**\n * 发送者信息\n */\n whoGive: any;\n /**\n * 领取者信息\n */\n whoGot: any[];\n}\n","import { UserAppRole } from '.';\nimport { domain, toMetal } from '../utils';\n\nexport interface IUserLite {\n oId: string;\n userAvatarURL: string;\n userNickname: string;\n userName: string;\n}\n\n/**\n * 用户信息\n */\nexport class UserInfo {\n /**\n * 用户 id\n */\n oId: string = '';\n /**\n * 用户编号\n */\n userNo: string = '';\n /**\n * 用户名\n */\n userName: string = '';\n /**\n * 昵称\n */\n userNickname: string = '';\n /**\n * 首页地址\n */\n URL: string = '';\n /**\n * 所在城市\n */\n city: string = '';\n /**\n * 签名\n */\n intro: string = '';\n /**\n * 是否在线\n */\n online: boolean = false;\n /**\n * 用户积分\n */\n points: number = 0;\n /**\n * 用户组\n */\n role: string = '';\n /**\n * 角色\n */\n appRole: UserAppRole = UserAppRole.Hack;\n /**\n * 用户头像地址\n */\n avatar: string = '';\n /**\n * 用户卡片背景\n */\n cardBg: string = '';\n /**\n * 用户关注数\n */\n following: number = 0;\n /**\n * 用户被关注数\n */\n follower: number = 0;\n /**\n * 在线时长,单位分钟\n */\n onlineMinute: number = 0;\n /**\n * 是否已经关注,未登录则为 `hide`\n */\n canFollow: 'hide' | 'no' | 'yes' = 'hide';\n /**\n * 用户所有勋章列表,包含未佩戴\n */\n ownedMetal: Metal[] = [];\n\n /**\n * 用户勋章列表\n */\n sysMetal: Metal[] = [];\n /**\n * MBTI 性格类型\n */\n mbti: string = '';\n\n get name(): string {\n return this.userNickname ? `${this.userNickname}(${this.userName})` : this.userName;\n }\n\n static from(user: Record<string, any>) {\n const data = new UserInfo();\n data.oId = user.oId;\n data.userNo = user.userNo;\n data.userName = user.userName;\n data.userNickname = user.userNickname;\n data.URL = user.userURL;\n data.city = user.userCity;\n data.intro = user.userIntro;\n data.online = user.userOnlineFlag;\n data.points = user.userPoint;\n data.role = user.userRole;\n data.appRole = user.userAppRole;\n data.avatar = user.userAvatarURL;\n data.cardBg = user.cardBg;\n data.following = user.followingUserCount;\n data.follower = user.followerCount;\n data.onlineMinute = user.onlineMinute;\n data.canFollow = user.canFollow;\n data.ownedMetal = toMetal(user.allMetalOwned);\n data.sysMetal = toMetal(user.sysMetal);\n data.mbti = user.mbti;\n\n return data;\n }\n}\n\n/**\n * 徽章属性\n */\nexport class MetalAttr {\n /**\n * 徽标图地址\n */\n url: string = '';\n /**\n * 背景色\n */\n backcolor: string = '';\n /**\n * 文字颜色\n */\n fontcolor: string = '';\n /**\n * 版本号\n */\n ver: number = 0.1;\n /**\n * 缩放比例\n */\n scale: number = 0.79;\n\n toString() {\n return `url=${this.url}&backcolor=${this.backcolor}&fontcolor=${this.fontcolor}&ver=${this.ver}&scale=${this.scale}`;\n }\n}\n\n/**\n * 徽章基本信息\n */\nexport class MetalBase {\n /**\n * 徽章属性\n */\n attr: MetalAttr | string = new MetalAttr();\n /**\n * 徽章名\n */\n name: string = '';\n /**\n * 徽章描述\n */\n description: string = '';\n /**\n * 徽章数据\n */\n data: string = '';\n\n constructor(metal?: MetalBase) {\n if (!metal) {\n return;\n }\n this.attr = Object.assign(new MetalAttr(), metal.attr);\n this.name = metal.name;\n this.description = metal.description;\n this.data = metal.data;\n }\n\n toUrl(includeText: boolean = true) {\n let url = `https://${domain}/gen?txt=${this.name}&${this.attr.toString()}`;\n if (!includeText) {\n url = `https://${domain}/gen?txt=&${this.attr.toString()}`;\n }\n return url;\n }\n}\n\n/**\n * 徽章信息\n */\nexport class Metal extends MetalBase {\n /**\n * 完整徽章地址(含文字)\n */\n url?: string;\n /**\n * 徽章地址(不含文字)\n */\n icon?: string;\n /**\n * 是否佩戴\n */\n enable: boolean = true;\n}\n\nexport class AtUser {\n /**\n * 用户名\n */\n userName: string = '';\n /**\n * 用户头像\n */\n userAvatarURL: string = '';\n /**\n * 全小写用户名\n */\n userNameLowerCase: string = '';\n}\n\n/**\n * 徽章属性\n */\nexport interface IMetalAttr {\n /**\n * 徽标图地址\n */\n url: string;\n /**\n * 背景色\n */\n backcolor: string;\n /**\n * 文字颜色\n */\n fontcolor: string;\n}\n\n/**\n * 徽章基本信息\n */\nexport interface IMetalBase {\n /**\n * 徽章属性\n */\n attr: IMetalAttr | string;\n /**\n * 徽章名\n */\n name: string;\n /**\n * 徽章描述\n */\n description: string;\n /**\n * 徽章数据\n */\n data: string;\n}\n\n/**\n * 徽章信息\n */\nexport interface IMetal extends IMetalBase {\n /**\n * 完整徽章地址(含文字)\n */\n url?: string;\n /**\n * 徽章地址(不含文字)\n */\n icon?: string;\n /**\n * 是否佩戴\n */\n enable: boolean;\n}\n\nexport interface IAtUser {\n /**\n * 用户名\n */\n userName: string;\n /**\n * 用户头像\n */\n userAvatarURL: string;\n /**\n * 全小写用户名\n */\n userNameLowerCase: string;\n}\n\n/**\n * 更新用户信息参数\n */\nexport interface UserUpdateParams {\n /**\n * 昵称\n */\n userNickname?: string;\n /**\n * 用户标签,多个标签用逗号分隔\n */\n userTags?: string;\n /**\n * 个人主页 URL\n */\n userURL?: string;\n /**\n * 个人简介\n */\n userIntro?: string;\n /**\n * MBTI 性格类型(例如:ENFP)\n */\n mbti?: string;\n}\n","/**\n * 摸鱼大闯关信息\n */\nexport class MoFishGame implements IMoFishGame {\n userName = '';\n stage = '';\n time = 0;\n}\n\n/**\n * 用户背包物品类型\n */\nexport enum UserBagType {\n checkin1day,\n checkin2days,\n patchCheckinCard,\n metalTicket,\n}\n\n/**\n * 摸鱼大闯关信息\n */\nexport interface IMoFishGame {\n userName: string;\n stage: string;\n time: number;\n}\n\n/**\n * 用户 IP 信息\n */\nexport interface IUserIP {\n latestLoginIP: string;\n userId: string;\n}\n\n/**\n * 用户背包信息\n */\nexport interface IUserBag {\n /**\n * 免签卡\n */\n checkin1day: number;\n\n /**\n * 两日免签卡\n */\n checkin2days: number;\n\n /**\n * 补签卡\n */\n patchCheckinCard: number;\n\n /**\n * 摸鱼派一周年纪念勋章领取券\n */\n metalTicket: number;\n\n /**\n * 改名卡\n */\n nameCard: number;\n\n /**\n * 免签天数\n */\n sysCheckinRemain: number;\n}\n","import { DataType, ArticleTag } from '.';\n\n/**\n * 通知类型\n */\nexport enum NoticeType {\n /**\n * 积分\n */\n Point = 'point',\n /**\n * 评论\n */\n Comment = 'commented',\n /**\n * 回复\n */\n Reply = 'reply',\n /**\n * 提及我的\n */\n At = 'at',\n /**\n * 我关注的\n */\n Following = 'following',\n /**\n * 同城\n */\n Broadcast = 'broadcast',\n /**\n * 系统\n */\n System = 'sys-announce',\n}\n\n/**\n * 通知列表\n */\nexport type NoticeList = Array<\n INoticePoint | INoticeComment | INoticeReply | INoticeAt | INoticeArticle | INoticeSystem\n>;\n\n/**\n * 通知数\n */\nexport interface INoticeCount {\n /**\n * 用户是否启用 Web 通知\n */\n userNotifyStatus: boolean;\n /**\n * 未读通知数\n */\n unreadNotificationCnt: number;\n /**\n * 未读回复通知数\n */\n unreadReplyNotificationCnt: number;\n /**\n * 未读积分通知数\n */\n unreadPointNotificationCnt: number;\n /**\n * 未读 @ 通知数\n */\n unreadAtNotificationCnt: number;\n /**\n * 未读同城通知数\n */\n unreadBroadcastNotificationCnt: number;\n /**\n * 未读系统通知数\n */\n unreadSysAnnounceNotificationCnt: number;\n /**\n * 未读关注者通知数\n */\n unreadNewFollowerNotificationCnt: number;\n /**\n * 未读关注通知数\n */\n unreadFollowingNotificationCnt: number;\n /**\n * 未读评论通知数\n */\n unreadCommentedNotificationCnt: number;\n}\n\n/**\n * 积分通知\n */\nexport interface INoticePoint {\n /**\n * 通知 id\n */\n oId: string;\n /**\n * 数据 id\n */\n dataId: string;\n /**\n * 用户 id\n */\n userId: string;\n /**\n * 数据类型\n */\n dataType: DataType;\n /**\n * 通知描述\n */\n description: string;\n /**\n * 是否已读\n */\n hasRead: boolean;\n /**\n * 创建日期\n */\n createTime: string;\n}\n\n/**\n * 评论通知\n */\nexport interface INoticeComment {\n /**\n * 通知 id\n */\n oId: string;\n /**\n * 文章标题\n */\n commentArticleTitle: string;\n /**\n * 文章作者\n */\n commentAuthorName: string;\n /**\n * 作者头像\n */\n commentAuthorThumbnailURL: string;\n /**\n * 文章类型\n */\n commentArticleType: number;\n /**\n * 是否精选\n */\n commentArticlePerfect: number;\n /**\n * 评论内容\n */\n commentContent: string;\n /**\n * 评论地址\n */\n commentSharpURL: string;\n /**\n * 是否已读\n */\n hasRead: boolean;\n /**\n * 评论时间\n */\n commentCreateTime: string;\n}\n\n/**\n * 回帖通知\n */\nexport interface INoticeReply extends INoticeComment {\n /**\n * 文章 id\n */\n articleId: string;\n /**\n * 数据类型\n */\n dataType: DataType;\n}\n\n/**\n * 提到我通知\n */\nexport interface INoticeAt {\n /**\n * 通知 id\n */\n oId: string;\n /**\n * 数据 id\n */\n dataId: string;\n /**\n * 数据类型\n */\n dataType: DataType;\n /**\n * 用户名\n */\n userName: string;\n /**\n * 用户头像\n */\n thumbnailURL: string;\n /**\n * 通知内容\n */\n description: string;\n /**\n * 是否已读\n */\n hasRead: boolean;\n /**\n * 创建时间\n */\n createTime: string;\n}\n\n/**\n * 我关注的通知\n */\nexport interface INoticeArticle {\n /**\n * 通知 Id\n */\n oId: string;\n /**\n * 文章地址\n */\n url: string;\n /**\n * 数据类型\n */\n dataType: DataType;\n /**\n * 文章标题\n */\n articleTitle: string;\n /**\n * 作者\n */\n authorName: string;\n /**\n * 通知内容\n */\n content: string;\n /**\n * 是否评论\n */\n isComment: boolean;\n /**\n * 作者头像\n */\n thumbnailURL: string;\n /**\n * 文章评论数\n */\n articleCommentCount: number;\n /**\n * 是否精选\n */\n articlePerfect: number;\n /**\n * 文章标签列表\n */\n articleTagObjs: ArticleTag[];\n /**\n * 文章标签\n */\n articleTags: string;\n /**\n * 文章类型\n */\n articleType: number;\n /**\n * 是否已读\n */\n hasRead: boolean;\n /**\n * 通知创建时间\n */\n createTime: string;\n}\n\n/**\n * 系统通知数据\n */\nexport interface INoticeSystem {\n /**\n * 消息的 oId\n */\n oId: string;\n /**\n * 用户 Id\n */\n userId: string;\n /**\n * 数据 Id\n */\n dataId: string;\n /**\n * 数据类型\n */\n dataType: DataType;\n /**\n * 消息描述\n */\n description: string;\n /**\n * 是否已读\n */\n hasRead: boolean;\n /**\n * 创建日期\n */\n createTime: string;\n}\n\nexport enum NoticeCommandType {\n /** 刷新通知 */\n RefreshNotification = 'refreshNotification',\n /**\n * 聊天未读数刷新\n */\n ChatUnreadCountRefresh = 'chatUnreadCountRefresh',\n /**\n * 新的闲聊消息\n */\n NewIdleChatMessage = 'newIdleChatMessage',\n /**\n * 系统广播警告\n */\n WarnBroadcast = 'warnBroadcast',\n /**\n * 清风明月更新\n */\n bzUpdate = 'bzUpdate',\n}\n\n/**\n * 通知消息\n */\nexport interface INoticeCommand {\n /**\n * 通知类型\n */\n command: NoticeCommandType;\n}\n\n/**\n * 未读消息数\n */\nexport interface INoticeUnReadCount extends INoticeCommand {\n /**\n * 未读数\n */\n count: number;\n}\n\n/**\n * 私聊通知\n */\nexport interface INoticeIdleChat extends INoticeCommand {\n senderUserName: string;\n senderAvatar: string;\n preview: string;\n}\n\n/**\n * 系统广播\n */\nexport interface INoticeWarnBroadcast extends INoticeCommand {\n warnBroadcastText: string;\n who: string;\n}\n\n/**\n * 清风明月更新\n */\nexport interface INoticeBreezemoon extends INoticeCommand {\n /**\n * 发布者用户名\n */\n breezemoonAuthorName: string;\n /**\n * 发布者头像\n */\n breezemoonAuthorThumbnailURL48: string;\n /**\n * 内容\n */\n breezemoonContent: string;\n /**\n * 清风明月ID\n */\n oId: string;\n}\n","export * from './article';\nexport * from './breezemoon';\nexport * from './chat';\nexport * from './chatroom';\nexport * from './redpacket';\nexport * from './user';\nexport * from './finger';\nexport * from './notice';\n\n/**\n * 数据类型\n */\nexport enum DataType {\n /**\n * 文章\n */\n article = 0,\n\n /**\n * 评论\n */\n comment = 1,\n\n /**\n * @\n */\n at = 2,\n\n /**\n * 被评论\n */\n commented = 3,\n\n /**\n * 关注者\n */\n followingUser = 4,\n\n /**\n * 积分 - 充值\n */\n pointCharge = 5,\n\n /**\n * 积分 - 转账\n */\n pointTransfer = 6,\n\n /**\n * 积分 - 文章打赏\n */\n pointArticleReward = 7,\n\n /**\n * 积分 - 评论感谢\n */\n pointCommentThank = 8,\n\n /**\n * 同城广播\n */\n broadcast = 9,\n\n /**\n * 积分 - 交易\n */\n pointExchange = 10,\n\n /**\n * 积分 - 滥用扣除\n */\n abusePointDeduct = 11,\n\n /**\n * 积分 - 文章被感谢\n */\n pointArticleThank = 12,\n\n /**\n * 回复\n */\n reply = 13,\n\n /**\n * 使用邀请码\n */\n invitecodeUsed = 14,\n\n /**\n * 系统公告 - 文章\n */\n sysAnnounceArticle = 15,\n\n /**\n * 系统公告 - 新用户\n */\n sysAnnounceNewUser = 16,\n\n /**\n * 新的关注者\n */\n newFollower = 17,\n\n /**\n * 邀请链接\n */\n invitationLinkUsed = 18,\n\n /**\n * 系统通知 - 角色变化\n */\n sysAnnounceRoleChanged = 19,\n\n /**\n * 关注的文章更新\n */\n followingArticleUpdate = 20,\n\n /**\n * 关注的文章评论\n */\n followingArticleComment = 21,\n\n /**\n * 积分 - 文章优选\n */\n pointPerfectArticle = 22,\n\n /**\n * 文章新的被关注者\n */\n articleNewFollower = 23,\n\n /**\n * 文章新的关注者\n */\n articleNewWatcher = 24,\n\n /**\n * 评论点赞\n */\n commentVoteUp = 25,\n\n /**\n * 评论点踩\n */\n commentVoteDown = 26,\n\n /**\n * 文章被点赞\n */\n articleVoteUp = 27,\n\n /**\n * 文章被点踩\n */\n articleVoteDown = 28,\n\n /**\n * 积分 - 评论被接受\n */\n pointCommentAccept = 33,\n\n /**\n * 积分 - 举报处理\n */\n pointReportHandled = 36,\n\n /**\n * 聊天室 @\n */\n chatRoomAt = 38,\n\n /**\n * 专属红包提醒\n */\n redPacket = 39,\n}\n\n/**\n * 用户角色类型\n */\nexport enum UserAppRole {\n /**\n * 黑客\n */\n Hack = 0,\n /**\n * 画家\n */\n Artist = 1,\n}\n\n/**\n * 举报数据类型\n */\nexport enum ReportDataType {\n /**\n * 文章\n */\n article = 0,\n /**\n * 评论\n */\n comment = 1,\n /**\n * 用户\n */\n user = 2,\n /**\n * 聊天消息\n */\n chatroom = 3,\n}\n\n/**\n * 举报类型\n */\nexport enum ReportType {\n /**\n * 垃圾广告\n */\n advertise = 0,\n /**\n * 色情\n */\n porn = 1,\n /**\n * 违规\n */\n violate = 2,\n /**\n * 侵权\n */\n infringement = 3,\n /**\n * 人身攻击\n */\n attacks = 4,\n /**\n * 冒充他人账号\n */\n impersonate = 5,\n /**\n * 垃圾广告账号\n */\n advertisingAccount = 6,\n /**\n * 违规泄露个人信息\n */\n leakPrivacy = 7,\n /**\n * 其它\n */\n other = 8,\n}\n\n/**\n * 登录信息\n */\nexport class Account implements IAccount {\n /**\n * 用户名\n */\n username: string = '';\n /**\n * 密码\n */\n passwd: string = '';\n /**\n * 二次验证码,非必填\n */\n mfaCode?: string = '';\n}\n\n/**\n * 注册信息\n */\nexport class PreRegisterInfo implements IPreRegisterInfo {\n /**\n * 用户名\n */\n username: string = '';\n /**\n * 手机号\n */\n phone: string = '';\n /**\n * 邀请码\n */\n invitecode?: string;\n /**\n * 验证码\n */\n captcha: string = '';\n}\n\n/**\n * 注册信息\n */\nexport class RegisterInfo implements IRegisterInfo {\n /**\n * 用户角色\n */\n role: string = '';\n /**\n * 用户密码\n */\n passwd: string = '';\n /**\n * 用户 Id\n */\n userId: string = '';\n /**\n * 邀请人用户名\n */\n r?: string;\n}\n\n/**\n * 举报接口数据\n */\nexport class Report implements IReport {\n /**\n * 举报对象的 oId\n */\n reportDataId: string = '';\n /**\n * 举报数据的类型\n */\n reportDataType: ReportDataType = ReportDataType.article;\n /**\n * 举报的类型\n */\n reportType: ReportType = ReportType.advertise;\n /**\n * 举报的理由\n */\n reportMemo: string = '';\n}\n\n/**\n * 登录信息\n */\nexport interface IAccount {\n /**\n * 用户名\n */\n username: string;\n /**\n * 密码\n */\n passwd: string;\n /**\n * 二次验证码,非必填\n */\n mfaCode?: string;\n}\n\n/**\n * 注册信息\n */\nexport interface IPreRegisterInfo {\n /**\n * 用户名\n */\n username: string;\n /**\n * 手机号\n */\n phone: string;\n /**\n * 邀请码\n */\n invitecode?: string;\n /**\n * 验证码\n */\n captcha: string;\n}\n\n/**\n * 注册信息\n */\nexport interface IRegisterInfo {\n /**\n * 用户角色\n */\n role: string;\n /**\n * 用户密码\n */\n passwd: string;\n /**\n * 用户 Id\n */\n userId: string;\n /**\n * 邀请人用户名\n */\n r?: string;\n}\n\n/**\n * 上传文件响应\n */\nexport interface IUploadInfo {\n /**\n * 上传失败文件\n */\n errFiles: string[];\n /**\n * 上传成功文件\n */\n succMap: {\n /**\n * Key 是文件名,value 为地址\n */\n [key: string]: string;\n };\n}\n\n/**\n * VIP 信息\n */\nexport interface IUserVIP {\n /**\n * VIP Id\n */\n oId: string;\n /**\n * VIP 状态\n */\n state: number;\n /**\n * 用户 Id\n */\n userId: string;\n /**\n * 是否 VIP\n */\n jointVip: boolean;\n /**\n * 颜色\n */\n color: string;\n /**\n * 是否有下划线\n */\n underline: boolean;\n /**\n * 是否有金属质感\n */\n metal: boolean;\n /**\n * 是否自动签到\n */\n autoCheckin: number;\n /**\n * 是否加粗\n */\n bold: boolean;\n /**\n * 等级代码\n */\n lvCode: string;\n /**\n * 过期时间\n */\n expiresAt: number;\n /**\n * 创建时间\n */\n createdAt: number;\n /**\n * 更新时间\n */\n updatedAt: number;\n}\n\nexport class UserVIP implements IUserVIP {\n /**\n * VIP Id\n */\n oId: string = '';\n /**\n * VIP 状态\n */\n state: number = 0;\n /**\n * 用户 Id\n */\n userId: string = '';\n /**\n * 是否 VIP\n */\n jointVip: boolean = false;\n /**\n * 颜色\n */\n color: string = '';\n /**\n * 是否有下划线\n */\n underline: boolean = false;\n /**\n * 是否有金属质感\n */\n metal: boolean = false;\n /**\n * 是否自动签到\n */\n autoCheckin: number = 0;\n /**\n * 是否加粗\n */\n bold: boolean = false;\n /**\n * 等级代码\n */\n lvCode: string = '';\n /**\n * 过期时间\n */\n expiresAt: number = 0;\n /**\n * 创建时间\n */\n createdAt: number = 0;\n /**\n * 更新时间\n */\n updatedAt: number = 0;\n\n get isVip(): boolean {\n return this.state === 1 && this.expiresAt * 1000 >= Date.now();\n }\n\n get vipName(): string {\n if (!this.isVip) return '非会员';\n return this.lvCode.replace(/_YEAR/, '(包年)').replace(/_MONTH/, '(包月)');\n }\n\n get expireDate(): Date {\n return new Date(this.expiresAt);\n }\n\n get createDate(): Date {\n return new Date(this.createdAt);\n }\n\n get updateDate(): Date {\n return new Date(this.updatedAt);\n }\n\n static from(data: any): UserVIP {\n const vip = new UserVIP();\n vip.oId = data.oId || '';\n vip.state = data.state || 0;\n vip.userId = data.userId || '';\n vip.jointVip = data.config?.jointVip || false;\n vip.color = data.config?.color || '';\n vip.underline = data.config?.underline || false;\n vip.metal = data.config?.metal || false;\n vip.autoCheckin = data.config?.autoCheckin || 0;\n vip.bold = data.config?.bold || false;\n vip.lvCode = data.lvCode || '';\n vip.expiresAt = data.expiresAt || 0;\n vip.createdAt = data.createdAt || 0;\n vip.updatedAt = data.updatedAt || 0;\n return vip;\n }\n}\n\n/**\n * 举报接口数据\n */\nexport interface IReport {\n /**\n * 举报对象的 oId\n */\n reportDataId: string;\n /**\n * 举报数据的类型\n */\n reportDataType: ReportDataType;\n /**\n * 举报的类型\n */\n reportType: ReportType;\n /**\n * 举报的理由\n */\n reportMemo: string;\n}\n\n/**\n * 禁言用户信息\n */\nexport interface IMuteItem {\n /**\n * 解除禁言时间戳\n */\n time: number;\n /**\n * 用户头像\n */\n userAvatarURL: string;\n /**\n * 用户名\n */\n userName: string;\n /**\n * 用户昵称\n */\n userNickname: string;\n}\n\nexport interface ILog {\n /**\n * 操作时间\n */\n key1: string;\n /**\n * IP\n */\n key2: string;\n /**\n * 内容\n */\n data: string;\n /**\n * 是否公开\n */\n public: boolean;\n /**\n * 操作类型\n */\n key3: string;\n /**\n * 唯一标识\n */\n oId: string;\n /**\n * 类型\n */\n type: string;\n}\n\nexport class Pagination {\n /**\n * 分页数\n */\n pageCount = 0;\n /**\n * 建议分页页码\n */\n pageNums: number[] = [];\n\n static from(data: any) {\n const p = new Pagination();\n p.pageCount = data.paginationPageCount;\n p.pageNums = data.paginationPageNums;\n return p;\n }\n}\n","import ReconnectingWebSocket, {\n Options as ReconnectingWebSocketOptions,\n} from 'reconnecting-websocket';\nimport { WebSocket, EventEmitter } from './utils';\n\nexport interface IWebSocketEvent {\n /**\n * Websocket 打开\n */\n open: (event: Event) => void;\n /**\n * Websocket 关闭\n */\n close: (event: CloseEvent) => void;\n /**\n * Websocket 错误\n */\n error: (error: ErrorEvent) => void;\n}\n\nexport class WsEventBase<T> {\n emitter = new EventEmitter();\n ws: ReconnectingWebSocket | null = null;\n rwsOptions: ReconnectingWebSocketOptions = {\n minReconnectionDelay: 10000,\n maxReconnectionDelay: 600000,\n reconnectionDelayGrowFactor: 1.3,\n maxRetries: 100,\n connectionTimeout: 10000,\n };\n constructor() {}\n\n /**\n * 重连通知频道\n * @returns Websocket 连接对象\n */\n reconnect() {\n if (!this.ws) return this.connect();\n return new Promise((resolve) => {\n if (!this.ws || this.ws.readyState === WebSocket.CONNECTING) return;\n this.ws.reconnect();\n this.ws.onopen = (e) => {\n resolve(this.ws!);\n };\n });\n }\n\n /**\n * 连接 WebSocket 频道\n * @returns Websocket 连接对象\n */\n connect(reload = false): Promise<ReconnectingWebSocket> {\n return new Promise(async (resolve, reject) => {\n if (this.ws && !reload) return resolve(this.ws);\n if (this.ws) this.ws.close();\n return reject(new Error('请在子类中实现 connect 方法'));\n });\n }\n\n /**\n * WebSocket 监听\n * @param event WebSocket 事件\n * @param listener 监听器\n */\n on<K extends keyof T>(event: K, listener: T[K]) {\n if (this.ws == null || this.ws.readyState !== WebSocket.OPEN) {\n this.connect();\n }\n return this.emitter.on(event as string, listener as (...args: any[]) => void);\n }\n\n /**\n * 移除 WebSocket 监听\n * @param event WebSocket 事件\n * @param listener 监听器\n */\n off<K extends keyof T>(event?: K, listener?: T[K]) {\n if (!event) return this.emitter.removeAllListeners();\n if (!listener) return this.emitter.removeAllListeners(event as string);\n return this.emitter.off(event as string, listener as (...args: any[]) => void);\n }\n\n /**\n * WebSocket 单次监听\n * @param event WebSocket 事件\n * @param listener 监听器\n */\n once<K extends keyof T>(event: K, listener: T[K]) {\n return this.emitter.once(event as string, listener as (...args: any[]) => void);\n }\n\n /**\n * 清除 WebSocket 监听\n */\n clearListener(event?: keyof T) {\n this.emitter.removeAllListeners(event as string);\n }\n\n /**\n * 移除 WebSocket 消息监听函数\n * @param event WebSocket 事件\n * @param listener 监听器\n */\n removeListener<K extends keyof T>(event: K, listener: T[K]) {\n return this.off(event, listener);\n }\n\n /**\n * 添加 WebSocket 消息监听函数\n * @param event WebSocket 事件\n * @param listener 监听器\n */\n addListener<K extends keyof T>(event: K, listener: T[K]) {\n return this.on(event, listener);\n }\n}\n","import ReconnectingWebSocket from 'reconnecting-websocket';\nimport { request, domain, toMetal, clientToVia, WebSocket } from './utils';\nimport {\n ChatContentType,\n ChatMessageType,\n GestureType,\n Redpacket,\n ClientType,\n IOnlineInfo,\n DiscussMsg,\n RevokeMsg,\n IBarragerMsg,\n IChatRoomMsg,\n IRedPacketInfo,\n IMusicMessage,\n IWeatherMessage,\n IRedPacketStatusMsg,\n CustomMsg,\n IChatRoomMessage,\n IMuteItem,\n IChatRoomNodeInfo,\n IRedpacket,\n} from './';\nimport { IWebSocketEvent, WsEventBase } from './ws';\n\ninterface IChatRoomEvents extends IWebSocketEvent {\n /**\n * 在线用户变更\n * @param onlines 在线用户\n */\n online: (onlines: IOnlineInfo[]) => void;\n /**\n * 话题变更\n * @param discuss 话题\n */\n discuss: (discuss: DiscussMsg) => void;\n /**\n * 撤回消息\n * @param oId 被撤回消息 oId\n */\n revoke: (oId: RevokeMsg) => void;\n /**\n * 弹幕消息\n * @param barrage 弹幕消息内容\n */\n barrager: (barrage: IBarragerMsg) => void;\n /**\n * 聊天消息\n * @param msg 聊天消息内容\n */\n msg: (msg: IChatRoomMsg) => void;\n /**\n * 红包消息\n * @param redpacket 红包内容\n */\n redPacket: (redpacket: IChatRoomMsg<IRedpacket>) => void;\n /**\n * 音乐消息\n * @param music 音乐消息内容\n */\n music: (music: IChatRoomMsg<IMusicMessage>) => void;\n /**\n * 天气消息\n * @param weather 天气消息内容\n */\n weather: (weather: IChatRoomMsg<IWeatherMessage>) => void;\n /**\n * 红包领取\n * @param status 红包领取状态\n */\n redPacketStatus: (status: IRedPacketStatusMsg) => void;\n /**\n * 进出通知\n * @param msg 进出通知内容\n */\n custom: (msg: CustomMsg) => void;\n /**\n * 发送所有消息\n * @param type 消息类型\n * @param data 消息内容\n */\n all: (type: string, data: any) => void;\n}\n\nexport class ChatRoom extends WsEventBase<IChatRoomEvents> {\n private apiKey: string = '';\n private _discusse: string = '';\n private _onlines: IOnlineInfo[] = [];\n private wsTimer: NodeJS.Timeout | null = null;\n private client: ClientType | string = ClientType.Other;\n private version: string = 'Latest';\n\n constructor(token: string = '') {\n super();\n if (!token) {\n return;\n }\n this.apiKey = token;\n }\n\n /**\n * 当前在线人数列表,需要先调用 addListener 添加聊天室消息监听\n */\n get onlines() {\n return this._onlines;\n }\n\n /**\n * 当前聊天室话题,需要先调用 addListener 添加聊天室消息监听\n */\n get discusse() {\n return this._discusse;\n }\n\n /**\n * 設置当前聊天室话题\n */\n set discusse(val) {\n this.send(`[setdiscuss]${val}[/setdiscuss]`).catch(() => {});\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(apiKey: string) {\n this.apiKey = apiKey;\n this.redpacket.setToken(apiKey);\n }\n\n /**\n * 设置当前来源类型\n * @param client 来源类型\n * @param version 版本号\n */\n setVia(client: ClientType | string, version: string) {\n this.client = client;\n this.version = version;\n }\n\n /**\n * 查询聊天室历史消息\n * @param page 消息页码\n * @param type 消息内容类型,HTML 或 Raw,默认 HTML\n */\n async history(page = 1, type = ChatContentType.HTML): Promise<IChatRoomMessage[]> {\n try {\n let rsp = await request({\n url: `chat-room/more?page=${page}&type=${type}&apiKey=${this.apiKey}`,\n });\n\n if (rsp.code != 0) {\n throw new Error(rsp.msg);\n }\n\n if (!rsp.data) return rsp;\n (rsp.data as Array<any>).forEach((d, i, data) => {\n try {\n data[i].type = 'msg';\n data[i].md = data[i].content;\n data[i].via = clientToVia(data[i].client);\n data[i].sysMetal = toMetal(data[i].sysMetal);\n data[i].content = JSON.parse(d.content);\n if (data[i].content.recivers)\n data[i].content.recivers = JSON.parse(data[i].content.recivers);\n data[i].type = data[i].content.msgType;\n } catch (e) {}\n });\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取指定消息附近的聊天室消息\n * @param oId 消息 Id\n * @param mode 获取模式,context 上下文模式,after 之后模式\n * @param size 获取消息数量,默认 25,最大 100\n * @param type 获取消息类型,默认 HTML\n */\n async get({\n oId,\n mode = ChatMessageType.Context,\n size = 25,\n type = ChatContentType.HTML,\n }: {\n oId: string;\n mode?: ChatMessageType;\n size?: number;\n type?: ChatContentType;\n }): Promise<IChatRoomMessage[]> {\n try {\n let rsp = await request({\n url: `chat-room/getMessage?oId=${oId}&mode=${mode}&size=${size}&type=${type}&apiKey=${this.apiKey}`,\n });\n\n if (rsp.code != 0) {\n throw new Error(rsp.msg);\n }\n\n if (!rsp.data) return rsp;\n let content;\n (rsp.data as any[]).forEach((d, i, data) => {\n try {\n data[i].via = clientToVia(data[i].client);\n data[i].sysMetal = toMetal(data[i].sysMetal);\n content = JSON.parse(d.content);\n if (content.msgType !== 'redPacket') return rsp;\n if (content.recivers) content.recivers = JSON.parse(content.recivers);\n data[i].content = content;\n } catch (e) {}\n });\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 撤回消息,普通成员 24 小时内可撤回一条自己的消息,纪律委员/OP/管理员角色可以撤回任意人消息\n * @param oId 消息 Id\n */\n async revoke(oId: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `chat-room/revoke/${oId}`,\n method: 'delete',\n data: {\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 发送一条消息\n * @param msg 消息内容,支持 Markdown\n */\n async send(msg: string, clientType?: ClientType | string, version?: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `chat-room/send`,\n method: 'post',\n data: {\n content: msg,\n client: `${clientType || this.client}/${version || this.version}`,\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 发送一条弹幕\n * @param msg 消息内容,支持 Markdown\n * @param color 弹幕颜色\n */\n async barrage(msg: string, color: string = '#ffffff'): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `chat-room/send`,\n method: 'post',\n data: {\n content: `[barrager]{\\\"color\\\":\\\"${color}\\\",\\\"content\\\":\\\"${msg}\\\"}[/barrager]`,\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取弹幕发送价格\n * @returns 返回价格`cost`与单位`unit`\n */\n async barragePay(): Promise<{ cost: number; unit: string }> {\n let rsp;\n try {\n rsp = await request({\n url: `chat-room/barrager/get?apiKey=${this.apiKey}`,\n method: 'get',\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n // 解析格式如 \"5积分\" 的字符串\n const mat = rsp.data.match(/([-0-9]+)(.+)/);\n if (mat) {\n return {\n cost: parseInt(mat[1]),\n unit: mat[2],\n };\n }\n\n return {\n cost: 20,\n unit: '积分',\n };\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取禁言中成员列表(思过崖)\n */\n async mutes(): Promise<IMuteItem[]> {\n let rsp;\n try {\n rsp = await request({\n url: `chat-room/si-guo-list`,\n method: 'get',\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取消息原文(比如 Markdown)\n * @param oId 消息 Id\n */\n async raw(oId: string): Promise<string> {\n let rsp;\n try {\n rsp = await request({\n url: `cr/raw/${oId}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.replace(/<!--.*?-->/g, '');\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 红包接口对象\n */\n redpacket = new RedPacket(this, this.apiKey);\n\n /**\n * 获取聊天室节点\n * @returns 返回节点地址\n */\n async getNode(): Promise<IChatRoomNodeInfo> {\n let rsp: any;\n try {\n rsp = await request({\n url: `chat-room/node/get?apiKey=${this.apiKey}`,\n method: 'get',\n });\n\n if (rsp.code != 0) throw new Error('获取节点失败:' + rsp.msg);\n\n return {\n recommend: {\n node: rsp.data,\n name: rsp.msg,\n online: rsp.avaliable.find((n: any) => n.node === rsp.data)?.online || 0,\n },\n avaliable: rsp.avaliable,\n };\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 连接聊天室\n * @param url 聊天室节点地址\n * @param timeout 超时时间,单位为秒,默认为 10\n * @returns 返回 Open Event\n */\n async connect(reload?: boolean): Promise<ReconnectingWebSocket>;\n async connect(url?: string, timeout?: number): Promise<ReconnectingWebSocket>;\n async connect(urlOrReload?: string | boolean, timeout: number = 10) {\n return new Promise(async (resolve) => {\n let url: string = '';\n if (urlOrReload === undefined || urlOrReload === '' || urlOrReload === true) {\n url = await this.getNode()\n .then((rsp) => rsp.recommend.node)\n .catch(() => `wss://${domain}/chat-room-channel?apiKey=${this.apiKey}`);\n } else {\n url = urlOrReload as string;\n }\n if (!url.includes('apiKey=')) url += `${url.includes('?') ? '&' : '?'}apiKey=${this.apiKey}`;\n if (this.ws) return resolve(this.reconnect());\n this.ws = new ReconnectingWebSocket(url, [], {\n WebSocket,\n ...this.rwsOptions,\n connectionTimeout: 1000 * timeout,\n });\n\n this.ws.onopen = (e) => {\n if (this.wsTimer) {\n clearInterval(this.wsTimer);\n }\n this.wsTimer = setInterval(\n () => {\n this.ws?.send('-hb-');\n },\n 1000 * 60 * 3,\n );\n resolve(e);\n this.emitter.emit('open', e);\n };\n this.ws.onmessage = async (e) => {\n let msg = JSON.parse(e.data);\n let data: any | null = null;\n switch (msg.type) {\n case 'online': {\n this._onlines = msg.users;\n this._discusse = msg.discussing;\n data = this._onlines;\n break;\n }\n case 'discussChanged': {\n data = msg.newDiscuss;\n msg.type = 'discuss';\n break;\n }\n case 'revoke': {\n data = msg.oId;\n break;\n }\n case 'barrager': {\n let {\n barragerContent,\n userAvatarURL,\n userAvatarURL20,\n userNickname,\n barragerColor,\n userName,\n userAvatarURL210,\n userAvatarURL48,\n } = msg;\n data = {\n barragerContent,\n userAvatarURL,\n userAvatarURL20,\n userNickname,\n barragerColor,\n userName,\n userAvatarURL210,\n userAvatarURL48,\n };\n break;\n }\n case 'msg': {\n let { userOId, oId, time, userName, userNickname, userAvatarURL, content, md, client } =\n msg;\n try {\n let data = JSON.parse(content);\n if (['redPacket', 'music', 'weather'].includes(data.msgType)) {\n content = data;\n msg.type = data.msgType;\n }\n } catch (e) {}\n data = {\n type: msg.type,\n userOId,\n oId,\n time,\n userName,\n userNickname,\n userAvatarURL,\n content,\n md,\n client,\n via: clientToVia(client),\n };\n break;\n }\n case 'redPacketStatus': {\n let { oId, count, got, whoGive, whoGot } = msg;\n data = { oId, count, got, whoGive, whoGot };\n break;\n }\n case 'customMessage': {\n data = msg.message;\n msg.type = 'custom';\n break;\n }\n }\n this.emitter.emit(msg.type, data);\n this.emitter.emit('all', data);\n };\n this.ws.onerror = (e) => {\n this.emitter.emit('error', e);\n };\n this.ws.onclose = (e) => {\n this.emitter.emit('close', e);\n };\n });\n }\n}\n\nclass RedPacket {\n private chatroom: ChatRoom;\n private apiKey: string = '';\n\n constructor(chatroom: ChatRoom, apiKey: string) {\n this.chatroom = chatroom;\n this.apiKey = apiKey;\n }\n\n setToken(apiKey: string) {\n this.apiKey = apiKey;\n }\n\n /**\n * 打开一个红包\n * @param oId 红包消息 Id\n * @param gesture 猜拳类型\n */\n async open(oId: string, gesture?: GestureType): Promise<IRedPacketInfo> {\n let rsp;\n try {\n rsp = await request({\n url: `chat-room/red-packet/open`,\n method: 'post',\n data: {\n oId,\n gesture,\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 发送一个红包\n * @param redpacket 红包对象\n */\n async send(redpacket: Redpacket) {\n return await this.chatroom.send(`[redpacket]${JSON.stringify(redpacket)}[/redpacket]`);\n }\n}\n","import ReconnectingWebSocket from 'reconnecting-websocket';\nimport {\n INoticeBreezemoon,\n INoticeCount,\n INoticeIdleChat,\n INoticeUnReadCount,\n INoticeWarnBroadcast,\n NoticeList,\n NoticeType,\n} from './';\nimport { domain, request, WebSocket } from './utils';\nimport { IWebSocketEvent, WsEventBase } from './ws';\n\ninterface INoticeEvents extends IWebSocketEvent {\n /**\n * 清风明月更新\n * @param data 清风明月\n */\n bzUpdate: (data: INoticeBreezemoon) => void;\n /**\n * 未读消息数通知\n * @param data 未读消息数\n */\n refreshNotification: (data: INoticeUnReadCount) => void;\n /**\n * 聊天未读消息数通知\n * @param data 聊天未读消息数\n */\n chatUnreadCountRefresh: (data: INoticeUnReadCount) => void;\n /**\n * 新私聊消息通知\n * @param data 新私聊消息\n */\n newIdleChatMessage: (data: INoticeIdleChat) => void;\n /**\n * 警告广播消息通知\n * @param data 警告广播消息\n */\n warnBroadcast: (data: INoticeWarnBroadcast) => void;\n}\n\nexport class Notice extends WsEventBase<INoticeEvents> {\n private apiKey: string = '';\n\n constructor(token: string = '') {\n super();\n if (!token) {\n return;\n }\n this.apiKey = token;\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(token: string) {\n this.apiKey = token;\n }\n\n /**\n * 获取未读消息数\n */\n async count(): Promise<INoticeCount> {\n let rsp;\n try {\n rsp = await request({\n url: `notifications/unread/count?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code !== 0) throw new Error(rsp.msg);\n\n if (rsp.userNotifyStatus) rsp.userNotifyStatus = rsp.userNotifyStatus != 0;\n return rsp;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取消息列表\n * @param type 消息类型\n */\n async list(type: NoticeType): Promise<NoticeList> {\n let rsp;\n try {\n rsp = await request({\n url: `api/getNotifications?apiKey=${this.apiKey}&type=${type}`,\n });\n\n if (rsp.code !== 0) throw new Error(rsp.msg);\n\n rsp.data.forEach((n: any) => {\n if (!n.description && n.content) n.description = n.content;\n return n;\n });\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 已读指定类型消息\n * @param type 消息类型\n */\n async makeRead(type: NoticeType): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `notifications/make-read/${type}?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code !== 0) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 已读所有消息\n */\n async readAll(): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `notifications/all-read?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code !== 0) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 重连通知频道\n * @returns Websocket 连接对象\n */\n reconnect() {\n if (!this.ws) return this.connect();\n return new Promise((resolve) => {\n if (!this.ws) return;\n this.ws.reconnect();\n this.ws.onopen = (e) => {\n resolve(this.ws!);\n };\n });\n }\n\n /**\n * 连接用户私聊频道\n * @returns Websocket 连接对象\n */\n connect(reload = false): Promise<ReconnectingWebSocket> {\n return new Promise(async (resolve, reject) => {\n if (this.ws && !reload) return resolve(this.ws);\n if (this.ws) this.ws.close();\n if (!this.apiKey) return reject(new Error('请先设置 API Key'));\n this.ws = new ReconnectingWebSocket(\n `wss://${domain}/user-channel?apiKey=${this.apiKey}`,\n [],\n {\n WebSocket,\n connectionTimeout: 10000,\n maxRetries: 10,\n },\n );\n this.ws.onopen = (e) => {\n resolve(this.ws!);\n };\n this.ws.onmessage = async (e) => {\n let msg = JSON.parse(e.data);\n if (msg.command == 'bz-update') {\n msg = { ...msg.bz, command: 'bzUpdate' };\n }\n if (msg.command) {\n this.emitter.emit(msg.command, msg);\n }\n };\n this.ws.onerror = (e) => {\n this.emitter.emit('error', e);\n };\n this.ws.onclose = (e) => {\n this.emitter.emit('close', e);\n };\n });\n }\n}\n","import { request, domain } from './utils';\n\nexport class Emoji {\n private apiKey: string = '';\n private emojis: string[] = [];\n\n constructor(token: string = '') {\n if (!token) {\n return;\n }\n this.setToken(token);\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(token: string) {\n this.apiKey = token;\n if (token)\n this.get()\n .then((e) => (this.emojis = e))\n .catch(() => {});\n }\n\n get default() {\n return {\n doge: 'https://cdn.jsdelivr.net/npm/vditor@3.8.7/dist/images/emoji/doge.png',\n trollface: 'https://cdn.jsdelivr.net/npm/vditor@3.8.7/dist/images/emoji/trollface.png',\n huaji: 'https://cdn.jsdelivr.net/npm/vditor@3.8.7/dist/images/emoji/huaji.gif',\n octocat: 'https://cdn.jsdelivr.net/npm/vditor@3.8.7/dist/images/emoji/octocat.png',\n wulian: 'https://cdn.jsdelivr.net/npm/vditor@3.8.7/dist/images/emoji/wulian.png',\n smile: `https://file.${domain}/emoji/graphics/smile.png`,\n laughing: `https://file.${domain}/emoji/graphics/laughing.png`,\n blush: `https://file.${domain}/emoji/graphics/blush.png`,\n smiley: `https://file.${domain}/emoji/graphics/smiley.png`,\n relaxed: `https://file.${domain}/emoji/graphics/relaxed.png`,\n smirk: `https://file.${domain}/emoji/graphics/smirk.png`,\n heart_eyes: `https://file.${domain}/emoji/graphics/heart_eyes.png`,\n kissing_heart: `https://file.${domain}/emoji/graphics/kissing_heart.png`,\n kissing_closed_eyes: `https://file.${domain}/emoji/graphics/kissing_closed_eyes.png`,\n flushed: `https://file.${domain}/emoji/graphics/flushed.png`,\n relieved: `https://file.${domain}/emoji/graphics/relieved.png`,\n satisfied: `https://file.${domain}/emoji/graphics/satisfied.png`,\n grin: `https://file.${domain}/emoji/graphics/grin.png`,\n wink: `https://file.${domain}/emoji/graphics/wink.png`,\n stuck_out_tongue_winking_eye: `https://file.${domain}/emoji/graphics/stuck_out_tongue_winking_eye.png`,\n stuck_out_tongue_closed_eyes: `https://file.${domain}/emoji/graphics/stuck_out_tongue_closed_eyes.png`,\n grinning: `https://file.${domain}/emoji/graphics/grinning.png`,\n kissing: `https://file.${domain}/emoji/graphics/kissing.png`,\n kissing_smiling_eyes: `https://file.${domain}/emoji/graphics/kissing_smiling_eyes.png`,\n stuck_out_tongue: `https://file.${domain}/emoji/graphics/stuck_out_tongue.png`,\n sleeping: `https://file.${domain}/emoji/graphics/sleeping.png`,\n worried: `https://file.${domain}/emoji/graphics/worried.png`,\n frowning: `https://file.${domain}/emoji/graphics/frowning.png`,\n anguished: `https://file.${domain}/emoji/graphics/anguished.png`,\n open_mouth: `https://file.${domain}/emoji/graphics/open_mouth.png`,\n grimacing: `https://file.${domain}/emoji/graphics/grimacing.png`,\n confused: `https://file.${domain}/emoji/graphics/confused.png`,\n hushed: `https://file.${domain}/emoji/graphics/hushed.png`,\n expressionless: `https://file.${domain}/emoji/graphics/expressionless.png`,\n unamused: `https://file.${domain}/emoji/graphics/unamused.png`,\n sweat_smile: `https://file.${domain}/emoji/graphics/sweat_smile.png`,\n sweat: `https://file.${domain}/emoji/graphics/sweat.png`,\n disappointed_relieved: `https://file.${domain}/emoji/graphics/disappointed_relieved.png`,\n weary: `https://file.${domain}/emoji/graphics/weary.png`,\n pensive: `https://file.${domain}/emoji/graphics/pensive.png`,\n disappointed: `https://file.${domain}/emoji/graphics/disappointed.png`,\n confounded: `https://file.${domain}/emoji/graphics/confounded.png`,\n fearful: `https://file.${domain}/emoji/graphics/fearful.png`,\n cold_sweat: `https://file.${domain}/emoji/graphics/cold_sweat.png`,\n persevere: `https://file.${domain}/emoji/graphics/persevere.png`,\n cry: `https://file.${domain}/emoji/graphics/cry.png`,\n sob: `https://file.${domain}/emoji/graphics/sob.png`,\n joy: `https://file.${domain}/emoji/graphics/joy.png`,\n astonished: `https://file.${domain}/emoji/graphics/astonished.png`,\n scream: `https://file.${domain}/emoji/graphics/scream.png`,\n tired_face: `https://file.${domain}/emoji/graphics/tired_face.png`,\n angry: `https://file.${domain}/emoji/graphics/angry.png`,\n rage: `https://file.${domain}/emoji/graphics/rage.png`,\n triumph: `https://file.${domain}/emoji/graphics/triumph.png`,\n sleepy: `https://file.${domain}/emoji/graphics/sleepy.png`,\n yum: `https://file.${domain}/emoji/graphics/yum.png`,\n mask: `https://file.${domain}/emoji/graphics/mask.png`,\n sunglasses: `https://file.${domain}/emoji/graphics/sunglasses.png`,\n dizzy_face: `https://file.${domain}/emoji/graphics/dizzy_face.png`,\n imp: `https://file.${domain}/emoji/graphics/imp.png`,\n smiling_imp: `https://file.${domain}/emoji/graphics/smiling_imp.png`,\n neutral_face: `https://file.${domain}/emoji/graphics/neutral_face.png`,\n no_mouth: `https://file.${domain}/emoji/graphics/no_mouth.png`,\n innocent: `https://file.${domain}/emoji/graphics/innocent.png`,\n alien: `https://file.${domain}/emoji/graphics/alien.png`,\n yellow_heart: `https://file.${domain}/emoji/graphics/yellow_heart.png`,\n blue_heart: `https://file.${domain}/emoji/graphics/blue_heart.png`,\n purple_heart: `https://file.${domain}/emoji/graphics/purple_heart.png`,\n heart: `https://file.${domain}/emoji/graphics/heart.png`,\n green_heart: `https://file.${domain}/emoji/graphics/green_heart.png`,\n broken_heart: `https://file.${domain}/emoji/graphics/broken_heart.png`,\n heartbeat: `https://file.${domain}/emoji/graphics/heartbeat.png`,\n heartpulse: `https://file.${domain}/emoji/graphics/heartpulse.png`,\n two_hearts: `https://file.${domain}/emoji/graphics/two_hearts.png`,\n revolving_hearts: `https://file.${domain}/emoji/graphics/revolving_hearts.png`,\n cupid: `https://file.${domain}/emoji/graphics/cupid.png`,\n sparkling_heart: `https://file.${domain}/emoji/graphics/sparkling_heart.png`,\n sparkles: `https://file.${domain}/emoji/graphics/sparkles.png`,\n star: `https://file.${domain}/emoji/graphics/star.png`,\n star2: `https://file.${domain}/emoji/graphics/star2.png`,\n dizzy: `https://file.${domain}/emoji/graphics/dizzy.png`,\n boom: `https://file.${domain}/emoji/graphics/boom.png`,\n collision: `https://file.${domain}/emoji/graphics/collision.png`,\n anger: `https://file.${domain}/emoji/graphics/anger.png`,\n exclamation: `https://file.${domain}/emoji/graphics/exclamation.png`,\n question: `https://file.${domain}/emoji/graphics/question.png`,\n grey_exclamation: `https://file.${domain}/emoji/graphics/grey_exclamation.png`,\n grey_question: `https://file.${domain}/emoji/graphics/grey_question.png`,\n zzz: `https://file.${domain}/emoji/graphics/zzz.png`,\n dash: `https://file.${domain}/emoji/graphics/dash.png`,\n sweat_drops: `https://file.${domain}/emoji/graphics/sweat_drops.png`,\n notes: `https://file.${domain}/emoji/graphics/notes.png`,\n musical_note: `https://file.${domain}/emoji/graphics/musical_note.png`,\n fire: `https://file.${domain}/emoji/graphics/fire.png`,\n poop: `https://file.${domain}/emoji/graphics/poop.png`,\n '+1': `https://file.${domain}/emoji/graphics/%2B1.png`,\n thumbsup: `https://file.${domain}/emoji/graphics/thumbsup.png`,\n '-1': `https://file.${domain}/emoji/graphics/-1.png`,\n thumbsdown: `https://file.${domain}/emoji/graphics/thumbsdown.png`,\n ok_hand: `https://file.${domain}/emoji/graphics/ok_hand.png`,\n punch: `https://file.${domain}/emoji/graphics/punch.png`,\n facepunch: `https://file.${domain}/emoji/graphics/facepunch.png`,\n fist: `https://file.${domain}/emoji/graphics/fist.png`,\n v: `https://file.${domain}/emoji/graphics/v.png`,\n wave: `https://file.${domain}/emoji/graphics/wave.png`,\n hand: `https://file.${domain}/emoji/graphics/hand.png`,\n raised_hand: `https://file.${domain}/emoji/graphics/raised_hand.png`,\n open_hands: `https://file.${domain}/emoji/graphics/open_hands.png`,\n point_up: `https://file.${domain}/emoji/graphics/point_up.png`,\n point_down: `https://file.${domain}/emoji/graphics/point_down.png`,\n point_left: `https://file.${domain}/emoji/graphics/point_left.png`,\n point_right: `https://file.${domain}/emoji/graphics/point_right.png`,\n raised_hands: `https://file.${domain}/emoji/graphics/raised_hands.png`,\n pray: `https://file.${domain}/emoji/graphics/pray.png`,\n point_up_2: `https://file.${domain}/emoji/graphics/point_up_2.png`,\n clap: `https://file.${domain}/emoji/graphics/clap.png`,\n muscle: `https://file.${domain}/emoji/graphics/muscle.png`,\n couple: `https://file.${domain}/emoji/graphics/couple.png`,\n family: `https://file.${domain}/emoji/graphics/family.png`,\n two_men_holding_hands: `https://file.${domain}/emoji/graphics/two_men_holding_hands.png`,\n two_women_holding_hands: `https://file.${domain}/emoji/graphics/two_women_holding_hands.png`,\n dancer: `https://file.${domain}/emoji/graphics/dancer.png`,\n dancers: `https://file.${domain}/emoji/graphics/dancers.png`,\n ok_woman: `https://file.${domain}/emoji/graphics/ok_woman.png`,\n no_good: `https://file.${domain}/emoji/graphics/no_good.png`,\n information_desk_person: `https://file.${domain}/emoji/graphics/information_desk_person.png`,\n raising_hand: `https://file.${domain}/emoji/graphics/raising_hand.png`,\n bride_with_veil: `https://file.${domain}/emoji/graphics/bride_with_veil.png`,\n person_with_pouting_face: `https://file.${domain}/emoji/graphics/person_with_pouting_face.png`,\n person_frowning: `https://file.${domain}/emoji/graphics/person_frowning.png`,\n bow: `https://file.${domain}/emoji/graphics/bow.png`,\n couplekiss: `https://file.${domain}/emoji/graphics/couplekiss.png`,\n couple_with_heart: `https://file.${domain}/emoji/graphics/couple_with_heart.png`,\n massage: `https://file.${domain}/emoji/graphics/massage.png`,\n haircut: `https://file.${domain}/emoji/graphics/haircut.png`,\n nail_care: `https://file.${domain}/emoji/graphics/nail_care.png`,\n boy: `https://file.${domain}/emoji/graphics/boy.png`,\n girl: `https://file.${domain}/emoji/graphics/girl.png`,\n woman: `https://file.${domain}/emoji/graphics/woman.png`,\n man: `https://file.${domain}/emoji/graphics/man.png`,\n baby: `https://file.${domain}/emoji/graphics/baby.png`,\n older_woman: `https://file.${domain}/emoji/graphics/older_woman.png`,\n older_man: `https://file.${domain}/emoji/graphics/older_man.png`,\n person_with_blond_hair: `https://file.${domain}/emoji/graphics/person_with_blond_hair.png`,\n man_with_gua_pi_mao: `https://file.${domain}/emoji/graphics/man_with_gua_pi_mao.png`,\n man_with_turban: `https://file.${domain}/emoji/graphics/man_with_turban.png`,\n construction_worker: `https://file.${domain}/emoji/graphics/construction_worker.png`,\n cop: `https://file.${domain}/emoji/graphics/cop.png`,\n angel: `https://file.${domain}/emoji/graphics/angel.png`,\n princess: `https://file.${domain}/emoji/graphics/princess.png`,\n smiley_cat: `https://file.${domain}/emoji/graphics/smiley_cat.png`,\n smile_cat: `https://file.${domain}/emoji/graphics/smile_cat.png`,\n heart_eyes_cat: `https://file.${domain}/emoji/graphics/heart_eyes_cat.png`,\n kissing_cat: `https://file.${domain}/emoji/graphics/kissing_cat.png`,\n smirk_cat: `https://file.${domain}/emoji/graphics/smirk_cat.png`,\n scream_cat: `https://file.${domain}/emoji/graphics/scream_cat.png`,\n crying_cat_face: `https://file.${domain}/emoji/graphics/crying_cat_face.png`,\n joy_cat: `https://file.${domain}/emoji/graphics/joy_cat.png`,\n pouting_cat: `https://file.${domain}/emoji/graphics/pouting_cat.png`,\n japanese_ogre: `https://file.${domain}/emoji/graphics/japanese_ogre.png`,\n japanese_goblin: `https://file.${domain}/emoji/graphics/japanese_goblin.png`,\n see_no_evil: `https://file.${domain}/emoji/graphics/see_no_evil.png`,\n hear_no_evil: `https://file.${domain}/emoji/graphics/hear_no_evil.png`,\n speak_no_evil: `https://file.${domain}/emoji/graphics/speak_no_evil.png`,\n guardsman: `https://file.${domain}/emoji/graphics/guardsman.png`,\n skull: `https://file.${domain}/emoji/graphics/skull.png`,\n feet: `https://file.${domain}/emoji/graphics/feet.png`,\n lips: `https://file.${domain}/emoji/graphics/lips.png`,\n kiss: `https://file.${domain}/emoji/graphics/kiss.png`,\n droplet: `https://file.${domain}/emoji/graphics/droplet.png`,\n ear: `https://file.${domain}/emoji/graphics/ear.png`,\n eyes: `https://file.${domain}/emoji/graphics/eyes.png`,\n nose: `https://file.${domain}/emoji/graphics/nose.png`,\n tongue: `https://file.${domain}/emoji/graphics/tongue.png`,\n love_letter: `https://file.${domain}/emoji/graphics/love_letter.png`,\n bust_in_silhouette: `https://file.${domain}/emoji/graphics/bust_in_silhouette.png`,\n busts_in_silhouette: `https://file.${domain}/emoji/graphics/busts_in_silhouette.png`,\n speech_balloon: `https://file.${domain}/emoji/graphics/speech_balloon.png`,\n thought_balloon: `https://file.${domain}/emoji/graphics/thought_balloon.png`,\n };\n }\n\n async get(): Promise<string[]> {\n let rsp;\n try {\n rsp = await request({\n url: `api/cloud/get`,\n method: 'post',\n data: {\n gameId: 'emojis',\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n this.emojis = JSON.parse(rsp.data);\n return this.emojis.concat([]);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 设置表情包列表\n * @param data 所有表情包图像列表\n */\n async set(data: string[]) {\n let rsp;\n try {\n rsp = await request({\n url: `api/cloud/sync`,\n method: 'post',\n data: {\n gameId: 'emojis',\n data: JSON.stringify(data),\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp;\n } catch (e) {\n throw e;\n }\n }\n\n async append(url: string): Promise<string[]> {\n let emojis = this.emojis.length > 0 ? this.emojis : await this.get();\n if (emojis.indexOf(url) >= 0) throw new Error('表情包已存在');\n emojis.push(url);\n await this.set(emojis);\n this.emojis = emojis;\n return emojis.concat([]);\n }\n\n async remove(url: string): Promise<string[]> {\n let emojis = this.emojis.length > 0 ? this.emojis : await this.get();\n if (emojis.indexOf(url) < 0) return emojis;\n emojis.splice(emojis.indexOf(url), 1);\n await this.set(emojis);\n this.emojis = emojis;\n return emojis.concat([]);\n }\n\n async exists(url: string): Promise<Boolean> {\n let emojis = this.emojis.length > 0 ? this.emojis : await this.get();\n return emojis.indexOf(url) >= 0;\n }\n}\n","import { UserInfo, UserUpdateParams } from './';\nimport { request, toMetal } from './utils';\n\nexport class User {\n private apiKey: string = '';\n\n constructor(token: string = '') {\n if (!token) {\n return;\n }\n this.apiKey = token;\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(token: string) {\n this.apiKey = token;\n }\n\n /**\n * 返回登录账户信息,需要先登录或设置有效的 api key\n * @returns 用户信息\n */\n async info(): Promise<UserInfo> {\n try {\n let rsp = await request({\n url: `api/user?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n if (rsp.data) rsp.data.sysMetal = toMetal(rsp.data.sysMetal);\n\n return UserInfo.from(rsp.data);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询登录用户常用表情\n * @returns 常用表情列表\n */\n async emotions(): Promise<Array<string>> {\n let rsp;\n try {\n rsp = await request({\n url: `users/emotions?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n rsp.data = Object.keys(rsp.data);\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询登录用户当前活跃度,请求频率请控制在 30 ~ 60 秒一次\n * @returns 活跃度\n */\n async liveness(): Promise<number> {\n if (!this.apiKey) {\n return 0;\n }\n try {\n let rsp = await request({\n url: `user/liveness?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.liveness || 0;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 检查登录用户是否已经签到\n * @returns 是否已经签到\n */\n async isCheckIn(): Promise<boolean> {\n if (!this.apiKey) {\n return false;\n }\n try {\n let rsp = await request({\n url: `user/checkedIn?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.checkedIn || false;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 检查登录用户是否已经领取昨日活跃奖励\n * @returns 是否已经领取昨日活跃奖励\n */\n async isCollectedLiveness(): Promise<boolean> {\n if (!this.apiKey) {\n return false;\n }\n try {\n let rsp = await request({\n url: `api/activity/is-collected-liveness?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.isCollectedYesterdayLivenessReward || false;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 领取昨日活跃度奖励\n * @returns sum 领取的奖励积分\n */\n async rewardLiveness(): Promise<number> {\n if (!this.apiKey) {\n return 0;\n }\n try {\n let rsp = await request({\n url: `activity/yesterday-liveness-reward-api?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.sum || 0;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 转账\n * @param userName 转账目标用户名\n * @param amount 转账金额\n * @param memo 转账备注\n * @returns code 0 为成功,失败则有 msg\n */\n async transfer(userName: string, amount: number, memo: string): Promise<void> {\n try {\n let rsp = await request({\n method: 'POST',\n url: `point/transfer`,\n data: {\n apiKey: this.apiKey,\n userName,\n amount,\n memo,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 关注用户\n * @param followingId 用户id\n */\n async follow(followingId: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `follow/user`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n followingId,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 取消关注用户\n * @param followingId 用户id\n */\n async unfollow(followingId: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `unfollow/user`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n followingId,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 修改用户头像\n * @param userAvatarURL 用户头像地址\n */\n async updateUserAvatar(userAvatarURL: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `api/settings/avatar`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n userAvatarURL,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 修改用户信息\n * @param data 用户信息参数\n */\n async updateUserInfo(data: UserUpdateParams): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `api/settings/profiles`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n ...data,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n}\n","import { domain, request, WebSocket } from './utils';\nimport ReconnectingWebSocket from 'reconnecting-websocket';\nimport {\n ArticleListType,\n ArticlePost,\n ArticleType,\n ArticleDetail,\n ArticleList,\n VoteType,\n IArticlePost,\n IArticleHeat,\n ArticleComment,\n} from './';\nimport { IWebSocketEvent, WsEventBase } from './ws';\n\ninterface IArticleEvents extends IWebSocketEvent {\n heat: (msg: IArticleHeat) => void;\n comment: (msg: ArticleComment) => void;\n}\n\nexport class Article {\n private apiKey: string = '';\n private channels: { [key: string]: ArticleChannel } = {};\n\n constructor(token: string = '') {\n if (!token) {\n return;\n }\n this.apiKey = token;\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(token: string) {\n this.apiKey = token;\n }\n\n /**\n * 发布文章\n * @param data 文章信息\n * @returns 发布成功返回文章Id (articleId)\n */\n async post(data: IArticlePost): Promise<string> {\n let rsp;\n try {\n rsp = await request({\n url: `article`,\n method: 'post',\n data: {\n ...ArticlePost.from(data).toJson(),\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.articleId;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 更新文章\n * @param id 文章 Id\n * @param data 文章信息\n * @returns 更新成功返回文章Id (articleId)\n */\n async update(id: string, data: IArticlePost): Promise<string> {\n let rsp;\n try {\n rsp = await request({\n url: `article/${id}`,\n method: 'put',\n data: {\n ...ArticlePost.from(data).toJson(),\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.articleId;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询文章列表\n * @param type 查询类型\n * @param tag 指定查询标签,可选\n * @returns 文章列表\n */\n async list({\n type,\n page = 1,\n size = 20,\n tag,\n }: {\n type: ArticleListType;\n page?: number;\n size?: number;\n tag?: string;\n }): Promise<ArticleList> {\n let rsp;\n try {\n rsp = await request({\n url: `api/articles/${\n tag ? `tag/${tag}` : 'recent'\n }${type}?p=${page}&size=${size}&${this.apiKey ? `apiKey=${this.apiKey}` : ''}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return ArticleList.from(rsp.data);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询用户文章列表\n * @param userName 用户名\n * @param page 页码\n * @returns 文章列表\n */\n async userArticles({\n userName,\n page = 1,\n size = 20,\n }: {\n userName: string;\n page?: number;\n size?: number;\n }): Promise<ArticleList> {\n let rsp;\n try {\n rsp = await request({\n url: `api/user/${userName}/articles?p=${page}&size=${size}&${\n this.apiKey ? `apiKey=${this.apiKey}` : ''\n }`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return ArticleList.from(rsp.data);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取文章详情\n * @param id 文章id\n * @returns 文章详情\n */\n async detail(id: string, p = 1): Promise<ArticleDetail> {\n let rsp;\n try {\n rsp = await request({\n url: `api/article/${id}?apiKey=${this.apiKey}&p=${p}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return ArticleDetail.from(rsp.data.article);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 点赞/取消点赞文章\n * @param id 文章id\n * @param type 点赞类型\n * @returns 文章点赞状态\n */\n async vote(id: string, type: 'up' | 'down'): Promise<VoteType> {\n let rsp;\n try {\n rsp = await request({\n url: `vote/${type}/article`,\n method: 'post',\n data: {\n dataId: id,\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.type;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 感谢文章\n * @param id 文章id\n */\n async thank(id: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `article/thank?articleId=${id}`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 收藏文章\n * @param followingId 文章id\n */\n async follow(followingId: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `follow/article`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n followingId,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 取消收藏文章\n * @param followingId 文章id\n */\n async unfollow(followingId: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `unfollow/article`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n followingId,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 关注文章\n * @param followingId 文章id\n */\n async watch(followingId: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `follow/article-watch`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n followingId,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 取消关注文章\n * @param followingId 文章id\n */\n async unwatch(followingId: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `unfollow/article-watch`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n followingId,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 打赏文章\n * @param id 文章id\n */\n async reward(id: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `article/reward?articleId=${id}`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取文章在线人数\n * @param id 文章id\n */\n async heat(id: string): Promise<number> {\n let rsp;\n try {\n rsp = await request({\n url: `api/article/heat/${id}?apiKey=${this.apiKey}`,\n method: 'get',\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.articleHeat;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取帖子的Markdown原文\n * @param articleId 文章Id\n */\n async md(articleId: string): Promise<string> {\n let rsp;\n try {\n rsp = await request({\n url: `api/article/md/${articleId}?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp;\n } catch (e) {\n throw e;\n }\n }\n\n channel(id: string, type: ArticleType): ArticleChannel {\n if (!this.channels[id]) this.channels[id] = new ArticleChannel(this.apiKey, id, type);\n return this.channels[id];\n }\n}\n\nexport class ArticleChannel extends WsEventBase<IArticleEvents> {\n private apiKey: string = '';\n private id: string = '';\n private type: ArticleType = ArticleType.Normal;\n\n constructor(token: string, id: string, type: ArticleType) {\n super();\n if (!token) {\n return;\n }\n this.apiKey = token;\n }\n /**\n * 添加文章监听器\n * @param id 文章id\n * @param type 文章类型\n * @param callback 监听回调\n */\n async connect(reload?: boolean): Promise<ReconnectingWebSocket> {\n return new Promise(async (resolve, reject) => {\n if (this.ws && !reload) return resolve(this.ws);\n if (this.ws) this.ws.close();\n if (!this.apiKey) return reject(new Error('请先设置 API Key'));\n\n this.ws = new ReconnectingWebSocket(\n `wss://${domain}/article-channel?articleId=${this.id}&articleType=${this.type}&apiKey=${this.apiKey}`,\n [],\n {\n // eslint-disable-next-line @typescript-eslint/naming-convention\n WebSocket,\n connectionTimeout: 10000,\n },\n );\n\n this.ws.onopen = (e) => {\n this.emitter.emit('open', e);\n };\n this.ws.onmessage = (ev: MessageEvent) => {\n let msg = JSON.parse(ev.data);\n let eventType = msg.type;\n if (eventType === 'articleHeat') {\n this.emitter.emit('heat', msg.data);\n } else {\n this.emitter.emit(msg.type, ArticleComment.from(msg.data));\n }\n };\n this.ws.onerror = (e) => {\n this.emitter.emit('error', e);\n };\n this.ws.onclose = (e) => {\n this.emitter.emit('close', e);\n };\n return this.ws;\n });\n }\n}\n","import { CommentPost, ICommentPost, VoteType } from './';\nimport { request } from './utils';\n\nexport class Comment {\n private apiKey: string = '';\n\n constructor(token: string = '') {\n if (!token) {\n return;\n }\n this.apiKey = token;\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(token: string) {\n this.apiKey = token;\n }\n\n /**\n * 发布评论\n * @param data 评论信息\n */\n async send(data: ICommentPost): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `comment`,\n method: 'post',\n data: {\n ...CommentPost.from(data).toJson(),\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 更新评论\n * @param id 评论 Id\n * @param data 评论信息\n */\n async update(id: string, data: ICommentPost): Promise<string> {\n let rsp;\n try {\n rsp = await request({\n url: `comment/${id}`,\n method: 'put',\n data: {\n ...CommentPost.from(data).toJson(),\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.commentContent;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 评论点赞\n * @param id 评论 Id\n * @param type 点赞类型\n */\n async vote(id: string, type: 'up' | 'down'): Promise<VoteType> {\n let rsp;\n try {\n rsp = await request({\n url: `vote/${type}/comment`,\n method: 'post',\n data: {\n dataId: id,\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.type;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 评论感谢\n * @param id 评论 Id\n */\n async thank(id: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `comment/thank`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n commentId: id,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 删除评论\n * @param id 评论 Id\n */\n async remove(id: string): Promise<string> {\n let rsp;\n try {\n rsp = await request({\n url: `comment/${id}/remove`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.commentId;\n } catch (e) {\n throw e;\n }\n }\n}\n","import ReconnectingWebSocket from 'reconnecting-websocket';\nimport { request, domain, WebSocket } from './utils';\nimport { IChatData, IChatQuery } from '.';\nimport { IWebSocketEvent, WsEventBase } from './ws';\n\ninterface IChatEvents extends IWebSocketEvent {\n /**\n * 私聊消息\n * @param msg 私聊消息内容\n */\n data: (msg: IChatData) => void;\n /**\n * 撤回消息\n * @param oId 消息 ID\n */\n revoke: (oId: string) => void;\n}\n\nclass ChatChannel extends WsEventBase<IChatEvents> {\n private apiKey: string = '';\n private user = '';\n\n constructor(user: string, apiKey: string) {\n super();\n this.apiKey = apiKey;\n this.user = user;\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(apiKey: string) {\n this.apiKey = apiKey;\n this.connect(true);\n }\n\n /**\n * 连接用户私聊频道\n * @returns Websocket 连接对象\n */\n connect(reload = false): Promise<ReconnectingWebSocket> {\n return new Promise(async (resolve, reject) => {\n if (this.ws && !reload) return resolve(this.ws);\n if (this.ws) this.ws.close();\n if (!this.user) return reject(new Error('请先设置私聊用户名'));\n if (!this.apiKey) return reject(new Error('请先设置 API Key'));\n this.ws = new ReconnectingWebSocket(\n `wss://${domain}/chat-channel?apiKey=${this.apiKey}&toUser=${this.user}`,\n [],\n {\n WebSocket,\n connectionTimeout: 10000,\n },\n );\n this.ws.onopen = (e) => {\n resolve(this.ws!);\n };\n this.ws.onmessage = async (e) => {\n let msg = JSON.parse(e.data);\n let type = 'data';\n if (msg.type == 'revoke') {\n type = 'revoke';\n msg = msg.data;\n }\n this.emitter.emit(type, msg);\n };\n this.ws.onerror = (e) => {\n this.emitter.emit('error', e);\n };\n this.ws.onclose = (e) => {\n this.emitter.emit('close', e);\n };\n });\n }\n\n async send(msg: string) {\n if (this.ws == null) {\n await this.connect();\n }\n if (this.user) this.ws?.send(msg);\n }\n\n close() {\n this.ws?.close();\n }\n\n /**\n * 获取用户私聊历史消息\n * @param param 消息参数\n * @returns 私聊消息列表\n */\n async get({ page = 1, size = 20, autoRead = true }: IChatQuery): Promise<IChatData[]> {\n if (!this.user) return [];\n try {\n let rsp = await request({\n url: `chat/get-message?apiKey=${this.apiKey}&toUser=${this.user}&page=${page}&pageSize=${size}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n if (autoRead) this.markRead();\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 标记用户消息已读\n * @param user 用户名\n * @returns 执行结果\n */\n async markRead(): Promise<void> {\n if (!this.user) return;\n try {\n let rsp = await request({\n url: `chat/mark-as-read?apiKey=${this.apiKey}&fromUser=${this.user}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n}\n\nexport class Chat {\n private apiKey: string = '';\n private chats: { [key: string]: ChatChannel } = {};\n\n constructor(token: string = '') {\n if (!token) {\n return;\n }\n this.apiKey = token;\n }\n\n /**\n * 获取私聊频道\n * @param user 私聊用户名\n * @returns 私聊频道\n */\n channel(user: string) {\n if (!this.chats[user]) this.chats[user] = new ChatChannel(user, this.apiKey);\n return this.chats[user];\n }\n\n /**\n * 关闭私聊频道\n * @param user 私聊用户名\n */\n close(user: string = '') {\n if (user) {\n this.chats[user]?.close();\n delete this.chats[user];\n return;\n }\n Object.values(this.chats).forEach((c) => c.close());\n this.chats = {};\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(apiKey: string) {\n this.apiKey = apiKey;\n Object.values(this.chats).forEach((c) => c.setToken(apiKey));\n }\n\n /**\n * 获取有私聊用户列表以及第一条消息\n * @returns 私聊消息列表\n */\n async list(): Promise<IChatData[]> {\n try {\n let rsp = await request({\n url: `chat/get-list?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取未读消息\n * @returns 未读消息列表\n */\n async unread(): Promise<IChatData> {\n try {\n let rsp = await request({\n url: `chat/has-unread?apiKey=${this.apiKey}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 撤回私聊消息\n * @param msgId 消息 ID\n */\n async revoke(msgId: string): Promise<number> {\n try {\n let rsp = await request({\n url: `chat/revoke?apiKey=${this.apiKey}&oId=${msgId}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.result;\n } catch (e) {\n throw e;\n }\n }\n}\n","import { BreezemoonContent, BreezemoonList } from '.';\nimport { request } from './utils';\n\nexport class Breezemoon {\n private apiKey: string = '';\n\n constructor(token: string = '') {\n if (!token) {\n return;\n }\n this.apiKey = token;\n }\n\n /**\n * 重新设置请求 Token\n * @param apiKey 接口 API Key\n */\n setToken(token: string) {\n this.apiKey = token;\n }\n\n /**\n * 获取清风明月列表\n * @param page 消息页码\n * @param size 每页个数\n */\n async list(page = 1, size = 20): Promise<BreezemoonContent[]> {\n try {\n let rsp = await request({\n url: `api/breezemoons?p=${page}&size=${size}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.breezemoons.map((b: any) => BreezemoonContent.from(b));\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取用户清风明月列表\n * @param user 用户名\n * @param page 消息页码\n * @param size 每页个数\n */\n async listByUser(user: string, page = 1, size = 20): Promise<BreezemoonList> {\n try {\n let rsp = await request({\n url: `api/user/${user}/breezemoons?p=${page}&size=${size}&apiKey=${this.apiKey}`,\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return BreezemoonList.from(rsp.data);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 发送清风明月\n * @param content 内容\n */\n async send(content: string): Promise<void> {\n try {\n let rsp = await request({\n url: `breezemoon`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n breezemoonContent: content,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n}\n","import { IUserBag, IUserIP, MetalBase } from './';\nimport { request } from './utils';\n\nexport class Finger {\n private goldFingerKey: string = '';\n\n constructor(key: string) {\n if (!key) {\n return;\n }\n this.goldFingerKey = key;\n }\n\n /**\n * 设置金手指\n * @param key 金手指密钥\n */\n setFinger(key: string) {\n this.goldFingerKey = key;\n }\n\n /**\n * 上传摸鱼大闯关关卡数据\n * @param userName: 用户在摸鱼派的用户名\n * @param stage: 关卡数\n * @param time: 通过此关时间(毫秒级时间戳)\n */\n async addMofishScore({\n userName,\n stage,\n time = new Date().getTime(),\n }: {\n userName: string;\n stage: string;\n time: number;\n }): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `api/games/mofish/score`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n stage,\n time,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询用户最近登录的IP地址\n * @param userName: 用户在摸鱼派的用户名\n */\n async queryLatestLoginIP(userName: string): Promise<IUserIP> {\n let rsp;\n try {\n rsp = await request({\n url: `user/query/latest-login-iP`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 添加勋章\n * @param userName: 用户在摸鱼派的用户名\n * @param metal: 勋章信息\n */\n async addMetal(userName: string, metal: MetalBase): Promise<void> {\n let rsp;\n metal = new MetalBase(metal);\n try {\n rsp = await request({\n url: `user/edit/give-metal`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n ...metal,\n attr: metal.attr.toString(),\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 删除勋章\n * @param userName: 用户在摸鱼派的用户名\n * @param name: 勋章名称\n */\n async deleteMetal(userName: string, name: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `user/edit/remove-metal`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n name,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 删除勋章By userId\n * @param userId: 用户在摸鱼派的用户ID\n * @param name: 勋章名称\n */\n async deleteMetalByUserId(userId: string, name: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `user/edit/remove-metal-by-user-id`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userId,\n name,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询用户背包\n * @param userName: 用户在摸鱼派的用户名\n */\n async queryUserBag(userName: string): Promise<IUserBag> {\n let rsp;\n try {\n rsp = await request({\n url: `user/query/items`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 调整用户背包\n * @param userName: 用户在摸鱼派的用户名\n * @param item: 物品名称\n * @param sum: 物品数量\n */\n async editUserBag(userName: string, item: string, sum: number): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `user/edit/items`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n item,\n sum,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 调整用户积分\n * @param userName: 用户在摸鱼派的用户名\n * @param point: 积分数量\n * @param memo: 备注\n */\n async editUserPoints(userName: string, point: number, memo: string): Promise<void> {\n let rsp;\n try {\n rsp = await request({\n url: `user/edit/points`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n point,\n memo,\n },\n });\n\n if (rsp.code) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询用户当前活跃度\n * @param userName: 用户在摸鱼派的用户名\n */\n async getLiveness(userName: string): Promise<number> {\n let rsp;\n try {\n rsp = await request({\n url: `user/liveness`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n },\n });\n\n if (rsp.code !== 0) throw new Error(rsp.msg);\n\n return rsp.liveness;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询用户昨日活跃度奖励\n * @param userName: 用户在摸鱼派的用户名\n */\n async getYesterDayLivenessReward(userName: string): Promise<number> {\n let rsp;\n try {\n rsp = await request({\n url: `activity/yesterday-liveness-reward-api`,\n method: 'post',\n data: {\n goldFingerKey: this.goldFingerKey,\n userName,\n },\n });\n\n return rsp.sum;\n } catch (e) {\n throw e;\n }\n }\n}\n","import md5 from 'js-md5';\nimport { domain, isBrowse, request, setDomain } from './utils';\nimport { ChatRoom, Notice, Emoji, User, Article, Comment, Chat, Breezemoon, Finger } from './';\nimport {\n IAtUser,\n ILog,\n IUploadInfo,\n IReport,\n UserInfo,\n Account,\n PreRegisterInfo,\n RegisterInfo,\n} from './';\nimport { IUserLite, UserVIP } from './types';\n\nexport class FishPi {\n /**\n * 请求 API 的 API Key\n */\n private apiKey: string = '';\n /**\n * 聊天室接口对象\n */\n readonly chatroom: ChatRoom = new ChatRoom();\n /**\n * 通知接口对象\n */\n readonly notice: Notice = new Notice();\n /**\n * 表情包接口对象\n */\n readonly emoji: Emoji = new Emoji();\n /**\n * 用户接口对象\n */\n readonly account: User = new User();\n /**\n * 文章接口对象\n */\n readonly article: Article = new Article();\n /**\n * 评论接口对象\n */\n readonly comment: Comment = new Comment();\n /**\n * 清风明月对象\n */\n readonly breezemoon: Breezemoon = new Breezemoon();\n /**\n * 私聊接口对象\n */\n readonly chat: Chat = new Chat();\n\n /**\n * 构造一个 API 请求对象\n * @param token 接口 API Key,没有可以传空\n */\n constructor(token: string = '') {\n if (!token) {\n return;\n }\n this.setToken(token);\n }\n\n async setToken(apiKey: string) {\n this.apiKey = apiKey;\n this.chatroom.setToken(this.apiKey);\n this.notice.setToken(this.apiKey);\n this.emoji.setToken(this.apiKey);\n this.account.setToken(this.apiKey);\n this.article.setToken(this.apiKey);\n this.comment.setToken(this.apiKey);\n this.breezemoon.setToken(this.apiKey);\n this.chat.setToken(this.apiKey);\n }\n\n async setDomain(domain: string) {\n setDomain(domain);\n }\n\n /**\n * 登录账号返回 API Key\n * @param data 用户账密\n */\n async login(data: Account): Promise<string> {\n try {\n let rsp = await request({\n url: 'api/getKey',\n method: 'post',\n data: {\n nameOrEmail: data.username,\n userPassword: md5(data.passwd),\n mfaCode: data.mfaCode,\n },\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n this.setToken(rsp.Key);\n\n return rsp.Key;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 预注册账号\n * @param data 用户信息\n * @returns\n */\n async preRegister(data: PreRegisterInfo): Promise<void> {\n try {\n let rsp = await request({\n url: 'register',\n method: 'post',\n data: {\n userName: data.username,\n userPhone: data.phone,\n invitecode: data.invitecode,\n captcha: data.captcha,\n },\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 验证手机验证码\n * @param code 验证码\n * @returns\n */\n async verify(code: string): Promise<number> {\n try {\n let rsp = await request({\n url: 'verify?code=' + code,\n method: 'get',\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n return rsp.userId;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 注册账号\n */\n async register(data: RegisterInfo): Promise<void> {\n try {\n let rsp = await request({\n url: `register2${data.r ? `?r=${data.r}` : ''}`,\n method: 'post',\n data: {\n userAppRole: data.role,\n userPassword: md5(data.passwd),\n userId: data.userId,\n },\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询指定用户信息\n * @param username 用户名\n */\n async user(username: string): Promise<UserInfo | undefined> {\n try {\n let rsp = await request({\n url: `user/${username}${this.apiKey ? `?apiKey=${this.apiKey}` : ''}`,\n });\n\n if (rsp.code && rsp.code !== 0) return;\n\n return UserInfo.from(rsp);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 查询指定用户积分\n * @param username 用户名\n * @returns 用户积分\n */\n async userPoints(username: string): Promise<number> {\n try {\n let rsp = await request({\n url: `user/${username}/point`,\n });\n\n if (rsp.code && rsp.code !== 0) return 0;\n\n return rsp.data.userPoint;\n } catch (e) {\n throw e;\n }\n }\n /**\n * 查询指定用户 oId 的用户信息\n */\n async userByoId(oId: string): Promise<IUserLite | undefined> {\n try {\n let rsp = await request({\n url: `api/user/getInfoById?userId=${oId}`,\n });\n\n if (rsp.code && rsp.code !== 0) return;\n\n return { ...rsp.data, oId };\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 用户名联想,通常用于 @ 列表\n * @param username 用户名\n */\n async names(name: string): Promise<IAtUser[]> {\n let rsp;\n try {\n rsp = await request({\n url: `users/names`,\n method: 'post',\n data: {\n name,\n },\n });\n\n return rsp.data || [];\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取最近注册的20个用户\n */\n async recentRegister(): Promise<{ userNickname: string; userName: string }[]> {\n let rsp;\n try {\n rsp = await request({\n url: `api/user/recentReg`,\n method: 'get',\n });\n\n return rsp.data || [];\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取用户 VIP 信息\n * @param userId 用户 oId\n */\n async vipInfo(userId: string): Promise<UserVIP> {\n let rsp;\n try {\n rsp = await request({\n url: `api/membership/${userId}`,\n method: 'get',\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n if (rsp.data.config) {\n rsp.data.config = JSON.parse(rsp.data.config);\n }\n\n return UserVIP.from(rsp.data);\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 举报\n * @param data 举报信息\n */\n async report(data: IReport): Promise<void> {\n try {\n let rsp = await request({\n url: `report`,\n method: 'post',\n data: {\n apiKey: this.apiKey,\n ...data,\n },\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n return rsp;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 获取操作日志\n * @param page 页码\n * @param pageSize 每页数量\n */\n async log({ page = 1, pageSize = 30 }): Promise<ILog[]> {\n try {\n let rsp = await request({\n url: `/logs/more?page=${page}&pageSize=${pageSize}`,\n method: 'get',\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 上传文件\n * @param files 要上传的文件,如果是在 Node 使用,则传入文件路径数组,若是在浏览器使用,则传入文件对象数组。\n */\n async upload(files: Array<File | string>): Promise<IUploadInfo> {\n let data: any;\n\n if (isBrowse) {\n data = new FormData();\n files.forEach((f) => data.append('file[]', f));\n } else {\n const FormData = await import('form-data').then((mod) => mod.default);\n const fs = await import('fs');\n const path = await import('path');\n data = new FormData();\n files.forEach((f) =>\n data.append('file[]', fs.readFileSync(f.toString()), path.basename(f.toString())),\n );\n }\n\n data.append('apiKey', this.apiKey);\n\n let rsp;\n try {\n rsp = await request({\n url: `upload`,\n method: 'post',\n data,\n headers: isBrowse ? undefined : data.getHeaders(),\n });\n\n if (rsp.code != 0) throw new Error(rsp.msg);\n\n return rsp.data;\n } catch (e) {\n throw e;\n }\n }\n\n /**\n * 生成登录认证地址\n * @param redirect 登录成功后跳转的地址\n */\n generateAuthURL(redirect: string): string {\n const redirectOrigin = new URL(redirect).origin;\n return `https://${domain}/openid/login?openid.ns=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0&openid.mode=checkid_setup&openid.return_to=${encodeURIComponent(redirect)}&openid.realm=${encodeURIComponent(redirectOrigin)}&openid.claimed_id=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select&openid.identity=http%3A%2F%2Fspecs.openid.net%2Fauth%2F2.0%2Fidentifier_select`;\n }\n\n /**\n * 校验登录回调\n * @param query 验证返回的地址 QueryString 参数\n * @returns 验证成功则返回用户简略信息,否则返回 undefined\n */\n async authVerify(query: Record<string, string>): Promise<IUserLite | undefined> {\n const openVerify = {\n 'openid.ns': 'http://specs.openid.net/auth/2.0',\n 'openid.mode': 'check_authentication',\n 'openid.op_endpoint': query['openid.op_endpoint'],\n 'openid.return_to': query['openid.return_to'],\n 'openid.identity': query['openid.identity'],\n 'openid.claimed_id': query['openid.claimed_id'],\n 'openid.response_nonce': query['openid.response_nonce'],\n 'openid.assoc_handle': query['openid.assoc_handle'],\n 'openid.sig': query['openid.sig'],\n };\n let rsp;\n try {\n rsp = await request({\n url: `openid/verify`,\n method: 'post',\n data: openVerify,\n });\n\n if (rsp.includes('is_valid:true')) {\n const claimed_id = query['openid.claimed_id']?.split('/').pop();\n if (!claimed_id) return;\n return await this.userByoId(claimed_id);\n } else {\n return;\n }\n } catch (e) {\n throw e;\n }\n }\n}\n\nexport * from './chatroom';\nexport * from './notice';\nexport * from './emoji';\nexport * from './user';\nexport * from './article';\nexport * from './comment';\nexport * from './chat';\nexport * from './breezemoon';\nexport * from './finger';\nexport * from './types';\n\nexport function FingerTo(key: string) {\n return new Finger(key);\n}\n\nexport default FishPi;\n"],"mappings":"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"}
|