Skip to content

Commit c0925c1

Browse files
committed
Refactor initializing endpoint to fix bug.
1 parent 3764954 commit c0925c1

File tree

10 files changed

+160
-131
lines changed

10 files changed

+160
-131
lines changed

src/common/providers/tasks.ts

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ import { DecodedIdToken } from "firebase-admin/auth";
2626
import * as logger from "../../logger";
2727
import * as https from "./https";
2828
import { Expression } from "../../params";
29-
import { ResettableKeys, ResetValue } from "../options";
30-
import { ManifestEndpoint } from "../../runtime/manifest";
29+
import { ResetValue } from "../options";
3130

3231
/** How a task should be retried in the event of a non-2xx return. */
3332
export interface RetryConfig {
@@ -109,25 +108,6 @@ export interface Request<T = any> {
109108
type v1TaskHandler = (data: any, context: TaskContext) => void | Promise<void>;
110109
type v2TaskHandler<Req> = (request: Request<Req>) => void | Promise<void>;
111110

112-
/** @internal */
113-
export const RESETTABLE_RETRY_CONFIG_OPTIONS: ResettableKeys<
114-
ManifestEndpoint["taskQueueTrigger"]["retryConfig"]
115-
> = {
116-
maxAttempts: null,
117-
maxDoublings: null,
118-
maxBackoffSeconds: null,
119-
maxRetrySeconds: null,
120-
minBackoffSeconds: null,
121-
};
122-
123-
/** @internal */
124-
export const RESETTABLE_RATE_LIMITS_OPTIONS: ResettableKeys<
125-
ManifestEndpoint["taskQueueTrigger"]["rateLimits"]
126-
> = {
127-
maxConcurrentDispatches: null,
128-
maxDispatchesPerSecond: null,
129-
};
130-
131111
/** @internal */
132112
export function onDispatchHandler<Req = any>(
133113
handler: v1TaskHandler | v2TaskHandler<Req>

src/runtime/manifest.ts

Lines changed: 117 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121
// SOFTWARE.
2222

23-
import { ResetValue } from "../common/options";
23+
import { RESET_VALUE, RESETTABLE_OPTIONS, ResettableKeys, ResetValue } from "../common/options";
2424
import { Expression } from "../params";
2525
import { WireParamSpec } from "../params/types";
2626

@@ -64,14 +64,14 @@ export interface ManifestEndpoint {
6464
};
6565

6666
taskQueueTrigger?: {
67-
retryConfig: {
67+
retryConfig?: {
6868
maxAttempts?: number | Expression<number> | ResetValue;
6969
maxRetrySeconds?: number | Expression<number> | ResetValue;
7070
maxBackoffSeconds?: number | Expression<number> | ResetValue;
7171
maxDoublings?: number | Expression<number> | ResetValue;
7272
minBackoffSeconds?: number | Expression<number> | ResetValue;
7373
};
74-
rateLimits: {
74+
rateLimits?: {
7575
maxConcurrentDispatches?: number | Expression<number> | ResetValue;
7676
maxDispatchesPerSecond?: number | Expression<number> | ResetValue;
7777
};
@@ -137,3 +137,117 @@ export function stackToWire(stack: ManifestStack): Record<string, unknown> {
137137
traverse(wireStack.endpoints);
138138
return wireStack;
139139
}
140+
141+
/**
142+
* @internal
143+
*/
144+
export function initEndpoint(...opts: { preserveExternalChanges?: boolean }[]): ManifestEndpoint {
145+
const endpoint: ManifestEndpoint = {};
146+
if (opts.every((opt) => !opt.preserveExternalChanges)) {
147+
for (const key of Object.keys(RESETTABLE_OPTIONS)) {
148+
endpoint[key] = RESET_VALUE;
149+
}
150+
// VPC settings is not flat and handled separately.
151+
endpoint.vpc = {
152+
connector: RESET_VALUE,
153+
egressSettings: RESET_VALUE,
154+
};
155+
}
156+
return endpoint;
157+
}
158+
159+
const RESETTABLE_RETRY_CONFIG_OPTIONS: ResettableKeys<
160+
ManifestEndpoint["taskQueueTrigger"]["retryConfig"]
161+
> = {
162+
maxAttempts: null,
163+
maxDoublings: null,
164+
maxBackoffSeconds: null,
165+
maxRetrySeconds: null,
166+
minBackoffSeconds: null,
167+
};
168+
169+
const RESETTABLE_RATE_LIMITS_OPTIONS: ResettableKeys<
170+
ManifestEndpoint["taskQueueTrigger"]["rateLimits"]
171+
> = {
172+
maxConcurrentDispatches: null,
173+
maxDispatchesPerSecond: null,
174+
};
175+
176+
/**
177+
* @internal
178+
*/
179+
export function initTaskQueueTrigger(
180+
...opts: { preserveExternalChanges?: boolean }[]
181+
): ManifestEndpoint["taskQueueTrigger"] {
182+
let taskQueueTrigger = {};
183+
if (opts.every((opt) => !opt.preserveExternalChanges)) {
184+
const retryConfig = {};
185+
for (const key of Object.keys(RESETTABLE_RETRY_CONFIG_OPTIONS)) {
186+
retryConfig[key] = RESET_VALUE;
187+
}
188+
const rateLimits = {};
189+
for (const key of Object.keys(RESETTABLE_RATE_LIMITS_OPTIONS)) {
190+
rateLimits[key] = RESET_VALUE;
191+
}
192+
taskQueueTrigger = { retryConfig, rateLimits };
193+
}
194+
return taskQueueTrigger;
195+
}
196+
197+
export const RESETTABLE_V1_SCHEDULE_OPTIONS: Omit<
198+
ResettableKeys<ManifestEndpoint["scheduleTrigger"]["retryConfig"]>,
199+
"maxBackoffSeconds" | "minBackoffSeconds" | "maxRetrySeconds"
200+
> = {
201+
retryCount: null,
202+
maxDoublings: null,
203+
maxRetryDuration: null,
204+
maxBackoffDuration: null,
205+
minBackoffDuration: null,
206+
};
207+
208+
const RESETTABLE_V2_SCHEDULE_OPTIONS: Omit<
209+
ResettableKeys<ManifestEndpoint["scheduleTrigger"]["retryConfig"]>,
210+
"maxRetryDuration" | "maxBackoffDuration" | "minBackoffDuration"
211+
> = {
212+
retryCount: null,
213+
maxDoublings: null,
214+
maxRetrySeconds: null,
215+
minBackoffSeconds: null,
216+
maxBackoffSeconds: null,
217+
};
218+
219+
function initScheduleTrigger(
220+
resetOptions: Record<string, unknown>,
221+
schedule: string | Expression<string>,
222+
...opts: { preserveExternalChanges?: boolean }[]
223+
): ManifestEndpoint["scheduleTrigger"] {
224+
let scheduleTrigger: ManifestEndpoint["scheduleTrigger"] = { schedule };
225+
if (opts.every((opt) => !opt.preserveExternalChanges)) {
226+
const retryConfig = {};
227+
for (const key of Object.keys(resetOptions)) {
228+
retryConfig[key] = RESET_VALUE;
229+
}
230+
scheduleTrigger = { ...scheduleTrigger, timeZone: RESET_VALUE, retryConfig };
231+
}
232+
return scheduleTrigger;
233+
}
234+
235+
/**
236+
* @internal
237+
*/
238+
export function initV1ScheduleTrigger(
239+
schedule: string | Expression<string>,
240+
...opts: { preserveExternalChanges?: boolean }[]
241+
): ManifestEndpoint["scheduleTrigger"] {
242+
return initScheduleTrigger(RESETTABLE_V1_SCHEDULE_OPTIONS, schedule, ...opts);
243+
}
244+
245+
/**
246+
* @internal
247+
*/
248+
export function initV2ScheduleTrigger(
249+
schedule: string | Expression<string>,
250+
...opts: { preserveExternalChanges?: boolean }[]
251+
): ManifestEndpoint["scheduleTrigger"] {
252+
return initScheduleTrigger(RESETTABLE_V2_SCHEDULE_OPTIONS, schedule, ...opts);
253+
}

src/v1/cloud-functions.ts

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,26 +25,19 @@ import { warn } from "../logger";
2525
import { DeploymentOptions, RESET_VALUE } from "./function-configuration";
2626
export { Request, Response };
2727
import { convertIfPresent, copyIfPresent } from "../common/encoding";
28-
import { ManifestEndpoint, ManifestRequiredAPI } from "../runtime/manifest";
29-
import { RESETTABLE_OPTIONS, ResettableKeys, ResetValue } from "../common/options";
28+
import {
29+
initEndpoint,
30+
initV1ScheduleTrigger,
31+
ManifestEndpoint,
32+
ManifestRequiredAPI,
33+
} from "../runtime/manifest";
34+
import { ResetValue } from "../common/options";
3035

3136
export { Change } from "../common/change";
3237

3338
/** @internal */
3439
const WILDCARD_REGEX = new RegExp("{[^/{}]*}", "g");
3540

36-
/** @internal */
37-
export const RESETTABLE_SCHEDULE_OPTIONS: Omit<
38-
ResettableKeys<ManifestEndpoint["scheduleTrigger"]["retryConfig"]>,
39-
"maxBackoffSeconds" | "minBackoffSeconds" | "maxRetrySeconds"
40-
> = {
41-
retryCount: null,
42-
maxDoublings: null,
43-
maxRetryDuration: null,
44-
maxBackoffDuration: null,
45-
minBackoffDuration: null,
46-
};
47-
4841
/**
4942
* Wire format for an event.
5043
*/
@@ -381,21 +374,12 @@ export function makeCloudFunction<EventData>({
381374

382375
const endpoint: ManifestEndpoint = {
383376
platform: "gcfv1",
377+
...initEndpoint(options),
384378
...optionsToEndpoint(options),
385379
};
386380

387381
if (options.schedule) {
388-
let scheduleTrigger: ManifestEndpoint["scheduleTrigger"] = {
389-
schedule: options.schedule.schedule,
390-
};
391-
if (!options.preserveExternalChanges) {
392-
const retryConfig = {};
393-
for (const key of Object.keys(RESETTABLE_SCHEDULE_OPTIONS)) {
394-
retryConfig[key] = RESET_VALUE;
395-
}
396-
scheduleTrigger = { ...scheduleTrigger, timeZone: RESET_VALUE, retryConfig };
397-
}
398-
endpoint.scheduleTrigger = scheduleTrigger;
382+
endpoint.scheduleTrigger = initV1ScheduleTrigger(options.schedule.schedule, options);
399383
copyIfPresent(endpoint.scheduleTrigger, options.schedule, "timeZone");
400384
copyIfPresent(
401385
endpoint.scheduleTrigger.retryConfig,
@@ -406,7 +390,6 @@ export function makeCloudFunction<EventData>({
406390
"maxRetryDuration",
407391
"minBackoffDuration"
408392
);
409-
endpoint.scheduleTrigger = scheduleTrigger;
410393
} else {
411394
endpoint.eventTrigger = {
412395
eventType: legacyEventType || provider + "." + eventType,
@@ -490,12 +473,7 @@ function _detectAuthType(event: Event) {
490473

491474
/** @internal */
492475
export function optionsToEndpoint(options: DeploymentOptions): ManifestEndpoint {
493-
const endpoint: ManifestEndpoint = {};
494-
if (!options.preserveExternalChanges) {
495-
for (const key of Object.keys(RESETTABLE_OPTIONS)) {
496-
endpoint[key] = RESET_VALUE;
497-
}
498-
}
476+
const endpoint: ManifestEndpoint = initEndpoint(options);
499477
copyIfPresent(
500478
endpoint,
501479
options,
@@ -512,7 +490,7 @@ export function optionsToEndpoint(options: DeploymentOptions): ManifestEndpoint
512490
);
513491
if (options?.vpcConnector !== undefined) {
514492
if (options.vpcConnector === null || options.vpcConnector instanceof ResetValue) {
515-
endpoint.vpc = null;
493+
endpoint.vpc = { connector: RESET_VALUE, egressSettings: RESET_VALUE };
516494
} else {
517495
const vpc: ManifestEndpoint["vpc"] = { connector: options.vpcConnector };
518496
convertIfPresent(vpc, options, "egressSettings", "vpcConnectorEgressSettings");

src/v1/providers/auth.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import {
4242
optionsToEndpoint,
4343
} from "../cloud-functions";
4444
import { DeploymentOptions } from "../function-configuration";
45+
import { initEndpoint } from "../../runtime/manifest";
4546

4647
// TODO: yank in next breaking change release
4748
export { UserRecord, UserInfo, UserRecordMetadata, userRecordConstructor };
@@ -215,6 +216,7 @@ export class UserBuilder {
215216
func.__endpoint = {
216217
platform: "gcfv1",
217218
labels: {},
219+
...initEndpoint(this.options),
218220
...optionsToEndpoint(this.options),
219221
blockingTrigger: {
220222
eventType: legacyEventType,

src/v1/providers/https.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import {
3232
} from "../../common/providers/https";
3333
import { HttpsFunction, optionsToEndpoint, Runnable } from "../cloud-functions";
3434
import { DeploymentOptions } from "../function-configuration";
35+
import { initEndpoint } from "../../runtime/manifest";
3536

3637
export { Request, CallableContext, FunctionsErrorCode, HttpsError };
3738

@@ -69,6 +70,7 @@ export function _onRequestWithOptions(
6970

7071
cloudFunction.__endpoint = {
7172
platform: "gcfv1",
73+
...initEndpoint(options),
7274
...optionsToEndpoint(options),
7375
httpsTrigger: {},
7476
};
@@ -102,6 +104,7 @@ export function _onCallWithOptions(
102104
func.__endpoint = {
103105
platform: "gcfv1",
104106
labels: {},
107+
...initEndpoint(options),
105108
...optionsToEndpoint(options),
106109
callableTrigger: {},
107110
};

src/v1/providers/tasks.ts

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,17 @@ import { Request } from "../../common/providers/https";
2727
import {
2828
onDispatchHandler,
2929
RateLimits,
30-
RESETTABLE_RATE_LIMITS_OPTIONS,
31-
RESETTABLE_RETRY_CONFIG_OPTIONS,
3230
RetryConfig,
3331
TaskContext,
3432
} from "../../common/providers/tasks";
35-
import { ManifestEndpoint, ManifestRequiredAPI } from "../../runtime/manifest";
33+
import {
34+
initEndpoint,
35+
initTaskQueueTrigger,
36+
ManifestEndpoint,
37+
ManifestRequiredAPI,
38+
} from "../../runtime/manifest";
3639
import { optionsToEndpoint } from "../cloud-functions";
37-
import { DeploymentOptions, RESET_VALUE } from "../function-configuration";
40+
import { DeploymentOptions } from "../function-configuration";
3841

3942
export { RetryConfig, RateLimits, TaskContext };
4043

@@ -103,23 +106,11 @@ export class TaskQueueBuilder {
103106
const fixedLen = (data: any, context: TaskContext) => handler(data, context);
104107
const func: any = onDispatchHandler(fixedLen);
105108

106-
let taskQueueTrigger = {};
107-
if (!this.depOpts?.preserveExternalChanges) {
108-
const retryConfig = {};
109-
for (const key of Object.keys(RESETTABLE_RETRY_CONFIG_OPTIONS)) {
110-
retryConfig[key] = RESET_VALUE;
111-
}
112-
const rateLimits = {};
113-
for (const key of Object.keys(RESETTABLE_RATE_LIMITS_OPTIONS)) {
114-
rateLimits[key] = RESET_VALUE;
115-
}
116-
taskQueueTrigger = { retryConfig, rateLimits };
117-
}
118-
119109
func.__endpoint = {
120110
platform: "gcfv1",
111+
...initEndpoint(this.depOpts),
121112
...optionsToEndpoint(this.depOpts),
122-
taskQueueTrigger,
113+
taskQueueTrigger: initTaskQueueTrigger(this.depOpts),
123114
};
124115
copyIfPresent(func.__endpoint.taskQueueTrigger, this.tqOpts, "retryConfig");
125116
copyIfPresent(func.__endpoint.taskQueueTrigger, this.tqOpts, "rateLimits");

0 commit comments

Comments
 (0)