/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { Injectable } from '@nestjs/common' import { Firebender } from '../../../services' import { HttpService } from '../../../services/http' import { RemoteConfigRequest, RemoteConfigTemplate } from './types' import { RemoteConfigModel } from './models' export type RemoteConfigParameters = { name: string value: string } export const REMOTE_CONFIG_URL = 'https://firebaseremoteconfig.googleapis.com/v1/projects' @Injectable() export class RemoteConfig { constructor(private readonly firebender: Firebender, private readonly httpService: HttpService) {} async setCurrentVersion(version: string): Promise { return this.setParameters([{ name: 'current_version', value: version }]) } async setParameters(parameters: Array = []): Promise { const { etag, ...template } = await this.getTemplate() parameters.forEach((parameter: RemoteConfigParameters) => { template.parameters = this.setValueOnTemplate(template.parameters, parameter.name, parameter.value) }) return this.publishTemplate(template, etag) } async publishTemplate(template: any, etag: string): Promise { return this.httpService.put(this.url, template, { headers: { Authorization: await this.authorization(), 'Content-Type': 'application/json; UTF-8', 'If-Match': etag, 'Accept-Encoding': 'gzip', }, }) } async getTemplate(): Promise { const { headers, ...response } = await this.httpService.fetch({ url: this.url, headers: { Authorization: await this.authorization(), 'Accept-Encoding': 'gzip', }, method: 'GET', returnHeaders: true, }) const etag = headers.etag if (!response.parameters) throw new Error('Remote config parameters not fetched.') response.parameters = Object.keys(response.parameters).reduce((previous: any, current: string) => { previous[current] = new RemoteConfigModel(response.parameters[current]) return previous }, {}) return { ...response, etag } } private setValueOnTemplate = (template: RemoteConfigTemplate, name: string, value: any): RemoteConfigTemplate => { if (template[name]) template[name].setValue(value) return template } private async authorization(): Promise { return `Bearer ${await this.accessToken()}` } private async accessToken(): Promise { const response = await this.firebender.firebaseAdmin.options.credential.getAccessToken() return response.access_token } private get url(): string { return `${REMOTE_CONFIG_URL}/${ this.firebender.firebaseAdmin.instanceId().app.options.credential['projectId'] }/remoteConfig` } }