From 8f35e63b3ad87af41f3718d1648446deae61c33e Mon Sep 17 00:00:00 2001 From: Dessalines Date: Sun, 22 Aug 2021 21:01:40 -0400 Subject: [PATCH] Adding typedoc, and code comments. Fixes #29 (#30) --- .gitignore | 1 + README.md | 20 +++- package.json | 2 + src/http.ts | 184 ++++++++++++++++++++++++++++- src/interfaces/aggregates.ts | 42 +++++++ src/interfaces/api/comment.ts | 26 ++++- src/interfaces/api/community.ts | 18 ++- src/interfaces/api/person.ts | 72 +++++++++--- src/interfaces/api/post.ts | 23 ++-- src/interfaces/api/site.ts | 31 ++++- src/interfaces/others.ts | 65 ++++++++++- src/websocket.ts | 200 +++++++++++++++++++++++++++++++- yarn.lock | 119 ++++++++++++++++++- 13 files changed, 759 insertions(+), 44 deletions(-) diff --git a/.gitignore b/.gitignore index a17df76..d49f885 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ dist package node_modules +docs diff --git a/README.md b/README.md index 1587d90..d6a742a 100644 --- a/README.md +++ b/README.md @@ -16,20 +16,28 @@ A javascript / typescript http and websocket client and type system for [Lemmy]( ## Usage -Check out the [Lemmy HTTP / websocket API](https://dev.lemmy.ml/docs/contributing_websocket_http_api.html) for all the commands. +### Websocket Client -### Websocket +[LemmyWebsocket docs](classes/LemmyWebsocket.html) -```js -import { LoginForm, LemmyWebsocket } from 'lemmy-js-client'; +```ts +import { Login, LemmyWebsocket } from 'lemmy-js-client'; let client: LemmyWebsocket = new LemmyWebsocket(); + +let form: Login { + username_or_email: "my_email@email.tld", + password: "my_pass", +}; + this.ws.send(client.login(form)); ``` -### HTTP +### HTTP Client -```js +[LemmyHttp docs](classes/LemmyHttp.html) + +```ts import { LemmyHttp } from 'lemmy-js-client'; let baseUrl = 'https://lemmy.ml'; diff --git a/package.json b/package.json index e99f9b1..ffef482 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ ], "scripts": { "build": "tsc", + "docs": "typedoc src/index.ts", "lint": "tsc --noEmit && eslint --report-unused-disable-directives --ext .js,.ts,.tsx src", "prepare": "yarn run build" }, @@ -23,6 +24,7 @@ "node-fetch": "^2.6.1", "prettier": "^2.3.2", "sortpack": "^2.2.0", + "typedoc": "^0.21.6", "typescript": "^4.3.5" }, "types": "./dist/index.d.ts", diff --git a/src/http.ts b/src/http.ts index ead965f..509a1e9 100644 --- a/src/http.ts +++ b/src/http.ts @@ -105,14 +105,17 @@ enum HttpType { Put = 'PUT', } +/** + * Helps build lemmy HTTP requests. + */ export class LemmyHttp { private apiUrl: string; private headers: { [key: string]: string } = {}; /** - * Generates a new instance of LemmyHttp + * Generates a new instance of LemmyHttp. * @param baseUrl the base url, without the vX version: https://lemmy.ml -> goes to https://lemmy.ml/api/vX - * @param headers optional headers. Should contain x-real-ip and x-forwarded-for + * @param headers optional headers. Should contain `x-real-ip` and `x-forwarded-for` . */ constructor(baseUrl: string, headers?: { [key: string]: string }) { this.apiUrl = `${baseUrl}/api/${VERSION}`; @@ -122,264 +125,441 @@ export class LemmyHttp { } } + /** + * Gets the site, and your user data. + */ async getSite(form: GetSite): Promise { return this.wrapper(HttpType.Get, '/site', form); } + /** + * Create your site. + */ async createSite(form: CreateSite): Promise { return this.wrapper(HttpType.Post, '/site', form); } + /** + * Edit your site. + */ async editSite(form: EditSite): Promise { return this.wrapper(HttpType.Put, '/site', form); } + /** + * Transfer your site to another user. + */ async transferSite(form: TransferSite): Promise { return this.wrapper(HttpType.Post, '/site/transfer', form); } + /** + * Get your site configuration. + */ async getSiteConfig(form: GetSiteConfig): Promise { return this.wrapper(HttpType.Get, '/site/config', form); } + /** + * Save your site config. + */ async saveSiteConfig(form: SaveSiteConfig): Promise { return this.wrapper(HttpType.Put, '/site/config', form); } + /** + * Get the modlog. + */ async getModlog(form: GetModlog): Promise { return this.wrapper(HttpType.Get, '/modlog', form); } + /** + * Search lemmy. + */ async search(form: Search): Promise { return this.wrapper(HttpType.Get, '/search', form); } + /** + * Create a new community. + */ async createCommunity(form: CreateCommunity): Promise { return this.wrapper(HttpType.Post, '/community', form); } + /** + * Get / fetch a community. + */ async getCommunity(form: GetCommunity): Promise { return this.wrapper(HttpType.Get, '/community', form); } + /** + * Edit a community. + */ async editCommunity(form: EditCommunity): Promise { return this.wrapper(HttpType.Put, '/community', form); } + /** + * List communities, with various filters. + */ async listCommunities( form: ListCommunities ): Promise { return this.wrapper(HttpType.Get, '/community/list', form); } + /** + * Follow / subscribe to a community. + */ async followCommunity(form: FollowCommunity): Promise { return this.wrapper(HttpType.Post, '/community/follow', form); } + /** + * Block a community. + */ async blockCommunity(form: BlockCommunity): Promise { return this.wrapper(HttpType.Post, '/community/block', form); } + /** + * Delete a community. + */ async deleteCommunity(form: DeleteCommunity): Promise { return this.wrapper(HttpType.Post, '/community/delete', form); } + /** + * A moderator remove for a community. + */ async removeCommunity(form: RemoveCommunity): Promise { return this.wrapper(HttpType.Post, '/community/remove', form); } + /** + * Transfer your community to an existing moderator. + */ async transferCommunity( form: TransferCommunity ): Promise { return this.wrapper(HttpType.Post, '/community/transfer', form); } + /** + * Ban a user from a community. + */ async banFromCommunity( form: BanFromCommunity ): Promise { return this.wrapper(HttpType.Post, '/community/ban_user', form); } + /** + * Add a moderator to your community. + */ async addModToCommunity( form: AddModToCommunity ): Promise { return this.wrapper(HttpType.Post, '/community/mod', form); } + /** + * Create a post. + */ async createPost(form: CreatePost): Promise { return this.wrapper(HttpType.Post, '/post', form); } + /** + * Get / fetch a post. + */ async getPost(form: GetPost): Promise { return this.wrapper(HttpType.Get, '/post', form); } + /** + * Edit a post. + */ async editPost(form: EditPost): Promise { return this.wrapper(HttpType.Put, '/post', form); } + /** + * Delete a post. + */ async deletePost(form: DeletePost): Promise { return this.wrapper(HttpType.Post, '/post/delete', form); } + /** + * A moderator remove for a post. + */ async removePost(form: RemovePost): Promise { return this.wrapper(HttpType.Post, '/post/remove', form); } + /** + * A moderator can lock a post ( IE disable new comments ). + */ async lockPost(form: LockPost): Promise { return this.wrapper(HttpType.Post, '/post/lock', form); } + /** + * A moderator can sticky a post ( IE stick it to the top of a community ). + */ async stickyPost(form: StickyPost): Promise { return this.wrapper(HttpType.Post, '/post/sticky', form); } + /** + * Get / fetch posts, with various filters. + */ async getPosts(form: GetPosts): Promise { return this.wrapper(HttpType.Get, '/post/list', form); } + /** + * Like / vote on a post. + */ async likePost(form: CreatePostLike): Promise { return this.wrapper(HttpType.Post, '/post/like', form); } + /** + * Save a post. + */ async savePost(form: SavePost): Promise { return this.wrapper(HttpType.Put, '/post/save', form); } + /** + * Fetch metadata for any given site. + */ async getSiteMetadata( form: GetSiteMetadata ): Promise { return this.wrapper(HttpType.Get, '/post/site_metadata', form); } + /** + * Create a comment. + */ async createComment(form: CreateComment): Promise { return this.wrapper(HttpType.Post, '/comment', form); } + /** + * Edit a comment. + */ async editComment(form: EditComment): Promise { return this.wrapper(HttpType.Put, '/comment', form); } + /** + * Delete a comment. + */ async deleteComment(form: DeleteComment): Promise { return this.wrapper(HttpType.Post, '/comment/delete', form); } + /** + * A moderator remove for a comment. + */ async removeComment(form: RemoveComment): Promise { return this.wrapper(HttpType.Post, '/comment/remove', form); } + /** + * Mark a comment as read. + */ async markCommentAsRead(form: MarkCommentAsRead): Promise { return this.wrapper(HttpType.Post, '/comment/mark_as_read', form); } + /** + * Like / vote on a comment. + */ async likeComment(form: CreateCommentLike): Promise { return this.wrapper(HttpType.Post, '/comment/like', form); } + /** + * Save a comment. + */ async saveComment(form: SaveComment): Promise { return this.wrapper(HttpType.Put, '/comment/save', form); } + /** + * Get / fetch comments. + */ async getComments(form: GetComments): Promise { return this.wrapper(HttpType.Get, '/comment/list', form); } + /** + * Get / fetch private messages. + */ async getPrivateMessages( form: GetPrivateMessages ): Promise { return this.wrapper(HttpType.Get, '/private_message/list', form); } + /** + * Create a private message. + */ async createPrivateMessage( form: CreatePrivateMessage ): Promise { return this.wrapper(HttpType.Post, '/private_message', form); } + /** + * Edit a private message. + */ async editPrivateMessage( form: EditPrivateMessage ): Promise { return this.wrapper(HttpType.Put, '/private_message', form); } + /** + * Delete a private message. + */ async deletePrivateMessage( form: DeletePrivateMessage ): Promise { return this.wrapper(HttpType.Post, '/private_message/delete', form); } + /** + * Mark a private message as read. + */ async markPrivateMessageAsRead( form: MarkPrivateMessageAsRead ): Promise { return this.wrapper(HttpType.Post, '/private_message/mark_as_read', form); } + /** + * Register a new user. + */ async register(form: Register): Promise { return this.wrapper(HttpType.Post, '/user/register', form); } + /** + * Log into lemmy. + */ async login(form: Login): Promise { return this.wrapper(HttpType.Post, '/user/login', form); } + /** + * Get the details for a person. + */ async getPersonDetails( form: GetPersonDetails ): Promise { return this.wrapper(HttpType.Get, '/user', form); } + /** + * Get mentions for your user. + */ async getPersonMentions( form: GetPersonMentions ): Promise { return this.wrapper(HttpType.Get, '/user/mention', form); } + /** + * Mark a person mention as read. + */ async markPersonMentionAsRead( form: MarkPersonMentionAsRead ): Promise { return this.wrapper(HttpType.Post, '/user/mention/mark_as_read', form); } + /** + * Get comment replies. + */ async getReplies(form: GetReplies): Promise { return this.wrapper(HttpType.Get, '/user/replies', form); } + /** + * Ban a person from your site. + */ async banPerson(form: BanPerson): Promise { return this.wrapper(HttpType.Post, '/user/ban', form); } + /** + * Block a person. + */ async blockPerson(form: BlockPerson): Promise { return this.wrapper(HttpType.Post, '/user/block', form); } + /** + * Fetch a Captcha. + */ async getCaptcha(): Promise { return this.wrapper(HttpType.Get, '/user/get_captcha', {}); } + /** + * Delete your account. + */ async deleteAccount(form: DeleteAccount): Promise { return this.wrapper(HttpType.Post, '/user/delete_account', form); } + /** + * Reset your password. + */ async passwordReset(form: PasswordReset): Promise { return this.wrapper(HttpType.Post, '/user/password_reset', form); } + /** + * Change your password from an email / token based reset. + */ async passwordChange(form: PasswordChange): Promise { return this.wrapper(HttpType.Post, '/user/password_change', form); } + /** + * Mark all replies as read. + */ async markAllAsRead(form: MarkAllAsRead): Promise { return this.wrapper(HttpType.Post, '/user/mark_all_as_read', form); } + /** + * Save your user settings. + */ async saveUserSettings(form: SaveUserSettings): Promise { return this.wrapper(HttpType.Put, '/user/save_user_settings', form); } + /** + * Change your user password. + */ async changePassword(form: ChangePassword): Promise { return this.wrapper(HttpType.Put, '/user/change_password', form); } + /** + * Add an admin to your site. + */ async addAdmin(form: AddAdmin): Promise { return this.wrapper(HttpType.Post, '/admin/add', form); } diff --git a/src/interfaces/aggregates.ts b/src/interfaces/aggregates.ts index 43ca451..56f8d6a 100644 --- a/src/interfaces/aggregates.ts +++ b/src/interfaces/aggregates.ts @@ -1,3 +1,6 @@ +/** + * Aggregate data for a person. + */ export interface PersonAggregates { id: number; person_id: number; @@ -7,6 +10,9 @@ export interface PersonAggregates { comment_score: number; } +/** + * Aggregate data for your site. + */ export interface SiteAggregates { id: number; site_id: number; @@ -14,12 +20,27 @@ export interface SiteAggregates { posts: number; comments: number; communities: number; + /** + * Active users per day. + */ users_active_day: number; + /** + * Active users per week. + */ users_active_week: number; + /** + * Active users per month. + */ users_active_month: number; + /** + * Active users per year. + */ users_active_half_year: number; } +/** + * Aggregate data for your post. + */ export interface PostAggregates { id: number; post_id: number; @@ -27,22 +48,43 @@ export interface PostAggregates { score: number; upvotes: number; downvotes: number; + /** + * Newest comment time, limited to 2 days, to prevent necrobumping. + */ newest_comment_time_necro: string; newest_comment_time: string; } +/** + * Aggregate data for your community. + */ export interface CommunityAggregates { id: number; community_id: number; subscribers: number; posts: number; comments: number; + /** + * Active users per day. + */ users_active_day: number; + /** + * Active users per week. + */ users_active_week: number; + /** + * Active users per month. + */ users_active_month: number; + /** + * Active users per year. + */ users_active_half_year: number; } +/** + * Aggregate data for your comment. + */ export interface CommentAggregates { id: number; comment_id: number; diff --git a/src/interfaces/api/comment.ts b/src/interfaces/api/comment.ts index a9b4b3e..d042116 100644 --- a/src/interfaces/api/comment.ts +++ b/src/interfaces/api/comment.ts @@ -4,13 +4,19 @@ export interface CreateComment { content: string; parent_id?: number; post_id: number; - form_id?: string; // An optional front end ID, to tell which is coming back + /** + * An optional front end ID, to tell which is comment is coming back. + */ + form_id?: string; auth: string; } export interface EditComment { content: string; comment_id: number; + /** + * An optional front end ID, to tell which is comment is coming back. + */ form_id?: string; auth: string; } @@ -52,7 +58,10 @@ export interface SaveComment { export interface CommentResponse { comment_view: CommentView; recipient_ids: number[]; - form_id?: string; // An optional front end ID, to tell which is coming back + /** + * An optional front end ID, to tell which is comment is coming back. + */ + form_id?: string; } export interface CreateCommentLike { @@ -64,10 +73,17 @@ export interface CreateCommentLike { /** * Comment listing types are `All, Subscribed, Community` * - * `community_name` can only be used for local communities. To get posts for a federated community, pass `community_id` instead. + * You can use either `community_id` or `community_name` as an id. + * To get posts for a federated community by name, use `name@instance.tld` . */ export interface GetComments { + /** + * The [[ListingType]]. + */ type_?: string; + /** + * The [[SortType]]. + */ sort?: string; page?: number; limit?: number; @@ -106,7 +122,9 @@ export interface ResolveCommentReportResponse { export interface ListCommentReports { page?: number; limit?: number; - // if no community is given, it returns reports for all communities moderated by the auth user + /** + * if no community is given, it returns reports for all communities moderated by the auth user. + */ community?: number; auth: string; } diff --git a/src/interfaces/api/community.ts b/src/interfaces/api/community.ts index 8959468..90dedac 100644 --- a/src/interfaces/api/community.ts +++ b/src/interfaces/api/community.ts @@ -4,6 +4,11 @@ import { PersonViewSafe, } from '../views'; +/** + * You can use either `id` or `name` as an id. + * + * To get a federated community by name, use `name@instance.tld` . + */ export interface GetCommunity { id?: number; name?: string; @@ -31,7 +36,14 @@ export interface CommunityResponse { } export interface ListCommunities { + /** + * The [[ListingType]]. + */ type_?: string; + + /** + * The [[SortType]]. + */ sort?: string; page?: number; limit?: number; @@ -46,7 +58,11 @@ export interface BanFromCommunity { community_id: number; person_id: number; ban: boolean; - remove_data?: boolean; // Removes/Restores their comments and posts for that community + + /** + * Removes/Restores their comments and posts for that community. + */ + remove_data?: boolean; reason?: string; expires?: number; auth: string; diff --git a/src/interfaces/api/person.ts b/src/interfaces/api/person.ts index 4a58211..05d69c0 100644 --- a/src/interfaces/api/person.ts +++ b/src/interfaces/api/person.ts @@ -1,13 +1,10 @@ import { CommentView, - CommunityFollowerView, CommunityModeratorView, PostView, PrivateMessageView, PersonMentionView, PersonViewSafe, - CommunityBlockView, - PersonBlockView, } from '../views'; export interface Login { @@ -16,7 +13,9 @@ export interface Login { } /** - * Only the first user will be able to be the admin. + * Register a new user. + * + * Only the first user to register will be able to be the admin. */ export interface Register { username: string; @@ -24,27 +23,60 @@ export interface Register { password: string; password_verify: string; show_nsfw: boolean; - captcha_uuid?: string; // Only checked if these are enabled in the server + /** + * Captcha is only checked if these are enabled in the server. + */ + captcha_uuid?: string; captcha_answer?: string; } export interface GetCaptcha {} export interface GetCaptchaResponse { - ok?: CaptchaResponse; // Will be undefined if captchas are disabled + /** + * Will be undefined if captchas are disabled. + */ + ok?: CaptchaResponse; } export interface CaptchaResponse { - png: string; // A Base64 encoded png - wav?: string; // A Base64 encoded wav aud, + /** + * A Base64 encoded png. + */ + png: string; + + /** + * A Base64 encoded wav file. + */ + wav?: string; + + /** + * A UUID to match the one given on request. + */ uuid: string; } export interface SaveUserSettings { show_nsfw?: boolean; - theme?: string; // Default 'browser' - default_sort_type?: number; // The Sort types from above, zero indexed as a number - default_listing_type?: number; // Post listing types are `All, Subscribed, Community` + + /** + * Default for this is `browser`. + */ + theme?: string; + + /** + * The [[SortType]]. + * + * The Sort types from above, zero indexed as a number + */ + default_sort_type?: number; + + /** + * The [[ListingType]]. + * + * Post listing types are `All, Subscribed, Community` + */ + default_listing_type?: number; lang?: string; avatar?: string; banner?: string; @@ -76,11 +108,11 @@ export interface LoginResponse { jwt: string; } -/** - * `username` can only be used for local users. To get details for a federated user, pass `user_id` instead. - */ export interface GetPersonDetails { person_id?: number; + /** + * To get details for a federated user, use `person@instance.tld`. + */ username?: string; sort?: string; page?: number; @@ -122,7 +154,11 @@ export interface AddAdminResponse { export interface BanPerson { person_id: number; ban: boolean; - remove_data?: boolean; // Removes/Restores their comments, posts, and communities + + /** + * Removes/Restores their comments, posts, and communities + */ + remove_data?: boolean; reason?: string; expires?: number; auth: string; @@ -134,6 +170,9 @@ export interface BanPersonResponse { } export interface GetReplies { + /** + * The [[SortType]]. + */ sort?: string; page?: number; limit?: number; @@ -142,6 +181,9 @@ export interface GetReplies { } export interface GetPersonMentions { + /** + * The [[SortType]]. + */ sort?: string; page?: number; limit?: number; diff --git a/src/interfaces/api/post.ts b/src/interfaces/api/post.ts index 6562b28..99dbc9c 100644 --- a/src/interfaces/api/post.ts +++ b/src/interfaces/api/post.ts @@ -33,17 +33,23 @@ export interface GetPostResponse { online: number; } -/** - * Post listing types are `All, Subscribed, Community` - * - * `community_name` can only be used for local communities. To get posts for a federated community, pass `community_id` instead. - */ export interface GetPosts { + /** + * The [[ListingType]]. + * + * Post listing types are `All, Subscribed, Community` + */ type_?: string; + /** + * The [[SortType]]. + */ sort?: string; page?: number; limit?: number; community_id?: number; + /** + * To get posts for a federated community by name, use `name@instance.tld` . + */ community_name?: string; saved_only?: boolean; auth?: string; @@ -53,11 +59,12 @@ export interface GetPostsResponse { posts: PostView[]; } -/** - * `score` can be 0, -1, or 1 - */ export interface CreatePostLike { post_id: number; + + /** + * `score` can be 0, -1, or 1. Anything else will be rejected. + */ score: number; auth: string; } diff --git a/src/interfaces/api/site.ts b/src/interfaces/api/site.ts index 24f1518..ec3e96c 100644 --- a/src/interfaces/api/site.ts +++ b/src/interfaces/api/site.ts @@ -24,15 +24,28 @@ import { } from '../views'; /** - * Search types are `All, Comments, Posts, Communities, Users, Url` + * Search lemmy for different types of data. */ export interface Search { + /** + * The search query string. + */ q: string; + + /** + * The [[SearchType]]. + */ type_?: string; community_id?: number; community_name?: string; creator_id?: number; + /** + * The [[SortType]]. + */ sort?: string; + /** + * The [[ListingType]]. + */ listing_type?: string; page?: number; limit?: number; @@ -40,6 +53,9 @@ export interface Search { } export interface SearchResponse { + /** + * The [[SearchType]]. + */ type_: string; comments: CommentView[]; posts: PostView[]; @@ -102,15 +118,24 @@ export interface SiteResponse { } export interface GetSiteResponse { - site_view?: SiteView; // Because the site might not be set up yet + /** + * Optional, because the site might not be set up yet. + */ + site_view?: SiteView; admins: PersonViewSafe[]; banned: PersonViewSafe[]; online: number; version: string; - my_user?: MyUserInfo; // Gives back your local user, settings, follows, and blocks if logged in + /** + * If you're logged in, you'll get back extra user info. + */ + my_user?: MyUserInfo; federated_instances?: FederatedInstances; } +/** + * Your user info, such as blocks, follows, etc. + */ export interface MyUserInfo { local_user_view: LocalUserSettingsView; follows: CommunityFollowerView[]; diff --git a/src/interfaces/others.ts b/src/interfaces/others.ts index 014b0ae..c163d2f 100644 --- a/src/interfaces/others.ts +++ b/src/interfaces/others.ts @@ -1,7 +1,7 @@ export const VERSION = 'v3'; /** - * All of the websocket operations available + * All of the websocket operations available. */ export enum UserOperation { Login, @@ -68,19 +68,52 @@ export enum UserOperation { BlockPerson, } +/** + * Different sort types used in lemmy. + */ export enum SortType { + /** + * Posts sorted by the most recent comment. + */ Active = 'Active', + /** + * Posts sorted by the published time. + */ Hot = 'Hot', New = 'New', + /** + * The top posts for this last day. + */ TopDay = 'TopDay', + /** + * The top posts for this last week. + */ TopWeek = 'TopWeek', + /** + * The top posts for this last month. + */ TopMonth = 'TopMonth', + /** + * The top posts for this last year. + */ TopYear = 'TopYear', + /** + * The top posts of all time. + */ TopAll = 'TopAll', + /** + * Posts sorted by the most comments. + */ MostComments = 'MostComments', + /** + * Posts sorted by the newest comments, with no necrobumping. IE a forum sort. + */ NewComments = 'NewComments', } +/** + * The different listing types for post and comment fetches. + */ export enum ListingType { All = 'All', Local = 'Local', @@ -88,6 +121,9 @@ export enum ListingType { Community = 'Community', } +/** + * Search types for lemmy's search. + */ export enum SearchType { All = 'All', Comments = 'Comments', @@ -97,18 +133,45 @@ export enum SearchType { Url = 'Url', } +/** + * A websocket response. Includes the return type. + * Can be used like: + * + * ```ts + * if (op == UserOperation.Search) { + * let data = wsJsonToRes(msg).data; + * } + * ``` + */ export interface WebSocketResponse { op: UserOperation; + /** + * This contains the data for a websocket response. + * + * The correct response type if given is in [[LemmyHttp]]. + */ data: ResponseType; } +/** + * A websocket JSON response that includes the errors. + */ export interface WebSocketJsonResponse { op?: string; + + /** + * This contains the data for a websocket response. + * + * The correct response type if given is in [[LemmyHttp]]. + */ data?: ResponseType; error?: string; reconnect?: boolean; } +/** + * A holder for a site's metadata ( such as opengraph tags ), used for post links. + */ export interface SiteMetadata { title?: string; description?: string; diff --git a/src/websocket.ts b/src/websocket.ts index f8c02fc..a00104a 100644 --- a/src/websocket.ts +++ b/src/websocket.ts @@ -70,255 +70,453 @@ import { UserJoin, PostJoin, CommunityJoin } from './interfaces/api/websocket'; import { UserOperation } from './interfaces/others'; /** - * Helps build lemmy websocket message requests, that you can use in your Websocket sends + * Helps build lemmy websocket message requests, that you can use in your Websocket sends. + * + * You'll receive back a [[WebsocketResponse]]. + * + * The return types for these are given in [[LemmyHttp]] */ export class LemmyWebsocket { constructor() {} + /** + * Log into lemmy. + */ login(form: Login): string { return wrapper(UserOperation.Login, form); } + /** + * A websocket join for your user. + * + * Allows your user to receive private messages and notifications. + */ userJoin(form: UserJoin): string { return wrapper(UserOperation.UserJoin, form); } + /** + * A websocket join for the current post room. + * + * Allows your user to receive new comments and updates for that post. + */ postJoin(form: PostJoin): string { return wrapper(UserOperation.PostJoin, form); } + /** + * A websocket join for a given community. + * + * Allows your user to receive community updates. + * + * Note: community_id: 0, is your front page. + */ communityJoin(form: CommunityJoin): string { return wrapper(UserOperation.CommunityJoin, form); } + /** + * Register a new user. + */ register(register: Register) { return wrapper(UserOperation.Register, register); } + /** + * Fetch a Captcha. + */ getCaptcha() { return wrapper(UserOperation.GetCaptcha, {}); } + /** + * Create a new community. + */ createCommunity(form: CreateCommunity) { return wrapper(UserOperation.CreateCommunity, form); } + /** + * Edit a community. + */ editCommunity(form: EditCommunity) { return wrapper(UserOperation.EditCommunity, form); } + /** + * Delete a community. + */ deleteCommunity(form: DeleteCommunity) { return wrapper(UserOperation.DeleteCommunity, form); } + /** + * A moderator remove for a community. + */ removeCommunity(form: RemoveCommunity) { return wrapper(UserOperation.RemoveCommunity, form); } + /** + * Follow / subscribe to a community. + */ followCommunity(form: FollowCommunity) { return wrapper(UserOperation.FollowCommunity, form); } + /** + * List communities, with various filters. + */ listCommunities(form: ListCommunities) { return wrapper(UserOperation.ListCommunities, form); } + /** + * Create a post. + */ createPost(form: CreatePost) { return wrapper(UserOperation.CreatePost, form); } + /** + * Get / fetch a post. + */ getPost(form: GetPost) { return wrapper(UserOperation.GetPost, form); } + /** + * Get / fetch a community. + */ getCommunity(form: GetCommunity) { return wrapper(UserOperation.GetCommunity, form); } + /** + * Create a comment. + */ createComment(form: CreateComment) { return wrapper(UserOperation.CreateComment, form); } + /** + * Edit a comment. + */ editComment(form: EditComment) { return wrapper(UserOperation.EditComment, form); } + /** + * Delete a comment. + */ deleteComment(form: DeleteComment) { return wrapper(UserOperation.DeleteComment, form); } + /** + * A moderator remove for a comment. + */ removeComment(form: RemoveComment) { return wrapper(UserOperation.RemoveComment, form); } + /** + * Mark a comment as read. + */ markCommentAsRead(form: MarkCommentAsRead) { return wrapper(UserOperation.MarkCommentAsRead, form); } + /** + * Like / vote on a comment. + */ likeComment(form: CreateCommentLike) { return wrapper(UserOperation.CreateCommentLike, form); } + /** + * Save a comment. + */ saveComment(form: SaveComment) { return wrapper(UserOperation.SaveComment, form); } + /** + * Get / fetch posts, with various filters. + */ getPosts(form: GetPosts) { return wrapper(UserOperation.GetPosts, form); } + /** + * Get / fetch comments. + */ getComments(form: GetComments) { return wrapper(UserOperation.GetComments, form); } + /** + * Like / vote on a post. + */ likePost(form: CreatePostLike) { return wrapper(UserOperation.CreatePostLike, form); } + /** + * Edit a post. + */ editPost(form: EditPost) { return wrapper(UserOperation.EditPost, form); } + /** + * Delete a post. + */ deletePost(form: DeletePost) { return wrapper(UserOperation.DeletePost, form); } + /** + * A moderator remove for a post. + */ removePost(form: RemovePost) { return wrapper(UserOperation.RemovePost, form); } + /** + * A moderator can lock a post ( IE disable new comments ). + */ lockPost(form: LockPost) { return wrapper(UserOperation.LockPost, form); } + /** + * A moderator can sticky a post ( IE stick it to the top of a community ). + */ stickyPost(form: StickyPost) { return wrapper(UserOperation.StickyPost, form); } + /** + * Save a post. + */ savePost(form: SavePost) { return wrapper(UserOperation.SavePost, form); } + /** + * Fetch metadata for any given site. + */ getSiteMetadata(form: GetSiteMetadata) { return wrapper(UserOperation.GetSiteMetadata, form); } + /** + * Ban a user from a community. + */ banFromCommunity(form: BanFromCommunity) { return wrapper(UserOperation.BanFromCommunity, form); } + /** + * Add a moderator to your community. + */ addModToCommunity(form: AddModToCommunity) { return wrapper(UserOperation.AddModToCommunity, form); } + /** + * Transfer your community to an existing moderator. + */ transferCommunity(form: TransferCommunity) { return wrapper(UserOperation.TransferCommunity, form); } + /** + * Transfer your site to another user. + */ transferSite(form: TransferSite) { return wrapper(UserOperation.TransferSite, form); } + /** + * Ban a person from your site. + */ banPerson(form: BanPerson) { return wrapper(UserOperation.BanPerson, form); } + /** + * Add an admin to your site. + */ addAdmin(form: AddAdmin) { return wrapper(UserOperation.AddAdmin, form); } + /** + * Get the details for a person. + */ getPersonDetails(form: GetPersonDetails) { return wrapper(UserOperation.GetPersonDetails, form); } + /** + * Get comment replies. + */ getReplies(form: GetReplies) { return wrapper(UserOperation.GetReplies, form); } + /** + * Get mentions for your user. + */ getPersonMentions(form: GetPersonMentions) { return wrapper(UserOperation.GetPersonMentions, form); } + /** + * Mark a person mention as read. + */ markPersonMentionAsRead(form: MarkPersonMentionAsRead) { return wrapper(UserOperation.MarkPersonMentionAsRead, form); } + /** + * Get the modlog. + */ getModlog(form: GetModlog) { return wrapper(UserOperation.GetModlog, form); } + /** + * Create your site. + */ createSite(form: CreateSite) { return wrapper(UserOperation.CreateSite, form); } + /** + * Edit your site. + */ editSite(form: EditSite) { return wrapper(UserOperation.EditSite, form); } + /** + * Gets the site, and your user data. + */ getSite(form: GetSite = {}) { return wrapper(UserOperation.GetSite, form); } + /** + * Get your site configuration. + */ getSiteConfig(form: GetSiteConfig) { return wrapper(UserOperation.GetSiteConfig, form); } + /** + * Search lemmy. + */ search(form: Search) { return wrapper(UserOperation.Search, form); } + /** + * Mark all replies as read. + */ markAllAsRead(form: MarkAllAsRead) { return wrapper(UserOperation.MarkAllAsRead, form); } + /** + * Save your user settings. + */ saveUserSettings(form: SaveUserSettings) { return wrapper(UserOperation.SaveUserSettings, form); } + /** + * Change your user password. + */ changePassword(form: ChangePassword) { return wrapper(UserOperation.ChangePassword, form); } + /** + * Delete your account. + */ deleteAccount(form: DeleteAccount) { return wrapper(UserOperation.DeleteAccount, form); } + /** + * Reset your password. + */ passwordReset(form: PasswordReset) { return wrapper(UserOperation.PasswordReset, form); } + /** + * Change your password from an email / token based reset. + */ passwordChange(form: PasswordChange) { return wrapper(UserOperation.PasswordChange, form); } + /** + * Create a private message. + */ createPrivateMessage(form: CreatePrivateMessage) { return wrapper(UserOperation.CreatePrivateMessage, form); } + /** + * Edit a private message. + */ editPrivateMessage(form: EditPrivateMessage) { return wrapper(UserOperation.EditPrivateMessage, form); } + /** + * Delete a private message. + */ deletePrivateMessage(form: DeletePrivateMessage) { return wrapper(UserOperation.DeletePrivateMessage, form); } + /** + * Mark a private message as read. + */ markPrivateMessageAsRead(form: MarkPrivateMessageAsRead) { return wrapper(UserOperation.MarkPrivateMessageAsRead, form); } + /** + * Get / fetch private messages. + */ getPrivateMessages(form: GetPrivateMessages) { return wrapper(UserOperation.GetPrivateMessages, form); } + /** + * Save your site config. + */ saveSiteConfig(form: SaveSiteConfig) { return wrapper(UserOperation.SaveSiteConfig, form); } + /** + * Block a person. + */ blockPerson(form: BlockPerson) { return wrapper(UserOperation.BlockPerson, form); } + /** + * Block a community. + */ blockCommunity(form: BlockCommunity) { return wrapper(UserOperation.BlockCommunity, form); } diff --git a/yarn.lock b/yarn.lock index 0a68688..2cc0d67 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1253,6 +1253,18 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.1.7: + version "7.1.7" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" + integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -1289,6 +1301,18 @@ graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== +handlebars@^4.7.7: + version "4.7.7" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" + integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.0" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -1524,6 +1548,13 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" +json5@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== + dependencies: + minimist "^1.2.5" + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz#41108d2cec408c3453c1bbe8a4aae9e1e2bd8f82" @@ -1671,6 +1702,13 @@ loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" @@ -1678,6 +1716,16 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lunr@^2.3.9: + version "2.3.9" + resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" + integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== + +marked@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/marked/-/marked-2.1.3.tgz#bd017cef6431724fd4b27e0657f5ceb14bff3753" + integrity sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA== + merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -1721,14 +1769,14 @@ mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== -minimatch@^3.0.4: +minimatch@^3.0.0, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0: +minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== @@ -1753,6 +1801,11 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +neo-async@^2.6.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + node-fetch@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" @@ -1849,6 +1902,13 @@ onetime@^5.1.0, onetime@^5.1.2: dependencies: mimic-fn "^2.1.0" +onigasm@^2.2.5: + version "2.2.5" + resolved "https://registry.yarnpkg.com/onigasm/-/onigasm-2.2.5.tgz#cc4d2a79a0fa0b64caec1f4c7ea367585a676892" + integrity sha512-F+th54mPc0l1lp1ZcFMyL/jTs2Tlq4SqIHKIXGZOR/VkHkF9A7Fr5rRr5+ZG/lWeRsyrClLYRq7s/yFQ/XhWCA== + dependencies: + lru-cache "^5.1.1" + optionator@^0.9.1: version "0.9.1" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" @@ -2018,7 +2078,7 @@ prettier@^2.3.2: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.2.tgz#ef280a05ec253712e486233db5c6f23441e7342d" integrity sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ== -progress@^2.0.0: +progress@^2.0.0, progress@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== @@ -2197,6 +2257,15 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== +shiki@^0.9.3: + version "0.9.7" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.9.7.tgz#9c760254798a9bbc6df52bbd26f888486f780079" + integrity sha512-rOoAmwRWDiGKjQ1GaSKmbp1J5CamCera+I+DMM3wG/phbwNYQPt1mrjBBZbK66v80Vl1/A9TTLgXVHMbgtOCIQ== + dependencies: + json5 "^2.2.0" + onigasm "^2.2.5" + vscode-textmate "5.2.0" + side-channel@^1.0.2, side-channel@^1.0.3: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -2244,6 +2313,11 @@ source-map@^0.5.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= +source-map@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + spdx-correct@^3.0.0: version "3.1.1" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" @@ -2446,11 +2520,35 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +typedoc-default-themes@^0.12.10: + version "0.12.10" + resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.12.10.tgz#614c4222fe642657f37693ea62cad4dafeddf843" + integrity sha512-fIS001cAYHkyQPidWXmHuhs8usjP5XVJjWB8oZGqkTowZaz3v7g3KDZeeqE82FBrmkAnIBOY3jgy7lnPnqATbA== + +typedoc@^0.21.6: + version "0.21.6" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.21.6.tgz#854bfa2d6b3ac818ac70aa4734a4d1ba93695595" + integrity sha512-+4u3PEBjQdaL5/yfus5WJbjIdQHv7E/FpZq3cNki9BBdGmZhqnTF6JLIXDQ2EfVggojOJG9/soB5QVFgXRYnIw== + dependencies: + glob "^7.1.7" + handlebars "^4.7.7" + lunr "^2.3.9" + marked "^2.1.1" + minimatch "^3.0.0" + progress "^2.0.3" + shiki "^0.9.3" + typedoc-default-themes "^0.12.10" + typescript@^4.3.5: version "4.3.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== +uglify-js@^3.1.4: + version "3.14.1" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.1.tgz#e2cb9fe34db9cb4cf7e35d1d26dfea28e09a7d06" + integrity sha512-JhS3hmcVaXlp/xSo3PKY5R0JqKs5M3IV+exdLHW99qKvKivPO4Z8qbej6mte17SOPqAOVMjt/XGgWacnFSzM3g== + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -2471,6 +2569,11 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +vscode-textmate@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e" + integrity sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ== + which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -2483,6 +2586,11 @@ word-wrap@^1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" @@ -2506,6 +2614,11 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"