firebase-functions 4.4.1 → 4.6.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.
@@ -46,7 +46,7 @@ let server = undefined;
46
46
  const app = express();
47
47
  function handleQuitquitquit(req, res) {
48
48
  res.send("ok");
49
- server.close(() => console.log("shutdown requested via /__/quitquitquit"));
49
+ server.close();
50
50
  }
51
51
  app.get("/__/quitquitquit", handleQuitquitquit);
52
52
  app.post("/__/quitquitquit", handleQuitquitquit);
@@ -58,6 +58,7 @@ if (process.env.FUNCTIONS_CONTROL_API === "true") {
58
58
  res.send(JSON.stringify((0, manifest_1.stackToWire)(stack)));
59
59
  }
60
60
  catch (e) {
61
+ console.error(e);
61
62
  res.status(400).send(`Failed to generate manifest from function source: ${e}`);
62
63
  }
63
64
  });
@@ -1,5 +1,5 @@
1
1
  /**
2
- * `ChangeJson` is the JSON format used to construct a Change object.
2
+ * `ChangeJson` is the JSON format used to construct a `Change` object.
3
3
  */
4
4
  export interface ChangeJson {
5
5
  /**
@@ -17,8 +17,8 @@ export interface ChangeJson {
17
17
  fieldMask?: string;
18
18
  }
19
19
  /**
20
- * The Functions interface for events that change state, such as
21
- * Realtime Database or Cloud Firestore `onWrite` and `onUpdate`.
20
+ * The Cloud Functions interface for events that change state, such as
21
+ * Realtime Database or Cloud Firestore `onWrite` and `onUpdate` events.
22
22
  *
23
23
  * For more information about the format used to construct `Change` objects, see
24
24
  * {@link ChangeJson} below.
@@ -28,12 +28,12 @@ export declare class Change<T> {
28
28
  before: T;
29
29
  after: T;
30
30
  /**
31
- * Factory method for creating a Change from a `before` object and an `after`
31
+ * Factory method for creating a `Change` from a `before` object and an `after`
32
32
  * object.
33
33
  */
34
34
  static fromObjects<T>(before: T, after: T): Change<T>;
35
35
  /**
36
- * Factory method for creating a Change from a JSON and an optional customizer
36
+ * Factory method for creating a `Change` from JSON and an optional customizer
37
37
  * function to be applied to both the `before` and the `after` fields.
38
38
  */
39
39
  static fromJSON<T>(json: ChangeJson, customizer?: (x: any) => T): Change<T>;
@@ -46,8 +46,8 @@ function applyFieldMask(sparseBefore, after, fieldMask) {
46
46
  }
47
47
  exports.applyFieldMask = applyFieldMask;
48
48
  /**
49
- * The Functions interface for events that change state, such as
50
- * Realtime Database or Cloud Firestore `onWrite` and `onUpdate`.
49
+ * The Cloud Functions interface for events that change state, such as
50
+ * Realtime Database or Cloud Firestore `onWrite` and `onUpdate` events.
51
51
  *
52
52
  * For more information about the format used to construct `Change` objects, see
53
53
  * {@link ChangeJson} below.
@@ -55,14 +55,14 @@ exports.applyFieldMask = applyFieldMask;
55
55
  */
56
56
  class Change {
57
57
  /**
58
- * Factory method for creating a Change from a `before` object and an `after`
58
+ * Factory method for creating a `Change` from a `before` object and an `after`
59
59
  * object.
60
60
  */
61
61
  static fromObjects(before, after) {
62
62
  return new Change(before, after);
63
63
  }
64
64
  /**
65
- * Factory method for creating a Change from a JSON and an optional customizer
65
+ * Factory method for creating a `Change` from JSON and an optional customizer
66
66
  * function to be applied to both the `before` and the `after` fields.
67
67
  */
68
68
  static fromJSON(json, customizer = (x) => x) {
@@ -9,16 +9,17 @@ export { HttpsError };
9
9
  */
10
10
  export type AuthBlockingEventType = "beforeCreate" | "beforeSignIn";
11
11
  /**
12
- * The UserRecord passed to Cloud Functions is the same UserRecord that is returned by the Firebase Admin
13
- * SDK.
12
+ * The `UserRecord` passed to Cloud Functions is the same
13
+ * {@link https://firebase.google.com/docs/reference/admin/node/firebase-admin.auth.userrecord | UserRecord}
14
+ * that is returned by the Firebase Admin SDK.
14
15
  */
15
16
  export type UserRecord = auth.UserRecord;
16
17
  /**
17
- * UserInfo that is part of the UserRecord
18
+ * `UserInfo` that is part of the `UserRecord`.
18
19
  */
19
20
  export type UserInfo = auth.UserInfo;
20
21
  /**
21
- * Helper class to create the user metadata in a UserRecord object
22
+ * Helper class to create the user metadata in a `UserRecord` object.
22
23
  */
23
24
  export declare class UserRecordMetadata implements auth.UserMetadata {
24
25
  creationTime: string;
@@ -28,13 +29,13 @@ export declare class UserRecordMetadata implements auth.UserMetadata {
28
29
  toJSON(): AuthUserMetadata;
29
30
  }
30
31
  /**
31
- * Helper function that creates a UserRecord Class from data sent over the wire.
32
+ * Helper function that creates a `UserRecord` class from data sent over the wire.
32
33
  * @param wireData data sent over the wire
33
- * @returns an instance of UserRecord with correct toJSON functions
34
+ * @returns an instance of `UserRecord` with correct toJSON functions
34
35
  */
35
36
  export declare function userRecordConstructor(wireData: Record<string, unknown>): UserRecord;
36
37
  /**
37
- * User info that is part of the AuthUserRecord
38
+ * User info that is part of the `AuthUserRecord`.
38
39
  */
39
40
  export interface AuthUserInfo {
40
41
  /**
@@ -110,7 +111,7 @@ export interface AuthMultiFactorSettings {
110
111
  enrolledFactors: AuthMultiFactorInfo[];
111
112
  }
112
113
  /**
113
- * The UserRecord passed to auth blocking Cloud Functions from the identity platform.
114
+ * The `UserRecord` passed to auth blocking functions from the identity platform.
114
115
  */
115
116
  export interface AuthUserRecord {
116
117
  /**
@@ -182,6 +183,7 @@ export interface AdditionalUserInfo {
182
183
  profile?: any;
183
184
  username?: string;
184
185
  isNewUser: boolean;
186
+ recaptchaScore?: number;
185
187
  }
186
188
  /** The credential component of the auth event context */
187
189
  export interface Credential {
@@ -204,19 +206,24 @@ export interface AuthEventContext extends EventContext {
204
206
  additionalUserInfo?: AdditionalUserInfo;
205
207
  credential?: Credential;
206
208
  }
207
- /** Defines the auth event for v2 blocking events */
209
+ /** Defines the auth event for 2nd gen blocking events */
208
210
  export interface AuthBlockingEvent extends AuthEventContext {
209
211
  data: AuthUserRecord;
210
212
  }
211
- /** The handler response type for beforeCreate blocking events */
213
+ /**
214
+ * The reCAPTCHA action options.
215
+ */
216
+ export type RecaptchaActionOptions = "ALLOW" | "BLOCK";
217
+ /** The handler response type for `beforeCreate` blocking events */
212
218
  export interface BeforeCreateResponse {
213
219
  displayName?: string;
214
220
  disabled?: boolean;
215
221
  emailVerified?: boolean;
216
222
  photoURL?: string;
217
223
  customClaims?: object;
224
+ recaptchaActionOverride?: RecaptchaActionOptions;
218
225
  }
219
- /** The handler response type for beforeSignIn blocking events */
226
+ /** The handler response type for `beforeSignIn` blocking events */
220
227
  export interface BeforeSignInResponse extends BeforeCreateResponse {
221
228
  sessionClaims?: object;
222
229
  }
@@ -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.wrapHandler = exports.getUpdateMask = exports.validateAuthResponse = exports.parseAuthEventContext = exports.parseAuthUserRecord = exports.parseMultiFactor = exports.parseDate = exports.parseProviderData = exports.parseMetadata = exports.isValidRequest = exports.userRecordConstructor = exports.UserRecordMetadata = exports.HttpsError = void 0;
24
+ exports.wrapHandler = exports.getUpdateMask = exports.validateAuthResponse = exports.parseAuthEventContext = exports.generateResponsePayload = exports.parseAuthUserRecord = exports.parseMultiFactor = exports.parseDate = exports.parseProviderData = exports.parseMetadata = exports.isValidRequest = exports.userRecordConstructor = exports.UserRecordMetadata = exports.HttpsError = void 0;
25
25
  const auth = require("firebase-admin/auth");
26
26
  const logger = require("../../logger");
27
27
  const app_1 = require("../app");
@@ -51,7 +51,7 @@ const EVENT_MAPPING = {
51
51
  beforeSignIn: "providers/cloud.auth/eventTypes/user.beforeSignIn",
52
52
  };
53
53
  /**
54
- * Helper class to create the user metadata in a UserRecord object
54
+ * Helper class to create the user metadata in a `UserRecord` object.
55
55
  */
56
56
  class UserRecordMetadata {
57
57
  constructor(creationTime, lastSignInTime) {
@@ -68,9 +68,9 @@ class UserRecordMetadata {
68
68
  }
69
69
  exports.UserRecordMetadata = UserRecordMetadata;
70
70
  /**
71
- * Helper function that creates a UserRecord Class from data sent over the wire.
71
+ * Helper function that creates a `UserRecord` class from data sent over the wire.
72
72
  * @param wireData data sent over the wire
73
- * @returns an instance of UserRecord with correct toJSON functions
73
+ * @returns an instance of `UserRecord` with correct toJSON functions
74
74
  */
75
75
  function userRecordConstructor(wireData) {
76
76
  // Falsey values from the wire format proto get lost when converted to JSON, this adds them back.
@@ -122,7 +122,7 @@ function userRecordConstructor(wireData) {
122
122
  }
123
123
  exports.userRecordConstructor = userRecordConstructor;
124
124
  /**
125
- * Checks for a valid identity platform web request, otherwise throws an HttpsError
125
+ * Checks for a valid identity platform web request, otherwise throws an HttpsError.
126
126
  * @internal
127
127
  */
128
128
  function isValidRequest(req) {
@@ -156,15 +156,15 @@ function unsafeDecodeAuthBlockingToken(token) {
156
156
  return decoded;
157
157
  }
158
158
  /**
159
- * Helper function to parse the decoded metadata object into a UserMetaData object
159
+ * Helper function to parse the decoded metadata object into a `UserMetaData` object
160
160
  * @internal
161
161
  */
162
162
  function parseMetadata(metadata) {
163
163
  const creationTime = (metadata === null || metadata === void 0 ? void 0 : metadata.creation_time)
164
- ? new Date(metadata.creation_time * 1000).toUTCString()
164
+ ? new Date(metadata.creation_time).toUTCString()
165
165
  : null;
166
166
  const lastSignInTime = (metadata === null || metadata === void 0 ? void 0 : metadata.last_sign_in_time)
167
- ? new Date(metadata.last_sign_in_time * 1000).toUTCString()
167
+ ? new Date(metadata.last_sign_in_time).toUTCString()
168
168
  : null;
169
169
  return {
170
170
  creationTime,
@@ -173,7 +173,7 @@ function parseMetadata(metadata) {
173
173
  }
174
174
  exports.parseMetadata = parseMetadata;
175
175
  /**
176
- * Helper function to parse the decoded user info array into an AuthUserInfo array
176
+ * Helper function to parse the decoded user info array into an `AuthUserInfo` array.
177
177
  * @internal
178
178
  */
179
179
  function parseProviderData(providerData) {
@@ -192,7 +192,7 @@ function parseProviderData(providerData) {
192
192
  }
193
193
  exports.parseProviderData = parseProviderData;
194
194
  /**
195
- * Helper function to parse the date into a UTC string
195
+ * Helper function to parse the date into a UTC string.
196
196
  * @internal
197
197
  */
198
198
  function parseDate(tokensValidAfterTime) {
@@ -276,7 +276,7 @@ function parseAuthUserRecord(decodedJWTUserRecord) {
276
276
  };
277
277
  }
278
278
  exports.parseAuthUserRecord = parseAuthUserRecord;
279
- /** Helper to get the AdditionalUserInfo from the decoded jwt */
279
+ /** Helper to get the `AdditionalUserInfo` from the decoded JWT */
280
280
  function parseAdditionalUserInfo(decodedJWT) {
281
281
  let profile;
282
282
  let username;
@@ -301,9 +301,33 @@ function parseAdditionalUserInfo(decodedJWT) {
301
301
  profile,
302
302
  username,
303
303
  isNewUser: decodedJWT.event_type === "beforeCreate" ? true : false,
304
+ recaptchaScore: decodedJWT.recaptcha_score,
304
305
  };
305
306
  }
306
- /** Helper to get the Credential from the decoded jwt */
307
+ /**
308
+ * Helper to generate a response from the blocking function to the Firebase Auth backend.
309
+ * @internal
310
+ */
311
+ function generateResponsePayload(authResponse) {
312
+ if (!authResponse) {
313
+ return {};
314
+ }
315
+ const { recaptchaActionOverride, ...formattedAuthResponse } = authResponse;
316
+ const result = {};
317
+ const updateMask = getUpdateMask(formattedAuthResponse);
318
+ if (updateMask.length !== 0) {
319
+ result.userRecord = {
320
+ ...formattedAuthResponse,
321
+ updateMask,
322
+ };
323
+ }
324
+ if (recaptchaActionOverride !== undefined) {
325
+ result.recaptchaActionOverride = recaptchaActionOverride;
326
+ }
327
+ return result;
328
+ }
329
+ exports.generateResponsePayload = generateResponsePayload;
330
+ /** Helper to get the Credential from the decoded JWT */
307
331
  function parseAuthCredential(decodedJWT, time) {
308
332
  if (!decodedJWT.sign_in_attributes &&
309
333
  !decodedJWT.oauth_id_token &&
@@ -437,15 +461,7 @@ function wrapHandler(eventType, handler) {
437
461
  })) || undefined;
438
462
  }
439
463
  validateAuthResponse(eventType, authResponse);
440
- const updateMask = getUpdateMask(authResponse);
441
- const result = updateMask.length === 0
442
- ? {}
443
- : {
444
- userRecord: {
445
- ...authResponse,
446
- updateMask,
447
- },
448
- };
464
+ const result = generateResponsePayload(authResponse);
449
465
  res.status(200);
450
466
  res.setHeader("Content-Type", "application/json");
451
467
  res.send(JSON.stringify(result));
@@ -53,17 +53,60 @@ export interface TaskContext {
53
53
  * The result of decoding and verifying an ODIC token.
54
54
  */
55
55
  auth?: AuthData;
56
+ /**
57
+ * The name of the queue.
58
+ * Populated via the `X-CloudTasks-QueueName` header.
59
+ */
60
+ queueName: string;
61
+ /**
62
+ * The "short" name of the task, or, if no name was specified at creation, a unique
63
+ * system-generated id.
64
+ * This is the "my-task-id" value in the complete task name, such as "task_name =
65
+ * projects/my-project-id/locations/my-location/queues/my-queue-id/tasks/my-task-id."
66
+ * Populated via the `X-CloudTasks-TaskName` header.
67
+ */
68
+ id: string;
69
+ /**
70
+ * The number of times this task has been retried.
71
+ * For the first attempt, this value is 0. This number includes attempts where the task failed
72
+ * due to 5XX error codes and never reached the execution phase.
73
+ * Populated via the `X-CloudTasks-TaskRetryCount` header.
74
+ */
75
+ retryCount: number;
76
+ /**
77
+ * The total number of times that the task has received a response from the handler.
78
+ * Since Cloud Tasks deletes the task once a successful response has been received, all
79
+ * previous handler responses were failures. This number does not include failures due to 5XX
80
+ * error codes.
81
+ * Populated via the `X-CloudTasks-TaskExecutionCount` header.
82
+ */
83
+ executionCount: number;
84
+ /**
85
+ * The schedule time of the task, as an RFC 3339 string in UTC time zone.
86
+ * Populated via the `X-CloudTasks-TaskETA` header, which uses seconds since January 1 1970.
87
+ */
88
+ scheduledTime: string;
89
+ /**
90
+ * The HTTP response code from the previous retry.
91
+ * Populated via the `X-CloudTasks-TaskPreviousResponse` header
92
+ */
93
+ previousResponse?: number;
94
+ /**
95
+ * The reason for retrying the task.
96
+ * Populated via the `X-CloudTasks-TaskRetryReason` header.
97
+ */
98
+ retryReason?: string;
99
+ /**
100
+ * Raw request headers.
101
+ */
102
+ headers?: Record<string, string>;
56
103
  }
57
104
  /**
58
- * The request used to call a Task Queue function.
105
+ * The request used to call a task queue function.
59
106
  */
60
- export interface Request<T = any> {
107
+ export type Request<T = any> = TaskContext & {
61
108
  /**
62
109
  * The parameters used by a client when calling this function.
63
110
  */
64
111
  data: T;
65
- /**
66
- * The result of decoding and verifying an ODIC token.
67
- */
68
- auth?: AuthData;
69
- }
112
+ };
@@ -33,7 +33,28 @@ function onDispatchHandler(handler) {
33
33
  logger.error("Invalid request, unable to process.");
34
34
  throw new https.HttpsError("invalid-argument", "Bad Request");
35
35
  }
36
- const context = {};
36
+ const headers = {};
37
+ for (const [key, value] of Object.entries(req.headers)) {
38
+ if (!Array.isArray(value)) {
39
+ headers[key] = value;
40
+ }
41
+ }
42
+ const context = {
43
+ queueName: req.header("X-CloudTasks-QueueName"),
44
+ id: req.header("X-CloudTasks-TaskName"),
45
+ retryCount: req.header("X-CloudTasks-TaskRetryCount")
46
+ ? Number(req.header("X-CloudTasks-TaskRetryCount"))
47
+ : undefined,
48
+ executionCount: req.header("X-CloudTasks-TaskExecutionCount")
49
+ ? Number(req.header("X-CloudTasks-TaskExecutionCount"))
50
+ : undefined,
51
+ scheduledTime: req.header("X-CloudTasks-TaskETA"),
52
+ previousResponse: req.header("X-CloudTasks-TaskPreviousResponse")
53
+ ? Number(req.header("X-CloudTasks-TaskPreviousResponse"))
54
+ : undefined,
55
+ retryReason: req.header("X-CloudTasks-TaskRetryReason"),
56
+ headers,
57
+ };
37
58
  if (!process.env.FUNCTIONS_EMULATOR) {
38
59
  const authHeader = req.header("Authorization") || "";
39
60
  const token = (_a = authHeader.match(/^Bearer (.*)$/)) === null || _a === void 0 ? void 0 : _a[1];
@@ -177,7 +177,8 @@ export interface RuntimeOptions {
177
177
  *
178
178
  * @remarks
179
179
  * Set this to true to enable the App Check replay protection feature by consuming the App Check token on callable
180
- * request. Tokens that are found to be already consumed will have request.app.alreadyConsumed property set true.
180
+ * request. Tokens that are found to be already consumed will have the `request.app.alreadyConsumed` property set
181
+ * to true.
181
182
  *
182
183
  *
183
184
  * Tokens are only considered to be consumed if it is sent to the App Check service by setting this option to true.
@@ -188,10 +189,10 @@ export interface RuntimeOptions {
188
189
  * performance and can potentially deplete your attestation providers' quotas faster. Use this feature only for
189
190
  * protecting low volume, security critical, or expensive operations.
190
191
  *
191
- * This option does not affect the enforceAppCheck option. Setting the latter to true will cause the callable function
192
- * to automatically respond with a 401 Unauthorized status code when request includes an invalid App Check token.
193
- * When request includes valid but consumed App Check tokens, requests will not be automatically rejected. Instead,
194
- * the request.app.alreadyConsumed property will be set to true and pass the execution to the handler code for making
192
+ * This option does not affect the `enforceAppCheck` option. Setting the latter to true will cause the callable function
193
+ * to automatically respond with a 401 Unauthorized status code when the request includes an invalid App Check token.
194
+ * When the request includes valid but consumed App Check tokens, requests will not be automatically rejected. Instead,
195
+ * the `request.app.alreadyConsumed` property will be set to true and pass the execution to the handler code for making
195
196
  * further decisions, such as requiring additional security checks or rejecting the request.
196
197
  */
197
198
  consumeAppCheckToken?: boolean;
package/lib/v2/core.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Core functionality of the Firebase Functions v2 SDK.
2
+ * Core functionality of the Cloud Functions for Firebase 2nd gen SDK.
3
3
  * @packageDocumentation
4
4
  */
5
5
  import { Change } from "../common/change";
@@ -7,8 +7,8 @@ import { ManifestEndpoint } from "../runtime/manifest";
7
7
  export { Change };
8
8
  export { ParamsOf } from "../common/params";
9
9
  /**
10
- * A CloudEventBase is the base of a cross-platform format for encoding a serverless event.
11
- * More information can be found in https://github.com/cloudevents/spec
10
+ * A `CloudEventBase` is the base of a cross-platform format for encoding a serverless event.
11
+ * For more information, see https://github.com/cloudevents/spec.
12
12
  * @typeParam T - The type of the event data.
13
13
  * @beta
14
14
  */
@@ -17,9 +17,9 @@ export interface CloudEvent<T> {
17
17
  readonly specversion: "1.0";
18
18
  /** A globally unique ID for this event. */
19
19
  id: string;
20
- /** The resource which published this event. */
20
+ /** The resource that published this event. */
21
21
  source: string;
22
- /** The resource, provided by source, that this event relates to */
22
+ /** The resource, provided by source, that this event relates to. */
23
23
  subject?: string;
24
24
  /** The type of event that this represents. */
25
25
  type: string;
@@ -41,10 +41,10 @@ export interface CloudFunction<EventType extends CloudEvent<unknown>> {
41
41
  /** @alpha */
42
42
  __endpoint: ManifestEndpoint;
43
43
  /**
44
- * The callback passed to the CloudFunction constructor.
45
- * Use run to test a CloudFunction
44
+ * The callback passed to the `CloudFunction` constructor.
45
+ * Use `run` to test a function.
46
46
  * @param event - The parsed event to handle.
47
- * @returns Any return value. Google Cloud Functions awaits any promise
47
+ * @returns Any return value. Cloud Functions awaits any promise
48
48
  * before shutting down your function. Resolved return values
49
49
  * are only used for unit testing purposes.
50
50
  * @beta
package/lib/v2/core.js CHANGED
@@ -23,7 +23,7 @@
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.Change = void 0;
25
25
  /**
26
- * Core functionality of the Firebase Functions v2 SDK.
26
+ * Core functionality of the Cloud Functions for Firebase 2nd gen SDK.
27
27
  * @packageDocumentation
28
28
  */
29
29
  const change_1 = require("../common/change");
package/lib/v2/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  /**
2
- * The V2 API for Cloud Functions for Firebase.
3
- * This SDK also supports deep imports. For example, the namespace
4
- * 'pubsub' is available at 'firebase-functions/v2' or is directly importable
5
- * from 'firebase-functions/v2/pubsub'.
2
+ * The 2nd gen API for Cloud Functions for Firebase.
3
+ * This SDK supports deep imports. For example, the namespace
4
+ * `pubsub` is available at `firebase-functions/v2` or is directly importable
5
+ * from `firebase-functions/v2/pubsub`.
6
6
  * @packageDocumentation
7
7
  */
8
8
  import * as logger from "../logger";
package/lib/v2/index.js CHANGED
@@ -23,10 +23,10 @@
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.params = exports.Change = 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
- * The V2 API for Cloud Functions for Firebase.
27
- * This SDK also supports deep imports. For example, the namespace
28
- * 'pubsub' is available at 'firebase-functions/v2' or is directly importable
29
- * from 'firebase-functions/v2/pubsub'.
26
+ * The 2nd gen API for Cloud Functions for Firebase.
27
+ * This SDK supports deep imports. For example, the namespace
28
+ * `pubsub` is available at `firebase-functions/v2` or is directly importable
29
+ * from `firebase-functions/v2/pubsub`.
30
30
  * @packageDocumentation
31
31
  */
32
32
  const logger = require("../logger");
@@ -3,7 +3,7 @@ import { Expression } from "../params";
3
3
  import { ParamSpec, SecretParam } from "../params/types";
4
4
  export { RESET_VALUE } from "../common/options";
5
5
  /**
6
- * List of all regions supported by Cloud Functions v2
6
+ * List of all regions supported by Cloud Functions (2nd gen).
7
7
  */
8
8
  export type SupportedRegion = "asia-east1" | "asia-northeast1" | "asia-northeast2" | "europe-north1" | "europe-west1" | "europe-west4" | "us-central1" | "us-east1" | "us-east4" | "us-west1" | "asia-east2" | "asia-northeast3" | "asia-southeast1" | "asia-southeast2" | "asia-south1" | "australia-southeast1" | "europe-central2" | "europe-west2" | "europe-west3" | "europe-west6" | "northamerica-northeast1" | "southamerica-east1" | "us-west2" | "us-west3" | "us-west4";
9
9
  /**
@@ -11,16 +11,16 @@ export type SupportedRegion = "asia-east1" | "asia-northeast1" | "asia-northeast
11
11
  */
12
12
  export type MemoryOption = "128MiB" | "256MiB" | "512MiB" | "1GiB" | "2GiB" | "4GiB" | "8GiB" | "16GiB" | "32GiB";
13
13
  /**
14
- * List of available options for VpcConnectorEgressSettings.
14
+ * List of available options for `VpcConnectorEgressSettings`.
15
15
  */
16
16
  export type VpcEgressSetting = "PRIVATE_RANGES_ONLY" | "ALL_TRAFFIC";
17
17
  /**
18
- * List of available options for IngressSettings.
18
+ * List of available options for `IngressSettings`.
19
19
  */
20
20
  export type IngressSetting = "ALLOW_ALL" | "ALLOW_INTERNAL_ONLY" | "ALLOW_INTERNAL_AND_GCLB";
21
21
  /**
22
- * GlobalOptions are options that can be set across an entire project.
23
- * These options are common to HTTPS and Event handling functions.
22
+ * `GlobalOptions` are options that can be set across an entire project.
23
+ * These options are common to HTTPS and event handling functions.
24
24
  */
25
25
  export interface GlobalOptions {
26
26
  /**
@@ -40,30 +40,30 @@ export interface GlobalOptions {
40
40
  * HTTPS functions can specify a higher timeout.
41
41
  *
42
42
  * @remarks
43
- * The minimum timeout for a gen 2 function is 1s. The maximum timeout for a
43
+ * The minimum timeout for a 2nd gen function is 1s. The maximum timeout for a
44
44
  * function depends on the type of function: Event handling functions have a
45
45
  * maximum timeout of 540s (9 minutes). HTTPS and callable functions have a
46
46
  * maximum timeout of 36,00s (1 hour). Task queue functions have a maximum
47
- * timeout of 1,800s (30 minutes)
47
+ * timeout of 1,800s (30 minutes).
48
48
  */
49
49
  timeoutSeconds?: number | Expression<number> | ResetValue;
50
50
  /**
51
- * Min number of actual instances to be running at a given time.
51
+ * Minimum number of actual instances to be running at a given time.
52
52
  *
53
53
  * @remarks
54
- * Instances will be billed for memory allocation and 10% of CPU allocation
54
+ * Instances are billed for memory allocation and 10% of CPU allocation
55
55
  * while idle.
56
56
  */
57
57
  minInstances?: number | Expression<number> | ResetValue;
58
58
  /**
59
- * Max number of instances to be running in parallel.
59
+ * Max number of instances that can be running in parallel.
60
60
  */
61
61
  maxInstances?: number | Expression<number> | ResetValue;
62
62
  /**
63
63
  * Number of requests a function can serve at once.
64
64
  *
65
65
  * @remarks
66
- * Can only be applied to functions running on Cloud Functions v2.
66
+ * Can be applied only to functions running on Cloud Functions (2nd gen)).
67
67
  * A value of null restores the default concurrency (80 when CPU >= 1, 1 otherwise).
68
68
  * Concurrency cannot be set to any value other than 1 if `cpu` is less than 1.
69
69
  * The maximum value for concurrency is 1,000.
@@ -75,13 +75,13 @@ export interface GlobalOptions {
75
75
  * @remarks
76
76
  * Defaults to 1 for functions with <= 2GB RAM and increases for larger memory sizes.
77
77
  * This is different from the defaults when using the gcloud utility and is different from
78
- * the fixed amount assigned in Google Cloud Functions generation 1.
79
- * To revert to the CPU amounts used in gcloud or in Cloud Functions generation 1, set this
78
+ * the fixed amount assigned in Cloud Functions (1st gen).
79
+ * To revert to the CPU amounts used in gcloud or in Cloud Functions (1st gen), set this
80
80
  * to the value "gcf_gen1"
81
81
  */
82
82
  cpu?: number | "gcf_gen1";
83
83
  /**
84
- * Connect cloud function to specified VPC connector.
84
+ * Connect a function to a specified VPC connector.
85
85
  */
86
86
  vpcConnector?: string | Expression<string> | ResetValue;
87
87
  /**
@@ -97,7 +97,7 @@ export interface GlobalOptions {
97
97
  */
98
98
  ingressSettings?: IngressSetting | ResetValue;
99
99
  /**
100
- * Invoker to set access control on https functions.
100
+ * Invoker to set access control on HTTPS functions.
101
101
  */
102
102
  invoker?: "public" | "private" | string | string[];
103
103
  /**
@@ -106,36 +106,39 @@ export interface GlobalOptions {
106
106
  labels?: Record<string, string>;
107
107
  secrets?: (string | SecretParam)[];
108
108
  /**
109
- * Determines whether Firebase AppCheck is enforced. Defaults to false.
109
+ * Determines whether Firebase App Check is enforced. Defaults to false.
110
110
  *
111
111
  * @remarks
112
112
  * When true, requests with invalid tokens autorespond with a 401
113
113
  * (Unauthorized) error.
114
- * When false, requests with invalid tokens set event.app to undefined.
114
+ * When false, requests with invalid tokens set `event.app` to `undefined`.
115
115
  */
116
116
  enforceAppCheck?: boolean;
117
117
  /**
118
118
  * Controls whether function configuration modified outside of function source is preserved. Defaults to false.
119
119
  *
120
120
  * @remarks
121
- * When setting configuration available in the underlying platform that is not yet available in the Firebase Functions
122
- * SDK, we highly recommend setting `preserveExternalChanges` to `true`. Otherwise, when the Firebase Functions SDK releases
121
+ * When setting configuration available in an underlying platform that is not yet available in the Firebase SDK
122
+ * for Cloud Functions, we recommend setting `preserveExternalChanges` to `true`. Otherwise, when Google releases
123
123
  * a new version of the SDK with support for the missing configuration, your function's manually configured setting
124
124
  * may inadvertently be wiped out.
125
125
  */
126
126
  preserveExternalChanges?: boolean;
127
127
  }
128
128
  /**
129
- * Sets default options for all functions written using the v2 SDK.
129
+ * Sets default options for all functions written using the 2nd gen SDK.
130
130
  * @param options Options to set as default
131
131
  */
132
132
  export declare function setGlobalOptions(options: GlobalOptions): void;
133
133
  /**
134
- * Additional fields that can be set on any event-handling Cloud Function.
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. Valid values are TODO */
137
138
  eventType?: string;
139
+ /** TODO */
138
140
  eventFilters?: Record<string, string | Expression<string>>;
141
+ /** TODO */
139
142
  eventFilterPathPatterns?: Record<string, string | Expression<string>>;
140
143
  /** Whether failed executions should be delivered again. */
141
144
  retry?: boolean | Expression<boolean> | ResetValue;
package/lib/v2/options.js CHANGED
@@ -46,7 +46,7 @@ const MemoryOptionToMB = {
46
46
  };
47
47
  let globalOptions;
48
48
  /**
49
- * Sets default options for all functions written using the v2 SDK.
49
+ * Sets default options for all functions written using the 2nd gen SDK.
50
50
  * @param options Options to set as default
51
51
  */
52
52
  function setGlobalOptions(options) {
@@ -30,6 +30,7 @@ const core_1 = require("../core");
30
30
  Object.defineProperty(exports, "Change", { enumerable: true, get: function () { return core_1.Change; } });
31
31
  const options_1 = require("../options");
32
32
  const firestore_1 = require("../../common/providers/firestore");
33
+ const trace_1 = require("../trace");
33
34
  /** @internal */
34
35
  exports.writtenEventType = "google.cloud.firestore.document.v1.written";
35
36
  /** @internal */
@@ -219,7 +220,7 @@ function onOperation(eventType, documentOrOpts, handler) {
219
220
  const event = raw;
220
221
  const params = makeParams(event.document, documentPattern);
221
222
  const firestoreEvent = makeFirestoreEvent(eventType, event, params);
222
- return handler(firestoreEvent);
223
+ return (0, trace_1.wrapTraceContext)(handler)(firestoreEvent);
223
224
  };
224
225
  func.run = handler;
225
226
  func.__endpoint = makeEndpoint(eventType, opts, documentPattern, database, namespace);
@@ -78,16 +78,18 @@ function onRequest(optsOrHandler, handler) {
78
78
  allowInsecure: false,
79
79
  },
80
80
  };
81
+ (0, encoding_1.convertIfPresent)(trigger.httpsTrigger, options.getGlobalOptions(), "invoker", "invoker", encoding_1.convertInvoker);
81
82
  (0, encoding_1.convertIfPresent)(trigger.httpsTrigger, opts, "invoker", "invoker", encoding_1.convertInvoker);
82
83
  return trigger;
83
84
  },
84
85
  });
85
- const baseOpts = options.optionsToEndpoint(options.getGlobalOptions());
86
+ const globalOpts = options.getGlobalOptions();
87
+ const baseOpts = options.optionsToEndpoint(globalOpts);
86
88
  // global options calls region a scalar and https allows it to be an array,
87
89
  // but optionsToTriggerAnnotations handles both cases.
88
90
  const specificOpts = options.optionsToEndpoint(opts);
89
91
  const endpoint = {
90
- ...(0, manifest_1.initV2Endpoint)(options.getGlobalOptions(), opts),
92
+ ...(0, manifest_1.initV2Endpoint)(globalOpts, opts),
91
93
  platform: "gcfv2",
92
94
  ...baseOpts,
93
95
  ...specificOpts,
@@ -97,6 +99,7 @@ function onRequest(optsOrHandler, handler) {
97
99
  },
98
100
  httpsTrigger: {},
99
101
  };
102
+ (0, encoding_1.convertIfPresent)(endpoint.httpsTrigger, globalOpts, "invoker", "invoker", encoding_1.convertInvoker);
100
103
  (0, encoding_1.convertIfPresent)(endpoint.httpsTrigger, opts, "invoker", "invoker", encoding_1.convertInvoker);
101
104
  handler.__endpoint = endpoint;
102
105
  return handler;
@@ -116,11 +119,12 @@ function onCall(optsOrHandler, handler) {
116
119
  // onCallHandler sniffs the function length to determine which API to present.
117
120
  // fix the length to prevent api versions from being mismatched.
118
121
  const fixedLen = (req) => handler(req);
119
- const func = (0, https_1.onCallHandler)({
122
+ let func = (0, https_1.onCallHandler)({
120
123
  cors: { origin, methods: "POST" },
121
124
  enforceAppCheck: (_a = opts.enforceAppCheck) !== null && _a !== void 0 ? _a : options.getGlobalOptions().enforceAppCheck,
122
125
  consumeAppCheckToken: opts.consumeAppCheckToken,
123
126
  }, fixedLen);
127
+ func = (0, trace_1.wrapTraceContext)(func);
124
128
  Object.defineProperty(func, "__trigger", {
125
129
  get: () => {
126
130
  const baseOpts = options.optionsToTriggerAnnotations(options.getGlobalOptions());
@@ -52,6 +52,7 @@ function onTaskDispatched(optsOrHandler, handler) {
52
52
  const specificOpts = options.optionsToTriggerAnnotations(opts);
53
53
  const taskQueueTrigger = {};
54
54
  (0, encoding_1.copyIfPresent)(taskQueueTrigger, opts, "retryConfig", "rateLimits");
55
+ (0, encoding_1.convertIfPresent)(taskQueueTrigger, options.getGlobalOptions(), "invoker", "invoker", encoding_1.convertInvoker);
55
56
  (0, encoding_1.convertIfPresent)(taskQueueTrigger, opts, "invoker", "invoker", encoding_1.convertInvoker);
56
57
  return {
57
58
  platform: "gcfv2",
@@ -82,6 +83,7 @@ function onTaskDispatched(optsOrHandler, handler) {
82
83
  };
83
84
  (0, encoding_1.copyIfPresent)(func.__endpoint.taskQueueTrigger.retryConfig, opts.retryConfig, "maxAttempts", "maxBackoffSeconds", "maxDoublings", "maxRetrySeconds", "minBackoffSeconds");
84
85
  (0, encoding_1.copyIfPresent)(func.__endpoint.taskQueueTrigger.rateLimits, opts.rateLimits, "maxConcurrentDispatches", "maxDispatchesPerSecond");
86
+ (0, encoding_1.convertIfPresent)(func.__endpoint.taskQueueTrigger, options.getGlobalOptions(), "invoker", "invoker", encoding_1.convertInvoker);
85
87
  (0, encoding_1.convertIfPresent)(func.__endpoint.taskQueueTrigger, opts, "invoker", "invoker", encoding_1.convertInvoker);
86
88
  func.__requiredAPIs = [
87
89
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firebase-functions",
3
- "version": "4.4.1",
3
+ "version": "4.6.0",
4
4
  "description": "Firebase SDK for Cloud Functions",
5
5
  "keywords": [
6
6
  "firebase",
@@ -225,7 +225,7 @@
225
225
  "eslint-config-prettier": "^8.3.0",
226
226
  "eslint-plugin-jsdoc": "^39.2.9",
227
227
  "eslint-plugin-prettier": "^4.0.0",
228
- "firebase-admin": "^11.8.0",
228
+ "firebase-admin": "^12.0.0",
229
229
  "js-yaml": "^3.13.1",
230
230
  "jsdom": "^16.2.1",
231
231
  "jsonwebtoken": "^9.0.0",
@@ -245,7 +245,7 @@
245
245
  "yargs": "^15.3.1"
246
246
  },
247
247
  "peerDependencies": {
248
- "firebase-admin": "^10.0.0 || ^11.0.0"
248
+ "firebase-admin": "^10.0.0 || ^11.0.0 || ^12.0.0"
249
249
  },
250
250
  "engines": {
251
251
  "node": ">=14.10.0"