UNPKG

fhirformjs

Version:

FHIR Questionnaire To Form Converter for rendering

561 lines (553 loc) 21.9 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var tsFhirTypes = require('@ahryman40k/ts-fhir-types'); var uuidv4 = require('uuidv4'); var axios = require('axios'); function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); } function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; } function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); } function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function (t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (c = i[4] || 3, u = i[5] === e ? i[3] : i[5], i[4] = 3, i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i.return) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine(u), _regeneratorDefine(u, o, "Generator"), _regeneratorDefine(u, n, function () { return this; }), _regeneratorDefine(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function () { return { w: i, m: f }; })(); } function _regeneratorDefine(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine = function (e, r, n, t) { if (r) i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n;else { function o(r, n) { _regeneratorDefine(e, r, function (e) { return this._invoke(r, n, e); }); } o("next", 0), o("throw", 1), o("return", 2); } }, _regeneratorDefine(e, r, n, t); } var _extensionToWidget; var FhirJsonForm = function FhirJsonForm(fhirQuestionnaire) { var _fhirQuestionnaire$it, _fhirQuestionnaire$id; var ALL_PROPERTIES = {}; var requiredProperties = []; var UISchema = {}; var fhirQuestionnaireResponse = { resourceType: 'QuestionnaireResponse', item: [], status: tsFhirTypes.R4.QuestionnaireResponseStatusKind._inProgress }; (_fhirQuestionnaire$it = fhirQuestionnaire.item) == null || _fhirQuestionnaire$it.forEach(function (item, _) { // _ is the ignored index // If the item is a group if (item.type === tsFhirTypes.R4.Questionnaire_ItemTypeKind._group) { // Add legend to the group var groupProperty = typeof item.linkId === 'undefined' ? uuidv4.uuid() : item.linkId.toString(); var groupTitle = typeof item.text === 'undefined' ? uuidv4.uuid() : item.text.toString(); UISchema[groupProperty] = {}; ALL_PROPERTIES[groupProperty] = {}; ALL_PROPERTIES[groupProperty]['type'] = 'object'; ALL_PROPERTIES[groupProperty]['title'] = groupTitle; ALL_PROPERTIES[groupProperty]['properties'] = {}; // Get group items from outer item var groupItems = []; if (item.item) groupItems = item.item; groupItems.forEach(function (groupItem, _) { var _fhirQuestionnaireRes; var myProperty = typeof groupItem.linkId === 'undefined' ? uuidv4.uuid() : groupItem.linkId.toString(); ALL_PROPERTIES[groupProperty]['properties'][myProperty] = GetItemProperties(groupItem); if (groupItem.required) { if (ALL_PROPERTIES[groupProperty]['required'] === undefined) { ALL_PROPERTIES[groupProperty]['required'] = []; } ALL_PROPERTIES[groupProperty]['required'].push(myProperty); } UISchema[groupProperty][myProperty] = {}; var uiWidget = GetWidget(groupItem); if (uiWidget !== '') { UISchema[groupProperty][myProperty]['ui:widget'] = uiWidget; } var uiOptions = GetUIOptions(groupItem); if (uiOptions && Object.keys(uiOptions).length) { UISchema[groupProperty][myProperty]['ui:options'] = uiOptions; if (uiOptions != null && uiOptions.unit) { UISchema[groupProperty][myProperty]['ui:placeholder'] = uiOptions.unit; } } (_fhirQuestionnaireRes = fhirQuestionnaireResponse.item) == null || _fhirQuestionnaireRes.push(CreateResponseItem(groupItem)); }); item.required && requiredProperties.push(groupProperty); // Just push the fields if not a group } else { var _fhirQuestionnaireRes2; var myProperty = typeof item.linkId === 'undefined' ? uuidv4.uuid() : item.linkId.toString(); ALL_PROPERTIES[myProperty] = GetItemProperties(item); UISchema[myProperty] = {}; var uiWidget = GetWidget(item); if (uiWidget !== '') { UISchema[myProperty]['ui:widget'] = uiWidget; } var uiOptions = GetUIOptions(item); if (uiOptions && Object.keys(uiOptions).length) { UISchema[myProperty]['ui:options'] = uiOptions; } (_fhirQuestionnaireRes2 = fhirQuestionnaireResponse.item) == null || _fhirQuestionnaireRes2.push(CreateResponseItem(item)); item.required && requiredProperties.push(myProperty); } }); var fhirJsonSchema = { type: 'object', title: (_fhirQuestionnaire$id = fhirQuestionnaire.id) == null ? void 0 : _fhirQuestionnaire$id.toString(), properties: ALL_PROPERTIES, required: requiredProperties }; var fhirForm = { model: fhirQuestionnaireResponse, schema: fhirJsonSchema, uiSchema: UISchema }; return fhirForm; }; /** * Takes a R4.IQuestionnaire_Item and returns an extended FhirJsonField * @param {R4.IQuestionnaire_Item} item * * @returns {FhirJsonField} properties */ var GetItemProperties = function GetItemProperties(item) { var properties = ProcessQuestionnaireItem(item); var itemOptions = GetOptions(item); if (itemOptions !== '') { return _extends({}, properties, itemOptions); } return properties; }; /** * Takes a R4.IQuestionnaire_Item and returns the VueFormGeneratorField * @param {R4.IQuestionnaire_Item} item * * @returns {VueFormGeneratorField} */ var ProcessQuestionnaireItem = function ProcessQuestionnaireItem(item) { var _item$text; var ff_field = { type: GetControlType(item), title: (_item$text = item.text) == null ? void 0 : _item$text.toString() }; return ff_field; }; var GetOptions = function GetOptions(item) { var enumOptions = []; var enumNames = []; if (typeof item.answerOption !== 'undefined') { var _item$answerOption, _ext$valueCodeableCon; (_item$answerOption = item.answerOption) == null || _item$answerOption.forEach(function (choice, _) { var _choice$valueCoding$c, _choice$valueCoding; var code = typeof choice.valueCoding === 'undefined' ? '' : GetControlType(item) === 'integer' ? choice.valueCoding.code && parseInt(choice.valueCoding.code) : (_choice$valueCoding$c = choice.valueCoding.code) == null ? void 0 : _choice$valueCoding$c.toString(); enumOptions.push(typeof code === 'undefined' ? '' : code); var display = (_choice$valueCoding = choice.valueCoding) == null || (_choice$valueCoding = _choice$valueCoding.display) == null ? void 0 : _choice$valueCoding.toString(); if (display !== undefined) { enumNames.push(display); } }); var options = { "enum": enumOptions, enumNames: enumNames }; var ext = (item.extension || [])[0]; var coding = ((ext == null || (_ext$valueCodeableCon = ext.valueCodeableConcept) == null ? void 0 : _ext$valueCodeableCon.coding) || [])[0]; if ((coding == null ? void 0 : coding.code) === EXTENSION_CHECKBOX) { return { uniqueItems: true, items: _extends({ type: "string" }, options) }; } return options; } // if ( // item.type == R4.Questionnaire_ItemTypeKind._choice || // item.type == R4.Questionnaire_ItemTypeKind._openChoice // ) { // return 'select'; // } // if (item.type === R4.Questionnaire_ItemTypeKind._boolean) { // return 'boolean'; // } return ''; }; var GetWidget = function GetWidget(item) { if (item.type === tsFhirTypes.R4.Questionnaire_ItemTypeKind._date || item.type === tsFhirTypes.R4.Questionnaire_ItemTypeKind._dateTime || item.type === tsFhirTypes.R4.Questionnaire_ItemTypeKind._time) { return 'datetime'; } if (item.type == tsFhirTypes.R4.Questionnaire_ItemTypeKind._choice || item.type == tsFhirTypes.R4.Questionnaire_ItemTypeKind._openChoice || item.type == tsFhirTypes.R4.Questionnaire_ItemTypeKind._integer) { var _ext$valueCodeableCon2; var ext = (item.extension || [])[0]; var coding = ((ext == null || (_ext$valueCodeableCon2 = ext.valueCodeableConcept) == null ? void 0 : _ext$valueCodeableCon2.coding) || [])[0]; if (coding != null && coding.code && extensionToWidget[coding == null ? void 0 : coding.code]) { return extensionToWidget[coding == null ? void 0 : coding.code]; } } // if (item.type === R4.Questionnaire_ItemTypeKind._boolean) { // return 'boolean'; // } return ''; }; var GetUIOptions = function GetUIOptions(item) { var extensions = item.extension; return extensions == null ? void 0 : extensions.reduce(function (uiOptions, ext) { var _ext$url, _ext$valueCoding; var splitUrl = ext == null || (_ext$url = ext.url) == null ? void 0 : _ext$url.split('/'); var extensionName = splitUrl && splitUrl[splitUrl.length - 1]; switch (extensionName) { case 'questionnaire-unit': uiOptions['unit'] = ext == null || (_ext$valueCoding = ext.valueCoding) == null ? void 0 : _ext$valueCoding.display; break; case 'questionnaire-sliderStepValue': uiOptions['step'] = ext == null ? void 0 : ext.valueInteger; break; case 'minValue': uiOptions['min'] = ext == null ? void 0 : ext.valueInteger; break; case 'maxValue': uiOptions['max'] = ext == null ? void 0 : ext.valueInteger; break; } return uiOptions; }, {}); }; var GetControlType = function GetControlType(item) { // if ( // item.type == R4.Questionnaire_ItemTypeKind._date || // item.type == R4.Questionnaire_ItemTypeKind._dateTime || // item.type == R4.Questionnaire_ItemTypeKind._time // ) { // return 'dateTimePicker'; // } if (item.type == tsFhirTypes.R4.Questionnaire_ItemTypeKind._choice || item.type == tsFhirTypes.R4.Questionnaire_ItemTypeKind._openChoice) { var _ext$valueCodeableCon3; var ext = (item.extension || [])[0]; var coding = ((ext == null || (_ext$valueCodeableCon3 = ext.valueCodeableConcept) == null ? void 0 : _ext$valueCodeableCon3.coding) || [])[0]; if ((coding == null ? void 0 : coding.code) === EXTENSION_CHECKBOX) { return 'array'; } if ((coding == null ? void 0 : coding.code) === EXTENSION_SLIDER) { return 'integer'; } } if (item.type === tsFhirTypes.R4.Questionnaire_ItemTypeKind._boolean) { return 'boolean'; } if (item.type == tsFhirTypes.R4.Questionnaire_ItemTypeKind._decimal) { return 'number'; } if (item.type == tsFhirTypes.R4.Questionnaire_ItemTypeKind._integer) { return 'integer'; } return 'string'; }; var GetValueType = function GetValueType(item) { switch (item.type) { case tsFhirTypes.R4.Questionnaire_ItemTypeKind._date: return 'item.answer[0].valueDate'; case tsFhirTypes.R4.Questionnaire_ItemTypeKind._time: return 'item.answer[0].valueTime'; case tsFhirTypes.R4.Questionnaire_ItemTypeKind._dateTime: return 'item.answer[0].valueDateTime'; case tsFhirTypes.R4.Questionnaire_ItemTypeKind._integer: return 'item.answer[0].valueInteger'; case tsFhirTypes.R4.Questionnaire_ItemTypeKind._decimal: return 'item.answer[0].valueDecimal'; case tsFhirTypes.R4.Questionnaire_ItemTypeKind._boolean: return 'item.answer[0].valueBoolean'; case tsFhirTypes.R4.Questionnaire_ItemTypeKind._choice: case tsFhirTypes.R4.Questionnaire_ItemTypeKind._openChoice: return 'item.answer[0].valueCoding'; default: return 'item.answer[0].valueString'; } }; var CreateResponseItem = function CreateResponseItem(item) { var _responseItem$answer; var responseItem = { linkId: item.linkId, text: item.text, answer: [] }; var key = GetOnlyValueType(GetValueType(item)); var ans = {}; switch (item.type) { case tsFhirTypes.R4.Questionnaire_ItemTypeKind._choice: case tsFhirTypes.R4.Questionnaire_ItemTypeKind._openChoice: var option = (item.answerOption || [])[0]; ans[key] = Object.keys((option == null ? void 0 : option.valueCoding) || {}).reduce(function (acc, prop) { var _extends2; return _extends({}, acc, (_extends2 = {}, _extends2[prop] = '', _extends2)); }, {}); break; default: ans[key] = ''; break; } (_responseItem$answer = responseItem.answer) == null || _responseItem$answer.push(ans); return responseItem; }; /** * * @param valueType {string} full model path * * @returns {sting} just the type */ var GetOnlyValueType = function GetOnlyValueType(valueType) { var pieces = valueType.split(/[\s.]+/); // Split on . return pieces[pieces.length - 1]; }; var EXTENSION_DROPDOWN = 'drop-down'; var EXTENSION_RADIOBUTTON = 'radio-button'; var EXTENSION_CHECKBOX = 'check-box'; var EXTENSION_SLIDER = 'slider'; var extensionToWidget = (_extensionToWidget = {}, _extensionToWidget[EXTENSION_DROPDOWN] = 'select', _extensionToWidget[EXTENSION_RADIOBUTTON] = 'radio', _extensionToWidget[EXTENSION_CHECKBOX] = 'checkboxes', _extensionToWidget[EXTENSION_SLIDER] = 'range', _extensionToWidget); var supportedValueTypes = ['valueString', 'valueBoolean', 'valueDate', 'valueInteger', 'valueDecimal', 'valueCoding']; var FhirJsonResp = function FhirJsonResp(fhirResponse, formData, schema) { var _fhirResponse$item; (_fhirResponse$item = fhirResponse.item) == null || _fhirResponse$item.forEach(function (item, _) { var _item$answer; var myProperty = typeof item.linkId === 'undefined' ? uuidv4.uuid() : item.linkId.toString(); var myValue = _getObject(formData, myProperty); var myElement = (_item$answer = item.answer) == null ? void 0 : _item$answer.pop(); if (myElement && item.answer) { item.answer = item.answer.concat(formValueToFhirAnswer(myValue, myElement, schema, myProperty)); } }); return fhirResponse; }; // https://stackoverflow.com/questions/15523514/find-by-key-deep-in-a-nested-array var _getObject = function getObject(theObject, theProperty, returnObjects) { var result = null; if (theObject instanceof Array) { for (var i = 0; i < theObject.length; i++) { // end of the road of value is a string if (typeof theObject[i] === "string") { break; } result = _getObject(theObject[i], theProperty, returnObjects); if (result) { break; } } } else { for (var prop in theObject) { if (prop === theProperty && (!(theObject[prop] instanceof Object) || returnObjects)) { return theObject[prop]; } if (theObject[prop] instanceof Object || theObject[prop] instanceof Array) { result = _getObject(theObject[prop], theProperty, returnObjects); if (result) { break; } } } } return result; }; var formValueToFhirAnswer = function formValueToFhirAnswer(formDataValue, fhirElement, jsonSchema, linkId) { return supportedValueTypes.reduce(function (answer, propertyName) { if (fhirElement && fhirElement.hasOwnProperty(propertyName)) { var linkProperties = _getObject(jsonSchema.properties, linkId, true); var enumNames = linkProperties == null ? void 0 : linkProperties.enumNames; if (enumNames) { var _answer$push; var valueIndex = linkProperties["enum"].indexOf(formDataValue); answer.push((_answer$push = {}, _answer$push[propertyName] = { code: formDataValue !== null && formDataValue !== void 0 ? "" + formDataValue : formDataValue, display: enumNames[valueIndex] || null }, _answer$push)); } else { var _answer$push2; answer.push((_answer$push2 = {}, _answer$push2[propertyName] = formDataValue, _answer$push2)); } } return answer; }, []); }; /** * */ var FhirBackend = /*#__PURE__*/function () { function FhirBackend(baseUrl) { this.baseUrl = ''; this.questionnaireBundle = { resourceType: "Bundle" }; if (baseUrl != '') this.baseUrl = baseUrl; } var _proto = FhirBackend.prototype; _proto.initialize = /*#__PURE__*/function () { var _initialize = /*#__PURE__*/_asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() { var response; return _regenerator().w(function (_context) { while (1) switch (_context.n) { case 0: _context.n = 1; return axios.get(this.baseUrl + '/Questionnaire'); case 1: response = _context.v; this.questionnaireBundle = response.data; case 2: return _context.a(2); } }, _callee, this); })); function initialize() { return _initialize.apply(this, arguments); } return initialize; }(); _proto.getQuestionnaires = function getQuestionnaires() { return this.questionnaireBundle; }; _proto.getTableOfContents = function getTableOfContents() { var _this$questionnaireBu; return (_this$questionnaireBu = this.questionnaireBundle) == null || (_this$questionnaireBu = _this$questionnaireBu.entry) == null ? void 0 : _this$questionnaireBu.map(function (entry) { var _entry$resource; return { fullUrl: entry.fullUrl, id: (_entry$resource = entry.resource) == null ? void 0 : _entry$resource.id }; }); }; _proto.getQuestionnaire = function getQuestionnaire(id) { var _this$questionnaireBu2; return (_this$questionnaireBu2 = this.questionnaireBundle) == null || (_this$questionnaireBu2 = _this$questionnaireBu2.entry) == null || (_this$questionnaireBu2 = _this$questionnaireBu2.find(function (entry) { var _entry$resource2; return ((_entry$resource2 = entry.resource) == null ? void 0 : _entry$resource2.id) === id; })) == null ? void 0 : _this$questionnaireBu2.resource; }; return FhirBackend; }(); exports.FhirBackend = FhirBackend; exports.FhirJsonForm = FhirJsonForm; exports.FhirJsonResp = FhirJsonResp; //# sourceMappingURL=fhirformjs.cjs.development.js.map