@smile-cdr/fhirts 2.0.7 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/GETTINGSTARTED.md +40 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +5 -5
- package/dist/library/BundleUtils/BundleUtils.d.ts +16 -0
- package/dist/library/BundleUtils/BundleUtils.js +24 -0
- package/dist/library/BundleUtils/BundleUtils.spec.js +47 -0
- package/dist/library/{ResourceUtilities/ResourceUtilities.d.ts → ResourceUtils/ResourceUtils.d.ts} +14 -2
- package/dist/library/ResourceUtils/ResourceUtils.js +115 -0
- package/dist/library/{ResourceUtilities/ResourceUtilities.spec.js → ResourceUtils/ResourceUtils.spec.js} +72 -22
- package/package.json +1 -1
- package/src/index.ts +3 -3
- package/src/library/BundleUtils/BundleUtils.spec.ts +65 -0
- package/src/library/BundleUtils/BundleUtils.ts +26 -0
- package/src/library/{ResourceUtilities/ResourceUtilities.spec.ts → ResourceUtils/ResourceUtils.spec.ts} +96 -24
- package/src/library/ResourceUtils/ResourceUtils.ts +124 -0
- package/src/test-resources/CareTeam-R4.json +85 -0
- package/src/test-resources/Patient-R4.json +4 -0
- package/dist/library/BundleUtilities/BundleUtilities.d.ts +0 -10
- package/dist/library/BundleUtilities/BundleUtilities.js +0 -16
- package/dist/library/BundleUtilities/BundleUtilities.spec.js +0 -26
- package/dist/library/ResourceUtilities/ResourceUtilities.js +0 -51
- package/src/library/BundleUtilities/BundleUtilities.spec.ts +0 -28
- package/src/library/BundleUtilities/BundleUtilities.ts +0 -16
- package/src/library/ResourceUtilities/ResourceUtilities.ts +0 -52
- /package/dist/library/{BundleUtilities/BundleUtilities.spec.d.ts → BundleUtils/BundleUtils.spec.d.ts} +0 -0
- /package/dist/library/{ResourceUtilities/ResourceUtilities.spec.d.ts → ResourceUtils/ResourceUtils.spec.d.ts} +0 -0
package/GETTINGSTARTED.md
CHANGED
|
@@ -94,12 +94,51 @@ If you try writing this out you will see that the variable `resource` inside the
|
|
|
94
94
|
- The above utlity classes include common functionalities used by front end applications using FHIR.
|
|
95
95
|
- All utilities functions are static right now, so, no need for instantiating classes. **Note: This is subject to change in future**
|
|
96
96
|
|
|
97
|
+
### `v2.1.0`
|
|
98
|
+
#### BundleUtils usage
|
|
99
|
+
```js
|
|
100
|
+
import { BundleUtils } from '@smilecdr/fhirts';
|
|
101
|
+
|
|
102
|
+
const bundleUtils = new BundleUtils();
|
|
103
|
+
// returns arrayof Claim resources from Bundle.entry
|
|
104
|
+
const claimsList = bundleUtils.getResourcesFromBundle(Bundle.entry, 'Claim');
|
|
105
|
+
// returns a single resource with ID 123 from Bundle.entry
|
|
106
|
+
const resource = bundleUtils.getResourceFromBundle(Bundle.entry, '123');
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
#### ResourceUtils usage
|
|
110
|
+
```js
|
|
111
|
+
import { ResourceUtils } from '@smilecdr/fhirts';
|
|
112
|
+
const resourceUtils = new ResourceUtils();
|
|
113
|
+
// returns deserialized Patient resource
|
|
114
|
+
const deserializedPatientResource = resourceUtils.deserializeResource(jsonPatientPayload, new Patient());
|
|
115
|
+
|
|
116
|
+
// returns Patient.gender
|
|
117
|
+
const patientGender = resourceUtils.getResourceProperty(jsonPatientPayload, 'gender');
|
|
118
|
+
|
|
119
|
+
// returns all matching identifiers where Identifier.use = usual
|
|
120
|
+
const identifierFilter = resourceUtils.getIdentifiersByProperty(identifierList,"use","usual");
|
|
121
|
+
|
|
122
|
+
const url = "http://ns.electronichealth.net.au/id/hi/ihi/1.0";
|
|
123
|
+
// returns all matching extensions where Extension.use = "http://ns.electronichealth.net.au/id/hi/ihi/1.0"
|
|
124
|
+
const extensionFilter = resourceUtils.getExtensionsByUrl(extensionList, url);
|
|
125
|
+
|
|
126
|
+
// returns all matching codings where Coding.code = "abc"
|
|
127
|
+
const codingFilter = resourceUtils.getCodingsByProperty(codingList,"code","abc");
|
|
128
|
+
// returns array of elements found at provided path and returns empty array if no values found
|
|
129
|
+
const values = resourceUtils.getValuesAtResourcePath(jsonPatientPayload, "Patient.contact.relationship.coding.system");
|
|
130
|
+
// returns array of references found in a resource
|
|
131
|
+
const references = resourceUtils.getAllReferencesFromResource(resourcePayload);
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
|
|
97
135
|
|
|
136
|
+
### `v2.0.0`
|
|
98
137
|
#### BundleUtilities usage
|
|
99
138
|
```js
|
|
100
139
|
import { BundleUtilities } from '@smilecdr/fhirts';
|
|
101
140
|
|
|
102
|
-
// returns
|
|
141
|
+
// returns arrayof Claim resources from Bundle.entry
|
|
103
142
|
const claimsList = BundleUtilities.getResourcesFromBundle(Bundle.entry, 'Claim');
|
|
104
143
|
```
|
|
105
144
|
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ import * as fhirR4 from './FHIR-R4/classes/models-r4';
|
|
|
2
2
|
import * as IfhirR4 from './FHIR-R4/interfaces/IModel';
|
|
3
3
|
import * as fhirR3 from './FHIR-R3';
|
|
4
4
|
import * as dstu2 from './FHIR-DSTU2';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
export { fhirR4, fhirR3, IfhirR4, dstu2,
|
|
5
|
+
import { ResourceUtils } from './library/ResourceUtils/ResourceUtils';
|
|
6
|
+
import { BundleUtils } from './library/BundleUtils/BundleUtils';
|
|
7
|
+
export { fhirR4, fhirR3, IfhirR4, dstu2, ResourceUtils, BundleUtils };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.BundleUtils = exports.ResourceUtils = exports.dstu2 = exports.IfhirR4 = exports.fhirR3 = exports.fhirR4 = void 0;
|
|
4
4
|
const fhirR4 = require("./FHIR-R4/classes/models-r4");
|
|
5
5
|
exports.fhirR4 = fhirR4;
|
|
6
6
|
const IfhirR4 = require("./FHIR-R4/interfaces/IModel");
|
|
@@ -9,7 +9,7 @@ const fhirR3 = require("./FHIR-R3");
|
|
|
9
9
|
exports.fhirR3 = fhirR3;
|
|
10
10
|
const dstu2 = require("./FHIR-DSTU2");
|
|
11
11
|
exports.dstu2 = dstu2;
|
|
12
|
-
const
|
|
13
|
-
Object.defineProperty(exports, "
|
|
14
|
-
const
|
|
15
|
-
Object.defineProperty(exports, "
|
|
12
|
+
const ResourceUtils_1 = require("./library/ResourceUtils/ResourceUtils");
|
|
13
|
+
Object.defineProperty(exports, "ResourceUtils", { enumerable: true, get: function () { return ResourceUtils_1.ResourceUtils; } });
|
|
14
|
+
const BundleUtils_1 = require("./library/BundleUtils/BundleUtils");
|
|
15
|
+
Object.defineProperty(exports, "BundleUtils", { enumerable: true, get: function () { return BundleUtils_1.BundleUtils; } });
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare class BundleUtils {
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* @param bundleEntry Bundle.entry[] i.e. the bundle entries to filter
|
|
5
|
+
* @param resourceTypeToFilter ResourceType to filter from bundle entries
|
|
6
|
+
* @returns array of resources
|
|
7
|
+
*/
|
|
8
|
+
getResources(bundleEntry: any[], resourceTypeToFilter: string): any[];
|
|
9
|
+
/**
|
|
10
|
+
*
|
|
11
|
+
* @param bundleEntry Bundle.entry[] i.e. the bundle entries to filter
|
|
12
|
+
* @param resourceId Resource ID to filter from bundle entries
|
|
13
|
+
* @returns single resource
|
|
14
|
+
*/
|
|
15
|
+
getResource(bundleEntry: any[], resourceId: string): any;
|
|
16
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BundleUtils = void 0;
|
|
4
|
+
class BundleUtils {
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param bundleEntry Bundle.entry[] i.e. the bundle entries to filter
|
|
8
|
+
* @param resourceTypeToFilter ResourceType to filter from bundle entries
|
|
9
|
+
* @returns array of resources
|
|
10
|
+
*/
|
|
11
|
+
getResources(bundleEntry, resourceTypeToFilter) {
|
|
12
|
+
return (bundleEntry === null || bundleEntry === void 0 ? void 0 : bundleEntry.length) ? bundleEntry.filter(x => x['resource']['resourceType'] === resourceTypeToFilter) : [];
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @param bundleEntry Bundle.entry[] i.e. the bundle entries to filter
|
|
17
|
+
* @param resourceId Resource ID to filter from bundle entries
|
|
18
|
+
* @returns single resource
|
|
19
|
+
*/
|
|
20
|
+
getResource(bundleEntry, resourceId) {
|
|
21
|
+
return (bundleEntry === null || bundleEntry === void 0 ? void 0 : bundleEntry.length) ? bundleEntry.find(x => x['resource']['id'] === resourceId) : null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.BundleUtils = BundleUtils;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const BundleUtils_1 = require("./BundleUtils");
|
|
4
|
+
const inputPayload = require("./../../test-resources/Bundle-R4.json");
|
|
5
|
+
describe("BundleUtils", () => {
|
|
6
|
+
let bundleUtils = new BundleUtils_1.BundleUtils();
|
|
7
|
+
describe("#getResources()", () => {
|
|
8
|
+
it("should return empty array if null is passed as bundle entries", () => {
|
|
9
|
+
// execute
|
|
10
|
+
const actual = bundleUtils.getResources(null, "Patient");
|
|
11
|
+
// validate
|
|
12
|
+
expect(actual.length).toEqual(0);
|
|
13
|
+
});
|
|
14
|
+
it("should return empty array if invalid resourceType is passed", () => {
|
|
15
|
+
// execute
|
|
16
|
+
const actual = bundleUtils.getResources(inputPayload.entry, "patient");
|
|
17
|
+
// validate
|
|
18
|
+
expect(actual.length).toEqual(0);
|
|
19
|
+
});
|
|
20
|
+
it("should return all matches array", () => {
|
|
21
|
+
// execute
|
|
22
|
+
const actual = bundleUtils.getResources(inputPayload.entry, "Claim");
|
|
23
|
+
// validate
|
|
24
|
+
expect(actual.length).toEqual(27);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
describe("#getResource()", () => {
|
|
28
|
+
it("should return null if null is passed as bundle entries", () => {
|
|
29
|
+
// execute
|
|
30
|
+
const actual = bundleUtils.getResource(null, "123");
|
|
31
|
+
// validate
|
|
32
|
+
expect(actual).toBeNull();
|
|
33
|
+
});
|
|
34
|
+
it("should return undefined if resourceId is not found", () => {
|
|
35
|
+
// execute
|
|
36
|
+
const actual = bundleUtils.getResource(inputPayload.entry, "123");
|
|
37
|
+
// validate
|
|
38
|
+
expect(actual).toBeUndefined();
|
|
39
|
+
});
|
|
40
|
+
it("should return resource if resource is found", () => {
|
|
41
|
+
// execute
|
|
42
|
+
const actual = bundleUtils.getResource(inputPayload.entry, "ec0bb1b3-b229-36cf-7e34-3f5fec9d3afe");
|
|
43
|
+
// validate
|
|
44
|
+
expect(actual).not.toBeNull();
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
});
|
package/dist/library/{ResourceUtilities/ResourceUtilities.d.ts → ResourceUtils/ResourceUtils.d.ts}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare class
|
|
1
|
+
export declare class ResourceUtils {
|
|
2
2
|
/**
|
|
3
3
|
*
|
|
4
4
|
* @param inputJson - valid json
|
|
@@ -31,5 +31,17 @@ export declare class ResourceUtility {
|
|
|
31
31
|
* @returns array of matches
|
|
32
32
|
*/
|
|
33
33
|
getCodingsByProperty(codingList: any[], propertyToCompare: string, propertyValue: string | boolean): any[];
|
|
34
|
+
/**
|
|
35
|
+
*
|
|
36
|
+
* @param resource resource for which path needs to be validated
|
|
37
|
+
* @param elementPath path to validate in resource
|
|
38
|
+
* @returns array of elements found at the provided path
|
|
39
|
+
*/
|
|
40
|
+
getValuesAtResourcePath(resource: any, elementPath: string): any[];
|
|
41
|
+
private isPrimitive;
|
|
42
|
+
/**
|
|
43
|
+
* @param resource resource to pull out references from
|
|
44
|
+
* @returns array of references inside a resource
|
|
45
|
+
*/
|
|
46
|
+
getAllReferencesFromResource(resource: any): string[];
|
|
34
47
|
}
|
|
35
|
-
export declare const ResourceUtilities: ResourceUtility;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ResourceUtils = void 0;
|
|
4
|
+
class ResourceUtils {
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param inputJson - valid json
|
|
8
|
+
* @param propertyName - top level property for resource
|
|
9
|
+
* @returns json property if it exists
|
|
10
|
+
* @limitation currently just supports get for top level property on resource
|
|
11
|
+
*/
|
|
12
|
+
getResourceProperty(inputJson, propertyName) {
|
|
13
|
+
let resourcePropertyValue = null;
|
|
14
|
+
if (inputJson.hasOwnProperty(propertyName)) {
|
|
15
|
+
resourcePropertyValue = inputJson[propertyName];
|
|
16
|
+
}
|
|
17
|
+
return resourcePropertyValue;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
* @param identifierList list of identifiers
|
|
22
|
+
* @param propertyToCompare identifier property to compare
|
|
23
|
+
* @param propertyValue value we want to compare against
|
|
24
|
+
* @returns array of matches
|
|
25
|
+
* @limitations currently does not work with identifier.type, identifier.period & identifier.assigner
|
|
26
|
+
*/
|
|
27
|
+
getIdentifiersByProperty(identifierList, propertyToCompare, propertyValue) {
|
|
28
|
+
return (identifierList === null || identifierList === void 0 ? void 0 : identifierList.length)
|
|
29
|
+
? identifierList.filter((x) => x[propertyToCompare] === propertyValue)
|
|
30
|
+
: [];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
* @param extensionList list of extensions
|
|
35
|
+
* @param extensionUrl Extension.url to compare
|
|
36
|
+
* @returns array of matches
|
|
37
|
+
*/
|
|
38
|
+
getExtensionsByUrl(extensionList, extensionUrl) {
|
|
39
|
+
return (extensionList === null || extensionList === void 0 ? void 0 : extensionList.length)
|
|
40
|
+
? extensionList.filter((x) => x["url"] === extensionUrl)
|
|
41
|
+
: [];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
*
|
|
45
|
+
* @param codingList list of codings
|
|
46
|
+
* @param propertyToCompare coding property to compare
|
|
47
|
+
* @param propertyValue value we want to compare against string or boolean
|
|
48
|
+
* @returns array of matches
|
|
49
|
+
*/
|
|
50
|
+
getCodingsByProperty(codingList, propertyToCompare, propertyValue) {
|
|
51
|
+
return (codingList === null || codingList === void 0 ? void 0 : codingList.length)
|
|
52
|
+
? codingList.filter((x) => x[propertyToCompare] === propertyValue)
|
|
53
|
+
: [];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
*
|
|
57
|
+
* @param resource resource for which path needs to be validated
|
|
58
|
+
* @param elementPath path to validate in resource
|
|
59
|
+
* @returns array of elements found at the provided path
|
|
60
|
+
*/
|
|
61
|
+
getValuesAtResourcePath(resource, elementPath) {
|
|
62
|
+
const pathSections = elementPath.split(".");
|
|
63
|
+
let resourcePathValue;
|
|
64
|
+
for (let index = 1; index < pathSections.length; index++) {
|
|
65
|
+
const subPaths = pathSections[index];
|
|
66
|
+
resourcePathValue = resourcePathValue ? resourcePathValue[subPaths] : resource[subPaths];
|
|
67
|
+
if (resourcePathValue) {
|
|
68
|
+
if (this.isPrimitive(resourcePathValue)) {
|
|
69
|
+
return [resourcePathValue];
|
|
70
|
+
}
|
|
71
|
+
else if (Array.isArray(resourcePathValue) && resourcePathValue.length > 0) {
|
|
72
|
+
let resultSet = [];
|
|
73
|
+
for (let subPathIndex = 0; subPathIndex < resourcePathValue.length; subPathIndex++) {
|
|
74
|
+
const subPathValue = resourcePathValue[subPathIndex];
|
|
75
|
+
resultSet.push(...this.getValuesAtResourcePath(subPathValue, pathSections.slice(index).join(".")));
|
|
76
|
+
}
|
|
77
|
+
return resultSet;
|
|
78
|
+
}
|
|
79
|
+
else if (typeof (resourcePathValue) === 'object') {
|
|
80
|
+
return this.getValuesAtResourcePath(resourcePathValue, pathSections.slice(index).join("."));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
isPrimitive(value) {
|
|
90
|
+
return typeof (value) === "boolean" || typeof (value) === "string";
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* @param resource resource to pull out references from
|
|
94
|
+
* @returns array of references inside a resource
|
|
95
|
+
*/
|
|
96
|
+
getAllReferencesFromResource(resource) {
|
|
97
|
+
const stringifiedResource = JSON.stringify(resource);
|
|
98
|
+
const referenceJsonString = '"reference":';
|
|
99
|
+
let references = [];
|
|
100
|
+
let cursor = stringifiedResource.indexOf(referenceJsonString, 0);
|
|
101
|
+
while (cursor > -1) {
|
|
102
|
+
const referenceStart = stringifiedResource.indexOf(referenceJsonString, cursor) + referenceJsonString.length;
|
|
103
|
+
const referenceEnd = stringifiedResource.indexOf('"', referenceStart + 1);
|
|
104
|
+
const reference = stringifiedResource.substring(referenceStart, referenceEnd);
|
|
105
|
+
// this means the reference ends started reading from start again
|
|
106
|
+
if (referenceEnd < cursor) {
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
references.push(reference);
|
|
110
|
+
cursor = referenceEnd;
|
|
111
|
+
}
|
|
112
|
+
return references;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
exports.ResourceUtils = ResourceUtils;
|
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
|
|
3
|
+
const ResourceUtils_1 = require("./ResourceUtils");
|
|
4
|
+
const patientPayload = require("./../../test-resources/Patient-R4.json");
|
|
5
|
+
const careTeamPayload = require("./../../test-resources/CareTeam-R4.json");
|
|
6
|
+
describe("ResourceUtils", () => {
|
|
7
|
+
let resourceUtils = new ResourceUtils_1.ResourceUtils();
|
|
6
8
|
describe("#getResourceProperty()", () => {
|
|
7
|
-
it(
|
|
9
|
+
it("should return property if property exists in valid inputJson", () => {
|
|
8
10
|
// execute
|
|
9
|
-
const actual =
|
|
11
|
+
const actual = resourceUtils.getResourceProperty(patientPayload, "deceasedBoolean");
|
|
10
12
|
// validate
|
|
11
13
|
expect(actual).toBeFalse();
|
|
12
14
|
});
|
|
13
|
-
it(
|
|
15
|
+
it("should return null if property exists in valid inputJson", () => {
|
|
14
16
|
// execute
|
|
15
|
-
const actual =
|
|
17
|
+
const actual = resourceUtils.getResourceProperty(patientPayload, "abcd");
|
|
16
18
|
// validate
|
|
17
19
|
expect(actual).toBeNull();
|
|
18
20
|
});
|
|
19
|
-
it(
|
|
21
|
+
it("should return null if invalid inputJson is passed", () => {
|
|
20
22
|
// setup
|
|
21
23
|
const inputPayload = [1, 2];
|
|
22
24
|
// execute
|
|
23
|
-
const actual =
|
|
25
|
+
const actual = resourceUtils.getResourceProperty(inputPayload, "deceasedBoolean");
|
|
24
26
|
// validate
|
|
25
27
|
expect(actual).toBeNull();
|
|
26
28
|
});
|
|
@@ -42,7 +44,7 @@ describe("ResourceUtilities", () => {
|
|
|
42
44
|
// setup
|
|
43
45
|
const value = "abc";
|
|
44
46
|
// execute
|
|
45
|
-
const actual =
|
|
47
|
+
const actual = resourceUtils.getIdentifiersByProperty(null, "abc", value);
|
|
46
48
|
// validate
|
|
47
49
|
expect(actual.length).toEqual(0);
|
|
48
50
|
});
|
|
@@ -50,7 +52,7 @@ describe("ResourceUtilities", () => {
|
|
|
50
52
|
// setup
|
|
51
53
|
const value = "abc";
|
|
52
54
|
// execute
|
|
53
|
-
const actual =
|
|
55
|
+
const actual = resourceUtils.getIdentifiersByProperty(identifierList, "abc", value);
|
|
54
56
|
// validate
|
|
55
57
|
expect(actual.length).toEqual(0);
|
|
56
58
|
});
|
|
@@ -58,7 +60,7 @@ describe("ResourceUtilities", () => {
|
|
|
58
60
|
// setup
|
|
59
61
|
const systemUrl = "http://somesystem.com";
|
|
60
62
|
// execute
|
|
61
|
-
const actual =
|
|
63
|
+
const actual = resourceUtils.getIdentifiersByProperty(identifierList, "system", systemUrl);
|
|
62
64
|
// validate
|
|
63
65
|
expect(actual.length).toEqual(0);
|
|
64
66
|
});
|
|
@@ -66,7 +68,7 @@ describe("ResourceUtilities", () => {
|
|
|
66
68
|
// setup
|
|
67
69
|
const value = "abc";
|
|
68
70
|
// execute
|
|
69
|
-
const actual =
|
|
71
|
+
const actual = resourceUtils.getIdentifiersByProperty(identifierList, "value", value);
|
|
70
72
|
// validate
|
|
71
73
|
expect(actual.length).toEqual(2);
|
|
72
74
|
});
|
|
@@ -84,7 +86,7 @@ describe("ResourceUtilities", () => {
|
|
|
84
86
|
];
|
|
85
87
|
it("should return empty array if null is passed as extension list", () => {
|
|
86
88
|
// execute
|
|
87
|
-
const actual =
|
|
89
|
+
const actual = resourceUtils.getExtensionsByUrl(null, "url");
|
|
88
90
|
// validate
|
|
89
91
|
expect(actual.length).toEqual(0);
|
|
90
92
|
});
|
|
@@ -99,7 +101,7 @@ describe("ResourceUtilities", () => {
|
|
|
99
101
|
];
|
|
100
102
|
const url = "http://ns.electronichealth.net.au/id/hi/ihi/1.0";
|
|
101
103
|
// execute
|
|
102
|
-
const actual =
|
|
104
|
+
const actual = resourceUtils.getExtensionsByUrl(extensionListInvalid, url);
|
|
103
105
|
// validate
|
|
104
106
|
expect(actual.length).toEqual(0);
|
|
105
107
|
});
|
|
@@ -107,7 +109,7 @@ describe("ResourceUtilities", () => {
|
|
|
107
109
|
// setup
|
|
108
110
|
const url = "http://somesystem.com";
|
|
109
111
|
// execute
|
|
110
|
-
const actual =
|
|
112
|
+
const actual = resourceUtils.getExtensionsByUrl(extensionList, url);
|
|
111
113
|
// validate
|
|
112
114
|
expect(actual.length).toEqual(0);
|
|
113
115
|
});
|
|
@@ -115,7 +117,7 @@ describe("ResourceUtilities", () => {
|
|
|
115
117
|
// setup
|
|
116
118
|
const url = "http://ns.electronichealth.net.au/id/hi/ihi/1.0";
|
|
117
119
|
// execute
|
|
118
|
-
const actual =
|
|
120
|
+
const actual = resourceUtils.getExtensionsByUrl(extensionList, url);
|
|
119
121
|
// validate
|
|
120
122
|
expect(actual.length).toEqual(1);
|
|
121
123
|
});
|
|
@@ -140,7 +142,7 @@ describe("ResourceUtilities", () => {
|
|
|
140
142
|
// setup
|
|
141
143
|
const value = "abc";
|
|
142
144
|
// execute
|
|
143
|
-
const actual =
|
|
145
|
+
const actual = resourceUtils.getCodingsByProperty(null, "abc", value);
|
|
144
146
|
// validate
|
|
145
147
|
expect(actual.length).toEqual(0);
|
|
146
148
|
});
|
|
@@ -148,7 +150,7 @@ describe("ResourceUtilities", () => {
|
|
|
148
150
|
// setup
|
|
149
151
|
const value = "abc";
|
|
150
152
|
// execute
|
|
151
|
-
const actual =
|
|
153
|
+
const actual = resourceUtils.getCodingsByProperty(codingList, "abc", value);
|
|
152
154
|
// validate
|
|
153
155
|
expect(actual.length).toEqual(0);
|
|
154
156
|
});
|
|
@@ -156,7 +158,7 @@ describe("ResourceUtilities", () => {
|
|
|
156
158
|
// setup
|
|
157
159
|
const systemUrl = "http://somesystem.com";
|
|
158
160
|
// execute
|
|
159
|
-
const actual =
|
|
161
|
+
const actual = resourceUtils.getCodingsByProperty(codingList, "system", systemUrl);
|
|
160
162
|
// validate
|
|
161
163
|
expect(actual.length).toEqual(0);
|
|
162
164
|
});
|
|
@@ -164,7 +166,7 @@ describe("ResourceUtilities", () => {
|
|
|
164
166
|
// setup
|
|
165
167
|
const value = "abc";
|
|
166
168
|
// execute
|
|
167
|
-
const actual =
|
|
169
|
+
const actual = resourceUtils.getCodingsByProperty(codingList, "code", value);
|
|
168
170
|
// validate
|
|
169
171
|
expect(actual.length).toEqual(2);
|
|
170
172
|
});
|
|
@@ -172,9 +174,57 @@ describe("ResourceUtilities", () => {
|
|
|
172
174
|
// setup
|
|
173
175
|
const value = false;
|
|
174
176
|
// execute
|
|
175
|
-
const actual =
|
|
177
|
+
const actual = resourceUtils.getCodingsByProperty(codingList, "userSelected", value);
|
|
176
178
|
// validate
|
|
177
179
|
expect(actual.length).toEqual(1);
|
|
178
180
|
});
|
|
179
181
|
});
|
|
182
|
+
describe("#getValuesAtResourcePath()", () => {
|
|
183
|
+
it("should return array with values if path exists for a top level element", () => {
|
|
184
|
+
// execute
|
|
185
|
+
const pathValues = resourceUtils.getValuesAtResourcePath(patientPayload, "Patient.gender");
|
|
186
|
+
// validate
|
|
187
|
+
expect(pathValues.length).toEqual(1);
|
|
188
|
+
expect(pathValues[0]).toEqual("male");
|
|
189
|
+
});
|
|
190
|
+
it("should return array with values if path exists for a deep array element", () => {
|
|
191
|
+
// execute
|
|
192
|
+
const pathValues = resourceUtils.getValuesAtResourcePath(patientPayload, "Patient.contact.relationship.coding.system");
|
|
193
|
+
// validate
|
|
194
|
+
expect(pathValues.length).toEqual(2);
|
|
195
|
+
expect(pathValues[0]).toEqual("http://terminology.hl7.org/CodeSystem/v2-0131");
|
|
196
|
+
expect(pathValues[1]).toEqual("http://terminology.hl7.org/CodeSystem/v2-0132");
|
|
197
|
+
});
|
|
198
|
+
it("should return array with values if path exists for a deep json element", () => {
|
|
199
|
+
// execute
|
|
200
|
+
const pathValues = resourceUtils.getValuesAtResourcePath(patientPayload, "Patient.maritalStatus.coding.system");
|
|
201
|
+
// validate
|
|
202
|
+
expect(pathValues.length).toEqual(1);
|
|
203
|
+
expect(pathValues[0]).toEqual("http://terminology.hl7.org/CodeSystem/v3-MaritalStatus");
|
|
204
|
+
});
|
|
205
|
+
it("should return empty array if path does not exist", () => {
|
|
206
|
+
// execute
|
|
207
|
+
const pathValues = resourceUtils.getValuesAtResourcePath(patientPayload, "Patient.contact.relationship.coding.abcd");
|
|
208
|
+
// validate
|
|
209
|
+
expect(pathValues.length).toEqual(0);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
describe("#getAllResourceReferences()", () => {
|
|
213
|
+
it("should return array of all references in a resource when references found", () => {
|
|
214
|
+
// execute
|
|
215
|
+
const actual = resourceUtils.getAllReferencesFromResource(careTeamPayload);
|
|
216
|
+
// validate
|
|
217
|
+
expect(actual.length).toEqual(6);
|
|
218
|
+
});
|
|
219
|
+
it("should return empty array if references in a resource not found", () => {
|
|
220
|
+
// setup
|
|
221
|
+
const input = {
|
|
222
|
+
"resourceType": "Patient"
|
|
223
|
+
};
|
|
224
|
+
// execute
|
|
225
|
+
const actual = resourceUtils.getAllReferencesFromResource(input);
|
|
226
|
+
// validate
|
|
227
|
+
expect(actual.length).toEqual(0);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
180
230
|
});
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -2,7 +2,7 @@ import * as fhirR4 from './FHIR-R4/classes/models-r4';
|
|
|
2
2
|
import * as IfhirR4 from './FHIR-R4/interfaces/IModel';
|
|
3
3
|
import * as fhirR3 from './FHIR-R3';
|
|
4
4
|
import * as dstu2 from './FHIR-DSTU2';
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
export { fhirR4, fhirR3, IfhirR4, dstu2,
|
|
5
|
+
import { ResourceUtils } from './library/ResourceUtils/ResourceUtils';
|
|
6
|
+
import { BundleUtils } from './library/BundleUtils/BundleUtils';
|
|
7
|
+
export { fhirR4, fhirR3, IfhirR4, dstu2, ResourceUtils, BundleUtils };
|
|
8
8
|
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { BundleUtils } from "./BundleUtils";
|
|
2
|
+
|
|
3
|
+
const inputPayload = require("./../../test-resources/Bundle-R4.json");
|
|
4
|
+
describe("BundleUtils", () => {
|
|
5
|
+
|
|
6
|
+
let bundleUtils = new BundleUtils();
|
|
7
|
+
|
|
8
|
+
describe("#getResources()", () => {
|
|
9
|
+
it("should return empty array if null is passed as bundle entries", () => {
|
|
10
|
+
// execute
|
|
11
|
+
const actual = bundleUtils.getResources(null, "Patient");
|
|
12
|
+
// validate
|
|
13
|
+
expect(actual.length).toEqual(0);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("should return empty array if invalid resourceType is passed", () => {
|
|
17
|
+
// execute
|
|
18
|
+
const actual = bundleUtils.getResources(
|
|
19
|
+
inputPayload.entry,
|
|
20
|
+
"patient"
|
|
21
|
+
);
|
|
22
|
+
// validate
|
|
23
|
+
expect(actual.length).toEqual(0);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("should return all matches array", () => {
|
|
27
|
+
// execute
|
|
28
|
+
const actual = bundleUtils.getResources(
|
|
29
|
+
inputPayload.entry,
|
|
30
|
+
"Claim"
|
|
31
|
+
);
|
|
32
|
+
// validate
|
|
33
|
+
expect(actual.length).toEqual(27);
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
describe("#getResource()", () => {
|
|
38
|
+
it("should return null if null is passed as bundle entries", () => {
|
|
39
|
+
// execute
|
|
40
|
+
const actual = bundleUtils.getResource(null, "123");
|
|
41
|
+
// validate
|
|
42
|
+
expect(actual).toBeNull();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("should return undefined if resourceId is not found", () => {
|
|
46
|
+
// execute
|
|
47
|
+
const actual = bundleUtils.getResource(
|
|
48
|
+
inputPayload.entry,
|
|
49
|
+
"123"
|
|
50
|
+
);
|
|
51
|
+
// validate
|
|
52
|
+
expect(actual).toBeUndefined();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("should return resource if resource is found", () => {
|
|
56
|
+
// execute
|
|
57
|
+
const actual = bundleUtils.getResource(
|
|
58
|
+
inputPayload.entry,
|
|
59
|
+
"ec0bb1b3-b229-36cf-7e34-3f5fec9d3afe"
|
|
60
|
+
);
|
|
61
|
+
// validate
|
|
62
|
+
expect(actual).not.toBeNull();
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export class BundleUtils {
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
*
|
|
5
|
+
* @param bundleEntry Bundle.entry[] i.e. the bundle entries to filter
|
|
6
|
+
* @param resourceTypeToFilter ResourceType to filter from bundle entries
|
|
7
|
+
* @returns array of resources
|
|
8
|
+
*/
|
|
9
|
+
getResources(bundleEntry: any[], resourceTypeToFilter: string): any[] {
|
|
10
|
+
return bundleEntry?.length ? bundleEntry.filter(x => x['resource']['resourceType'] === resourceTypeToFilter) : [];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
*
|
|
15
|
+
* @param bundleEntry Bundle.entry[] i.e. the bundle entries to filter
|
|
16
|
+
* @param resourceId Resource ID to filter from bundle entries
|
|
17
|
+
* @returns single resource
|
|
18
|
+
*/
|
|
19
|
+
getResource(bundleEntry: any[], resourceId: string): any {
|
|
20
|
+
return bundleEntry?.length ? bundleEntry.find(x => x['resource']['id'] === resourceId) : null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
|
|
@@ -1,29 +1,40 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { ResourceUtilities } from "./ResourceUtilities";
|
|
1
|
+
import { ResourceUtils } from "./ResourceUtils";
|
|
3
2
|
|
|
4
|
-
const
|
|
5
|
-
|
|
3
|
+
const patientPayload = require("./../../test-resources/Patient-R4.json");
|
|
4
|
+
const careTeamPayload = require("./../../test-resources/CareTeam-R4.json");
|
|
5
|
+
describe("ResourceUtils", () => {
|
|
6
|
+
|
|
7
|
+
let resourceUtils = new ResourceUtils();
|
|
6
8
|
|
|
7
9
|
describe("#getResourceProperty()", () => {
|
|
8
|
-
it(
|
|
10
|
+
it("should return property if property exists in valid inputJson", () => {
|
|
9
11
|
// execute
|
|
10
|
-
const actual =
|
|
12
|
+
const actual = resourceUtils.getResourceProperty(
|
|
13
|
+
patientPayload,
|
|
14
|
+
"deceasedBoolean"
|
|
15
|
+
);
|
|
11
16
|
// validate
|
|
12
17
|
expect(actual).toBeFalse();
|
|
13
18
|
});
|
|
14
19
|
|
|
15
|
-
it(
|
|
20
|
+
it("should return null if property exists in valid inputJson", () => {
|
|
16
21
|
// execute
|
|
17
|
-
const actual =
|
|
22
|
+
const actual = resourceUtils.getResourceProperty(
|
|
23
|
+
patientPayload,
|
|
24
|
+
"abcd"
|
|
25
|
+
);
|
|
18
26
|
// validate
|
|
19
27
|
expect(actual).toBeNull();
|
|
20
28
|
});
|
|
21
29
|
|
|
22
|
-
it(
|
|
30
|
+
it("should return null if invalid inputJson is passed", () => {
|
|
23
31
|
// setup
|
|
24
|
-
const inputPayload = [1,2];
|
|
32
|
+
const inputPayload = [1, 2];
|
|
25
33
|
// execute
|
|
26
|
-
const actual =
|
|
34
|
+
const actual = resourceUtils.getResourceProperty(
|
|
35
|
+
inputPayload,
|
|
36
|
+
"deceasedBoolean"
|
|
37
|
+
);
|
|
27
38
|
// validate
|
|
28
39
|
expect(actual).toBeNull();
|
|
29
40
|
});
|
|
@@ -47,7 +58,11 @@ describe("ResourceUtilities", () => {
|
|
|
47
58
|
// setup
|
|
48
59
|
const value = "abc";
|
|
49
60
|
// execute
|
|
50
|
-
const actual =
|
|
61
|
+
const actual = resourceUtils.getIdentifiersByProperty(
|
|
62
|
+
null,
|
|
63
|
+
"abc",
|
|
64
|
+
value
|
|
65
|
+
);
|
|
51
66
|
// validate
|
|
52
67
|
expect(actual.length).toEqual(0);
|
|
53
68
|
});
|
|
@@ -56,7 +71,7 @@ describe("ResourceUtilities", () => {
|
|
|
56
71
|
// setup
|
|
57
72
|
const value = "abc";
|
|
58
73
|
// execute
|
|
59
|
-
const actual =
|
|
74
|
+
const actual = resourceUtils.getIdentifiersByProperty(
|
|
60
75
|
identifierList,
|
|
61
76
|
"abc",
|
|
62
77
|
value
|
|
@@ -69,7 +84,7 @@ describe("ResourceUtilities", () => {
|
|
|
69
84
|
// setup
|
|
70
85
|
const systemUrl = "http://somesystem.com";
|
|
71
86
|
// execute
|
|
72
|
-
const actual =
|
|
87
|
+
const actual = resourceUtils.getIdentifiersByProperty(
|
|
73
88
|
identifierList,
|
|
74
89
|
"system",
|
|
75
90
|
systemUrl
|
|
@@ -82,7 +97,7 @@ describe("ResourceUtilities", () => {
|
|
|
82
97
|
// setup
|
|
83
98
|
const value = "abc";
|
|
84
99
|
// execute
|
|
85
|
-
const actual =
|
|
100
|
+
const actual = resourceUtils.getIdentifiersByProperty(
|
|
86
101
|
identifierList,
|
|
87
102
|
"value",
|
|
88
103
|
value
|
|
@@ -106,7 +121,7 @@ describe("ResourceUtilities", () => {
|
|
|
106
121
|
|
|
107
122
|
it("should return empty array if null is passed as extension list", () => {
|
|
108
123
|
// execute
|
|
109
|
-
const actual =
|
|
124
|
+
const actual = resourceUtils.getExtensionsByUrl(null, "url");
|
|
110
125
|
// validate
|
|
111
126
|
expect(actual.length).toEqual(0);
|
|
112
127
|
});
|
|
@@ -122,7 +137,7 @@ describe("ResourceUtilities", () => {
|
|
|
122
137
|
];
|
|
123
138
|
const url = "http://ns.electronichealth.net.au/id/hi/ihi/1.0";
|
|
124
139
|
// execute
|
|
125
|
-
const actual =
|
|
140
|
+
const actual = resourceUtils.getExtensionsByUrl(
|
|
126
141
|
extensionListInvalid,
|
|
127
142
|
url
|
|
128
143
|
);
|
|
@@ -134,7 +149,7 @@ describe("ResourceUtilities", () => {
|
|
|
134
149
|
// setup
|
|
135
150
|
const url = "http://somesystem.com";
|
|
136
151
|
// execute
|
|
137
|
-
const actual =
|
|
152
|
+
const actual = resourceUtils.getExtensionsByUrl(extensionList, url);
|
|
138
153
|
// validate
|
|
139
154
|
expect(actual.length).toEqual(0);
|
|
140
155
|
});
|
|
@@ -143,7 +158,7 @@ describe("ResourceUtilities", () => {
|
|
|
143
158
|
// setup
|
|
144
159
|
const url = "http://ns.electronichealth.net.au/id/hi/ihi/1.0";
|
|
145
160
|
// execute
|
|
146
|
-
const actual =
|
|
161
|
+
const actual = resourceUtils.getExtensionsByUrl(extensionList, url);
|
|
147
162
|
// validate
|
|
148
163
|
expect(actual.length).toEqual(1);
|
|
149
164
|
});
|
|
@@ -170,7 +185,7 @@ describe("ResourceUtilities", () => {
|
|
|
170
185
|
// setup
|
|
171
186
|
const value = "abc";
|
|
172
187
|
// execute
|
|
173
|
-
const actual =
|
|
188
|
+
const actual = resourceUtils.getCodingsByProperty(null, "abc", value);
|
|
174
189
|
// validate
|
|
175
190
|
expect(actual.length).toEqual(0);
|
|
176
191
|
});
|
|
@@ -179,7 +194,7 @@ describe("ResourceUtilities", () => {
|
|
|
179
194
|
// setup
|
|
180
195
|
const value = "abc";
|
|
181
196
|
// execute
|
|
182
|
-
const actual =
|
|
197
|
+
const actual = resourceUtils.getCodingsByProperty(
|
|
183
198
|
codingList,
|
|
184
199
|
"abc",
|
|
185
200
|
value
|
|
@@ -192,7 +207,7 @@ describe("ResourceUtilities", () => {
|
|
|
192
207
|
// setup
|
|
193
208
|
const systemUrl = "http://somesystem.com";
|
|
194
209
|
// execute
|
|
195
|
-
const actual =
|
|
210
|
+
const actual = resourceUtils.getCodingsByProperty(
|
|
196
211
|
codingList,
|
|
197
212
|
"system",
|
|
198
213
|
systemUrl
|
|
@@ -205,7 +220,7 @@ describe("ResourceUtilities", () => {
|
|
|
205
220
|
// setup
|
|
206
221
|
const value = "abc";
|
|
207
222
|
// execute
|
|
208
|
-
const actual =
|
|
223
|
+
const actual = resourceUtils.getCodingsByProperty(
|
|
209
224
|
codingList,
|
|
210
225
|
"code",
|
|
211
226
|
value
|
|
@@ -218,7 +233,7 @@ describe("ResourceUtilities", () => {
|
|
|
218
233
|
// setup
|
|
219
234
|
const value = false;
|
|
220
235
|
// execute
|
|
221
|
-
const actual =
|
|
236
|
+
const actual = resourceUtils.getCodingsByProperty(
|
|
222
237
|
codingList,
|
|
223
238
|
"userSelected",
|
|
224
239
|
value
|
|
@@ -227,4 +242,61 @@ describe("ResourceUtilities", () => {
|
|
|
227
242
|
expect(actual.length).toEqual(1);
|
|
228
243
|
});
|
|
229
244
|
});
|
|
245
|
+
|
|
246
|
+
describe("#getValuesAtResourcePath()", () => {
|
|
247
|
+
|
|
248
|
+
it("should return array with values if path exists for a top level element", () => {
|
|
249
|
+
// execute
|
|
250
|
+
const pathValues = resourceUtils.getValuesAtResourcePath(patientPayload, "Patient.gender");
|
|
251
|
+
// validate
|
|
252
|
+
expect(pathValues.length).toEqual(1);
|
|
253
|
+
expect(pathValues[0]).toEqual("male");
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
it("should return array with values if path exists for a deep array element", () => {
|
|
257
|
+
// execute
|
|
258
|
+
const pathValues = resourceUtils.getValuesAtResourcePath(patientPayload, "Patient.contact.relationship.coding.system");
|
|
259
|
+
// validate
|
|
260
|
+
expect(pathValues.length).toEqual(2);
|
|
261
|
+
expect(pathValues[0]).toEqual("http://terminology.hl7.org/CodeSystem/v2-0131");
|
|
262
|
+
expect(pathValues[1]).toEqual("http://terminology.hl7.org/CodeSystem/v2-0132");
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
it("should return array with values if path exists for a deep json element", () => {
|
|
266
|
+
// execute
|
|
267
|
+
const pathValues = resourceUtils.getValuesAtResourcePath(patientPayload, "Patient.maritalStatus.coding.system");
|
|
268
|
+
// validate
|
|
269
|
+
expect(pathValues.length).toEqual(1);
|
|
270
|
+
expect(pathValues[0]).toEqual("http://terminology.hl7.org/CodeSystem/v3-MaritalStatus");
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
it("should return empty array if path does not exist", () => {
|
|
274
|
+
// execute
|
|
275
|
+
const pathValues = resourceUtils.getValuesAtResourcePath(patientPayload, "Patient.contact.relationship.coding.abcd");
|
|
276
|
+
// validate
|
|
277
|
+
expect(pathValues.length).toEqual(0);
|
|
278
|
+
});
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
describe("#getAllResourceReferences()", () => {
|
|
282
|
+
|
|
283
|
+
it("should return array of all references in a resource when references found", () => {
|
|
284
|
+
// execute
|
|
285
|
+
const actual = resourceUtils.getAllReferencesFromResource(careTeamPayload);
|
|
286
|
+
// validate
|
|
287
|
+
expect(actual.length).toEqual(6);
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
it("should return empty array if references in a resource not found", () => {
|
|
291
|
+
// setup
|
|
292
|
+
const input = {
|
|
293
|
+
"resourceType": "Patient"
|
|
294
|
+
};
|
|
295
|
+
// execute
|
|
296
|
+
const actual = resourceUtils.getAllReferencesFromResource(input);
|
|
297
|
+
// validate
|
|
298
|
+
expect(actual.length).toEqual(0);
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
});
|
|
230
302
|
});
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
export class ResourceUtils {
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* @param inputJson - valid json
|
|
5
|
+
* @param propertyName - top level property for resource
|
|
6
|
+
* @returns json property if it exists
|
|
7
|
+
* @limitation currently just supports get for top level property on resource
|
|
8
|
+
*/
|
|
9
|
+
getResourceProperty(inputJson: object, propertyName: string) {
|
|
10
|
+
let resourcePropertyValue = null;
|
|
11
|
+
if (inputJson.hasOwnProperty(propertyName)) {
|
|
12
|
+
resourcePropertyValue = inputJson[propertyName];
|
|
13
|
+
}
|
|
14
|
+
return resourcePropertyValue;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
*
|
|
19
|
+
* @param identifierList list of identifiers
|
|
20
|
+
* @param propertyToCompare identifier property to compare
|
|
21
|
+
* @param propertyValue value we want to compare against
|
|
22
|
+
* @returns array of matches
|
|
23
|
+
* @limitations currently does not work with identifier.type, identifier.period & identifier.assigner
|
|
24
|
+
*/
|
|
25
|
+
getIdentifiersByProperty(
|
|
26
|
+
identifierList: any[],
|
|
27
|
+
propertyToCompare: string,
|
|
28
|
+
propertyValue: string
|
|
29
|
+
): any[] {
|
|
30
|
+
return identifierList?.length
|
|
31
|
+
? identifierList.filter((x) => x[propertyToCompare] === propertyValue)
|
|
32
|
+
: [];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
*
|
|
37
|
+
* @param extensionList list of extensions
|
|
38
|
+
* @param extensionUrl Extension.url to compare
|
|
39
|
+
* @returns array of matches
|
|
40
|
+
*/
|
|
41
|
+
getExtensionsByUrl(extensionList: any[], extensionUrl: string): any[] {
|
|
42
|
+
return extensionList?.length
|
|
43
|
+
? extensionList.filter((x) => x["url"] === extensionUrl)
|
|
44
|
+
: [];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
*
|
|
49
|
+
* @param codingList list of codings
|
|
50
|
+
* @param propertyToCompare coding property to compare
|
|
51
|
+
* @param propertyValue value we want to compare against string or boolean
|
|
52
|
+
* @returns array of matches
|
|
53
|
+
*/
|
|
54
|
+
getCodingsByProperty(
|
|
55
|
+
codingList: any[],
|
|
56
|
+
propertyToCompare: string,
|
|
57
|
+
propertyValue: string | boolean
|
|
58
|
+
): any[] {
|
|
59
|
+
return codingList?.length
|
|
60
|
+
? codingList.filter((x) => x[propertyToCompare] === propertyValue)
|
|
61
|
+
: [];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
*
|
|
66
|
+
* @param resource resource for which path needs to be validated
|
|
67
|
+
* @param elementPath path to validate in resource
|
|
68
|
+
* @returns array of elements found at the provided path
|
|
69
|
+
*/
|
|
70
|
+
getValuesAtResourcePath(resource: any, elementPath: string): any[] {
|
|
71
|
+
const pathSections = elementPath.split(".");
|
|
72
|
+
let resourcePathValue;
|
|
73
|
+
for (let index = 1; index < pathSections.length; index++) {
|
|
74
|
+
const subPaths = pathSections[index];
|
|
75
|
+
resourcePathValue = resourcePathValue ? resourcePathValue[subPaths] : resource[subPaths];
|
|
76
|
+
if (resourcePathValue) {
|
|
77
|
+
if (this.isPrimitive(resourcePathValue)) {
|
|
78
|
+
return [resourcePathValue];
|
|
79
|
+
} else if (Array.isArray(resourcePathValue) && resourcePathValue.length > 0) {
|
|
80
|
+
let resultSet = [];
|
|
81
|
+
for (let subPathIndex = 0; subPathIndex < resourcePathValue.length; subPathIndex++) {
|
|
82
|
+
const subPathValue = resourcePathValue[subPathIndex];
|
|
83
|
+
resultSet.push(...this.getValuesAtResourcePath(subPathValue,
|
|
84
|
+
pathSections.slice(index).join(".")));
|
|
85
|
+
}
|
|
86
|
+
return resultSet;
|
|
87
|
+
} else if (typeof(resourcePathValue) === 'object') {
|
|
88
|
+
return this.getValuesAtResourcePath(resourcePathValue,
|
|
89
|
+
pathSections.slice(index).join("."));
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return [];
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
private isPrimitive(value: any) {
|
|
99
|
+
return typeof(value) === "boolean" || typeof(value) === "string";
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* @param resource resource to pull out references from
|
|
104
|
+
* @returns array of references inside a resource
|
|
105
|
+
*/
|
|
106
|
+
getAllReferencesFromResource(resource: any): string[] {
|
|
107
|
+
const stringifiedResource = JSON.stringify(resource);
|
|
108
|
+
const referenceJsonString = '"reference":';
|
|
109
|
+
let references = [];
|
|
110
|
+
let cursor = stringifiedResource.indexOf(referenceJsonString, 0);
|
|
111
|
+
while (cursor > -1) {
|
|
112
|
+
const referenceStart = stringifiedResource.indexOf(referenceJsonString, cursor) + referenceJsonString.length;
|
|
113
|
+
const referenceEnd = stringifiedResource.indexOf('"', referenceStart + 1);
|
|
114
|
+
const reference = stringifiedResource.substring(referenceStart, referenceEnd);
|
|
115
|
+
// this means the reference ends started reading from start again
|
|
116
|
+
if(referenceEnd < cursor) {
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
references.push(reference);
|
|
120
|
+
cursor = referenceEnd;
|
|
121
|
+
}
|
|
122
|
+
return references;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
{
|
|
2
|
+
"resourceType": "CareTeam",
|
|
3
|
+
"id": "example",
|
|
4
|
+
"text": {
|
|
5
|
+
"status": "generated",
|
|
6
|
+
"div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">Care Team</div>"
|
|
7
|
+
},
|
|
8
|
+
"contained": [
|
|
9
|
+
{
|
|
10
|
+
"resourceType": "Practitioner",
|
|
11
|
+
"id": "pr1",
|
|
12
|
+
"name": [
|
|
13
|
+
{
|
|
14
|
+
"family": "Dietician",
|
|
15
|
+
"given": [
|
|
16
|
+
"Dorothy"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"identifier": [
|
|
23
|
+
{
|
|
24
|
+
"value": "12345"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"status": "active",
|
|
28
|
+
"category": [
|
|
29
|
+
{
|
|
30
|
+
"coding": [
|
|
31
|
+
{
|
|
32
|
+
"system": "http://loinc.org",
|
|
33
|
+
"code": "LA27976-2",
|
|
34
|
+
"display": "Encounter-focused care team"
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
],
|
|
39
|
+
"name": "Peter James Charlmers Care Plan for Inpatient Encounter",
|
|
40
|
+
"subject": {
|
|
41
|
+
"reference": "Patient/example",
|
|
42
|
+
"display": "Peter James Chalmers"
|
|
43
|
+
},
|
|
44
|
+
"encounter": {
|
|
45
|
+
"reference": "Encounter/example"
|
|
46
|
+
},
|
|
47
|
+
"period": {
|
|
48
|
+
"end": "2013-01-01"
|
|
49
|
+
},
|
|
50
|
+
"participant": [
|
|
51
|
+
{
|
|
52
|
+
"role": [
|
|
53
|
+
{
|
|
54
|
+
"text": "responsiblePerson"
|
|
55
|
+
}
|
|
56
|
+
],
|
|
57
|
+
"member": {
|
|
58
|
+
"reference": "Patient/example",
|
|
59
|
+
"display": "Peter James Chalmers"
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"role": [
|
|
64
|
+
{
|
|
65
|
+
"text": "adviser"
|
|
66
|
+
}
|
|
67
|
+
],
|
|
68
|
+
"member": {
|
|
69
|
+
"reference": "#pr1",
|
|
70
|
+
"display": "Dorothy Dietition"
|
|
71
|
+
},
|
|
72
|
+
"onBehalfOf": {
|
|
73
|
+
"reference": "Organization/f001"
|
|
74
|
+
},
|
|
75
|
+
"period": {
|
|
76
|
+
"end": "2013-01-01"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
"managingOrganization": [
|
|
81
|
+
{
|
|
82
|
+
"reference": "Organization/f001"
|
|
83
|
+
}
|
|
84
|
+
]
|
|
85
|
+
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export declare class BundleUtility {
|
|
2
|
-
/**
|
|
3
|
-
*
|
|
4
|
-
* @param bundleEntry Bundle.entry[] i.e. the bundle entries to filter
|
|
5
|
-
* @param resourceTypeToFilter ResourceType to filter from bundle entries
|
|
6
|
-
* @returns array of resources
|
|
7
|
-
*/
|
|
8
|
-
getResourcesFromBundle(bundleEntry: any[], resourceTypeToFilter: string): any[];
|
|
9
|
-
}
|
|
10
|
-
export declare const BundleUtilities: BundleUtility;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BundleUtilities = exports.BundleUtility = void 0;
|
|
4
|
-
class BundleUtility {
|
|
5
|
-
/**
|
|
6
|
-
*
|
|
7
|
-
* @param bundleEntry Bundle.entry[] i.e. the bundle entries to filter
|
|
8
|
-
* @param resourceTypeToFilter ResourceType to filter from bundle entries
|
|
9
|
-
* @returns array of resources
|
|
10
|
-
*/
|
|
11
|
-
getResourcesFromBundle(bundleEntry, resourceTypeToFilter) {
|
|
12
|
-
return (bundleEntry === null || bundleEntry === void 0 ? void 0 : bundleEntry.length) ? bundleEntry.filter(x => x['resource']['resourceType'] === resourceTypeToFilter) : [];
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
exports.BundleUtility = BundleUtility;
|
|
16
|
-
exports.BundleUtilities = new BundleUtility();
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const BundleUtilities_1 = require("./BundleUtilities");
|
|
4
|
-
const inputPayload = require("./../../test-resources/Bundle-R4.json");
|
|
5
|
-
describe("BundleUtilities", () => {
|
|
6
|
-
describe("#getResourcesFromBundle()", () => {
|
|
7
|
-
it('should return empty array if null is passed as bundle entries', () => {
|
|
8
|
-
// execute
|
|
9
|
-
const actual = BundleUtilities_1.BundleUtilities.getResourcesFromBundle(null, 'Patient');
|
|
10
|
-
// validate
|
|
11
|
-
expect(actual.length).toEqual(0);
|
|
12
|
-
});
|
|
13
|
-
it('should return empty array if invalid resourceType is passed', () => {
|
|
14
|
-
// execute
|
|
15
|
-
const actual = BundleUtilities_1.BundleUtilities.getResourcesFromBundle(inputPayload.entry, 'patient');
|
|
16
|
-
// validate
|
|
17
|
-
expect(actual.length).toEqual(0);
|
|
18
|
-
});
|
|
19
|
-
it('should return all matches array', () => {
|
|
20
|
-
// execute
|
|
21
|
-
const actual = BundleUtilities_1.BundleUtilities.getResourcesFromBundle(inputPayload.entry, 'Claim');
|
|
22
|
-
// validate
|
|
23
|
-
expect(actual.length).toEqual(27);
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
});
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ResourceUtilities = exports.ResourceUtility = void 0;
|
|
4
|
-
class ResourceUtility {
|
|
5
|
-
/**
|
|
6
|
-
*
|
|
7
|
-
* @param inputJson - valid json
|
|
8
|
-
* @param propertyName - top level property for resource
|
|
9
|
-
* @returns json property if it exists
|
|
10
|
-
* @limitation currently just supports get for top level property on resource
|
|
11
|
-
*/
|
|
12
|
-
getResourceProperty(inputJson, propertyName) {
|
|
13
|
-
let resourcePropertyValue = null;
|
|
14
|
-
if (inputJson.hasOwnProperty(propertyName)) {
|
|
15
|
-
resourcePropertyValue = inputJson[propertyName];
|
|
16
|
-
}
|
|
17
|
-
return resourcePropertyValue;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
*
|
|
21
|
-
* @param identifierList list of identifiers
|
|
22
|
-
* @param propertyToCompare identifier property to compare
|
|
23
|
-
* @param propertyValue value we want to compare against
|
|
24
|
-
* @returns array of matches
|
|
25
|
-
* @limitations currently does not work with identifier.type, identifier.period & identifier.assigner
|
|
26
|
-
*/
|
|
27
|
-
getIdentifiersByProperty(identifierList, propertyToCompare, propertyValue) {
|
|
28
|
-
return (identifierList === null || identifierList === void 0 ? void 0 : identifierList.length) ? identifierList.filter(x => x[propertyToCompare] === propertyValue) : [];
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
*
|
|
32
|
-
* @param extensionList list of extensions
|
|
33
|
-
* @param extensionUrl Extension.url to compare
|
|
34
|
-
* @returns array of matches
|
|
35
|
-
*/
|
|
36
|
-
getExtensionsByUrl(extensionList, extensionUrl) {
|
|
37
|
-
return (extensionList === null || extensionList === void 0 ? void 0 : extensionList.length) ? extensionList.filter(x => x['url'] === extensionUrl) : [];
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
*
|
|
41
|
-
* @param codingList list of codings
|
|
42
|
-
* @param propertyToCompare coding property to compare
|
|
43
|
-
* @param propertyValue value we want to compare against string or boolean
|
|
44
|
-
* @returns array of matches
|
|
45
|
-
*/
|
|
46
|
-
getCodingsByProperty(codingList, propertyToCompare, propertyValue) {
|
|
47
|
-
return (codingList === null || codingList === void 0 ? void 0 : codingList.length) ? codingList.filter(x => x[propertyToCompare] === propertyValue) : [];
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
exports.ResourceUtility = ResourceUtility;
|
|
51
|
-
exports.ResourceUtilities = new ResourceUtility();
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { BundleUtilities } from "./BundleUtilities";
|
|
2
|
-
|
|
3
|
-
const inputPayload = require("./../../test-resources/Bundle-R4.json");
|
|
4
|
-
describe("BundleUtilities", () => {
|
|
5
|
-
|
|
6
|
-
describe("#getResourcesFromBundle()", () => {
|
|
7
|
-
it('should return empty array if null is passed as bundle entries', () => {
|
|
8
|
-
// execute
|
|
9
|
-
const actual = BundleUtilities.getResourcesFromBundle(null, 'Patient');
|
|
10
|
-
// validate
|
|
11
|
-
expect(actual.length).toEqual(0);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('should return empty array if invalid resourceType is passed', () => {
|
|
15
|
-
// execute
|
|
16
|
-
const actual = BundleUtilities.getResourcesFromBundle(inputPayload.entry, 'patient');
|
|
17
|
-
// validate
|
|
18
|
-
expect(actual.length).toEqual(0);
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
it('should return all matches array', () => {
|
|
22
|
-
// execute
|
|
23
|
-
const actual = BundleUtilities.getResourcesFromBundle(inputPayload.entry, 'Claim');
|
|
24
|
-
// validate
|
|
25
|
-
expect(actual.length).toEqual(27);
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
});
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
export class BundleUtility {
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
* @param bundleEntry Bundle.entry[] i.e. the bundle entries to filter
|
|
6
|
-
* @param resourceTypeToFilter ResourceType to filter from bundle entries
|
|
7
|
-
* @returns array of resources
|
|
8
|
-
*/
|
|
9
|
-
getResourcesFromBundle(bundleEntry: any[], resourceTypeToFilter: string): any[] {
|
|
10
|
-
return bundleEntry?.length ? bundleEntry.filter(x => x['resource']['resourceType'] === resourceTypeToFilter) : [];
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const BundleUtilities = new BundleUtility();
|
|
15
|
-
|
|
16
|
-
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
export class ResourceUtility {
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
*
|
|
5
|
-
* @param inputJson - valid json
|
|
6
|
-
* @param propertyName - top level property for resource
|
|
7
|
-
* @returns json property if it exists
|
|
8
|
-
* @limitation currently just supports get for top level property on resource
|
|
9
|
-
*/
|
|
10
|
-
getResourceProperty(inputJson: object, propertyName: string) {
|
|
11
|
-
let resourcePropertyValue = null;
|
|
12
|
-
if (inputJson.hasOwnProperty(propertyName)) {
|
|
13
|
-
resourcePropertyValue = inputJson[propertyName];
|
|
14
|
-
}
|
|
15
|
-
return resourcePropertyValue;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
*
|
|
20
|
-
* @param identifierList list of identifiers
|
|
21
|
-
* @param propertyToCompare identifier property to compare
|
|
22
|
-
* @param propertyValue value we want to compare against
|
|
23
|
-
* @returns array of matches
|
|
24
|
-
* @limitations currently does not work with identifier.type, identifier.period & identifier.assigner
|
|
25
|
-
*/
|
|
26
|
-
getIdentifiersByProperty(identifierList: any[], propertyToCompare: string, propertyValue: string): any[] {
|
|
27
|
-
return identifierList?.length ? identifierList.filter(x => x[propertyToCompare] === propertyValue): [];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
*
|
|
32
|
-
* @param extensionList list of extensions
|
|
33
|
-
* @param extensionUrl Extension.url to compare
|
|
34
|
-
* @returns array of matches
|
|
35
|
-
*/
|
|
36
|
-
getExtensionsByUrl(extensionList: any[], extensionUrl: string): any[] {
|
|
37
|
-
return extensionList?.length ? extensionList.filter(x => x['url'] === extensionUrl) : [];
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
*
|
|
42
|
-
* @param codingList list of codings
|
|
43
|
-
* @param propertyToCompare coding property to compare
|
|
44
|
-
* @param propertyValue value we want to compare against string or boolean
|
|
45
|
-
* @returns array of matches
|
|
46
|
-
*/
|
|
47
|
-
getCodingsByProperty(codingList: any[], propertyToCompare: string, propertyValue: string | boolean): any[] {
|
|
48
|
-
return codingList?.length ? codingList.filter(x => x[propertyToCompare] === propertyValue) : [];
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export const ResourceUtilities = new ResourceUtility();
|
|
File without changes
|
|
File without changes
|