import { constants } from '../enum/constants'; import { EnvironmentType } from '../enum/environment.type'; import { IEncryptionDriver } from '../interfaces/encryption-driver.interface'; import { IRequestDriver } from '../interfaces/request-driver.interface'; const { urls } = constants; export interface IFgBaseAPIConstructorParams { requestDriver: IRequestDriver; encryptionDriver: IEncryptionDriver; baseUrl: string | null; opts: any; credentialObject: any | null; } export class FgBaseAPI { isProduction!: boolean; environment!: EnvironmentType; credential: any | null; credentialToken: string | null; credentialOnLogin: Function | null; private _encryptionDriver!: IEncryptionDriver; private _requestDriver!: IRequestDriver; private _opts: any; private _baseUrl!: string; constructor({ requestDriver, encryptionDriver, baseUrl = null, opts = {}, credentialObject = null }: IFgBaseAPIConstructorParams) { if (!requestDriver) { throw new Error('RequestDriver is required'); } if (!encryptionDriver) { throw new Error('EncryptionDriver is required'); } this._requestDriver = requestDriver; this._encryptionDriver = encryptionDriver; this._opts = opts; this.baseUrl = baseUrl || urls[opts.environment]; this.isProduction = opts.isProduction; this.environment = opts.environment; if (credentialObject) { this.credential = credentialObject.credential || null; this.credentialToken = credentialObject.token || null; this.credentialOnLogin = credentialObject.onLogin || opts.onLogin; // if (!this.credentialOnLogin) { // throw new Error("OnLogin is required"); // } } else { this.credential = null; this.credentialToken = null; this.credentialOnLogin = null; } this._afterLoad(); } protected get requestDriver(): IRequestDriver { return this._requestDriver; } protected get encryptionDriver(): IEncryptionDriver { return this._encryptionDriver; } get token(): string | null { // TODO Ver por qué no se está usando esto. return null; } get baseUrl(): string { return this._baseUrl; } set baseUrl(url: string) { this._baseUrl = url; if (!url.endsWith('/')) { this._baseUrl += '/'; } } protected async _get(url: string, _query?: any) { let finalUrl = url; if (_query) { const queryStr = Object.keys(_query).map(k => `${k}=${_query[k]}`).join('&'); finalUrl += `?${queryStr}`; } const response = await this._requestDriver.send('GET', this.baseUrl, finalUrl, null, (this.token !== null), this._createHeaders()); const body = await this._processResult(response); return body; } protected async _getString(url: string, _query?: any) { let finalUrl = url; if (_query) { const queryStr = Object.keys(_query).map(k => `${k}=${_query[k]}`).join('&'); finalUrl += `?${queryStr}`; } const response = await this._requestDriver.send('GET', this.baseUrl, finalUrl, null, (this.token !== null), this._createHeaders()); const body = await this._processResult(response, 'text'); return body; } protected async _getBlob(url: string, _query?: any) { let finalUrl = url; if (_query) { const queryStr = Object.keys(_query).map(k => `${k}=${_query[k]}`).join('&'); finalUrl += `?${queryStr}`; } const response = await this._requestDriver.send('GET', this.baseUrl, finalUrl, null, (this.token !== null), this._createHeaders(), 'blob'); const body = await this._processResult(response, 'blob'); return body; } protected async _delete(url: string, _data?: any, extraHeaders?: Record | null) { const response = await this._requestDriver.send('DELETE', this.baseUrl, url, _data, (this.token !== null), this._createHeaders(extraHeaders)); const body = await this._processResult(response); return body; } protected async _patch(url, data, extraHeaders?: Record | null) { const response = await this._requestDriver.send('PATCH', this.baseUrl, url, data, (this.token !== null), this._createHeaders(extraHeaders)); const body = await this._processResult(response); return body; } protected async _post(url: string, data: any, extraHeaders?: Record | null) { const response = await this._requestDriver.send('POST', this.baseUrl, url, data, (this.token !== null), this._createHeaders(extraHeaders)); const body = await this._processResult(response); return body; } protected async _upload(baseUrl: string, url: string, data: any, projectId: string, content: string | Blob, fileName: string, extraHeaders?: Record | null): Promise { await this._requestDriver.upload('POST', baseUrl, url, data, projectId, content, fileName, this._createHeaders(extraHeaders)); } private async _processResult(response, responseType = 'json') { const headers = this._requestDriver.getHeaders(response) || {}; if (responseType === 'text') { return await this._requestDriver.getContentAsText(response); } if (responseType === 'blob') { return await this._requestDriver.getContentAsBlob(response); } const body = await this._requestDriver.getBody(response); if (body && typeof body === 'object' && body.extraHeaders) { Object.assign(headers, body.extraHeaders); } if (headers['Api-New-Token'] && this.credentialOnLogin) { await this.credentialOnLogin(headers['Api-New-Token']); } return body; } protected _afterLoad() { // Virtual } protected _createHeaders(extraHeaders?: Record | null): Record { const headers: Record = extraHeaders || {}; if (this.token) { headers.Authorization = `Bearer ${this.token}`; } else if (this.credentialToken) { headers['Api-Token'] = this.credentialToken; } else if (this.credential) { headers['Api-Authorization'] = this.credential; } if (this.environment === 'rapidapi') { headers['X-RapidAPI-Key'] = this._opts.keys.rapidapi; let baseUrl = this.baseUrl.replace('https://', ''); if (baseUrl.includes('/')) { baseUrl = baseUrl.substring(0, baseUrl.indexOf('/')); } headers['X-RapidAPI-Host'] = baseUrl; } return headers; } }