( question: QuestionItem, response: RequestPermissionResponse, )
| 79 | * options surfaced by the client. |
| 80 | */ |
| 81 | export function outcomeToQuestionAnswer( |
| 82 | question: QuestionItem, |
| 83 | response: RequestPermissionResponse, |
| 84 | ): QuestionAnswers | null { |
| 85 | if (response.outcome.outcome === 'cancelled') return null; |
| 86 | const optionId = response.outcome.optionId; |
| 87 | // Skip — explicit dismissal path; treat the same as `cancelled`. |
| 88 | if (optionId === skipOptionId(0)) return null; |
| 89 | // Selected option — parse the `q0_opt_<i>` shape and look up the |
| 90 | // matching label. Reject anything that does not match the namespace |
| 91 | // (or whose index is out of bounds) defensively rather than crashing. |
| 92 | const match = /^q0_opt_(\d+)$/.exec(optionId); |
| 93 | if (!match) return null; |
| 94 | const optionIndex = Number(match[1]); |
| 95 | if (!Number.isInteger(optionIndex) || optionIndex < 0) return null; |
| 96 | const selected = question.options[optionIndex]; |
| 97 | if (!selected) return null; |
| 98 | return { [question.question]: selected.label }; |
| 99 | } |
no test coverage detected