@@ -38,6 +38,7 @@ let engine = {}; // the object with all FHIRPath functions and operations
38
38
let existence = require ( "./existence" ) ;
39
39
let filtering = require ( "./filtering" ) ;
40
40
let aggregate = require ( "./aggregate" ) ;
41
+ let supplements = require ( "./supplements" ) ;
41
42
let combining = require ( "./combining" ) ;
42
43
let misc = require ( "./misc" ) ;
43
44
let equality = require ( "./equality" ) ;
@@ -83,6 +84,7 @@ engine.invocationTable = {
83
84
min : { fn : aggregate . minFn } ,
84
85
max : { fn : aggregate . maxFn } ,
85
86
avg : { fn : aggregate . avgFn } ,
87
+ weight : { fn : supplements . weight } ,
86
88
single : { fn : filtering . singleFn } ,
87
89
first : { fn : filtering . firstFn } ,
88
90
last : { fn : filtering . lastFn } ,
@@ -194,7 +196,7 @@ engine.TermExpression = function(ctx, parentData, node) {
194
196
if ( parentData ) {
195
197
parentData = parentData . map ( ( x ) => {
196
198
if ( x instanceof Object && x . resourceType ) {
197
- return makeResNode ( x , x . resourceType , null , x . resourceType ) ;
199
+ return makeResNode ( x , null , x . resourceType , null , x . resourceType ) ;
198
200
}
199
201
return x ;
200
202
} ) ;
@@ -263,17 +265,17 @@ engine.ExternalConstantTerm = function(ctx, parentData, node) {
263
265
if ( Array . isArray ( value ) ) {
264
266
value = value . map (
265
267
i => i ?. __path__
266
- ? makeResNode ( i , i . __path__ . path || null , null ,
268
+ ? makeResNode ( i , i . __path__ . parentResNode , i . __path__ . path || null , null ,
267
269
i . __path__ . fhirNodeDataType || null )
268
270
: i ?. resourceType
269
- ? makeResNode ( i , null , null )
271
+ ? makeResNode ( i , null , null , null )
270
272
: i ) ;
271
273
} else {
272
274
value = value ?. __path__
273
- ? makeResNode ( value , value . __path__ . path || null , null ,
275
+ ? makeResNode ( value , value . __path__ . parentResNode , value . __path__ . path || null , null ,
274
276
value . __path__ . fhirNodeDataType || null )
275
277
: value ?. resourceType
276
- ? makeResNode ( value , null , null )
278
+ ? makeResNode ( value , null , null , null )
277
279
: value ;
278
280
}
279
281
ctx . processedVars [ varName ] = value ;
@@ -380,7 +382,7 @@ engine.MemberInvocation = function(ctx, parentData, node ) {
380
382
. filter ( ( x ) => x instanceof ResourceNode && x . path === key ) ;
381
383
} else {
382
384
return parentData . reduce ( function ( acc , res ) {
383
- res = makeResNode ( res , res . __path__ ?. path || null , null ,
385
+ res = makeResNode ( res , null , res . __path__ ?. path || null , null ,
384
386
res . __path__ ?. fhirNodeDataType || null ) ;
385
387
util . pushFn ( acc , util . makeChildResNodes ( res , key , model ) ) ;
386
388
return acc ;
@@ -676,14 +678,18 @@ function applyParsedPath(resource, parsedPath, context, model, options) {
676
678
constants . reset ( ) ;
677
679
let dataRoot = util . arraify ( resource ) . map (
678
680
i => i ?. __path__
679
- ? makeResNode ( i , i . __path__ . path , null ,
681
+ ? makeResNode ( i , i . __path__ . parentResNode , i . __path__ . path , null ,
680
682
i . __path__ . fhirNodeDataType || null )
681
683
: i ) ;
682
684
// doEval takes a "ctx" object, and we store things in that as we parse, so we
683
685
// need to put user-provided variable data in a sub-object, ctx.vars.
684
686
// Set up default standard variables, and allow override from the variables.
685
687
// However, we'll keep our own copy of dataRoot for internal processing.
686
- let vars = { context : dataRoot , ucum : 'http://unitsofmeasure.org' } ;
688
+ let vars = {
689
+ context : dataRoot ,
690
+ ucum : 'http://unitsofmeasure.org' ,
691
+ scoreExt : 'http://hl7.org/fhir/StructureDefinition/ordinalValue'
692
+ } ;
687
693
let ctx = { dataRoot, processedVars : vars , vars : context || { } , model} ;
688
694
if ( options . traceFn ) {
689
695
ctx . customTraceFn = options . traceFn ;
@@ -701,9 +707,11 @@ function applyParsedPath(resource, parsedPath, context, model, options) {
701
707
// Path for the data extracted from the resource.
702
708
let path ;
703
709
let fhirNodeDataType ;
710
+ let parentResNode ;
704
711
if ( n instanceof ResourceNode ) {
705
712
path = n . path ;
706
713
fhirNodeDataType = n . fhirNodeDataType ;
714
+ parentResNode = n . parentResNode ;
707
715
}
708
716
n = util . valData ( n ) ;
709
717
if ( n instanceof FP_Type ) {
@@ -716,7 +724,7 @@ function applyParsedPath(resource, parsedPath, context, model, options) {
716
724
// Add a hidden (non-enumerable) property with the path to the data extracted
717
725
// from the resource.
718
726
if ( path && typeof n === 'object' && ! n . __path__ ) {
719
- Object . defineProperty ( n , '__path__' , { value : { path, fhirNodeDataType} } ) ;
727
+ Object . defineProperty ( n , '__path__' , { value : { path, fhirNodeDataType, parentResNode } } ) ;
720
728
}
721
729
acc . push ( n ) ;
722
730
}
@@ -828,7 +836,7 @@ function compile(path, model, options) {
828
836
const baseFhirNodeDataType = model && model . path2Type [ basePath ] || null ;
829
837
basePath = baseFhirNodeDataType === 'BackboneElement' || baseFhirNodeDataType === 'Element' ? basePath : baseFhirNodeDataType || basePath ;
830
838
831
- fhirData = makeResNode ( fhirData , basePath , null , baseFhirNodeDataType ) ;
839
+ fhirData = makeResNode ( fhirData , null , basePath , null , baseFhirNodeDataType ) ;
832
840
}
833
841
// Globally set model before applying parsed FHIRPath expression
834
842
TypeInfo . model = model ;
@@ -854,8 +862,8 @@ function typesFn(fhirpathResult) {
854
862
return util . arraify ( fhirpathResult ) . map ( value => {
855
863
const ti = TypeInfo . fromValue (
856
864
value ?. __path__
857
- ? new ResourceNode ( value , value . __path__ ?. path , null ,
858
- value . __path__ ?. fhirNodeDataType )
865
+ ? new ResourceNode ( value , value . __path__ ?. parentResNode || null ,
866
+ value . __path__ ?. path || null , null , value . __path__ ?. fhirNodeDataType || null )
859
867
: value ) ;
860
868
return `${ ti . namespace } .${ ti . name } ` ;
861
869
} ) ;
0 commit comments