Skip to content

Commit

Permalink
update a few stragglers to apiv2 (#4570)
Browse files Browse the repository at this point in the history
* update a few stragglers to apiv2

* update app distribution api to apiv2

* fix some query params

* fix remote config tests
  • Loading branch information
bkendall committed May 23, 2022
1 parent f59ae25 commit c3ecb83
Show file tree
Hide file tree
Showing 8 changed files with 95 additions and 145 deletions.
47 changes: 19 additions & 28 deletions src/appdistribution/client.ts
@@ -1,10 +1,12 @@
import * as _ from "lodash";
import * as api from "../api";
import { ReadStream } from "fs";

import * as utils from "../utils";
import * as operationPoller from "../operation-poller";
import { Distribution } from "./distribution";
import { FirebaseError } from "../error";
import { Client, ClientResponse } from "../apiv2";
import { Client } from "../apiv2";
import { appDistributionOrigin } from "../api";

/**
* Helper interface for an app that is provisioned with App Distribution
Expand Down Expand Up @@ -65,39 +67,35 @@ export interface BatchRemoveTestersResponse {
*/
export class AppDistributionClient {
appDistroV2Client = new Client({
urlPrefix: api.appDistributionOrigin,
urlPrefix: appDistributionOrigin,
apiVersion: "v1",
});

async getAabInfo(appName: string): Promise<AabInfo> {
const apiResponse = await api.request("GET", `/v1/${appName}/aabInfo`, {
origin: api.appDistributionOrigin,
auth: true,
});

return _.get(apiResponse, "body");
const apiResponse = await this.appDistroV2Client.get<AabInfo>(`/${appName}/aabInfo`);
return apiResponse.body;
}

async uploadRelease(appName: string, distribution: Distribution): Promise<string> {
const apiResponse = await api.request("POST", `/upload/v1/${appName}/releases:upload`, {
auth: true,
origin: api.appDistributionOrigin,
const client = new Client({ urlPrefix: appDistributionOrigin });
const apiResponse = await client.request<ReadStream, { name: string }>({
method: "POST",
path: `/upload/v1/${appName}/releases:upload`,
headers: {
"X-Goog-Upload-File-Name": distribution.getFileName(),
"X-Goog-Upload-Protocol": "raw",
"Content-Type": "application/octet-stream",
},
data: distribution.readStream(),
json: false,
responseType: "json",
body: distribution.readStream(),
});

return _.get(JSON.parse(apiResponse.body), "name");
return apiResponse.body.name;
}

async pollUploadStatus(operationName: string): Promise<UploadReleaseResponse> {
return operationPoller.pollOperation<UploadReleaseResponse>({
pollerName: "App Distribution Upload Poller",
apiOrigin: api.appDistributionOrigin,
apiOrigin: appDistributionOrigin,
apiVersion: "v1",
operationResourceName: operationName,
masterTimeout: 5 * 60 * 1000,
Expand All @@ -120,15 +118,12 @@ export class AppDistributionClient {
text: releaseNotes,
},
};
const queryParams = { updateMask: "release_notes.text" };

try {
await api.request("PATCH", `/v1/${releaseName}?updateMask=release_notes.text`, {
origin: api.appDistributionOrigin,
auth: true,
data,
});
await this.appDistroV2Client.patch(`/${releaseName}`, data, { queryParams });
} catch (err: any) {
throw new FirebaseError(`failed to update release notes with ${err?.message}`, { exit: 1 });
throw new FirebaseError(`failed to update release notes with ${err?.message}`);
}

utils.logSuccess("added release notes successfully");
Expand All @@ -152,11 +147,7 @@ export class AppDistributionClient {
};

try {
await api.request("POST", `/v1/${releaseName}:distribute`, {
origin: api.appDistributionOrigin,
auth: true,
data,
});
await this.appDistroV2Client.post(`/${releaseName}:distribute`, data);
} catch (err: any) {
let errorMessage = err.message;
if (_.has(err, "context.body.error")) {
Expand Down
40 changes: 22 additions & 18 deletions src/deploy/remoteconfig/functions.ts
@@ -1,34 +1,38 @@
import { remoteConfigApiOrigin } from "../../api";
import { Client } from "../../apiv2";
import { FirebaseError } from "../../error";
import { RemoteConfigTemplate } from "../../remoteconfig/interfaces";

import api = require("../../api");

const TIMEOUT = 30000;

const client = new Client({ urlPrefix: remoteConfigApiOrigin, apiVersion: "v1" });

/**
* Gets Etag for Remote Config Project Template
* @param projectNumber Input is the Firebase Project's project number
* @param versionNumber Firebase Remote Config Template version number
* @return {Promise<string>} Returns a Promise of the Remote Config Template Etag string
*/
export async function getEtag(projectNumber: string, versionNumber?: string): Promise<string> {
let reqPath = `/v1/projects/${projectNumber}/remoteConfig`;
const reqPath = `/projects/${projectNumber}/remoteConfig`;
const queryParams: { versionNumber?: string } = {};
if (versionNumber) {
reqPath = reqPath + "?versionNumber=" + versionNumber;
queryParams.versionNumber = versionNumber;
}
const response = await api.request("GET", reqPath, {
auth: true,
origin: api.remoteConfigApiOrigin,
timeout: TIMEOUT,
const response = await client.request<void, void>({
method: "GET",
path: reqPath,
queryParams,
headers: { "Accept-Encoding": "gzip" },
timeout: TIMEOUT,
});
return response.response.headers.etag;
return response.response.headers.get("etag") || "";
}

/**
* Validates Remote Config Template before deploying project template
* @param template The Remote Config template to be deployed
* @return {Promise<RemoteConfigTemplate>} Returns a Promise of the valid Remote Config template
* @return Returns a Promise of the valid Remote Config template
*/
export function validateInputRemoteConfigTemplate(
template: RemoteConfigTemplate
Expand All @@ -54,28 +58,28 @@ export function validateInputRemoteConfigTemplate(
* @param etag Remote Config Template's etag value
* @param options Optional object when publishing a Remote Config template. If the
* force {boolean} is `true` the Remote Config template is forced to update and circumvent the Etag
* @return {Promise<RemoteConfigTemplate>} Returns a Promise of a Remote Config template
* @return Returns a Promise of a Remote Config template
*/
export async function deployTemplate(
projectNumber: string,
template: RemoteConfigTemplate,
etag: string,
options?: { force: boolean }
): Promise<RemoteConfigTemplate> {
const reqPath = `/v1/projects/${projectNumber}/remoteConfig`;
const reqPath = `/projects/${projectNumber}/remoteConfig`;
if (options?.force) {
etag = "*";
}
const response = await api.request("PUT", reqPath, {
auth: true,
origin: api.remoteConfigApiOrigin,
timeout: TIMEOUT,
const response = await client.request<any, RemoteConfigTemplate>({
method: "PUT",
path: reqPath,
headers: { "If-Match": etag },
data: {
body: {
conditions: template.conditions,
parameters: template.parameters,
parameterGroups: template.parameterGroups,
},
timeout: TIMEOUT,
});
return response.body;
}
Expand All @@ -86,7 +90,7 @@ export async function deployTemplate(
* @param template The Remote Config template to be published
* @param etag Remote Config Template's etag value
* @param options Force boolean option
* @return {Promise<RemoteConfigTemplate>} Returns a Promise that fulfills with the published Remote Config template
* @return Returns a Promise that fulfills with the published Remote Config template
*/
export function publishTemplate(
projectNumber: string,
Expand Down
10 changes: 4 additions & 6 deletions src/firestore/checkDatabaseType.ts
@@ -1,4 +1,5 @@
import * as api from "../api";
import { appengineOrigin } from "../api";
import { Client } from "../apiv2";
import { logger } from "../logger";

/**
Expand All @@ -12,11 +13,8 @@ import { logger } from "../logger";
*/
export async function checkDatabaseType(projectId: string): Promise<string | undefined> {
try {
const resp = await api.request("GET", "/v1/apps/" + projectId, {
auth: true,
origin: api.appengineOrigin,
});

const client = new Client({ urlPrefix: appengineOrigin, apiVersion: "v1" });
const resp = await client.get<{ databaseType?: string }>(`/apps/${projectId}`);
return resp.body.databaseType;
} catch (err: any) {
logger.debug("error getting database type", err);
Expand Down
8 changes: 3 additions & 5 deletions src/gcp/storage.ts
@@ -1,7 +1,7 @@
import { Readable } from "stream";
import * as path from "path";

import api, { appengineOrigin, storageOrigin } from "../api";
import { appengineOrigin, storageOrigin } from "../api";
import { Client } from "../apiv2";
import { logger } from "../logger";
import { FirebaseError } from "../error";
Expand Down Expand Up @@ -206,10 +206,8 @@ export async function uploadObject(
* @param {string} location A Firebase Storage location, of the form "/v0/b/<bucket>/o/<object>"
*/
export function deleteObject(location: string): Promise<any> {
return api.request("DELETE", location, {
auth: true,
origin: api.storageOrigin,
});
const localAPIClient = new Client({ urlPrefix: storageOrigin });
return localAPIClient.delete(location);
}

/**
Expand Down
8 changes: 3 additions & 5 deletions src/init/features/database.ts
@@ -1,5 +1,4 @@
import * as clc from "cli-color";
import * as api from "../../api";
import { prompt, promptOnce } from "../../prompt";
import { logger } from "../../logger";
import * as utils from "../../utils";
Expand All @@ -17,6 +16,7 @@ import ora = require("ora");
import { ensure } from "../../ensureApiEnabled";
import { getDefaultDatabaseInstance } from "../../getDefaultDatabaseInstance";
import { FirebaseError } from "../../error";
import { Client } from "../../apiv2";

interface DatabaseSetup {
projectId?: string;
Expand All @@ -41,10 +41,8 @@ async function getDBRules(instanceDetails: DatabaseInstance): Promise<string> {
if (!instanceDetails || !instanceDetails.name) {
return DEFAULT_RULES;
}
const response = await api.request("GET", "/.settings/rules.json", {
auth: true,
origin: instanceDetails.databaseUrl,
});
const client = new Client({ urlPrefix: instanceDetails.databaseUrl });
const response = await client.get<string>("/.settings/rules.json");
return response.body;
}

Expand Down

0 comments on commit c3ecb83

Please sign in to comment.