[REQUIRED] Environment info
firebase-tools: 15.26.0 (code is unchanged on main at ecda4df)
Platform: Windows (not platform specific)
[REQUIRED] Test case
A non-string param with a select input whose default is not the first option:
import { defineBoolean, select } from "firebase-functions/params";
export const makePublic = defineBoolean("MAKE_PUBLIC", {
label: "Make resized images public",
default: false,
input: select({ Yes: true, No: false }),
});
[REQUIRED] Steps to reproduce
- Declare the param above in a functions codebase.
- Run
firebase deploy --only functions with MAKE_PUBLIC unset so the CLI prompts for it.
- Observe which option is highlighted, then press Enter.
[REQUIRED] Expected behavior
"No" is preselected, since the declared default is false. Pressing Enter stores MAKE_PUBLIC=false.
[REQUIRED] Actual behavior
"Yes" (the first option) is preselected. Pressing Enter stores MAKE_PUBLIC=true.
Cause: promptSelect passes the resolved default to inquirer unchanged but stringifies every option value, so a boolean or number default never matches a choice and inquirer falls back to the first one.
|
async function promptSelect<T extends RawParamValue>( |
|
prompt: string, |
|
input: SelectInput<T>, |
|
resolvedDefault: T | undefined, |
|
converter: (res: string) => T | retryInput, |
|
): Promise<T> { |
|
const response = await select<string>({ |
|
default: resolvedDefault as string, |
|
message: prompt, |
|
choices: input.select.options.map((option: SelectOptions<T>): ListItem => { |
|
return { |
|
checked: false, |
|
name: option.label, |
|
value: option.value.toString(), |
|
}; |
const response = await select<string>({
default: resolvedDefault as string,
...
choices: input.select.options.map((option) => ({
value: option.value.toString(),
Affects defineBoolean and defineInt selects; string selects are fine. Any param whose default is the first option looks correct by coincidence, which is why this is easy to miss.
Suggested fix: default: resolvedDefault?.toString() (or compare against option.value before stringifying). promptSelectMultiple (L953) has the same pattern for defineList defaults.
Found while migrating the storage-resize-images extension to a Function Kit: firebase/extensions#3148 works around it by declaring the param as a string.
[REQUIRED] Environment info
firebase-tools: 15.26.0 (code is unchanged on
mainat ecda4df)Platform: Windows (not platform specific)
[REQUIRED] Test case
A non-string param with a
selectinput whosedefaultis not the first option:[REQUIRED] Steps to reproduce
firebase deploy --only functionswithMAKE_PUBLICunset so the CLI prompts for it.[REQUIRED] Expected behavior
"No" is preselected, since the declared default is
false. Pressing Enter storesMAKE_PUBLIC=false.[REQUIRED] Actual behavior
"Yes" (the first option) is preselected. Pressing Enter stores
MAKE_PUBLIC=true.Cause:
promptSelectpasses the resolved default to inquirer unchanged but stringifies every option value, so a boolean or number default never matches a choice and inquirer falls back to the first one.firebase-tools/src/deploy/functions/params.ts
Lines 914 to 928 in ecda4df
Affects
defineBooleananddefineIntselects; string selects are fine. Any param whose default is the first option looks correct by coincidence, which is why this is easy to miss.Suggested fix:
default: resolvedDefault?.toString()(or compare againstoption.valuebefore stringifying).promptSelectMultiple(L953) has the same pattern fordefineListdefaults.Found while migrating the
storage-resize-imagesextension to a Function Kit: firebase/extensions#3148 works around it by declaring the param as a string.