firebase-functions 6.3.1 → 6.4.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/bin/firebase-functions.js +65 -17
- package/lib/common/providers/database.js +3 -0
- package/lib/common/trace.d.ts +3 -0
- package/lib/common/trace.js +0 -1
- package/lib/logger/index.js +1 -0
- package/lib/v1/cloud-functions.d.ts +23 -1
- package/lib/v2/index.d.ts +1 -0
- package/lib/v2/index.js +3 -1
- package/lib/v2/options.d.ts +14 -3
- package/lib/v2/providers/https.d.ts +8 -2
- package/lib/v2/providers/https.js +19 -2
- package/lib/v2/providers/tasks.js +0 -1
- package/package.json +1 -1
|
@@ -23,6 +23,8 @@
|
|
|
23
23
|
// SOFTWARE.
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
const express = require("express");
|
|
26
|
+
const fs = require("fs/promises");
|
|
27
|
+
const path = require("path");
|
|
26
28
|
const loader_1 = require("../runtime/loader");
|
|
27
29
|
const manifest_1 = require("../runtime/manifest");
|
|
28
30
|
function printUsageAndExit() {
|
|
@@ -42,30 +44,76 @@ if (args.length > 1) {
|
|
|
42
44
|
}
|
|
43
45
|
functionsDir = args[0];
|
|
44
46
|
}
|
|
45
|
-
|
|
46
|
-
const app = express();
|
|
47
|
-
function handleQuitquitquit(req, res) {
|
|
47
|
+
function handleQuitquitquit(req, res, server) {
|
|
48
48
|
res.send("ok");
|
|
49
49
|
server.close();
|
|
50
50
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
if (process.env.FUNCTIONS_MANIFEST_OUTPUT_PATH) {
|
|
52
|
+
void (async () => {
|
|
53
|
+
var _a;
|
|
54
|
+
const outputPath = process.env.FUNCTIONS_MANIFEST_OUTPUT_PATH;
|
|
55
55
|
try {
|
|
56
|
+
// Validate the output path
|
|
57
|
+
const dir = path.dirname(outputPath);
|
|
58
|
+
try {
|
|
59
|
+
await fs.access(dir, fs.constants.W_OK);
|
|
60
|
+
}
|
|
61
|
+
catch (e) {
|
|
62
|
+
console.error(`Error: Cannot write to directory '${dir}': ${e instanceof Error ? e.message : String(e)}`);
|
|
63
|
+
console.error("Please ensure the directory exists and you have write permissions.");
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
56
66
|
const stack = await (0, loader_1.loadStack)(functionsDir);
|
|
57
|
-
|
|
58
|
-
|
|
67
|
+
const wireFormat = (0, manifest_1.stackToWire)(stack);
|
|
68
|
+
await fs.writeFile(outputPath, JSON.stringify(wireFormat, null, 2));
|
|
69
|
+
process.exit(0);
|
|
59
70
|
}
|
|
60
71
|
catch (e) {
|
|
61
|
-
|
|
62
|
-
|
|
72
|
+
if (e.code === "ENOENT") {
|
|
73
|
+
console.error(`Error: Directory '${path.dirname(outputPath)}' does not exist.`);
|
|
74
|
+
console.error("Please create the directory or specify a valid path.");
|
|
75
|
+
}
|
|
76
|
+
else if (e.code === "EACCES") {
|
|
77
|
+
console.error(`Error: Permission denied writing to '${outputPath}'.`);
|
|
78
|
+
console.error("Please check file permissions or choose a different location.");
|
|
79
|
+
}
|
|
80
|
+
else if ((_a = e.message) === null || _a === void 0 ? void 0 : _a.includes("Failed to generate manifest")) {
|
|
81
|
+
console.error(e.message);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
console.error(`Failed to generate manifest from function source: ${e instanceof Error ? e.message : String(e)}`);
|
|
85
|
+
}
|
|
86
|
+
if (e instanceof Error && e.stack) {
|
|
87
|
+
console.error(e.stack);
|
|
88
|
+
}
|
|
89
|
+
process.exit(1);
|
|
63
90
|
}
|
|
64
|
-
});
|
|
91
|
+
})();
|
|
65
92
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
93
|
+
else {
|
|
94
|
+
let server = undefined;
|
|
95
|
+
const app = express();
|
|
96
|
+
app.get("/__/quitquitquit", (req, res) => handleQuitquitquit(req, res, server));
|
|
97
|
+
app.post("/__/quitquitquit", (req, res) => handleQuitquitquit(req, res, server));
|
|
98
|
+
if (process.env.FUNCTIONS_CONTROL_API === "true") {
|
|
99
|
+
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
|
100
|
+
app.get("/__/functions.yaml", async (req, res) => {
|
|
101
|
+
try {
|
|
102
|
+
const stack = await (0, loader_1.loadStack)(functionsDir);
|
|
103
|
+
res.setHeader("content-type", "text/yaml");
|
|
104
|
+
res.send(JSON.stringify((0, manifest_1.stackToWire)(stack)));
|
|
105
|
+
}
|
|
106
|
+
catch (e) {
|
|
107
|
+
console.error(e);
|
|
108
|
+
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
109
|
+
res.status(400).send(`Failed to generate manifest from function source: ${errorMessage}`);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
let port = 8080;
|
|
114
|
+
if (process.env.PORT) {
|
|
115
|
+
port = Number.parseInt(process.env.PORT);
|
|
116
|
+
}
|
|
117
|
+
console.log("Serving at port", port);
|
|
118
|
+
server = app.listen(port);
|
|
69
119
|
}
|
|
70
|
-
console.log("Serving at port", port);
|
|
71
|
-
server = app.listen(port);
|
|
@@ -99,6 +99,9 @@ class DataSnapshot {
|
|
|
99
99
|
val() {
|
|
100
100
|
const parts = (0, path_1.pathParts)(this._childPath);
|
|
101
101
|
let source = this._data;
|
|
102
|
+
if (source === null) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
102
105
|
if (parts.length) {
|
|
103
106
|
for (const part of parts) {
|
|
104
107
|
if (source[part] === undefined) {
|
package/lib/common/trace.d.ts
CHANGED
package/lib/common/trace.js
CHANGED
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.extractTraceContext = exports.traceContext = void 0;
|
|
4
4
|
const async_hooks_1 = require("async_hooks");
|
|
5
|
-
/* @internal */
|
|
6
5
|
exports.traceContext = new async_hooks_1.AsyncLocalStorage();
|
|
7
6
|
/**
|
|
8
7
|
* A regex to match the Cloud Trace header.
|
package/lib/logger/index.js
CHANGED
|
@@ -55,8 +55,8 @@ export interface EventContext<Params = Record<string, string>> {
|
|
|
55
55
|
* does not exist.
|
|
56
56
|
*/
|
|
57
57
|
auth?: {
|
|
58
|
-
token: object;
|
|
59
58
|
uid: string;
|
|
59
|
+
token: EventContextAuthToken;
|
|
60
60
|
};
|
|
61
61
|
/**
|
|
62
62
|
* The level of permissions for a user.
|
|
@@ -152,6 +152,28 @@ export interface EventContext<Params = Record<string, string>> {
|
|
|
152
152
|
*/
|
|
153
153
|
timestamp: string;
|
|
154
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* https://firebase.google.com/docs/reference/security/database#authtoken
|
|
157
|
+
*/
|
|
158
|
+
export interface EventContextAuthToken {
|
|
159
|
+
iss: string;
|
|
160
|
+
aud: string;
|
|
161
|
+
auth_time: number;
|
|
162
|
+
iat: number;
|
|
163
|
+
exp: number;
|
|
164
|
+
sub: string;
|
|
165
|
+
email?: string;
|
|
166
|
+
email_verified?: boolean;
|
|
167
|
+
phone_number?: string;
|
|
168
|
+
name?: string;
|
|
169
|
+
firebase?: {
|
|
170
|
+
identities?: {
|
|
171
|
+
[key: string]: string[];
|
|
172
|
+
};
|
|
173
|
+
sign_in_provider?: string;
|
|
174
|
+
tenant?: string;
|
|
175
|
+
};
|
|
176
|
+
}
|
|
155
177
|
/**
|
|
156
178
|
* Resource is a standard format for defining a resource
|
|
157
179
|
* (google.rpc.context.AttributeContext.Resource). In Cloud Functions, it is the
|
package/lib/v2/index.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export { alerts, database, storage, https, identity, pubsub, logger, tasks, even
|
|
|
22
22
|
export { setGlobalOptions, GlobalOptions, SupportedRegion, MemoryOption, VpcEgressSetting, IngressSetting, EventHandlerOptions, } from "./options";
|
|
23
23
|
export { CloudFunction, CloudEvent, ParamsOf, onInit } from "./core";
|
|
24
24
|
export { Change } from "../common/change";
|
|
25
|
+
export { traceContext } from "../common/trace";
|
|
25
26
|
import * as params from "../params";
|
|
26
27
|
export { params };
|
|
27
28
|
export { config } from "../v1/config";
|
package/lib/v2/index.js
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
22
|
// SOFTWARE.
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
exports.app = exports.config = exports.params = exports.Change = exports.onInit = exports.setGlobalOptions = exports.firestore = exports.testLab = exports.remoteConfig = exports.scheduler = exports.eventarc = exports.tasks = exports.logger = exports.pubsub = exports.identity = exports.https = exports.storage = exports.database = exports.alerts = void 0;
|
|
24
|
+
exports.app = exports.config = exports.params = exports.traceContext = exports.Change = exports.onInit = exports.setGlobalOptions = exports.firestore = exports.testLab = exports.remoteConfig = exports.scheduler = exports.eventarc = exports.tasks = exports.logger = exports.pubsub = exports.identity = exports.https = exports.storage = exports.database = exports.alerts = void 0;
|
|
25
25
|
/**
|
|
26
26
|
* The 2nd gen API for Cloud Functions for Firebase.
|
|
27
27
|
* This SDK supports deep imports. For example, the namespace
|
|
@@ -61,6 +61,8 @@ var core_1 = require("./core");
|
|
|
61
61
|
Object.defineProperty(exports, "onInit", { enumerable: true, get: function () { return core_1.onInit; } });
|
|
62
62
|
var change_1 = require("../common/change");
|
|
63
63
|
Object.defineProperty(exports, "Change", { enumerable: true, get: function () { return change_1.Change; } });
|
|
64
|
+
var trace_1 = require("../common/trace");
|
|
65
|
+
Object.defineProperty(exports, "traceContext", { enumerable: true, get: function () { return trace_1.traceContext; } });
|
|
64
66
|
// NOTE: Equivalent to `export * as params from "../params"` but api-extractor doesn't support that syntax.
|
|
65
67
|
const params = require("../params");
|
|
66
68
|
exports.params = params;
|
package/lib/v2/options.d.ts
CHANGED
|
@@ -134,11 +134,22 @@ export declare function setGlobalOptions(options: GlobalOptions): void;
|
|
|
134
134
|
* Additional fields that can be set on any event-handling function.
|
|
135
135
|
*/
|
|
136
136
|
export interface EventHandlerOptions extends Omit<GlobalOptions, "enforceAppCheck"> {
|
|
137
|
-
/** Type of the event.
|
|
137
|
+
/** Type of the event. */
|
|
138
138
|
eventType?: string;
|
|
139
|
-
/**
|
|
139
|
+
/**
|
|
140
|
+
* Filters events based on exact matches on the CloudEvents attributes.
|
|
141
|
+
*
|
|
142
|
+
* Each key-value pair represents an attribute name and its required value for exact matching.
|
|
143
|
+
* Events must match all specified filters to trigger the function.
|
|
144
|
+
*/
|
|
140
145
|
eventFilters?: Record<string, string | Expression<string>>;
|
|
141
|
-
/**
|
|
146
|
+
/**
|
|
147
|
+
* Filters events based on path pattern matching on the CloudEvents attributes.
|
|
148
|
+
*
|
|
149
|
+
* Similar to eventFilters, but supports wildcard patterns for flexible matching where `*` matches
|
|
150
|
+
* any single path segment, `**` matches zero or more path segments, and `{param}` captures a path segment
|
|
151
|
+
* as a parameter
|
|
152
|
+
*/
|
|
142
153
|
eventFilterPathPatterns?: Record<string, string | Expression<string>>;
|
|
143
154
|
/** Whether failed executions should be delivered again. */
|
|
144
155
|
retry?: boolean | Expression<boolean> | ResetValue;
|
|
@@ -22,7 +22,7 @@ export interface HttpsOptions extends Omit<GlobalOptions, "region" | "enforceApp
|
|
|
22
22
|
* If this is an `Array`, allows requests from domains matching at least one entry of the array.
|
|
23
23
|
* Defaults to true for {@link https.CallableFunction} and false otherwise.
|
|
24
24
|
*/
|
|
25
|
-
cors?: string | boolean | RegExp | Array<string | RegExp>;
|
|
25
|
+
cors?: string | Expression<string> | Expression<string[]> | boolean | RegExp | Array<string | RegExp>;
|
|
26
26
|
/**
|
|
27
27
|
* Amount of memory to allocate to a function.
|
|
28
28
|
*/
|
|
@@ -140,18 +140,24 @@ export interface CallableOptions<T = any> extends HttpsOptions {
|
|
|
140
140
|
*/
|
|
141
141
|
heartbeatSeconds?: number | null;
|
|
142
142
|
/**
|
|
143
|
-
* Callback for whether a request is authorized.
|
|
143
|
+
* (Deprecated) Callback for whether a request is authorized.
|
|
144
144
|
*
|
|
145
145
|
* Designed to allow reusable auth policies to be passed as an options object. Two built-in reusable policies exist:
|
|
146
146
|
* isSignedIn and hasClaim.
|
|
147
|
+
*
|
|
148
|
+
* @deprecated
|
|
147
149
|
*/
|
|
148
150
|
authPolicy?: (auth: AuthData | null, data: T) => boolean | Promise<boolean>;
|
|
149
151
|
}
|
|
150
152
|
/**
|
|
153
|
+
* @deprecated
|
|
154
|
+
*
|
|
151
155
|
* An auth policy that requires a user to be signed in.
|
|
152
156
|
*/
|
|
153
157
|
export declare const isSignedIn: () => (auth: AuthData | null) => boolean;
|
|
154
158
|
/**
|
|
159
|
+
* @deprecated
|
|
160
|
+
*
|
|
155
161
|
* An auth policy that requires a user to be both signed in and have a specific claim (optionally with a specific value)
|
|
156
162
|
*/
|
|
157
163
|
export declare const hasClaim: (claim: string, value?: string) => (auth: AuthData | null) => boolean;
|
|
@@ -33,15 +33,20 @@ const debug_1 = require("../../common/debug");
|
|
|
33
33
|
const https_1 = require("../../common/providers/https");
|
|
34
34
|
Object.defineProperty(exports, "HttpsError", { enumerable: true, get: function () { return https_1.HttpsError; } });
|
|
35
35
|
const manifest_1 = require("../../runtime/manifest");
|
|
36
|
+
const params_1 = require("../../params");
|
|
36
37
|
const options = require("../options");
|
|
37
38
|
const onInit_1 = require("../../common/onInit");
|
|
38
39
|
const logger = require("../../logger");
|
|
39
40
|
/**
|
|
41
|
+
* @deprecated
|
|
42
|
+
*
|
|
40
43
|
* An auth policy that requires a user to be signed in.
|
|
41
44
|
*/
|
|
42
45
|
const isSignedIn = () => (auth) => !!auth;
|
|
43
46
|
exports.isSignedIn = isSignedIn;
|
|
44
47
|
/**
|
|
48
|
+
* @deprecated
|
|
49
|
+
*
|
|
45
50
|
* An auth policy that requires a user to be both signed in and have a specific claim (optionally with a specific value)
|
|
46
51
|
*/
|
|
47
52
|
const hasClaim = (claim, value) => (auth) => {
|
|
@@ -64,7 +69,7 @@ function onRequest(optsOrHandler, handler) {
|
|
|
64
69
|
opts = optsOrHandler;
|
|
65
70
|
}
|
|
66
71
|
if ((0, debug_1.isDebugFeatureEnabled)("enableCors") || "cors" in opts) {
|
|
67
|
-
let origin = opts.cors;
|
|
72
|
+
let origin = opts.cors instanceof params_1.Expression ? opts.cors.value() : opts.cors;
|
|
68
73
|
if ((0, debug_1.isDebugFeatureEnabled)("enableCors")) {
|
|
69
74
|
// Respect `cors: false` to turn off cors even if debug feature is enabled.
|
|
70
75
|
origin = opts.cors === false ? false : true;
|
|
@@ -142,7 +147,19 @@ function onCall(optsOrHandler, handler) {
|
|
|
142
147
|
else {
|
|
143
148
|
opts = optsOrHandler;
|
|
144
149
|
}
|
|
145
|
-
let
|
|
150
|
+
let cors;
|
|
151
|
+
if ("cors" in opts) {
|
|
152
|
+
if (opts.cors instanceof params_1.Expression) {
|
|
153
|
+
cors = opts.cors.value();
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
cors = opts.cors;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
cors = true;
|
|
161
|
+
}
|
|
162
|
+
let origin = (0, debug_1.isDebugFeatureEnabled)("enableCors") ? true : cors;
|
|
146
163
|
// Arrays cause the access-control-allow-origin header to be dynamic based
|
|
147
164
|
// on the origin header of the request. If there is only one element in the
|
|
148
165
|
// array, this is unnecessary.
|
|
@@ -86,7 +86,6 @@ function onTaskDispatched(optsOrHandler, handler) {
|
|
|
86
86
|
(0, encoding_1.copyIfPresent)(func.__endpoint.taskQueueTrigger.rateLimits, opts.rateLimits, "maxConcurrentDispatches", "maxDispatchesPerSecond");
|
|
87
87
|
(0, encoding_1.convertIfPresent)(func.__endpoint.taskQueueTrigger, options.getGlobalOptions(), "invoker", "invoker", encoding_1.convertInvoker);
|
|
88
88
|
(0, encoding_1.convertIfPresent)(func.__endpoint.taskQueueTrigger, opts, "invoker", "invoker", encoding_1.convertInvoker);
|
|
89
|
-
(0, encoding_1.copyIfPresent)(func.__endpoint.taskQueueTrigger, opts, "retry", "retry");
|
|
90
89
|
func.__requiredAPIs = [
|
|
91
90
|
{
|
|
92
91
|
api: "cloudtasks.googleapis.com",
|