From 7ec65270fe98b9f96033684542c2023791460fda Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Mon, 15 Dec 2025 18:53:03 -0800 Subject: [PATCH 1/7] fix: allow JsonSecretParam in secrets array JsonSecretParam was not accepted in the `secrets` option array because: 1. The type was defined as `(string | SecretParam)[]`, excluding JsonSecretParam 2. Runtime converters only checked for `instanceof SecretParam` Fixes https://github.com/firebase/firebase-functions/issues/1783 --- spec/params/params.spec.ts | 1 + spec/v1/cloud-functions.spec.ts | 26 +++++++++++++ spec/v2/options.spec.ts | 43 ++++++++++++++++++++++ src/params/types.ts | 6 +++ src/v1/cloud-functions.ts | 9 +++-- src/v1/function-builder.ts | 7 +++- src/v1/function-configuration.ts | 4 +- src/v2/options.ts | 11 ++++-- src/v2/providers/alerts/alerts.ts | 4 +- src/v2/providers/alerts/appDistribution.ts | 4 +- src/v2/providers/alerts/crashlytics.ts | 4 +- src/v2/providers/database.ts | 4 +- src/v2/providers/eventarc.ts | 4 +- src/v2/providers/https.ts | 4 +- src/v2/providers/identity.ts | 4 +- src/v2/providers/pubsub.ts | 4 +- src/v2/providers/storage.ts | 4 +- src/v2/providers/tasks.ts | 4 +- 18 files changed, 116 insertions(+), 31 deletions(-) create mode 100644 spec/v2/options.spec.ts diff --git a/spec/params/params.spec.ts b/spec/params/params.spec.ts index 1a37c40cb..553d20ea6 100644 --- a/spec/params/params.spec.ts +++ b/spec/params/params.spec.ts @@ -437,3 +437,4 @@ describe("Params as CEL", () => { ).to.equal("{{ params.A != params.B ? params.FOO : params.BAR }}"); }); }); + diff --git a/spec/v1/cloud-functions.spec.ts b/spec/v1/cloud-functions.spec.ts index 8729f300b..0753fb0a2 100644 --- a/spec/v1/cloud-functions.spec.ts +++ b/spec/v1/cloud-functions.spec.ts @@ -31,6 +31,7 @@ import { RESET_VALUE, } from "../../src/v1"; import { MINIMAL_V1_ENDPOINT } from "../fixtures"; +import { defineJsonSecret, defineSecret } from "../../src/params"; describe("makeCloudFunction", () => { const cloudFunctionArgs: MakeCloudFunctionArgs = { @@ -161,6 +162,31 @@ describe("makeCloudFunction", () => { }); }); + it("should accept all valid secret types in secrets array (type test)", () => { + // This is a compile-time type test. If any of these types are not assignable + // to the secrets array, TypeScript will fail to compile this test file. + const jsonSecret = defineJsonSecret<{ key: string }>("JSON_SECRET"); + const stringSecret = defineSecret("STRING_SECRET"); + const plainSecret = "PLAIN_SECRET"; + + const cf = makeCloudFunction({ + provider: "mock.provider", + eventType: "mock.event", + service: "service", + triggerResource: () => "resource", + handler: () => null, + options: { + secrets: [plainSecret, stringSecret, jsonSecret], + }, + }); + + expect(cf.__endpoint.secretEnvironmentVariables).to.deep.equal([ + { key: "PLAIN_SECRET" }, + { key: "STRING_SECRET" }, + { key: "JSON_SECRET" }, + ]); + }); + it("should set retry given failure policy in __endpoint", () => { const cf = makeCloudFunction({ provider: "mock.provider", diff --git a/spec/v2/options.spec.ts b/spec/v2/options.spec.ts new file mode 100644 index 000000000..7594cb062 --- /dev/null +++ b/spec/v2/options.spec.ts @@ -0,0 +1,43 @@ +// The MIT License (MIT) +// +// Copyright (c) 2022 Firebase +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import { expect } from "chai"; +import { defineJsonSecret, defineSecret } from "../../src/params"; +import { GlobalOptions } from "../../src/v2/options"; + +describe("v2/options", () => { + describe("GlobalOptions", () => { + it("should accept all valid secret types in secrets array (type test)", () => { + // This is a compile-time type test. If any of these types are not assignable + // to the secrets array, TypeScript will fail to compile this test file. + const jsonSecret = defineJsonSecret<{ key: string }>("JSON_SECRET"); + const stringSecret = defineSecret("STRING_SECRET"); + const plainSecret = "PLAIN_SECRET"; + + const opts: GlobalOptions = { + secrets: [plainSecret, stringSecret, jsonSecret], + }; + + expect(opts.secrets).to.have.length(3); + }); + }); +}); diff --git a/src/params/types.ts b/src/params/types.ts index 14f7ce69d..0d9028b17 100644 --- a/src/params/types.ts +++ b/src/params/types.ts @@ -535,6 +535,12 @@ export class JsonSecretParam { } } +/** + * A union type representing all valid secret parameter types that can be used + * in a function's `secrets` configuration array. + */ +export type SupportedSecretParam = string | SecretParam | JsonSecretParam; + /** * A parametrized value of String type that will be read from .env files * if present, or prompted for by the CLI if missing. diff --git a/src/v1/cloud-functions.ts b/src/v1/cloud-functions.ts index ac0d87752..da4e6f0fa 100644 --- a/src/v1/cloud-functions.ts +++ b/src/v1/cloud-functions.ts @@ -43,7 +43,7 @@ import { ManifestRequiredAPI, } from "../runtime/manifest"; import { ResetValue } from "../common/options"; -import { SecretParam } from "../params/types"; +import { JsonSecretParam, SecretParam, SupportedSecretParam } from "../params/types"; import { withInit } from "../common/onInit"; export { Change } from "../common/change"; @@ -638,8 +638,11 @@ export function optionsToEndpoint(options: DeploymentOptions): ManifestEndpoint options, "secretEnvironmentVariables", "secrets", - (secrets: (string | SecretParam)[]) => - secrets.map((secret) => ({ key: secret instanceof SecretParam ? secret.name : secret })) + (secrets: SupportedSecretParam[]) => + secrets.map((secret) => ({ + key: + secret instanceof SecretParam || secret instanceof JsonSecretParam ? secret.name : secret, + })) ); if (options?.vpcConnector !== undefined) { if (options.vpcConnector === null || options.vpcConnector instanceof ResetValue) { diff --git a/src/v1/function-builder.ts b/src/v1/function-builder.ts index e70f26166..c8c69a710 100644 --- a/src/v1/function-builder.ts +++ b/src/v1/function-builder.ts @@ -23,7 +23,7 @@ import * as express from "express"; import { ResetValue } from "../common/options"; -import { Expression, SecretParam } from "../params/types"; +import { Expression, JsonSecretParam, SecretParam } from "../params/types"; import { EventContext } from "./cloud-functions"; import { DeploymentOptions, @@ -200,7 +200,10 @@ function assertRuntimeOptionsValid(runtimeOptions: RuntimeOptions): boolean { if (runtimeOptions.secrets !== undefined) { const invalidSecrets = runtimeOptions.secrets.filter( - (s) => !/^[A-Za-z\d\-_]+$/.test(s instanceof SecretParam ? s.name : s) + (s) => + !/^[A-Za-z\d\-_]+$/.test( + s instanceof SecretParam || s instanceof JsonSecretParam ? s.name : s + ) ); if (invalidSecrets.length > 0) { throw new Error( diff --git a/src/v1/function-configuration.ts b/src/v1/function-configuration.ts index 90aa391fc..fa7b4d5c2 100644 --- a/src/v1/function-configuration.ts +++ b/src/v1/function-configuration.ts @@ -1,6 +1,6 @@ import { Expression } from "../params"; import { ResetValue } from "../common/options"; -import { SecretParam } from "../params/types"; +import { SupportedSecretParam } from "../params/types"; export { RESET_VALUE } from "../common/options"; @@ -235,7 +235,7 @@ export interface RuntimeOptions { /* * Secrets to bind to a function instance. */ - secrets?: (string | SecretParam)[]; + secrets?: SupportedSecretParam[]; /** * Determines whether Firebase AppCheck is enforced. diff --git a/src/v2/options.ts b/src/v2/options.ts index 608db1fa4..21ebdca93 100644 --- a/src/v2/options.ts +++ b/src/v2/options.ts @@ -35,7 +35,7 @@ import { RESET_VALUE, ResetValue } from "../common/options"; import { ManifestEndpoint } from "../runtime/manifest"; import { TriggerAnnotation } from "./core"; import { declaredParams, Expression } from "../params"; -import { ParamSpec, SecretParam } from "../params/types"; +import { JsonSecretParam, ParamSpec, SecretParam, SupportedSecretParam } from "../params/types"; import { HttpsOptions } from "./providers/https"; import * as logger from "../logger"; @@ -210,7 +210,7 @@ export interface GlobalOptions { /* * Secrets to bind to a function. */ - secrets?: (string | SecretParam)[]; + secrets?: SupportedSecretParam[]; /** * Determines whether Firebase App Check is enforced. Defaults to false. @@ -396,8 +396,11 @@ export function optionsToEndpoint( opts, "secretEnvironmentVariables", "secrets", - (secrets: (string | SecretParam)[]) => - secrets.map((secret) => ({ key: secret instanceof SecretParam ? secret.name : secret })) + (secrets: SupportedSecretParam[]) => + secrets.map((secret) => ({ + key: + secret instanceof SecretParam || secret instanceof JsonSecretParam ? secret.name : secret, + })) ); return endpoint; diff --git a/src/v2/providers/alerts/alerts.ts b/src/v2/providers/alerts/alerts.ts index e3b51c549..1cfacd706 100644 --- a/src/v2/providers/alerts/alerts.ts +++ b/src/v2/providers/alerts/alerts.ts @@ -26,7 +26,7 @@ import { CloudEvent, CloudFunction } from "../../core"; import { Expression } from "../../../params"; import { wrapTraceContext } from "../../trace"; import * as options from "../../options"; -import { SecretParam } from "../../../params/types"; +import { SupportedSecretParam } from "../../../params/types"; import { withInit } from "../../../common/onInit"; /** @@ -180,7 +180,7 @@ export interface FirebaseAlertOptions extends options.EventHandlerOptions { /* * Secrets to bind to a function. */ - secrets?: (string | SecretParam)[]; + secrets?: SupportedSecretParam[]; /** Whether failed executions should be delivered again. */ retry?: boolean | Expression | ResetValue; diff --git a/src/v2/providers/alerts/appDistribution.ts b/src/v2/providers/alerts/appDistribution.ts index 6aa54e733..a26c5e108 100644 --- a/src/v2/providers/alerts/appDistribution.ts +++ b/src/v2/providers/alerts/appDistribution.ts @@ -31,7 +31,7 @@ import { CloudEvent, CloudFunction } from "../../core"; import { wrapTraceContext } from "../../trace"; import { convertAlertAndApp, FirebaseAlertData, getEndpointAnnotation } from "./alerts"; import * as options from "../../options"; -import { SecretParam } from "../../../params/types"; +import { SupportedSecretParam } from "../../../params/types"; import { withInit } from "../../../common/onInit"; /** @@ -191,7 +191,7 @@ export interface AppDistributionOptions extends options.EventHandlerOptions { /* * Secrets to bind to a function. */ - secrets?: (string | SecretParam)[]; + secrets?: SupportedSecretParam[]; /** Whether failed executions should be delivered again. */ retry?: boolean | Expression | ResetValue; diff --git a/src/v2/providers/alerts/crashlytics.ts b/src/v2/providers/alerts/crashlytics.ts index 9fd2b26bb..638b7f18e 100644 --- a/src/v2/providers/alerts/crashlytics.ts +++ b/src/v2/providers/alerts/crashlytics.ts @@ -31,7 +31,7 @@ import { CloudEvent, CloudFunction } from "../../core"; import { wrapTraceContext } from "../../trace"; import { convertAlertAndApp, FirebaseAlertData, getEndpointAnnotation } from "./alerts"; import * as options from "../../options"; -import { SecretParam } from "../../../params/types"; +import { SupportedSecretParam } from "../../../params/types"; import { withInit } from "../../../common/onInit"; /** Generic Crashlytics issue interface */ @@ -271,7 +271,7 @@ export interface CrashlyticsOptions extends options.EventHandlerOptions { /* * Secrets to bind to a function. */ - secrets?: (string | SecretParam)[]; + secrets?: SupportedSecretParam[]; /** Whether failed executions should be delivered again. */ retry?: boolean | Expression | ResetValue; diff --git a/src/v2/providers/database.ts b/src/v2/providers/database.ts index c85f01172..a32786528 100644 --- a/src/v2/providers/database.ts +++ b/src/v2/providers/database.ts @@ -33,7 +33,7 @@ import { CloudEvent, CloudFunction } from "../core"; import { Expression } from "../../params"; import { wrapTraceContext } from "../trace"; import * as options from "../options"; -import { SecretParam } from "../../params/types"; +import { SupportedSecretParam } from "../../params/types"; import { withInit } from "../../common/onInit"; export { DataSnapshot }; @@ -192,7 +192,7 @@ export interface ReferenceOptions extends options.E /* * Secrets to bind to a function. */ - secrets?: (string | SecretParam)[]; + secrets?: SupportedSecretParam[]; /** Whether failed executions should be delivered again. */ retry?: boolean | Expression | ResetValue; diff --git a/src/v2/providers/eventarc.ts b/src/v2/providers/eventarc.ts index 48f5974be..f00597bab 100644 --- a/src/v2/providers/eventarc.ts +++ b/src/v2/providers/eventarc.ts @@ -32,7 +32,7 @@ import { CloudEvent, CloudFunction } from "../core"; import { wrapTraceContext } from "../trace"; import { Expression } from "../../params"; import * as options from "../options"; -import { SecretParam } from "../../params/types"; +import { SupportedSecretParam } from "../../params/types"; import { withInit } from "../../common/onInit"; /** Options that can be set on an Eventarc trigger. */ @@ -156,7 +156,7 @@ export interface EventarcTriggerOptions extends options.EventHandlerOptions { /* * Secrets to bind to a function. */ - secrets?: (string | SecretParam)[]; + secrets?: SupportedSecretParam[]; /** Whether failed executions should be delivered again. */ retry?: boolean | Expression | ResetValue; diff --git a/src/v2/providers/https.ts b/src/v2/providers/https.ts index b5ebc5b05..f38400029 100644 --- a/src/v2/providers/https.ts +++ b/src/v2/providers/https.ts @@ -44,7 +44,7 @@ import { import { initV2Endpoint, ManifestEndpoint } from "../../runtime/manifest"; import { GlobalOptions, SupportedRegion } from "../options"; import { Expression } from "../../params"; -import { SecretParam } from "../../params/types"; +import { SupportedSecretParam } from "../../params/types"; import * as options from "../options"; import { withInit } from "../../common/onInit"; import * as logger from "../../logger"; @@ -165,7 +165,7 @@ export interface HttpsOptions extends Omit | ResetValue; diff --git a/src/v2/providers/storage.ts b/src/v2/providers/storage.ts index e05187eb1..f619b814d 100644 --- a/src/v2/providers/storage.ts +++ b/src/v2/providers/storage.ts @@ -33,7 +33,7 @@ import { CloudEvent, CloudFunction } from "../core"; import { wrapTraceContext } from "../trace"; import { Expression } from "../../params"; import * as options from "../options"; -import { SecretParam } from "../../params/types"; +import { SupportedSecretParam } from "../../params/types"; import { withInit } from "../../common/onInit"; /** @@ -297,7 +297,7 @@ export interface StorageOptions extends options.EventHandlerOptions { /* * Secrets to bind to a function. */ - secrets?: (string | SecretParam)[]; + secrets?: SupportedSecretParam[]; /** Whether failed executions should be delivered again. */ retry?: boolean | Expression | ResetValue; diff --git a/src/v2/providers/tasks.ts b/src/v2/providers/tasks.ts index e4e0ca127..90c2bf656 100644 --- a/src/v2/providers/tasks.ts +++ b/src/v2/providers/tasks.ts @@ -38,7 +38,7 @@ import * as options from "../options"; import { wrapTraceContext } from "../trace"; import { HttpsFunction } from "./https"; import { Expression } from "../../params"; -import { SecretParam } from "../../params/types"; +import { SupportedSecretParam } from "../../params/types"; import { initV2Endpoint, initTaskQueueTrigger } from "../../runtime/manifest"; import { withInit } from "../../common/onInit"; @@ -154,7 +154,7 @@ export interface TaskQueueOptions extends options.EventHandlerOptions { /* * Secrets to bind to a function. */ - secrets?: (string | SecretParam)[]; + secrets?: SupportedSecretParam[]; /** Whether failed executions should be delivered again. */ retry?: boolean; From 0ee3d531896e031b1120199fef4df892f590a2b4 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 16 Dec 2025 11:15:24 -0800 Subject: [PATCH 2/7] fix tests. --- spec/params/params.spec.ts | 1 - spec/v2/options.spec.ts | 26 ++++++++++++-------------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/spec/params/params.spec.ts b/spec/params/params.spec.ts index 553d20ea6..1a37c40cb 100644 --- a/spec/params/params.spec.ts +++ b/spec/params/params.spec.ts @@ -437,4 +437,3 @@ describe("Params as CEL", () => { ).to.equal("{{ params.A != params.B ? params.FOO : params.BAR }}"); }); }); - diff --git a/spec/v2/options.spec.ts b/spec/v2/options.spec.ts index 7594cb062..4105f9a1f 100644 --- a/spec/v2/options.spec.ts +++ b/spec/v2/options.spec.ts @@ -1,6 +1,6 @@ // The MIT License (MIT) // -// Copyright (c) 2022 Firebase +// Copyright (c) 2025 Firebase // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -24,20 +24,18 @@ import { expect } from "chai"; import { defineJsonSecret, defineSecret } from "../../src/params"; import { GlobalOptions } from "../../src/v2/options"; -describe("v2/options", () => { - describe("GlobalOptions", () => { - it("should accept all valid secret types in secrets array (type test)", () => { - // This is a compile-time type test. If any of these types are not assignable - // to the secrets array, TypeScript will fail to compile this test file. - const jsonSecret = defineJsonSecret<{ key: string }>("JSON_SECRET"); - const stringSecret = defineSecret("STRING_SECRET"); - const plainSecret = "PLAIN_SECRET"; +describe("GlobalOptions", () => { + it("should accept all valid secret types in secrets array (type test)", () => { + // This is a compile-time type test. If any of these types are not assignable + // to the secrets array, TypeScript will fail to compile this test file. + const jsonSecret = defineJsonSecret<{ key: string }>("JSON_SECRET"); + const stringSecret = defineSecret("STRING_SECRET"); + const plainSecret = "PLAIN_SECRET"; - const opts: GlobalOptions = { - secrets: [plainSecret, stringSecret, jsonSecret], - }; + const opts: GlobalOptions = { + secrets: [plainSecret, stringSecret, jsonSecret], + }; - expect(opts.secrets).to.have.length(3); - }); + expect(opts.secrets).to.have.length(3); }); }); From 0b4cbf622840c3008bee05a115290acea496b2b1 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 16 Dec 2025 11:16:06 -0800 Subject: [PATCH 3/7] Update src/v1/cloud-functions.ts Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- src/v1/cloud-functions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v1/cloud-functions.ts b/src/v1/cloud-functions.ts index da4e6f0fa..c3a93acbf 100644 --- a/src/v1/cloud-functions.ts +++ b/src/v1/cloud-functions.ts @@ -641,7 +641,7 @@ export function optionsToEndpoint(options: DeploymentOptions): ManifestEndpoint (secrets: SupportedSecretParam[]) => secrets.map((secret) => ({ key: - secret instanceof SecretParam || secret instanceof JsonSecretParam ? secret.name : secret, + typeof secret === "string" ? secret : secret.name })) ); if (options?.vpcConnector !== undefined) { From 566387f86eb707b9555d7767e558c6bb95932fef Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 16 Dec 2025 11:16:22 -0800 Subject: [PATCH 4/7] Update src/v2/options.ts Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- src/v2/options.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v2/options.ts b/src/v2/options.ts index 21ebdca93..8a0f2a18d 100644 --- a/src/v2/options.ts +++ b/src/v2/options.ts @@ -399,7 +399,7 @@ export function optionsToEndpoint( (secrets: SupportedSecretParam[]) => secrets.map((secret) => ({ key: - secret instanceof SecretParam || secret instanceof JsonSecretParam ? secret.name : secret, + typeof secret === "string" ? secret : secret.name })) ); From 4345cb95a880ae830718981ba8ca7e67e7bc5c75 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 16 Dec 2025 11:16:33 -0800 Subject: [PATCH 5/7] Update src/v1/function-builder.ts Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- src/v1/function-builder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/v1/function-builder.ts b/src/v1/function-builder.ts index c8c69a710..9a3cb7a86 100644 --- a/src/v1/function-builder.ts +++ b/src/v1/function-builder.ts @@ -202,7 +202,7 @@ function assertRuntimeOptionsValid(runtimeOptions: RuntimeOptions): boolean { const invalidSecrets = runtimeOptions.secrets.filter( (s) => !/^[A-Za-z\d\-_]+$/.test( - s instanceof SecretParam || s instanceof JsonSecretParam ? s.name : s + typeof s === "string" ? s : s.name ) ); if (invalidSecrets.length > 0) { From 7e1915a4e0ea1fd846f509f06763e975dbecaccc Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 16 Dec 2025 11:27:37 -0800 Subject: [PATCH 6/7] nit: remove unused imports --- src/v1/cloud-functions.ts | 5 ++--- src/v1/function-builder.ts | 7 ++----- src/v2/options.ts | 5 ++--- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/v1/cloud-functions.ts b/src/v1/cloud-functions.ts index c3a93acbf..8e88cddee 100644 --- a/src/v1/cloud-functions.ts +++ b/src/v1/cloud-functions.ts @@ -43,7 +43,7 @@ import { ManifestRequiredAPI, } from "../runtime/manifest"; import { ResetValue } from "../common/options"; -import { JsonSecretParam, SecretParam, SupportedSecretParam } from "../params/types"; +import { SupportedSecretParam } from "../params/types"; import { withInit } from "../common/onInit"; export { Change } from "../common/change"; @@ -640,8 +640,7 @@ export function optionsToEndpoint(options: DeploymentOptions): ManifestEndpoint "secrets", (secrets: SupportedSecretParam[]) => secrets.map((secret) => ({ - key: - typeof secret === "string" ? secret : secret.name + key: typeof secret === "string" ? secret : secret.name, })) ); if (options?.vpcConnector !== undefined) { diff --git a/src/v1/function-builder.ts b/src/v1/function-builder.ts index 9a3cb7a86..3e8286933 100644 --- a/src/v1/function-builder.ts +++ b/src/v1/function-builder.ts @@ -23,7 +23,7 @@ import * as express from "express"; import { ResetValue } from "../common/options"; -import { Expression, JsonSecretParam, SecretParam } from "../params/types"; +import { Expression } from "../params/types"; import { EventContext } from "./cloud-functions"; import { DeploymentOptions, @@ -200,10 +200,7 @@ function assertRuntimeOptionsValid(runtimeOptions: RuntimeOptions): boolean { if (runtimeOptions.secrets !== undefined) { const invalidSecrets = runtimeOptions.secrets.filter( - (s) => - !/^[A-Za-z\d\-_]+$/.test( - typeof s === "string" ? s : s.name - ) + (s) => !/^[A-Za-z\d\-_]+$/.test(typeof s === "string" ? s : s.name) ); if (invalidSecrets.length > 0) { throw new Error( diff --git a/src/v2/options.ts b/src/v2/options.ts index 8a0f2a18d..5b7e12aa9 100644 --- a/src/v2/options.ts +++ b/src/v2/options.ts @@ -35,7 +35,7 @@ import { RESET_VALUE, ResetValue } from "../common/options"; import { ManifestEndpoint } from "../runtime/manifest"; import { TriggerAnnotation } from "./core"; import { declaredParams, Expression } from "../params"; -import { JsonSecretParam, ParamSpec, SecretParam, SupportedSecretParam } from "../params/types"; +import { ParamSpec, SupportedSecretParam } from "../params/types"; import { HttpsOptions } from "./providers/https"; import * as logger from "../logger"; @@ -398,8 +398,7 @@ export function optionsToEndpoint( "secrets", (secrets: SupportedSecretParam[]) => secrets.map((secret) => ({ - key: - typeof secret === "string" ? secret : secret.name + key: typeof secret === "string" ? secret : secret.name, })) ); From 871e7e867e41dd1fac0d734ee7a580b0e5ba6a53 Mon Sep 17 00:00:00 2001 From: Daniel Lee Date: Tue, 16 Dec 2025 11:35:13 -0800 Subject: [PATCH 7/7] add changelog. --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69de29bb..4601cb23b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -0,0 +1 @@ +- Allow `JsonSecretParam` in function `secrets` option arrays. (#1788)