UNPKG

@lifeomic/cli

Version:

CLI for interacting with the LifeOmic PHC API.

120 lines (111 loc) 4.06 kB
'use strict'; const querystring = require('querystring'); const { get } = require('../../api'); const plainPrint = require('../../plainPrint'); exports.command = 'export-responses <projectId> <surveyId>'; exports.desc = 'Export all responses in .csv format'; exports.builder = yargs => { yargs.positional('projectId', { describe: 'The ID of the project containing the survey.', type: 'string' }).positional('surveyId', { describe: 'The ID of the survey to export responses from.', type: 'string' }).option( 'query', { describe: 'Optional query', type: 'string' } ); }; function buildQuestionList (surveyItem, results) { if (surveyItem.linkId && surveyItem.text && surveyItem.type && surveyItem.type !== 'group' && surveyItem.type !== 'display') { results.push({ text: surveyItem.text.replace(/\n/g, ' ').replace(/"/g, '""'), linkId: surveyItem.linkId }); } if (surveyItem.item) { (surveyItem.item || []).forEach(_ => buildQuestionList(_, results)); } } function generateLinkAnswerMap (responseItem, results) { if (responseItem.linkId && responseItem.answer) { results[responseItem.linkId] = responseItem.answer; } if (responseItem.item) { (responseItem.item || []).forEach(_ => generateLinkAnswerMap(_, results)); } } function handleDefaultValue (value) { return value[Object.keys(value)[0]]; } function handleValueCoding (coding) { if (coding.valueCoding.display) { return coding.valueCoding.display; } else if (coding.valueCoding.code) { return coding.valueCoding.code; } else { return ''; } } function handleValueQuantity (responseValue) { const { value = '', unit = '' } = responseValue.valueQuantity || {}; return `${value} ${unit}`; } exports.handler = async argv => { const query = argv.query ? querystring.parse(argv.query) : {}; const surveyUrl = `/v1/survey/projects/${argv.projectId}/surveys/${argv.surveyId}`; const survey = await get(argv, surveyUrl); const results = [{text: 'Patient ID', linkId: ''}, {text: 'Date', linkId: ''}]; (survey.data.item || []).forEach(_ => buildQuestionList(_, results)); const responseItems = []; const responseQuery = querystring.stringify({ 'surveyId': `${argv.surveyId}`, 'pageSize': 10, ...query }); const responsesUrl = `/v1/survey/projects/${argv.projectId}/responses?${responseQuery}`; let responses = await get(argv, responsesUrl); responseItems.push(...responses.data.items); while (responses.data.links.next) { const nextPageUrl = responses.data.links.next; responses = await get(argv, nextPageUrl); responseItems.push(...responses.data.items); } const csvRows = []; csvRows.push(`"${results.map(_ => _.text).join('","')}"`); responseItems.forEach(responseItem => { const responseColumns = []; responseColumns.push(responseItem.subject.reference); responseColumns.push(responseItem.authored); const responseItemResults = {}; (responseItem.item || []).forEach(_ => generateLinkAnswerMap(_, responseItemResults)); results.map(_ => _.linkId) .filter(_ => _ !== '') .forEach(linkId => { if (responseItemResults[linkId]) { let responseString = ''; responseItemResults[linkId].forEach(value => { if (value.valueQuantity) { responseString = responseString.concat(handleValueQuantity(value)); } else if (value.valueCoding) { responseString = responseString.concat(handleValueCoding(value)); } else { responseString = responseString.concat(handleDefaultValue(value)); } responseString = responseString.concat('|'); }); responseColumns.push(responseString.slice(0, -1).replace(/"/g, '""').replace(/\n/g, ' ')); } else { // optional questions may not have answers responseColumns.push(''); } }); csvRows.push(`"${responseColumns.join('","')}"`); }); plainPrint(csvRows.join('\n')); };