220 lines
5.0 KiB
Go
220 lines
5.0 KiB
Go
// exportable typescript generated from golang
|
|
// Copyright (C) 2022 Fabio Prada
|
|
|
|
package tsrpc
|
|
|
|
const TsApiTemplate = `
|
|
//
|
|
// Typescript API generated from gofiber backend
|
|
// Copyright (C) 2022 - 2025 Fabio Prada
|
|
//
|
|
// This file was generated by github.com/millevolte/ts-rpc
|
|
//
|
|
// {{.CreatedOn.Format "Jan 02, 2006 15:04:05 UTC" }}
|
|
//
|
|
|
|
export interface ApiRestResponse {
|
|
data?: unknown;
|
|
error: string | null;
|
|
}
|
|
|
|
function isApiRestResponse(data: unknown): data is ApiRestResponse {
|
|
return (
|
|
typeof data === 'object' &&
|
|
data !== null &&
|
|
Object.prototype.hasOwnProperty.call(data, 'data') &&
|
|
Object.prototype.hasOwnProperty.call(data, 'error')
|
|
);
|
|
}
|
|
|
|
function normalizeError(error: unknown): Error {
|
|
if (error instanceof DOMException && error.name === 'AbortError') {
|
|
return new Error('api.error.timeouterror');
|
|
}
|
|
|
|
if (error instanceof TypeError && error.message === 'Failed to fetch') {
|
|
return new Error('api.error.connectionerror');
|
|
}
|
|
|
|
if (error instanceof Error) {
|
|
return error;
|
|
}
|
|
|
|
return new Error(String(error));
|
|
}
|
|
|
|
export default class Api {
|
|
apiUrl: string;
|
|
localStorage: Storage | null;
|
|
|
|
constructor(apiurl: string) {
|
|
this.apiUrl = apiurl;
|
|
this.localStorage = window.localStorage;
|
|
}
|
|
|
|
async request(
|
|
method: string,
|
|
url: string,
|
|
data: unknown,
|
|
timeout = 7000,
|
|
upload = false,
|
|
): Promise<ApiRestResponse> {
|
|
const headers: { [key: string]: string } = {
|
|
'Cache-Control': 'no-cache',
|
|
};
|
|
|
|
if (!upload) {
|
|
headers['Content-Type'] = 'application/json';
|
|
}
|
|
|
|
if (this.localStorage) {
|
|
const auth = this.localStorage.getItem('Auth-Token');
|
|
if (auth) {
|
|
headers['Auth-Token'] = auth;
|
|
}
|
|
}
|
|
|
|
const controller = new AbortController();
|
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
const requestOptions: RequestInit = {
|
|
method,
|
|
cache: 'no-store',
|
|
mode: 'cors',
|
|
credentials: 'include',
|
|
headers,
|
|
signal: controller.signal,
|
|
};
|
|
|
|
if (upload) {
|
|
requestOptions.body = data as FormData;
|
|
} else if (data !== null && data !== undefined) {
|
|
requestOptions.body = JSON.stringify(data);
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(url, requestOptions);
|
|
|
|
if (!response.ok) {
|
|
throw new Error('api.error.' + response.statusText);
|
|
}
|
|
|
|
if (this.localStorage) {
|
|
const jwt = response.headers.get('Auth-Token');
|
|
if (jwt) {
|
|
this.localStorage.setItem('Auth-Token', jwt);
|
|
}
|
|
}
|
|
|
|
const responseData = (await response.json()) as unknown;
|
|
if (!isApiRestResponse(responseData)) {
|
|
throw new Error('api.error.wrongdatatype');
|
|
}
|
|
|
|
if (responseData.error) {
|
|
throw new Error(responseData.error);
|
|
}
|
|
|
|
return responseData;
|
|
} catch (error: unknown) {
|
|
throw normalizeError(error);
|
|
} finally {
|
|
clearTimeout(timeoutId);
|
|
}
|
|
}
|
|
|
|
processResult(result: ApiRestResponse): { data: unknown; error: string | null } {
|
|
if (typeof result.data !== 'object') {
|
|
return { data: result.data, error: null };
|
|
}
|
|
|
|
if (!result.data) {
|
|
result.data = {};
|
|
}
|
|
|
|
return { data: result.data, error: null };
|
|
}
|
|
|
|
processError(error: unknown): {
|
|
data: unknown;
|
|
error: string | null;
|
|
} {
|
|
const normalizedError = normalizeError(error);
|
|
|
|
if (normalizedError.message === 'api.error.timeouterror') {
|
|
Object.defineProperty(normalizedError, '__api_error__', {
|
|
value: normalizedError.message,
|
|
writable: false,
|
|
});
|
|
|
|
return { data: null, error: normalizedError.message };
|
|
}
|
|
|
|
if (normalizedError.message === 'api.error.connectionerror') {
|
|
Object.defineProperty(normalizedError, '__api_error__', {
|
|
value: normalizedError.message,
|
|
writable: false,
|
|
});
|
|
|
|
return { data: null, error: normalizedError.message };
|
|
}
|
|
|
|
return {
|
|
data: null,
|
|
error: normalizedError.message,
|
|
};
|
|
}
|
|
|
|
async POST(
|
|
url: string,
|
|
data: unknown,
|
|
timeout?: number,
|
|
): Promise<{
|
|
data: unknown;
|
|
error: string | null;
|
|
}> {
|
|
try {
|
|
const upload = url.includes('/upload/');
|
|
const result = await this.request('POST', this.apiUrl + url, data, timeout, upload);
|
|
|
|
return this.processResult(result);
|
|
} catch (error: unknown) {
|
|
return this.processError(error);
|
|
}
|
|
}
|
|
|
|
async GET(
|
|
url: string,
|
|
timeout?: number,
|
|
): Promise<{
|
|
data: unknown;
|
|
error: string | null;
|
|
}> {
|
|
try {
|
|
const result = await this.request('GET', this.apiUrl + url, null, timeout);
|
|
return this.processResult(result);
|
|
} catch (error: unknown) {
|
|
return this.processError(error);
|
|
}
|
|
}
|
|
|
|
async UPLOAD(
|
|
url: string,
|
|
data: unknown,
|
|
timeout?: number,
|
|
): Promise<{
|
|
data: unknown;
|
|
error: string | null;
|
|
}> {
|
|
try {
|
|
const result = await this.request('POST', this.apiUrl + url, data, timeout, true);
|
|
|
|
return this.processResult(result);
|
|
} catch (error: unknown) {
|
|
return this.processError(error);
|
|
}
|
|
}
|
|
}
|
|
|
|
const api = new Api('{{ .APIURL }}');
|
|
`
|