@@ -32,7 +32,15 @@ import {
32
32
firestore ,
33
33
HttpsFunction ,
34
34
Runnable ,
35
+ // @ts -ignore
36
+ resetCache ,
35
37
} from 'firebase-functions' ;
38
+ import { Expression } from 'firebase-functions/params' ;
39
+ import {
40
+ getEventFilters ,
41
+ getEventType ,
42
+ resolveStringExpression ,
43
+ } from './cloudevent/mocks/helpers' ;
36
44
37
45
/** Fields of the event context that can be overridden/customized. */
38
46
export type EventContextOptions = {
@@ -116,13 +124,13 @@ export function wrapV1<T>(
116
124
export function wrapV1 < T > (
117
125
cloudFunction : CloudFunction < T >
118
126
) : WrappedScheduledFunction | WrappedFunction < T , CloudFunction < T > > {
119
- if ( ! has ( cloudFunction , '__trigger ' ) ) {
127
+ if ( ! has ( cloudFunction , '__endpoint ' ) ) {
120
128
throw new Error (
121
129
'Wrap can only be called on functions written with the firebase-functions SDK.'
122
130
) ;
123
131
}
124
132
125
- if ( get ( cloudFunction , '__trigger.labels.deployment-scheduled' ) === 'true' ) {
133
+ if ( has ( cloudFunction , '__endpoint.scheduleTrigger' ) ) {
126
134
const scheduledWrapped : WrappedScheduledFunction = (
127
135
options : ContextOptions
128
136
) => {
@@ -139,10 +147,7 @@ export function wrapV1<T>(
139
147
return scheduledWrapped ;
140
148
}
141
149
142
- if (
143
- has ( cloudFunction , '__trigger.httpsTrigger' ) &&
144
- get ( cloudFunction , '__trigger.labels.deployment-callable' ) !== 'true'
145
- ) {
150
+ if ( has ( cloudFunction , '__endpoint.httpsTrigger' ) ) {
146
151
throw new Error (
147
152
'Wrap function is only available for `onCall` HTTP functions, not `onRequest`.'
148
153
) ;
@@ -154,8 +159,7 @@ export function wrapV1<T>(
154
159
) ;
155
160
}
156
161
157
- const isCallableFunction =
158
- get ( cloudFunction , '__trigger.labels.deployment-callable' ) === 'true' ;
162
+ const isCallableFunction = has ( cloudFunction , '__endpoint.callableTrigger' ) ;
159
163
160
164
let wrapped : WrappedFunction < T , typeof cloudFunction > = ( data , options ) => {
161
165
// Although in Typescript we require `options` some of our JS samples do not pass it.
@@ -197,11 +201,12 @@ export function wrapV1<T>(
197
201
198
202
/** @internal */
199
203
export function _makeResourceName (
200
- triggerResource : string ,
204
+ triggerResource : string | Expression < string > ,
201
205
params = { }
202
206
) : string {
207
+ const resource = resolveStringExpression ( triggerResource ) ;
203
208
const wildcardRegex = new RegExp ( '{[^/{}]*}' , 'g' ) ;
204
- let resourceName = triggerResource . replace ( wildcardRegex , ( wildcard ) => {
209
+ let resourceName = resource . replace ( wildcardRegex , ( wildcard ) => {
205
210
let wildcardNoBraces = wildcard . slice ( 1 , - 1 ) ; // .slice removes '{' and '}' from wildcard
206
211
let sub = get ( params , wildcardNoBraces ) ;
207
212
return sub || wildcardNoBraces + random ( 1 , 9 ) ;
@@ -244,8 +249,8 @@ function _makeDefaultContext<T>(
244
249
triggerData ?: T
245
250
) : EventContext {
246
251
let eventContextOptions = options as EventContextOptions ;
247
- const eventResource = cloudFunction . __trigger . eventTrigger ?. resource ;
248
- const eventType = cloudFunction . __trigger . eventTrigger ?. eventType ;
252
+ const eventType = getEventType ( cloudFunction ) ;
253
+ const eventResource = getEventFilters ( cloudFunction ) . resource ;
249
254
250
255
const optionsParams = eventContextOptions . params ?? { } ;
251
256
let triggerParams = { } ;
@@ -281,7 +286,7 @@ function _makeDefaultContext<T>(
281
286
const defaultContext : EventContext = {
282
287
eventId : _makeEventId ( ) ,
283
288
resource : eventResource && {
284
- service : cloudFunction . __trigger . eventTrigger ?. service ,
289
+ service : serviceFromEventType ( eventType ) ,
285
290
name : _makeResourceName ( eventResource , params ) ,
286
291
} ,
287
292
eventType,
@@ -292,20 +297,22 @@ function _makeDefaultContext<T>(
292
297
}
293
298
294
299
function _extractDatabaseParams (
295
- triggerResource : string ,
300
+ triggerResource : string | Expression < string > ,
296
301
data : database . DataSnapshot
297
302
) : EventContext [ 'params' ] {
303
+ const resource = resolveStringExpression ( triggerResource ) ;
298
304
const path = data . ref . toString ( ) . replace ( data . ref . root . toString ( ) , '' ) ;
299
- return _extractParams ( triggerResource , path ) ;
305
+ return _extractParams ( resource , path ) ;
300
306
}
301
307
302
308
function _extractFirestoreDocumentParams (
303
- triggerResource : string ,
309
+ triggerResource : string | Expression < string > ,
304
310
data : firestore . DocumentSnapshot
305
311
) : EventContext [ 'params' ] {
312
+ const resource = resolveStringExpression ( triggerResource ) ;
306
313
// Resource format: databases/(default)/documents/<path>
307
314
return _extractParams (
308
- triggerResource . replace ( / ^ d a t a b a s e s \/ [ ^ \/ ] + \/ d o c u m e n t s \/ / , '' ) ,
315
+ resource . replace ( / ^ d a t a b a s e s \/ [ ^ \/ ] + \/ d o c u m e n t s \/ / , '' ) ,
309
316
data . ref . path
310
317
) ;
311
318
}
@@ -338,16 +345,38 @@ export function _extractParams(
338
345
return params ;
339
346
}
340
347
348
+ function serviceFromEventType ( eventType ?: string ) : string {
349
+ if ( eventType ) {
350
+ const providerToService : Array < [ string , string ] > = [
351
+ [ 'google.analytics' , 'app-measurement.com' ] ,
352
+ [ 'google.firebase.auth' , 'firebaseauth.googleapis.com' ] ,
353
+ [ 'google.firebase.database' , 'firebaseio.com' ] ,
354
+ [ 'google.firestore' , 'firestore.googleapis.com' ] ,
355
+ [ 'google.pubsub' , 'pubsub.googleapis.com' ] ,
356
+ [ 'google.firebase.remoteconfig' , 'firebaseremoteconfig.googleapis.com' ] ,
357
+ [ 'google.storage' , 'storage.googleapis.com' ] ,
358
+ [ 'google.testing' , 'testing.googleapis.com' ] ,
359
+ ] ;
360
+
361
+ const match = providerToService . find ( ( [ provider ] ) => {
362
+ eventType . includes ( provider ) ;
363
+ } ) ;
364
+ if ( match ) {
365
+ return match [ 1 ] ;
366
+ }
367
+ }
368
+ return 'unknown-service.googleapis.com' ;
369
+ }
370
+
341
371
/** Make a Change object to be used as test data for Firestore and real time database onWrite and onUpdate functions. */
342
372
export function makeChange < T > ( before : T , after : T ) : Change < T > {
343
373
return Change . fromObjects ( before , after ) ;
344
374
}
345
375
346
376
/** Mock values returned by `functions.config()`. */
347
377
export function mockConfig ( conf : { [ key : string ] : { [ key : string ] : any } } ) {
348
- if ( config . singleton ) {
349
- delete config . singleton ;
378
+ if ( resetCache ) {
379
+ resetCache ( ) ;
350
380
}
351
-
352
381
process . env . CLOUD_RUNTIME_CONFIG = JSON . stringify ( conf ) ;
353
382
}
0 commit comments