Skip to content

Commit

Permalink
fix(fhir-ts-codegen): group elements by type
Browse files Browse the repository at this point in the history
For some profiles, the name and ElementDefinition paths use the base
type. Changed `getElementGroups` to group using the `type` field in the
StructureDefinition and then replace the group name with the profile
name. This fixes a bug when generating profiles from snapshots like
the MoneyQuantity profile on Quantity.
  • Loading branch information
tangdrew committed Feb 20, 2019
1 parent 0771377 commit 6f46af6
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 16 deletions.
57 changes: 42 additions & 15 deletions packages/fhir-ts-codegen/lib/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,61 @@ export const writeFileAsync = promisify(writeFile);

/**
* Groups list of ElementDefinitions into related elements
* E.g. the root resource and the embedded backbone elements
* e.g. the root resource and the embedded backbone elements.
* Root resource is grouped using the type name, but assigned
* the StructureDefinition name. For example, for MoneyQuantity,
* the root resource type is Quantity, but the name of the type
* will be MoneyQuantity.
*/
export const getElementGroups = (
resourceName: string,
resourceTypeName: string,
elementDefinitions: ElementDefinition[]
): ElementGroup[] => {
/**
* If the target and comparison string are the same, return
* the alternative string else return the target.
* Useful for renaming profile ElementDefinition paths from
* the base type to the name of the profile e.g. Quantity -> MoneyQuantity
*/
const replaceIfMatch = (
target: string,
comparison: string,
alternative: string
) => (target === comparison ? alternative : target);

const groupNames = elementDefinitions
.filter(
el =>
isBackboneDefinition(el) ||
isElementDefinition(el) ||
isResourceDefinition(resourceName, el)
isResourceDefinition(resourceTypeName, el)
)
.map(e => pathToPascalCase(e.path));
.map(e =>
replaceIfMatch(pathToPascalCase(e.path), resourceTypeName, resourceName)
);

const groups = elementDefinitions.reduce<{ [key: string]: ElementGroup }>(
(accum, curr) => {
const { path } = curr;
const parentName = isResourceDefinition(resourceName, curr)
? ""
: pathToPascalCase(
path
.split(".")
.slice(0, -1)
.join(".")
);

const name = pathToPascalCase(path);
const parentName = replaceIfMatch(
isResourceDefinition(resourceTypeName, curr)
? ""
: pathToPascalCase(
path
.split(".")
.slice(0, -1)
.join(".")
),
resourceTypeName,
resourceName
);

const name = replaceIfMatch(
pathToPascalCase(path),
resourceTypeName,
resourceName
);
const isGroupRoot = groupNames.includes(name);
const group = accum[name] || {};
const isGroupChild = groupNames.includes(parentName);
Expand Down Expand Up @@ -222,9 +249,9 @@ export const elementName = (elementDefinition: ElementDefinition) => {
* Determines if ElementDefinition is root declaration of Resource
*/
export const isResourceDefinition = (
resourceName: string,
resourceTypeName: string,
e: ElementDefinition
) => e.path === resourceName;
) => e.path === resourceTypeName;

/**
* Determines if ElementDefinition is root declaration of BackboneElement on a Resource
Expand Down
2 changes: 1 addition & 1 deletion packages/fhir-ts-codegen/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export class Generator {
// TODO: Support from Differential
const elementDefinitions = snapshot!.element || [];

const elementGroups = getElementGroups(name, elementDefinitions);
const elementGroups = getElementGroups(name, type, elementDefinitions);

const imports = this.configuration.singleFile
? ""
Expand Down

0 comments on commit 6f46af6

Please sign in to comment.