Skip to content

fix(functions): preselect list param defaults in multi-select prompts - #11062

Open
Ishkirat-Singh wants to merge 3 commits into
firebase:mainfrom
Ishkirat-Singh:fix/functions-params-multiselect-default
Open

fix(functions): preselect list param defaults in multi-select prompts#11062
Ishkirat-Singh wants to merge 3 commits into
firebase:mainfrom
Ishkirat-Singh:fix/functions-params-multiselect-default

Conversation

@Ishkirat-Singh

Copy link
Copy Markdown

Description

promptSelectMultiple passed the resolved default to the checkbox prompt as default, but @inquirer/checkbox has no such option — it preselects through checked on each choice, and every choice was hardcoded to checked: false. A defineList param with a multi-select input therefore always opened with nothing selected, whatever default it declared.

This marks the choices whose value is in the resolved default as checked. default is kept because the non-interactive path (guard) still returns it.

Found while fixing #11053 in the same file; there is no separate issue for this one.

Scenarios Tested

  • Added preselects the default values in a multi-select prompt to src/deploy/functions/params.spec.ts: a list param with options a/b/c and default ["b", "c"] produces choices checked [false, true, true] and resolves to the expected ParamValue.
  • npx mocha src/deploy/functions/params.spec.ts: 19 passing; the new test fails against main without the fix.

Sample Commands

N/A — the change is in the interactive firebase deploy --only functions param prompt.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request implements preselection of default values for list function parameters in multi-select prompts. It updates promptSelectMultiple to check if each option's value is included in the resolved defaults, adds a corresponding unit test, and updates the changelog. The reviewer suggested a more robust approach to preselection by stringifying the elements of resolvedDefault outside the loop to prevent potential runtime type mismatches and avoid recreating the mapped array on every iteration.

Comment on lines 946 to 956
const response = await checkbox({
// `default` only serves non-interactive mode; the checkbox prompt itself
// preselects through `checked` on each choice.
default: resolvedDefault,
message: prompt,
choices: input.multiSelect.options.map((option: SelectOptions<string>): ListItem => {
return {
checked: false,
checked: resolvedDefault?.includes(option.value.toString()) ?? false,
name: option.label,
value: option.value.toString(),
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To make the preselection more robust against potential runtime type mismatches (e.g., if default values are parsed as numbers or booleans from environment files or configuration), we should stringify the elements of resolvedDefault before performing the .includes() check. Pre-mapping the defaults outside the loop also avoids recreating the mapped array on every iteration.

  const stringifiedDefaults = resolvedDefault?.map((val) => String(val));
  const response = await checkbox({
    // default only serves non-interactive mode; the checkbox prompt itself
    // preselects through checked on each choice.
    default: resolvedDefault,
    message: prompt,
    choices: input.multiSelect.options.map((option: SelectOptions<string>): ListItem => {
      return {
        checked: stringifiedDefaults?.includes(option.value.toString()) ?? false,
        name: option.label,
        value: option.value.toString(),
      };

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 4c59a1a: defaults are stringified once into a Set before the choices are built.

promptSelectMultiple passed the resolved default to the checkbox prompt as
`default`, but @inquirer/checkbox has no such option: it preselects through
`checked` on each choice, and every choice was hardcoded to `checked: false`.
A `defineList` param with a multi-select input therefore always opened with
nothing selected, whatever its declared default.

Mark the choices whose value is in the resolved default as checked. `default`
is kept because the non-interactive path still returns it.
@Ishkirat-Singh
Ishkirat-Singh force-pushed the fix/functions-params-multiselect-default branch from 3ed705f to a36b048 Compare September 10, 2026 19:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants