firebase-functions 4.2.1 → 4.3.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.
Files changed (44) hide show
  1. package/lib/common/change.js +4 -4
  2. package/lib/common/encoding.d.ts +3 -2
  3. package/lib/common/encoding.js +4 -0
  4. package/lib/common/params.d.ts +4 -4
  5. package/lib/common/providers/firestore.d.ts +1 -0
  6. package/lib/common/providers/firestore.js +106 -0
  7. package/lib/common/providers/https.d.ts +3 -3
  8. package/lib/common/providers/identity.d.ts +3 -3
  9. package/lib/common/providers/tasks.d.ts +1 -1
  10. package/lib/common/timezone.d.ts +1 -1
  11. package/lib/common/utilities/path-pattern.js +5 -5
  12. package/lib/logger/index.d.ts +1 -1
  13. package/lib/params/index.d.ts +1 -1
  14. package/lib/params/types.d.ts +5 -5
  15. package/lib/v1/function-builder.d.ts +4 -2
  16. package/lib/v1/function-builder.js +7 -5
  17. package/lib/v1/function-configuration.d.ts +5 -5
  18. package/lib/v1/providers/auth.js +3 -3
  19. package/lib/v1/providers/firestore.d.ts +2 -2
  20. package/lib/v1/providers/firestore.js +4 -39
  21. package/lib/v1/providers/testLab.d.ts +3 -3
  22. package/lib/v2/index.d.ts +2 -1
  23. package/lib/v2/index.js +3 -1
  24. package/lib/v2/options.d.ts +8 -8
  25. package/lib/v2/providers/alerts/alerts.d.ts +3 -3
  26. package/lib/v2/providers/alerts/appDistribution.d.ts +2 -2
  27. package/lib/v2/providers/alerts/crashlytics.d.ts +2 -2
  28. package/lib/v2/providers/database.d.ts +3 -3
  29. package/lib/v2/providers/eventarc.d.ts +2 -2
  30. package/lib/v2/providers/firestore.d.ts +91 -0
  31. package/lib/v2/providers/firestore.js +243 -0
  32. package/lib/v2/providers/https.d.ts +3 -3
  33. package/lib/v2/providers/identity.d.ts +2 -2
  34. package/lib/v2/providers/pubsub.d.ts +2 -2
  35. package/lib/v2/providers/remoteConfig.d.ts +2 -2
  36. package/lib/v2/providers/storage.d.ts +2 -2
  37. package/lib/v2/providers/tasks.d.ts +3 -3
  38. package/lib/v2/providers/testLab.d.ts +2 -2
  39. package/lib/v2/trace.d.ts +1 -1
  40. package/package.json +13 -6
  41. package/protos/README.md +15 -0
  42. package/protos/compiledFirestore.d.ts +1342 -0
  43. package/protos/compiledFirestore.js +3514 -0
  44. package/protos/update.sh +75 -0
@@ -54,10 +54,6 @@ exports.applyFieldMask = applyFieldMask;
54
54
  *
55
55
  */
56
56
  class Change {
57
- constructor(before, after) {
58
- this.before = before;
59
- this.after = after;
60
- }
61
57
  /**
62
58
  * Factory method for creating a Change from a `before` object and an `after`
63
59
  * object.
@@ -76,5 +72,9 @@ class Change {
76
72
  }
77
73
  return Change.fromObjects(customizer(before || {}), customizer(json.after || {}));
78
74
  }
75
+ constructor(before, after) {
76
+ this.before = before;
77
+ this.after = after;
78
+ }
79
79
  }
80
80
  exports.Change = Change;
@@ -1,8 +1,9 @@
1
+ import { Expression } from "../params";
1
2
  /**
2
3
  * A type alias used to annotate interfaces as using a google.protobuf.Duration.
3
4
  * This type is parsed/encoded as a string of seconds + the "s" prefix.
4
5
  */
5
- export declare type Duration = string;
6
+ export type Duration = string;
6
7
  /** Get a google.protobuf.Duration for a number of seconds. */
7
8
  export declare function durationFromSeconds(s: number): Duration;
8
9
  /**
@@ -12,5 +13,5 @@ export declare function durationFromSeconds(s: number): Duration;
12
13
  */
13
14
  export declare function copyIfPresent<Src, Dest>(dest: Dest, src: Src, ...fields: Array<keyof Src & keyof Dest>): void;
14
15
  export declare function convertIfPresent<Src, Dest>(dest: Dest, src: Src, destField: keyof Dest, srcField: keyof Src, converter?: (from: any) => any): void;
15
- export declare function serviceAccountFromShorthand(serviceAccount: string): string | null;
16
+ export declare function serviceAccountFromShorthand(serviceAccount: string | Expression<string>): string | Expression<string> | null;
16
17
  export declare function convertInvoker(invoker: string | string[]): string[];
@@ -22,6 +22,7 @@
22
22
  // SOFTWARE.
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.convertInvoker = exports.serviceAccountFromShorthand = exports.convertIfPresent = exports.copyIfPresent = exports.durationFromSeconds = void 0;
25
+ const params_1 = require("../params");
25
26
  /** Get a google.protobuf.Duration for a number of seconds. */
26
27
  function durationFromSeconds(s) {
27
28
  return `${s}s`;
@@ -60,6 +61,9 @@ function serviceAccountFromShorthand(serviceAccount) {
60
61
  if (serviceAccount === "default") {
61
62
  return null;
62
63
  }
64
+ else if (serviceAccount instanceof params_1.Expression) {
65
+ return serviceAccount;
66
+ }
63
67
  else if (serviceAccount.endsWith("@")) {
64
68
  if (!process.env.GCLOUD_PROJECT) {
65
69
  throw new Error(`Unable to determine email for service account '${serviceAccount}' because process.env.GCLOUD_PROJECT is not set.`);
@@ -3,13 +3,13 @@
3
3
  *
4
4
  * For example Split<"a/b/c", "/"> is ['a' | "b" | "c"]
5
5
  */
6
- export declare type Split<S extends string, D extends string> = string extends S ? string[] : S extends "" ? [] : S extends `${D}${infer Tail}` ? [...Split<Tail, D>] : S extends `${infer Head}${D}${infer Tail}` ? string extends Head ? [...Split<Tail, D>] : [Head, ...Split<Tail, D>] : [
6
+ export type Split<S extends string, D extends string> = string extends S ? string[] : S extends "" ? [] : S extends `${D}${infer Tail}` ? [...Split<Tail, D>] : S extends `${infer Head}${D}${infer Tail}` ? string extends Head ? [...Split<Tail, D>] : [Head, ...Split<Tail, D>] : [
7
7
  S
8
8
  ];
9
9
  /**
10
10
  * A type that ensure that type S is not null or undefined.
11
11
  */
12
- export declare type NullSafe<S extends null | undefined | string> = S extends null ? never : S extends undefined ? never : S extends string ? S : never;
12
+ export type NullSafe<S extends null | undefined | string> = S extends null ? never : S extends undefined ? never : S extends string ? S : never;
13
13
  /**
14
14
  * A type that extracts parameter name enclosed in bracket as string.
15
15
  * Ignore wildcard matches
@@ -18,7 +18,7 @@ export declare type NullSafe<S extends null | undefined | string> = S extends nu
18
18
  * For example, Extract<"{uid=*}"> is "uid".
19
19
  * For example, Extract<"{uid=**}"> is "uid".
20
20
  */
21
- export declare type Extract<Part extends string> = Part extends `{${infer Param}=**}` ? Param : Part extends `{${infer Param}=*}` ? Param : Part extends `{${infer Param}}` ? Param : never;
21
+ export type Extract<Part extends string> = Part extends `{${infer Param}=**}` ? Param : Part extends `{${infer Param}=*}` ? Param : Part extends `{${infer Param}}` ? Param : never;
22
22
  /**
23
23
  * A type that maps all parameter capture gropus into keys of a record.
24
24
  * For example, ParamsOf<"users/{uid}"> is { uid: string }
@@ -27,6 +27,6 @@ export declare type Extract<Part extends string> = Part extends `{${infer Param}
27
27
  *
28
28
  * For flexibility reasons, ParamsOf<string> is Record<string, string>
29
29
  */
30
- export declare type ParamsOf<PathPattern extends string> = string extends PathPattern ? Record<string, string> : {
30
+ export type ParamsOf<PathPattern extends string> = string extends PathPattern ? Record<string, string> : {
31
31
  [Key in Extract<Split<NullSafe<PathPattern>, "/">[number]>]: string;
32
32
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ // The MIT License (MIT)
3
+ //
4
+ // Copyright (c) 2023 Firebase
5
+ //
6
+ // Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ // of this software and associated documentation files (the "Software"), to deal
8
+ // in the Software without restriction, including without limitation the rights
9
+ // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ // copies of the Software, and to permit persons to whom the Software is
11
+ // furnished to do so, subject to the following conditions:
12
+ //
13
+ // The above copyright notice and this permission notice shall be included in all
14
+ // copies or substantial portions of the Software.
15
+ //
16
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ // SOFTWARE.
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.createBeforeSnapshotFromJson = exports.createSnapshotFromJson = exports.createBeforeSnapshotFromProtobuf = exports.createSnapshotFromProtobuf = void 0;
25
+ const firestore = require("firebase-admin/firestore");
26
+ const logger = require("../../logger");
27
+ const app_1 = require("../../common/app");
28
+ const compiledFirestore_1 = require("../../../protos/compiledFirestore");
29
+ const encoder_1 = require("../../common/utilities/encoder");
30
+ /** static-complied protobufs */
31
+ const DocumentEventData = compiledFirestore_1.google.events.cloud.firestore.v1.DocumentEventData;
32
+ let firestoreInstance;
33
+ /** @hidden */
34
+ function _getValueProto(data, resource, valueFieldName) {
35
+ const value = data === null || data === void 0 ? void 0 : data[valueFieldName];
36
+ if (typeof value === "undefined" ||
37
+ value === null ||
38
+ (typeof value === "object" && !Object.keys(value).length)) {
39
+ // Firestore#snapshot_ takes resource string instead of proto for a non-existent snapshot
40
+ return resource;
41
+ }
42
+ const proto = {
43
+ fields: (value === null || value === void 0 ? void 0 : value.fields) || {},
44
+ createTime: (0, encoder_1.dateToTimestampProto)(value === null || value === void 0 ? void 0 : value.createTime),
45
+ updateTime: (0, encoder_1.dateToTimestampProto)(value === null || value === void 0 ? void 0 : value.updateTime),
46
+ name: (value === null || value === void 0 ? void 0 : value.name) || resource,
47
+ };
48
+ return proto;
49
+ }
50
+ /** @internal */
51
+ function createSnapshotFromProtobuf(data, path) {
52
+ if (!firestoreInstance) {
53
+ firestoreInstance = firestore.getFirestore((0, app_1.getApp)());
54
+ }
55
+ try {
56
+ const dataBuffer = Buffer.from(data);
57
+ const firestoreDecoded = DocumentEventData.decode(dataBuffer);
58
+ return firestoreInstance.snapshot_(firestoreDecoded.value || path, null, "protobufJS");
59
+ }
60
+ catch (err) {
61
+ logger.error("Failed to decode protobuf and create a snapshot.");
62
+ throw err;
63
+ }
64
+ }
65
+ exports.createSnapshotFromProtobuf = createSnapshotFromProtobuf;
66
+ /** @internal */
67
+ function createBeforeSnapshotFromProtobuf(data, path) {
68
+ if (!firestoreInstance) {
69
+ firestoreInstance = firestore.getFirestore((0, app_1.getApp)());
70
+ }
71
+ try {
72
+ const dataBuffer = Buffer.from(data);
73
+ const firestoreDecoded = DocumentEventData.decode(dataBuffer);
74
+ return firestoreInstance.snapshot_(firestoreDecoded.oldValue || path, null, "protobufJS");
75
+ }
76
+ catch (err) {
77
+ logger.error("Failed to decode protobuf and create a before snapshot.");
78
+ throw err;
79
+ }
80
+ }
81
+ exports.createBeforeSnapshotFromProtobuf = createBeforeSnapshotFromProtobuf;
82
+ /** @internal */
83
+ function createSnapshotFromJson(data, source, createTime, updateTime) {
84
+ if (!firestoreInstance) {
85
+ firestoreInstance = firestore.getFirestore((0, app_1.getApp)());
86
+ }
87
+ const valueProto = _getValueProto(data, source, "value");
88
+ let timeString = createTime || updateTime;
89
+ if (!timeString) {
90
+ logger.warn("Snapshot has no readTime. Using now()");
91
+ timeString = new Date().toISOString();
92
+ }
93
+ const readTime = (0, encoder_1.dateToTimestampProto)(timeString);
94
+ return firestoreInstance.snapshot_(valueProto, readTime, "json");
95
+ }
96
+ exports.createSnapshotFromJson = createSnapshotFromJson;
97
+ /** @internal */
98
+ function createBeforeSnapshotFromJson(data, source, createTime, updateTime) {
99
+ if (!firestoreInstance) {
100
+ firestoreInstance = firestore.getFirestore((0, app_1.getApp)());
101
+ }
102
+ const oldValueProto = _getValueProto(data, source, "oldValue");
103
+ const oldReadTime = (0, encoder_1.dateToTimestampProto)(createTime || updateTime);
104
+ return firestoreInstance.snapshot_(oldValueProto, oldReadTime, "json");
105
+ }
106
+ exports.createBeforeSnapshotFromJson = createBeforeSnapshotFromJson;
@@ -123,9 +123,9 @@ export interface CallableRequest<T = any> {
123
123
  * - `unauthenticated`: The request does not have valid authentication
124
124
  * credentials for the operation.
125
125
  */
126
- export declare type FunctionsErrorCode = "ok" | "cancelled" | "unknown" | "invalid-argument" | "deadline-exceeded" | "not-found" | "already-exists" | "permission-denied" | "resource-exhausted" | "failed-precondition" | "aborted" | "out-of-range" | "unimplemented" | "internal" | "unavailable" | "data-loss" | "unauthenticated";
126
+ export type FunctionsErrorCode = "ok" | "cancelled" | "unknown" | "invalid-argument" | "deadline-exceeded" | "not-found" | "already-exists" | "permission-denied" | "resource-exhausted" | "failed-precondition" | "aborted" | "out-of-range" | "unimplemented" | "internal" | "unavailable" | "data-loss" | "unauthenticated";
127
127
  /** @hidden */
128
- export declare type CanonicalErrorCodeName = "OK" | "CANCELLED" | "UNKNOWN" | "INVALID_ARGUMENT" | "DEADLINE_EXCEEDED" | "NOT_FOUND" | "ALREADY_EXISTS" | "PERMISSION_DENIED" | "UNAUTHENTICATED" | "RESOURCE_EXHAUSTED" | "FAILED_PRECONDITION" | "ABORTED" | "OUT_OF_RANGE" | "UNIMPLEMENTED" | "INTERNAL" | "UNAVAILABLE" | "DATA_LOSS";
128
+ export type CanonicalErrorCodeName = "OK" | "CANCELLED" | "UNKNOWN" | "INVALID_ARGUMENT" | "DEADLINE_EXCEEDED" | "NOT_FOUND" | "ALREADY_EXISTS" | "PERMISSION_DENIED" | "UNAUTHENTICATED" | "RESOURCE_EXHAUSTED" | "FAILED_PRECONDITION" | "ABORTED" | "OUT_OF_RANGE" | "UNIMPLEMENTED" | "INTERNAL" | "UNAVAILABLE" | "DATA_LOSS";
129
129
  /** @hidden */
130
130
  interface HttpErrorCode {
131
131
  canonicalName: CanonicalErrorCodeName;
@@ -191,7 +191,7 @@ export declare function decode(data: any): any;
191
191
  *
192
192
  */
193
193
  /** @hidden */
194
- declare type TokenStatus = "MISSING" | "VALID" | "INVALID";
194
+ type TokenStatus = "MISSING" | "VALID" | "INVALID";
195
195
  /** @interanl */
196
196
  export declare function checkAuthToken(req: Request, ctx: CallableContext | TaskContext): Promise<TokenStatus>;
197
197
  export {};
@@ -7,16 +7,16 @@ export { HttpsError };
7
7
  * @hidden
8
8
  * @alpha
9
9
  */
10
- export declare type AuthBlockingEventType = "beforeCreate" | "beforeSignIn";
10
+ export type AuthBlockingEventType = "beforeCreate" | "beforeSignIn";
11
11
  /**
12
12
  * The UserRecord passed to Cloud Functions is the same UserRecord that is returned by the Firebase Admin
13
13
  * SDK.
14
14
  */
15
- export declare type UserRecord = auth.UserRecord;
15
+ export type UserRecord = auth.UserRecord;
16
16
  /**
17
17
  * UserInfo that is part of the UserRecord
18
18
  */
19
- export declare type UserInfo = auth.UserInfo;
19
+ export type UserInfo = auth.UserInfo;
20
20
  /**
21
21
  * Helper class to create the user metadata in a UserRecord object
22
22
  */
@@ -32,7 +32,7 @@ export interface RetryConfig {
32
32
  /** How congestion control should be applied to the function. */
33
33
  export interface RateLimits {
34
34
  /**
35
- * The maximum number of requests that can be outstanding at a time.
35
+ * The maximum number of requests that can be processed at a time.
36
36
  * If left unspecified, will default to 1000.
37
37
  */
38
38
  maxConcurrentDispatches?: number | Expression<number> | ResetValue;
@@ -1,2 +1,2 @@
1
1
  export declare const tzDatabase: Record<string, string>;
2
- export declare type timezone = keyof typeof tzDatabase;
2
+ export type timezone = keyof typeof tzDatabase;
@@ -82,16 +82,16 @@ class MultiCaptureSegment {
82
82
  * @internal
83
83
  */
84
84
  class PathPattern {
85
- constructor(raw) {
86
- this.raw = raw;
87
- this.segments = [];
88
- this.initPathSegments(raw);
89
- }
90
85
  /** @throws on validation error */
91
86
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
92
87
  static compile(rawPath) {
93
88
  return undefined;
94
89
  }
90
+ constructor(raw) {
91
+ this.raw = raw;
92
+ this.segments = [];
93
+ this.initPathSegments(raw);
94
+ }
95
95
  getValue() {
96
96
  return this.raw;
97
97
  }
@@ -2,7 +2,7 @@
2
2
  * `LogSeverity` indicates the detailed severity of the log entry. See [LogSeverity](https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#logseverity).
3
3
  * @public
4
4
  */
5
- export declare type LogSeverity = "DEBUG" | "INFO" | "NOTICE" | "WARNING" | "ERROR" | "CRITICAL" | "ALERT" | "EMERGENCY";
5
+ export type LogSeverity = "DEBUG" | "INFO" | "NOTICE" | "WARNING" | "ERROR" | "CRITICAL" | "ALERT" | "EMERGENCY";
6
6
  /**
7
7
  * `LogEntry` represents a [structured Cloud Logging](https://cloud.google.com/logging/docs/structured-logging)
8
8
  * entry. All keys aside from `severity` and `message` are
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { BooleanParam, Expression, IntParam, Param, ParamOptions, SecretParam, StringParam, ListParam } from "./types";
6
6
  export { ParamOptions, Expression };
7
- declare type SecretOrExpr = Param<any> | SecretParam;
7
+ type SecretOrExpr = Param<any> | SecretParam;
8
8
  export declare const declaredParams: SecretOrExpr[];
9
9
  /**
10
10
  * A builtin param that resolves to the default RTDB database URL associated
@@ -29,8 +29,8 @@ export declare class CompareExpression<T extends string | number | boolean | str
29
29
  thenElse<retT extends string | number | boolean | string[]>(ifTrue: retT | Expression<retT>, ifFalse: retT | Expression<retT>): TernaryExpression<retT>;
30
30
  }
31
31
  /** @hidden */
32
- declare type ParamValueType = "string" | "list" | "boolean" | "int" | "float" | "secret";
33
- declare type ParamInput<T> = {
32
+ type ParamValueType = "string" | "list" | "boolean" | "int" | "float" | "secret";
33
+ type ParamInput<T> = {
34
34
  text: TextInput<T>;
35
35
  } | {
36
36
  select: SelectInput<T>;
@@ -92,7 +92,7 @@ export interface SelectOptions<T = unknown> {
92
92
  value: T;
93
93
  }
94
94
  /** The wire representation of a Param when it's sent to the CLI. A superset of ParamOptions. */
95
- export declare type ParamSpec<T extends string | number | boolean | string[]> = {
95
+ export type ParamSpec<T extends string | number | boolean | string[]> = {
96
96
  /** The name of the parameter which will be stored in .env files. Use UPPERCASE. */
97
97
  name: string;
98
98
  /** An optional default value to be used while prompting for input. Can be a literal or another parametrized expression. */
@@ -112,7 +112,7 @@ export declare type ParamSpec<T extends string | number | boolean | string[]> =
112
112
  *
113
113
  * @alpha
114
114
  */
115
- export declare type WireParamSpec<T extends string | number | boolean | string[]> = {
115
+ export type WireParamSpec<T extends string | number | boolean | string[]> = {
116
116
  name: string;
117
117
  default?: T | string;
118
118
  label?: string;
@@ -121,7 +121,7 @@ export declare type WireParamSpec<T extends string | number | boolean | string[]
121
121
  input?: ParamInput<T>;
122
122
  };
123
123
  /** Configuration options which can be used to customize the prompting behavior of a Param. */
124
- export declare type ParamOptions<T extends string | number | boolean | string[]> = Omit<ParamSpec<T>, "name" | "type">;
124
+ export type ParamOptions<T extends string | number | boolean | string[]> = Omit<ParamSpec<T>, "name" | "type">;
125
125
  /**
126
126
  * Represents a parametrized value that will be read from .env files if present,
127
127
  * or prompted for by the CLI if missing. Instantiate these with the defineX
@@ -1,4 +1,6 @@
1
1
  import * as express from "express";
2
+ import { ResetValue } from "../common/options";
3
+ import { Expression } from "../params/types";
2
4
  import { EventContext } from "./cloud-functions";
3
5
  import { DeploymentOptions, RuntimeOptions, SUPPORTED_REGIONS } from "./function-configuration";
4
6
  import * as analytics from "./providers/analytics";
@@ -19,7 +21,7 @@ import * as testLab from "./providers/testLab";
19
21
  * @example
20
22
  * functions.region('us-east1', 'us-central1')
21
23
  */
22
- export declare function region(...regions: Array<typeof SUPPORTED_REGIONS[number] | string>): FunctionBuilder;
24
+ export declare function region(...regions: Array<(typeof SUPPORTED_REGIONS)[number] | string | Expression<string> | ResetValue>): FunctionBuilder;
23
25
  /**
24
26
  * Configure runtime options for the function.
25
27
  * @param runtimeOptions Object with optional fields:
@@ -50,7 +52,7 @@ export declare class FunctionBuilder {
50
52
  * @example
51
53
  * functions.region('us-east1', 'us-central1')
52
54
  */
53
- region(...regions: Array<typeof SUPPORTED_REGIONS[number] | string>): FunctionBuilder;
55
+ region(...regions: Array<(typeof SUPPORTED_REGIONS)[number] | string | Expression<string> | ResetValue>): FunctionBuilder;
54
56
  /**
55
57
  * Configure runtime options for the function.
56
58
  * @param runtimeOptions Object with optional fields:
@@ -45,7 +45,8 @@ function assertRuntimeOptionsValid(runtimeOptions) {
45
45
  if (mem && typeof mem !== "object" && !function_configuration_1.VALID_MEMORY_OPTIONS.includes(mem)) {
46
46
  throw new Error(`The only valid memory allocation values are: ${function_configuration_1.VALID_MEMORY_OPTIONS.join(", ")}`);
47
47
  }
48
- if (runtimeOptions.timeoutSeconds > function_configuration_1.MAX_TIMEOUT_SECONDS || runtimeOptions.timeoutSeconds < 0) {
48
+ if (typeof runtimeOptions.timeoutSeconds === "number" &&
49
+ (runtimeOptions.timeoutSeconds > function_configuration_1.MAX_TIMEOUT_SECONDS || runtimeOptions.timeoutSeconds < 0)) {
49
50
  throw new Error(`TimeoutSeconds must be between 0 and ${function_configuration_1.MAX_TIMEOUT_SECONDS}`);
50
51
  }
51
52
  if (runtimeOptions.ingressSettings &&
@@ -61,10 +62,11 @@ function assertRuntimeOptionsValid(runtimeOptions) {
61
62
  validateFailurePolicy(runtimeOptions.failurePolicy);
62
63
  const serviceAccount = runtimeOptions.serviceAccount;
63
64
  if (serviceAccount &&
64
- serviceAccount !== "default" &&
65
- !(serviceAccount instanceof options_1.ResetValue) &&
66
- !serviceAccount.includes("@")) {
67
- throw new Error(`serviceAccount must be set to 'default', a service account email, or '{serviceAccountName}@'`);
65
+ !(serviceAccount === "default" ||
66
+ serviceAccount instanceof options_1.ResetValue ||
67
+ serviceAccount instanceof types_1.Expression ||
68
+ serviceAccount.includes("@"))) {
69
+ throw new Error(`serviceAccount must be set to 'default', a string expression, a service account email, or '{serviceAccountName}@'`);
68
70
  }
69
71
  if (runtimeOptions.labels) {
70
72
  // Labels must follow the rules listed in
@@ -121,7 +121,7 @@ export interface RuntimeOptions {
121
121
  /**
122
122
  * Amount of memory to allocate to the function.
123
123
  */
124
- memory?: typeof VALID_MEMORY_OPTIONS[number] | Expression<number> | ResetValue;
124
+ memory?: (typeof VALID_MEMORY_OPTIONS)[number] | Expression<number> | ResetValue;
125
125
  /**
126
126
  * Timeout for the function in seconds, possible values are 0 to 540.
127
127
  */
@@ -145,15 +145,15 @@ export interface RuntimeOptions {
145
145
  /**
146
146
  * Egress settings for VPC connector.
147
147
  */
148
- vpcConnectorEgressSettings?: typeof VPC_EGRESS_SETTINGS_OPTIONS[number] | ResetValue;
148
+ vpcConnectorEgressSettings?: (typeof VPC_EGRESS_SETTINGS_OPTIONS)[number] | ResetValue;
149
149
  /**
150
150
  * Specific service account for the function to run as.
151
151
  */
152
- serviceAccount?: "default" | string | ResetValue;
152
+ serviceAccount?: "default" | string | Expression<string> | ResetValue;
153
153
  /**
154
154
  * Ingress settings which control where this function can be called from.
155
155
  */
156
- ingressSettings?: typeof INGRESS_SETTINGS_OPTIONS[number] | ResetValue;
156
+ ingressSettings?: (typeof INGRESS_SETTINGS_OPTIONS)[number] | ResetValue;
157
157
  /**
158
158
  * User labels to set on the function.
159
159
  */
@@ -194,7 +194,7 @@ export interface DeploymentOptions extends RuntimeOptions {
194
194
  /**
195
195
  * Regions where function should be deployed.
196
196
  */
197
- regions?: Array<typeof SUPPORTED_REGIONS[number] | string>;
197
+ regions?: Array<(typeof SUPPORTED_REGIONS)[number] | string | Expression<string> | ResetValue>;
198
198
  /**
199
199
  * Schedule for the scheduled function.
200
200
  */
@@ -59,15 +59,15 @@ exports._userWithOptions = _userWithOptions;
59
59
  * @public
60
60
  */
61
61
  class UserBuilder {
62
+ static dataConstructor(raw) {
63
+ return (0, identity_1.userRecordConstructor)(raw.data);
64
+ }
62
65
  /* @internal */
63
66
  constructor(triggerResource, options, userOptions) {
64
67
  this.triggerResource = triggerResource;
65
68
  this.options = options;
66
69
  this.userOptions = userOptions;
67
70
  }
68
- static dataConstructor(raw) {
69
- return (0, identity_1.userRecordConstructor)(raw.data);
70
- }
71
71
  /**
72
72
  * Responds to the creation of a Firebase Auth user.
73
73
  *
@@ -3,8 +3,8 @@ import { Change } from "../../common/change";
3
3
  import { ParamsOf } from "../../common/params";
4
4
  import { CloudFunction, Event, EventContext } from "../cloud-functions";
5
5
  import { DeploymentOptions } from "../function-configuration";
6
- export declare type DocumentSnapshot = firestore.DocumentSnapshot;
7
- export declare type QueryDocumentSnapshot = firestore.QueryDocumentSnapshot;
6
+ export type DocumentSnapshot = firestore.DocumentSnapshot;
7
+ export type QueryDocumentSnapshot = firestore.QueryDocumentSnapshot;
8
8
  /**
9
9
  * Select the Firestore document to listen to for events.
10
10
  * @param path Full database path to listen to. This includes the name of
@@ -22,12 +22,9 @@
22
22
  // SOFTWARE.
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.DocumentBuilder = exports.beforeSnapshotConstructor = exports.snapshotConstructor = exports.NamespaceBuilder = exports.DatabaseBuilder = exports._documentWithOptions = exports._namespaceWithOptions = exports._databaseWithOptions = exports.database = exports.namespace = exports.document = exports.defaultDatabase = exports.service = exports.provider = void 0;
25
- const firestore = require("firebase-admin/firestore");
26
25
  const path_1 = require("path");
27
- const app_1 = require("../../common/app");
28
26
  const change_1 = require("../../common/change");
29
- const encoder_1 = require("../../common/utilities/encoder");
30
- const logger = require("../../logger");
27
+ const firestore_1 = require("../../common/providers/firestore");
31
28
  const cloud_functions_1 = require("../cloud-functions");
32
29
  /** @internal */
33
30
  exports.provider = "google.firestore";
@@ -35,7 +32,6 @@ exports.provider = "google.firestore";
35
32
  exports.service = "firestore.googleapis.com";
36
33
  /** @internal */
37
34
  exports.defaultDatabase = "(default)";
38
- let firestoreInstance;
39
35
  /**
40
36
  * Select the Firestore document to listen to for events.
41
37
  * @param path Full database path to listen to. This includes the name of
@@ -102,46 +98,15 @@ class NamespaceBuilder {
102
98
  }
103
99
  }
104
100
  exports.NamespaceBuilder = NamespaceBuilder;
105
- function _getValueProto(data, resource, valueFieldName) {
106
- const value = data === null || data === void 0 ? void 0 : data[valueFieldName];
107
- if (typeof value === "undefined" ||
108
- value === null ||
109
- (typeof value === "object" && !Object.keys(value).length)) {
110
- // Firestore#snapshot_ takes resource string instead of proto for a non-existent snapshot
111
- return resource;
112
- }
113
- const proto = {
114
- fields: (value === null || value === void 0 ? void 0 : value.fields) || {},
115
- createTime: (0, encoder_1.dateToTimestampProto)(value === null || value === void 0 ? void 0 : value.createTime),
116
- updateTime: (0, encoder_1.dateToTimestampProto)(value === null || value === void 0 ? void 0 : value.updateTime),
117
- name: (value === null || value === void 0 ? void 0 : value.name) || resource,
118
- };
119
- return proto;
120
- }
121
101
  function snapshotConstructor(event) {
122
- var _a, _b, _c, _d, _e;
123
- if (!firestoreInstance) {
124
- firestoreInstance = firestore.getFirestore((0, app_1.getApp)());
125
- }
126
- const valueProto = _getValueProto(event.data, event.context.resource.name, "value");
127
- let timeString = (_c = (_b = (_a = event === null || event === void 0 ? void 0 : event.data) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.readTime) !== null && _c !== void 0 ? _c : (_e = (_d = event === null || event === void 0 ? void 0 : event.data) === null || _d === void 0 ? void 0 : _d.value) === null || _e === void 0 ? void 0 : _e.updateTime;
128
- if (!timeString) {
129
- logger.warn("Snapshot has no readTime. Using now()");
130
- timeString = new Date().toISOString();
131
- }
132
- const readTime = (0, encoder_1.dateToTimestampProto)(timeString);
133
- return firestoreInstance.snapshot_(valueProto, readTime, "json");
102
+ var _a, _b, _c, _d;
103
+ return (0, firestore_1.createSnapshotFromJson)(event.data, event.context.resource.name, (_b = (_a = event === null || event === void 0 ? void 0 : event.data) === null || _a === void 0 ? void 0 : _a.value) === null || _b === void 0 ? void 0 : _b.readTime, (_d = (_c = event === null || event === void 0 ? void 0 : event.data) === null || _c === void 0 ? void 0 : _c.value) === null || _d === void 0 ? void 0 : _d.updateTime);
134
104
  }
135
105
  exports.snapshotConstructor = snapshotConstructor;
136
106
  // TODO remove this function when wire format changes to new format
137
107
  function beforeSnapshotConstructor(event) {
138
108
  var _a, _b;
139
- if (!firestoreInstance) {
140
- firestoreInstance = firestore.getFirestore((0, app_1.getApp)());
141
- }
142
- const oldValueProto = _getValueProto(event.data, event.context.resource.name, "oldValue");
143
- const oldReadTime = (0, encoder_1.dateToTimestampProto)((_b = (_a = event === null || event === void 0 ? void 0 : event.data) === null || _a === void 0 ? void 0 : _a.oldValue) === null || _b === void 0 ? void 0 : _b.readTime);
144
- return firestoreInstance.snapshot_(oldValueProto, oldReadTime, "json");
109
+ return (0, firestore_1.createBeforeSnapshotFromJson)(event.data, event.context.resource.name, (_b = (_a = event === null || event === void 0 ? void 0 : event.data) === null || _a === void 0 ? void 0 : _a.oldValue) === null || _b === void 0 ? void 0 : _b.readTime, undefined);
145
110
  }
146
111
  exports.beforeSnapshotConstructor = beforeSnapshotConstructor;
147
112
  function changeConstructor(raw) {
@@ -136,7 +136,7 @@ export declare class ResultStorage {
136
136
  * - `INVALID_APK_PREVIEW_SDK`: APK is built for a preview SDK which is
137
137
  * unsupported.
138
138
  */
139
- export declare type InvalidMatrixDetails = "DETAILS_UNAVAILABLE" | "MALFORMED_APK" | "MALFORMED_TEST_APK" | "NO_MANIFEST" | "NO_PACKAGE_NAME" | "INVALID_PACKAGE_NAME" | "TEST_SAME_AS_APP" | "NO_INSTRUMENTATION" | "NO_SIGNATURE" | "INSTRUMENTATION_ORCHESTRATOR_INCOMPATIBLE" | "NO_TEST_RUNNER_CLASS" | "NO_LAUNCHER_ACTIVITY" | "FORBIDDEN_PERMISSIONS" | "INVALID_ROBO_DIRECTIVES" | "INVALID_RESOURCE_NAME" | "INVALID_DIRECTIVE_ACTION" | "TEST_LOOP_INTENT_FILTER_NOT_FOUND" | "SCENARIO_LABEL_NOT_DECLARED" | "SCENARIO_LABEL_MALFORMED" | "SCENARIO_NOT_DECLARED" | "DEVICE_ADMIN_RECEIVER" | "MALFORMED_XC_TEST_ZIP" | "BUILT_FOR_IOS_SIMULATOR" | "NO_TESTS_IN_XC_TEST_ZIP" | "USE_DESTINATION_ARTIFACTS" | "TEST_NOT_APP_HOSTED" | "PLIST_CANNOT_BE_PARSED" | "NO_CODE_APK" | "INVALID_INPUT_APK" | "INVALID_APK_PREVIEW_SDK";
139
+ export type InvalidMatrixDetails = "DETAILS_UNAVAILABLE" | "MALFORMED_APK" | "MALFORMED_TEST_APK" | "NO_MANIFEST" | "NO_PACKAGE_NAME" | "INVALID_PACKAGE_NAME" | "TEST_SAME_AS_APP" | "NO_INSTRUMENTATION" | "NO_SIGNATURE" | "INSTRUMENTATION_ORCHESTRATOR_INCOMPATIBLE" | "NO_TEST_RUNNER_CLASS" | "NO_LAUNCHER_ACTIVITY" | "FORBIDDEN_PERMISSIONS" | "INVALID_ROBO_DIRECTIVES" | "INVALID_RESOURCE_NAME" | "INVALID_DIRECTIVE_ACTION" | "TEST_LOOP_INTENT_FILTER_NOT_FOUND" | "SCENARIO_LABEL_NOT_DECLARED" | "SCENARIO_LABEL_MALFORMED" | "SCENARIO_NOT_DECLARED" | "DEVICE_ADMIN_RECEIVER" | "MALFORMED_XC_TEST_ZIP" | "BUILT_FOR_IOS_SIMULATOR" | "NO_TESTS_IN_XC_TEST_ZIP" | "USE_DESTINATION_ARTIFACTS" | "TEST_NOT_APP_HOSTED" | "PLIST_CANNOT_BE_PARSED" | "NO_CODE_APK" | "INVALID_INPUT_APK" | "INVALID_APK_PREVIEW_SDK";
140
140
  /**
141
141
  * The state (i.e. progress) of a TestMatrix.
142
142
  *
@@ -158,7 +158,7 @@ export declare type InvalidMatrixDetails = "DETAILS_UNAVAILABLE" | "MALFORMED_AP
158
158
  * valid. E.g. the input file is not of the expected type, or is
159
159
  * malformed/corrupt.
160
160
  */
161
- export declare type TestState = "VALIDATING" | "PENDING" | "FINISHED" | "ERROR" | "INVALID";
161
+ export type TestState = "VALIDATING" | "PENDING" | "FINISHED" | "ERROR" | "INVALID";
162
162
  /**
163
163
  * Outcome summary for a finished TestMatrix.
164
164
  *
@@ -181,4 +181,4 @@ export declare type TestState = "VALIDATING" | "PENDING" | "FINISHED" | "ERROR"
181
181
  * - `SKIPPED`: All tests were skipped, for instance:
182
182
  * - All device configurations were incompatible.
183
183
  */
184
- export declare type OutcomeSummary = "SUCCESS" | "FAILURE" | "INCONCLUSIVE" | "SKIPPED";
184
+ export type OutcomeSummary = "SUCCESS" | "FAILURE" | "INCONCLUSIVE" | "SKIPPED";
package/lib/v2/index.d.ts CHANGED
@@ -17,7 +17,8 @@ import * as storage from "./providers/storage";
17
17
  import * as tasks from "./providers/tasks";
18
18
  import * as remoteConfig from "./providers/remoteConfig";
19
19
  import * as testLab from "./providers/testLab";
20
- export { alerts, database, storage, https, identity, pubsub, logger, tasks, eventarc, scheduler, remoteConfig, testLab, };
20
+ import * as firestore from "./providers/firestore";
21
+ export { alerts, database, storage, https, identity, pubsub, logger, tasks, eventarc, scheduler, remoteConfig, testLab, firestore, };
21
22
  export { setGlobalOptions, GlobalOptions, SupportedRegion, MemoryOption, VpcEgressSetting, IngressSetting, EventHandlerOptions, } from "./options";
22
23
  export { CloudFunction, CloudEvent, ParamsOf } from "./core";
23
24
  export { Change } from "../common/change";
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.Change = exports.setGlobalOptions = 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.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
26
  * The V2 API for Cloud Functions for Firebase.
27
27
  * This SDK also supports deep imports. For example, the namespace
@@ -53,6 +53,8 @@ const remoteConfig = require("./providers/remoteConfig");
53
53
  exports.remoteConfig = remoteConfig;
54
54
  const testLab = require("./providers/testLab");
55
55
  exports.testLab = testLab;
56
+ const firestore = require("./providers/firestore");
57
+ exports.firestore = firestore;
56
58
  var options_1 = require("./options");
57
59
  Object.defineProperty(exports, "setGlobalOptions", { enumerable: true, get: function () { return options_1.setGlobalOptions; } });
58
60
  var change_1 = require("../common/change");