firebase-functions 4.2.0 → 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.
- package/lib/common/change.js +4 -4
- package/lib/common/encoding.d.ts +3 -2
- package/lib/common/encoding.js +4 -0
- package/lib/common/params.d.ts +4 -4
- package/lib/common/providers/database.js +1 -6
- package/lib/common/providers/firestore.d.ts +1 -0
- package/lib/common/providers/firestore.js +106 -0
- package/lib/common/providers/https.d.ts +3 -3
- package/lib/common/providers/https.js +28 -1
- package/lib/common/providers/identity.d.ts +3 -3
- package/lib/common/providers/tasks.d.ts +1 -1
- package/lib/common/timezone.d.ts +1 -1
- package/lib/common/utilities/path-pattern.js +5 -5
- package/lib/logger/index.d.ts +1 -1
- package/lib/params/index.d.ts +1 -1
- package/lib/params/types.d.ts +5 -5
- package/lib/v1/function-builder.d.ts +4 -2
- package/lib/v1/function-builder.js +7 -5
- package/lib/v1/function-configuration.d.ts +5 -5
- package/lib/v1/providers/auth.js +3 -3
- package/lib/v1/providers/firestore.d.ts +2 -2
- package/lib/v1/providers/firestore.js +4 -39
- package/lib/v1/providers/testLab.d.ts +4 -4
- package/lib/v2/index.d.ts +2 -1
- package/lib/v2/index.js +3 -1
- package/lib/v2/options.d.ts +8 -8
- package/lib/v2/providers/alerts/alerts.d.ts +3 -3
- package/lib/v2/providers/alerts/appDistribution.d.ts +2 -2
- package/lib/v2/providers/alerts/crashlytics.d.ts +2 -2
- package/lib/v2/providers/database.d.ts +3 -3
- package/lib/v2/providers/database.js +8 -2
- package/lib/v2/providers/eventarc.d.ts +2 -2
- package/lib/v2/providers/firestore.d.ts +91 -0
- package/lib/v2/providers/firestore.js +243 -0
- package/lib/v2/providers/https.d.ts +3 -3
- package/lib/v2/providers/identity.d.ts +2 -2
- package/lib/v2/providers/pubsub.d.ts +2 -2
- package/lib/v2/providers/remoteConfig.d.ts +2 -2
- package/lib/v2/providers/storage.d.ts +2 -2
- package/lib/v2/providers/tasks.d.ts +3 -3
- package/lib/v2/providers/testLab.d.ts +2 -2
- package/lib/v2/trace.d.ts +1 -1
- package/package.json +13 -6
- package/protos/README.md +15 -0
- package/protos/compiledFirestore.d.ts +1342 -0
- package/protos/compiledFirestore.js +3514 -0
- package/protos/update.sh +75 -0
package/lib/common/change.js
CHANGED
|
@@ -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;
|
package/lib/common/encoding.d.ts
CHANGED
|
@@ -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
|
|
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[];
|
package/lib/common/encoding.js
CHANGED
|
@@ -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.`);
|
package/lib/common/params.d.ts
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
*
|
|
4
4
|
* For example Split<"a/b/c", "/"> is ['a' | "b" | "c"]
|
|
5
5
|
*/
|
|
6
|
-
export
|
|
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
|
|
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
|
|
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
|
|
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
|
};
|
|
@@ -31,14 +31,9 @@ const path_1 = require("../../common/utilities/path");
|
|
|
31
31
|
class DataSnapshot {
|
|
32
32
|
constructor(data, path, // path is undefined for the database root
|
|
33
33
|
app, instance) {
|
|
34
|
-
var _a, _b;
|
|
35
34
|
this.app = app;
|
|
36
35
|
const config = (0, config_1.firebaseConfig)();
|
|
37
|
-
if (
|
|
38
|
-
// In this case we're dealing with an emulator
|
|
39
|
-
this.instance = app.options.databaseURL;
|
|
40
|
-
}
|
|
41
|
-
else if (instance) {
|
|
36
|
+
if (instance) {
|
|
42
37
|
// SDK always supplies instance, but user's unit tests may not
|
|
43
38
|
this.instance = instance;
|
|
44
39
|
}
|
|
@@ -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
|
|
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
|
|
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
|
-
|
|
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 {};
|
|
@@ -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.onCallHandler = exports.checkAuthToken = exports.unsafeDecodeAppCheckToken = exports.unsafeDecodeIdToken = exports.unsafeDecodeToken = exports.decode = exports.encode = exports.isValidRequest = exports.HttpsError = void 0;
|
|
24
|
+
exports.onCallHandler = exports.checkAuthToken = exports.unsafeDecodeAppCheckToken = exports.unsafeDecodeIdToken = exports.unsafeDecodeToken = exports.decode = exports.encode = exports.isValidRequest = exports.HttpsError = exports.ORIGINAL_AUTH_HEADER = exports.CALLABLE_AUTH_HEADER = void 0;
|
|
25
25
|
const cors = require("cors");
|
|
26
26
|
const logger = require("../../logger");
|
|
27
27
|
// TODO(inlined): Decide whether we want to un-version apps or whether we want a
|
|
@@ -31,6 +31,10 @@ const auth_1 = require("firebase-admin/auth");
|
|
|
31
31
|
const app_1 = require("../app");
|
|
32
32
|
const debug_1 = require("../debug");
|
|
33
33
|
const JWT_REGEX = /^[a-zA-Z0-9\-_=]+?\.[a-zA-Z0-9\-_=]+?\.([a-zA-Z0-9\-_=]+)?$/;
|
|
34
|
+
/** @internal */
|
|
35
|
+
exports.CALLABLE_AUTH_HEADER = "x-callable-context-auth";
|
|
36
|
+
/** @internal */
|
|
37
|
+
exports.ORIGINAL_AUTH_HEADER = "x-original-auth";
|
|
34
38
|
/**
|
|
35
39
|
* Standard error codes and HTTP statuses for different ways a request can fail,
|
|
36
40
|
* as defined by:
|
|
@@ -382,6 +386,29 @@ function wrapOnCallHandler(options, handler) {
|
|
|
382
386
|
throw new HttpsError("invalid-argument", "Bad Request");
|
|
383
387
|
}
|
|
384
388
|
const context = { rawRequest: req };
|
|
389
|
+
// TODO(colerogers): yank this when we release a breaking change of the CLI that removes
|
|
390
|
+
// our monkey-patching code referenced below and increases the minimum supported SDK version.
|
|
391
|
+
//
|
|
392
|
+
// Note: This code is needed to fix v1 callable functions in the emulator with a monorepo setup.
|
|
393
|
+
// The original monkey-patched code lived in the functionsEmulatorRuntime
|
|
394
|
+
// (link: https://github.com/firebase/firebase-tools/blob/accea7abda3cc9fa6bb91368e4895faf95281c60/src/emulator/functionsEmulatorRuntime.ts#L480)
|
|
395
|
+
// and was not compatible with how monorepos separate out packages (see https://github.com/firebase/firebase-tools/issues/5210).
|
|
396
|
+
if ((0, debug_1.isDebugFeatureEnabled)("skipTokenVerification") && handler.length === 2) {
|
|
397
|
+
const authContext = context.rawRequest.header(exports.CALLABLE_AUTH_HEADER);
|
|
398
|
+
if (authContext) {
|
|
399
|
+
logger.debug("Callable functions auth override", {
|
|
400
|
+
key: exports.CALLABLE_AUTH_HEADER,
|
|
401
|
+
value: authContext,
|
|
402
|
+
});
|
|
403
|
+
context.auth = JSON.parse(decodeURIComponent(authContext));
|
|
404
|
+
delete context.rawRequest.headers[exports.CALLABLE_AUTH_HEADER];
|
|
405
|
+
}
|
|
406
|
+
const originalAuth = context.rawRequest.header(exports.ORIGINAL_AUTH_HEADER);
|
|
407
|
+
if (originalAuth) {
|
|
408
|
+
context.rawRequest.headers["authorization"] = originalAuth;
|
|
409
|
+
delete context.rawRequest.headers[exports.ORIGINAL_AUTH_HEADER];
|
|
410
|
+
}
|
|
411
|
+
}
|
|
385
412
|
const tokenStatus = await checkTokens(req, context);
|
|
386
413
|
if (tokenStatus.auth === "INVALID") {
|
|
387
414
|
throw new HttpsError("unauthenticated", "Unauthenticated");
|
|
@@ -7,16 +7,16 @@ export { HttpsError };
|
|
|
7
7
|
* @hidden
|
|
8
8
|
* @alpha
|
|
9
9
|
*/
|
|
10
|
-
export
|
|
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
|
|
15
|
+
export type UserRecord = auth.UserRecord;
|
|
16
16
|
/**
|
|
17
17
|
* UserInfo that is part of the UserRecord
|
|
18
18
|
*/
|
|
19
|
-
export
|
|
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
|
|
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;
|
package/lib/common/timezone.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export declare const tzDatabase: Record<string, string>;
|
|
2
|
-
export
|
|
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
|
}
|
package/lib/logger/index.d.ts
CHANGED
|
@@ -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
|
|
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
|
package/lib/params/index.d.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
package/lib/params/types.d.ts
CHANGED
|
@@ -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
|
-
|
|
33
|
-
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
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
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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
|
*/
|
package/lib/v1/providers/auth.js
CHANGED
|
@@ -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
|
|
7
|
-
export
|
|
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
|
|
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
|
|
123
|
-
|
|
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
|
-
|
|
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) {
|