@smile-cdr/fhirts 2.1.1 → 2.1.2
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/CHANGELOG.md +4 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/library/QueryBuilder/QueryBuilder.d.ts +59 -0
- package/dist/library/QueryBuilder/QueryBuilder.js +112 -0
- package/dist/library/QueryBuilder/QueryBuilder.spec.d.ts +1 -0
- package/dist/library/QueryBuilder/QueryBuilder.spec.js +135 -0
- package/dist/library/constants.d.ts +4 -0
- package/dist/library/constants.js +8 -0
- package/package.json +4 -6
- package/src/index.ts +2 -1
- package/src/library/QueryBuilder/QueryBuilder.spec.ts +149 -0
- package/src/library/QueryBuilder/QueryBuilder.ts +119 -0
- package/src/library/constants.ts +4 -0
package/CHANGELOG.md
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -4,4 +4,5 @@ import * as fhirR3 from './FHIR-R3';
|
|
|
4
4
|
import * as dstu2 from './FHIR-DSTU2';
|
|
5
5
|
import { ResourceUtils } from './library/ResourceUtils/ResourceUtils';
|
|
6
6
|
import { BundleUtils } from './library/BundleUtils/BundleUtils';
|
|
7
|
-
|
|
7
|
+
import { QueryBuilder } from './library/QueryBuilder/QueryBuilder';
|
|
8
|
+
export { fhirR4, fhirR3, IfhirR4, dstu2, ResourceUtils, BundleUtils, QueryBuilder };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BundleUtils = exports.ResourceUtils = exports.dstu2 = exports.IfhirR4 = exports.fhirR3 = exports.fhirR4 = void 0;
|
|
3
|
+
exports.QueryBuilder = 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");
|
|
@@ -13,3 +13,5 @@ const ResourceUtils_1 = require("./library/ResourceUtils/ResourceUtils");
|
|
|
13
13
|
Object.defineProperty(exports, "ResourceUtils", { enumerable: true, get: function () { return ResourceUtils_1.ResourceUtils; } });
|
|
14
14
|
const BundleUtils_1 = require("./library/BundleUtils/BundleUtils");
|
|
15
15
|
Object.defineProperty(exports, "BundleUtils", { enumerable: true, get: function () { return BundleUtils_1.BundleUtils; } });
|
|
16
|
+
const QueryBuilder_1 = require("./library/QueryBuilder/QueryBuilder");
|
|
17
|
+
Object.defineProperty(exports, "QueryBuilder", { enumerable: true, get: function () { return QueryBuilder_1.QueryBuilder; } });
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { SORT_ORDER } from "../constants";
|
|
2
|
+
export declare class QueryBuilder {
|
|
3
|
+
readonly REV_INCLUDE_KEYWORD = "_revinclude";
|
|
4
|
+
readonly INCLUDE_KEYWORD = "_include";
|
|
5
|
+
readonly SORT_KEYWORD = "_sort";
|
|
6
|
+
readonly WILDCARD_ASTERIK = "*";
|
|
7
|
+
readonly EQUALS = "=";
|
|
8
|
+
readonly COLON = ":";
|
|
9
|
+
readonly QUERY_DELIMETER = "&";
|
|
10
|
+
readonly COMMA = ",";
|
|
11
|
+
private baseResource;
|
|
12
|
+
private singularQueries;
|
|
13
|
+
private sortQueries;
|
|
14
|
+
/**
|
|
15
|
+
* @returns base resource for the query
|
|
16
|
+
*/
|
|
17
|
+
getBaseResource(): String;
|
|
18
|
+
/**
|
|
19
|
+
* @param resourceType Base ResourceType for the query
|
|
20
|
+
* sets base resource type for the query
|
|
21
|
+
* i.e. which resource the query will performed for
|
|
22
|
+
*/
|
|
23
|
+
setBaseResource(resourceType: String): this;
|
|
24
|
+
/**
|
|
25
|
+
* @param searchParameter SearchParameter reference to targeted resource
|
|
26
|
+
*/
|
|
27
|
+
include(searchParameter: String): this;
|
|
28
|
+
/**
|
|
29
|
+
* @param resourceType Source ResourceType
|
|
30
|
+
* @param searchParameter SearchParameter reference from target resource to baseResource
|
|
31
|
+
*/
|
|
32
|
+
revinclude(resourceType: String, searchParameter: String): this;
|
|
33
|
+
/**
|
|
34
|
+
* _include all references in query
|
|
35
|
+
*/
|
|
36
|
+
includeAll(): this;
|
|
37
|
+
/**
|
|
38
|
+
* _revinclude all references in query
|
|
39
|
+
*/
|
|
40
|
+
revincludeAll(): this;
|
|
41
|
+
/**
|
|
42
|
+
* @param searchParameter search parameter for the element to sort on
|
|
43
|
+
* @param sortOrder ASCENDING or DESCENDING
|
|
44
|
+
*/
|
|
45
|
+
sort(searchParameter: String, sortOrder: SORT_ORDER): this;
|
|
46
|
+
/**
|
|
47
|
+
* Resets queries to it empty state
|
|
48
|
+
*/
|
|
49
|
+
resetQuery(): this;
|
|
50
|
+
/**
|
|
51
|
+
* @returns complete generated query with encoded parameter values
|
|
52
|
+
*/
|
|
53
|
+
getCompleteUrl(): String;
|
|
54
|
+
/**
|
|
55
|
+
* @returns complete generated query with decoded parameter values
|
|
56
|
+
*/
|
|
57
|
+
getCompleteUrlDecoded(): String;
|
|
58
|
+
private createSortQuery;
|
|
59
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QueryBuilder = void 0;
|
|
4
|
+
const constants_1 = require("../constants");
|
|
5
|
+
class QueryBuilder {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.REV_INCLUDE_KEYWORD = "_revinclude";
|
|
8
|
+
this.INCLUDE_KEYWORD = "_include";
|
|
9
|
+
this.SORT_KEYWORD = "_sort";
|
|
10
|
+
this.WILDCARD_ASTERIK = "*";
|
|
11
|
+
this.EQUALS = "=";
|
|
12
|
+
this.COLON = ":";
|
|
13
|
+
this.QUERY_DELIMETER = "&";
|
|
14
|
+
this.COMMA = ",";
|
|
15
|
+
this.baseResource = "";
|
|
16
|
+
this.singularQueries = [];
|
|
17
|
+
this.sortQueries = [];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* @returns base resource for the query
|
|
21
|
+
*/
|
|
22
|
+
getBaseResource() {
|
|
23
|
+
return this.baseResource;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* @param resourceType Base ResourceType for the query
|
|
27
|
+
* sets base resource type for the query
|
|
28
|
+
* i.e. which resource the query will performed for
|
|
29
|
+
*/
|
|
30
|
+
setBaseResource(resourceType) {
|
|
31
|
+
this.baseResource = resourceType;
|
|
32
|
+
return this;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* @param searchParameter SearchParameter reference to targeted resource
|
|
36
|
+
*/
|
|
37
|
+
include(searchParameter) {
|
|
38
|
+
this.singularQueries.push(this.INCLUDE_KEYWORD + this.EQUALS + encodeURIComponent(this.baseResource + this.COLON + searchParameter));
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* @param resourceType Source ResourceType
|
|
43
|
+
* @param searchParameter SearchParameter reference from target resource to baseResource
|
|
44
|
+
*/
|
|
45
|
+
revinclude(resourceType, searchParameter) {
|
|
46
|
+
this.singularQueries.push(this.REV_INCLUDE_KEYWORD + this.EQUALS + encodeURIComponent(resourceType + this.COLON + searchParameter));
|
|
47
|
+
return this;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* _include all references in query
|
|
51
|
+
*/
|
|
52
|
+
includeAll() {
|
|
53
|
+
this.singularQueries.push(this.INCLUDE_KEYWORD + this.EQUALS + this.WILDCARD_ASTERIK);
|
|
54
|
+
return this;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* _revinclude all references in query
|
|
58
|
+
*/
|
|
59
|
+
revincludeAll() {
|
|
60
|
+
this.singularQueries.push(this.REV_INCLUDE_KEYWORD + this.EQUALS + this.WILDCARD_ASTERIK);
|
|
61
|
+
return this;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* @param searchParameter search parameter for the element to sort on
|
|
65
|
+
* @param sortOrder ASCENDING or DESCENDING
|
|
66
|
+
*/
|
|
67
|
+
sort(searchParameter, sortOrder) {
|
|
68
|
+
if (sortOrder === constants_1.SORT_ORDER.ASCENDING) {
|
|
69
|
+
this.sortQueries.push(searchParameter);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
this.sortQueries.push("-" + searchParameter);
|
|
73
|
+
}
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Resets queries to it empty state
|
|
78
|
+
*/
|
|
79
|
+
resetQuery() {
|
|
80
|
+
this.sortQueries = [];
|
|
81
|
+
this.singularQueries = [];
|
|
82
|
+
this.baseResource = "";
|
|
83
|
+
return this;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* @returns complete generated query with encoded parameter values
|
|
87
|
+
*/
|
|
88
|
+
getCompleteUrl() {
|
|
89
|
+
let completeUrl = this.baseResource + "?";
|
|
90
|
+
const singularQueriesLength = this.singularQueries.length;
|
|
91
|
+
if (singularQueriesLength > 0) {
|
|
92
|
+
completeUrl += this.singularQueries.join(this.QUERY_DELIMETER);
|
|
93
|
+
}
|
|
94
|
+
completeUrl += this.createSortQuery(singularQueriesLength);
|
|
95
|
+
return completeUrl;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* @returns complete generated query with decoded parameter values
|
|
99
|
+
*/
|
|
100
|
+
getCompleteUrlDecoded() {
|
|
101
|
+
return decodeURIComponent(this.getCompleteUrl().toString());
|
|
102
|
+
}
|
|
103
|
+
createSortQuery(singularQueriesLength) {
|
|
104
|
+
let sortQuery = "";
|
|
105
|
+
const sortDelimeter = singularQueriesLength > 0 ? this.QUERY_DELIMETER : "";
|
|
106
|
+
if (this.sortQueries.length > 0) {
|
|
107
|
+
sortQuery += sortDelimeter + this.SORT_KEYWORD + this.EQUALS + encodeURIComponent(this.sortQueries.join(this.COMMA));
|
|
108
|
+
}
|
|
109
|
+
return sortQuery;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
exports.QueryBuilder = QueryBuilder;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const constants_1 = require("../constants");
|
|
4
|
+
const QueryBuilder_1 = require("./QueryBuilder");
|
|
5
|
+
describe("QueryBuilder", () => {
|
|
6
|
+
let queryBuilder;
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
queryBuilder = new QueryBuilder_1.QueryBuilder();
|
|
9
|
+
});
|
|
10
|
+
it('setBaseResource() should set base resource and getBaseResource() should return correct base resource', () => {
|
|
11
|
+
// setup
|
|
12
|
+
const expected = "Patient";
|
|
13
|
+
// execute
|
|
14
|
+
queryBuilder.setBaseResource(expected);
|
|
15
|
+
// validate
|
|
16
|
+
expect(queryBuilder.getBaseResource()).toEqual(expected);
|
|
17
|
+
});
|
|
18
|
+
it('include() should make query for _include', () => {
|
|
19
|
+
// setup
|
|
20
|
+
const expected = "Patient?_include=Patient%3Aorganization";
|
|
21
|
+
// execute
|
|
22
|
+
queryBuilder.setBaseResource("Patient").include("organization");
|
|
23
|
+
// validate
|
|
24
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
25
|
+
});
|
|
26
|
+
it('include() should make query for multiple _include', () => {
|
|
27
|
+
// setup
|
|
28
|
+
const expected = "Patient?_include=Patient%3Aorganization&_include=Patient%3Alink";
|
|
29
|
+
// execute
|
|
30
|
+
queryBuilder.setBaseResource("Patient")
|
|
31
|
+
.include("organization")
|
|
32
|
+
.include("link");
|
|
33
|
+
// validate
|
|
34
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
35
|
+
});
|
|
36
|
+
it('revinclude() should make query for _revinclude', () => {
|
|
37
|
+
// setup
|
|
38
|
+
const expected = "MedicationRequest?_revinclude=CarePlan%3Aactivity-reference";
|
|
39
|
+
// execute
|
|
40
|
+
queryBuilder.setBaseResource("MedicationRequest")
|
|
41
|
+
.revinclude("CarePlan", "activity-reference");
|
|
42
|
+
// validate
|
|
43
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
44
|
+
});
|
|
45
|
+
it('revinclude() should make query for multiple _revinclude', () => {
|
|
46
|
+
// setup
|
|
47
|
+
const expected = "MedicationRequest?_revinclude=CarePlan%3Aactivity-reference&_revinclude=Observation%3Abased-on";
|
|
48
|
+
// execute
|
|
49
|
+
queryBuilder.setBaseResource("MedicationRequest")
|
|
50
|
+
.revinclude("CarePlan", "activity-reference")
|
|
51
|
+
.revinclude("Observation", "based-on");
|
|
52
|
+
// validate
|
|
53
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
54
|
+
});
|
|
55
|
+
it('include() and revinclude() should make query for _include & _revinclude', () => {
|
|
56
|
+
// setup
|
|
57
|
+
const expected = "MedicationRequest?_revinclude=CarePlan%3Aactivity-reference&_include=MedicationRequest%3Aencounter";
|
|
58
|
+
// execute
|
|
59
|
+
queryBuilder.setBaseResource("MedicationRequest")
|
|
60
|
+
.revinclude("CarePlan", "activity-reference")
|
|
61
|
+
.include("encounter");
|
|
62
|
+
// validate
|
|
63
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
64
|
+
});
|
|
65
|
+
it('includeAll() should make query for _include all', () => {
|
|
66
|
+
// setup
|
|
67
|
+
const expected = "MedicationRequest?_include=*";
|
|
68
|
+
// execute
|
|
69
|
+
queryBuilder.setBaseResource("MedicationRequest").includeAll();
|
|
70
|
+
// validate
|
|
71
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
72
|
+
});
|
|
73
|
+
it('revincludeAll() should make query for _revinclude all', () => {
|
|
74
|
+
// setup
|
|
75
|
+
const expected = "MedicationRequest?_revinclude=*";
|
|
76
|
+
// execute
|
|
77
|
+
queryBuilder.setBaseResource("MedicationRequest").revincludeAll();
|
|
78
|
+
// validate
|
|
79
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
80
|
+
});
|
|
81
|
+
it('includeAll() & revincludeAll() should make query for _include all & _revinclude all', () => {
|
|
82
|
+
// setup
|
|
83
|
+
const expected = "MedicationRequest?_revinclude=*&_include=*";
|
|
84
|
+
// execute
|
|
85
|
+
queryBuilder.setBaseResource("MedicationRequest")
|
|
86
|
+
.revincludeAll()
|
|
87
|
+
.includeAll();
|
|
88
|
+
// validate
|
|
89
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
90
|
+
});
|
|
91
|
+
it('sort() should make query for _sort', () => {
|
|
92
|
+
// setup
|
|
93
|
+
const expected = "Observation?_sort=status%2C-date";
|
|
94
|
+
// execute
|
|
95
|
+
queryBuilder.setBaseResource("Observation")
|
|
96
|
+
.sort("status", constants_1.SORT_ORDER.ASCENDING)
|
|
97
|
+
.sort("date", constants_1.SORT_ORDER.DESCENDING);
|
|
98
|
+
// validate
|
|
99
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
100
|
+
});
|
|
101
|
+
it('sort(), include() and revincludeAll() should make query for _sort, _include & _revinclude', () => {
|
|
102
|
+
// setup
|
|
103
|
+
const expected = "Observation?_revinclude=*&_include=Observation%3Abased-on&_sort=status";
|
|
104
|
+
// execute
|
|
105
|
+
queryBuilder.setBaseResource("Observation")
|
|
106
|
+
.revincludeAll()
|
|
107
|
+
.include("based-on")
|
|
108
|
+
.sort("status", constants_1.SORT_ORDER.ASCENDING);
|
|
109
|
+
// validate
|
|
110
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
111
|
+
});
|
|
112
|
+
it('resetQuery() should reset query', () => {
|
|
113
|
+
// setup
|
|
114
|
+
const expected = "";
|
|
115
|
+
queryBuilder.setBaseResource("Observation")
|
|
116
|
+
.revincludeAll()
|
|
117
|
+
.include("based-on")
|
|
118
|
+
.sort("status", constants_1.SORT_ORDER.ASCENDING);
|
|
119
|
+
// execute
|
|
120
|
+
queryBuilder.resetQuery();
|
|
121
|
+
// validate
|
|
122
|
+
expect(queryBuilder.getBaseResource()).toEqual(expected);
|
|
123
|
+
});
|
|
124
|
+
it('getCompleteUrlDecoded() should get uri decoded query', () => {
|
|
125
|
+
// setup
|
|
126
|
+
const expected = "Observation?_revinclude=*&_include=Observation:based-on&_sort=status";
|
|
127
|
+
// execute
|
|
128
|
+
queryBuilder.setBaseResource("Observation")
|
|
129
|
+
.revincludeAll()
|
|
130
|
+
.include("based-on")
|
|
131
|
+
.sort("status", constants_1.SORT_ORDER.ASCENDING);
|
|
132
|
+
// validate
|
|
133
|
+
expect(queryBuilder.getCompleteUrlDecoded()).toEqual(expected);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SORT_ORDER = void 0;
|
|
4
|
+
var SORT_ORDER;
|
|
5
|
+
(function (SORT_ORDER) {
|
|
6
|
+
SORT_ORDER[SORT_ORDER["ASCENDING"] = 0] = "ASCENDING";
|
|
7
|
+
SORT_ORDER[SORT_ORDER["DESCENDING"] = 1] = "DESCENDING";
|
|
8
|
+
})(SORT_ORDER = exports.SORT_ORDER || (exports.SORT_ORDER = {}));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@smile-cdr/fhirts",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "Fhir ts/js library for frontend apps",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -14,13 +14,11 @@
|
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@types/jasmine": "^4.3.1",
|
|
17
|
+
"@types/node": "^20.12.12",
|
|
18
|
+
"better-npm-audit": "^3.7.3",
|
|
17
19
|
"jasmine": "^4.5.0",
|
|
20
|
+
"nyc": "^15.1.0",
|
|
18
21
|
"ts-node": "^10.9.1",
|
|
19
22
|
"typescript": "^4.0.2"
|
|
20
|
-
},
|
|
21
|
-
"dependencies": {
|
|
22
|
-
"@types/node": "^18.11.15",
|
|
23
|
-
"better-npm-audit": "^3.7.3",
|
|
24
|
-
"nyc": "^15.1.0"
|
|
25
23
|
}
|
|
26
24
|
}
|
package/src/index.ts
CHANGED
|
@@ -4,5 +4,6 @@ import * as fhirR3 from './FHIR-R3';
|
|
|
4
4
|
import * as dstu2 from './FHIR-DSTU2';
|
|
5
5
|
import { ResourceUtils } from './library/ResourceUtils/ResourceUtils';
|
|
6
6
|
import { BundleUtils } from './library/BundleUtils/BundleUtils';
|
|
7
|
-
|
|
7
|
+
import { QueryBuilder } from './library/QueryBuilder/QueryBuilder';
|
|
8
|
+
export { fhirR4, fhirR3, IfhirR4, dstu2, ResourceUtils, BundleUtils, QueryBuilder };
|
|
8
9
|
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { SORT_ORDER } from "../constants";
|
|
2
|
+
import { QueryBuilder } from "./QueryBuilder";
|
|
3
|
+
|
|
4
|
+
describe("QueryBuilder", () => {
|
|
5
|
+
|
|
6
|
+
let queryBuilder: QueryBuilder;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
queryBuilder = new QueryBuilder();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('setBaseResource() should set base resource and getBaseResource() should return correct base resource', () => {
|
|
13
|
+
// setup
|
|
14
|
+
const expected: String = "Patient";
|
|
15
|
+
// execute
|
|
16
|
+
queryBuilder.setBaseResource(expected);
|
|
17
|
+
// validate
|
|
18
|
+
expect(queryBuilder.getBaseResource()).toEqual(expected);
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('include() should make query for _include', () => {
|
|
22
|
+
// setup
|
|
23
|
+
const expected: String = "Patient?_include=Patient%3Aorganization"
|
|
24
|
+
// execute
|
|
25
|
+
queryBuilder.setBaseResource("Patient").include("organization");
|
|
26
|
+
// validate
|
|
27
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('include() should make query for multiple _include', () => {
|
|
31
|
+
// setup
|
|
32
|
+
const expected: String = "Patient?_include=Patient%3Aorganization&_include=Patient%3Alink"
|
|
33
|
+
// execute
|
|
34
|
+
queryBuilder.setBaseResource("Patient")
|
|
35
|
+
.include("organization")
|
|
36
|
+
.include("link");
|
|
37
|
+
// validate
|
|
38
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it('revinclude() should make query for _revinclude', () => {
|
|
42
|
+
// setup
|
|
43
|
+
const expected: String = "MedicationRequest?_revinclude=CarePlan%3Aactivity-reference"
|
|
44
|
+
// execute
|
|
45
|
+
queryBuilder.setBaseResource("MedicationRequest")
|
|
46
|
+
.revinclude("CarePlan", "activity-reference");
|
|
47
|
+
// validate
|
|
48
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('revinclude() should make query for multiple _revinclude', () => {
|
|
52
|
+
// setup
|
|
53
|
+
const expected: String = "MedicationRequest?_revinclude=CarePlan%3Aactivity-reference&_revinclude=Observation%3Abased-on"
|
|
54
|
+
// execute
|
|
55
|
+
queryBuilder.setBaseResource("MedicationRequest")
|
|
56
|
+
.revinclude("CarePlan", "activity-reference")
|
|
57
|
+
.revinclude("Observation", "based-on");
|
|
58
|
+
// validate
|
|
59
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('include() and revinclude() should make query for _include & _revinclude', () => {
|
|
63
|
+
// setup
|
|
64
|
+
const expected: String = "MedicationRequest?_revinclude=CarePlan%3Aactivity-reference&_include=MedicationRequest%3Aencounter"
|
|
65
|
+
// execute
|
|
66
|
+
queryBuilder.setBaseResource("MedicationRequest")
|
|
67
|
+
.revinclude("CarePlan", "activity-reference")
|
|
68
|
+
.include("encounter");
|
|
69
|
+
// validate
|
|
70
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('includeAll() should make query for _include all', () => {
|
|
74
|
+
// setup
|
|
75
|
+
const expected: String = "MedicationRequest?_include=*"
|
|
76
|
+
// execute
|
|
77
|
+
queryBuilder.setBaseResource("MedicationRequest").includeAll();
|
|
78
|
+
// validate
|
|
79
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('revincludeAll() should make query for _revinclude all', () => {
|
|
83
|
+
// setup
|
|
84
|
+
const expected: String = "MedicationRequest?_revinclude=*"
|
|
85
|
+
// execute
|
|
86
|
+
queryBuilder.setBaseResource("MedicationRequest").revincludeAll();
|
|
87
|
+
// validate
|
|
88
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('includeAll() & revincludeAll() should make query for _include all & _revinclude all', () => {
|
|
92
|
+
// setup
|
|
93
|
+
const expected: String = "MedicationRequest?_revinclude=*&_include=*"
|
|
94
|
+
// execute
|
|
95
|
+
queryBuilder.setBaseResource("MedicationRequest")
|
|
96
|
+
.revincludeAll()
|
|
97
|
+
.includeAll();
|
|
98
|
+
// validate
|
|
99
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('sort() should make query for _sort', () => {
|
|
103
|
+
// setup
|
|
104
|
+
const expected: String = "Observation?_sort=status%2C-date"
|
|
105
|
+
// execute
|
|
106
|
+
queryBuilder.setBaseResource("Observation")
|
|
107
|
+
.sort("status", SORT_ORDER.ASCENDING)
|
|
108
|
+
.sort("date", SORT_ORDER.DESCENDING);
|
|
109
|
+
// validate
|
|
110
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('sort(), include() and revincludeAll() should make query for _sort, _include & _revinclude', () => {
|
|
114
|
+
// setup
|
|
115
|
+
const expected: String = "Observation?_revinclude=*&_include=Observation%3Abased-on&_sort=status"
|
|
116
|
+
// execute
|
|
117
|
+
queryBuilder.setBaseResource("Observation")
|
|
118
|
+
.revincludeAll()
|
|
119
|
+
.include("based-on")
|
|
120
|
+
.sort("status", SORT_ORDER.ASCENDING);
|
|
121
|
+
// validate
|
|
122
|
+
expect(queryBuilder.getCompleteUrl()).toEqual(expected);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('resetQuery() should reset query', () => {
|
|
126
|
+
// setup
|
|
127
|
+
const expected: String = ""
|
|
128
|
+
queryBuilder.setBaseResource("Observation")
|
|
129
|
+
.revincludeAll()
|
|
130
|
+
.include("based-on")
|
|
131
|
+
.sort("status", SORT_ORDER.ASCENDING);
|
|
132
|
+
// execute
|
|
133
|
+
queryBuilder.resetQuery();
|
|
134
|
+
// validate
|
|
135
|
+
expect(queryBuilder.getBaseResource()).toEqual(expected);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('getCompleteUrlDecoded() should get uri decoded query', () => {
|
|
139
|
+
// setup
|
|
140
|
+
const expected: String = "Observation?_revinclude=*&_include=Observation:based-on&_sort=status"
|
|
141
|
+
// execute
|
|
142
|
+
queryBuilder.setBaseResource("Observation")
|
|
143
|
+
.revincludeAll()
|
|
144
|
+
.include("based-on")
|
|
145
|
+
.sort("status", SORT_ORDER.ASCENDING);
|
|
146
|
+
// validate
|
|
147
|
+
expect(queryBuilder.getCompleteUrlDecoded()).toEqual(expected);
|
|
148
|
+
});
|
|
149
|
+
});
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { SORT_ORDER } from "../constants";
|
|
2
|
+
|
|
3
|
+
export class QueryBuilder {
|
|
4
|
+
|
|
5
|
+
readonly REV_INCLUDE_KEYWORD = "_revinclude";
|
|
6
|
+
readonly INCLUDE_KEYWORD = "_include";
|
|
7
|
+
readonly SORT_KEYWORD = "_sort";
|
|
8
|
+
readonly WILDCARD_ASTERIK = "*";
|
|
9
|
+
readonly EQUALS = "=";
|
|
10
|
+
readonly COLON = ":";
|
|
11
|
+
readonly QUERY_DELIMETER = "&";
|
|
12
|
+
readonly COMMA = ",";
|
|
13
|
+
private baseResource: String = "";
|
|
14
|
+
private singularQueries: String[] = [];
|
|
15
|
+
private sortQueries: String[] = [];
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @returns base resource for the query
|
|
19
|
+
*/
|
|
20
|
+
getBaseResource(): String {
|
|
21
|
+
return this.baseResource;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @param resourceType Base ResourceType for the query
|
|
26
|
+
* sets base resource type for the query
|
|
27
|
+
* i.e. which resource the query will performed for
|
|
28
|
+
*/
|
|
29
|
+
setBaseResource(resourceType: String) {
|
|
30
|
+
this.baseResource = resourceType;
|
|
31
|
+
return this;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @param searchParameter SearchParameter reference to targeted resource
|
|
36
|
+
*/
|
|
37
|
+
include(searchParameter: String) {
|
|
38
|
+
this.singularQueries.push(this.INCLUDE_KEYWORD + this.EQUALS + encodeURIComponent(this.baseResource + this.COLON + searchParameter));
|
|
39
|
+
return this;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param resourceType Source ResourceType
|
|
44
|
+
* @param searchParameter SearchParameter reference from target resource to baseResource
|
|
45
|
+
*/
|
|
46
|
+
revinclude(resourceType: String, searchParameter: String) {
|
|
47
|
+
this.singularQueries.push(this.REV_INCLUDE_KEYWORD + this.EQUALS + encodeURIComponent(resourceType + this.COLON + searchParameter));
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* _include all references in query
|
|
53
|
+
*/
|
|
54
|
+
includeAll() {
|
|
55
|
+
this.singularQueries.push(this.INCLUDE_KEYWORD + this.EQUALS + this.WILDCARD_ASTERIK);
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* _revinclude all references in query
|
|
61
|
+
*/
|
|
62
|
+
revincludeAll() {
|
|
63
|
+
this.singularQueries.push(this.REV_INCLUDE_KEYWORD + this.EQUALS + this.WILDCARD_ASTERIK);
|
|
64
|
+
return this;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @param searchParameter search parameter for the element to sort on
|
|
69
|
+
* @param sortOrder ASCENDING or DESCENDING
|
|
70
|
+
*/
|
|
71
|
+
sort(searchParameter: String, sortOrder: SORT_ORDER) {
|
|
72
|
+
if(sortOrder === SORT_ORDER.ASCENDING) {
|
|
73
|
+
this.sortQueries.push(searchParameter);
|
|
74
|
+
} else {
|
|
75
|
+
this.sortQueries.push("-" + searchParameter);
|
|
76
|
+
}
|
|
77
|
+
return this;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Resets queries to it empty state
|
|
82
|
+
*/
|
|
83
|
+
resetQuery() {
|
|
84
|
+
this.sortQueries = [];
|
|
85
|
+
this.singularQueries = [];
|
|
86
|
+
this.baseResource = "";
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @returns complete generated query with encoded parameter values
|
|
92
|
+
*/
|
|
93
|
+
getCompleteUrl(): String {
|
|
94
|
+
let completeUrl = this.baseResource + "?";
|
|
95
|
+
const singularQueriesLength = this.singularQueries.length;
|
|
96
|
+
if(singularQueriesLength > 0) {
|
|
97
|
+
completeUrl += this.singularQueries.join(this.QUERY_DELIMETER);
|
|
98
|
+
}
|
|
99
|
+
completeUrl += this.createSortQuery(singularQueriesLength);
|
|
100
|
+
return completeUrl;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* @returns complete generated query with decoded parameter values
|
|
105
|
+
*/
|
|
106
|
+
getCompleteUrlDecoded(): String {
|
|
107
|
+
return decodeURIComponent(this.getCompleteUrl().toString());
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private createSortQuery(singularQueriesLength: number): String {
|
|
111
|
+
let sortQuery = "";
|
|
112
|
+
const sortDelimeter = singularQueriesLength > 0 ? this.QUERY_DELIMETER : "";
|
|
113
|
+
if(this.sortQueries.length > 0) {
|
|
114
|
+
sortQuery += sortDelimeter + this.SORT_KEYWORD + this.EQUALS + encodeURIComponent(this.sortQueries.join(this.COMMA));
|
|
115
|
+
}
|
|
116
|
+
return sortQuery;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
}
|