Started implementing PictureService (Testing+JSDoc TODO)

This commit is contained in:
2026-04-03 07:38:53 +02:00
parent f61fcb4daa
commit 7b1d023a94
7 changed files with 359 additions and 19 deletions

View File

@@ -1,9 +1,11 @@
export interface SDKConfig {
apiUrl: string;
cdnUrl: string;
}
const DefaultEnvironment: SDKConfig = {
apiUrl: "https://api.chatenium.hu"
apiUrl: "https://api.chatenium.hu",
cdnUrl: "https://cdn.chatenium.hu",
}
let currentConfig = {...DefaultEnvironment}

View File

@@ -1,11 +1,11 @@
import axios, {AxiosInstance} from 'axios';
import {environment} from "./environment";
export const getClient = () => {
export const getClient = (cdn: boolean) => {
const env = environment.get();
return axios.create({
baseURL: env.apiUrl,
baseURL: cdn ? env.cdnUrl : env.apiUrl,
timeout: 5000,
headers: {'Content-Type': 'application/json'}
});

View File

@@ -0,0 +1,98 @@
import {PublicUserData, TimeStamp} from "./common.schema";
// Request schemas
export interface GetReq {
userid: string
target: string
}
export interface CreateAlbumReq {
name: string
userid: string
}
export interface FinalizeUploadReq {
userid: string
uploadId: string
}
export interface DeleteImageReq {
userid: string
imageId: string
}
export interface ChangePictureVisibilityReq {
visibility: string
userid: string
imageId: string
}
export interface EditPictureTitleReq {
title: string
userid: string
imageId: string
}
export interface TogglePictureLikeReq {
userid: string
imageId: string
}
export interface PostCommentReq {
comment: string
userid: string
imageId: string
}
export interface ToggleFollowReq {
uploaderId: string
userid: string
}
export interface GetAlbumReq {
userid: string
}
export interface GetCommentsReq {
imageId: string
}
export interface UploadImageReq {
userid: string
picture: string
title: string
visibility: string
album: string
uploadId: string
name: string
}
// Response schemas
export interface GetResp {
userData: PublicUserData
pictures: Album[]
}
export interface DiscoveryResp {
recent: Image[]
mostLiked: Image[]
}
// Types
export interface Album {
created_at: TimeStamp
name: string
albumId: string
images: Image[]
}
export interface Image {
path: string
visibility: string
title: string
imageId: string
uploaded_at: TimeStamp
liked: boolean
likes: number
userData: PublicUserData | null
}

View File

@@ -17,7 +17,7 @@ export class AuthService {
*/
async getAuthMethods(unameMailPhone: string): Promise<AuthMethods> {
try {
const resp = await getClient().get<AuthMethods>(`user/authOptions?unameMailPhone=${unameMailPhone}`);
const resp = await getClient(false).get<AuthMethods>(`user/authOptions?unameMailPhone=${unameMailPhone}`);
return resp.data
} catch (e) {
if (isAxiosError<GenericErrorBody>(e)) {
@@ -35,7 +35,7 @@ export class AuthService {
*/
async otpSendCode(unameMailPhone: string, type: number): Promise<void|number> {
try {
const resp = await getClient().post<OtpPleCodeSendTestingResp>("v2/user/otpSendCode", <OtpSendCodeReq>{
const resp = await getClient(false).post<OtpPleCodeSendTestingResp>("v2/user/otpSendCode", <OtpSendCodeReq>{
usernamePhoneMail: unameMailPhone,
type: type
});
@@ -60,7 +60,7 @@ export class AuthService {
*/
async otpVerifyCode(unameMailPhone: string, type: number, code: number): Promise<SignInSuccessResp> {
try {
const resp = await getClient().post<SignInSuccessResp>("v2/user/otpVerifyCode", <OtpVerifyCodeReq>{
const resp = await getClient(false).post<SignInSuccessResp>("v2/user/otpVerifyCode", <OtpVerifyCodeReq>{
usernamePhoneMail: unameMailPhone,
type: type,
code: code
@@ -81,7 +81,7 @@ export class AuthService {
*/
async loginPasswordAuth(usernamePhoneMail: string, password: string): Promise<SignInSuccessResp> {
try {
const resp = await getClient().post<SignInSuccessResp>("v2/user/loginPasswordAuth", <LoginPasswordAuthReq>{
const resp = await getClient(false).post<SignInSuccessResp>("v2/user/loginPasswordAuth", <LoginPasswordAuthReq>{
unameMailPhone: usernamePhoneMail,
password: password
});
@@ -99,7 +99,7 @@ export class AuthService {
*/
async isUsernameUsed(username: string): Promise<Boolean> {
try {
const resp = await getClient().get<UserDataValidationResp>(`v2/user/unameUsage?username=${username}`);
const resp = await getClient(false).get<UserDataValidationResp>(`v2/user/unameUsage?username=${username}`);
return resp.data.used
} catch (e) {
if (isAxiosError<GenericErrorBody>(e)) {
@@ -114,7 +114,7 @@ export class AuthService {
*/
async isEmailUsed(email: string): Promise<Boolean> {
try {
const resp = await getClient().get<UserDataValidationResp>(`v2/user/emailUsage?email=${email}`);
const resp = await getClient(false).get<UserDataValidationResp>(`v2/user/emailUsage?email=${email}`);
return resp.data.used
} catch (e) {
if (isAxiosError<GenericErrorBody>(e)) {
@@ -132,7 +132,7 @@ export class AuthService {
*/
async pleSendVCode(phoneMail: string, type: number): Promise<void|number> {
try {
const resp = await getClient().post<OtpPleCodeSendTestingResp>("v2/user/pleSendVCode", <PleSendCodeReq>{
const resp = await getClient(false).post<OtpPleCodeSendTestingResp>("v2/user/pleSendVCode", <PleSendCodeReq>{
phoneMail: phoneMail,
type: type,
});
@@ -157,7 +157,7 @@ export class AuthService {
*/
async pleVerifyCode(phoneMail: string, type: number, code: number): Promise<string> {
try {
const resp = await getClient().post<PleVerifyCodeResp>("v2/user/pleVerifyCode", <PleVerifyCodeReq>{
const resp = await getClient(false).post<PleVerifyCodeResp>("v2/user/pleVerifyCode", <PleVerifyCodeReq>{
phoneMail: phoneMail,
type: type,
code: code
@@ -181,7 +181,7 @@ export class AuthService {
*/
async finishPLEAccount(phoneMail: string, authCode: string, username: string, displayName: string|null): Promise<SignInSuccessResp> {
try {
const resp = await getClient().post<SignInSuccessResp>("v2/user/finishPLEAccount", <FinishPleAccountReq>{
const resp = await getClient(false).post<SignInSuccessResp>("v2/user/finishPLEAccount", <FinishPleAccountReq>{
phoneMail: phoneMail,
authCode: authCode,
displayName: displayName,
@@ -202,7 +202,7 @@ export class AuthService {
*/
async loginWithGoogle(code: string): Promise<SignInSuccessResp> {
try {
const resp = await getClient().post<SignInSuccessResp>("user/loginWithGoogle", <LoginWithGoogleReq>{
const resp = await getClient(false).post<SignInSuccessResp>("user/loginWithGoogle", <LoginWithGoogleReq>{
code: code
});
return resp.data
@@ -220,7 +220,7 @@ export class AuthService {
*/
async loginWithApple(code: string): Promise<SignInSuccessResp> {
try {
const resp = await getClient().post<SignInSuccessResp>("user/loginWithGoogle", <LoginWithApple>{
const resp = await getClient(false).post<SignInSuccessResp>("user/loginWithGoogle", <LoginWithApple>{
code: code,
isApple: false,
});
@@ -241,7 +241,7 @@ export class AuthService {
*/
async register(username: string, password: string, displayName: string|null): Promise<SignInSuccessResp> {
try {
const resp = await getClient().post<SignInSuccessResp>("v2/user/register", <RegisterReq>{
const resp = await getClient(false).post<SignInSuccessResp>("v2/user/register", <RegisterReq>{
username: username,
displayName: displayName,
password: password,
@@ -263,7 +263,7 @@ export class AuthService {
*/
async resetPassword(unameMailPhone: string): Promise<void|number> {
try {
const resp = await getClient().post<OtpPleCodeSendTestingResp>("user/resetPassword", <ResetPasswordReq>{
const resp = await getClient(false).post<OtpPleCodeSendTestingResp>("user/resetPassword", <ResetPasswordReq>{
unameMailPhone: unameMailPhone,
});
if (resp.data.code != null) {
@@ -287,7 +287,7 @@ export class AuthService {
*/
async verifyPasswordReset(unameMailPhone: string, code: number, newPassword: string): Promise<void> {
try {
await getClient().post<GenericSuccessBody>("user/verifyResetCode", <VerifyPasswordResetReq>{
await getClient(false).post<GenericSuccessBody>("user/verifyResetCode", <VerifyPasswordResetReq>{
unameMailPhone: unameMailPhone,
vCode: code,
newPassword: newPassword,

View File

@@ -6,7 +6,7 @@ import {getClient} from "../core/http";
import {environment, SDKConfig} from "../core/environment";
describe("NetworkService", () => {
const service = new NetworkService("", "", "", new DatabaseMock(), getClient())
const service = new NetworkService("", "", "", new DatabaseMock(), getClient(false))
it('should get invites', async () => {
const invites = await service.getInvites();

View File

@@ -30,7 +30,7 @@ export class NetworkService {
this.userid = userid;
this.networkId = networkId;
this.database = database;
this.client = (httpClientOverwrite ?? getClient()).create({
this.client = (httpClientOverwrite ?? getClient(false)).create({
headers: {
"Authorization": token
}

View File

@@ -0,0 +1,240 @@
import {DatabaseAPI} from "../storage/database";
import {AxiosInstance, isAxiosError} from "axios";
import {getClient} from "../core/http";
import {NetworkInvite} from "../domain/networkService.schema";
import {GenericErrorBody} from "../domain/http.schema";
import {
Album, ChangePictureVisibilityReq,
CreateAlbumReq,
DeleteImageReq,
DiscoveryResp, EditPictureTitleReq,
FinalizeUploadReq,
GetResp, PostCommentReq, ToggleFollowReq, TogglePictureLikeReq, UploadImageReq
} from "../domain/pictureService.schema";
import {environment} from "../core/environment";
export class PictureService {
userid: string;
uploaderId: string;
database: DatabaseAPI;
client: AxiosInstance
cdnClient: AxiosInstance
constructor(token: string, uploaderId: string, userid: string, database: DatabaseAPI, httpClientOverwrite: AxiosInstance | null, cdnClientOverwrite: AxiosInstance | null) {
this.userid = userid;
this.uploaderId = uploaderId;
this.database = database;
this.client = (httpClientOverwrite ?? getClient(false)).create({
headers: {
"Authorization": token
}
})
this.cdnClient = (cdnClientOverwrite ?? getClient(true)).create({
headers: {
"Authorization": token
}
})
}
async get(): Promise<GetResp> {
try {
const resp = await this.client.get<GetResp>(`picture/pictures?userid=${this.userid}&target=${this.uploaderId}`);
return resp.data
} catch (e) {
console.log(e)
if (isAxiosError<GenericErrorBody>(e)) {
throw e;
}
throw new Error("Unexpected error")
}
}
async discovery(): Promise<DiscoveryResp> {
try {
const resp = await this.client.get<DiscoveryResp>("picture/discovery");
return resp.data
} catch (e) {
console.log(e)
if (isAxiosError<GenericErrorBody>(e)) {
throw e;
}
throw new Error("Unexpected error")
}
}
async createAlbum(name: string): Promise<Album> {
try {
const resp = await this.client.post<Album>("picture/createAlbum", <CreateAlbumReq>{
userid: this.userid,
name: name
});
return resp.data
} catch (e) {
console.log(e)
if (isAxiosError<GenericErrorBody>(e)) {
throw e;
}
throw new Error("Unexpected error")
}
}
async finalizeUpload(uploadId: string): Promise<void> {
try {
await this.client.post("picture/finalizeUpload", <FinalizeUploadReq>{
userid: this.userid,
uploadId: uploadId,
});
return
} catch (e) {
console.log(e)
if (isAxiosError<GenericErrorBody>(e)) {
throw e;
}
throw new Error("Unexpected error")
}
}
async deletePicture(imageId: string): Promise<void> {
try {
await this.client.post("picture/delete", <DeleteImageReq>{
userid: this.userid,
imageId: imageId
});
return
} catch (e) {
console.log(e)
if (isAxiosError<GenericErrorBody>(e)) {
throw e;
}
throw new Error("Unexpected error")
}
}
async changeVisibility(imageId: string, newVisibility: string): Promise<void> {
try {
await this.client.post("picture/changeVisibility", <ChangePictureVisibilityReq>{
userid: this.userid,
visibility: newVisibility
});
return
} catch (e) {
console.log(e)
if (isAxiosError<GenericErrorBody>(e)) {
throw e;
}
throw new Error("Unexpected error")
}
}
async editTitle(imageId: string, newTitle: string): Promise<void> {
try {
await this.client.post("picture/editTitle", <EditPictureTitleReq>{
userid: this.userid,
title: newTitle
});
return
} catch (e) {
console.log(e)
if (isAxiosError<GenericErrorBody>(e)) {
throw e;
}
throw new Error("Unexpected error")
}
}
async toggleLike(imageId: string): Promise<void> {
try {
await this.client.post("picture/toggleLike", <TogglePictureLikeReq>{
userid: this.userid,
imageId: imageId
});
return
} catch (e) {
console.log(e)
if (isAxiosError<GenericErrorBody>(e)) {
throw e;
}
throw new Error("Unexpected error")
}
}
async postComment(imageId: string, comment: string): Promise<void> {
try {
await this.client.post("picture/comment", <PostCommentReq>{
userid: this.userid,
imageId: imageId,
comment: comment
});
return
} catch (e) {
console.log(e)
if (isAxiosError<GenericErrorBody>(e)) {
throw e;
}
throw new Error("Unexpected error")
}
}
async toggleFollow(): Promise<void> {
try {
await this.client.post("picture/toggleFollow", <ToggleFollowReq>{
userid: this.userid,
uploaderId: this.uploaderId,
});
return
} catch (e) {
console.log(e)
if (isAxiosError<GenericErrorBody>(e)) {
throw e;
}
throw new Error("Unexpected error")
}
}
async getAlbums(): Promise<Album[]> {
try {
const resp = await this.client.get(`picture/getAlbums?userid=${this.userid}`);
return resp.data
} catch (e) {
console.log(e)
if (isAxiosError<GenericErrorBody>(e)) {
throw e;
}
throw new Error("Unexpected error")
}
}
async getComments(imageId: string): Promise<Album[]> {
try {
const resp = await this.client.get(`picture/comment?userid=${this.userid}&imageId=${imageId}`);
return resp.data
} catch (e) {
console.log(e)
if (isAxiosError<GenericErrorBody>(e)) {
throw e;
}
throw new Error("Unexpected error")
}
}
async uploadPicture(picture: string, title: string, visibility: string, album: string, uploadId: string, name: string): Promise<void> {
try {
await this.cdnClient.post("picture/upload", <UploadImageReq>{
album: album,
uploadId: uploadId,
title: title,
picture: picture,
name: name,
visibility: visibility,
userid: this.userid,
});
return
} catch (e) {
console.log(e)
if (isAxiosError<GenericErrorBody>(e)) {
throw e;
}
throw new Error("Unexpected error")
}
}
}