Skip to content

Commit

Permalink
fix: restore backward compatibility for /parse-template
Browse files Browse the repository at this point in the history
  • Loading branch information
ruscoder committed May 28, 2024
1 parent c32c69c commit 32c57da
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 11 deletions.
2 changes: 2 additions & 0 deletions ts/server/src/app.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export class AppController {
context,
fhirpath_r4_model,
strict,
true,
);
}

Expand All @@ -45,6 +46,7 @@ export class AppController {
context,
null,
strict,
false
);
}
}
2 changes: 2 additions & 0 deletions ts/server/src/app.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export class AppService {
context: Context,
model?: Model,
strict?: boolean,
dropNulls?: boolean,
): object {
const options: FPOptions = {
userInvocationTable: {
Expand Down Expand Up @@ -42,6 +43,7 @@ export class AppService {
model,
options,
strict,
dropNulls,
);
}
}
76 changes: 69 additions & 7 deletions ts/server/src/utils/extract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ export function resolveTemplate(
model?: Model,
fpOptions?: FPOptions,
strict?: boolean,
// TODO: it's fast hack for backward compatibility
dropNulls?: boolean,
): any {
return resolveTemplateRecur(
[],
Expand All @@ -50,6 +52,7 @@ export function resolveTemplate(
context,
model,
fpOptions,
dropNulls,
);
}

Expand All @@ -60,6 +63,7 @@ function resolveTemplateRecur(
initialContext?: Context,
model?: Model,
fpOptions?: FPOptions,
dropNulls?: boolean,
): any {
return iterateObject(
startPath,
Expand All @@ -74,6 +78,7 @@ function resolveTemplateRecur(
context,
model,
fpOptions,
dropNulls,
);
const matchers = [
processContextBlock,
Expand All @@ -82,7 +87,15 @@ function resolveTemplateRecur(
processIfBlock,
];
for (const matcher of matchers) {
const result = matcher(path, resource, newNode, newContext, model, fpOptions);
const result = matcher(
path,
resource,
newNode,
newContext,
model,
fpOptions,
dropNulls,
);

if (result) {
return { node: result.node, context: newContext };
Expand All @@ -92,7 +105,15 @@ function resolveTemplateRecur(
return { node: newNode, context: newContext };
} else if (typeof node === 'string') {
return {
node: processTemplateString(path, resource, node, context, model, fpOptions),
node: processTemplateString(
path,
resource,
node,
context,
model,
fpOptions,
dropNulls,
),
context,
};
}
Expand All @@ -109,6 +130,7 @@ function processTemplateString(
context: Context,
model: Model,
fpOptions: FPOptions,
dropNulls?: boolean,
) {
const templateRegExp = /{{-?\s*([\s\S]+?)\s*-?}}/g;
let match:
Expand All @@ -126,7 +148,7 @@ function processTemplateString(
return undefined;
}

return null;
return dropNulls ? undefined : null;
}

if (match[0] === node) {
Expand All @@ -146,6 +168,7 @@ function processAssignBlock(
context: Context,
model: Model,
fpOptions: FPOptions,
dropNulls?: boolean,
): { node: any; context: Context } {
const extendedContext = { ...context };
const keys = Object.keys(node);
Expand All @@ -163,7 +186,15 @@ function processAssignBlock(
}

Object.entries(
resolveTemplateRecur(path, resource, obj, extendedContext, model, fpOptions),
resolveTemplateRecur(
path,
resource,
obj,
extendedContext,
model,
fpOptions,
dropNulls,
),
).forEach(([key, value]) => {
extendedContext[key] = value;
});
Expand All @@ -183,6 +214,7 @@ function processAssignBlock(
extendedContext,
model,
fpOptions,
dropNulls,
),
).forEach(([key, value]) => {
extendedContext[key] = value;
Expand All @@ -204,6 +236,7 @@ function processMergeBlock(
context: Context,
model: Model,
fpOptions: FPOptions,
dropNulls?: boolean,
): { node: any } | undefined {
const keys = Object.keys(node);

Expand All @@ -221,6 +254,7 @@ function processMergeBlock(
context,
model,
fpOptions,
dropNulls,
);
if (!isPlainObject(result) && result !== null) {
throw new FPMLValidationError('Merge block must contain object', path);
Expand All @@ -241,6 +275,7 @@ function processForBlock(
context: Context,
model: Model,
fpOptions: FPOptions,
dropNulls?: boolean,
): { node: any } | undefined {
const keys = Object.keys(node);

Expand Down Expand Up @@ -272,6 +307,7 @@ function processForBlock(
},
model,
fpOptions,
dropNulls,
),
),
};
Expand All @@ -285,6 +321,7 @@ function processContextBlock(
context: Context,
model: Model,
fpOptions: FPOptions,
dropNulls?: boolean,
): { node: any } | undefined {
const keys = Object.keys(node);

Expand All @@ -300,7 +337,15 @@ function processContextBlock(

const answers = evaluateExpression(path, resource, expr, context, model, fpOptions);
const result: any[] = answers.map((answer) =>
resolveTemplateRecur(path, answer, node[contextKey], context, model, fpOptions),
resolveTemplateRecur(
path,
answer,
node[contextKey],
context,
model,
fpOptions,
dropNulls,
),
);

return { node: result };
Expand All @@ -314,6 +359,7 @@ function processIfBlock(
context: Context,
model: Model,
fpOptions: FPOptions,
dropNulls?: boolean,
): { node: any } | undefined {
const keys = Object.keys(node);

Expand Down Expand Up @@ -353,9 +399,25 @@ function processIfBlock(
)[0];

const newNode = answer
? resolveTemplateRecur(path, resource, node[ifKey], context, model, fpOptions)
? resolveTemplateRecur(
path,
resource,
node[ifKey],
context,
model,
fpOptions,
dropNulls,
)
: elseKey
? resolveTemplateRecur(path, resource, node[elseKey], context, model, fpOptions)
? resolveTemplateRecur(
path,
resource,
node[elseKey],
context,
model,
fpOptions,
dropNulls,
)
: null;

const isMergeBehavior = keys.length !== (elseKey ? 2 : 1);
Expand Down
8 changes: 4 additions & 4 deletions ts/server/test/app.e2e-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('AppController (e2e)', () => {
resourceType: 'Patient',
id: 'foo',
},
template: { id: '{{ Patient.id }}' },
template: { id: '{{ Patient.id }}', name: '{{ name }}' },
})
.expect(200)
.expect({ id: 'foo' });
Expand All @@ -37,7 +37,7 @@ describe('AppController (e2e)', () => {
resourceType: 'Patient',
id: 'foo',
},
template: { id: '{{ Patient.id }}' },
template: { id: '{{ Patient.id }}', name: '{{ name }}' },
})
.expect(200)
.expect({ id: 'foo' });
Expand All @@ -51,10 +51,10 @@ describe('AppController (e2e)', () => {
resourceType: 'Patient',
id: 'foo',
},
template: { id: '{{ Patient.id }}' },
template: { id: '{{ Patient.id }}', name: '{{ name }}' },
})
.expect(200)
.expect({ id: 'foo' });
.expect({ id: 'foo', name: null });
});

it('$extract r4', () => {
Expand Down

0 comments on commit 32c57da

Please sign in to comment.