firebase-functions 3.15.4 → 3.16.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/apps.js +1 -1
- package/lib/cloud-functions.d.ts +3 -2
- package/lib/cloud-functions.js +6 -7
- package/lib/common/debug.d.ts +1 -0
- package/lib/common/debug.js +54 -0
- package/lib/common/encoding.js +7 -1
- package/lib/common/providers/https.d.ts +49 -43
- package/lib/common/providers/https.js +80 -17
- package/lib/function-configuration.d.ts +1 -1
- package/lib/handler-builder.js +2 -2
- package/lib/index.js +1 -1
- package/lib/logger/compat.js +1 -1
- package/lib/providers/analytics.js +1 -1
- package/lib/providers/auth.js +1 -1
- package/lib/providers/database.js +11 -11
- package/lib/providers/firestore.js +7 -7
- package/lib/providers/https.js +8 -3
- package/lib/providers/pubsub.js +2 -2
- package/lib/providers/remoteConfig.js +1 -1
- package/lib/providers/storage.js +2 -2
- package/lib/providers/testLab.js +1 -1
- package/lib/setup.js +3 -3
- package/lib/v2/index.d.ts +2 -1
- package/lib/v2/index.js +3 -1
- package/lib/v2/options.d.ts +1 -1
- package/lib/v2/options.js +7 -8
- package/lib/v2/providers/https.d.ts +1 -1
- package/lib/v2/providers/https.js +5 -2
- package/lib/v2/providers/storage.d.ts +170 -0
- package/lib/v2/providers/storage.js +110 -0
- package/package.json +9 -5
package/lib/apps.js
CHANGED
|
@@ -103,7 +103,7 @@ exports.apps = apps;
|
|
|
103
103
|
this._emulatedAdminApp = app;
|
|
104
104
|
}
|
|
105
105
|
get firebaseArgs() {
|
|
106
|
-
return _.assign({}, config_1.firebaseConfig(), {
|
|
106
|
+
return _.assign({}, (0, config_1.firebaseConfig)(), {
|
|
107
107
|
credential: firebase.credential.applicationDefault(),
|
|
108
108
|
});
|
|
109
109
|
}
|
package/lib/cloud-functions.d.ts
CHANGED
|
@@ -185,7 +185,9 @@ export interface TriggerAnnotated {
|
|
|
185
185
|
service: string;
|
|
186
186
|
};
|
|
187
187
|
failurePolicy?: FailurePolicy;
|
|
188
|
-
httpsTrigger?: {
|
|
188
|
+
httpsTrigger?: {
|
|
189
|
+
invoker?: string[];
|
|
190
|
+
};
|
|
189
191
|
labels?: {
|
|
190
192
|
[key: string]: string;
|
|
191
193
|
};
|
|
@@ -196,7 +198,6 @@ export interface TriggerAnnotated {
|
|
|
196
198
|
vpcConnectorEgressSettings?: string;
|
|
197
199
|
serviceAccountEmail?: string;
|
|
198
200
|
ingressSettings?: string;
|
|
199
|
-
invoker?: string[];
|
|
200
201
|
};
|
|
201
202
|
}
|
|
202
203
|
/**
|
package/lib/cloud-functions.js
CHANGED
|
@@ -135,7 +135,7 @@ function makeCloudFunction({ after = () => { }, before = () => { }, contextOnlyH
|
|
|
135
135
|
promise = handler(dataOrChange, context);
|
|
136
136
|
}
|
|
137
137
|
if (typeof promise === 'undefined') {
|
|
138
|
-
logger_1.warn('Function returned undefined, expected Promise or value');
|
|
138
|
+
(0, logger_1.warn)('Function returned undefined, expected Promise or value');
|
|
139
139
|
}
|
|
140
140
|
return Promise.resolve(promise)
|
|
141
141
|
.then((result) => {
|
|
@@ -216,8 +216,8 @@ function _detectAuthType(event) {
|
|
|
216
216
|
/** @hidden */
|
|
217
217
|
function optionsToTrigger(options) {
|
|
218
218
|
const trigger = {};
|
|
219
|
-
encoding_1.copyIfPresent(trigger, options, 'regions', 'schedule', 'minInstances', 'maxInstances', 'ingressSettings', 'vpcConnectorEgressSettings', 'vpcConnector', 'labels');
|
|
220
|
-
encoding_1.convertIfPresent(trigger, options, 'failurePolicy', 'failurePolicy', (policy) => {
|
|
219
|
+
(0, encoding_1.copyIfPresent)(trigger, options, 'regions', 'schedule', 'minInstances', 'maxInstances', 'ingressSettings', 'vpcConnectorEgressSettings', 'vpcConnector', 'labels');
|
|
220
|
+
(0, encoding_1.convertIfPresent)(trigger, options, 'failurePolicy', 'failurePolicy', (policy) => {
|
|
221
221
|
if (policy === false) {
|
|
222
222
|
return undefined;
|
|
223
223
|
}
|
|
@@ -228,8 +228,8 @@ function optionsToTrigger(options) {
|
|
|
228
228
|
return policy;
|
|
229
229
|
}
|
|
230
230
|
});
|
|
231
|
-
encoding_1.convertIfPresent(trigger, options, 'timeout', 'timeoutSeconds', encoding_1.durationFromSeconds);
|
|
232
|
-
encoding_1.convertIfPresent(trigger, options, 'availableMemoryMb', 'memory', (mem) => {
|
|
231
|
+
(0, encoding_1.convertIfPresent)(trigger, options, 'timeout', 'timeoutSeconds', encoding_1.durationFromSeconds);
|
|
232
|
+
(0, encoding_1.convertIfPresent)(trigger, options, 'availableMemoryMb', 'memory', (mem) => {
|
|
233
233
|
const memoryLookup = {
|
|
234
234
|
'128MB': 128,
|
|
235
235
|
'256MB': 256,
|
|
@@ -241,8 +241,7 @@ function optionsToTrigger(options) {
|
|
|
241
241
|
};
|
|
242
242
|
return memoryLookup[mem];
|
|
243
243
|
});
|
|
244
|
-
encoding_1.convertIfPresent(trigger, options, 'serviceAccountEmail', 'serviceAccount', encoding_1.serviceAccountFromShorthand);
|
|
245
|
-
encoding_1.convertIfPresent(trigger, options, 'invoker', 'invoker', encoding_1.convertInvoker);
|
|
244
|
+
(0, encoding_1.convertIfPresent)(trigger, options, 'serviceAccountEmail', 'serviceAccount', encoding_1.serviceAccountFromShorthand);
|
|
246
245
|
return trigger;
|
|
247
246
|
}
|
|
248
247
|
exports.optionsToTrigger = optionsToTrigger;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// The MIT License (MIT)
|
|
3
|
+
//
|
|
4
|
+
// Copyright (c) 2021 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.isDebugFeatureEnabled = exports.debugFeatureValue = void 0;
|
|
25
|
+
// Do NOT turn on a debug feature in production.
|
|
26
|
+
const debugMode = process.env.FIREBASE_DEBUG_MODE === 'true';
|
|
27
|
+
function loadDebugFeatures() {
|
|
28
|
+
if (!debugMode) {
|
|
29
|
+
return {};
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const obj = JSON.parse(process.env.FIREBASE_DEBUG_FEATURES);
|
|
33
|
+
if (typeof obj !== 'object') {
|
|
34
|
+
return {};
|
|
35
|
+
}
|
|
36
|
+
return obj;
|
|
37
|
+
}
|
|
38
|
+
catch (e) {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/* @internal */
|
|
43
|
+
function debugFeatureValue(feat) {
|
|
44
|
+
if (!debugMode) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
return loadDebugFeatures()[feat];
|
|
48
|
+
}
|
|
49
|
+
exports.debugFeatureValue = debugFeatureValue;
|
|
50
|
+
/* @internal */
|
|
51
|
+
function isDebugFeatureEnabled(feat) {
|
|
52
|
+
return debugMode && !!debugFeatureValue(feat);
|
|
53
|
+
}
|
|
54
|
+
exports.isDebugFeatureEnabled = isDebugFeatureEnabled;
|
package/lib/common/encoding.js
CHANGED
|
@@ -52,9 +52,15 @@ function convertInvoker(invoker) {
|
|
|
52
52
|
if (typeof invoker === 'string') {
|
|
53
53
|
invoker = [invoker];
|
|
54
54
|
}
|
|
55
|
+
if (invoker.length === 0) {
|
|
56
|
+
throw new Error('Invalid option for invoker: Must be a non-empty array.');
|
|
57
|
+
}
|
|
58
|
+
if (invoker.find((inv) => inv.length === 0)) {
|
|
59
|
+
throw new Error('Invalid option for invoker: Must be a non-empty string.');
|
|
60
|
+
}
|
|
55
61
|
if (invoker.length > 1 &&
|
|
56
62
|
invoker.find((inv) => inv === 'public' || inv === 'private')) {
|
|
57
|
-
throw new Error("Invalid option for invoker
|
|
63
|
+
throw new Error("Invalid option for invoker: Cannot have 'public' or 'private' in an array of service accounts.");
|
|
58
64
|
}
|
|
59
65
|
return invoker;
|
|
60
66
|
}
|
|
@@ -6,53 +6,54 @@ import * as firebase from 'firebase-admin';
|
|
|
6
6
|
export interface Request extends express.Request {
|
|
7
7
|
rawBody: Buffer;
|
|
8
8
|
}
|
|
9
|
+
interface DecodedAppCheckToken {
|
|
10
|
+
/**
|
|
11
|
+
* The issuer identifier for the issuer of the response.
|
|
12
|
+
*
|
|
13
|
+
* This value is a URL with the format
|
|
14
|
+
* `https://firebaseappcheck.googleapis.com/<PROJECT_NUMBER>`, where `<PROJECT_NUMBER>` is the
|
|
15
|
+
* same project number specified in the [`aud`](#aud) property.
|
|
16
|
+
*/
|
|
17
|
+
iss: string;
|
|
18
|
+
/**
|
|
19
|
+
* The Firebase App ID corresponding to the app the token belonged to.
|
|
20
|
+
*
|
|
21
|
+
* As a convenience, this value is copied over to the [`app_id`](#app_id) property.
|
|
22
|
+
*/
|
|
23
|
+
sub: string;
|
|
24
|
+
/**
|
|
25
|
+
* The audience for which this token is intended.
|
|
26
|
+
*
|
|
27
|
+
* This value is a JSON array of two strings, the first is the project number of your
|
|
28
|
+
* Firebase project, and the second is the project ID of the same project.
|
|
29
|
+
*/
|
|
30
|
+
aud: string[];
|
|
31
|
+
/**
|
|
32
|
+
* The App Check token's expiration time, in seconds since the Unix epoch. That is, the
|
|
33
|
+
* time at which this App Check token expires and should no longer be considered valid.
|
|
34
|
+
*/
|
|
35
|
+
exp: number;
|
|
36
|
+
/**
|
|
37
|
+
* The App Check token's issued-at time, in seconds since the Unix epoch. That is, the
|
|
38
|
+
* time at which this App Check token was issued and should start to be considered
|
|
39
|
+
* valid.;
|
|
40
|
+
*/
|
|
41
|
+
iat: number;
|
|
42
|
+
/**
|
|
43
|
+
* The App ID corresponding to the App the App Check token belonged to.
|
|
44
|
+
*
|
|
45
|
+
* This value is not actually one of the JWT token claims. It is added as a
|
|
46
|
+
* convenience, and is set as the value of the [`sub`](#sub) property.
|
|
47
|
+
*/
|
|
48
|
+
app_id: string;
|
|
49
|
+
[key: string]: any;
|
|
50
|
+
}
|
|
9
51
|
/**
|
|
10
52
|
* The interface for AppCheck tokens verified in Callable functions
|
|
11
53
|
*/
|
|
12
54
|
export interface AppCheckData {
|
|
13
55
|
appId: string;
|
|
14
|
-
token:
|
|
15
|
-
/**
|
|
16
|
-
* The issuer identifier for the issuer of the response.
|
|
17
|
-
*
|
|
18
|
-
* This value is a URL with the format
|
|
19
|
-
* `https://firebaseappcheck.googleapis.com/<PROJECT_NUMBER>`, where `<PROJECT_NUMBER>` is the
|
|
20
|
-
* same project number specified in the [`aud`](#aud) property.
|
|
21
|
-
*/
|
|
22
|
-
iss: string;
|
|
23
|
-
/**
|
|
24
|
-
* The Firebase App ID corresponding to the app the token belonged to.
|
|
25
|
-
*
|
|
26
|
-
* As a convenience, this value is copied over to the [`app_id`](#app_id) property.
|
|
27
|
-
*/
|
|
28
|
-
sub: string;
|
|
29
|
-
/**
|
|
30
|
-
* The audience for which this token is intended.
|
|
31
|
-
*
|
|
32
|
-
* This value is a JSON array of two strings, the first is the project number of your
|
|
33
|
-
* Firebase project, and the second is the project ID of the same project.
|
|
34
|
-
*/
|
|
35
|
-
aud: string[];
|
|
36
|
-
/**
|
|
37
|
-
* The App Check token's expiration time, in seconds since the Unix epoch. That is, the
|
|
38
|
-
* time at which this App Check token expires and should no longer be considered valid.
|
|
39
|
-
*/
|
|
40
|
-
exp: number;
|
|
41
|
-
/**
|
|
42
|
-
* The App Check token's issued-at time, in seconds since the Unix epoch. That is, the
|
|
43
|
-
* time at which this App Check token was issued and should start to be considered
|
|
44
|
-
* valid.
|
|
45
|
-
*/
|
|
46
|
-
iat: number;
|
|
47
|
-
/**
|
|
48
|
-
* The App ID corresponding to the App the App Check token belonged to.
|
|
49
|
-
*
|
|
50
|
-
* This value is not actually one of the JWT token claims. It is added as a
|
|
51
|
-
* convenience, and is set as the value of the [`sub`](#sub) property.
|
|
52
|
-
*/
|
|
53
|
-
app_id: string;
|
|
54
|
-
[key: string]: any;
|
|
55
|
-
};
|
|
56
|
+
token: DecodedAppCheckToken;
|
|
56
57
|
}
|
|
57
58
|
/**
|
|
58
59
|
* The interface for Auth tokens verified in Callable functions
|
|
@@ -197,6 +198,11 @@ export declare function encode(data: any): any;
|
|
|
197
198
|
export declare function decode(data: any): any;
|
|
198
199
|
declare type v1Handler = (data: any, context: CallableContext) => any | Promise<any>;
|
|
199
200
|
declare type v2Handler<Req, Res> = (request: CallableRequest<Req>) => Res;
|
|
201
|
+
/** @hidden **/
|
|
202
|
+
export interface CallableOptions {
|
|
203
|
+
cors: cors.CorsOptions;
|
|
204
|
+
allowInvalidAppCheckToken?: boolean;
|
|
205
|
+
}
|
|
200
206
|
/** @hidden */
|
|
201
|
-
export declare function onCallHandler<Req = any, Res = any>(options:
|
|
207
|
+
export declare function onCallHandler<Req = any, Res = any>(options: CallableOptions, handler: v1Handler | v2Handler<Req, Res>): (req: Request, res: express.Response) => Promise<void>;
|
|
202
208
|
export {};
|
|
@@ -21,12 +21,14 @@
|
|
|
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.decode = exports.encode = exports.HttpsError = void 0;
|
|
24
|
+
exports.onCallHandler = exports.unsafeDecodeAppCheckToken = exports.unsafeDecodeIdToken = exports.decode = exports.encode = exports.HttpsError = 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
|
|
28
28
|
// different strategy
|
|
29
29
|
const apps_1 = require("../../apps");
|
|
30
|
+
const debug_1 = require("../../common/debug");
|
|
31
|
+
const JWT_REGEX = /^[a-zA-Z0-9\-_=]+?\.[a-zA-Z0-9\-_=]+?\.([a-zA-Z0-9\-_=]+)?$/;
|
|
30
32
|
/**
|
|
31
33
|
* Standard error codes and HTTP statuses for different ways a request can fail,
|
|
32
34
|
* as defined by:
|
|
@@ -148,7 +150,7 @@ function encode(data) {
|
|
|
148
150
|
if (Array.isArray(data)) {
|
|
149
151
|
return data.map(encode);
|
|
150
152
|
}
|
|
151
|
-
if (typeof data === 'object') {
|
|
153
|
+
if (typeof data === 'object' || typeof data === 'function') {
|
|
152
154
|
// Sadly we don't have Object.fromEntries in Node 10, so we can't use a single
|
|
153
155
|
// list comprehension
|
|
154
156
|
const obj = {};
|
|
@@ -206,6 +208,53 @@ function decode(data) {
|
|
|
206
208
|
return data;
|
|
207
209
|
}
|
|
208
210
|
exports.decode = decode;
|
|
211
|
+
function unsafeDecodeToken(token) {
|
|
212
|
+
if (!JWT_REGEX.test(token)) {
|
|
213
|
+
return {};
|
|
214
|
+
}
|
|
215
|
+
const components = token
|
|
216
|
+
.split('.')
|
|
217
|
+
.map((s) => Buffer.from(s, 'base64').toString());
|
|
218
|
+
let payload = components[1];
|
|
219
|
+
if (typeof payload === 'string') {
|
|
220
|
+
try {
|
|
221
|
+
const obj = JSON.parse(payload);
|
|
222
|
+
if (typeof obj === 'object') {
|
|
223
|
+
payload = obj;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch (e) { }
|
|
227
|
+
}
|
|
228
|
+
return payload;
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Decode, but not verify, a Auth ID token.
|
|
232
|
+
*
|
|
233
|
+
* Do not use in production. Token should always be verified using the Admin SDK.
|
|
234
|
+
*
|
|
235
|
+
* This is exposed only for testing.
|
|
236
|
+
*/
|
|
237
|
+
/** @internal */
|
|
238
|
+
function unsafeDecodeIdToken(token) {
|
|
239
|
+
const decoded = unsafeDecodeToken(token);
|
|
240
|
+
decoded.uid = decoded.sub;
|
|
241
|
+
return decoded;
|
|
242
|
+
}
|
|
243
|
+
exports.unsafeDecodeIdToken = unsafeDecodeIdToken;
|
|
244
|
+
/**
|
|
245
|
+
* Decode, but not verify, an App Check token.
|
|
246
|
+
*
|
|
247
|
+
* Do not use in production. Token should always be verified using the Admin SDK.
|
|
248
|
+
*
|
|
249
|
+
* This is exposed only for testing.
|
|
250
|
+
*/
|
|
251
|
+
/** @internal */
|
|
252
|
+
function unsafeDecodeAppCheckToken(token) {
|
|
253
|
+
const decoded = unsafeDecodeToken(token);
|
|
254
|
+
decoded.app_id = decoded.sub;
|
|
255
|
+
return decoded;
|
|
256
|
+
}
|
|
257
|
+
exports.unsafeDecodeAppCheckToken = unsafeDecodeAppCheckToken;
|
|
209
258
|
/**
|
|
210
259
|
* Check and verify tokens included in the requests. Once verified, tokens
|
|
211
260
|
* are injected into the callable context.
|
|
@@ -220,20 +269,25 @@ async function checkTokens(req, ctx) {
|
|
|
220
269
|
app: 'MISSING',
|
|
221
270
|
auth: 'MISSING',
|
|
222
271
|
};
|
|
272
|
+
const skipTokenVerify = (0, debug_1.isDebugFeatureEnabled)('skipTokenVerification');
|
|
223
273
|
const appCheck = req.header('X-Firebase-AppCheck');
|
|
224
274
|
if (appCheck) {
|
|
225
275
|
verifications.app = 'INVALID';
|
|
226
276
|
try {
|
|
227
|
-
if (!apps_1.apps().admin.appCheck) {
|
|
277
|
+
if (!(0, apps_1.apps)().admin.appCheck) {
|
|
228
278
|
throw new Error('Cannot validate AppCheck token. Please update Firebase Admin SDK to >= v9.8.0');
|
|
229
279
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
280
|
+
let appCheckData;
|
|
281
|
+
if (skipTokenVerify) {
|
|
282
|
+
const decodedToken = unsafeDecodeAppCheckToken(appCheck);
|
|
283
|
+
appCheckData = { appId: decodedToken.app_id, token: decodedToken };
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
appCheckData = await (0, apps_1.apps)()
|
|
287
|
+
.admin.appCheck()
|
|
288
|
+
.verifyToken(appCheck);
|
|
289
|
+
}
|
|
290
|
+
ctx.app = appCheckData;
|
|
237
291
|
verifications.app = 'VALID';
|
|
238
292
|
}
|
|
239
293
|
catch (err) {
|
|
@@ -247,9 +301,15 @@ async function checkTokens(req, ctx) {
|
|
|
247
301
|
if (match) {
|
|
248
302
|
const idToken = match[1];
|
|
249
303
|
try {
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
304
|
+
let authToken;
|
|
305
|
+
if (skipTokenVerify) {
|
|
306
|
+
authToken = unsafeDecodeIdToken(idToken);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
authToken = await (0, apps_1.apps)()
|
|
310
|
+
.admin.auth()
|
|
311
|
+
.verifyIdToken(idToken);
|
|
312
|
+
}
|
|
253
313
|
verifications.auth = 'VALID';
|
|
254
314
|
ctx.auth = {
|
|
255
315
|
uid: authToken.uid,
|
|
@@ -284,11 +344,11 @@ async function checkTokens(req, ctx) {
|
|
|
284
344
|
}
|
|
285
345
|
/** @hidden */
|
|
286
346
|
function onCallHandler(options, handler) {
|
|
287
|
-
const wrapped = wrapOnCallHandler(handler);
|
|
347
|
+
const wrapped = wrapOnCallHandler(options, handler);
|
|
288
348
|
return (req, res) => {
|
|
289
349
|
return new Promise((resolve) => {
|
|
290
350
|
res.on('finish', resolve);
|
|
291
|
-
cors(options)(req, res, () => {
|
|
351
|
+
cors(options.cors)(req, res, () => {
|
|
292
352
|
resolve(wrapped(req, res));
|
|
293
353
|
});
|
|
294
354
|
});
|
|
@@ -296,7 +356,7 @@ function onCallHandler(options, handler) {
|
|
|
296
356
|
}
|
|
297
357
|
exports.onCallHandler = onCallHandler;
|
|
298
358
|
/** @internal */
|
|
299
|
-
function wrapOnCallHandler(handler) {
|
|
359
|
+
function wrapOnCallHandler(options, handler) {
|
|
300
360
|
return async (req, res) => {
|
|
301
361
|
try {
|
|
302
362
|
if (!isValidRequest(req)) {
|
|
@@ -305,7 +365,10 @@ function wrapOnCallHandler(handler) {
|
|
|
305
365
|
}
|
|
306
366
|
const context = { rawRequest: req };
|
|
307
367
|
const tokenStatus = await checkTokens(req, context);
|
|
308
|
-
if (tokenStatus.
|
|
368
|
+
if (tokenStatus.auth === 'INVALID') {
|
|
369
|
+
throw new HttpsError('unauthenticated', 'Unauthenticated');
|
|
370
|
+
}
|
|
371
|
+
if (tokenStatus.app === 'INVALID' && !options.allowInvalidAppCheckToken) {
|
|
309
372
|
throw new HttpsError('unauthenticated', 'Unauthenticated');
|
|
310
373
|
}
|
|
311
374
|
const instanceId = req.header('Firebase-Instance-ID-Token');
|
|
@@ -68,7 +68,6 @@ export interface RuntimeOptions {
|
|
|
68
68
|
* Min number of actual instances to be running at a given time.
|
|
69
69
|
* Instances will be billed for memory allocation and 10% of CPU allocation
|
|
70
70
|
* while idle.
|
|
71
|
-
* @hidden
|
|
72
71
|
*/
|
|
73
72
|
minInstances?: number;
|
|
74
73
|
/**
|
|
@@ -99,6 +98,7 @@ export interface RuntimeOptions {
|
|
|
99
98
|
* Invoker to set access control on https functions.
|
|
100
99
|
*/
|
|
101
100
|
invoker?: 'public' | 'private' | string | string[];
|
|
101
|
+
allowInvalidAppCheckToken?: boolean;
|
|
102
102
|
}
|
|
103
103
|
export interface DeploymentOptions extends RuntimeOptions {
|
|
104
104
|
regions?: Array<typeof SUPPORTED_REGIONS[number] | string>;
|
package/lib/handler-builder.js
CHANGED
|
@@ -111,12 +111,12 @@ class HandlerBuilder {
|
|
|
111
111
|
get instance() {
|
|
112
112
|
return {
|
|
113
113
|
get ref() {
|
|
114
|
-
return new database.RefBuilder(apps_1.apps(), () => null, {});
|
|
114
|
+
return new database.RefBuilder((0, apps_1.apps)(), () => null, {});
|
|
115
115
|
},
|
|
116
116
|
};
|
|
117
117
|
},
|
|
118
118
|
get ref() {
|
|
119
|
-
return new database.RefBuilder(apps_1.apps(), () => null, {});
|
|
119
|
+
return new database.RefBuilder((0, apps_1.apps)(), () => null, {});
|
|
120
120
|
},
|
|
121
121
|
};
|
|
122
122
|
}
|
package/lib/index.js
CHANGED
package/lib/logger/compat.js
CHANGED
|
@@ -6,7 +6,7 @@ const common_1 = require("./common");
|
|
|
6
6
|
function patchedConsole(severity) {
|
|
7
7
|
return function (data, ...args) {
|
|
8
8
|
if (common_1.SUPPORTS_STRUCTURED_LOGS) {
|
|
9
|
-
common_1.UNPATCHED_CONSOLE[common_1.CONSOLE_SEVERITY[severity]](JSON.stringify({ severity, message: util_1.format(data, ...args) }));
|
|
9
|
+
common_1.UNPATCHED_CONSOLE[common_1.CONSOLE_SEVERITY[severity]](JSON.stringify({ severity, message: (0, util_1.format)(data, ...args) }));
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
12
|
common_1.UNPATCHED_CONSOLE[common_1.CONSOLE_SEVERITY[severity]](data, ...args);
|
|
@@ -73,7 +73,7 @@ class AnalyticsEventBuilder {
|
|
|
73
73
|
const dataConstructor = (raw) => {
|
|
74
74
|
return new AnalyticsEvent(raw.data);
|
|
75
75
|
};
|
|
76
|
-
return cloud_functions_1.makeCloudFunction({
|
|
76
|
+
return (0, cloud_functions_1.makeCloudFunction)({
|
|
77
77
|
handler,
|
|
78
78
|
provider: exports.provider,
|
|
79
79
|
eventType: 'event.log',
|
package/lib/providers/auth.js
CHANGED
|
@@ -78,7 +78,7 @@ class UserBuilder {
|
|
|
78
78
|
return this.onOperation(handler, 'user.delete');
|
|
79
79
|
}
|
|
80
80
|
onOperation(handler, eventType) {
|
|
81
|
-
return cloud_functions_1.makeCloudFunction({
|
|
81
|
+
return (0, cloud_functions_1.makeCloudFunction)({
|
|
82
82
|
handler,
|
|
83
83
|
provider: exports.provider,
|
|
84
84
|
eventType,
|
|
@@ -104,20 +104,20 @@ class InstanceBuilder {
|
|
|
104
104
|
* @return Firebase Realtime Database reference builder interface.
|
|
105
105
|
*/
|
|
106
106
|
ref(path) {
|
|
107
|
-
const normalized = path_1.normalizePath(path);
|
|
108
|
-
return new RefBuilder(apps_1.apps(), () => `projects/_/instances/${this.instance}/refs/${normalized}`, this.options);
|
|
107
|
+
const normalized = (0, path_1.normalizePath)(path);
|
|
108
|
+
return new RefBuilder((0, apps_1.apps)(), () => `projects/_/instances/${this.instance}/refs/${normalized}`, this.options);
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
exports.InstanceBuilder = InstanceBuilder;
|
|
112
112
|
/** @hidden */
|
|
113
113
|
function _refWithOptions(path, options) {
|
|
114
114
|
const resourceGetter = () => {
|
|
115
|
-
const normalized = path_1.normalizePath(path);
|
|
116
|
-
const databaseURL = config_1.firebaseConfig().databaseURL;
|
|
115
|
+
const normalized = (0, path_1.normalizePath)(path);
|
|
116
|
+
const databaseURL = (0, config_1.firebaseConfig)().databaseURL;
|
|
117
117
|
if (!databaseURL) {
|
|
118
118
|
throw new Error('Missing expected firebase config value databaseURL, ' +
|
|
119
119
|
'config is actually' +
|
|
120
|
-
JSON.stringify(config_1.firebaseConfig()) +
|
|
120
|
+
JSON.stringify((0, config_1.firebaseConfig)()) +
|
|
121
121
|
'\n If you are unit testing, please set process.env.FIREBASE_CONFIG');
|
|
122
122
|
}
|
|
123
123
|
let instance;
|
|
@@ -136,7 +136,7 @@ function _refWithOptions(path, options) {
|
|
|
136
136
|
}
|
|
137
137
|
return `projects/_/instances/${instance}/refs/${normalized}`;
|
|
138
138
|
};
|
|
139
|
-
return new RefBuilder(apps_1.apps(), resourceGetter, options);
|
|
139
|
+
return new RefBuilder((0, apps_1.apps)(), resourceGetter, options);
|
|
140
140
|
}
|
|
141
141
|
exports._refWithOptions = _refWithOptions;
|
|
142
142
|
/**
|
|
@@ -153,7 +153,7 @@ class RefBuilder {
|
|
|
153
153
|
this.changeConstructor = (raw) => {
|
|
154
154
|
const [dbInstance, path] = extractInstanceAndPath(raw.context.resource.name, raw.context.domain);
|
|
155
155
|
const before = new DataSnapshot(raw.data.data, path, this.apps.admin, dbInstance);
|
|
156
|
-
const after = new DataSnapshot(utils_1.applyChange(raw.data.data, raw.data.delta), path, this.apps.admin, dbInstance);
|
|
156
|
+
const after = new DataSnapshot((0, utils_1.applyChange)(raw.data.data, raw.data.delta), path, this.apps.admin, dbInstance);
|
|
157
157
|
return {
|
|
158
158
|
before,
|
|
159
159
|
after,
|
|
@@ -214,7 +214,7 @@ class RefBuilder {
|
|
|
214
214
|
return this.onOperation(handler, 'ref.delete', dataConstructor);
|
|
215
215
|
}
|
|
216
216
|
onOperation(handler, eventType, dataConstructor) {
|
|
217
|
-
return cloud_functions_1.makeCloudFunction({
|
|
217
|
+
return (0, cloud_functions_1.makeCloudFunction)({
|
|
218
218
|
handler,
|
|
219
219
|
provider: exports.provider,
|
|
220
220
|
service: exports.service,
|
|
@@ -310,7 +310,7 @@ class DataSnapshot {
|
|
|
310
310
|
* However, accessing the key on the root URL of a Database will return `null`.
|
|
311
311
|
*/
|
|
312
312
|
get key() {
|
|
313
|
-
const last = _.last(path_1.pathParts(this._fullPath()));
|
|
313
|
+
const last = _.last((0, path_1.pathParts)(this._fullPath()));
|
|
314
314
|
return !last || last === '' ? null : last;
|
|
315
315
|
}
|
|
316
316
|
/**
|
|
@@ -325,7 +325,7 @@ class DataSnapshot {
|
|
|
325
325
|
* Array, string, number, boolean, or `null`).
|
|
326
326
|
*/
|
|
327
327
|
val() {
|
|
328
|
-
const parts = path_1.pathParts(this._childPath);
|
|
328
|
+
const parts = (0, path_1.pathParts)(this._childPath);
|
|
329
329
|
const source = this._data;
|
|
330
330
|
const node = _.cloneDeep(parts.length ? _.get(source, parts, null) : source);
|
|
331
331
|
return this._checkAndConvertToArray(node);
|
|
@@ -493,7 +493,7 @@ class DataSnapshot {
|
|
|
493
493
|
const dup = new DataSnapshot(this._data, undefined, this.app, this.instance);
|
|
494
494
|
[dup._path, dup._childPath] = [this._path, this._childPath];
|
|
495
495
|
if (childPath) {
|
|
496
|
-
dup._childPath = path_1.joinPath(dup._childPath, childPath);
|
|
496
|
+
dup._childPath = (0, path_1.joinPath)(dup._childPath, childPath);
|
|
497
497
|
}
|
|
498
498
|
return dup;
|
|
499
499
|
}
|
|
@@ -113,8 +113,8 @@ function _getValueProto(data, resource, valueFieldName) {
|
|
|
113
113
|
}
|
|
114
114
|
const proto = {
|
|
115
115
|
fields: _.get(data, [valueFieldName, 'fields'], {}),
|
|
116
|
-
createTime: encoder_1.dateToTimestampProto(_.get(data, [valueFieldName, 'createTime'])),
|
|
117
|
-
updateTime: encoder_1.dateToTimestampProto(_.get(data, [valueFieldName, 'updateTime'])),
|
|
116
|
+
createTime: (0, encoder_1.dateToTimestampProto)(_.get(data, [valueFieldName, 'createTime'])),
|
|
117
|
+
updateTime: (0, encoder_1.dateToTimestampProto)(_.get(data, [valueFieldName, 'updateTime'])),
|
|
118
118
|
name: _.get(data, [valueFieldName, 'name'], resource),
|
|
119
119
|
};
|
|
120
120
|
return proto;
|
|
@@ -123,7 +123,7 @@ function _getValueProto(data, resource, valueFieldName) {
|
|
|
123
123
|
function snapshotConstructor(event) {
|
|
124
124
|
var _a;
|
|
125
125
|
if (!firestoreInstance) {
|
|
126
|
-
firestoreInstance = firebase.firestore(apps_1.apps().admin);
|
|
126
|
+
firestoreInstance = firebase.firestore((0, apps_1.apps)().admin);
|
|
127
127
|
}
|
|
128
128
|
const valueProto = _getValueProto(event.data, event.context.resource.name, 'value');
|
|
129
129
|
let timeString = (_a = _.get(event, 'data.value.readTime')) !== null && _a !== void 0 ? _a : _.get(event, 'data.value.updateTime');
|
|
@@ -131,7 +131,7 @@ function snapshotConstructor(event) {
|
|
|
131
131
|
logger.warn('Snapshot has no readTime. Using now()');
|
|
132
132
|
timeString = new Date().toISOString();
|
|
133
133
|
}
|
|
134
|
-
const readTime = encoder_1.dateToTimestampProto(timeString);
|
|
134
|
+
const readTime = (0, encoder_1.dateToTimestampProto)(timeString);
|
|
135
135
|
return firestoreInstance.snapshot_(valueProto, readTime, 'json');
|
|
136
136
|
}
|
|
137
137
|
exports.snapshotConstructor = snapshotConstructor;
|
|
@@ -139,10 +139,10 @@ exports.snapshotConstructor = snapshotConstructor;
|
|
|
139
139
|
// TODO remove this function when wire format changes to new format
|
|
140
140
|
function beforeSnapshotConstructor(event) {
|
|
141
141
|
if (!firestoreInstance) {
|
|
142
|
-
firestoreInstance = firebase.firestore(apps_1.apps().admin);
|
|
142
|
+
firestoreInstance = firebase.firestore((0, apps_1.apps)().admin);
|
|
143
143
|
}
|
|
144
144
|
const oldValueProto = _getValueProto(event.data, event.context.resource.name, 'oldValue');
|
|
145
|
-
const oldReadTime = encoder_1.dateToTimestampProto(_.get(event, 'data.oldValue.readTime'));
|
|
145
|
+
const oldReadTime = (0, encoder_1.dateToTimestampProto)(_.get(event, 'data.oldValue.readTime'));
|
|
146
146
|
return firestoreInstance.snapshot_(oldValueProto, oldReadTime, 'json');
|
|
147
147
|
}
|
|
148
148
|
exports.beforeSnapshotConstructor = beforeSnapshotConstructor;
|
|
@@ -173,7 +173,7 @@ class DocumentBuilder {
|
|
|
173
173
|
return this.onOperation(handler, 'document.delete', beforeSnapshotConstructor);
|
|
174
174
|
}
|
|
175
175
|
onOperation(handler, eventType, dataConstructor) {
|
|
176
|
-
return cloud_functions_1.makeCloudFunction({
|
|
176
|
+
return (0, cloud_functions_1.makeCloudFunction)({
|
|
177
177
|
handler,
|
|
178
178
|
provider: exports.provider,
|
|
179
179
|
eventType,
|
package/lib/providers/https.js
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
24
|
exports._onCallWithOptions = exports._onRequestWithOptions = exports.onCall = exports.onRequest = exports.HttpsError = void 0;
|
|
25
25
|
const cloud_functions_1 = require("../cloud-functions");
|
|
26
|
+
const encoding_1 = require("../common/encoding");
|
|
26
27
|
const https_1 = require("../common/providers/https");
|
|
27
28
|
Object.defineProperty(exports, "HttpsError", { enumerable: true, get: function () { return https_1.HttpsError; } });
|
|
28
29
|
/**
|
|
@@ -49,9 +50,10 @@ function _onRequestWithOptions(handler, options) {
|
|
|
49
50
|
return handler(req, res);
|
|
50
51
|
};
|
|
51
52
|
cloudFunction.__trigger = {
|
|
52
|
-
...cloud_functions_1.optionsToTrigger(options),
|
|
53
|
+
...(0, cloud_functions_1.optionsToTrigger)(options),
|
|
53
54
|
httpsTrigger: {},
|
|
54
55
|
};
|
|
56
|
+
(0, encoding_1.convertIfPresent)(cloudFunction.__trigger.httpsTrigger, options, 'invoker', 'invoker', encoding_1.convertInvoker);
|
|
55
57
|
// TODO parse the options
|
|
56
58
|
return cloudFunction;
|
|
57
59
|
}
|
|
@@ -62,10 +64,13 @@ function _onCallWithOptions(handler, options) {
|
|
|
62
64
|
// and the user could have only tried to listen to data. Wrap their handler
|
|
63
65
|
// in another handler to avoid accidentally triggering the v2 API
|
|
64
66
|
const fixedLen = (data, context) => handler(data, context);
|
|
65
|
-
const func = https_1.onCallHandler({
|
|
67
|
+
const func = (0, https_1.onCallHandler)({
|
|
68
|
+
allowInvalidAppCheckToken: options.allowInvalidAppCheckToken,
|
|
69
|
+
cors: { origin: true, methods: 'POST' },
|
|
70
|
+
}, fixedLen);
|
|
66
71
|
func.__trigger = {
|
|
67
72
|
labels: {},
|
|
68
|
-
...cloud_functions_1.optionsToTrigger(options),
|
|
73
|
+
...(0, cloud_functions_1.optionsToTrigger)(options),
|
|
69
74
|
httpsTrigger: {},
|
|
70
75
|
};
|
|
71
76
|
func.__trigger.labels['deployment-callable'] = 'true';
|
package/lib/providers/pubsub.js
CHANGED
|
@@ -71,7 +71,7 @@ class TopicBuilder {
|
|
|
71
71
|
* @return A Cloud Function that you can export and deploy.
|
|
72
72
|
*/
|
|
73
73
|
onPublish(handler) {
|
|
74
|
-
return cloud_functions_1.makeCloudFunction({
|
|
74
|
+
return (0, cloud_functions_1.makeCloudFunction)({
|
|
75
75
|
handler,
|
|
76
76
|
provider: exports.provider,
|
|
77
77
|
service: exports.service,
|
|
@@ -140,7 +140,7 @@ class ScheduleBuilder {
|
|
|
140
140
|
* @return A Cloud Function that you can export and deploy.
|
|
141
141
|
*/
|
|
142
142
|
onRun(handler) {
|
|
143
|
-
const cloudFunction = cloud_functions_1.makeCloudFunction({
|
|
143
|
+
const cloudFunction = (0, cloud_functions_1.makeCloudFunction)({
|
|
144
144
|
contextOnlyHandler: handler,
|
|
145
145
|
provider: exports.provider,
|
|
146
146
|
service: exports.service,
|
|
@@ -65,7 +65,7 @@ class UpdateBuilder {
|
|
|
65
65
|
* version metadata as an argument.
|
|
66
66
|
*/
|
|
67
67
|
onUpdate(handler) {
|
|
68
|
-
return cloud_functions_1.makeCloudFunction({
|
|
68
|
+
return (0, cloud_functions_1.makeCloudFunction)({
|
|
69
69
|
handler,
|
|
70
70
|
provider: exports.provider,
|
|
71
71
|
service: exports.service,
|
package/lib/providers/storage.js
CHANGED
|
@@ -53,7 +53,7 @@ exports.object = object;
|
|
|
53
53
|
/** @hidden */
|
|
54
54
|
function _bucketWithOptions(options, bucket) {
|
|
55
55
|
const resourceGetter = () => {
|
|
56
|
-
bucket = bucket || config_1.firebaseConfig().storageBucket;
|
|
56
|
+
bucket = bucket || (0, config_1.firebaseConfig)().storageBucket;
|
|
57
57
|
if (!bucket) {
|
|
58
58
|
throw new Error('Missing bucket name. If you are unit testing, please provide a bucket name' +
|
|
59
59
|
' through `functions.storage.bucket(bucketName)`, or set process.env.FIREBASE_CONFIG.');
|
|
@@ -170,7 +170,7 @@ class ObjectBuilder {
|
|
|
170
170
|
}
|
|
171
171
|
/** @hidden */
|
|
172
172
|
onOperation(handler, eventType) {
|
|
173
|
-
return cloud_functions_1.makeCloudFunction({
|
|
173
|
+
return (0, cloud_functions_1.makeCloudFunction)({
|
|
174
174
|
handler,
|
|
175
175
|
provider: exports.provider,
|
|
176
176
|
service: exports.service,
|
package/lib/providers/testLab.js
CHANGED
|
@@ -57,7 +57,7 @@ class TestMatrixBuilder {
|
|
|
57
57
|
const dataConstructor = (raw) => {
|
|
58
58
|
return new TestMatrix(raw.data);
|
|
59
59
|
};
|
|
60
|
-
return cloud_functions_1.makeCloudFunction({
|
|
60
|
+
return (0, cloud_functions_1.makeCloudFunction)({
|
|
61
61
|
provider: exports.PROVIDER,
|
|
62
62
|
eventType: exports.TEST_MATRIX_COMPLETE_EVENT_TYPE,
|
|
63
63
|
triggerResource: this.triggerResource,
|
package/lib/setup.js
CHANGED
|
@@ -31,7 +31,7 @@ function setup() {
|
|
|
31
31
|
// Until the Cloud Functions builder can publish FIREBASE_CONFIG, automatically provide it on import based on what
|
|
32
32
|
// we can deduce.
|
|
33
33
|
if (!process.env.FIREBASE_CONFIG) {
|
|
34
|
-
const cfg = config_1.firebaseConfig();
|
|
34
|
+
const cfg = (0, config_1.firebaseConfig)();
|
|
35
35
|
if (cfg) {
|
|
36
36
|
process.env.FIREBASE_CONFIG = JSON.stringify(cfg);
|
|
37
37
|
}
|
|
@@ -43,7 +43,7 @@ function setup() {
|
|
|
43
43
|
// If FIREBASE_CONFIG is still not found, try using GCLOUD_PROJECT to estimate
|
|
44
44
|
if (!process.env.FIREBASE_CONFIG) {
|
|
45
45
|
if (process.env.GCLOUD_PROJECT) {
|
|
46
|
-
logger_1.warn('Warning, estimating Firebase Config based on GCLOUD_PROJECT. Initializing firebase-admin may fail');
|
|
46
|
+
(0, logger_1.warn)('Warning, estimating Firebase Config based on GCLOUD_PROJECT. Initializing firebase-admin may fail');
|
|
47
47
|
process.env.FIREBASE_CONFIG = JSON.stringify({
|
|
48
48
|
databaseURL: process.env.DATABASE_URL ||
|
|
49
49
|
`https://${process.env.GCLOUD_PROJECT}.firebaseio.com`,
|
|
@@ -53,7 +53,7 @@ function setup() {
|
|
|
53
53
|
});
|
|
54
54
|
}
|
|
55
55
|
else {
|
|
56
|
-
logger_1.warn('Warning, FIREBASE_CONFIG and GCLOUD_PROJECT environment variables are missing. Initializing firebase-admin will fail');
|
|
56
|
+
(0, logger_1.warn)('Warning, FIREBASE_CONFIG and GCLOUD_PROJECT environment variables are missing. Initializing firebase-admin will fail');
|
|
57
57
|
}
|
|
58
58
|
}
|
|
59
59
|
}
|
package/lib/v2/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import * as logger from '../logger';
|
|
|
2
2
|
import * as params from './params';
|
|
3
3
|
import * as https from './providers/https';
|
|
4
4
|
import * as pubsub from './providers/pubsub';
|
|
5
|
-
|
|
5
|
+
import * as storage from './providers/storage';
|
|
6
|
+
export { https, pubsub, storage, logger, params };
|
|
6
7
|
export { setGlobalOptions, GlobalOptions } from './options';
|
|
7
8
|
export { CloudFunction, CloudEvent } from './core';
|
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.setGlobalOptions = exports.params = exports.logger = exports.pubsub = exports.https = void 0;
|
|
24
|
+
exports.setGlobalOptions = exports.params = exports.logger = exports.storage = exports.pubsub = exports.https = void 0;
|
|
25
25
|
const logger = require("../logger");
|
|
26
26
|
exports.logger = logger;
|
|
27
27
|
const params = require("./params");
|
|
@@ -30,5 +30,7 @@ const https = require("./providers/https");
|
|
|
30
30
|
exports.https = https;
|
|
31
31
|
const pubsub = require("./providers/pubsub");
|
|
32
32
|
exports.pubsub = pubsub;
|
|
33
|
+
const storage = require("./providers/storage");
|
|
34
|
+
exports.storage = storage;
|
|
33
35
|
var options_1 = require("./options");
|
|
34
36
|
Object.defineProperty(exports, "setGlobalOptions", { enumerable: true, get: function () { return options_1.setGlobalOptions; } });
|
package/lib/v2/options.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { ParamSpec } from './params/types';
|
|
|
2
2
|
/**
|
|
3
3
|
* List of all regions supported by Cloud Functions v2
|
|
4
4
|
*/
|
|
5
|
-
export declare const SUPPORTED_REGIONS: readonly ["us-west1"];
|
|
5
|
+
export declare const SUPPORTED_REGIONS: readonly ["us-west1", "europe-west4"];
|
|
6
6
|
/**
|
|
7
7
|
* A region known to be supported by CloudFunctions v2
|
|
8
8
|
*/
|
package/lib/v2/options.js
CHANGED
|
@@ -29,7 +29,7 @@ const params_1 = require("./params");
|
|
|
29
29
|
/**
|
|
30
30
|
* List of all regions supported by Cloud Functions v2
|
|
31
31
|
*/
|
|
32
|
-
exports.SUPPORTED_REGIONS = ['us-west1'];
|
|
32
|
+
exports.SUPPORTED_REGIONS = ['us-west1', 'europe-west4'];
|
|
33
33
|
/**
|
|
34
34
|
* Cloud Functions v2 min timeout value.
|
|
35
35
|
*/
|
|
@@ -107,22 +107,21 @@ exports.getGlobalOptions = getGlobalOptions;
|
|
|
107
107
|
*/
|
|
108
108
|
function optionsToTriggerAnnotations(opts) {
|
|
109
109
|
const annotation = {};
|
|
110
|
-
encoding_2.copyIfPresent(annotation, opts, 'concurrency', 'minInstances', 'maxInstances', 'ingressSettings', 'labels', 'vpcConnector', 'vpcConnectorEgressSettings');
|
|
111
|
-
encoding_2.convertIfPresent(annotation, opts, 'availableMemoryMb', 'memory', (mem) => {
|
|
110
|
+
(0, encoding_2.copyIfPresent)(annotation, opts, 'concurrency', 'minInstances', 'maxInstances', 'ingressSettings', 'labels', 'vpcConnector', 'vpcConnectorEgressSettings');
|
|
111
|
+
(0, encoding_2.convertIfPresent)(annotation, opts, 'availableMemoryMb', 'memory', (mem) => {
|
|
112
112
|
return MemoryOptionToMB[mem];
|
|
113
113
|
});
|
|
114
|
-
encoding_2.convertIfPresent(annotation, opts, 'regions', 'region', (region) => {
|
|
114
|
+
(0, encoding_2.convertIfPresent)(annotation, opts, 'regions', 'region', (region) => {
|
|
115
115
|
if (typeof region === 'string') {
|
|
116
116
|
return [region];
|
|
117
117
|
}
|
|
118
118
|
return region;
|
|
119
119
|
});
|
|
120
|
-
encoding_2.convertIfPresent(annotation, opts, 'serviceAccountEmail', 'serviceAccount', encoding_1.serviceAccountFromShorthand);
|
|
121
|
-
encoding_2.convertIfPresent(annotation, opts, 'timeout', 'timeoutSeconds', encoding_1.durationFromSeconds);
|
|
122
|
-
encoding_2.convertIfPresent(annotation, opts, 'failurePolicy', 'retry', (retry) => {
|
|
120
|
+
(0, encoding_2.convertIfPresent)(annotation, opts, 'serviceAccountEmail', 'serviceAccount', encoding_1.serviceAccountFromShorthand);
|
|
121
|
+
(0, encoding_2.convertIfPresent)(annotation, opts, 'timeout', 'timeoutSeconds', encoding_1.durationFromSeconds);
|
|
122
|
+
(0, encoding_2.convertIfPresent)(annotation, opts, 'failurePolicy', 'retry', (retry) => {
|
|
123
123
|
return retry ? { retry: true } : null;
|
|
124
124
|
});
|
|
125
|
-
encoding_2.convertIfPresent(annotation, opts, 'invoker', 'invoker', encoding_1.convertInvoker);
|
|
126
125
|
return annotation;
|
|
127
126
|
}
|
|
128
127
|
exports.optionsToTriggerAnnotations = optionsToTriggerAnnotations;
|
|
@@ -4,7 +4,7 @@ import * as options from '../options';
|
|
|
4
4
|
export { Request, CallableRequest, FunctionsErrorCode, HttpsError };
|
|
5
5
|
export interface HttpsOptions extends Omit<options.GlobalOptions, 'region'> {
|
|
6
6
|
region?: options.SupportedRegion | string | Array<options.SupportedRegion | string>;
|
|
7
|
-
cors?: string | boolean
|
|
7
|
+
cors?: string | boolean | RegExp | Array<string | RegExp>;
|
|
8
8
|
}
|
|
9
9
|
export declare type HttpsFunction = ((req: Request, res: express.Response) => void | Promise<void>) & {
|
|
10
10
|
__trigger: unknown;
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
24
|
exports.onCall = exports.onRequest = exports.HttpsError = void 0;
|
|
25
25
|
const cors = require("cors");
|
|
26
|
+
const encoding_1 = require("../../common/encoding");
|
|
26
27
|
const https_1 = require("../../common/providers/https");
|
|
27
28
|
Object.defineProperty(exports, "HttpsError", { enumerable: true, get: function () { return https_1.HttpsError; } });
|
|
28
29
|
const options = require("../options");
|
|
@@ -52,7 +53,7 @@ function onRequest(optsOrHandler, handler) {
|
|
|
52
53
|
// global options calls region a scalar and https allows it to be an array,
|
|
53
54
|
// but optionsToTriggerAnnotations handles both cases.
|
|
54
55
|
const specificOpts = options.optionsToTriggerAnnotations(opts);
|
|
55
|
-
|
|
56
|
+
const trigger = {
|
|
56
57
|
// TODO(inlined): Remove "apiVersion" once the latest version of the CLI
|
|
57
58
|
// has migrated to "platform".
|
|
58
59
|
apiVersion: 2,
|
|
@@ -67,6 +68,8 @@ function onRequest(optsOrHandler, handler) {
|
|
|
67
68
|
allowInsecure: false,
|
|
68
69
|
},
|
|
69
70
|
};
|
|
71
|
+
(0, encoding_1.convertIfPresent)(trigger.httpsTrigger, opts, 'invoker', 'invoker', encoding_1.convertInvoker);
|
|
72
|
+
return trigger;
|
|
70
73
|
},
|
|
71
74
|
});
|
|
72
75
|
return handler;
|
|
@@ -85,7 +88,7 @@ function onCall(optsOrHandler, handler) {
|
|
|
85
88
|
// onCallHandler sniffs the function length to determine which API to present.
|
|
86
89
|
// fix the length to prevent api versions from being mismatched.
|
|
87
90
|
const fixedLen = (req) => handler(req);
|
|
88
|
-
const func = https_1.onCallHandler({ origin, methods: 'POST' }, fixedLen);
|
|
91
|
+
const func = (0, https_1.onCallHandler)({ cors: { origin, methods: 'POST' } }, fixedLen);
|
|
89
92
|
Object.defineProperty(func, '__trigger', {
|
|
90
93
|
get: () => {
|
|
91
94
|
const baseOpts = options.optionsToTriggerAnnotations(options.getGlobalOptions());
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { CloudEvent, CloudFunction } from '../core';
|
|
2
|
+
import * as options from '../options';
|
|
3
|
+
/**
|
|
4
|
+
* An object within Google Cloud Storage.
|
|
5
|
+
* Ref: https://github.com/googleapis/google-cloudevents-nodejs/blob/main/cloud/storage/v1/StorageObjectData.ts
|
|
6
|
+
*/
|
|
7
|
+
export interface StorageObjectData {
|
|
8
|
+
/**
|
|
9
|
+
* The name of the bucket containing this object.
|
|
10
|
+
*/
|
|
11
|
+
bucket?: string;
|
|
12
|
+
/**
|
|
13
|
+
* Cache-Control directive for the object data, matching
|
|
14
|
+
* [https://tools.ietf.org/html/rfc7234#section-5.2"][RFC 7234 §5.2].
|
|
15
|
+
*/
|
|
16
|
+
cacheControl?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Number of underlying components that make up this object. Components are
|
|
19
|
+
* accumulated by compose operations.
|
|
20
|
+
* Attempting to set this field will result in an error.
|
|
21
|
+
*/
|
|
22
|
+
componentCount?: number;
|
|
23
|
+
/**
|
|
24
|
+
* Content-Disposition of the object data, matching
|
|
25
|
+
* [https://tools.ietf.org/html/rfc6266][RFC 6266].
|
|
26
|
+
*/
|
|
27
|
+
contentDisposition?: string;
|
|
28
|
+
/**
|
|
29
|
+
* Content-Encoding of the object data, matching
|
|
30
|
+
* [https://tools.ietf.org/html/rfc7231#section-3.1.2.2][RFC 7231 §3.1.2.2]
|
|
31
|
+
*/
|
|
32
|
+
contentEncoding?: string;
|
|
33
|
+
/**
|
|
34
|
+
* Content-Language of the object data, matching
|
|
35
|
+
* [https://tools.ietf.org/html/rfc7231#section-3.1.3.2][RFC 7231 §3.1.3.2].
|
|
36
|
+
*/
|
|
37
|
+
contentLanguage?: string;
|
|
38
|
+
/**
|
|
39
|
+
* Content-Type of the object data, matching
|
|
40
|
+
* [https://tools.ietf.org/html/rfc7231#section-3.1.1.5][RFC 7231 §3.1.1.5].
|
|
41
|
+
* If an object is stored without a Content-Type, it is served as
|
|
42
|
+
* `application/octet-stream`.
|
|
43
|
+
*/
|
|
44
|
+
contentType?: string;
|
|
45
|
+
/**
|
|
46
|
+
* CRC32c checksum. For more information about using the CRC32c
|
|
47
|
+
* checksum, see
|
|
48
|
+
* [https://cloud.google.com/storage/docs/hashes-etags#_JSONAPI][Hashes and
|
|
49
|
+
* ETags: Best Practices].
|
|
50
|
+
*/
|
|
51
|
+
crc32c?: string;
|
|
52
|
+
/**
|
|
53
|
+
* Metadata of customer-supplied encryption key, if the object is encrypted by
|
|
54
|
+
* such a key.
|
|
55
|
+
*/
|
|
56
|
+
customerEncryption?: CustomerEncryption;
|
|
57
|
+
/**
|
|
58
|
+
* HTTP 1.1 Entity tag for the object. See
|
|
59
|
+
* [https://tools.ietf.org/html/rfc7232#section-2.3][RFC 7232 §2.3].
|
|
60
|
+
*/
|
|
61
|
+
etag?: string;
|
|
62
|
+
/**
|
|
63
|
+
* The content generation of this object. Used for object versioning.
|
|
64
|
+
* Attempting to set this field will result in an error.
|
|
65
|
+
*/
|
|
66
|
+
generation?: number;
|
|
67
|
+
/**
|
|
68
|
+
* The ID of the object, including the bucket name, object name, and
|
|
69
|
+
* generation number.
|
|
70
|
+
*/
|
|
71
|
+
id?: string;
|
|
72
|
+
/**
|
|
73
|
+
* The kind of item this is. For objects, this is always "storage#object".
|
|
74
|
+
*/
|
|
75
|
+
kind?: string;
|
|
76
|
+
/**
|
|
77
|
+
* MD5 hash of the data; encoded using base64 as per
|
|
78
|
+
* [https://tools.ietf.org/html/rfc4648#section-4][RFC 4648 §4]. For more
|
|
79
|
+
* information about using the MD5 hash, see
|
|
80
|
+
* [https://cloud.google.com/storage/docs/hashes-etags#_JSONAPI][Hashes and
|
|
81
|
+
* ETags: Best Practices].
|
|
82
|
+
*/
|
|
83
|
+
md5Hash?: string;
|
|
84
|
+
/**
|
|
85
|
+
* Media download link.
|
|
86
|
+
*/
|
|
87
|
+
mediaLink?: string;
|
|
88
|
+
/**
|
|
89
|
+
* User-provided metadata, in key/value pairs.
|
|
90
|
+
*/
|
|
91
|
+
metadata?: {
|
|
92
|
+
[key: string]: string;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* The version of the metadata for this object at this generation. Used for
|
|
96
|
+
* preconditions and for detecting changes in metadata. A metageneration
|
|
97
|
+
* number is only meaningful in the context of a particular generation of a
|
|
98
|
+
* particular object.
|
|
99
|
+
*/
|
|
100
|
+
metageneration?: number;
|
|
101
|
+
/**
|
|
102
|
+
* The name of the object.
|
|
103
|
+
*/
|
|
104
|
+
name?: string;
|
|
105
|
+
/**
|
|
106
|
+
* The link to this object.
|
|
107
|
+
*/
|
|
108
|
+
selfLink?: string;
|
|
109
|
+
/**
|
|
110
|
+
* Content-Length of the object data in bytes, matching
|
|
111
|
+
* [https://tools.ietf.org/html/rfc7230#section-3.3.2][RFC 7230 §3.3.2].
|
|
112
|
+
*/
|
|
113
|
+
size?: number;
|
|
114
|
+
/**
|
|
115
|
+
* Storage class of the object.
|
|
116
|
+
*/
|
|
117
|
+
storageClass?: string;
|
|
118
|
+
/**
|
|
119
|
+
* The creation time of the object.
|
|
120
|
+
* Attempting to set this field will result in an error.
|
|
121
|
+
*/
|
|
122
|
+
timeCreated?: Date | string;
|
|
123
|
+
/**
|
|
124
|
+
* The deletion time of the object. Will be returned if and only if this
|
|
125
|
+
* version of the object has been deleted.
|
|
126
|
+
*/
|
|
127
|
+
timeDeleted?: Date | string;
|
|
128
|
+
/**
|
|
129
|
+
* The time at which the object's storage class was last changed.
|
|
130
|
+
*/
|
|
131
|
+
timeStorageClassUpdated?: Date | string;
|
|
132
|
+
/**
|
|
133
|
+
* The modification time of the object metadata.
|
|
134
|
+
*/
|
|
135
|
+
updated?: Date | string;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Metadata of customer-supplied encryption key, if the object is encrypted by
|
|
139
|
+
* such a key.
|
|
140
|
+
*/
|
|
141
|
+
export interface CustomerEncryption {
|
|
142
|
+
/**
|
|
143
|
+
* The encryption algorithm.
|
|
144
|
+
*/
|
|
145
|
+
encryptionAlgorithm?: string;
|
|
146
|
+
/**
|
|
147
|
+
* SHA256 hash value of the encryption key.
|
|
148
|
+
*/
|
|
149
|
+
keySha256?: string;
|
|
150
|
+
}
|
|
151
|
+
/** StorageOptions extend EventHandlerOptions with a bucket name */
|
|
152
|
+
export interface StorageOptions extends options.EventHandlerOptions {
|
|
153
|
+
bucket?: string;
|
|
154
|
+
}
|
|
155
|
+
/** Handle a storage object archived */
|
|
156
|
+
export declare function onObjectArchived(handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>): CloudFunction<StorageObjectData>;
|
|
157
|
+
export declare function onObjectArchived(bucket: string, handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>): CloudFunction<StorageObjectData>;
|
|
158
|
+
export declare function onObjectArchived(opts: StorageOptions, handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>): CloudFunction<StorageObjectData>;
|
|
159
|
+
/** Handle a storage object finalized */
|
|
160
|
+
export declare function onObjectFinalized(handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>): CloudFunction<StorageObjectData>;
|
|
161
|
+
export declare function onObjectFinalized(bucket: string, handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>): CloudFunction<StorageObjectData>;
|
|
162
|
+
export declare function onObjectFinalized(opts: StorageOptions, handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>): CloudFunction<StorageObjectData>;
|
|
163
|
+
/** Handle a storage object deleted */
|
|
164
|
+
export declare function onObjectDeleted(handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>): CloudFunction<StorageObjectData>;
|
|
165
|
+
export declare function onObjectDeleted(bucket: string, handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>): CloudFunction<StorageObjectData>;
|
|
166
|
+
export declare function onObjectDeleted(opts: StorageOptions, handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>): CloudFunction<StorageObjectData>;
|
|
167
|
+
/** Handle a storage object metadata updated */
|
|
168
|
+
export declare function onObjectMetadataUpdated(handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>): CloudFunction<StorageObjectData>;
|
|
169
|
+
export declare function onObjectMetadataUpdated(bucket: string, handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>): CloudFunction<StorageObjectData>;
|
|
170
|
+
export declare function onObjectMetadataUpdated(opts: StorageOptions, handler: (event: CloudEvent<StorageObjectData>) => any | Promise<any>): CloudFunction<StorageObjectData>;
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// The MIT License (MIT)
|
|
3
|
+
//
|
|
4
|
+
// Copyright (c) 2017 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.getOptsAndBucket = exports.onOperation = exports.onObjectMetadataUpdated = exports.onObjectDeleted = exports.onObjectFinalized = exports.onObjectArchived = exports.metadataUpdatedEvent = exports.deletedEvent = exports.finalizedEvent = exports.archivedEvent = void 0;
|
|
25
|
+
const config_1 = require("../../config");
|
|
26
|
+
const options = require("../options");
|
|
27
|
+
/** @internal */
|
|
28
|
+
exports.archivedEvent = 'google.cloud.storage.object.v1.archived';
|
|
29
|
+
/** @internal */
|
|
30
|
+
exports.finalizedEvent = 'google.cloud.storage.object.v1.finalized';
|
|
31
|
+
/** @internal */
|
|
32
|
+
exports.deletedEvent = 'google.cloud.storage.object.v1.deleted';
|
|
33
|
+
/** @internal */
|
|
34
|
+
exports.metadataUpdatedEvent = 'google.cloud.storage.object.v1.metadataUpdated';
|
|
35
|
+
function onObjectArchived(buketOrOptsOrHandler, handler) {
|
|
36
|
+
return onOperation(exports.archivedEvent, buketOrOptsOrHandler, handler);
|
|
37
|
+
}
|
|
38
|
+
exports.onObjectArchived = onObjectArchived;
|
|
39
|
+
function onObjectFinalized(buketOrOptsOrHandler, handler) {
|
|
40
|
+
return onOperation(exports.finalizedEvent, buketOrOptsOrHandler, handler);
|
|
41
|
+
}
|
|
42
|
+
exports.onObjectFinalized = onObjectFinalized;
|
|
43
|
+
function onObjectDeleted(buketOrOptsOrHandler, handler) {
|
|
44
|
+
return onOperation(exports.deletedEvent, buketOrOptsOrHandler, handler);
|
|
45
|
+
}
|
|
46
|
+
exports.onObjectDeleted = onObjectDeleted;
|
|
47
|
+
function onObjectMetadataUpdated(buketOrOptsOrHandler, handler) {
|
|
48
|
+
return onOperation(exports.metadataUpdatedEvent, buketOrOptsOrHandler, handler);
|
|
49
|
+
}
|
|
50
|
+
exports.onObjectMetadataUpdated = onObjectMetadataUpdated;
|
|
51
|
+
/** @internal */
|
|
52
|
+
function onOperation(eventType, bucketOrOptsOrHandler, handler) {
|
|
53
|
+
if (typeof bucketOrOptsOrHandler === 'function') {
|
|
54
|
+
handler = bucketOrOptsOrHandler;
|
|
55
|
+
bucketOrOptsOrHandler = {};
|
|
56
|
+
}
|
|
57
|
+
const [opts, bucket] = getOptsAndBucket(bucketOrOptsOrHandler);
|
|
58
|
+
const func = (raw) => {
|
|
59
|
+
return handler(raw);
|
|
60
|
+
};
|
|
61
|
+
func.run = handler;
|
|
62
|
+
// TypeScript doesn't recongize defineProperty as adding a property and complains
|
|
63
|
+
// that __trigger doesn't exist. We can either cast to any and lose all type safety
|
|
64
|
+
// or we can just assign a meaningless value before calling defineProperty.
|
|
65
|
+
func.__trigger = 'silence the transpiler';
|
|
66
|
+
Object.defineProperty(func, '__trigger', {
|
|
67
|
+
get: () => {
|
|
68
|
+
const baseOpts = options.optionsToTriggerAnnotations(options.getGlobalOptions());
|
|
69
|
+
const specificOpts = options.optionsToTriggerAnnotations(opts);
|
|
70
|
+
return {
|
|
71
|
+
platform: 'gcfv2',
|
|
72
|
+
...baseOpts,
|
|
73
|
+
...specificOpts,
|
|
74
|
+
labels: {
|
|
75
|
+
...baseOpts === null || baseOpts === void 0 ? void 0 : baseOpts.labels,
|
|
76
|
+
...specificOpts === null || specificOpts === void 0 ? void 0 : specificOpts.labels,
|
|
77
|
+
},
|
|
78
|
+
eventTrigger: {
|
|
79
|
+
eventType,
|
|
80
|
+
resource: bucket, // TODO(colerogers): replace with 'bucket,' eventually
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
return func;
|
|
86
|
+
}
|
|
87
|
+
exports.onOperation = onOperation;
|
|
88
|
+
/** @internal */
|
|
89
|
+
function getOptsAndBucket(bucketOrOpts) {
|
|
90
|
+
let bucket;
|
|
91
|
+
let opts;
|
|
92
|
+
if (typeof bucketOrOpts === 'string') {
|
|
93
|
+
bucket = bucketOrOpts;
|
|
94
|
+
opts = {};
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
bucket = bucketOrOpts.bucket || (0, config_1.firebaseConfig)().storageBucket;
|
|
98
|
+
opts = { ...bucketOrOpts };
|
|
99
|
+
delete opts.bucket;
|
|
100
|
+
}
|
|
101
|
+
if (!bucket) {
|
|
102
|
+
throw new Error('Missing bucket name. If you are unit testing, please provide a bucket name' +
|
|
103
|
+
' by providing bucket name directly in the event handler or by setting process.env.FIREBASE_CONFIG.');
|
|
104
|
+
}
|
|
105
|
+
if (!/^[a-z\d][a-z\d\\._-]{1,230}[a-z\d]$/.test(bucket)) {
|
|
106
|
+
throw new Error(`Invalid bucket name ${bucket}`);
|
|
107
|
+
}
|
|
108
|
+
return [opts, bucket];
|
|
109
|
+
}
|
|
110
|
+
exports.getOptsAndBucket = getOptsAndBucket;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "firebase-functions",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.16.0",
|
|
4
4
|
"description": "Firebase SDK for Cloud Functions",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"firebase",
|
|
@@ -53,7 +53,8 @@
|
|
|
53
53
|
"./v2/options": "./lib/v2/options.js",
|
|
54
54
|
"./v2/https": "./lib/v2/providers/https.js",
|
|
55
55
|
"./v2/params": "./lib/v2/params/index.js",
|
|
56
|
-
"./v2/pubsub": "./lib/v2/providers/pubsub.js"
|
|
56
|
+
"./v2/pubsub": "./lib/v2/providers/pubsub.js",
|
|
57
|
+
"./v2/storage": "./lib/v2/providers/storage.js"
|
|
57
58
|
},
|
|
58
59
|
"typesVersions": {
|
|
59
60
|
"*": {
|
|
@@ -110,6 +111,9 @@
|
|
|
110
111
|
],
|
|
111
112
|
"v2/pubsub": [
|
|
112
113
|
"lib/v2/providers/pubsub"
|
|
114
|
+
],
|
|
115
|
+
"v2/storage": [
|
|
116
|
+
"lib/v2/providers/storage"
|
|
113
117
|
]
|
|
114
118
|
}
|
|
115
119
|
},
|
|
@@ -148,7 +152,7 @@
|
|
|
148
152
|
"chai": "^4.2.0",
|
|
149
153
|
"chai-as-promised": "^7.1.1",
|
|
150
154
|
"child-process-promise": "^2.2.1",
|
|
151
|
-
"firebase-admin": "
|
|
155
|
+
"firebase-admin": "10.0.0",
|
|
152
156
|
"js-yaml": "^3.13.1",
|
|
153
157
|
"jsdom": "^16.2.1",
|
|
154
158
|
"jsonwebtoken": "^8.5.1",
|
|
@@ -164,12 +168,12 @@
|
|
|
164
168
|
"tslint-config-prettier": "^1.18.0",
|
|
165
169
|
"tslint-no-unused-expression-chai": "^0.1.4",
|
|
166
170
|
"tslint-plugin-prettier": "^2.0.1",
|
|
167
|
-
"typedoc": "
|
|
171
|
+
"typedoc": "0.21.2",
|
|
168
172
|
"typescript": "^4.3.5",
|
|
169
173
|
"yargs": "^15.3.1"
|
|
170
174
|
},
|
|
171
175
|
"peerDependencies": {
|
|
172
|
-
"firebase-admin": "^8.0.0 || ^9.0.0"
|
|
176
|
+
"firebase-admin": "^8.0.0 || ^9.0.0 || ^10.0.0"
|
|
173
177
|
},
|
|
174
178
|
"engines": {
|
|
175
179
|
"node": "^8.13.0 || >=10.10.0"
|