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 { 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 { 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 { 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 { 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 { 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 { 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(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 { 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; } }