import graphiteCLIRoutes from '@screenplaydev/graphite-cli-routes' ; import { default as t } from '@screenplaydev/retype' ; import { request } from '@screenplaydev/retyped-routes' ; import prompts from 'prompts' ; import { API_SERVER } from '../../../lib/api' ; import surveyConfig from '../../../lib/config/survey_config' ; import { cliAuthPrecondition } from '../../../lib/preconditions' ; import { logMessageFromGraphite , logNewline } from '../../utils' ; import { postSurveyResponse } from './post_survey' ; export type SurveyT = t . UnwrapSchemaMap < typeof graphiteCLIRoutes . cliSurvey . response > [ 'survey' ] ; export async function getSurvey ( ) { try { const authToken = cliAuthPrecondition ( ) ; const response = await request . requestWithArgs ( API_SERVER , graphiteCLIRoutes . cliSurvey , { } , { authToken : authToken } ) ; if ( response . _response . status === 200 ) { return response . survey ; } } catch ( e ) { } return undefined ; } class ExitedSurveyError extends Error { constructor ( ) { super ( `User exited Graphite survey early` ) ; this . name = 'Killed' ; } } export type SurveyResponseT = { timestamp : number ; responses : { [ question ] : string ; } ; exitedEarly : boolean ; } ; export async function showSurvey ( survey ) { const responses = { timestamp : Date . now ( ) , responses : { } , exitedEarly : false , } ; try { if ( survey === undefined ) { return ; } logNewline ( ) ; if ( survey ?. introMessage !== undefined ) { logMessageFromGraphite ( survey . introMessage ) ; } logNewline ( ) ; await askSurveyQuestions ( { questions : survey . questions , responses : responses , } ) ; logNewline ( ) ; await logAnswers ( { responses : responses , completionMessage : survey ?. completionMessage , } ) ; } catch ( err ) { switch ( err . constructor ) { case ExitedSurveyError : responses . exitedEarly = true ; logNewline ( ) ; await logAnswers ( { responses : responses , completionMessage : survey ?. completionMessage , } ) ; break ; default : throw err ; } } } /**
 * While capturing the responses, mutate the passed-in object so we can always
 * capture and potential responses before the user decided to exit the survey
 * early.
 */ async function askSurveyQuestions ( args ) { for ( const [ index , question ] of args . questions . entries ( ) ) { const onCancel = { onCancel : ( ) => { throw new ExitedSurveyError ( ) ; } , } ; let promptResponse ; const questionText = `Question [${ index + 1 }/${ args . questions . length }]: ${ question . question }` ; switch ( question . type ) { case 'TEXT' : promptResponse = await prompts ( { type : 'text' , name : 'answer' , message : questionText , } , onCancel ) ; break ; case 'OPTIONS' : promptResponse = await prompts ( { type : 'select' , name : 'answer' , message : questionText , choices : question . options . map ( ( option ) => { return { title : option , value : option , } ; } ) , } , onCancel ) ; break ; default : assertUnreachable ( question ) ; continue ; } logNewline ( ) ; args . responses . responses [ question . question ] = promptResponse . answer ; } } function assertUnreachable ( arg ) { } async function logAnswers ( args ) { surveyConfig . setSurveyResponses ( args . responses ) ; await postSurveyResponse ( ) ; if ( args . completionMessage !== undefined ) { logMessageFromGraphite ( args . completionMessage ) ; } return ; }