forked from firebase/firebase-tools
-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfetchWebSetup.ts
130 lines (113 loc) · 3.8 KB
/
fetchWebSetup.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import { Client } from "./apiv2";
import { configstore } from "./configstore";
import { firebaseApiOrigin, hostingApiOrigin } from "./api";
import { needProjectId } from "./projectUtils";
import { logger } from "./logger";
import { Constants } from "./emulator/constants";
export interface WebConfig {
projectId: string;
appId?: string;
databaseURL?: string;
storageBucket?: string;
locationId?: string;
apiKey?: string;
authDomain?: string;
messagingSenderId?: string;
}
/**
* See
* https://firebase.google.com/docs/reference/hosting/rest/v1beta1/projects.sites#Site
*/
interface Site {
name: string;
defaultUrl: string;
appId?: string;
labels?: Record<string, string>;
type: "DEFAULT_SITE" | "USER_SITE" | "SITE_UNSPECIFIED";
}
interface ListSitesResponse {
sites: Site[];
nextPageToken: string;
}
const apiClient = new Client({ urlPrefix: firebaseApiOrigin(), auth: true, apiVersion: "v1beta1" });
const hostingApiClient = new Client({
urlPrefix: hostingApiOrigin(),
auth: true,
apiVersion: "v1beta1",
});
const CONFIGSTORE_KEY = "webconfig";
function setCachedWebSetup(projectId: string, config: WebConfig): void {
const allConfigs = configstore.get(CONFIGSTORE_KEY) || {};
allConfigs[projectId] = config;
configstore.set(CONFIGSTORE_KEY, allConfigs);
}
/**
* Get the last known WebConfig from the cache.
* @param options CLI options.
* @return web app configuration, or undefined.
*/
export function getCachedWebSetup(options: any): WebConfig | undefined {
const projectId = needProjectId(options);
const allConfigs = configstore.get(CONFIGSTORE_KEY) || {};
return allConfigs[projectId];
}
/**
* Recursively list all hosting sites for a given project.
*/
async function listAllSites(projectId: string, nextPageToken?: string): Promise<Site[]> {
const queryParams: Record<string, string> = nextPageToken ? { pageToken: nextPageToken } : {};
const res = await hostingApiClient.get<ListSitesResponse>(`/projects/${projectId}/sites`, {
queryParams,
});
const sites = res.body.sites;
if (res.body.nextPageToken) {
const remainder = await listAllSites(projectId, res.body.nextPageToken);
return [...sites, ...remainder];
}
return sites;
}
/**
* Construct a fake configuration based on the project ID.
*/
export function constructDefaultWebSetup(projectId: string): WebConfig {
return {
projectId,
databaseURL: `https://${projectId}.firebaseio.com`,
storageBucket: `${projectId}.appspot.com`,
apiKey: "fake-api-key",
authDomain: `${projectId}.firebaseapp.com`,
};
}
/**
* TODO: deprecate this function in favor of `getAppConfig()` in `/src/management/apps.ts`
* @param options CLI options.
* @return web app configuration.
*/
export async function fetchWebSetup(options: any): Promise<WebConfig> {
const projectId = needProjectId(options);
// When using the emulators with a fake project ID, use a fake web config
if (Constants.isDemoProject(projectId)) {
return constructDefaultWebSetup(projectId);
}
// Try to determine the appId from the default Hosting site, if it is linked.
let hostingAppId: string | undefined = undefined;
try {
const sites = await listAllSites(projectId);
const defaultSite = sites.find((s) => s.type === "DEFAULT_SITE");
if (defaultSite && defaultSite.appId) {
hostingAppId = defaultSite.appId;
}
} catch (e: any) {
logger.debug("Failed to list hosting sites");
logger.debug(e);
}
// Get the web app config for the appId, or use the '-' special value if the appId is not known
const appId = hostingAppId || "-";
const res = await apiClient.get<WebConfig>(`/projects/${projectId}/webApps/${appId}/config`);
const config = res.body;
if (!config.appId && hostingAppId) {
config.appId = hostingAppId;
}
setCachedWebSetup(config.projectId, config);
return config;
}