fhirformjs
Version:
FHIR Questionnaire To Form Converter for rendering
561 lines (553 loc) • 21.9 kB
JavaScript
;
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