firebase-tools 11.1.0 → 11.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/accountExporter.js +11 -4
- package/lib/accountImporter.js +5 -6
- package/lib/appdistribution/client.js +7 -9
- package/lib/auth.js +3 -5
- package/lib/checkValidTargetFilters.js +28 -18
- package/lib/commands/database-profile.js +2 -3
- package/lib/commands/database-push.js +2 -3
- package/lib/commands/database-remove.js +1 -2
- package/lib/commands/database-set.js +1 -2
- package/lib/commands/deploy.js +5 -6
- package/lib/commands/ext-dev-emulators-exec.js +1 -1
- package/lib/commands/ext-dev-emulators-start.js +1 -1
- package/lib/commands/ext-dev-list.js +6 -7
- package/lib/commands/ext-export.js +2 -0
- package/lib/commands/ext-info.js +12 -13
- package/lib/commands/ext.js +2 -3
- package/lib/commands/functions-delete.js +1 -7
- package/lib/commands/open.js +5 -6
- package/lib/commands/serve.js +3 -5
- package/lib/commands/use.js +2 -3
- package/lib/config.js +4 -3
- package/lib/deploy/database/prepare.js +2 -3
- package/lib/deploy/extensions/planner.js +1 -0
- package/lib/deploy/extensions/prepare.js +18 -1
- package/lib/deploy/extensions/release.js +4 -0
- package/lib/deploy/extensions/secrets.js +3 -3
- package/lib/deploy/functions/build.js +35 -53
- package/lib/deploy/functions/ensure.js +1 -11
- package/lib/deploy/functions/params.js +189 -0
- package/lib/deploy/functions/prepare.js +3 -13
- package/lib/deploy/functions/prepareFunctionsUpload.js +2 -3
- package/lib/deploy/functions/release/fabricator.js +0 -1
- package/lib/deploy/functions/release/index.js +1 -5
- package/lib/deploy/functions/runtimes/discovery/index.js +18 -3
- package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +3 -2
- package/lib/deploy/functions/runtimes/golang/index.js +2 -22
- package/lib/deploy/functions/runtimes/node/index.js +3 -7
- package/lib/deploy/functions/runtimes/node/parseTriggers.js +2 -2
- package/lib/deploy/lifecycleHooks.js +8 -11
- package/lib/deploy/storage/prepare.js +2 -2
- package/lib/emulator/auth/index.js +1 -1
- package/lib/emulator/auth/operations.js +336 -64
- package/lib/emulator/auth/server.js +2 -2
- package/lib/emulator/auth/state.js +32 -7
- package/lib/emulator/commandUtils.js +1 -1
- package/lib/emulator/constants.js +1 -1
- package/lib/emulator/controller.js +6 -5
- package/lib/emulator/databaseEmulator.js +2 -2
- package/lib/emulator/download.js +1 -1
- package/lib/emulator/downloadableEmulators.js +6 -6
- package/lib/emulator/events/types.js +2 -3
- package/lib/emulator/firestoreEmulator.js +2 -2
- package/lib/emulator/functionsEmulator.js +36 -45
- package/lib/emulator/functionsEmulatorRuntime.js +12 -16
- package/lib/emulator/functionsEmulatorShared.js +7 -5
- package/lib/emulator/functionsRuntimeWorker.js +0 -6
- package/lib/emulator/hostingEmulator.js +1 -1
- package/lib/emulator/hub.js +1 -1
- package/lib/emulator/loggingEmulator.js +1 -1
- package/lib/emulator/pubsubEmulator.js +1 -1
- package/lib/emulator/storage/crc.js +4 -4
- package/lib/emulator/storage/index.js +1 -1
- package/lib/emulator/types.js +1 -1
- package/lib/extensions/askUserForConsent.js +1 -2
- package/lib/extensions/askUserForParam.js +15 -18
- package/lib/extensions/emulator/optionsHelper.js +4 -4
- package/lib/extensions/etags.js +28 -0
- package/lib/extensions/extensionsApi.js +1 -22
- package/lib/extensions/extensionsHelper.js +6 -6
- package/lib/extensions/listExtensions.js +9 -10
- package/lib/extensions/manifest.js +2 -2
- package/lib/extensions/resolveSource.js +11 -7
- package/lib/extensions/secretsUtils.js +3 -3
- package/lib/extensions/types.js +24 -0
- package/lib/extensions/updateHelper.js +1 -1
- package/lib/extensions/utils.js +1 -2
- package/lib/extensions/warnings.js +10 -4
- package/lib/firestore/encodeFirestoreValue.js +11 -8
- package/lib/fsAsync.js +3 -3
- package/lib/functions/env.js +5 -1
- package/lib/functionsConfig.js +18 -15
- package/lib/functionsConfigClone.js +10 -12
- package/lib/gcp/cloudfunctions.js +2 -15
- package/lib/gcp/rules.js +3 -4
- package/lib/gcp/runtimeconfig.js +2 -2
- package/lib/hosting/api.js +9 -11
- package/lib/hosting/expireUtils.js +2 -2
- package/lib/hosting/proxy.js +1 -1
- package/lib/init/features/hosting/github.js +1 -1
- package/lib/init/features/hosting/index.js +2 -2
- package/lib/localFunction.js +4 -4
- package/lib/management/projects.js +6 -7
- package/lib/previews.js +1 -1
- package/lib/profileReport.js +24 -22
- package/lib/prompt.js +1 -2
- package/lib/rc.js +12 -2
- package/lib/rulesDeploy.js +2 -2
- package/lib/serve/index.js +4 -5
- package/lib/utils.js +30 -6
- package/npm-shrinkwrap.json +2 -2
- package/package.json +10 -9
package/lib/functionsConfig.js
CHANGED
|
@@ -27,7 +27,7 @@ function setVariable(projectId, configId, varPath, val) {
|
|
|
27
27
|
return runtimeconfig.variables.set(projectId, configId, varPath, val);
|
|
28
28
|
}
|
|
29
29
|
function isReservedNamespace(id) {
|
|
30
|
-
return
|
|
30
|
+
return exports.RESERVED_NAMESPACES.some((reserved) => {
|
|
31
31
|
return id.config.toLowerCase().startsWith(reserved);
|
|
32
32
|
});
|
|
33
33
|
}
|
|
@@ -44,7 +44,7 @@ function varNameToIds(varName) {
|
|
|
44
44
|
}
|
|
45
45
|
exports.varNameToIds = varNameToIds;
|
|
46
46
|
function idsToVarName(projectId, configId, varId) {
|
|
47
|
-
return
|
|
47
|
+
return ["projects", projectId, "configs", configId, "variables", varId].join("/");
|
|
48
48
|
}
|
|
49
49
|
exports.idsToVarName = idsToVarName;
|
|
50
50
|
function getAppEngineLocation(config) {
|
|
@@ -63,16 +63,16 @@ async function getFirebaseConfig(options) {
|
|
|
63
63
|
exports.getFirebaseConfig = getFirebaseConfig;
|
|
64
64
|
async function setVariablesRecursive(projectId, configId, varPath, val) {
|
|
65
65
|
let parsed = val;
|
|
66
|
-
if (
|
|
66
|
+
if (typeof val === "string") {
|
|
67
67
|
try {
|
|
68
68
|
parsed = JSON.parse(val);
|
|
69
69
|
}
|
|
70
70
|
catch (e) {
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
-
if (
|
|
74
|
-
return Promise.all(
|
|
75
|
-
const newVarPath = varPath ?
|
|
73
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
74
|
+
return Promise.all(Object.entries(parsed).map(([key, item]) => {
|
|
75
|
+
const newVarPath = varPath ? [varPath, key].join("/") : key;
|
|
76
76
|
return setVariablesRecursive(projectId, configId, newVarPath, item);
|
|
77
77
|
}));
|
|
78
78
|
}
|
|
@@ -87,7 +87,7 @@ async function materializeConfig(configName, output) {
|
|
|
87
87
|
_.set(output, key, variable.text);
|
|
88
88
|
};
|
|
89
89
|
const traverseVariables = async function (variables) {
|
|
90
|
-
return Promise.all(
|
|
90
|
+
return Promise.all(variables.map((variable) => {
|
|
91
91
|
return materializeVariable(variable.name);
|
|
92
92
|
}));
|
|
93
93
|
};
|
|
@@ -99,7 +99,10 @@ exports.materializeConfig = materializeConfig;
|
|
|
99
99
|
async function materializeAll(projectId) {
|
|
100
100
|
const output = {};
|
|
101
101
|
const configs = await runtimeconfig.configs.list(projectId);
|
|
102
|
-
|
|
102
|
+
if (!Array.isArray(configs) || !configs.length) {
|
|
103
|
+
return output;
|
|
104
|
+
}
|
|
105
|
+
await Promise.all(configs.map((config) => {
|
|
103
106
|
if (config.name.match(new RegExp("configs/firebase"))) {
|
|
104
107
|
return;
|
|
105
108
|
}
|
|
@@ -110,7 +113,7 @@ async function materializeAll(projectId) {
|
|
|
110
113
|
exports.materializeAll = materializeAll;
|
|
111
114
|
function parseSetArgs(args) {
|
|
112
115
|
const parsed = [];
|
|
113
|
-
|
|
116
|
+
for (const arg of args) {
|
|
114
117
|
const parts = arg.split("=");
|
|
115
118
|
const key = parts[0];
|
|
116
119
|
if (parts.length < 2) {
|
|
@@ -129,17 +132,17 @@ function parseSetArgs(args) {
|
|
|
129
132
|
varId: id.variable,
|
|
130
133
|
val: val,
|
|
131
134
|
});
|
|
132
|
-
}
|
|
135
|
+
}
|
|
133
136
|
return parsed;
|
|
134
137
|
}
|
|
135
138
|
exports.parseSetArgs = parseSetArgs;
|
|
136
139
|
function parseUnsetArgs(args) {
|
|
137
140
|
const parsed = [];
|
|
138
141
|
let splitArgs = [];
|
|
139
|
-
|
|
140
|
-
splitArgs =
|
|
141
|
-
}
|
|
142
|
-
|
|
142
|
+
for (const arg of args) {
|
|
143
|
+
splitArgs = Array.from(new Set([...splitArgs, ...arg.split(",")]));
|
|
144
|
+
}
|
|
145
|
+
for (const key of splitArgs) {
|
|
143
146
|
const id = keyToIds(key);
|
|
144
147
|
if (isReservedNamespace(id)) {
|
|
145
148
|
throw new error_1.FirebaseError("Cannot unset reserved namespace " + clc.bold(id.config));
|
|
@@ -148,7 +151,7 @@ function parseUnsetArgs(args) {
|
|
|
148
151
|
configId: id.config,
|
|
149
152
|
varId: id.variable,
|
|
150
153
|
});
|
|
151
|
-
}
|
|
154
|
+
}
|
|
152
155
|
return parsed;
|
|
153
156
|
}
|
|
154
157
|
exports.parseUnsetArgs = parseUnsetArgs;
|
|
@@ -10,14 +10,12 @@ function matchPrefix(short, long) {
|
|
|
10
10
|
if (short.length > long.length) {
|
|
11
11
|
return false;
|
|
12
12
|
}
|
|
13
|
-
return
|
|
14
|
-
return accum && x === long[i];
|
|
15
|
-
}, true);
|
|
13
|
+
return short.reduce((accum, x, i) => accum && x === long[i], true);
|
|
16
14
|
}
|
|
17
15
|
function applyExcept(json, except) {
|
|
18
|
-
|
|
16
|
+
for (const key of except) {
|
|
19
17
|
_.unset(json, key);
|
|
20
|
-
}
|
|
18
|
+
}
|
|
21
19
|
}
|
|
22
20
|
function cloneVariable(varName, toProject) {
|
|
23
21
|
return runtimeconfig.variables.get(varName).then((variable) => {
|
|
@@ -27,42 +25,42 @@ function cloneVariable(varName, toProject) {
|
|
|
27
25
|
}
|
|
28
26
|
function cloneConfig(configName, toProject) {
|
|
29
27
|
return runtimeconfig.variables.list(configName).then((variables) => {
|
|
30
|
-
return Promise.all(
|
|
28
|
+
return Promise.all(variables.map((variable) => {
|
|
31
29
|
return cloneVariable(variable.name, toProject);
|
|
32
30
|
}));
|
|
33
31
|
});
|
|
34
32
|
}
|
|
35
33
|
async function cloneConfigOrVariable(key, fromProject, toProject) {
|
|
36
34
|
const parts = key.split(".");
|
|
37
|
-
if (
|
|
35
|
+
if (functionsConfig.RESERVED_NAMESPACES.includes(parts[0])) {
|
|
38
36
|
throw new error_1.FirebaseError("Cannot clone reserved namespace " + clc.bold(parts[0]));
|
|
39
37
|
}
|
|
40
|
-
const configName =
|
|
38
|
+
const configName = ["projects", fromProject, "configs", parts[0]].join("/");
|
|
41
39
|
if (parts.length === 1) {
|
|
42
40
|
return cloneConfig(configName, toProject);
|
|
43
41
|
}
|
|
44
42
|
return runtimeconfig.variables.list(configName).then((variables) => {
|
|
45
43
|
const promises = [];
|
|
46
|
-
|
|
44
|
+
for (const variable of variables) {
|
|
47
45
|
const varId = functionsConfig.varNameToIds(variable.name).variable;
|
|
48
46
|
const variablePrefixFilter = parts.slice(1);
|
|
49
47
|
if (matchPrefix(variablePrefixFilter, varId.split("/"))) {
|
|
50
48
|
promises.push(cloneVariable(variable.name, toProject));
|
|
51
49
|
}
|
|
52
|
-
}
|
|
50
|
+
}
|
|
53
51
|
return Promise.all(promises);
|
|
54
52
|
});
|
|
55
53
|
}
|
|
56
54
|
async function functionsConfigClone(fromProject, toProject, only, except = []) {
|
|
57
55
|
if (only) {
|
|
58
|
-
return Promise.all(
|
|
56
|
+
return Promise.all(only.map((key) => {
|
|
59
57
|
return cloneConfigOrVariable(key, fromProject, toProject);
|
|
60
58
|
}));
|
|
61
59
|
}
|
|
62
60
|
return functionsConfig.materializeAll(fromProject).then((toClone) => {
|
|
63
61
|
_.unset(toClone, "firebase");
|
|
64
62
|
applyExcept(toClone, except);
|
|
65
|
-
return Promise.all(
|
|
63
|
+
return Promise.all(Object.entries(toClone).map(([configId, val]) => {
|
|
66
64
|
return functionsConfig.setVariablesRecursive(toProject, configId, "", val);
|
|
67
65
|
}));
|
|
68
66
|
});
|
|
@@ -4,7 +4,6 @@ exports.functionFromEndpoint = exports.endpointFromFunction = exports.listAllFun
|
|
|
4
4
|
const clc = require("cli-color");
|
|
5
5
|
const error_1 = require("../error");
|
|
6
6
|
const logger_1 = require("../logger");
|
|
7
|
-
const previews_1 = require("../previews");
|
|
8
7
|
const backend = require("../deploy/functions/backend");
|
|
9
8
|
const utils = require("../utils");
|
|
10
9
|
const proto = require("./proto");
|
|
@@ -24,10 +23,6 @@ const BLOCKING_EVENT_TO_LABEL_KEY = {
|
|
|
24
23
|
"providers/cloud.auth/eventTypes/user.beforeCreate": "before-create",
|
|
25
24
|
"providers/cloud.auth/eventTypes/user.beforeSignIn": "before-sign-in",
|
|
26
25
|
};
|
|
27
|
-
function validateFunction(func) {
|
|
28
|
-
proto.assertOneOf("Cloud Function", func, "sourceCode", "sourceArchiveUrl", "sourceRepository", "sourceUploadUrl");
|
|
29
|
-
proto.assertOneOf("Cloud Function", func, "trigger", "httpsTrigger", "eventTrigger");
|
|
30
|
-
}
|
|
31
26
|
function functionsOpLogReject(funcName, type, err) {
|
|
32
27
|
var _a, _b;
|
|
33
28
|
if (((_b = (_a = err === null || err === void 0 ? void 0 : err.context) === null || _a === void 0 ? void 0 : _a.response) === null || _b === void 0 ? void 0 : _b.statusCode) === 429) {
|
|
@@ -58,11 +53,7 @@ async function createFunction(cloudFunction) {
|
|
|
58
53
|
const apiPath = cloudFunction.name.substring(0, cloudFunction.name.lastIndexOf("/"));
|
|
59
54
|
const endpoint = `/${apiPath}`;
|
|
60
55
|
try {
|
|
61
|
-
const
|
|
62
|
-
if (previews_1.previews.artifactregistry) {
|
|
63
|
-
headers["X-Firebase-Artifact-Registry"] = "optin";
|
|
64
|
-
}
|
|
65
|
-
const res = await client.post(endpoint, cloudFunction, { headers });
|
|
56
|
+
const res = await client.post(endpoint, cloudFunction);
|
|
66
57
|
return {
|
|
67
58
|
name: res.body.name,
|
|
68
59
|
type: "create",
|
|
@@ -147,12 +138,7 @@ async function updateFunction(cloudFunction) {
|
|
|
147
138
|
const endpoint = `/${cloudFunction.name}`;
|
|
148
139
|
const fieldMasks = proto.fieldMasks(cloudFunction, "labels", "environmentVariables", "secretEnvironmentVariables");
|
|
149
140
|
try {
|
|
150
|
-
const headers = {};
|
|
151
|
-
if (previews_1.previews.artifactregistry) {
|
|
152
|
-
headers["X-Firebase-Artifact-Registry"] = "optin";
|
|
153
|
-
}
|
|
154
141
|
const res = await client.patch(endpoint, cloudFunction, {
|
|
155
|
-
headers,
|
|
156
142
|
queryParams: {
|
|
157
143
|
updateMask: fieldMasks.join(","),
|
|
158
144
|
},
|
|
@@ -293,6 +279,7 @@ function functionFromEndpoint(endpoint, sourceUploadUrl) {
|
|
|
293
279
|
sourceUploadUrl: sourceUploadUrl,
|
|
294
280
|
entryPoint: endpoint.entryPoint,
|
|
295
281
|
runtime: endpoint.runtime,
|
|
282
|
+
dockerRegistry: "ARTIFACT_REGISTRY",
|
|
296
283
|
};
|
|
297
284
|
proto.copyIfPresent(gcfFunction, endpoint, "labels");
|
|
298
285
|
if (backend.isEventTriggered(endpoint)) {
|
package/lib/gcp/rules.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.testRuleset = exports.updateOrCreateRelease = exports.updateRelease = exports.createRelease = exports.createRuleset = exports.deleteRuleset = exports.getRulesetId = exports.listAllRulesets = exports.listRulesets = exports.getRulesetContent = exports.listAllReleases = exports.listReleases = exports.getLatestRulesetName = void 0;
|
|
4
|
-
const _ = require("lodash");
|
|
5
4
|
const api_1 = require("../api");
|
|
6
5
|
const apiv2_1 = require("../apiv2");
|
|
7
6
|
const logger_1 = require("../logger");
|
|
@@ -20,7 +19,7 @@ function _handleErrorResponse(response) {
|
|
|
20
19
|
async function getLatestRulesetName(projectId, service) {
|
|
21
20
|
const releases = await listAllReleases(projectId);
|
|
22
21
|
const prefix = `projects/${projectId}/releases/${service}`;
|
|
23
|
-
const release =
|
|
22
|
+
const release = releases.find((r) => r.name.startsWith(prefix));
|
|
24
23
|
if (!release) {
|
|
25
24
|
return null;
|
|
26
25
|
}
|
|
@@ -51,7 +50,7 @@ async function listAllReleases(projectId) {
|
|
|
51
50
|
}
|
|
52
51
|
pageToken = response.nextPageToken;
|
|
53
52
|
} while (pageToken);
|
|
54
|
-
return
|
|
53
|
+
return releases.sort((a, b) => b.createTime.localeCompare(a.createTime));
|
|
55
54
|
}
|
|
56
55
|
exports.listAllReleases = listAllReleases;
|
|
57
56
|
async function getRulesetContent(name) {
|
|
@@ -90,7 +89,7 @@ async function listAllRulesets(projectId) {
|
|
|
90
89
|
}
|
|
91
90
|
pageToken = response.nextPageToken;
|
|
92
91
|
} while (pageToken);
|
|
93
|
-
return
|
|
92
|
+
return rulesets.sort((a, b) => b.createTime.localeCompare(a.createTime));
|
|
94
93
|
}
|
|
95
94
|
exports.listAllRulesets = listAllRulesets;
|
|
96
95
|
function getRulesetId(ruleset) {
|
package/lib/gcp/runtimeconfig.js
CHANGED
|
@@ -15,7 +15,7 @@ function listConfigs(projectId) {
|
|
|
15
15
|
.then((resp) => resp.body.configs);
|
|
16
16
|
}
|
|
17
17
|
function createConfig(projectId, configId) {
|
|
18
|
-
const path =
|
|
18
|
+
const path = ["projects", projectId, "configs"].join("/");
|
|
19
19
|
return apiClient
|
|
20
20
|
.post(`/projects/${projectId}/configs`, {
|
|
21
21
|
name: path + "/" + configId,
|
|
@@ -88,7 +88,7 @@ function updateVariable(projectId, configId, varId, value) {
|
|
|
88
88
|
});
|
|
89
89
|
}
|
|
90
90
|
function setVariable(projectId, configId, varId, value) {
|
|
91
|
-
const path =
|
|
91
|
+
const path = ["projects", projectId, "configs", configId, "variables", varId].join("/");
|
|
92
92
|
return getVariable(path)
|
|
93
93
|
.then(() => {
|
|
94
94
|
return updateVariable(projectId, configId, varId, value);
|
package/lib/hosting/api.js
CHANGED
|
@@ -43,7 +43,7 @@ async function getChannel(project = "-", site, channelId) {
|
|
|
43
43
|
return res.body;
|
|
44
44
|
}
|
|
45
45
|
catch (e) {
|
|
46
|
-
if (e.status === 404) {
|
|
46
|
+
if (e instanceof error_1.FirebaseError && e.status === 404) {
|
|
47
47
|
return null;
|
|
48
48
|
}
|
|
49
49
|
throw e;
|
|
@@ -51,23 +51,22 @@ async function getChannel(project = "-", site, channelId) {
|
|
|
51
51
|
}
|
|
52
52
|
exports.getChannel = getChannel;
|
|
53
53
|
async function listChannels(project = "-", site) {
|
|
54
|
-
var _a, _b;
|
|
55
54
|
const channels = [];
|
|
56
55
|
let nextPageToken = "";
|
|
57
56
|
for (;;) {
|
|
58
57
|
try {
|
|
59
58
|
const res = await apiClient.get(`/projects/${project}/sites/${site}/channels`, { queryParams: { pageToken: nextPageToken, pageSize: 10 } });
|
|
60
|
-
const c =
|
|
59
|
+
const c = res.body.channels;
|
|
61
60
|
if (c) {
|
|
62
61
|
channels.push(...c);
|
|
63
62
|
}
|
|
64
|
-
nextPageToken =
|
|
63
|
+
nextPageToken = res.body.nextPageToken || "";
|
|
65
64
|
if (!nextPageToken) {
|
|
66
65
|
return channels;
|
|
67
66
|
}
|
|
68
67
|
}
|
|
69
68
|
catch (e) {
|
|
70
|
-
if (e.status === 404) {
|
|
69
|
+
if (e instanceof error_1.FirebaseError && e.status === 404) {
|
|
71
70
|
throw new error_1.FirebaseError(`could not find channels for site "${site}"`, {
|
|
72
71
|
original: e,
|
|
73
72
|
});
|
|
@@ -116,23 +115,22 @@ async function createRelease(site, channel, version) {
|
|
|
116
115
|
}
|
|
117
116
|
exports.createRelease = createRelease;
|
|
118
117
|
async function listSites(project) {
|
|
119
|
-
var _a, _b;
|
|
120
118
|
const sites = [];
|
|
121
119
|
let nextPageToken = "";
|
|
122
120
|
for (;;) {
|
|
123
121
|
try {
|
|
124
122
|
const res = await apiClient.get(`/projects/${project}/sites`, { queryParams: { pageToken: nextPageToken, pageSize: 10 } });
|
|
125
|
-
const c =
|
|
123
|
+
const c = res.body.sites;
|
|
126
124
|
if (c) {
|
|
127
125
|
sites.push(...c);
|
|
128
126
|
}
|
|
129
|
-
nextPageToken =
|
|
127
|
+
nextPageToken = res.body.nextPageToken || "";
|
|
130
128
|
if (!nextPageToken) {
|
|
131
129
|
return sites;
|
|
132
130
|
}
|
|
133
131
|
}
|
|
134
132
|
catch (e) {
|
|
135
|
-
if (e.status === 404) {
|
|
133
|
+
if (e instanceof error_1.FirebaseError && e.status === 404) {
|
|
136
134
|
throw new error_1.FirebaseError(`could not find sites for project "${project}"`, {
|
|
137
135
|
original: e,
|
|
138
136
|
});
|
|
@@ -148,7 +146,7 @@ async function getSite(project, site) {
|
|
|
148
146
|
return res.body;
|
|
149
147
|
}
|
|
150
148
|
catch (e) {
|
|
151
|
-
if (e.status === 404) {
|
|
149
|
+
if (e instanceof error_1.FirebaseError && e.status === 404) {
|
|
152
150
|
throw new error_1.FirebaseError(`could not find site "${site}" for project "${project}"`, {
|
|
153
151
|
original: e,
|
|
154
152
|
});
|
|
@@ -158,7 +156,7 @@ async function getSite(project, site) {
|
|
|
158
156
|
}
|
|
159
157
|
exports.getSite = getSite;
|
|
160
158
|
async function createSite(project, site, appId = "") {
|
|
161
|
-
const res = await apiClient.post(`/projects/${project}/sites`, { appId: appId }, { queryParams: {
|
|
159
|
+
const res = await apiClient.post(`/projects/${project}/sites`, { appId: appId }, { queryParams: { siteId: site } });
|
|
162
160
|
return res.body;
|
|
163
161
|
}
|
|
164
162
|
exports.createSite = createSite;
|
|
@@ -16,8 +16,8 @@ const DURATIONS = {
|
|
|
16
16
|
};
|
|
17
17
|
exports.MAX_DURATION = 30 * Duration.DAY;
|
|
18
18
|
exports.DEFAULT_DURATION = 7 * Duration.DAY;
|
|
19
|
-
function calculateChannelExpireTTL(flag) {
|
|
20
|
-
const match = exports.DURATION_REGEX.exec(flag
|
|
19
|
+
function calculateChannelExpireTTL(flag = "") {
|
|
20
|
+
const match = exports.DURATION_REGEX.exec(flag);
|
|
21
21
|
if (!match) {
|
|
22
22
|
throw new error_1.FirebaseError(`"expires" flag must be a duration string (e.g. 24h or 7d) at most 30d`);
|
|
23
23
|
}
|
package/lib/hosting/proxy.js
CHANGED
|
@@ -133,7 +133,7 @@ function proxyRequestHandler(url, rewriteIdentifier) {
|
|
|
133
133
|
}
|
|
134
134
|
exports.proxyRequestHandler = proxyRequestHandler;
|
|
135
135
|
function errorRequestHandler(error) {
|
|
136
|
-
return (req, res
|
|
136
|
+
return (req, res) => {
|
|
137
137
|
res.statusCode = 500;
|
|
138
138
|
const out = `A problem occurred while trying to handle a proxied rewrite: ${error}`;
|
|
139
139
|
logger_1.logger.error(out);
|
|
@@ -27,7 +27,7 @@ const YML_MERGE_FILENAME = "firebase-hosting-merge.yml";
|
|
|
27
27
|
const CHECKOUT_GITHUB_ACTION_NAME = "actions/checkout@v2";
|
|
28
28
|
const HOSTING_GITHUB_ACTION_NAME = "FirebaseExtended/action-hosting-deploy@v0";
|
|
29
29
|
const githubApiClient = new apiv2_1.Client({ urlPrefix: api_1.githubApiOrigin, auth: false });
|
|
30
|
-
async function initGitHub(setup
|
|
30
|
+
async function initGitHub(setup) {
|
|
31
31
|
if (!setup.projectId) {
|
|
32
32
|
return (0, utils_1.reject)("Could not determine Project ID, can't set up GitHub workflow.", { exit: 1 });
|
|
33
33
|
}
|
|
@@ -10,7 +10,7 @@ const logger_1 = require("../../../logger");
|
|
|
10
10
|
const INDEX_TEMPLATE = fs.readFileSync(__dirname + "/../../../../templates/init/hosting/index.html", "utf8");
|
|
11
11
|
const MISSING_TEMPLATE = fs.readFileSync(__dirname + "/../../../../templates/init/hosting/404.html", "utf8");
|
|
12
12
|
const DEFAULT_IGNORES = ["firebase.json", "**/.*", "**/node_modules/**"];
|
|
13
|
-
async function doSetup(setup, config
|
|
13
|
+
async function doSetup(setup, config) {
|
|
14
14
|
setup.hosting = {};
|
|
15
15
|
logger_1.logger.info();
|
|
16
16
|
logger_1.logger.info(`Your ${clc.bold("public")} directory is the folder (relative to your project directory) that`);
|
|
@@ -51,7 +51,7 @@ async function doSetup(setup, config, options) {
|
|
|
51
51
|
const response = await c.get("/firebasejs/releases.json");
|
|
52
52
|
await config.askWriteProjectFile(`${setup.hosting.public}/index.html`, INDEX_TEMPLATE.replace(/{{VERSION}}/g, response.body.current.version));
|
|
53
53
|
if (setup.hosting.github) {
|
|
54
|
-
return (0, github_1.initGitHub)(setup
|
|
54
|
+
return (0, github_1.initGitHub)(setup);
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
exports.doSetup = doSetup;
|
package/lib/localFunction.js
CHANGED
|
@@ -38,13 +38,13 @@ LocalFunction.prototype._substituteParams = function (resource, params) {
|
|
|
38
38
|
return resource.replace(wildcardRegex, function (wildcard) {
|
|
39
39
|
var wildcardNoBraces = wildcard.slice(1, -1);
|
|
40
40
|
var sub = _.get(params, wildcardNoBraces);
|
|
41
|
-
return sub || wildcardNoBraces +
|
|
41
|
+
return sub || wildcardNoBraces + utils.randomInt(1, 9);
|
|
42
42
|
});
|
|
43
43
|
};
|
|
44
44
|
LocalFunction.prototype._constructCallableFunc = function (data, opts) {
|
|
45
45
|
opts = opts || {};
|
|
46
46
|
var headers = {};
|
|
47
|
-
if (
|
|
47
|
+
if (opts.instanceIdToken) {
|
|
48
48
|
headers["Firebase-Instance-ID-Token"] = opts.instanceIdToken;
|
|
49
49
|
}
|
|
50
50
|
return request.post({
|
|
@@ -134,7 +134,7 @@ LocalFunction.prototype._call = function (data, opts) {
|
|
|
134
134
|
}
|
|
135
135
|
else if (this.eventTrigger) {
|
|
136
136
|
if (this._isDatabaseFunc(this.eventTrigger)) {
|
|
137
|
-
operationType =
|
|
137
|
+
operationType = utils.last(this.eventTrigger.eventType.split("."));
|
|
138
138
|
switch (operationType) {
|
|
139
139
|
case "create":
|
|
140
140
|
dataPayload = {
|
|
@@ -159,7 +159,7 @@ LocalFunction.prototype._call = function (data, opts) {
|
|
|
159
159
|
this.controller.call(this.name, dataPayload, opts);
|
|
160
160
|
}
|
|
161
161
|
else if (this._isFirestoreFunc(this.eventTrigger)) {
|
|
162
|
-
operationType =
|
|
162
|
+
operationType = utils.last(this.eventTrigger.eventType.split("."));
|
|
163
163
|
switch (operationType) {
|
|
164
164
|
case "create":
|
|
165
165
|
dataPayload = {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getFirebaseProject = exports.listFirebaseProjects = exports.getAvailableCloudProjectPage = exports.getFirebaseProjectPage = exports.addFirebaseToCloudProject = exports.createCloudProject = exports.promptAvailableProjectId = exports.getOrPromptProject = exports.addFirebaseToCloudProjectAndLog = exports.createFirebaseProjectAndLog = exports.PROJECTS_CREATE_QUESTIONS = exports.ProjectParentResourceType = void 0;
|
|
4
|
-
const _ = require("lodash");
|
|
5
4
|
const clc = require("cli-color");
|
|
6
5
|
const ora = require("ora");
|
|
7
6
|
const apiv2_1 = require("../apiv2");
|
|
@@ -110,15 +109,15 @@ async function selectProjectByPrompting() {
|
|
|
110
109
|
return await getFirebaseProject(projectId);
|
|
111
110
|
}
|
|
112
111
|
async function selectProjectFromList(projects = []) {
|
|
113
|
-
|
|
112
|
+
const choices = projects
|
|
114
113
|
.filter((p) => !!p)
|
|
115
114
|
.map((p) => {
|
|
116
115
|
return {
|
|
117
116
|
name: p.projectId + (p.displayName ? ` (${p.displayName})` : ""),
|
|
118
117
|
value: p.projectId,
|
|
119
118
|
};
|
|
120
|
-
})
|
|
121
|
-
|
|
119
|
+
})
|
|
120
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
122
121
|
if (choices.length >= 25) {
|
|
123
122
|
utils.logBullet(`Don't want to scroll through all your projects? If you know your project ID, ` +
|
|
124
123
|
`you can initialize it directly using ${clc.bold("firebase init --project <project_id>")}.\n`);
|
|
@@ -151,7 +150,7 @@ async function promptAvailableProjectId() {
|
|
|
151
150
|
});
|
|
152
151
|
}
|
|
153
152
|
else {
|
|
154
|
-
|
|
153
|
+
const choices = projects
|
|
155
154
|
.filter((p) => !!p)
|
|
156
155
|
.map((p) => {
|
|
157
156
|
const projectId = getProjectId(p);
|
|
@@ -159,8 +158,8 @@ async function promptAvailableProjectId() {
|
|
|
159
158
|
name: projectId + (p.displayName ? ` (${p.displayName})` : ""),
|
|
160
159
|
value: projectId,
|
|
161
160
|
};
|
|
162
|
-
})
|
|
163
|
-
|
|
161
|
+
})
|
|
162
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
164
163
|
return await (0, prompt_1.promptOnce)({
|
|
165
164
|
type: "list",
|
|
166
165
|
name: "id",
|
package/lib/previews.js
CHANGED
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.previews = void 0;
|
|
4
4
|
const lodash_1 = require("lodash");
|
|
5
5
|
const configstore_1 = require("./configstore");
|
|
6
|
-
exports.previews = Object.assign({ rtdbrules: false, ext: false, extdev: false, rtdbmanagement: false, golang: false, deletegcfartifacts: false,
|
|
6
|
+
exports.previews = Object.assign({ rtdbrules: false, ext: false, extdev: false, rtdbmanagement: false, golang: false, deletegcfartifacts: false, emulatoruisnapshot: false, frameworkawareness: false, functionsparams: false }, configstore_1.configstore.get("previews"));
|
|
7
7
|
if (process.env.FIREBASE_CLI_PREVIEWS) {
|
|
8
8
|
process.env.FIREBASE_CLI_PREVIEWS.split(",").forEach((feature) => {
|
|
9
9
|
if ((0, lodash_1.has)(exports.previews, feature)) {
|
package/lib/profileReport.js
CHANGED
|
@@ -62,7 +62,7 @@ function formatBytes(bytes) {
|
|
|
62
62
|
}
|
|
63
63
|
exports.formatBytes = formatBytes;
|
|
64
64
|
function extractReadableIndex(query) {
|
|
65
|
-
if (
|
|
65
|
+
if (query.orderBy) {
|
|
66
66
|
return query.orderBy;
|
|
67
67
|
}
|
|
68
68
|
const indexPath = _.get(query, "index.path");
|
|
@@ -96,13 +96,13 @@ class ProfileReport {
|
|
|
96
96
|
if (!data.unIndexed) {
|
|
97
97
|
return;
|
|
98
98
|
}
|
|
99
|
-
if (!
|
|
99
|
+
if (!this.state.unindexed.path) {
|
|
100
100
|
this.state.unindexed[path] = {};
|
|
101
101
|
}
|
|
102
102
|
const pathNode = this.state.unindexed[path];
|
|
103
103
|
const query = data.querySet[0];
|
|
104
104
|
const index = JSON.stringify(query.index);
|
|
105
|
-
if (!
|
|
105
|
+
if (!pathNode[index]) {
|
|
106
106
|
pathNode[index] = {
|
|
107
107
|
times: 0,
|
|
108
108
|
query: query,
|
|
@@ -132,7 +132,7 @@ class ProfileReport {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
collectSpeed(data, path, opType) {
|
|
135
|
-
if (!
|
|
135
|
+
if (!opType[path]) {
|
|
136
136
|
opType[path] = {
|
|
137
137
|
times: 0,
|
|
138
138
|
millis: 0,
|
|
@@ -155,7 +155,7 @@ class ProfileReport {
|
|
|
155
155
|
}
|
|
156
156
|
}
|
|
157
157
|
collectBandwidth(bytes, path, direction) {
|
|
158
|
-
if (!
|
|
158
|
+
if (!direction[path]) {
|
|
159
159
|
direction[path] = {
|
|
160
160
|
times: 0,
|
|
161
161
|
bytes: 0,
|
|
@@ -239,7 +239,7 @@ class ProfileReport {
|
|
|
239
239
|
if (!this.options.collapse) {
|
|
240
240
|
return pathedObject;
|
|
241
241
|
}
|
|
242
|
-
const allSegments =
|
|
242
|
+
const allSegments = Object.keys(pathedObject).map((path) => {
|
|
243
243
|
return path.split("/").filter((s) => {
|
|
244
244
|
return s !== "";
|
|
245
245
|
});
|
|
@@ -302,15 +302,15 @@ class ProfileReport {
|
|
|
302
302
|
};
|
|
303
303
|
});
|
|
304
304
|
});
|
|
305
|
-
const paths =
|
|
306
|
-
|
|
307
|
-
const indices =
|
|
308
|
-
|
|
305
|
+
const paths = Object.keys(unindexed);
|
|
306
|
+
for (const path of paths) {
|
|
307
|
+
const indices = Object.keys(unindexed[path]);
|
|
308
|
+
for (const index of indices) {
|
|
309
309
|
const data = unindexed[path][index];
|
|
310
310
|
const row = [path, extractReadableIndex(data.query), formatNumber(data.times)];
|
|
311
311
|
table.push(row);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
314
|
return table;
|
|
315
315
|
}
|
|
316
316
|
renderBandwidth(pureData) {
|
|
@@ -327,8 +327,10 @@ class ProfileReport {
|
|
|
327
327
|
times: b1.times + b2.times,
|
|
328
328
|
};
|
|
329
329
|
});
|
|
330
|
-
const paths =
|
|
331
|
-
|
|
330
|
+
const paths = Object.keys(data).sort((a, b) => {
|
|
331
|
+
return data[b].bytes - data[a].bytes;
|
|
332
|
+
});
|
|
333
|
+
for (const path of paths) {
|
|
332
334
|
const bandwidth = data[path];
|
|
333
335
|
const row = [
|
|
334
336
|
path,
|
|
@@ -337,7 +339,7 @@ class ProfileReport {
|
|
|
337
339
|
formatBytes(bandwidth.bytes / bandwidth.times),
|
|
338
340
|
];
|
|
339
341
|
table.push(row);
|
|
340
|
-
}
|
|
342
|
+
}
|
|
341
343
|
return table;
|
|
342
344
|
}
|
|
343
345
|
renderOutgoingBandwidth() {
|
|
@@ -392,12 +394,12 @@ class ProfileReport {
|
|
|
392
394
|
rejected: s1.rejected + s2.rejected,
|
|
393
395
|
};
|
|
394
396
|
});
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
const
|
|
398
|
-
return
|
|
399
|
-
}
|
|
400
|
-
|
|
397
|
+
const paths = Object.keys(data).sort((a, b) => {
|
|
398
|
+
const speedA = data[a].millis / data[a].times;
|
|
399
|
+
const speedB = data[b].millis / data[b].times;
|
|
400
|
+
return speedB - speedA;
|
|
401
|
+
});
|
|
402
|
+
for (const path of paths) {
|
|
401
403
|
const speed = data[path];
|
|
402
404
|
const row = [
|
|
403
405
|
path,
|
|
@@ -409,7 +411,7 @@ class ProfileReport {
|
|
|
409
411
|
row.push(formatNumber(speed.rejected));
|
|
410
412
|
}
|
|
411
413
|
table.push(row);
|
|
412
|
-
}
|
|
414
|
+
}
|
|
413
415
|
return table;
|
|
414
416
|
}
|
|
415
417
|
renderReadSpeed() {
|
package/lib/prompt.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.promptOnce = exports.prompt = void 0;
|
|
4
4
|
const inquirer = require("inquirer");
|
|
5
|
-
const _ = require("lodash");
|
|
6
5
|
const error_1 = require("./error");
|
|
7
6
|
async function prompt(options, questions) {
|
|
8
7
|
const prompts = [];
|
|
@@ -12,7 +11,7 @@ async function prompt(options, questions) {
|
|
|
12
11
|
}
|
|
13
12
|
}
|
|
14
13
|
if (prompts.length && options.nonInteractive) {
|
|
15
|
-
const missingOptions =
|
|
14
|
+
const missingOptions = Array.from(new Set(prompts.map((p) => p.name))).join(", ");
|
|
16
15
|
throw new error_1.FirebaseError(`Missing required options (${missingOptions}) while running in non-interactive mode`, {
|
|
17
16
|
children: prompts,
|
|
18
17
|
});
|