Skip to content

Commit 1205233

Browse files
committed
refactor: code improvements
1 parent 769db4a commit 1205233

File tree

12 files changed

+162
-149
lines changed

12 files changed

+162
-149
lines changed

spec/providers/firestore.spec.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { expect } from 'chai';
22
import * as firebase from 'firebase-admin';
3-
import { FeaturesList } from '../../src/features';
3+
import { FeaturesList } from '../../src/types/commonTypes';
44
import fft = require('../../src/index');
55

66
describe('providers/firestore', () => {

spec/v2.spec.ts

-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ import {
3939
import { defineString } from 'firebase-functions/params';
4040
import { makeDataSnapshot } from '../src/providers/database';
4141
import { makeDocumentSnapshot } from '../src/providers/firestore';
42-
import { inspect } from 'util';
4342

4443
describe('v2', () => {
4544
describe('#wrapV2', () => {

src/cloudevent/generate.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ import {
88
DocumentSnapshot,
99
QueryDocumentSnapshot,
1010
} from 'firebase-admin/firestore';
11-
import { LIST_OF_MOCK_CLOUD_EVENT_PARTIALS } from './mocks/partials';
12-
import { DeepPartial } from './types';
1311
import { Change } from 'firebase-functions/v1';
1412
import merge from 'ts-deepmerge';
1513

14+
import { LIST_OF_MOCK_CLOUD_EVENT_PARTIALS } from './mocks/partials';
15+
import { DeepPartial } from './types';
16+
1617
/**
1718
* @return {CloudEvent} Generated Mock CloudEvent
1819
*/

src/features.ts

+1-17
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,7 @@ import * as database from './providers/database';
55
import * as firestore from './providers/firestore';
66
import * as pubsub from './providers/pubsub';
77
import * as storage from './providers/storage';
8-
import { FirebaseFunctionsTest } from './lifecycle';
9-
10-
export interface LazyFeatures {
11-
mockConfig: typeof mockConfig;
12-
wrap: typeof wrap;
13-
makeChange: typeof makeChange;
14-
analytics: typeof analytics;
15-
auth: typeof auth;
16-
database: typeof database;
17-
firestore: typeof firestore;
18-
pubsub: typeof pubsub;
19-
storage: typeof storage;
20-
}
8+
import { LazyFeatures } from './types/commonTypes';
219

2210
export const features: LazyFeatures = {
2311
mockConfig,
@@ -30,7 +18,3 @@ export const features: LazyFeatures = {
3018
pubsub,
3119
storage,
3220
};
33-
34-
export interface FeaturesList extends LazyFeatures {
35-
cleanup: InstanceType<typeof FirebaseFunctionsTest>['cleanup'];
36-
}

src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { AppOptions } from 'firebase-admin';
2424
import { merge } from 'lodash';
2525

2626
import { FirebaseFunctionsTest } from './lifecycle';
27-
import { FeaturesList } from './features';
27+
import { FeaturesList } from './types/commonTypes';
2828

2929
export = (
3030
firebaseConfig?: AppOptions,

src/main.ts

+22-30
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,35 @@ import {
2525
HttpsFunction,
2626
Runnable,
2727
} from 'firebase-functions/v1';
28-
2928
import {
3029
CloudFunction as CloudFunctionV2,
3130
CloudEvent,
3231
} from 'firebase-functions/v2';
33-
3432
import {
3533
CallableFunction,
3634
HttpsFunction as HttpsFunctionV2,
3735
} from 'firebase-functions/v2/https';
3836

39-
import { wrapV1, WrappedFunction, WrappedScheduledFunction } from './v1';
40-
41-
import { wrapV2, WrappedV2Function, WrappedV2CallableFunction } from './v2';
37+
import { wrapV1 } from './v1';
38+
import { wrapV2 } from './v2';
39+
import { WrappedFunction, WrappedScheduledFunction } from './types/v1Types';
40+
import { WrappedV2Function, WrappedV2CallableFunction } from './types/v2Types';
41+
import { HttpsFunctionOrCloudFunctionV1 } from './types/v1Types';
4242

43-
type HttpsFunctionOrCloudFunctionV1<T, U> = U extends HttpsFunction &
44-
Runnable<T>
45-
? HttpsFunction & Runnable<T>
46-
: CloudFunctionV1<T>;
43+
/**
44+
* The key differences between V1 and V2 CloudFunctions are:
45+
* <ul>
46+
* <li> V1 CloudFunction is sometimes a binary function
47+
* <li> V2 CloudFunction is always a unary function
48+
* <li> V1 CloudFunction.run is always a binary function
49+
* <li> V2 CloudFunction.run is always a unary function
50+
* @return True iff the CloudFunction is a V2 function.
51+
*/
52+
function isV2CloudFunction<T extends CloudEvent<unknown>>(
53+
cloudFunction: any
54+
): cloudFunction is CloudFunctionV2<T> {
55+
return cloudFunction.length === 1 && cloudFunction?.run?.length === 1;
56+
}
4757

4858
// Re-exporting V1 (to reduce breakage)
4959
export {
@@ -52,13 +62,10 @@ export {
5262
WrappedFunction,
5363
WrappedScheduledFunction,
5464
CallableContextOptions,
55-
makeChange,
56-
mockConfig,
57-
} from './v1';
58-
65+
} from './types/v1Types';
66+
export { makeChange, mockConfig } from './v1';
5967
// V2 Exports
60-
export { WrappedV2Function } from './v2';
61-
68+
export { WrappedV2Function } from './types/v2Types';
6269
export function wrap<T>(
6370
cloudFunction: HttpsFunction & Runnable<T>
6471
): WrappedFunction<T, HttpsFunction & Runnable<T>>;
@@ -85,18 +92,3 @@ export function wrap<T, V extends CloudEvent<unknown>>(
8592
cloudFunction as HttpsFunctionOrCloudFunctionV1<T, typeof cloudFunction>
8693
);
8794
}
88-
89-
/**
90-
* The key differences between V1 and V2 CloudFunctions are:
91-
* <ul>
92-
* <li> V1 CloudFunction is sometimes a binary function
93-
* <li> V2 CloudFunction is always a unary function
94-
* <li> V1 CloudFunction.run is always a binary function
95-
* <li> V2 CloudFunction.run is always a unary function
96-
* @return True iff the CloudFunction is a V2 function.
97-
*/
98-
function isV2CloudFunction<T extends CloudEvent<unknown>>(
99-
cloudFunction: any
100-
): cloudFunction is CloudFunctionV2<T> {
101-
return cloudFunction.length === 1 && cloudFunction?.run?.length === 1;
102-
}

src/providers/firestore.ts

+1-7
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,10 @@
2323
import { Change } from 'firebase-functions/v1';
2424
import { firestore, app } from 'firebase-admin';
2525
import { has, get, isEmpty, isPlainObject, mapValues } from 'lodash';
26-
import { inspect } from 'util';
26+
import * as http from 'http';
2727

2828
import { testApp } from '../app';
2929

30-
import * as http from 'http';
31-
import {
32-
DocumentSnapshot,
33-
QueryDocumentSnapshot,
34-
} from 'firebase-admin/firestore';
35-
3630
function dateToTimestampProto(
3731
timeString?: string
3832
): { seconds: number; nanos: number } | undefined {

src/types/commonTypes.ts

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { makeChange, wrap, mockConfig } from '../main';
2+
import * as analytics from '../providers/analytics';
3+
import * as auth from '../providers/auth';
4+
import * as database from '../providers/database';
5+
import * as firestore from '../providers/firestore';
6+
import * as pubsub from '../providers/pubsub';
7+
import * as storage from '../providers/storage';
8+
import { FirebaseFunctionsTest } from '../lifecycle';
9+
10+
export interface LazyFeatures {
11+
mockConfig: typeof mockConfig;
12+
wrap: typeof wrap;
13+
makeChange: typeof makeChange;
14+
analytics: typeof analytics;
15+
auth: typeof auth;
16+
database: typeof database;
17+
firestore: typeof firestore;
18+
pubsub: typeof pubsub;
19+
storage: typeof storage;
20+
}
21+
22+
export interface FeaturesList extends LazyFeatures {
23+
cleanup: InstanceType<typeof FirebaseFunctionsTest>['cleanup'];
24+
}

src/types/v1Types.ts

+86
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import {
2+
CloudFunction as CloudFunctionV1,
3+
https,
4+
HttpsFunction,
5+
Runnable,
6+
} from 'firebase-functions/v1';
7+
8+
/** Fields of the event context that can be overridden/customized. */
9+
export type EventContextOptions = {
10+
/** ID of the event. If omitted, a random ID will be generated. */
11+
eventId?: string;
12+
/** ISO time string of when the event occurred. If omitted, the current time is used. */
13+
timestamp?: string;
14+
/** The values for the wildcards in the reference path that a database or Firestore function is listening to.
15+
* If omitted, random values will be generated.
16+
*/
17+
params?: { [option: string]: any };
18+
/** (Only for database functions and https.onCall.) Firebase auth variable representing the user that triggered
19+
* the function. Defaults to null.
20+
*/
21+
auth?: any;
22+
/** (Only for database and https.onCall functions.) The authentication state of the user that triggered the function.
23+
* Default is 'UNAUTHENTICATED'.
24+
*/
25+
authType?: 'ADMIN' | 'USER' | 'UNAUTHENTICATED';
26+
27+
/** Resource is a standard format for defining a resource (google.rpc.context.AttributeContext.Resource).
28+
* In Cloud Functions, it is the resource that triggered the function - such as a storage bucket.
29+
*/
30+
resource?: {
31+
service: string;
32+
name: string;
33+
type?: string;
34+
labels?: {
35+
[tag: string]: string;
36+
};
37+
};
38+
};
39+
40+
/** Fields of the callable context that can be overridden/customized. */
41+
export type CallableContextOptions = {
42+
/**
43+
* The result of decoding and verifying a Firebase AppCheck token.
44+
*/
45+
app?: any;
46+
47+
/**
48+
* The result of decoding and verifying a Firebase Auth ID token.
49+
*/
50+
auth?: any;
51+
52+
/**
53+
* An unverified token for a Firebase Instance ID.
54+
*/
55+
instanceIdToken?: string;
56+
57+
/**
58+
* The raw HTTP request object.
59+
*/
60+
rawRequest?: https.Request;
61+
};
62+
63+
/* Fields for both Event and Callable contexts, checked at runtime */
64+
export type ContextOptions<T = void> = T extends HttpsFunction & Runnable<T>
65+
? CallableContextOptions
66+
: EventContextOptions;
67+
68+
/** A function that can be called with test data and optional override values for the event context.
69+
* It will subsequently invoke the cloud function it wraps with the provided test data and a generated event context.
70+
*/
71+
export type WrappedFunction<T, U = void> = (
72+
data: T,
73+
options?: ContextOptions<U>
74+
) => any | Promise<any>;
75+
76+
/** A scheduled function that can be called with optional override values for the event context.
77+
* It will subsequently invoke the cloud function it wraps with a generated event context.
78+
*/
79+
export type WrappedScheduledFunction = (
80+
options?: ContextOptions
81+
) => any | Promise<any>;
82+
83+
export type HttpsFunctionOrCloudFunctionV1<T, U> = U extends HttpsFunction &
84+
Runnable<T>
85+
? HttpsFunction & Runnable<T>
86+
: CloudFunctionV1<T>;

src/types/v2Types.ts

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { CallableRequest } from 'firebase-functions/v2/https';
2+
import { DeepPartial } from '../cloudevent/types';
3+
import { CloudEvent } from 'firebase-functions/v2';
4+
5+
/** A function that can be called with test data and optional override values for {@link CloudEvent}
6+
* It will subsequently invoke the cloud function it wraps with the provided {@link CloudEvent}
7+
*/
8+
export type WrappedV2Function<T extends CloudEvent<unknown>> = (
9+
cloudEventPartial?: DeepPartial<T | object>
10+
) => any | Promise<any>;
11+
12+
export type WrappedV2CallableFunction<T> = (
13+
data: CallableRequest
14+
) => T | Promise<T>;

0 commit comments

Comments
 (0)