ac-fhir-models
Advanced tools
Comparing version 5.6.0 to 6.0.0
62
index.js
@@ -194,2 +194,29 @@ 'use strict'; | ||
const toString = unitArr => { | ||
let buff = ''; | ||
for (let i = 0, l = unitArr.length; i < l; i++) { | ||
buff += String.fromCharCode(unitArr[i]); | ||
} | ||
return buff | ||
}; | ||
// convert a Unicode string to a string in which | ||
// each 16-bit unit occupies only one byte | ||
const safeToBinary = string => { | ||
const codeUnits = new Uint16Array(string.length); | ||
for (let i = 0; i < codeUnits.length; i++) { | ||
codeUnits[i] = string.charCodeAt(i); | ||
} | ||
return btoa(toString(new Uint8Array(codeUnits.buffer))) | ||
}; | ||
const fromBinary = encoded => { | ||
const binary = atob(encoded); | ||
const bytes = new Uint8Array(binary.length); | ||
for (let i = 0; i < bytes.length; i++) { | ||
bytes[i] = binary.charCodeAt(i); | ||
} | ||
return toString(new Uint16Array(bytes.buffer)) | ||
}; | ||
// @ts-check | ||
@@ -278,29 +305,2 @@ | ||
const toString = unitArr => { | ||
let buff = ''; | ||
for (let i = 0, l = unitArr.length; i < l; i++) { | ||
buff += String.fromCharCode(unitArr[i]); | ||
} | ||
return buff | ||
}; | ||
// convert a Unicode string to a string in which | ||
// each 16-bit unit occupies only one byte | ||
const safeToBinary = string => { | ||
const codeUnits = new Uint16Array(string.length); | ||
for (let i = 0; i < codeUnits.length; i++) { | ||
codeUnits[i] = string.charCodeAt(i); | ||
} | ||
return btoa(toString(new Uint8Array(codeUnits.buffer))) | ||
}; | ||
const fromBinary = encoded => { | ||
const binary = atob(encoded); | ||
const bytes = new Uint8Array(binary.length); | ||
for (let i = 0; i < bytes.length; i++) { | ||
bytes[i] = binary.charCodeAt(i); | ||
} | ||
return toString(new Uint16Array(bytes.buffer)) | ||
}; | ||
/** | ||
@@ -1397,9 +1397,2 @@ * @param {string} name` | ||
const polyfillBtoaAtob = () => { | ||
// eslint-disable-next-line no-undef | ||
global.atob = str => Buffer.from(str, 'base64').toString(); | ||
// eslint-disable-next-line no-undef | ||
global.btoa = str => Buffer.from(str, 'latin1').toString('base64'); | ||
}; | ||
exports.ORGANIZATION_TYPES = ORGANIZATION_TYPES; | ||
@@ -1423,4 +1416,3 @@ exports.VALID_APPOINTMENT_STATUSES = VALID_APPOINTMENT_STATUSES; | ||
exports.patientDefinition = patientDefinition; | ||
exports.polyfillBtoaAtob = polyfillBtoaAtob; | ||
exports.practitionerDefinition = practitionerDefinition; | ||
exports.roomDefinition = roomDefinition; |
@@ -8,2 +8,1 @@ export * from './src/models/location.js' | ||
export * from './src/helpers/fhir-types.js' | ||
export * from './src/helpers/polyfills' |
{ | ||
"name": "ac-fhir-models", | ||
"version": "5.6.0", | ||
"version": "6.0.0", | ||
"author": "Henrik Joreteg <henrik@anesthesiacharting.com>", | ||
@@ -21,2 +21,5 @@ "dependencies": { | ||
}, | ||
"engines": { | ||
"node": ">=16" | ||
}, | ||
"keywords": [], | ||
@@ -23,0 +26,0 @@ "main": "index.js", |
// @ts-check | ||
import dlv from 'dlv' | ||
import { setValue, updateObject } from 'sinks' | ||
import { buildDefinition, setValue, updateObject } from 'sinks' | ||
import { fromBinary, safeToBinary } from './encoding' | ||
@@ -86,29 +87,2 @@ /** | ||
const toString = unitArr => { | ||
let buff = '' | ||
for (let i = 0, l = unitArr.length; i < l; i++) { | ||
buff += String.fromCharCode(unitArr[i]) | ||
} | ||
return buff | ||
} | ||
// convert a Unicode string to a string in which | ||
// each 16-bit unit occupies only one byte | ||
export const safeToBinary = string => { | ||
const codeUnits = new Uint16Array(string.length) | ||
for (let i = 0; i < codeUnits.length; i++) { | ||
codeUnits[i] = string.charCodeAt(i) | ||
} | ||
return btoa(toString(new Uint8Array(codeUnits.buffer))) | ||
} | ||
export const fromBinary = encoded => { | ||
const binary = atob(encoded) | ||
const bytes = new Uint8Array(binary.length) | ||
for (let i = 0; i < bytes.length; i++) { | ||
bytes[i] = binary.charCodeAt(i) | ||
} | ||
return toString(new Uint16Array(bytes.buffer)) | ||
} | ||
/** | ||
@@ -177,2 +151,46 @@ * @param {string} name` | ||
/** | ||
* @param {string} namespace | ||
* @returns {GetterSetter} | ||
*/ | ||
export const getJSONExtensionProp = (namespace, childDefSpec) => { | ||
const childDef = childDefSpec ? buildDefinition(childDefSpec) : null | ||
const getExtensionIndex = obj => | ||
(obj.extension || []).findIndex(item => item.url === namespace) | ||
return { | ||
get: obj => { | ||
const matchingIndex = getExtensionIndex(obj) | ||
if (matchingIndex === -1) { | ||
return null | ||
} | ||
return JSON.parse(obj.extension[matchingIndex].valueString) | ||
}, | ||
set: (obj, updated, definition) => { | ||
const hasExtensions = obj.extension && obj.extension.length | ||
let insertionIndex = !hasExtensions ? 0 : getExtensionIndex(obj) | ||
if (insertionIndex === -1) { | ||
insertionIndex = 0 | ||
} | ||
const newExtensionList = obj.extension ? obj.extension.slice() : [] | ||
if (updated && Object.keys(updated).length) { | ||
if (childDef) { | ||
childDef.validate(updated) | ||
} | ||
newExtensionList[insertionIndex] = { | ||
url: namespace, | ||
valueString: JSON.stringify(updated), | ||
} | ||
} else { | ||
newExtensionList[insertionIndex] = null | ||
} | ||
const filtered = newExtensionList.filter(Boolean) | ||
return definition.setValue( | ||
obj, | ||
'extension', | ||
filtered.length ? filtered : null | ||
) | ||
}, | ||
} | ||
} | ||
/** | ||
* @param {{ | ||
@@ -368,3 +386,3 @@ * namespace: string | ||
) | ||
return matchedIds.length === 0 ? null : matchedIds | ||
return matchedIds.length ? matchedIds : null | ||
}, | ||
@@ -378,7 +396,3 @@ set: (obj, updatedListOfCompositionIds, definition) => { | ||
const newList = [...other, ...updatedReferenceList] | ||
return definition.setValue( | ||
obj, | ||
propName, | ||
newList.length === 0 ? null : newList | ||
) | ||
return definition.setValue(obj, propName, newList.length ? newList : null) | ||
}, | ||
@@ -385,0 +399,0 @@ } |
import { buildDefinition } from 'sinks' | ||
import test from 'tape' | ||
import { fromBinary, safeToBinary } from './encoding.js' | ||
import { createFHIRModelDefinition } from './fhir-model.js' | ||
@@ -9,2 +10,3 @@ import { | ||
getNestedExtensionListProp, | ||
getJSONExtensionProp, | ||
} from './prop-definitions.js' | ||
@@ -486,1 +488,33 @@ | ||
}) | ||
test('getJSONExtensionProp', t => { | ||
const def = createFHIRModelDefinition({ | ||
resourceType: 'Blah', | ||
props: { | ||
reqs: getJSONExtensionProp('https://some', { | ||
'[].name': 'str', | ||
}), | ||
}, | ||
definition: buildDefinition({ | ||
resourceType: 'str', | ||
'extension.[].url': 'str', | ||
'extension.[].valueString': 'str', | ||
}), | ||
}) | ||
t.deepEqual(def.create({}), { resourceType: 'Blah' }) | ||
t.deepEqual(def.create({ reqs: [] }), { resourceType: 'Blah' }) | ||
t.deepEqual(def.create({ reqs: [{ name: 'hi' }] }), { | ||
resourceType: 'Blah', | ||
extension: [{ url: 'https://some', valueString: '[{"name":"hi"}]' }], | ||
}) | ||
t.end() | ||
}) | ||
test('fromBinary toBinary', t => { | ||
const start = 'O₂' | ||
t.equal(fromBinary(safeToBinary(start)), start) | ||
t.end() | ||
}) |
import test from 'tape' | ||
import { compositionDefinition } from './composition' | ||
import { polyfillBtoaAtob } from '../helpers/polyfills' | ||
polyfillBtoaAtob() | ||
test('compositionDefinition', t => { | ||
@@ -132,2 +129,15 @@ const composition = compositionDefinition.create({ | ||
test('test odd characters', t => { | ||
const input = 'O₂' | ||
const thing = compositionDefinition.create({ | ||
caseData: { | ||
something: input, | ||
}, | ||
}) | ||
const output = compositionDefinition.getValues(thing).caseData.something | ||
t.deepEqual(input, output, 'input and output is the same') | ||
t.end() | ||
}) | ||
test('test for really large case data objects', t => { | ||
@@ -134,0 +144,0 @@ const alphabet = 'abcdefghijklmnopqrstuvwxyz' |
123213
4275