You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
frontend/src/app/service/db-api.service.ts

140 lines
4.6 KiB

import {Injectable} from '@angular/core';
import {ApiService} from './api.service';
import {Observable} from 'rxjs';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import ApiResponse from '../structures/ApiResponse';
import {environment} from '../../environments/environment';
import {debug} from '../utility';
import * as Structures from '../structures/db-api';
@Injectable({
providedIn: 'root',
})
export class DbApiService {
protected token?: string;
protected tokenTime?: number;
protected databaseBase: string = environment.databaseBase;
constructor(
protected readonly api: ApiService,
protected readonly http: HttpClient,
) {
Structures._setDbApi(this);
}
public async getDatabase(databaseId: string): Promise<Structures.Database> {
return new Promise(async (res, rej) => {
this._authRequest(`/${databaseId}`).subscribe({
next: async response => {
if ( response.status !== 200 ) {
debug('Invalid get database response.', response);
return rej(new Error('Invalid database ID.'));
}
return res(new Structures.Database(response.data));
},
error: rej,
});
});
}
public async getDatabases(): Promise<Structures.Database[]> {
return new Promise(async (res, rej) => {
this._authRequest('/').subscribe({
next: async response => {
return res(response.data.map(x => new Structures.Database(x)));
},
error: rej,
});
});
}
public async getColumns(databaseId: string): Promise<Structures.DatabaseColumn[]> {
return new Promise(async (res, rej) => {
this._authRequest(`${databaseId}/columns`).subscribe({
next: async response => {
return res(response.data.map(x => new Structures.DatabaseColumn(x)));
},
error: rej,
});
});
}
public async getColumnOrder(databaseId: string): Promise<string[]> {
return new Promise(async (res, rej) => {
this._authRequest(`${databaseId}/columns/order`).subscribe({
next: async response => {
return res(response.data);
},
error: rej,
});
});
}
public async getData(databaseId: string): Promise<Structures.DatabaseRecord[]> {
return new Promise(async (res, rej) => {
this._authRequest(`${databaseId}/data`).subscribe({
next: async response => {
return res(response.data.map(x => new Structures.DatabaseRecord(x)));
},
error: rej,
});
});
}
public async getDataRecord(databaseId: string, recordId: string): Promise<Structures.DatabaseRecord> {
return new Promise(async (res, rej) => {
this._authRequest(`${databaseId}/record/${recordId}`).subscribe({
next: async response => {
return res(new Structures.DatabaseRecord(response.data));
},
error: rej,
});
});
}
protected _authRequest(endpoint, params = {}, method: 'get' | 'post' = 'get') {
return new Observable<ApiResponse>(sub => {
this.getToken().then(token => {
const headers = new HttpHeaders({
authorization: `bearer ${token}`
});
debug('Auth request headers', headers);
if ( method === 'get' ) {
const data = {
params,
headers,
};
this.http.get(this.api._build_url(endpoint, this.databaseBase), data).subscribe({
next: (response: any) => {
return sub.next(new ApiResponse(response));
},
error: e => {
return sub.error(e);
},
});
}
});
});
}
public async getToken(): Promise<string> {
const now = (new Date()).getTime();
// 1 hour
if ( this.token && this.tokenTime && (now - this.tokenTime) < (60 * 60 * 1000) ) {
return this.token;
}
this.token = await this.api.getToken();
this.tokenTime = now;
return this.token;
}
}