feat: add image upload method to http client (#108)

* feat: add image upload method to http client

* fix: Make files optional on UploadImageResponse

* fix: Fix comment typo

* fix: replace loose equals with strict equals

* fix: Remove useless awaits

* fix: Add explicit return types to image upload helper functions

* fix: Include client headers in image upload request

* fix: Change type of uploadImage arg to File | Buffer instead of Blob | Buffer

* doc: Add doc string

* refactor: Switch to using cross-fetch instead of node-fetch v3

* chore: remove unnecessary asyncs
This commit is contained in:
SleeplessOne1917 2023-03-22 14:33:54 -04:00 committed by GitHub
parent 1e6ddc3587
commit 360196c8ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 198 additions and 111 deletions

View file

@ -26,11 +26,11 @@
] ]
}, },
"dependencies": { "dependencies": {
"node-fetch": "2.6.6" "cross-fetch": "^3.1.5",
"form-data": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^18.6.2", "@types/node": "^18.6.2",
"@types/node-fetch": "2.6.2",
"@typescript-eslint/eslint-plugin": "^5.31.0", "@typescript-eslint/eslint-plugin": "^5.31.0",
"@typescript-eslint/parser": "^5.31.0", "@typescript-eslint/parser": "^5.31.0",
"eslint": "^8.20.0", "eslint": "^8.20.0",

View file

@ -1,4 +1,6 @@
import fetch from "node-fetch"; import fetch from "cross-fetch";
import FormData from "form-data";
import { import {
CommentReportResponse, CommentReportResponse,
CommentResponse, CommentResponse,
@ -131,7 +133,7 @@ import {
SearchResponse, SearchResponse,
SiteResponse, SiteResponse,
} from "./interfaces/api/site"; } from "./interfaces/api/site";
import { VERSION } from "./interfaces/others"; import { UploadImage, UploadImageResponse, VERSION } from "./interfaces/others";
enum HttpType { enum HttpType {
Get = "GET", Get = "GET",
@ -145,6 +147,7 @@ enum HttpType {
export class LemmyHttp { export class LemmyHttp {
private apiUrl: string; private apiUrl: string;
private headers: { [key: string]: string } = {}; private headers: { [key: string]: string } = {};
private pictrsUrl: string;
/** /**
* Generates a new instance of LemmyHttp. * Generates a new instance of LemmyHttp.
@ -153,6 +156,7 @@ export class LemmyHttp {
*/ */
constructor(baseUrl: string, headers?: { [key: string]: string }) { constructor(baseUrl: string, headers?: { [key: string]: string }) {
this.apiUrl = `${baseUrl}/api/${VERSION}`; this.apiUrl = `${baseUrl}/api/${VERSION}`;
this.pictrsUrl = `${baseUrl}/pictrs/image`;
if (headers) { if (headers) {
this.headers = headers; this.headers = headers;
@ -164,7 +168,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /site` * `HTTP.GET /site`
*/ */
async getSite(form: GetSite) { getSite(form: GetSite) {
return this.wrapper<GetSite, GetSiteResponse>(HttpType.Get, "/site", form); return this.wrapper<GetSite, GetSiteResponse>(HttpType.Get, "/site", form);
} }
@ -173,7 +177,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /site` * `HTTP.POST /site`
*/ */
async createSite(form: CreateSite) { createSite(form: CreateSite) {
return this.wrapper<CreateSite, SiteResponse>(HttpType.Post, "/site", form); return this.wrapper<CreateSite, SiteResponse>(HttpType.Post, "/site", form);
} }
@ -182,7 +186,7 @@ export class LemmyHttp {
* *
* `HTTP.PUT /site` * `HTTP.PUT /site`
*/ */
async editSite(form: EditSite) { editSite(form: EditSite) {
return this.wrapper<EditSite, SiteResponse>(HttpType.Put, "/site", form); return this.wrapper<EditSite, SiteResponse>(HttpType.Put, "/site", form);
} }
@ -191,7 +195,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /user/leave_admin` * `HTTP.POST /user/leave_admin`
*/ */
async leaveAdmin(form: LeaveAdmin) { leaveAdmin(form: LeaveAdmin) {
return this.wrapper<LeaveAdmin, GetSiteResponse>( return this.wrapper<LeaveAdmin, GetSiteResponse>(
HttpType.Post, HttpType.Post,
"/user/leave_admin", "/user/leave_admin",
@ -204,7 +208,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /modlog` * `HTTP.GET /modlog`
*/ */
async getModlog(form: GetModlog) { getModlog(form: GetModlog) {
return this.wrapper<GetModlog, GetModlogResponse>( return this.wrapper<GetModlog, GetModlogResponse>(
HttpType.Get, HttpType.Get,
"/modlog", "/modlog",
@ -217,7 +221,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /search` * `HTTP.GET /search`
*/ */
async search(form: Search) { search(form: Search) {
return this.wrapper<Search, SearchResponse>(HttpType.Get, "/search", form); return this.wrapper<Search, SearchResponse>(HttpType.Get, "/search", form);
} }
@ -226,7 +230,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /resolve_object` * `HTTP.GET /resolve_object`
*/ */
async resolveObject(form: ResolveObject) { resolveObject(form: ResolveObject) {
return this.wrapper<ResolveObject, ResolveObjectResponse>( return this.wrapper<ResolveObject, ResolveObjectResponse>(
HttpType.Get, HttpType.Get,
"/resolve_object", "/resolve_object",
@ -239,7 +243,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /community` * `HTTP.POST /community`
*/ */
async createCommunity(form: CreateCommunity) { createCommunity(form: CreateCommunity) {
return this.wrapper<CreateCommunity, CommunityResponse>( return this.wrapper<CreateCommunity, CommunityResponse>(
HttpType.Post, HttpType.Post,
"/community", "/community",
@ -252,7 +256,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /community` * `HTTP.GET /community`
*/ */
async getCommunity(form: GetCommunity) { getCommunity(form: GetCommunity) {
return this.wrapper<GetCommunity, GetCommunityResponse>( return this.wrapper<GetCommunity, GetCommunityResponse>(
HttpType.Get, HttpType.Get,
"/community", "/community",
@ -265,7 +269,7 @@ export class LemmyHttp {
* *
* `HTTP.PUT /community` * `HTTP.PUT /community`
*/ */
async editCommunity(form: EditCommunity) { editCommunity(form: EditCommunity) {
return this.wrapper<EditCommunity, CommunityResponse>( return this.wrapper<EditCommunity, CommunityResponse>(
HttpType.Put, HttpType.Put,
"/community", "/community",
@ -278,7 +282,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /community/list` * `HTTP.GET /community/list`
*/ */
async listCommunities(form: ListCommunities) { listCommunities(form: ListCommunities) {
return this.wrapper<ListCommunities, ListCommunitiesResponse>( return this.wrapper<ListCommunities, ListCommunitiesResponse>(
HttpType.Get, HttpType.Get,
"/community/list", "/community/list",
@ -291,7 +295,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /community/follow` * `HTTP.POST /community/follow`
*/ */
async followCommunity(form: FollowCommunity) { followCommunity(form: FollowCommunity) {
return this.wrapper<FollowCommunity, CommunityResponse>( return this.wrapper<FollowCommunity, CommunityResponse>(
HttpType.Post, HttpType.Post,
"/community/follow", "/community/follow",
@ -304,7 +308,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /community/block` * `HTTP.POST /community/block`
*/ */
async blockCommunity(form: BlockCommunity) { blockCommunity(form: BlockCommunity) {
return this.wrapper<BlockCommunity, BlockCommunityResponse>( return this.wrapper<BlockCommunity, BlockCommunityResponse>(
HttpType.Post, HttpType.Post,
"/community/block", "/community/block",
@ -317,7 +321,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /community/delete` * `HTTP.POST /community/delete`
*/ */
async deleteCommunity(form: DeleteCommunity) { deleteCommunity(form: DeleteCommunity) {
return this.wrapper<DeleteCommunity, CommunityResponse>( return this.wrapper<DeleteCommunity, CommunityResponse>(
HttpType.Post, HttpType.Post,
"/community/delete", "/community/delete",
@ -330,7 +334,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /community/remove` * `HTTP.POST /community/remove`
*/ */
async removeCommunity(form: RemoveCommunity) { removeCommunity(form: RemoveCommunity) {
return this.wrapper<RemoveCommunity, CommunityResponse>( return this.wrapper<RemoveCommunity, CommunityResponse>(
HttpType.Post, HttpType.Post,
"/community/remove", "/community/remove",
@ -343,7 +347,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /community/transfer` * `HTTP.POST /community/transfer`
*/ */
async transferCommunity(form: TransferCommunity) { transferCommunity(form: TransferCommunity) {
return this.wrapper<TransferCommunity, GetCommunityResponse>( return this.wrapper<TransferCommunity, GetCommunityResponse>(
HttpType.Post, HttpType.Post,
"/community/transfer", "/community/transfer",
@ -356,7 +360,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /community/ban_user` * `HTTP.POST /community/ban_user`
*/ */
async banFromCommunity(form: BanFromCommunity) { banFromCommunity(form: BanFromCommunity) {
return this.wrapper<BanFromCommunity, BanFromCommunityResponse>( return this.wrapper<BanFromCommunity, BanFromCommunityResponse>(
HttpType.Post, HttpType.Post,
"/community/ban_user", "/community/ban_user",
@ -369,7 +373,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /community/mod` * `HTTP.POST /community/mod`
*/ */
async addModToCommunity(form: AddModToCommunity) { addModToCommunity(form: AddModToCommunity) {
return this.wrapper<AddModToCommunity, AddModToCommunityResponse>( return this.wrapper<AddModToCommunity, AddModToCommunityResponse>(
HttpType.Post, HttpType.Post,
"/community/mod", "/community/mod",
@ -382,7 +386,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /post` * `HTTP.POST /post`
*/ */
async createPost(form: CreatePost) { createPost(form: CreatePost) {
return this.wrapper<CreatePost, PostResponse>(HttpType.Post, "/post", form); return this.wrapper<CreatePost, PostResponse>(HttpType.Post, "/post", form);
} }
@ -391,7 +395,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /post` * `HTTP.GET /post`
*/ */
async getPost(form: GetPost) { getPost(form: GetPost) {
return this.wrapper<GetPost, GetPostResponse>(HttpType.Get, "/post", form); return this.wrapper<GetPost, GetPostResponse>(HttpType.Get, "/post", form);
} }
@ -400,7 +404,7 @@ export class LemmyHttp {
* *
* `HTTP.PUT /post` * `HTTP.PUT /post`
*/ */
async editPost(form: EditPost) { editPost(form: EditPost) {
return this.wrapper<EditPost, PostResponse>(HttpType.Put, "/post", form); return this.wrapper<EditPost, PostResponse>(HttpType.Put, "/post", form);
} }
@ -409,7 +413,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /post/delete` * `HTTP.POST /post/delete`
*/ */
async deletePost(form: DeletePost) { deletePost(form: DeletePost) {
return this.wrapper<DeletePost, PostResponse>( return this.wrapper<DeletePost, PostResponse>(
HttpType.Post, HttpType.Post,
"/post/delete", "/post/delete",
@ -422,7 +426,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /post/remove` * `HTTP.POST /post/remove`
*/ */
async removePost(form: RemovePost) { removePost(form: RemovePost) {
return this.wrapper<RemovePost, PostResponse>( return this.wrapper<RemovePost, PostResponse>(
HttpType.Post, HttpType.Post,
"/post/remove", "/post/remove",
@ -435,7 +439,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /post/mark_as_read` * `HTTP.POST /post/mark_as_read`
*/ */
async markPostAsRead(form: MarkPostAsRead) { markPostAsRead(form: MarkPostAsRead) {
return this.wrapper<MarkPostAsRead, PostResponse>( return this.wrapper<MarkPostAsRead, PostResponse>(
HttpType.Post, HttpType.Post,
"/post/mark_as_read", "/post/mark_as_read",
@ -448,7 +452,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /post/lock` * `HTTP.POST /post/lock`
*/ */
async lockPost(form: LockPost) { lockPost(form: LockPost) {
return this.wrapper<LockPost, PostResponse>( return this.wrapper<LockPost, PostResponse>(
HttpType.Post, HttpType.Post,
"/post/lock", "/post/lock",
@ -461,7 +465,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /post/feature` * `HTTP.POST /post/feature`
*/ */
async featurePost(form: FeaturePost) { featurePost(form: FeaturePost) {
return this.wrapper<FeaturePost, PostResponse>( return this.wrapper<FeaturePost, PostResponse>(
HttpType.Post, HttpType.Post,
"/post/feature", "/post/feature",
@ -474,7 +478,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /post/list` * `HTTP.GET /post/list`
*/ */
async getPosts(form: GetPosts) { getPosts(form: GetPosts) {
return this.wrapper<GetPosts, GetPostsResponse>( return this.wrapper<GetPosts, GetPostsResponse>(
HttpType.Get, HttpType.Get,
"/post/list", "/post/list",
@ -487,7 +491,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /post/like` * `HTTP.POST /post/like`
*/ */
async likePost(form: CreatePostLike) { likePost(form: CreatePostLike) {
return this.wrapper<CreatePostLike, PostResponse>( return this.wrapper<CreatePostLike, PostResponse>(
HttpType.Post, HttpType.Post,
"/post/like", "/post/like",
@ -500,7 +504,7 @@ export class LemmyHttp {
* *
* `HTTP.PUT /post/save` * `HTTP.PUT /post/save`
*/ */
async savePost(form: SavePost) { savePost(form: SavePost) {
return this.wrapper<SavePost, PostResponse>( return this.wrapper<SavePost, PostResponse>(
HttpType.Put, HttpType.Put,
"/post/save", "/post/save",
@ -513,7 +517,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /post/report` * `HTTP.POST /post/report`
*/ */
async createPostReport(form: CreatePostReport) { createPostReport(form: CreatePostReport) {
return this.wrapper<CreatePostReport, PostReportResponse>( return this.wrapper<CreatePostReport, PostReportResponse>(
HttpType.Post, HttpType.Post,
"/post/report", "/post/report",
@ -526,7 +530,7 @@ export class LemmyHttp {
* *
* `HTTP.PUT /post/report/resolve` * `HTTP.PUT /post/report/resolve`
*/ */
async resolvePostReport(form: ResolvePostReport) { resolvePostReport(form: ResolvePostReport) {
return this.wrapper<ResolvePostReport, PostReportResponse>( return this.wrapper<ResolvePostReport, PostReportResponse>(
HttpType.Put, HttpType.Put,
"/post/report/resolve", "/post/report/resolve",
@ -539,7 +543,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /post/report/list` * `HTTP.GET /post/report/list`
*/ */
async listPostReports(form: ListPostReports) { listPostReports(form: ListPostReports) {
return this.wrapper<ListPostReports, ListPostReportsResponse>( return this.wrapper<ListPostReports, ListPostReportsResponse>(
HttpType.Get, HttpType.Get,
"/post/report/list", "/post/report/list",
@ -552,7 +556,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /post/site_metadata` * `HTTP.GET /post/site_metadata`
*/ */
async getSiteMetadata(form: GetSiteMetadata) { getSiteMetadata(form: GetSiteMetadata) {
return this.wrapper<GetSiteMetadata, GetSiteMetadataResponse>( return this.wrapper<GetSiteMetadata, GetSiteMetadataResponse>(
HttpType.Get, HttpType.Get,
"/post/site_metadata", "/post/site_metadata",
@ -565,7 +569,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /comment` * `HTTP.POST /comment`
*/ */
async createComment(form: CreateComment) { createComment(form: CreateComment) {
return this.wrapper<CreateComment, CommentResponse>( return this.wrapper<CreateComment, CommentResponse>(
HttpType.Post, HttpType.Post,
"/comment", "/comment",
@ -578,7 +582,7 @@ export class LemmyHttp {
* *
* `HTTP.PUT /comment` * `HTTP.PUT /comment`
*/ */
async editComment(form: EditComment) { editComment(form: EditComment) {
return this.wrapper<EditComment, CommentResponse>( return this.wrapper<EditComment, CommentResponse>(
HttpType.Put, HttpType.Put,
"/comment", "/comment",
@ -591,7 +595,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /comment/delete` * `HTTP.POST /comment/delete`
*/ */
async deleteComment(form: DeleteComment) { deleteComment(form: DeleteComment) {
return this.wrapper<DeleteComment, CommentResponse>( return this.wrapper<DeleteComment, CommentResponse>(
HttpType.Post, HttpType.Post,
"/comment/delete", "/comment/delete",
@ -604,7 +608,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /comment/remove` * `HTTP.POST /comment/remove`
*/ */
async removeComment(form: RemoveComment) { removeComment(form: RemoveComment) {
return this.wrapper<RemoveComment, CommentResponse>( return this.wrapper<RemoveComment, CommentResponse>(
HttpType.Post, HttpType.Post,
"/comment/remove", "/comment/remove",
@ -617,7 +621,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /comment/mark_as_read` * `HTTP.POST /comment/mark_as_read`
*/ */
async markCommentReplyAsRead(form: MarkCommentReplyAsRead) { markCommentReplyAsRead(form: MarkCommentReplyAsRead) {
return this.wrapper<MarkCommentReplyAsRead, CommentResponse>( return this.wrapper<MarkCommentReplyAsRead, CommentResponse>(
HttpType.Post, HttpType.Post,
"/comment/mark_as_read", "/comment/mark_as_read",
@ -630,7 +634,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /comment/like` * `HTTP.POST /comment/like`
*/ */
async likeComment(form: CreateCommentLike) { likeComment(form: CreateCommentLike) {
return this.wrapper<CreateCommentLike, CommentResponse>( return this.wrapper<CreateCommentLike, CommentResponse>(
HttpType.Post, HttpType.Post,
"/comment/like", "/comment/like",
@ -643,7 +647,7 @@ export class LemmyHttp {
* *
* `HTTP.PUT /comment/save` * `HTTP.PUT /comment/save`
*/ */
async saveComment(form: SaveComment) { saveComment(form: SaveComment) {
return this.wrapper<SaveComment, CommentResponse>( return this.wrapper<SaveComment, CommentResponse>(
HttpType.Put, HttpType.Put,
"/comment/save", "/comment/save",
@ -656,7 +660,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /comment/list` * `HTTP.GET /comment/list`
*/ */
async getComments(form: GetComments) { getComments(form: GetComments) {
return this.wrapper<GetComments, GetCommentsResponse>( return this.wrapper<GetComments, GetCommentsResponse>(
HttpType.Get, HttpType.Get,
"/comment/list", "/comment/list",
@ -669,7 +673,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /comment/report` * `HTTP.POST /comment/report`
*/ */
async createCommentReport(form: CreateCommentReport) { createCommentReport(form: CreateCommentReport) {
return this.wrapper<CreateCommentReport, CommentReportResponse>( return this.wrapper<CreateCommentReport, CommentReportResponse>(
HttpType.Post, HttpType.Post,
"/comment/report", "/comment/report",
@ -682,7 +686,7 @@ export class LemmyHttp {
* *
* `HTTP.PUT /comment/report/resolve` * `HTTP.PUT /comment/report/resolve`
*/ */
async resolveCommentReport(form: ResolveCommentReport) { resolveCommentReport(form: ResolveCommentReport) {
return this.wrapper<ResolveCommentReport, CommentReportResponse>( return this.wrapper<ResolveCommentReport, CommentReportResponse>(
HttpType.Put, HttpType.Put,
"/comment/report/resolve", "/comment/report/resolve",
@ -695,7 +699,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /comment/report/list` * `HTTP.GET /comment/report/list`
*/ */
async listCommentReports(form: ListCommentReports) { listCommentReports(form: ListCommentReports) {
return this.wrapper<ListCommentReports, ListCommentReportsResponse>( return this.wrapper<ListCommentReports, ListCommentReportsResponse>(
HttpType.Get, HttpType.Get,
"/comment/report/list", "/comment/report/list",
@ -708,7 +712,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /private_message/list` * `HTTP.GET /private_message/list`
*/ */
async getPrivateMessages(form: GetPrivateMessages) { getPrivateMessages(form: GetPrivateMessages) {
return this.wrapper<GetPrivateMessages, PrivateMessagesResponse>( return this.wrapper<GetPrivateMessages, PrivateMessagesResponse>(
HttpType.Get, HttpType.Get,
"/private_message/list", "/private_message/list",
@ -721,7 +725,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /private_message` * `HTTP.POST /private_message`
*/ */
async createPrivateMessage(form: CreatePrivateMessage) { createPrivateMessage(form: CreatePrivateMessage) {
return this.wrapper<CreatePrivateMessage, PrivateMessageResponse>( return this.wrapper<CreatePrivateMessage, PrivateMessageResponse>(
HttpType.Post, HttpType.Post,
"/private_message", "/private_message",
@ -734,7 +738,7 @@ export class LemmyHttp {
* *
* `HTTP.PUT /private_message` * `HTTP.PUT /private_message`
*/ */
async editPrivateMessage(form: EditPrivateMessage) { editPrivateMessage(form: EditPrivateMessage) {
return this.wrapper<EditPrivateMessage, PrivateMessageResponse>( return this.wrapper<EditPrivateMessage, PrivateMessageResponse>(
HttpType.Put, HttpType.Put,
"/private_message", "/private_message",
@ -747,7 +751,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /private_message/delete` * `HTTP.POST /private_message/delete`
*/ */
async deletePrivateMessage(form: DeletePrivateMessage) { deletePrivateMessage(form: DeletePrivateMessage) {
return this.wrapper<DeletePrivateMessage, PrivateMessageResponse>( return this.wrapper<DeletePrivateMessage, PrivateMessageResponse>(
HttpType.Post, HttpType.Post,
"/private_message/delete", "/private_message/delete",
@ -760,7 +764,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /private_message/mark_as_read` * `HTTP.POST /private_message/mark_as_read`
*/ */
async markPrivateMessageAsRead(form: MarkPrivateMessageAsRead) { markPrivateMessageAsRead(form: MarkPrivateMessageAsRead) {
return this.wrapper<MarkPrivateMessageAsRead, PrivateMessageResponse>( return this.wrapper<MarkPrivateMessageAsRead, PrivateMessageResponse>(
HttpType.Post, HttpType.Post,
"/private_message/mark_as_read", "/private_message/mark_as_read",
@ -773,7 +777,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /private_message/report` * `HTTP.POST /private_message/report`
*/ */
async createPrivateMessageReport(form: CreatePrivateMessageReport) { createPrivateMessageReport(form: CreatePrivateMessageReport) {
return this.wrapper< return this.wrapper<
CreatePrivateMessageReport, CreatePrivateMessageReport,
PrivateMessageReportResponse PrivateMessageReportResponse
@ -785,7 +789,7 @@ export class LemmyHttp {
* *
* `HTTP.PUT /private_message/report/resolve` * `HTTP.PUT /private_message/report/resolve`
*/ */
async resolvePrivateMessageReport(form: ResolvePrivateMessageReport) { resolvePrivateMessageReport(form: ResolvePrivateMessageReport) {
return this.wrapper< return this.wrapper<
ResolvePrivateMessageReport, ResolvePrivateMessageReport,
PrivateMessageReportResponse PrivateMessageReportResponse
@ -797,7 +801,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /private_message/report/list` * `HTTP.GET /private_message/report/list`
*/ */
async listPrivateMessageReports(form: ListPrivateMessageReports) { listPrivateMessageReports(form: ListPrivateMessageReports) {
return this.wrapper< return this.wrapper<
ListPrivateMessageReports, ListPrivateMessageReports,
ListPrivateMessageReportsResponse ListPrivateMessageReportsResponse
@ -809,7 +813,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /user/register` * `HTTP.POST /user/register`
*/ */
async register(form: Register) { register(form: Register) {
return this.wrapper<Register, LoginResponse>( return this.wrapper<Register, LoginResponse>(
HttpType.Post, HttpType.Post,
"/user/register", "/user/register",
@ -822,7 +826,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /user/login` * `HTTP.POST /user/login`
*/ */
async login(form: Login) { login(form: Login) {
return this.wrapper<Login, LoginResponse>( return this.wrapper<Login, LoginResponse>(
HttpType.Post, HttpType.Post,
"/user/login", "/user/login",
@ -835,7 +839,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /user` * `HTTP.GET /user`
*/ */
async getPersonDetails(form: GetPersonDetails) { getPersonDetails(form: GetPersonDetails) {
return this.wrapper<GetPersonDetails, GetPersonDetailsResponse>( return this.wrapper<GetPersonDetails, GetPersonDetailsResponse>(
HttpType.Get, HttpType.Get,
"/user", "/user",
@ -848,7 +852,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /user/mention` * `HTTP.GET /user/mention`
*/ */
async getPersonMentions(form: GetPersonMentions) { getPersonMentions(form: GetPersonMentions) {
return this.wrapper<GetPersonMentions, GetPersonMentionsResponse>( return this.wrapper<GetPersonMentions, GetPersonMentionsResponse>(
HttpType.Get, HttpType.Get,
"/user/mention", "/user/mention",
@ -861,7 +865,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /user/mention/mark_as_read` * `HTTP.POST /user/mention/mark_as_read`
*/ */
async markPersonMentionAsRead(form: MarkPersonMentionAsRead) { markPersonMentionAsRead(form: MarkPersonMentionAsRead) {
return this.wrapper<MarkPersonMentionAsRead, PersonMentionResponse>( return this.wrapper<MarkPersonMentionAsRead, PersonMentionResponse>(
HttpType.Post, HttpType.Post,
"/user/mention/mark_as_read", "/user/mention/mark_as_read",
@ -874,7 +878,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /user/replies` * `HTTP.GET /user/replies`
*/ */
async getReplies(form: GetReplies) { getReplies(form: GetReplies) {
return this.wrapper<GetReplies, GetRepliesResponse>( return this.wrapper<GetReplies, GetRepliesResponse>(
HttpType.Get, HttpType.Get,
"/user/replies", "/user/replies",
@ -887,7 +891,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /user/ban` * `HTTP.POST /user/ban`
*/ */
async banPerson(form: BanPerson) { banPerson(form: BanPerson) {
return this.wrapper<BanPerson, BanPersonResponse>( return this.wrapper<BanPerson, BanPersonResponse>(
HttpType.Post, HttpType.Post,
"/user/ban", "/user/ban",
@ -900,7 +904,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /user/banned` * `HTTP.GET /user/banned`
*/ */
async getBannedPersons(form: GetBannedPersons) { getBannedPersons(form: GetBannedPersons) {
return this.wrapper<GetBannedPersons, BannedPersonsResponse>( return this.wrapper<GetBannedPersons, BannedPersonsResponse>(
HttpType.Get, HttpType.Get,
"/user/banned", "/user/banned",
@ -913,7 +917,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /user/block` * `HTTP.POST /user/block`
*/ */
async blockPerson(form: BlockPerson) { blockPerson(form: BlockPerson) {
return this.wrapper<BlockPerson, BlockPersonResponse>( return this.wrapper<BlockPerson, BlockPersonResponse>(
HttpType.Post, HttpType.Post,
"/user/block", "/user/block",
@ -926,7 +930,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /user/get_captcha` * `HTTP.GET /user/get_captcha`
*/ */
async getCaptcha() { getCaptcha() {
return this.wrapper<any, GetCaptchaResponse>( return this.wrapper<any, GetCaptchaResponse>(
HttpType.Get, HttpType.Get,
"/user/get_captcha", "/user/get_captcha",
@ -939,7 +943,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /user/delete_account` * `HTTP.POST /user/delete_account`
*/ */
async deleteAccount(form: DeleteAccount) { deleteAccount(form: DeleteAccount) {
return this.wrapper<DeleteAccount, DeleteAccountResponse>( return this.wrapper<DeleteAccount, DeleteAccountResponse>(
HttpType.Post, HttpType.Post,
"/user/delete_account", "/user/delete_account",
@ -952,7 +956,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /user/password_reset` * `HTTP.POST /user/password_reset`
*/ */
async passwordReset(form: PasswordReset) { passwordReset(form: PasswordReset) {
return this.wrapper<PasswordReset, PasswordResetResponse>( return this.wrapper<PasswordReset, PasswordResetResponse>(
HttpType.Post, HttpType.Post,
"/user/password_reset", "/user/password_reset",
@ -965,7 +969,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /user/password_change` * `HTTP.POST /user/password_change`
*/ */
async passwordChange(form: PasswordChange) { passwordChange(form: PasswordChange) {
return this.wrapper<PasswordChange, LoginResponse>( return this.wrapper<PasswordChange, LoginResponse>(
HttpType.Post, HttpType.Post,
"/user/password_change", "/user/password_change",
@ -978,7 +982,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /user/mark_all_as_read` * `HTTP.POST /user/mark_all_as_read`
*/ */
async markAllAsRead(form: MarkAllAsRead) { markAllAsRead(form: MarkAllAsRead) {
return this.wrapper<MarkAllAsRead, GetRepliesResponse>( return this.wrapper<MarkAllAsRead, GetRepliesResponse>(
HttpType.Post, HttpType.Post,
"/user/mark_all_as_read", "/user/mark_all_as_read",
@ -991,7 +995,7 @@ export class LemmyHttp {
* *
* `HTTP.PUT /user/save_user_settings` * `HTTP.PUT /user/save_user_settings`
*/ */
async saveUserSettings(form: SaveUserSettings) { saveUserSettings(form: SaveUserSettings) {
return this.wrapper<SaveUserSettings, LoginResponse>( return this.wrapper<SaveUserSettings, LoginResponse>(
HttpType.Put, HttpType.Put,
"/user/save_user_settings", "/user/save_user_settings",
@ -1004,7 +1008,7 @@ export class LemmyHttp {
* *
* `HTTP.PUT /user/change_password` * `HTTP.PUT /user/change_password`
*/ */
async changePassword(form: ChangePassword) { changePassword(form: ChangePassword) {
return this.wrapper<ChangePassword, LoginResponse>( return this.wrapper<ChangePassword, LoginResponse>(
HttpType.Put, HttpType.Put,
"/user/change_password", "/user/change_password",
@ -1017,7 +1021,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /user/report_count` * `HTTP.GET /user/report_count`
*/ */
async getReportCount(form: GetReportCount) { getReportCount(form: GetReportCount) {
return this.wrapper<GetReportCount, GetReportCountResponse>( return this.wrapper<GetReportCount, GetReportCountResponse>(
HttpType.Get, HttpType.Get,
"/user/report_count", "/user/report_count",
@ -1030,7 +1034,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /user/unread_count` * `HTTP.GET /user/unread_count`
*/ */
async getUnreadCount(form: GetUnreadCount) { getUnreadCount(form: GetUnreadCount) {
return this.wrapper<GetUnreadCount, GetUnreadCountResponse>( return this.wrapper<GetUnreadCount, GetUnreadCountResponse>(
HttpType.Get, HttpType.Get,
"/user/unread_count", "/user/unread_count",
@ -1043,7 +1047,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /user/verify_email` * `HTTP.POST /user/verify_email`
*/ */
async verifyEmail(form: VerifyEmail) { verifyEmail(form: VerifyEmail) {
return this.wrapper<VerifyEmail, VerifyEmailResponse>( return this.wrapper<VerifyEmail, VerifyEmailResponse>(
HttpType.Post, HttpType.Post,
"/user/verify_email", "/user/verify_email",
@ -1056,7 +1060,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /admin/add` * `HTTP.POST /admin/add`
*/ */
async addAdmin(form: AddAdmin) { addAdmin(form: AddAdmin) {
return this.wrapper<AddAdmin, AddAdminResponse>( return this.wrapper<AddAdmin, AddAdminResponse>(
HttpType.Post, HttpType.Post,
"/admin/add", "/admin/add",
@ -1069,7 +1073,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /admin/registration_application/count` * `HTTP.GET /admin/registration_application/count`
*/ */
async getUnreadRegistrationApplicationCount( getUnreadRegistrationApplicationCount(
form: GetUnreadRegistrationApplicationCount form: GetUnreadRegistrationApplicationCount
) { ) {
return this.wrapper< return this.wrapper<
@ -1083,7 +1087,7 @@ export class LemmyHttp {
* *
* `HTTP.GET /admin/registration_application/list` * `HTTP.GET /admin/registration_application/list`
*/ */
async listRegistrationApplications(form: ListRegistrationApplications) { listRegistrationApplications(form: ListRegistrationApplications) {
return this.wrapper< return this.wrapper<
ListRegistrationApplications, ListRegistrationApplications,
ListRegistrationApplicationsResponse ListRegistrationApplicationsResponse
@ -1095,7 +1099,7 @@ export class LemmyHttp {
* *
* `HTTP.PUT /admin/registration_application/approve` * `HTTP.PUT /admin/registration_application/approve`
*/ */
async approveRegistrationApplication(form: ApproveRegistrationApplication) { approveRegistrationApplication(form: ApproveRegistrationApplication) {
return this.wrapper< return this.wrapper<
ApproveRegistrationApplication, ApproveRegistrationApplication,
RegistrationApplicationResponse RegistrationApplicationResponse
@ -1107,7 +1111,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /admin/purge/person` * `HTTP.POST /admin/purge/person`
*/ */
async purgePerson(form: PurgePerson) { purgePerson(form: PurgePerson) {
return this.wrapper<PurgePerson, PurgeItemResponse>( return this.wrapper<PurgePerson, PurgeItemResponse>(
HttpType.Post, HttpType.Post,
"/admin/purge/person", "/admin/purge/person",
@ -1120,7 +1124,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /admin/purge/community` * `HTTP.POST /admin/purge/community`
*/ */
async purgeCommunity(form: PurgeCommunity) { purgeCommunity(form: PurgeCommunity) {
return this.wrapper<PurgeCommunity, PurgeItemResponse>( return this.wrapper<PurgeCommunity, PurgeItemResponse>(
HttpType.Post, HttpType.Post,
"/admin/purge/community", "/admin/purge/community",
@ -1133,7 +1137,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /admin/purge/post` * `HTTP.POST /admin/purge/post`
*/ */
async purgePost(form: PurgePost) { purgePost(form: PurgePost) {
return this.wrapper<PurgePost, PurgeItemResponse>( return this.wrapper<PurgePost, PurgeItemResponse>(
HttpType.Post, HttpType.Post,
"/admin/purge/post", "/admin/purge/post",
@ -1146,7 +1150,7 @@ export class LemmyHttp {
* *
* `HTTP.POST /admin/purge/comment` * `HTTP.POST /admin/purge/comment`
*/ */
async purgeComment(form: PurgeComment) { purgeComment(form: PurgeComment) {
return this.wrapper<PurgeComment, PurgeItemResponse>( return this.wrapper<PurgeComment, PurgeItemResponse>(
HttpType.Post, HttpType.Post,
"/admin/purge/comment", "/admin/purge/comment",
@ -1154,7 +1158,52 @@ export class LemmyHttp {
); );
} }
private buildFullUrl(endpoint: string): string { /**
* Upload an image to the server.
*/
async uploadImage({
image,
auth,
}: UploadImage): Promise<UploadImageResponse> {
const formData = createFormData(image);
// If jwt cookie not already set by browser, set it with passed in auth
const headers = {} as any;
if (
!globalThis?.document?.cookie?.includes("jwt=") &&
!this.headers?.Cookie?.includes("jwt=")
) {
headers.Cookie = `jwt=${auth}`;
}
let url: string | undefined = undefined;
let delete_url: string | undefined = undefined;
const response = await fetch(this.pictrsUrl, {
method: HttpType.Post,
body: formData as unknown as BodyInit,
headers: {
...this.headers,
...headers,
},
});
const responseJson = await response.json();
if (responseJson.msg === "ok") {
const { file: hash, delete_token: deleteToken } = responseJson.files[0];
delete_url = `${this.pictrsUrl}/delete/${deleteToken}/${hash}`;
url = `${this.pictrsUrl}/${hash}`;
}
return {
...responseJson,
url,
delete_url,
};
}
private buildFullUrl(endpoint: string) {
return `${this.apiUrl}${endpoint}`; return `${this.apiUrl}${endpoint}`;
} }
@ -1163,21 +1212,25 @@ export class LemmyHttp {
endpoint: string, endpoint: string,
form: BodyType form: BodyType
): Promise<ResponseType> { ): Promise<ResponseType> {
if (type_ == HttpType.Get) { if (type_ === HttpType.Get) {
let getUrl = `${this.buildFullUrl(endpoint)}?${encodeGetParams(form)}`; const getUrl = `${this.buildFullUrl(endpoint)}?${encodeGetParams(form)}`;
return fetch(getUrl, { const response = await fetch(getUrl, {
method: "GET", method: HttpType.Get,
headers: this.headers, headers: this.headers,
}).then(d => d.json() as Promise<ResponseType>); });
return await response.json();
} else { } else {
return fetch(this.buildFullUrl(endpoint), { const response = await fetch(this.buildFullUrl(endpoint), {
method: type_, method: type_,
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
...this.headers, ...this.headers,
}, },
body: JSON.stringify(form), body: JSON.stringify(form),
}).then(d => d.json() as Promise<ResponseType>); });
return await response.json();
} }
} }
} }
@ -1188,3 +1241,16 @@ function encodeGetParams<BodyType extends object>(p: BodyType): string {
.map(kv => kv.map(encodeURIComponent).join("=")) .map(kv => kv.map(encodeURIComponent).join("="))
.join("&"); .join("&");
} }
function createFormData(image: File | Buffer): FormData {
let formData = new FormData();
if (image.constructor.name === "File") {
formData.append("images[]", image);
} else {
// The filename doesn't affect the file type or file name that ends up in pictrs
formData.append("images[]", image, { filename: "image.jpg" });
}
return formData;
}

View file

@ -230,3 +230,26 @@ export interface SiteMetadata {
image?: string; image?: string;
html?: string; html?: string;
} }
export interface UploadImage {
image: File | Buffer;
/**
* Optional if cookie with jwt set is already present. Otherwise, auth is required.
*/
auth?: string;
}
export interface UploadImageResponse {
/**
* Is "ok" if the upload was successful; is something else otherwise.
*/
msg: string;
files?: ImageFile[];
url?: string;
delete_url?: string;
}
export interface ImageFile {
file: string;
delete_token: string;
}

View file

@ -9,10 +9,9 @@
"target": "ES5", "target": "ES5",
"experimentalDecorators": true, "experimentalDecorators": true,
"strictNullChecks": true, "strictNullChecks": true,
"moduleResolution": "Node" "moduleResolution": "Node",
"esModuleInterop": true
}, },
"include": [ "include": ["src/**/*"],
"src/**/*"
],
"exclude": ["node_modules", "dist"] "exclude": ["node_modules", "dist"]
} }

View file

@ -303,14 +303,6 @@
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca"
integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==
"@types/node-fetch@2.6.2":
version "2.6.2"
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.2.tgz#d1a9c5fd049d9415dce61571557104dec3ec81da"
integrity sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==
dependencies:
"@types/node" "*"
form-data "^3.0.0"
"@types/node@*", "@types/node@^18.6.2": "@types/node@*", "@types/node@^18.6.2":
version "18.11.18" version "18.11.18"
resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f"
@ -665,6 +657,13 @@ cosmiconfig@^5.0.5:
js-yaml "^3.13.1" js-yaml "^3.13.1"
parse-json "^4.0.0" parse-json "^4.0.0"
cross-fetch@^3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f"
integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==
dependencies:
node-fetch "2.6.7"
cross-spawn@^7.0.2, cross-spawn@^7.0.3: cross-spawn@^7.0.2, cross-spawn@^7.0.3:
version "7.0.3" version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
@ -988,10 +987,10 @@ flatted@^3.1.0:
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787"
integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==
form-data@^3.0.0: form-data@^4.0.0:
version "3.0.1" version "4.0.0"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies: dependencies:
asynckit "^0.4.0" asynckit "^0.4.0"
combined-stream "^1.0.8" combined-stream "^1.0.8"
@ -1513,10 +1512,10 @@ neo-async@^2.6.0:
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
node-fetch@2.6.6: node-fetch@2.6.7:
version "2.6.6" version "2.6.7"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA== integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
dependencies: dependencies:
whatwg-url "^5.0.0" whatwg-url "^5.0.0"