Skip to content

Instantly share code, notes, and snippets.

@progapandist
Created March 20, 2021 11:49
Show Gist options
  • Save progapandist/55a58d6d8f9c7b024c3ab73150b777f0 to your computer and use it in GitHub Desktop.
Save progapandist/55a58d6d8f9c7b024c3ab73150b777f0 to your computer and use it in GitHub Desktop.
import sf from "@util/simple_fetch";
type Indexed = {
[key in string]: unknown;
};
export interface PasswordData extends Indexed {
oldPassword?: string;
newPassword?: string;
}
export interface UserData extends Indexed {
first_name?: string;
second_name?: string;
login?: string;
email?: string;
password?: string;
phone?: string | number;
id?: number;
avatar?: string;
display_name?: string;
error?: object;
status?: unknown;
}
type PackedResponse = [boolean, string | null];
export class YandexUser {
packedResult: PackedResponse;
getResult: UserData | {};
BASE_URL = "https://ya-praktikum.tech/api/v2/user";
DEFAULT_HEADERS = {
"Content-Type": "application/json",
Accept: "application/json",
};
constructor() {
this.packedResult = [false, null];
this.getResult = {};
}
static request(): YandexUser {
return new this();
}
public async searchByLogin(data: UserData): Promise<PackedResponse> {
await sf
.post(`${this.BASE_URL}/search`, {
headers: this.DEFAULT_HEADERS,
data: JSON.stringify(data),
})
.then((res) => {
this.packedResult = [true, JSON.parse(res as string)];
})
.catch((error) => {
this.handleError(error, "reason");
});
return this.packedResult;
}
public async avatar(data: FormData): Promise<PackedResponse> {
await sf
.put(`${this.BASE_URL}/profile/avatar`, {
data,
headers: {
Accept: "image/*",
},
})
.then((res) => {
this.packedResult = [true, res as string];
})
.catch((error) => {
this.handleError(error, "reason");
});
return this.packedResult;
}
public async password(data: PasswordData): Promise<PackedResponse> {
await sf
.put(`${this.BASE_URL}/password`, {
headers: this.DEFAULT_HEADERS,
data: JSON.stringify(data),
})
.then((res) => {
this.packedResult = [true, res as string];
})
.catch((error) => {
this.handleError(error, "reason");
});
return this.packedResult;
}
public async profile(data: UserData): Promise<PackedResponse> {
await sf
.put(`${this.BASE_URL}/profile`, {
headers: this.DEFAULT_HEADERS,
data: JSON.stringify(data),
})
.then((res) => {
this.packedResult = [true, res as string];
})
.catch((error) => {
this.handleError(error, "reason");
});
return this.packedResult;
}
private handleError(error: string, error_field: string): void {
let serverErrorMessage: string;
try {
serverErrorMessage = JSON.parse(error)[error_field].toString();
} catch {
serverErrorMessage = error;
}
console.error(serverErrorMessage);
this.packedResult = [false, serverErrorMessage];
}
}
export class YandexAuth {
postResult: PackedResponse;
getResult: UserData | {};
BASE_URL = "https://ya-praktikum.tech/api/v2/auth";
DEFAULT_HEADERS = {
"Content-Type": "application/json",
Accept: "application/json",
};
static request(): YandexAuth {
return new this();
}
constructor() {
this.postResult = [false, null];
this.getResult = {};
}
public async signin(data: UserData): Promise<PackedResponse> {
await sf
.post(`${this.BASE_URL}/signin`, {
headers: this.DEFAULT_HEADERS,
data: JSON.stringify(data),
})
.then((response) => {
this.postResult = [true, response as string];
})
.catch((error) => this.handleError(error));
return this.postResult;
}
public async logout(): Promise<PackedResponse> {
await sf
.post(`${this.BASE_URL}/logout`, {
headers: this.DEFAULT_HEADERS,
})
.then((response) => {
this.postResult = [true, response as string];
})
.catch((error) => {
this.handleError(error);
});
return this.postResult;
}
public async user(): Promise<UserData> {
await sf
.get(`${this.BASE_URL}/user`)
.then((response) => {
this.getResult = JSON.parse(response as string) as UserData;
})
.catch((error) => {
console.error(error);
this.getResult = { error: JSON.parse(error) };
});
return this.getResult;
}
public async signup(data: UserData): Promise<PackedResponse> {
await sf
.post(`${this.BASE_URL}/signup`, {
headers: this.DEFAULT_HEADERS,
data: JSON.stringify(data),
})
.then((response) => {
this.postResult = [true, response as string];
})
.catch((error) => {
this.handleError(error);
});
return this.postResult;
}
private handleError(error: string): void {
let serverErrorMessage: string;
try {
serverErrorMessage = JSON.parse(error).reason.toString();
} catch {
serverErrorMessage = error;
}
console.error(serverErrorMessage);
this.postResult = [false, serverErrorMessage];
}
}
enum METHODS {
GET = "GET",
PUT = "PUT",
POST = "POST",
DELETE = "DELETE",
}
type bodyData =
| string
| Document
| Blob
| ArrayBufferView
| ArrayBuffer
| FormData
| URLSearchParams
| ReadableStream<Uint8Array>
| null
| undefined;
interface fetchOptions {
headers?: object;
data?: bodyData;
timeout?: number;
method?: METHODS;
}
function queryStringify(data: bodyData) {
let str = Object.entries(data as object).reduce((acc, val) => {
return acc + `${val[0].toString()}=${val[1].toString()}&`;
}, "?");
return str.substring(0, str.length - 1);
}
export default class SimpleFetch {
static get = (url: string, options: fetchOptions = {}) => {
return SimpleFetch.request(url, { ...options, method: METHODS.GET }, options.timeout);
};
static post = (url: string, options: fetchOptions = {}) => {
return SimpleFetch.request(url, { ...options, method: METHODS.POST }, options.timeout);
};
static put = (url: string, options: fetchOptions = {}) => {
return SimpleFetch.request(url, { ...options, method: METHODS.PUT }, options.timeout);
};
static delete = (url: string, options: fetchOptions = {}) => {
return SimpleFetch.request(url, { ...options, method: METHODS.DELETE }, options.timeout);
};
private static request = (url: string, options: fetchOptions, timeout = 5000) => {
const { method, data, headers } = options;
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.timeout = timeout;
if (method === METHODS.GET) {
xhr.open(method, `${url}${data ? queryStringify(data) : ""}`);
} else {
xhr.open(method!, url);
}
if (headers) {
Object.entries(headers).forEach((arr) => {
xhr.setRequestHeader(arr[0], arr[1]);
});
}
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response);
} else {
reject(xhr.response);
}
};
xhr.onabort = reject;
xhr.onerror = reject;
xhr.ontimeout = reject;
if (method === METHODS.GET || !data) {
xhr.send();
} else {
data ? xhr.send(data) : xhr.send();
}
});
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment