firebase-tools 15.22.4 → 15.23.0
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/apiv2.js +91 -32
- package/lib/apphosting/backend.js +11 -4
- package/lib/commands/functions-delete.js +5 -3
- package/lib/commands/functions-lifecycle-list.js +94 -0
- package/lib/commands/functions-lifecycle-run.js +29 -0
- package/lib/commands/index.js +3 -0
- package/lib/database/import.js +3 -3
- package/lib/dataconnect/webhook.js +1 -2
- package/lib/deploy/functions/backend.js +9 -0
- package/lib/deploy/functions/build.js +3 -0
- package/lib/deploy/functions/prepare.js +90 -1
- package/lib/deploy/functions/prompts.js +62 -0
- package/lib/deploy/functions/release/fabricator.js +79 -4
- package/lib/deploy/functions/release/index.js +40 -25
- package/lib/deploy/functions/release/lifecycle.js +44 -51
- package/lib/deploy/functions/release/planner.js +41 -5
- package/lib/deploy/functions/runtimes/discovery/index.js +4 -3
- package/lib/deploy/functions/runtimes/discovery/v1alpha1.js +18 -1
- package/lib/deploy/functions/runtimes/node/index.js +1 -2
- package/lib/deploy/functions/runtimes/python/index.js +1 -2
- package/lib/deploy/hosting/uploader.js +2 -3
- package/lib/downloadUtils.js +3 -1
- package/lib/emulator/auth/operations.js +18 -8
- package/lib/emulator/downloadableEmulatorInfo.json +24 -24
- package/lib/emulator/storage/apis/gcloud.js +61 -0
- package/lib/emulator/storage/multipart.js +82 -2
- package/lib/emulator/taskQueue.js +3 -11
- package/lib/extensions/extensionsHelper.js +6 -4
- package/lib/gcp/iam.js +68 -2
- package/lib/gcp/knownRoles.json +99 -0
- package/lib/gcp/resourceManager.js +42 -1
- package/lib/gemini/fdcExperience.js +2 -2
- package/lib/hosting/initMiddleware.js +1 -1
- package/lib/hosting/proxy.js +42 -20
- package/lib/management/apps.js +4 -2
- package/lib/profiler.js +1 -2
- package/lib/streamUtils.js +24 -0
- package/lib/track.js +1 -2
- package/lib/tsconfig.compile.tsbuildinfo +1 -1
- package/lib/tsconfig.publish.tsbuildinfo +1 -1
- package/lib/utils.js +4 -21
- package/package.json +2 -4
package/lib/hosting/proxy.js
CHANGED
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.proxyRequestHandler = proxyRequestHandler;
|
|
4
4
|
exports.errorRequestHandler = errorRequestHandler;
|
|
5
5
|
const lodash_1 = require("lodash");
|
|
6
|
-
const node_fetch_1 = require("node-fetch");
|
|
7
6
|
const stream_1 = require("stream");
|
|
8
7
|
const url_1 = require("url");
|
|
9
8
|
const apiv2_1 = require("../apiv2");
|
|
@@ -41,7 +40,7 @@ function proxyRequestHandler(url, rewriteIdentifier, options = {}) {
|
|
|
41
40
|
passThrough = new stream_1.PassThrough();
|
|
42
41
|
req.pipe(passThrough);
|
|
43
42
|
}
|
|
44
|
-
const headers = new
|
|
43
|
+
const headers = new Headers({
|
|
45
44
|
"X-Forwarded-Host": req.headers.host || "",
|
|
46
45
|
"X-Original-Url": req.url || "",
|
|
47
46
|
Pragma: "no-cache",
|
|
@@ -83,13 +82,14 @@ function proxyRequestHandler(url, rewriteIdentifier, options = {}) {
|
|
|
83
82
|
});
|
|
84
83
|
}
|
|
85
84
|
catch (err) {
|
|
85
|
+
logger_1.logger.error("[PROXY ERROR]", err);
|
|
86
86
|
const isAbortError = err instanceof error_1.FirebaseError && err.original?.name.includes("AbortError");
|
|
87
87
|
const isTimeoutError = err instanceof error_1.FirebaseError &&
|
|
88
|
-
err.original
|
|
89
|
-
|
|
88
|
+
(err.original?.code === "ETIMEDOUT" ||
|
|
89
|
+
err.original?.cause?.code === "ETIMEDOUT");
|
|
90
90
|
const isSocketTimeoutError = err instanceof error_1.FirebaseError &&
|
|
91
|
-
err.original
|
|
92
|
-
|
|
91
|
+
(err.original?.code === "ESOCKETTIMEDOUT" ||
|
|
92
|
+
err.original?.cause?.code === "ESOCKETTIMEDOUT");
|
|
93
93
|
if (isAbortError || isTimeoutError || isSocketTimeoutError) {
|
|
94
94
|
res.statusCode = 504;
|
|
95
95
|
return res.end("Timed out waiting for function to respond.\n");
|
|
@@ -97,38 +97,60 @@ function proxyRequestHandler(url, rewriteIdentifier, options = {}) {
|
|
|
97
97
|
res.statusCode = 500;
|
|
98
98
|
return res.end(`An internal error occurred while proxying for ${rewriteIdentifier}\n`);
|
|
99
99
|
}
|
|
100
|
+
finally {
|
|
101
|
+
if (passThrough) {
|
|
102
|
+
passThrough.resume();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
const resHeaders = {};
|
|
106
|
+
for (const [key, value] of proxyRes.response.headers.entries()) {
|
|
107
|
+
resHeaders[key.toLowerCase()] = value;
|
|
108
|
+
}
|
|
100
109
|
if (proxyRes.status === 404) {
|
|
101
|
-
const cascade =
|
|
102
|
-
if (options.forceCascade ||
|
|
110
|
+
const cascade = resHeaders["x-cascade"];
|
|
111
|
+
if (options.forceCascade ||
|
|
112
|
+
(typeof cascade === "string" && cascade.toUpperCase() === "PASS")) {
|
|
103
113
|
return next();
|
|
104
114
|
}
|
|
105
115
|
}
|
|
106
|
-
if (!
|
|
107
|
-
|
|
116
|
+
if (!resHeaders["cache-control"]) {
|
|
117
|
+
resHeaders["cache-control"] = "private";
|
|
108
118
|
}
|
|
109
|
-
const cc =
|
|
110
|
-
if (cc && !cc.includes("private")) {
|
|
111
|
-
|
|
119
|
+
const cc = resHeaders["cache-control"];
|
|
120
|
+
if (typeof cc === "string" && !cc.includes("private")) {
|
|
121
|
+
delete resHeaders["set-cookie"];
|
|
112
122
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
const vary = resHeaders["vary"];
|
|
124
|
+
resHeaders["vary"] = makeVary(typeof vary === "string" ? vary : null);
|
|
125
|
+
const location = resHeaders["location"];
|
|
126
|
+
if (typeof location === "string" && location) {
|
|
116
127
|
try {
|
|
117
128
|
const locationURL = new url_1.URL(location);
|
|
118
129
|
if (locationURL.origin === u.origin) {
|
|
119
130
|
const unborkedLocation = location.replace(locationURL.origin, "");
|
|
120
|
-
|
|
131
|
+
resHeaders["location"] = unborkedLocation;
|
|
121
132
|
}
|
|
122
133
|
}
|
|
123
134
|
catch (e) {
|
|
124
135
|
logger_1.logger.debug(`[hosting] had trouble parsing location header, but this may be okay: "${location}"`);
|
|
125
136
|
}
|
|
126
137
|
}
|
|
127
|
-
for (const
|
|
128
|
-
|
|
138
|
+
for (const key of Object.keys(resHeaders)) {
|
|
139
|
+
const value = resHeaders[key];
|
|
140
|
+
if (key === "set-cookie") {
|
|
141
|
+
if (typeof proxyRes.response.headers.getSetCookie === "function") {
|
|
142
|
+
res.setHeader(key, proxyRes.response.headers.getSetCookie());
|
|
143
|
+
}
|
|
144
|
+
else {
|
|
145
|
+
res.setHeader(key, value);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
res.setHeader(key, value);
|
|
150
|
+
}
|
|
129
151
|
}
|
|
130
152
|
res.statusCode = proxyRes.status;
|
|
131
|
-
proxyRes.
|
|
153
|
+
proxyRes.body.pipe(res);
|
|
132
154
|
};
|
|
133
155
|
}
|
|
134
156
|
function errorRequestHandler(error) {
|
package/lib/management/apps.js
CHANGED
|
@@ -84,9 +84,11 @@ https://firebase.google.com/docs/flutter/setup
|
|
|
84
84
|
async function initiateIosAppCreation(options) {
|
|
85
85
|
if (!options.nonInteractive) {
|
|
86
86
|
options.displayName = options.displayName || (await getDisplayName());
|
|
87
|
+
const promptAppStoreId = !options.bundleId;
|
|
87
88
|
options.bundleId = options.bundleId || (await (0, prompt_1.input)("Please specify your iOS app bundle ID:"));
|
|
88
|
-
options.appStoreId
|
|
89
|
-
options.appStoreId
|
|
89
|
+
if (promptAppStoreId && !options.appStoreId) {
|
|
90
|
+
options.appStoreId = await (0, prompt_1.input)("Please specify your iOS app App Store ID:");
|
|
91
|
+
}
|
|
90
92
|
}
|
|
91
93
|
if (!options.bundleId) {
|
|
92
94
|
throw new error_1.FirebaseError("Bundle ID for iOS app cannot be empty");
|
package/lib/profiler.js
CHANGED
|
@@ -5,7 +5,6 @@ const fs = require("fs");
|
|
|
5
5
|
const ora = require("ora");
|
|
6
6
|
const readline = require("readline");
|
|
7
7
|
const tmp = require("tmp");
|
|
8
|
-
const abort_controller_1 = require("abort-controller");
|
|
9
8
|
const apiv2_1 = require("./apiv2");
|
|
10
9
|
const api_1 = require("./database/api");
|
|
11
10
|
const logger_1 = require("./logger");
|
|
@@ -26,7 +25,7 @@ async function profiler(options) {
|
|
|
26
25
|
color: "yellow",
|
|
27
26
|
});
|
|
28
27
|
const outputFormat = options.raw ? "RAW" : options.parent.json ? "JSON" : "TXT";
|
|
29
|
-
const controller = new
|
|
28
|
+
const controller = new AbortController();
|
|
30
29
|
const generateReport = () => {
|
|
31
30
|
rl.close();
|
|
32
31
|
spinner.stop();
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.stringToStream = stringToStream;
|
|
4
|
+
exports.streamToString = streamToString;
|
|
5
|
+
const stream_1 = require("stream");
|
|
6
|
+
function stringToStream(text) {
|
|
7
|
+
if (!text) {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
const s = new stream_1.Readable();
|
|
11
|
+
s.push(text);
|
|
12
|
+
s.push(null);
|
|
13
|
+
return s;
|
|
14
|
+
}
|
|
15
|
+
function streamToString(s) {
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
let b = "";
|
|
18
|
+
s.on("error", reject);
|
|
19
|
+
s.on("data", (d) => {
|
|
20
|
+
b += d.toString();
|
|
21
|
+
});
|
|
22
|
+
s.once("end", () => resolve(b));
|
|
23
|
+
});
|
|
24
|
+
}
|
package/lib/track.js
CHANGED
|
@@ -8,7 +8,6 @@ exports.trackVSCode = trackVSCode;
|
|
|
8
8
|
exports.emulatorSession = emulatorSession;
|
|
9
9
|
exports.vscodeSession = vscodeSession;
|
|
10
10
|
exports.cliSession = cliSession;
|
|
11
|
-
const node_fetch_1 = require("node-fetch");
|
|
12
11
|
const crypto_1 = require("crypto");
|
|
13
12
|
const auth_1 = require("./auth");
|
|
14
13
|
const configstore_1 = require("./configstore");
|
|
@@ -134,7 +133,7 @@ async function _ga4Track(args) {
|
|
|
134
133
|
logger_1.logger.info(`Sending Analytics for event ${eventName} to property ${session.measurementId}`, params, body);
|
|
135
134
|
}
|
|
136
135
|
try {
|
|
137
|
-
const response = await (
|
|
136
|
+
const response = await fetch(url, {
|
|
138
137
|
method: "POST",
|
|
139
138
|
headers: {
|
|
140
139
|
"content-type": "application/json;charset=UTF-8",
|