@@ -30,6 +30,8 @@ import {
3030 config ,
3131 database ,
3232 firestore ,
33+ HttpsFunction ,
34+ Runnable ,
3335} from 'firebase-functions' ;
3436
3537/** Fields of the event context that can be overridden/customized. */
@@ -88,14 +90,16 @@ export type CallableContextOptions = {
8890} ;
8991
9092/* Fields for both Event and Callable contexts, checked at runtime */
91- export type ContextOptions = EventContextOptions | CallableContextOptions ;
93+ export type ContextOptions < T = void > = T extends HttpsFunction & Runnable < T >
94+ ? CallableContextOptions
95+ : EventContextOptions ;
9296
9397/** A function that can be called with test data and optional override values for the event context.
9498 * It will subsequently invoke the cloud function it wraps with the provided test data and a generated event context.
9599 */
96- export type WrappedFunction < T > = (
100+ export type WrappedFunction < T , U = void > = (
97101 data : T ,
98- options ?: ContextOptions
102+ options ?: ContextOptions < U >
99103) => any | Promise < any > ;
100104
101105/** A scheduled function that can be called with optional override values for the event context.
@@ -106,9 +110,12 @@ export type WrappedScheduledFunction = (
106110) => any | Promise < any > ;
107111
108112/** Takes a cloud function to be tested, and returns a WrappedFunction which can be called in test code. */
113+ export function wrapV1 < T > (
114+ cloudFunction : HttpsFunction & Runnable < T >
115+ ) : WrappedFunction < T , HttpsFunction & Runnable < T > > ;
109116export function wrapV1 < T > (
110117 cloudFunction : CloudFunction < T >
111- ) : WrappedScheduledFunction | WrappedFunction < T > {
118+ ) : WrappedScheduledFunction | WrappedFunction < T , CloudFunction < T > > {
112119 if ( ! has ( cloudFunction , '__trigger' ) ) {
113120 throw new Error (
114121 'Wrap can only be called on functions written with the firebase-functions SDK.'
@@ -150,26 +157,26 @@ export function wrapV1<T>(
150157 const isCallableFunction =
151158 get ( cloudFunction , '__trigger.labels.deployment-callable' ) === 'true' ;
152159
153- let wrapped : WrappedFunction < T > = ( data : T , options : ContextOptions ) => {
160+ let wrapped : WrappedFunction < T , typeof cloudFunction > = ( data , options ) => {
154161 // Although in Typescript we require `options` some of our JS samples do not pass it.
155- options = options || { } ;
162+ const _options = { ... options } ;
156163 let context ;
157164
158165 if ( isCallableFunction ) {
159166 _checkOptionValidity (
160167 [ 'app' , 'auth' , 'instanceIdToken' , 'rawRequest' ] ,
161- options
168+ _options
162169 ) ;
163- let callableContextOptions = options as CallableContextOptions ;
170+ let callableContextOptions = _options as CallableContextOptions ;
164171 context = {
165172 ...callableContextOptions ,
166173 } ;
167174 } else {
168175 _checkOptionValidity (
169176 [ 'eventId' , 'timestamp' , 'params' , 'auth' , 'authType' , 'resource' ] ,
170- options
177+ _options
171178 ) ;
172- const defaultContext = _makeDefaultContext ( cloudFunction , options , data ) ;
179+ const defaultContext = _makeDefaultContext ( cloudFunction , _options , data ) ;
173180
174181 if (
175182 has ( defaultContext , 'eventType' ) &&
@@ -179,7 +186,7 @@ export function wrapV1<T>(
179186 defaultContext . authType = 'UNAUTHENTICATED' ;
180187 defaultContext . auth = null ;
181188 }
182- context = merge ( { } , defaultContext , options ) ;
189+ context = merge ( { } , defaultContext , _options ) ;
183190 }
184191
185192 return cloudFunction . run ( data , context ) ;
@@ -226,9 +233,14 @@ function _checkOptionValidity(
226233 } ) ;
227234}
228235
236+ function _makeDefaultContext < T > (
237+ cloudFunction : HttpsFunction & Runnable < T > ,
238+ options : CallableContextOptions ,
239+ triggerData ?: T
240+ ) ;
229241function _makeDefaultContext < T > (
230242 cloudFunction : CloudFunction < T > ,
231- options : ContextOptions ,
243+ options : EventContextOptions ,
232244 triggerData ?: T
233245) : EventContext {
234246 let eventContextOptions = options as EventContextOptions ;
0 commit comments