Skip to content

Commit b3566bf

Browse files
merlinnotthechenky
authored andcommitted
Extract configuration to break dependency cycle (#494)
* Extract configuration to break dependency cycle * Add comments to Schedule and ScheduleRetryConfig * Stricten regions definition * Fix tests broken due to strict typings * More strict types for regions - reverse order * Reformat
1 parent 340bc77 commit b3566bf

14 files changed

+106
-79
lines changed

spec/function-builder.spec.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ describe('FunctionBuilder', () => {
123123
expect(() => {
124124
functions
125125
.runWith({ timeoutSeconds: 90, memory: '256MB' })
126-
.region('unsupported');
126+
.region('unsupported' as any);
127127
}).to.throw(Error, 'region');
128128
});
129129

@@ -165,21 +165,21 @@ describe('FunctionBuilder', () => {
165165

166166
it('should throw an error if user chooses an invalid region', () => {
167167
expect(() => {
168-
return functions.region('unsupported');
168+
return functions.region('unsupported' as any);
169169
}).to.throw(Error, 'region');
170170

171171
expect(() => {
172-
return functions.region('unsupported').runWith({
172+
return functions.region('unsupported' as any).runWith({
173173
timeoutSeconds: 500,
174174
} as any);
175175
}).to.throw(Error, 'region');
176176

177177
expect(() => {
178-
return functions.region('unsupported', 'us-east1');
178+
return functions.region('unsupported' as any, 'us-east1');
179179
}).to.throw(Error, 'region');
180180

181181
expect(() => {
182-
return functions.region('unsupported', 'us-east1').runWith({
182+
return functions.region('unsupported' as any, 'us-east1').runWith({
183183
timeoutSeconds: 500,
184184
} as any);
185185
}).to.throw(Error, 'region');

src/cloud-functions.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
import { Request, Response } from 'express';
2424
import * as _ from 'lodash';
2525
import { apps } from './apps';
26-
import { DeploymentOptions } from './function-builder';
26+
import { DeploymentOptions, Schedule } from './function-configuration';
2727
export { Request, Response };
2828

2929
const WILDCARD_REGEX = new RegExp('{[^/{}]*}', 'g');
@@ -168,20 +168,6 @@ export interface TriggerAnnotated {
168168
};
169169
}
170170

171-
export interface ScheduleRetryConfig {
172-
retryCount?: number;
173-
maxRetryDuration?: string;
174-
minBackoffDuration?: string;
175-
maxBackoffDuration?: string;
176-
maxDoublings?: number;
177-
}
178-
179-
export interface Schedule {
180-
schedule: string;
181-
timeZone?: string;
182-
retryConfig?: ScheduleRetryConfig;
183-
}
184-
185171
/** A Runnable has a `run` method which directly invokes the user-defined function - useful for unit testing. */
186172
export interface Runnable<T> {
187173
run: (data: T, context: any) => PromiseLike<any> | any;

src/function-builder.ts

Lines changed: 14 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,14 @@
2323
import * as express from 'express';
2424
import * as _ from 'lodash';
2525

26-
import { CloudFunction, EventContext, Schedule } from './cloud-functions';
26+
import { CloudFunction, EventContext } from './cloud-functions';
27+
import {
28+
DeploymentOptions,
29+
MAX_TIMEOUT_SECONDS,
30+
RuntimeOptions,
31+
SUPPORTED_REGIONS,
32+
VALID_MEMORY_OPTIONS,
33+
} from './function-configuration';
2734
import * as analytics from './providers/analytics';
2835
import * as auth from './providers/auth';
2936
import * as crashlytics from './providers/crashlytics';
@@ -34,34 +41,6 @@ import * as pubsub from './providers/pubsub';
3441
import * as remoteConfig from './providers/remoteConfig';
3542
import * as storage from './providers/storage';
3643

37-
/**
38-
* List of all regions supported by Cloud Functions.
39-
*/
40-
const SUPPORTED_REGIONS = [
41-
'us-central1',
42-
'us-east1',
43-
'us-east4',
44-
'europe-west1',
45-
'europe-west2',
46-
'asia-east2',
47-
'asia-northeast1',
48-
];
49-
50-
/**
51-
* List of available memory options supported by Cloud Functions.
52-
*/
53-
const VALID_MEMORY_OPTS = ['128MB', '256MB', '512MB', '1GB', '2GB'];
54-
55-
// Adding this memory type here to error on compile for TS users.
56-
// Unfortunately I have not found a way to merge this with VALID_MEMORY_OPS
57-
// without it being super ugly. But here they are right next to each other at least.
58-
type Memory = '128MB' | '256MB' | '512MB' | '1GB' | '2GB';
59-
60-
/**
61-
* Cloud Functions max timeout value.
62-
*/
63-
const MAX_TIMEOUT_SECONDS = 540;
64-
6544
/**
6645
* Assert that the runtime options passed in are valid.
6746
* @param runtimeOptions object containing memory and timeout information.
@@ -70,10 +49,10 @@ const MAX_TIMEOUT_SECONDS = 540;
7049
function assertRuntimeOptionsValid(runtimeOptions: RuntimeOptions): boolean {
7150
if (
7251
runtimeOptions.memory &&
73-
!_.includes(VALID_MEMORY_OPTS, runtimeOptions.memory)
52+
!_.includes(VALID_MEMORY_OPTIONS, runtimeOptions.memory)
7453
) {
7554
throw new Error(
76-
`The only valid memory allocation values are: ${VALID_MEMORY_OPTS.join(
55+
`The only valid memory allocation values are: ${VALID_MEMORY_OPTIONS.join(
7756
', '
7857
)}`
7958
);
@@ -111,7 +90,9 @@ function assertRegionsAreValid(regions: string[]): boolean {
11190
* @param regions One of more region strings.
11291
* For example: `functions.region('us-east1')` or `functions.region('us-east1', 'us-central1')`
11392
*/
114-
export function region(...regions: string[]): FunctionBuilder {
93+
export function region(
94+
...regions: Array<typeof SUPPORTED_REGIONS[number]>
95+
): FunctionBuilder {
11596
if (assertRegionsAreValid(regions)) {
11697
return new FunctionBuilder({ regions });
11798
}
@@ -130,18 +111,6 @@ export function runWith(runtimeOptions: RuntimeOptions): FunctionBuilder {
130111
}
131112
}
132113

133-
export interface RuntimeOptions {
134-
timeoutSeconds?: number;
135-
memory?: Memory;
136-
}
137-
138-
export interface DeploymentOptions {
139-
regions?: string[];
140-
timeoutSeconds?: number;
141-
memory?: Memory;
142-
schedule?: Schedule;
143-
}
144-
145114
export class FunctionBuilder {
146115
constructor(private options: DeploymentOptions) {}
147116

@@ -150,7 +119,7 @@ export class FunctionBuilder {
150119
* @param regions One or more region strings.
151120
* For example: `functions.region('us-east1')` or `functions.region('us-east1', 'us-central1')`
152121
*/
153-
region(...regions: string[]): FunctionBuilder {
122+
region(...regions: Array<typeof SUPPORTED_REGIONS[number]>): FunctionBuilder {
154123
if (assertRegionsAreValid(regions)) {
155124
this.options.regions = regions;
156125
return this;

src/function-configuration.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/**
2+
* List of all regions supported by Cloud Functions.
3+
*/
4+
export const SUPPORTED_REGIONS = [
5+
'us-central1',
6+
'us-east1',
7+
'us-east4',
8+
'europe-west1',
9+
'europe-west2',
10+
'asia-east2',
11+
'asia-northeast1',
12+
] as const;
13+
14+
/**
15+
* Cloud Functions min timeout value.
16+
*/
17+
export const MIN_TIMEOUT_SECONDS = 0;
18+
19+
/**
20+
* Cloud Functions max timeout value.
21+
*/
22+
export const MAX_TIMEOUT_SECONDS = 540;
23+
24+
/**
25+
* List of available memory options supported by Cloud Functions.
26+
*/
27+
export const VALID_MEMORY_OPTIONS = [
28+
'128MB',
29+
'256MB',
30+
'512MB',
31+
'1GB',
32+
'2GB',
33+
] as const;
34+
35+
/**
36+
* Scheduler retry options. Applies only to scheduled functions.
37+
*/
38+
export interface ScheduleRetryConfig {
39+
retryCount?: number;
40+
maxRetryDuration?: string;
41+
minBackoffDuration?: string;
42+
maxBackoffDuration?: string;
43+
maxDoublings?: number;
44+
}
45+
46+
/**
47+
* Configuration options for scheduled functions.
48+
*/
49+
export interface Schedule {
50+
schedule: string;
51+
timeZone?: string;
52+
retryConfig?: ScheduleRetryConfig;
53+
}
54+
55+
export interface RuntimeOptions {
56+
/**
57+
* Amount of memory to allocate to the function.
58+
*/
59+
memory?: typeof VALID_MEMORY_OPTIONS[number];
60+
/**
61+
* Timeout for the function in seconds, possible values are 0 to 540.
62+
*/
63+
timeoutSeconds?: number;
64+
}
65+
66+
export interface DeploymentOptions extends RuntimeOptions {
67+
regions?: string[];
68+
schedule?: Schedule;
69+
}

src/index.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,16 @@
2323
// Providers:
2424
import * as analytics from './providers/analytics';
2525
import * as auth from './providers/auth';
26-
27-
import * as apps from './apps';
28-
import { handler } from './handler-builder';
2926
import * as crashlytics from './providers/crashlytics';
3027
import * as database from './providers/database';
3128
import * as firestore from './providers/firestore';
3229
import * as https from './providers/https';
3330
import * as pubsub from './providers/pubsub';
3431
import * as remoteConfig from './providers/remoteConfig';
3532
import * as storage from './providers/storage';
33+
34+
import * as apps from './apps';
35+
import { handler } from './handler-builder';
3636
import { setup } from './setup';
3737

3838
const app = apps.apps();
@@ -52,8 +52,9 @@ export {
5252
};
5353

5454
// Exported root types:
55-
export * from './config';
5655
export * from './cloud-functions';
56+
export * from './config';
5757
export * from './function-builder';
58+
export * from './function-configuration';
5859

5960
setup();

src/providers/analytics.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
EventContext,
2929
makeCloudFunction,
3030
} from '../cloud-functions';
31-
import { DeploymentOptions } from '../function-builder';
31+
import { DeploymentOptions } from '../function-configuration';
3232

3333
/** @internal */
3434
export const provider = 'google.analytics';

src/providers/auth.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import {
2828
EventContext,
2929
makeCloudFunction,
3030
} from '../cloud-functions';
31-
import { DeploymentOptions } from '../function-builder';
31+
import { DeploymentOptions } from '../function-configuration';
3232

3333
/** @internal */
3434
export const provider = 'google.firebase.auth';

src/providers/crashlytics.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
EventContext,
2626
makeCloudFunction,
2727
} from '../cloud-functions';
28-
import { DeploymentOptions } from '../function-builder';
28+
import { DeploymentOptions } from '../function-configuration';
2929

3030
/** @internal */
3131
export const provider = 'google.firebase.crashlytics';

src/providers/database.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import {
3131
makeCloudFunction,
3232
} from '../cloud-functions';
3333
import { firebaseConfig } from '../config';
34-
import { DeploymentOptions } from '../function-builder';
34+
import { DeploymentOptions } from '../function-configuration';
3535
import { applyChange, joinPath, normalizePath, pathParts } from '../utils';
3636

3737
/** @internal */

src/providers/firestore.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import {
3232
makeCloudFunction,
3333
} from '../cloud-functions';
3434
import { dateToTimestampProto } from '../encoder';
35-
import { DeploymentOptions } from '../function-builder';
35+
import { DeploymentOptions } from '../function-configuration';
3636

3737
/** @internal */
3838
export const provider = 'google.firestore';

0 commit comments

Comments
 (0)