@haste-health/client 0.15.3
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/README.md +228 -0
- package/lib/http/index.d.ts +29 -0
- package/lib/http/index.js +566 -0
- package/lib/http/index.js.map +1 -0
- package/lib/index.d.ts +39 -0
- package/lib/index.js +341 -0
- package/lib/index.js.map +1 -0
- package/lib/interface.d.ts +38 -0
- package/lib/interface.js +2 -0
- package/lib/interface.js.map +1 -0
- package/lib/middleware/index.d.ts +15 -0
- package/lib/middleware/index.js +34 -0
- package/lib/middleware/index.js.map +1 -0
- package/lib/types/index.d.ts +225 -0
- package/lib/types/index.js +2 -0
- package/lib/types/index.js.map +1 -0
- package/lib/types/r4.d.ts +257 -0
- package/lib/types/r4.js +2 -0
- package/lib/types/r4.js.map +1 -0
- package/lib/types/r4b.d.ts +257 -0
- package/lib/types/r4b.js +2 -0
- package/lib/types/r4b.js.map +1 -0
- package/lib/types/utilities.d.ts +40 -0
- package/lib/types/utilities.js +10 -0
- package/lib/types/utilities.js.map +1 -0
- package/lib/url.d.ts +51 -0
- package/lib/url.js +83 -0
- package/lib/url.js.map +1 -0
- package/package.json +45 -0
- package/src/http/index.ts +673 -0
- package/src/index.ts +555 -0
- package/src/interface.ts +203 -0
- package/src/middleware/index.test.ts +120 -0
- package/src/middleware/index.ts +95 -0
- package/src/types/index.ts +373 -0
- package/src/types/utilities.ts +62 -0
- package/src/url.test.ts +52 -0
- package/src/url.ts +141 -0
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
import { code, id } from "@haste-health/fhir-types/r4/types";
|
|
2
|
+
import {
|
|
3
|
+
AllResourceTypes,
|
|
4
|
+
FHIR_VERSION,
|
|
5
|
+
Resource,
|
|
6
|
+
ResourceType,
|
|
7
|
+
} from "@haste-health/fhir-types/versions";
|
|
8
|
+
|
|
9
|
+
import type { Parameters } from "../url.js";
|
|
10
|
+
import {
|
|
11
|
+
Interaction,
|
|
12
|
+
Request,
|
|
13
|
+
RequestLevel,
|
|
14
|
+
RequestType,
|
|
15
|
+
ResponseType,
|
|
16
|
+
} from "./utilities.js";
|
|
17
|
+
|
|
18
|
+
export * from "./utilities.js";
|
|
19
|
+
|
|
20
|
+
export interface InstanceInteraction<Version extends FHIR_VERSION>
|
|
21
|
+
extends Request<Version, "instance"> {
|
|
22
|
+
resource: ResourceType<Version>;
|
|
23
|
+
id: id;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface TypeInteraction<Version extends FHIR_VERSION>
|
|
27
|
+
extends Request<Version, "type"> {
|
|
28
|
+
resource: ResourceType<Version>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface SystemInteraction<Version extends FHIR_VERSION>
|
|
32
|
+
extends Request<Version, "system"> {}
|
|
33
|
+
|
|
34
|
+
export interface ReadRequest<Version extends FHIR_VERSION>
|
|
35
|
+
extends InstanceInteraction<Version> {
|
|
36
|
+
type: RequestType["read"];
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface VersionReadRequest<Version extends FHIR_VERSION>
|
|
40
|
+
extends InstanceInteraction<Version> {
|
|
41
|
+
type: RequestType["vread"];
|
|
42
|
+
versionId: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface InstanceUpdateRequest<Version extends FHIR_VERSION>
|
|
46
|
+
extends InstanceInteraction<Version> {
|
|
47
|
+
type: RequestType["update"];
|
|
48
|
+
body: Resource<Version, ResourceType<Version>>;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// TODO - implement patch type
|
|
52
|
+
export interface PatchRequest<Version extends FHIR_VERSION>
|
|
53
|
+
extends InstanceInteraction<Version> {
|
|
54
|
+
type: RequestType["patch"];
|
|
55
|
+
body: unknown;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface InstanceDeleteRequest<Version extends FHIR_VERSION>
|
|
59
|
+
extends InstanceInteraction<Version> {
|
|
60
|
+
type: RequestType["delete"];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface TypeDeleteRequest<Version extends FHIR_VERSION>
|
|
64
|
+
extends TypeInteraction<Version> {
|
|
65
|
+
parameters: Parameters<Version>;
|
|
66
|
+
type: RequestType["delete"];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface SystemDeleteRequest<Version extends FHIR_VERSION>
|
|
70
|
+
extends SystemInteraction<Version> {
|
|
71
|
+
parameters: Parameters<Version>;
|
|
72
|
+
type: RequestType["delete"];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface HistoryInstanceRequest<Version extends FHIR_VERSION>
|
|
76
|
+
extends InstanceInteraction<Version> {
|
|
77
|
+
type: RequestType["history"];
|
|
78
|
+
parameters?: Parameters<Version>;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export interface CreateRequest<Version extends FHIR_VERSION>
|
|
82
|
+
extends TypeInteraction<Version> {
|
|
83
|
+
type: RequestType["create"];
|
|
84
|
+
body: Resource<Version, ResourceType<Version>>;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export interface ConditionalUpdateRequest<Version extends FHIR_VERSION>
|
|
88
|
+
extends TypeInteraction<Version> {
|
|
89
|
+
type: RequestType["update"];
|
|
90
|
+
parameters: Parameters<Version>;
|
|
91
|
+
body: Resource<Version, ResourceType<Version>>;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export interface TypeSearchRequest<Version extends FHIR_VERSION>
|
|
95
|
+
extends TypeInteraction<Version> {
|
|
96
|
+
parameters: Parameters<Version>;
|
|
97
|
+
type: RequestType["search"];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export interface TypeHistoryRequest<Version extends FHIR_VERSION>
|
|
101
|
+
extends TypeInteraction<Version> {
|
|
102
|
+
type: RequestType["history"];
|
|
103
|
+
parameters?: Parameters<Version>;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface CapabilitiesRequest<Version extends FHIR_VERSION>
|
|
107
|
+
extends SystemInteraction<Version> {
|
|
108
|
+
type: RequestType["capabilities"];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export interface BatchRequest<Version extends FHIR_VERSION>
|
|
112
|
+
extends SystemInteraction<Version> {
|
|
113
|
+
type: RequestType["batch"];
|
|
114
|
+
body: Resource<Version, "Bundle">;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export interface TransactionRequest<Version extends FHIR_VERSION>
|
|
118
|
+
extends SystemInteraction<Version> {
|
|
119
|
+
type: RequestType["transaction"];
|
|
120
|
+
body: Resource<Version, "Bundle">;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export interface SystemHistoryRequest<Version extends FHIR_VERSION>
|
|
124
|
+
extends SystemInteraction<Version> {
|
|
125
|
+
type: RequestType["history"];
|
|
126
|
+
parameters?: Parameters<Version>;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export interface SystemSearchRequest<Version extends FHIR_VERSION>
|
|
130
|
+
extends SystemInteraction<Version> {
|
|
131
|
+
parameters: Parameters<Version>;
|
|
132
|
+
type: RequestType["search"];
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface InvokeInstanceRequest<Version extends FHIR_VERSION>
|
|
136
|
+
extends InstanceInteraction<Version> {
|
|
137
|
+
type: RequestType["invoke"];
|
|
138
|
+
operation: code;
|
|
139
|
+
body: Resource<Version, "Parameters">;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface InvokeTypeRequest<Version extends FHIR_VERSION>
|
|
143
|
+
extends TypeInteraction<Version> {
|
|
144
|
+
type: RequestType["invoke"];
|
|
145
|
+
operation: code;
|
|
146
|
+
body: Resource<Version, "Parameters">;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export interface InvokeSystemRequest<Version extends FHIR_VERSION>
|
|
150
|
+
extends SystemInteraction<Version> {
|
|
151
|
+
type: RequestType["invoke"];
|
|
152
|
+
operation: code;
|
|
153
|
+
body: Resource<Version, "Parameters">;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface ReadResponse<Version extends FHIR_VERSION>
|
|
157
|
+
extends InstanceInteraction<Version> {
|
|
158
|
+
type: ResponseType["read"];
|
|
159
|
+
body: Resource<Version, ResourceType<Version>>;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export interface VersionReadResponse<Version extends FHIR_VERSION>
|
|
163
|
+
extends InstanceInteraction<Version> {
|
|
164
|
+
type: ResponseType["vread"];
|
|
165
|
+
versionId: string;
|
|
166
|
+
body: Resource<Version, ResourceType<Version>>;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export interface UpdateResponse<Version extends FHIR_VERSION>
|
|
170
|
+
extends InstanceInteraction<Version> {
|
|
171
|
+
type: ResponseType["update"];
|
|
172
|
+
created?: boolean;
|
|
173
|
+
body: Resource<Version, ResourceType<Version>>;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// TODO - implement patch type
|
|
177
|
+
export interface PatchResponse<Version extends FHIR_VERSION>
|
|
178
|
+
extends InstanceInteraction<Version> {
|
|
179
|
+
type: ResponseType["patch"];
|
|
180
|
+
body: Resource<Version, ResourceType<Version>>;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export interface InstanceDeleteResponse<Version extends FHIR_VERSION>
|
|
184
|
+
extends InstanceInteraction<Version> {
|
|
185
|
+
type: ResponseType["delete"];
|
|
186
|
+
deletion?: Resource<Version, AllResourceTypes>;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export interface TypeDeleteResponse<Version extends FHIR_VERSION>
|
|
190
|
+
extends TypeInteraction<Version> {
|
|
191
|
+
parameters: Parameters<Version>;
|
|
192
|
+
type: ResponseType["delete"];
|
|
193
|
+
// For conditional deletes include the resources that were deleted.
|
|
194
|
+
deletion?: Resource<Version, AllResourceTypes>[];
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export interface SystemDeleteResponse<Version extends FHIR_VERSION>
|
|
198
|
+
extends SystemInteraction<Version> {
|
|
199
|
+
parameters: Parameters<Version>;
|
|
200
|
+
type: ResponseType["delete"];
|
|
201
|
+
// For conditional deletes include the resources that were deleted.
|
|
202
|
+
deletion?: Resource<Version, AllResourceTypes>[];
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export interface InstanceHistoryResponse<Version extends FHIR_VERSION>
|
|
206
|
+
extends InstanceInteraction<Version> {
|
|
207
|
+
type: ResponseType["history"];
|
|
208
|
+
body: Resource<Version, "Bundle">;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
export interface CreateResponse<Version extends FHIR_VERSION>
|
|
212
|
+
extends TypeInteraction<Version> {
|
|
213
|
+
type: ResponseType["create"];
|
|
214
|
+
body: Resource<Version, ResourceType<Version>>;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export interface TypeSearchResponse<Version extends FHIR_VERSION>
|
|
218
|
+
extends TypeInteraction<Version> {
|
|
219
|
+
parameters: Parameters<Version>;
|
|
220
|
+
type: ResponseType["search"];
|
|
221
|
+
body: Resource<Version, "Bundle">;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export interface TypeHistoryResponse<Version extends FHIR_VERSION>
|
|
225
|
+
extends TypeInteraction<Version> {
|
|
226
|
+
type: ResponseType["history"];
|
|
227
|
+
body: Resource<Version, "Bundle">;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
export interface CapabilitiesResponse<Version extends FHIR_VERSION>
|
|
231
|
+
extends SystemInteraction<Version> {
|
|
232
|
+
type: ResponseType["capabilities"];
|
|
233
|
+
body: Resource<Version, "CapabilityStatement">;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export interface BatchResponse<Version extends FHIR_VERSION>
|
|
237
|
+
extends SystemInteraction<Version> {
|
|
238
|
+
type: ResponseType["batch"];
|
|
239
|
+
body: Resource<Version, "Bundle">;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export interface TransactionResponse<Version extends FHIR_VERSION>
|
|
243
|
+
extends SystemInteraction<Version> {
|
|
244
|
+
type: ResponseType["transaction"];
|
|
245
|
+
body: Resource<Version, "Bundle">;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
export interface SystemHistoryResponse<Version extends FHIR_VERSION>
|
|
249
|
+
extends SystemInteraction<Version> {
|
|
250
|
+
type: ResponseType["history"];
|
|
251
|
+
body: Resource<Version, "Bundle">;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
export interface SystemSearchResponse<Version extends FHIR_VERSION>
|
|
255
|
+
extends SystemInteraction<Version> {
|
|
256
|
+
parameters: Parameters<Version>;
|
|
257
|
+
type: ResponseType["search"];
|
|
258
|
+
body: Resource<Version, "Bundle">;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export interface InvokeInstanceResponse<Version extends FHIR_VERSION>
|
|
262
|
+
extends InstanceInteraction<Version> {
|
|
263
|
+
type: ResponseType["invoke"];
|
|
264
|
+
operation: code;
|
|
265
|
+
body: Resource<Version, "Parameters">;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export interface InvokeTypeResponse<Version extends FHIR_VERSION>
|
|
269
|
+
extends TypeInteraction<Version> {
|
|
270
|
+
type: ResponseType["invoke"];
|
|
271
|
+
operation: code;
|
|
272
|
+
body: Resource<Version, "Parameters">;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export interface InvokeSystemResponse<Version extends FHIR_VERSION>
|
|
276
|
+
extends SystemInteraction<Version> {
|
|
277
|
+
type: ResponseType["invoke"];
|
|
278
|
+
operation: code;
|
|
279
|
+
body: Resource<Version, "Parameters">;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
export type InvokeResponse<Version extends FHIR_VERSION> =
|
|
283
|
+
| InvokeInstanceResponse<Version>
|
|
284
|
+
| InvokeTypeResponse<Version>
|
|
285
|
+
| InvokeSystemResponse<Version>;
|
|
286
|
+
|
|
287
|
+
export type InvokeRequest<Version extends FHIR_VERSION> =
|
|
288
|
+
| InvokeInstanceRequest<Version>
|
|
289
|
+
| InvokeTypeRequest<Version>
|
|
290
|
+
| InvokeSystemRequest<Version>;
|
|
291
|
+
|
|
292
|
+
export type DeleteRequest<Version extends FHIR_VERSION> =
|
|
293
|
+
| InstanceDeleteRequest<Version>
|
|
294
|
+
| TypeDeleteRequest<Version>
|
|
295
|
+
| SystemDeleteRequest<Version>;
|
|
296
|
+
export type DeleteResponse<Version extends FHIR_VERSION> =
|
|
297
|
+
| InstanceDeleteResponse<Version>
|
|
298
|
+
| TypeDeleteResponse<Version>
|
|
299
|
+
| SystemDeleteResponse<Version>;
|
|
300
|
+
|
|
301
|
+
export type HistoryRequest<Version extends FHIR_VERSION> =
|
|
302
|
+
| HistoryInstanceRequest<Version>
|
|
303
|
+
| TypeHistoryRequest<Version>
|
|
304
|
+
| SystemHistoryRequest<Version>;
|
|
305
|
+
export type HistoryResponse<Version extends FHIR_VERSION> =
|
|
306
|
+
| InstanceHistoryResponse<Version>
|
|
307
|
+
| TypeHistoryResponse<Version>
|
|
308
|
+
| SystemHistoryResponse<Version>;
|
|
309
|
+
|
|
310
|
+
export type SearchRequest<Version extends FHIR_VERSION> =
|
|
311
|
+
| TypeSearchRequest<Version>
|
|
312
|
+
| SystemSearchRequest<Version>;
|
|
313
|
+
export type SearchResponse<Version extends FHIR_VERSION> =
|
|
314
|
+
| TypeSearchResponse<Version>
|
|
315
|
+
| SystemSearchResponse<Version>;
|
|
316
|
+
|
|
317
|
+
export type UpdateRequest<Version extends FHIR_VERSION> =
|
|
318
|
+
| InstanceUpdateRequest<Version>
|
|
319
|
+
| ConditionalUpdateRequest<Version>;
|
|
320
|
+
|
|
321
|
+
interface ErrorResponse<
|
|
322
|
+
Version extends FHIR_VERSION,
|
|
323
|
+
Level extends keyof RequestLevel
|
|
324
|
+
> extends Request<Version, Level> {
|
|
325
|
+
type: ResponseType["error"];
|
|
326
|
+
body: Resource<Version, "OperationOutcome">;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
export type FHIRErrorResponse<Version extends FHIR_VERSION> =
|
|
330
|
+
| ErrorResponse<Version, "system">
|
|
331
|
+
| ErrorResponse<Version, "type">
|
|
332
|
+
| ErrorResponse<Version, "instance">;
|
|
333
|
+
|
|
334
|
+
type InteractionToRequest<Version extends FHIR_VERSION> = {
|
|
335
|
+
invoke: InvokeRequest<Version>;
|
|
336
|
+
read: ReadRequest<Version>;
|
|
337
|
+
vread: VersionReadRequest<Version>;
|
|
338
|
+
update: UpdateRequest<Version>;
|
|
339
|
+
patch: PatchRequest<Version>;
|
|
340
|
+
delete: DeleteRequest<Version>;
|
|
341
|
+
history: HistoryRequest<Version>;
|
|
342
|
+
create: CreateRequest<Version>;
|
|
343
|
+
search: SearchRequest<Version>;
|
|
344
|
+
capabilities: CapabilitiesRequest<Version>;
|
|
345
|
+
batch: BatchRequest<Version>;
|
|
346
|
+
transaction: TransactionRequest<Version>;
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
export type FHIRRequest<
|
|
350
|
+
Version extends FHIR_VERSION,
|
|
351
|
+
I extends Interaction[keyof Interaction]
|
|
352
|
+
> = InteractionToRequest<Version>[I];
|
|
353
|
+
|
|
354
|
+
type InteractionToResponse<Version extends FHIR_VERSION> = {
|
|
355
|
+
error: FHIRErrorResponse<Version>;
|
|
356
|
+
invoke: InvokeResponse<Version>;
|
|
357
|
+
read: ReadResponse<Version>;
|
|
358
|
+
vread: VersionReadResponse<Version>;
|
|
359
|
+
update: UpdateResponse<Version>;
|
|
360
|
+
patch: PatchResponse<Version>;
|
|
361
|
+
history: HistoryResponse<Version>;
|
|
362
|
+
delete: DeleteResponse<Version>;
|
|
363
|
+
create: CreateResponse<Version>;
|
|
364
|
+
capabilities: CapabilitiesResponse<Version>;
|
|
365
|
+
batch: BatchResponse<Version>;
|
|
366
|
+
transaction: TransactionResponse<Version>;
|
|
367
|
+
search: SearchResponse<Version>;
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
export type FHIRResponse<
|
|
371
|
+
Version extends FHIR_VERSION,
|
|
372
|
+
I extends Interaction[keyof Interaction] | "error"
|
|
373
|
+
> = InteractionToResponse<Version>[I];
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { FHIR_VERSIONS_SUPPORTED } from "@haste-health/fhir-types/versions";
|
|
2
|
+
|
|
3
|
+
export type RequestLevel = {
|
|
4
|
+
instance: "instance";
|
|
5
|
+
system: "system";
|
|
6
|
+
type: "type";
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type Interaction = {
|
|
10
|
+
read: "read";
|
|
11
|
+
vread: "vread";
|
|
12
|
+
update: "update";
|
|
13
|
+
patch: "patch";
|
|
14
|
+
delete: "delete";
|
|
15
|
+
history: "history";
|
|
16
|
+
create: "create";
|
|
17
|
+
search: "search";
|
|
18
|
+
capabilities: "capabilities";
|
|
19
|
+
batch: "batch";
|
|
20
|
+
transaction: "transaction";
|
|
21
|
+
invoke: "invoke";
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
export function toInteraction<I extends AllInteractions>(
|
|
25
|
+
r: RequestType[I] | ResponseType[I]
|
|
26
|
+
): I {
|
|
27
|
+
return r.split("-")[0] as I;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type AllInteractions = Interaction[keyof Interaction];
|
|
31
|
+
|
|
32
|
+
export type RequestType = {
|
|
33
|
+
[I in Interaction[keyof Interaction]]: `${I}-request`;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type ResponseType = {
|
|
37
|
+
[I in Interaction[keyof Interaction]]: `${I}-response`;
|
|
38
|
+
} & { error: "error-response" };
|
|
39
|
+
|
|
40
|
+
export function RequestType<I extends Interaction[keyof Interaction]>(
|
|
41
|
+
interaction: I
|
|
42
|
+
): RequestType[I] {
|
|
43
|
+
return `${interaction}-request` as RequestType[I];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function ResponseType<
|
|
47
|
+
I extends Interaction[keyof Interaction] | "error"
|
|
48
|
+
>(interaction: I): ResponseType[I] {
|
|
49
|
+
return `${interaction}-response` as ResponseType[I];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export type Request<
|
|
53
|
+
Version extends (typeof FHIR_VERSIONS_SUPPORTED)[number],
|
|
54
|
+
level extends keyof RequestLevel
|
|
55
|
+
> = {
|
|
56
|
+
fhirVersion: Version;
|
|
57
|
+
level: RequestLevel[level];
|
|
58
|
+
http?: {
|
|
59
|
+
status: number;
|
|
60
|
+
headers: Record<string, string>;
|
|
61
|
+
};
|
|
62
|
+
};
|
package/src/url.test.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { expect, test } from "@jest/globals";
|
|
2
|
+
|
|
3
|
+
import parseFHIRSearch, {
|
|
4
|
+
escapeParameter,
|
|
5
|
+
splitParameter,
|
|
6
|
+
unescapeParameter,
|
|
7
|
+
} from "./url.js";
|
|
8
|
+
|
|
9
|
+
test("Test resource level", () => {
|
|
10
|
+
expect(parseFHIRSearch("Patient?name:text=bob")).toEqual([
|
|
11
|
+
{ name: "name", modifier: "text", value: ["bob"] },
|
|
12
|
+
]);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
test("Test System level", () => {
|
|
16
|
+
expect(
|
|
17
|
+
parseFHIRSearch("Patient?name:text=bob&lastUpdated:not-in=1980-01-01"),
|
|
18
|
+
).toEqual([
|
|
19
|
+
{ name: "name", modifier: "text", value: ["bob"] },
|
|
20
|
+
{
|
|
21
|
+
name: "lastUpdated",
|
|
22
|
+
modifier: "not-in",
|
|
23
|
+
value: ["1980-01-01"],
|
|
24
|
+
},
|
|
25
|
+
]);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
test("TEST ESCAPING", () => {
|
|
29
|
+
expect(escapeParameter("test|123")).toEqual("test\\|123");
|
|
30
|
+
expect(unescapeParameter(escapeParameter("test|123"))).toEqual("test|123");
|
|
31
|
+
expect(escapeParameter("test\\123")).toEqual("test\\\\123");
|
|
32
|
+
expect(unescapeParameter(escapeParameter("test\\123"))).toEqual("test\\123");
|
|
33
|
+
expect(escapeParameter("test$123")).toEqual("test\\$123");
|
|
34
|
+
expect(escapeParameter("test,123")).toEqual("test\\,123");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("TEST Parameter Split", () => {
|
|
38
|
+
expect(splitParameter("test\\|123|456", "|")).toEqual(["test|123", "456"]);
|
|
39
|
+
expect(splitParameter("|test\\|123|456|", "|")).toEqual([
|
|
40
|
+
"",
|
|
41
|
+
"test|123",
|
|
42
|
+
"456",
|
|
43
|
+
"",
|
|
44
|
+
]);
|
|
45
|
+
|
|
46
|
+
expect(splitParameter("|123|test\\|123|456", "|")).toEqual([
|
|
47
|
+
"",
|
|
48
|
+
"123",
|
|
49
|
+
"test|123",
|
|
50
|
+
"456",
|
|
51
|
+
]);
|
|
52
|
+
});
|
package/src/url.ts
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { FHIR_VERSION, Resource } from "@haste-health/fhir-types/versions";
|
|
2
|
+
import { OperationError, outcomeError } from "@haste-health/operation-outcomes";
|
|
3
|
+
|
|
4
|
+
type SPECIAL_CHARACTER = "\\" | "|" | "$" | ",";
|
|
5
|
+
const SPECIAL_CHARACTERS: SPECIAL_CHARACTER[] = ["\\", "|", "$", ","];
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Returns string with split pieces and unescapes special characters from the split piece.
|
|
9
|
+
* @param parameter Parameter to be split
|
|
10
|
+
* @param specialCharacter One of special characters that get escaped on parameter.
|
|
11
|
+
*/
|
|
12
|
+
export function splitParameter(
|
|
13
|
+
parameter: string,
|
|
14
|
+
specialCharacter: SPECIAL_CHARACTER
|
|
15
|
+
): string[] {
|
|
16
|
+
const specialCharEg = new RegExp(`\\${specialCharacter}`, "g");
|
|
17
|
+
let prevIndex = -1;
|
|
18
|
+
const pieces = [];
|
|
19
|
+
let match;
|
|
20
|
+
|
|
21
|
+
while ((match = specialCharEg.exec(parameter))) {
|
|
22
|
+
if (match.index === 0 || parameter[match.index - 1] !== "\\") {
|
|
23
|
+
pieces.push(parameter.substring(prevIndex + 1, match.index));
|
|
24
|
+
prevIndex = match.index;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
pieces.push(parameter.substring(prevIndex + 1));
|
|
28
|
+
|
|
29
|
+
return pieces.map(unescapeParameter);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Escapes a parameter values special characters
|
|
34
|
+
* Reference: https://hl7.org/fhir/R4/search.html#escaping
|
|
35
|
+
* @param parameter Parameter value to escape
|
|
36
|
+
* @returns Escaped Parameter
|
|
37
|
+
*/
|
|
38
|
+
export function escapeParameter(parameter: string): string {
|
|
39
|
+
return SPECIAL_CHARACTERS.reduce(
|
|
40
|
+
(parameter: string, character: string): string => {
|
|
41
|
+
return parameter.replaceAll(character, `\\${character}`);
|
|
42
|
+
},
|
|
43
|
+
parameter
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Unescapes a parameter values special characters.
|
|
49
|
+
* Reference: https://hl7.org/fhir/R4/search.html#escaping
|
|
50
|
+
* @param parameter Escaped Parameter
|
|
51
|
+
* @returns Unescaped Parameter
|
|
52
|
+
*/
|
|
53
|
+
export function unescapeParameter(parameter: string): string {
|
|
54
|
+
return SPECIAL_CHARACTERS.reduce(
|
|
55
|
+
(parameter: string, character: string): string => {
|
|
56
|
+
return parameter.replaceAll(`\\${character}`, character);
|
|
57
|
+
},
|
|
58
|
+
parameter
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface ParsedParameter<T> {
|
|
63
|
+
name: string;
|
|
64
|
+
value: T[];
|
|
65
|
+
modifier?: string;
|
|
66
|
+
chains?: string[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface SearchParameterResource<Version extends FHIR_VERSION>
|
|
70
|
+
extends ParsedParameter<string | number> {
|
|
71
|
+
type: "resource";
|
|
72
|
+
searchParameter: Resource<Version, "SearchParameter">;
|
|
73
|
+
chainedParameters?: Resource<Version, "SearchParameter">[][];
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export interface SearchParameterResult
|
|
77
|
+
extends ParsedParameter<string | number> {
|
|
78
|
+
type: "result";
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export type MetaParameter<Version extends FHIR_VERSION> =
|
|
82
|
+
| SearchParameterResource<Version>
|
|
83
|
+
| SearchParameterResult;
|
|
84
|
+
|
|
85
|
+
export type Parameters<Version extends FHIR_VERSION> =
|
|
86
|
+
| ParsedParameter<string | number>[]
|
|
87
|
+
| MetaParameter<Version>[];
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Given a query string create complex FHIR Query object.
|
|
91
|
+
* @param queryParams Raw query parameters pulled off url
|
|
92
|
+
* @returns Record of parsed parameters with name modifier and value.
|
|
93
|
+
*/
|
|
94
|
+
export function parseQuery(
|
|
95
|
+
queryParams: string | undefined
|
|
96
|
+
): ParsedParameter<string>[] {
|
|
97
|
+
const parameters = !queryParams
|
|
98
|
+
? []
|
|
99
|
+
: queryParams
|
|
100
|
+
.split("&")
|
|
101
|
+
.map((param) => param.split("="))
|
|
102
|
+
.reduce(
|
|
103
|
+
(
|
|
104
|
+
parameters,
|
|
105
|
+
[key, value]
|
|
106
|
+
): Record<string, ParsedParameter<string>> => {
|
|
107
|
+
const chains = key.split(".");
|
|
108
|
+
|
|
109
|
+
const [name, modifier] = chains[0].split(":");
|
|
110
|
+
|
|
111
|
+
const searchParam: ParsedParameter<string> = {
|
|
112
|
+
name,
|
|
113
|
+
modifier,
|
|
114
|
+
value: value.split(",").map((v) => decodeURIComponent(v)),
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
if (chains.length > 1) searchParam.chains = chains.slice(1);
|
|
118
|
+
if (modifier) searchParam.modifier = modifier;
|
|
119
|
+
|
|
120
|
+
return { ...parameters, [searchParam.name]: searchParam };
|
|
121
|
+
},
|
|
122
|
+
{}
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
return Object.values(parameters);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Given a url string parsequery parameters.
|
|
130
|
+
* @param url Any url to parse out query parameters.
|
|
131
|
+
* @returns Record of parsed parameters with name modifier and value.
|
|
132
|
+
*/
|
|
133
|
+
export default function parseUrl(
|
|
134
|
+
url: string
|
|
135
|
+
): ParsedParameter<string | number>[] {
|
|
136
|
+
const chunks = url.split("?");
|
|
137
|
+
if (chunks.length > 2)
|
|
138
|
+
throw new OperationError(outcomeError("invalid", "Invalid query string"));
|
|
139
|
+
const [_, queryParams] = chunks;
|
|
140
|
+
return parseQuery(queryParams);
|
|
141
|
+
}
|