@smile-cdr/fhirts 1.5.0 → 2.0.1
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/.github/workflows/npm-publish.yml +4 -0
- package/.github/workflows/pr-build.yml +31 -0
- package/.nycrc +7 -0
- package/CHANGELOG.md +13 -0
- package/GETTINGSTARTED.md +40 -1
- package/dist/FHIR-R3.d.ts +78 -1
- package/dist/FHIR-R3.js +28 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +5 -1
- package/dist/library/BundleUtilities/BundleUtilities.d.ts +10 -0
- package/dist/library/BundleUtilities/BundleUtilities.js +16 -0
- package/dist/library/BundleUtilities/BundleUtilities.spec.d.ts +1 -0
- package/dist/library/BundleUtilities/BundleUtilities.spec.js +26 -0
- package/dist/library/ResourceUtilities/ResourceUtilities.d.ts +35 -0
- package/dist/library/ResourceUtilities/ResourceUtilities.js +51 -0
- package/dist/library/ResourceUtilities/ResourceUtilities.spec.d.ts +1 -0
- package/dist/library/ResourceUtilities/ResourceUtilities.spec.js +180 -0
- package/package.json +13 -2
- package/spec/support/jasmine.json +10 -0
- package/src/FHIR-R3.ts +88 -1
- package/src/index.ts +3 -1
- package/src/library/BundleUtilities/BundleUtilities.spec.ts +29 -0
- package/src/library/BundleUtilities/BundleUtilities.ts +16 -0
- package/src/library/ResourceUtilities/ResourceUtilities.spec.ts +230 -0
- package/src/library/ResourceUtilities/ResourceUtilities.ts +52 -0
- package/src/test-resources/Bundle-R4.json +27472 -0
- package/src/test-resources/Patient-R4.json +125 -0
package/src/FHIR-R3.ts
CHANGED
|
@@ -1250,4 +1250,91 @@ export class Age extends FHIRElement {
|
|
|
1250
1250
|
code: Code;
|
|
1251
1251
|
}
|
|
1252
1252
|
|
|
1253
|
-
export
|
|
1253
|
+
export class ValueSet extends BaseResource {
|
|
1254
|
+
resourceType: "ValueSet";
|
|
1255
|
+
url?: string;
|
|
1256
|
+
identifier?: Identifier[];
|
|
1257
|
+
version?: string;
|
|
1258
|
+
name?: string;
|
|
1259
|
+
title?: string;
|
|
1260
|
+
status: string;
|
|
1261
|
+
experimental?: boolean;
|
|
1262
|
+
date?: string | Date;
|
|
1263
|
+
publisher?: string;
|
|
1264
|
+
contact?: ContactDetail[];
|
|
1265
|
+
description?: string;
|
|
1266
|
+
useContext?: UsageContext[];
|
|
1267
|
+
jurisdiction?: CodeableConcept[];
|
|
1268
|
+
immutable?: boolean;
|
|
1269
|
+
purpose?: string;
|
|
1270
|
+
copyright?: string;
|
|
1271
|
+
extensible?: boolean;
|
|
1272
|
+
compose?: ValueSetCompose;
|
|
1273
|
+
expansion?: ValueSetExpansion;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
export class ValueSetCompose extends BackboneElement {
|
|
1277
|
+
lockedDate?: string | Date;
|
|
1278
|
+
inactive?: boolean;
|
|
1279
|
+
include: ValueSetInclude[];
|
|
1280
|
+
exclude?: ValueSetInclude[];
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
export class ValueSetInclude extends BackboneElement {
|
|
1284
|
+
system?: string;
|
|
1285
|
+
version?: string;
|
|
1286
|
+
concept?: ValueSetConcept[];
|
|
1287
|
+
filter?: ValueSetFilter[];
|
|
1288
|
+
valueSet?: string[];
|
|
1289
|
+
}
|
|
1290
|
+
|
|
1291
|
+
export class ValueSetConcept extends BackboneElement {
|
|
1292
|
+
code: string;
|
|
1293
|
+
display?: string;
|
|
1294
|
+
designation?: ValueSetDesignation[];
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
export class ValueSetDesignation extends BackboneElement {
|
|
1298
|
+
language?: string;
|
|
1299
|
+
use?: Coding;
|
|
1300
|
+
value: string;
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
export class ValueSetFilter extends BackboneElement {
|
|
1304
|
+
property: string;
|
|
1305
|
+
op: string;
|
|
1306
|
+
value: string;
|
|
1307
|
+
}
|
|
1308
|
+
|
|
1309
|
+
export class ValueSetExpansion extends BackboneElement {
|
|
1310
|
+
identifier?: string;
|
|
1311
|
+
timestamp: string | Date;
|
|
1312
|
+
total?: number;
|
|
1313
|
+
offset?: number;
|
|
1314
|
+
parameter?: ValueSetParameter[];
|
|
1315
|
+
contains?: ValueSetContains[];
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
export class ValueSetParameter extends BackboneElement {
|
|
1319
|
+
name: string;
|
|
1320
|
+
valueString?: string;
|
|
1321
|
+
valueBoolean?: boolean;
|
|
1322
|
+
valueInteger?: number;
|
|
1323
|
+
valueDecimal?: number;
|
|
1324
|
+
valueUri?: string;
|
|
1325
|
+
valueCode?: string;
|
|
1326
|
+
}
|
|
1327
|
+
|
|
1328
|
+
export class ValueSetContains extends BackboneElement {
|
|
1329
|
+
system?: string;
|
|
1330
|
+
abstract?: boolean;
|
|
1331
|
+
inactive?: boolean;
|
|
1332
|
+
version?: string;
|
|
1333
|
+
code?: Code;
|
|
1334
|
+
display?: string;
|
|
1335
|
+
designation?: ValueSetDesignation[];
|
|
1336
|
+
contains?: ValueSetContains[];
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
|
|
1340
|
+
export type Resource = AllergyIntolerance | ClinicalImpression | Schedule | HealthcareService | Bundle | AuditEvent | CommunicationRequest | Immunization | Observation | Device | Practitioner | PractitionerRole | ProcedureRequest | Task | Communication | CarePlan | EpisodeOfCare | CareTeam | Encounter | ProcessRequest | Account | Location | Organization | AppointmentResponse | Appointment | QuestionnaireResponse | Questionnaire | Slot | Patient | DocumentReference | ValueSet;
|
package/src/index.ts
CHANGED
|
@@ -2,5 +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
|
-
|
|
5
|
+
import { ResourceUtilities } from './library/ResourceUtilities/ResourceUtilities';
|
|
6
|
+
import { BundleUtilities } from './library/BundleUtilities/BundleUtilities';
|
|
7
|
+
export { fhirR4, fhirR3, IfhirR4, dstu2, ResourceUtilities, BundleUtilities };
|
|
6
8
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { Patient } from "../../FHIR-R4/classes/patient";
|
|
2
|
+
import { BundleUtilities } from "./BundleUtilities";
|
|
3
|
+
|
|
4
|
+
const inputPayload = require("./../../test-resources/Bundle-R4.json");
|
|
5
|
+
describe("BundleUtilities", () => {
|
|
6
|
+
|
|
7
|
+
describe("#getResourcesFromBundle()", () => {
|
|
8
|
+
it('should return empty array if null is passed as bundle entries', () => {
|
|
9
|
+
// execute
|
|
10
|
+
const actual = BundleUtilities.getResourcesFromBundle(null, 'Patient');
|
|
11
|
+
// validate
|
|
12
|
+
expect(actual.length).toEqual(0);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should return empty array if invalid resourceType is passed', () => {
|
|
16
|
+
// execute
|
|
17
|
+
const actual = BundleUtilities.getResourcesFromBundle(inputPayload.entry, 'patient');
|
|
18
|
+
// validate
|
|
19
|
+
expect(actual.length).toEqual(0);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should return all matches array', () => {
|
|
23
|
+
// execute
|
|
24
|
+
const actual = BundleUtilities.getResourcesFromBundle(inputPayload.entry, 'Claim');
|
|
25
|
+
// validate
|
|
26
|
+
expect(actual.length).toEqual(27);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
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
|
+
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { Patient } from "../../FHIR-R4/classes/patient";
|
|
2
|
+
import { ResourceUtilities } from "./ResourceUtilities";
|
|
3
|
+
|
|
4
|
+
const inputPayload = require("./../../test-resources/Patient-R4.json");
|
|
5
|
+
describe("ResourceUtilities", () => {
|
|
6
|
+
|
|
7
|
+
describe("#getResourceProperty()", () => {
|
|
8
|
+
it('should return property if property exists in valid inputJson', () => {
|
|
9
|
+
// execute
|
|
10
|
+
const actual = ResourceUtilities.getResourceProperty(inputPayload, 'deceasedBoolean');
|
|
11
|
+
// validate
|
|
12
|
+
expect(actual).toBeFalse();
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('should return null if property exists in valid inputJson', () => {
|
|
16
|
+
// execute
|
|
17
|
+
const actual = ResourceUtilities.getResourceProperty(inputPayload, 'abcd');
|
|
18
|
+
// validate
|
|
19
|
+
expect(actual).toBeNull();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('should return null if invalid inputJson is passed', () => {
|
|
23
|
+
// setup
|
|
24
|
+
const inputPayload = [1,2];
|
|
25
|
+
// execute
|
|
26
|
+
const actual = ResourceUtilities.getResourceProperty(inputPayload, 'deceasedBoolean');
|
|
27
|
+
// validate
|
|
28
|
+
expect(actual).toBeNull();
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe("#getIdentifiersByProperty()", () => {
|
|
33
|
+
const identifierList = [
|
|
34
|
+
{
|
|
35
|
+
use: "temp",
|
|
36
|
+
system: "http://hl7.org/fhir/sid/us-ssn",
|
|
37
|
+
value: "abc",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
use: "usual",
|
|
41
|
+
system: "http://ns.electronichealth.net.au/id/hi/ihi/1.0",
|
|
42
|
+
value: "abc",
|
|
43
|
+
},
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
it("should return empty array if null is passed as identifier list", () => {
|
|
47
|
+
// setup
|
|
48
|
+
const value = "abc";
|
|
49
|
+
// execute
|
|
50
|
+
const actual = ResourceUtilities.getIdentifiersByProperty(null, "abc", value);
|
|
51
|
+
// validate
|
|
52
|
+
expect(actual.length).toEqual(0);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("should return empty array if property not found", () => {
|
|
56
|
+
// setup
|
|
57
|
+
const value = "abc";
|
|
58
|
+
// execute
|
|
59
|
+
const actual = ResourceUtilities.getIdentifiersByProperty(
|
|
60
|
+
identifierList,
|
|
61
|
+
"abc",
|
|
62
|
+
value
|
|
63
|
+
);
|
|
64
|
+
// validate
|
|
65
|
+
expect(actual.length).toEqual(0);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("should return empty array if no matches found", () => {
|
|
69
|
+
// setup
|
|
70
|
+
const systemUrl = "http://somesystem.com";
|
|
71
|
+
// execute
|
|
72
|
+
const actual = ResourceUtilities.getIdentifiersByProperty(
|
|
73
|
+
identifierList,
|
|
74
|
+
"system",
|
|
75
|
+
systemUrl
|
|
76
|
+
);
|
|
77
|
+
// validate
|
|
78
|
+
expect(actual.length).toEqual(0);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("should return array with all matches", () => {
|
|
82
|
+
// setup
|
|
83
|
+
const value = "abc";
|
|
84
|
+
// execute
|
|
85
|
+
const actual = ResourceUtilities.getIdentifiersByProperty(
|
|
86
|
+
identifierList,
|
|
87
|
+
"value",
|
|
88
|
+
value
|
|
89
|
+
);
|
|
90
|
+
// validate
|
|
91
|
+
expect(actual.length).toEqual(2);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
describe("#getExtensionsByUrl()", () => {
|
|
96
|
+
const extensionList = [
|
|
97
|
+
{
|
|
98
|
+
url: "http://hl7.org/fhir/sid/us-ssn",
|
|
99
|
+
valueBoolean: true,
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
url: "http://ns.electronichealth.net.au/id/hi/ihi/1.0",
|
|
103
|
+
valueString: "abc",
|
|
104
|
+
},
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
it("should return empty array if null is passed as extension list", () => {
|
|
108
|
+
// execute
|
|
109
|
+
const actual = ResourceUtilities.getExtensionsByUrl(null, "url");
|
|
110
|
+
// validate
|
|
111
|
+
expect(actual.length).toEqual(0);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it("should return empty array if invalid extension array passed", () => {
|
|
115
|
+
// setup
|
|
116
|
+
const extensionListInvalid = [
|
|
117
|
+
{
|
|
118
|
+
use: "temp",
|
|
119
|
+
system: "http://hl7.org/fhir/sid/us-ssn",
|
|
120
|
+
value: "abc",
|
|
121
|
+
},
|
|
122
|
+
];
|
|
123
|
+
const url = "http://ns.electronichealth.net.au/id/hi/ihi/1.0";
|
|
124
|
+
// execute
|
|
125
|
+
const actual = ResourceUtilities.getExtensionsByUrl(
|
|
126
|
+
extensionListInvalid,
|
|
127
|
+
url
|
|
128
|
+
);
|
|
129
|
+
// validate
|
|
130
|
+
expect(actual.length).toEqual(0);
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
it("should return empty array if no matches found", () => {
|
|
134
|
+
// setup
|
|
135
|
+
const url = "http://somesystem.com";
|
|
136
|
+
// execute
|
|
137
|
+
const actual = ResourceUtilities.getExtensionsByUrl(extensionList, url);
|
|
138
|
+
// validate
|
|
139
|
+
expect(actual.length).toEqual(0);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
it("should return array with all matches", () => {
|
|
143
|
+
// setup
|
|
144
|
+
const url = "http://ns.electronichealth.net.au/id/hi/ihi/1.0";
|
|
145
|
+
// execute
|
|
146
|
+
const actual = ResourceUtilities.getExtensionsByUrl(extensionList, url);
|
|
147
|
+
// validate
|
|
148
|
+
expect(actual.length).toEqual(1);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
describe("#getCodingsByProperty()", () => {
|
|
153
|
+
const codingList = [
|
|
154
|
+
{
|
|
155
|
+
version: "1.0",
|
|
156
|
+
system: "http://hl7.org/fhir/sid/us-ssn",
|
|
157
|
+
code: "abc",
|
|
158
|
+
display: "abc",
|
|
159
|
+
userSelected: false,
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
version: "1.1",
|
|
163
|
+
system: "http://ns.electronichealth.net.au/id/hi/ihi/1.0",
|
|
164
|
+
code: "abc",
|
|
165
|
+
display: "abc",
|
|
166
|
+
},
|
|
167
|
+
];
|
|
168
|
+
|
|
169
|
+
it("should return empty array if null is passed as coding list", () => {
|
|
170
|
+
// setup
|
|
171
|
+
const value = "abc";
|
|
172
|
+
// execute
|
|
173
|
+
const actual = ResourceUtilities.getCodingsByProperty(null, "abc", value);
|
|
174
|
+
// validate
|
|
175
|
+
expect(actual.length).toEqual(0);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it("should return empty array if property not found", () => {
|
|
179
|
+
// setup
|
|
180
|
+
const value = "abc";
|
|
181
|
+
// execute
|
|
182
|
+
const actual = ResourceUtilities.getCodingsByProperty(
|
|
183
|
+
codingList,
|
|
184
|
+
"abc",
|
|
185
|
+
value
|
|
186
|
+
);
|
|
187
|
+
// validate
|
|
188
|
+
expect(actual.length).toEqual(0);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it("should return empty array if no matches found", () => {
|
|
192
|
+
// setup
|
|
193
|
+
const systemUrl = "http://somesystem.com";
|
|
194
|
+
// execute
|
|
195
|
+
const actual = ResourceUtilities.getCodingsByProperty(
|
|
196
|
+
codingList,
|
|
197
|
+
"system",
|
|
198
|
+
systemUrl
|
|
199
|
+
);
|
|
200
|
+
// validate
|
|
201
|
+
expect(actual.length).toEqual(0);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it("should return array with all matches for string values", () => {
|
|
205
|
+
// setup
|
|
206
|
+
const value = "abc";
|
|
207
|
+
// execute
|
|
208
|
+
const actual = ResourceUtilities.getCodingsByProperty(
|
|
209
|
+
codingList,
|
|
210
|
+
"code",
|
|
211
|
+
value
|
|
212
|
+
);
|
|
213
|
+
// validate
|
|
214
|
+
expect(actual.length).toEqual(2);
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
it("should return array with all matches for boolean values", () => {
|
|
218
|
+
// setup
|
|
219
|
+
const value = false;
|
|
220
|
+
// execute
|
|
221
|
+
const actual = ResourceUtilities.getCodingsByProperty(
|
|
222
|
+
codingList,
|
|
223
|
+
"userSelected",
|
|
224
|
+
value
|
|
225
|
+
);
|
|
226
|
+
// validate
|
|
227
|
+
expect(actual.length).toEqual(1);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
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();
|