@healthcloudai/hc-safe-cdx 0.4.0 → 0.4.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/README.md +12 -12
- package/dist/index.cjs +29 -63
- package/dist/index.d.cts +7 -9
- package/dist/index.d.ts +7 -9
- package/dist/index.js +34 -68
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -145,9 +145,9 @@ safeCdx.listTestProfilesByAccount(includeRegisterTestDetails?)
|
|
|
145
145
|
safeCdx.createUploadUrl(userTestResultId, gtin, imageType?)
|
|
146
146
|
safeCdx.updateCvmlStatus(imageOfCaptureId, cvmlStatus)
|
|
147
147
|
safeCdx.getCvmlResults(imageOfCaptureId)
|
|
148
|
-
safeCdx.
|
|
148
|
+
safeCdx.listPendingResults(excludeStatus?)
|
|
149
149
|
safeCdx.getLastResults(excludeStatus?)
|
|
150
|
-
safeCdx.
|
|
150
|
+
safeCdx.listTestHistory(excludeStatus?)
|
|
151
151
|
safeCdx.getResultDetails(userTestResultId)
|
|
152
152
|
safeCdx.getResultPdf(userTestResultId)
|
|
153
153
|
safeCdx.getImageCaptureUrl(userTestResultId)
|
|
@@ -761,14 +761,14 @@ const response = await safeCdx.getCvmlResults(imageOfCaptureId);
|
|
|
761
761
|
|
|
762
762
|
---
|
|
763
763
|
|
|
764
|
-
### `
|
|
764
|
+
### `listPendingResults(...)`
|
|
765
765
|
|
|
766
766
|
Returns pending or incomplete test results for the authenticated patient.
|
|
767
767
|
|
|
768
768
|
#### Signature
|
|
769
769
|
|
|
770
770
|
```ts
|
|
771
|
-
safeCdx.
|
|
771
|
+
safeCdx.listPendingResults(
|
|
772
772
|
excludeStatus?: string
|
|
773
773
|
): Promise<APIResponse<GetPendingResultsData>>
|
|
774
774
|
```
|
|
@@ -789,11 +789,11 @@ type GetPendingResultsData =
|
|
|
789
789
|
#### Usage
|
|
790
790
|
|
|
791
791
|
```ts
|
|
792
|
-
const pending = await safeCdx.
|
|
792
|
+
const pending = await safeCdx.listPendingResults();
|
|
793
793
|
```
|
|
794
794
|
|
|
795
795
|
```ts
|
|
796
|
-
const pending = await safeCdx.
|
|
796
|
+
const pending = await safeCdx.listPendingResults(
|
|
797
797
|
"Invalid,Canceled"
|
|
798
798
|
);
|
|
799
799
|
```
|
|
@@ -1081,14 +1081,14 @@ const lastResult = await safeCdx.getLastResults("Invalid");
|
|
|
1081
1081
|
|
|
1082
1082
|
---
|
|
1083
1083
|
|
|
1084
|
-
### `
|
|
1084
|
+
### `listTestHistory(...)`
|
|
1085
1085
|
|
|
1086
1086
|
Returns test result history for the authenticated patient.
|
|
1087
1087
|
|
|
1088
1088
|
#### Signature
|
|
1089
1089
|
|
|
1090
1090
|
```ts
|
|
1091
|
-
safeCdx.
|
|
1091
|
+
safeCdx.listTestHistory(
|
|
1092
1092
|
excludeStatus?: string
|
|
1093
1093
|
): Promise<APIResponse<GetTestHistoryData>>
|
|
1094
1094
|
```
|
|
@@ -1109,11 +1109,11 @@ type GetTestHistoryData =
|
|
|
1109
1109
|
#### Usage
|
|
1110
1110
|
|
|
1111
1111
|
```ts
|
|
1112
|
-
const history = await safeCdx.
|
|
1112
|
+
const history = await safeCdx.listTestHistory();
|
|
1113
1113
|
```
|
|
1114
1114
|
|
|
1115
1115
|
```ts
|
|
1116
|
-
const history = await safeCdx.
|
|
1116
|
+
const history = await safeCdx.listTestHistory("Invalid");
|
|
1117
1117
|
```
|
|
1118
1118
|
|
|
1119
1119
|
#### API request sent internally
|
|
@@ -1666,9 +1666,9 @@ Safe CDX calls a **different backend service** from all other connectors. The ho
|
|
|
1666
1666
|
| `uploadImage(preSignedURL, image, contentType?)` | `Promise<void>` — direct S3 upload, no envelope |
|
|
1667
1667
|
| `updateCvmlStatus(...)` | `SafeAPIResponse<UpdateCvmlStatusResponse>` |
|
|
1668
1668
|
| `getCvmlResults(imageOfCaptureId)` | `SafeAPIResponse<GetCvmlResultsResponse>` |
|
|
1669
|
-
| `
|
|
1669
|
+
| `listPendingResults(excludeStatus?)` | `APIResponse<GetPendingResultsData>` |
|
|
1670
1670
|
| `getLastResults(excludeStatus?)` | `APIResponse<GetLastResultsData>` |
|
|
1671
|
-
| `
|
|
1671
|
+
| `listTestHistory(excludeStatus?)` | `APIResponse<GetTestHistoryData>` |
|
|
1672
1672
|
| `getResultDetails(userTestResultId)` | `SafeAPIResponse<GetResultDetailsResponse>` |
|
|
1673
1673
|
| `getResultPdf(userTestResultId)` | `APIResponse<GetResultPdfData>` |
|
|
1674
1674
|
| `getImageCaptureUrl(userTestResultId)` | `SafeAPIResponse<GetImageCaptureUrlResponse>` |
|
package/dist/index.cjs
CHANGED
|
@@ -69,7 +69,7 @@ var HCSafeCDXClient = class extends import_hc_http.HCBaseConnector {
|
|
|
69
69
|
* Resolves the SafeCDX test profile associated with a GTIN barcode.
|
|
70
70
|
*/
|
|
71
71
|
async getTestProfileByGTIN(gtin) {
|
|
72
|
-
const resolvedGtin = this.requireValue(gtin, "GTIN");
|
|
72
|
+
const resolvedGtin = this.requireValue(gtin, "GTIN", "gtin");
|
|
73
73
|
return this.execute(
|
|
74
74
|
"getTestProfileByGTIN",
|
|
75
75
|
() => this.http.get(
|
|
@@ -88,7 +88,7 @@ var HCSafeCDXClient = class extends import_hc_http.HCBaseConnector {
|
|
|
88
88
|
const request = {
|
|
89
89
|
Data: { IncludeRegisterTestDetails: includeRegisterTestDetails }
|
|
90
90
|
};
|
|
91
|
-
return this.
|
|
91
|
+
return this.execute(
|
|
92
92
|
"listTestProfilesByAccount",
|
|
93
93
|
() => this.http.post(
|
|
94
94
|
this.url("test/profiles/by-account"),
|
|
@@ -105,9 +105,9 @@ var HCSafeCDXClient = class extends import_hc_http.HCBaseConnector {
|
|
|
105
105
|
* Requests a pre-signed URL used to upload a test image.
|
|
106
106
|
*/
|
|
107
107
|
async createUploadUrl(userTestResultId, gtin, imageType = "jpg") {
|
|
108
|
-
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID");
|
|
109
|
-
const resolvedGtin = this.requireValue(gtin, "GTIN");
|
|
110
|
-
const resolvedImageType = this.requireValue(imageType, "Image type");
|
|
108
|
+
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID", "userTestResultId");
|
|
109
|
+
const resolvedGtin = this.requireValue(gtin, "GTIN", "gtin");
|
|
110
|
+
const resolvedImageType = this.requireValue(imageType, "Image type", "imageType");
|
|
111
111
|
const request = {
|
|
112
112
|
Data: {
|
|
113
113
|
Gtin: resolvedGtin,
|
|
@@ -133,10 +133,10 @@ var HCSafeCDXClient = class extends import_hc_http.HCBaseConnector {
|
|
|
133
133
|
* The pre-signed URL embeds credentials; no Authorization header is needed.
|
|
134
134
|
*/
|
|
135
135
|
async uploadImage(preSignedURL, image, contentType = "image/jpeg") {
|
|
136
|
-
const resolvedPreSignedURL = this.requireValue(preSignedURL, "Pre-signed URL");
|
|
137
|
-
const resolvedContentType = this.requireValue(contentType, "Content type");
|
|
136
|
+
const resolvedPreSignedURL = this.requireValue(preSignedURL, "Pre-signed URL", "preSignedURL");
|
|
137
|
+
const resolvedContentType = this.requireValue(contentType, "Content type", "contentType");
|
|
138
138
|
if (image == null) {
|
|
139
|
-
throw new import_hc_http.ValidationError({ message: "Image is required.", code: "INVALID_INPUT" });
|
|
139
|
+
throw new import_hc_http.ValidationError({ message: "Image is required.", code: "INVALID_INPUT", param: "image" });
|
|
140
140
|
}
|
|
141
141
|
const response = await fetch(resolvedPreSignedURL, {
|
|
142
142
|
method: "PUT",
|
|
@@ -150,10 +150,8 @@ var HCSafeCDXClient = class extends import_hc_http.HCBaseConnector {
|
|
|
150
150
|
} catch {
|
|
151
151
|
body = void 0;
|
|
152
152
|
}
|
|
153
|
-
throw
|
|
154
|
-
|
|
155
|
-
code: response.status >= 500 ? "SERVER_ERROR" : "UNKNOWN_ERROR",
|
|
156
|
-
statusCode: response.status,
|
|
153
|
+
throw (0, import_hc_http.errorFromHttpStatus)(response.status, {
|
|
154
|
+
operationName: "uploadImage",
|
|
157
155
|
backendMessage: body,
|
|
158
156
|
details: { status: response.status, body }
|
|
159
157
|
});
|
|
@@ -167,15 +165,15 @@ var HCSafeCDXClient = class extends import_hc_http.HCBaseConnector {
|
|
|
167
165
|
* Updates the CVML processing status for an image capture.
|
|
168
166
|
*/
|
|
169
167
|
async updateCvmlStatus(imageOfCaptureId, cvmlStatus) {
|
|
170
|
-
const resolvedImageOfCaptureId = this.requireValue(imageOfCaptureId, "Image capture ID");
|
|
171
|
-
const resolvedCvmlStatus = this.requireValue(cvmlStatus, "CVML status");
|
|
168
|
+
const resolvedImageOfCaptureId = this.requireValue(imageOfCaptureId, "Image capture ID", "imageOfCaptureId");
|
|
169
|
+
const resolvedCvmlStatus = this.requireValue(cvmlStatus, "CVML status", "cvmlStatus");
|
|
172
170
|
const request = {
|
|
173
171
|
Data: {
|
|
174
172
|
ImageOfCaptureId: resolvedImageOfCaptureId,
|
|
175
173
|
CvmlStatus: resolvedCvmlStatus
|
|
176
174
|
}
|
|
177
175
|
};
|
|
178
|
-
return this.
|
|
176
|
+
return this.execute(
|
|
179
177
|
"updateCvmlStatus",
|
|
180
178
|
() => this.http.post(this.url("cvml/status"), request, this.getAuthHeaders())
|
|
181
179
|
);
|
|
@@ -185,8 +183,8 @@ var HCSafeCDXClient = class extends import_hc_http.HCBaseConnector {
|
|
|
185
183
|
* Returns the CVML analysis results for an image capture.
|
|
186
184
|
*/
|
|
187
185
|
async getCvmlResults(imageOfCaptureId) {
|
|
188
|
-
const resolvedImageOfCaptureId = this.requireValue(imageOfCaptureId, "Image capture ID");
|
|
189
|
-
return this.
|
|
186
|
+
const resolvedImageOfCaptureId = this.requireValue(imageOfCaptureId, "Image capture ID", "imageOfCaptureId");
|
|
187
|
+
return this.execute(
|
|
190
188
|
"getCvmlResults",
|
|
191
189
|
() => this.http.get(
|
|
192
190
|
this.url("cvml/results", { imageOfCaptureId: resolvedImageOfCaptureId }),
|
|
@@ -202,7 +200,7 @@ var HCSafeCDXClient = class extends import_hc_http.HCBaseConnector {
|
|
|
202
200
|
const request = {
|
|
203
201
|
Data: { ExcludeStatus: excludeStatus }
|
|
204
202
|
};
|
|
205
|
-
return this.
|
|
203
|
+
return this.execute(
|
|
206
204
|
"listPendingResults",
|
|
207
205
|
() => this.http.post(this.url("test/result/pending"), request, this.getAuthHeaders())
|
|
208
206
|
);
|
|
@@ -212,7 +210,7 @@ var HCSafeCDXClient = class extends import_hc_http.HCBaseConnector {
|
|
|
212
210
|
const request = {
|
|
213
211
|
Data: { ExcludeStatus: excludeStatus }
|
|
214
212
|
};
|
|
215
|
-
return this.
|
|
213
|
+
return this.execute(
|
|
216
214
|
"getLastResults",
|
|
217
215
|
() => this.http.post(this.url("test/result/last"), request, this.getAuthHeaders())
|
|
218
216
|
);
|
|
@@ -222,7 +220,7 @@ var HCSafeCDXClient = class extends import_hc_http.HCBaseConnector {
|
|
|
222
220
|
const request = {
|
|
223
221
|
Data: { ExcludeStatus: excludeStatus }
|
|
224
222
|
};
|
|
225
|
-
return this.
|
|
223
|
+
return this.execute(
|
|
226
224
|
"listTestHistory",
|
|
227
225
|
() => this.http.post(this.url("test/result/history"), request, this.getAuthHeaders())
|
|
228
226
|
);
|
|
@@ -232,22 +230,22 @@ var HCSafeCDXClient = class extends import_hc_http.HCBaseConnector {
|
|
|
232
230
|
* Returns full details for a single test result.
|
|
233
231
|
*/
|
|
234
232
|
async getResultDetails(userTestResultId) {
|
|
235
|
-
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID");
|
|
233
|
+
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID", "userTestResultId");
|
|
236
234
|
const request = {
|
|
237
235
|
Data: { UserTestResultId: resolvedUserTestResultId }
|
|
238
236
|
};
|
|
239
|
-
return this.
|
|
237
|
+
return this.execute(
|
|
240
238
|
"getResultDetails",
|
|
241
239
|
() => this.http.post(this.url("test/result/details"), request, this.getAuthHeaders())
|
|
242
240
|
);
|
|
243
241
|
}
|
|
244
242
|
/** POST test/result/pdf — returns the PDF report for a test result. */
|
|
245
243
|
async getResultPdf(userTestResultId) {
|
|
246
|
-
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID");
|
|
244
|
+
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID", "userTestResultId");
|
|
247
245
|
const request = {
|
|
248
246
|
Data: { UserTestResultId: resolvedUserTestResultId }
|
|
249
247
|
};
|
|
250
|
-
return this.
|
|
248
|
+
return this.execute(
|
|
251
249
|
"getResultPdf",
|
|
252
250
|
() => this.http.post(this.url("test/result/pdf"), request, this.getAuthHeaders())
|
|
253
251
|
);
|
|
@@ -257,11 +255,11 @@ var HCSafeCDXClient = class extends import_hc_http.HCBaseConnector {
|
|
|
257
255
|
* Returns a URL to capture an image for the given test result.
|
|
258
256
|
*/
|
|
259
257
|
async getImageCaptureUrl(userTestResultId) {
|
|
260
|
-
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID");
|
|
258
|
+
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID", "userTestResultId");
|
|
261
259
|
const request = {
|
|
262
260
|
Data: { UserTestResultId: resolvedUserTestResultId }
|
|
263
261
|
};
|
|
264
|
-
return this.
|
|
262
|
+
return this.execute(
|
|
265
263
|
"getImageCaptureUrl",
|
|
266
264
|
() => this.http.post(this.url("test/result/image/capture"), request, this.getAuthHeaders())
|
|
267
265
|
);
|
|
@@ -271,18 +269,18 @@ var HCSafeCDXClient = class extends import_hc_http.HCBaseConnector {
|
|
|
271
269
|
// -------------------------------------------------------------------------
|
|
272
270
|
/** POST test/resume */
|
|
273
271
|
async resumeFlow(userTestResultId, resumed = true) {
|
|
274
|
-
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID");
|
|
272
|
+
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID", "userTestResultId");
|
|
275
273
|
const request = {
|
|
276
274
|
Data: { UserTestResultId: resolvedUserTestResultId, Resumed: resumed }
|
|
277
275
|
};
|
|
278
|
-
return this.
|
|
276
|
+
return this.execute(
|
|
279
277
|
"resumeFlow",
|
|
280
278
|
() => this.http.post(this.url("test/resume"), request, this.getAuthHeaders())
|
|
281
279
|
);
|
|
282
280
|
}
|
|
283
281
|
/** POST test/answers */
|
|
284
282
|
async submitAnswers(submission) {
|
|
285
|
-
const resolvedId = this.requireValue(submission == null ? void 0 : submission.UserTestResultId, "User test result ID");
|
|
283
|
+
const resolvedId = this.requireValue(submission == null ? void 0 : submission.UserTestResultId, "User test result ID", "UserTestResultId");
|
|
286
284
|
if (!(submission == null ? void 0 : submission.Result) || submission.Result.length === 0) {
|
|
287
285
|
throw new import_hc_http.ValidationError({
|
|
288
286
|
message: "At least one answer result is required.",
|
|
@@ -293,14 +291,14 @@ var HCSafeCDXClient = class extends import_hc_http.HCBaseConnector {
|
|
|
293
291
|
const request = {
|
|
294
292
|
Data: { ...submission, UserTestResultId: resolvedId }
|
|
295
293
|
};
|
|
296
|
-
return this.
|
|
294
|
+
return this.execute(
|
|
297
295
|
"submitAnswers",
|
|
298
296
|
() => this.http.post(this.url("test/answers"), request, this.getAuthHeaders())
|
|
299
297
|
);
|
|
300
298
|
}
|
|
301
299
|
/** POST test/finalize */
|
|
302
300
|
async finalizeTest(userTestResultId) {
|
|
303
|
-
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID");
|
|
301
|
+
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID", "userTestResultId");
|
|
304
302
|
const request = {
|
|
305
303
|
Data: { UserTestResultId: resolvedUserTestResultId }
|
|
306
304
|
};
|
|
@@ -312,38 +310,6 @@ var HCSafeCDXClient = class extends import_hc_http.HCBaseConnector {
|
|
|
312
310
|
// -------------------------------------------------------------------------
|
|
313
311
|
// Private Helpers
|
|
314
312
|
// -------------------------------------------------------------------------
|
|
315
|
-
async executeSafe(operation, request) {
|
|
316
|
-
var _a;
|
|
317
|
-
let response;
|
|
318
|
-
try {
|
|
319
|
-
response = await request();
|
|
320
|
-
} catch (err) {
|
|
321
|
-
if (err instanceof import_hc_http.APIError) throw err;
|
|
322
|
-
if (err instanceof Error) {
|
|
323
|
-
throw new import_hc_http.APIError({ message: `${operation}: ${err.message}`, code: "UNKNOWN_ERROR", details: err });
|
|
324
|
-
}
|
|
325
|
-
throw new import_hc_http.APIError({ message: `${operation}: unexpected runtime failure`, code: "UNKNOWN_ERROR", details: err });
|
|
326
|
-
}
|
|
327
|
-
if (response == null) {
|
|
328
|
-
throw new import_hc_http.APIError({ message: `${operation}: empty response received`, code: "EMPTY_RESPONSE", details: response });
|
|
329
|
-
}
|
|
330
|
-
if (!this.isSafeApiResponse(response)) {
|
|
331
|
-
throw new import_hc_http.APIError({ message: `${operation}: invalid SafeCDX response structure`, code: "INVALID_RESPONSE", details: response });
|
|
332
|
-
}
|
|
333
|
-
if (!response.success) {
|
|
334
|
-
throw new import_hc_http.HCServiceError(
|
|
335
|
-
operation,
|
|
336
|
-
(_a = response.message) != null ? _a : "Backend returned success: false",
|
|
337
|
-
response
|
|
338
|
-
);
|
|
339
|
-
}
|
|
340
|
-
return response;
|
|
341
|
-
}
|
|
342
|
-
isSafeApiResponse(value) {
|
|
343
|
-
if (!value || typeof value !== "object") return false;
|
|
344
|
-
const r = value;
|
|
345
|
-
return "success" in r && typeof r.success === "boolean" && "data" in r && "message" in r && "code" in r && typeof r.code === "number";
|
|
346
|
-
}
|
|
347
313
|
getAuthHeaders() {
|
|
348
314
|
return { ...this.getHeaders(), ...this.auth.getAuthHeader() };
|
|
349
315
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -444,7 +444,7 @@ declare class HCSafeCDXClient extends HCBaseConnector {
|
|
|
444
444
|
* Returns test profiles configured for the authenticated patient's account.
|
|
445
445
|
* TenantId is resolved by the backend from the authenticated patient context.
|
|
446
446
|
*/
|
|
447
|
-
listTestProfilesByAccount(includeRegisterTestDetails?: boolean): Promise<SafeAPIResponse<TestProfileByAccountItem[]
|
|
447
|
+
listTestProfilesByAccount(includeRegisterTestDetails?: boolean): Promise<APIResponse<SafeAPIResponse<TestProfileByAccountItem[]>>>;
|
|
448
448
|
/**
|
|
449
449
|
* POST upload/url
|
|
450
450
|
* Requests a pre-signed URL used to upload a test image.
|
|
@@ -470,31 +470,29 @@ declare class HCSafeCDXClient extends HCBaseConnector {
|
|
|
470
470
|
*/
|
|
471
471
|
getCvmlResults(imageOfCaptureId: string): Promise<GetCvmlResultsResponse>;
|
|
472
472
|
/** POST test/result/pending — returns pending test results excluding the given statuses. */
|
|
473
|
-
listPendingResults(excludeStatus?: string): Promise<SafeAPIResponse<TestResultSummary[]
|
|
473
|
+
listPendingResults(excludeStatus?: string): Promise<APIResponse<SafeAPIResponse<TestResultSummary[]>>>;
|
|
474
474
|
/** POST test/result/last — returns the most recent test result. */
|
|
475
|
-
getLastResults(excludeStatus?: string): Promise<SafeAPIResponse<TestResultDetails
|
|
475
|
+
getLastResults(excludeStatus?: string): Promise<APIResponse<SafeAPIResponse<TestResultDetails>>>;
|
|
476
476
|
/** POST test/result/history — returns all test results excluding the given statuses. */
|
|
477
|
-
listTestHistory(excludeStatus?: string): Promise<SafeAPIResponse<TestResultSummary[]
|
|
477
|
+
listTestHistory(excludeStatus?: string): Promise<APIResponse<SafeAPIResponse<TestResultSummary[]>>>;
|
|
478
478
|
/**
|
|
479
479
|
* POST test/result/details
|
|
480
480
|
* Returns full details for a single test result.
|
|
481
481
|
*/
|
|
482
482
|
getResultDetails(userTestResultId: string): Promise<GetResultDetailsResponse>;
|
|
483
483
|
/** POST test/result/pdf — returns the PDF report for a test result. */
|
|
484
|
-
getResultPdf(userTestResultId: string): Promise<SafeAPIResponse<string
|
|
484
|
+
getResultPdf(userTestResultId: string): Promise<APIResponse<SafeAPIResponse<string>>>;
|
|
485
485
|
/**
|
|
486
486
|
* POST test/result/image/capture
|
|
487
487
|
* Returns a URL to capture an image for the given test result.
|
|
488
488
|
*/
|
|
489
489
|
getImageCaptureUrl(userTestResultId: string): Promise<GetImageCaptureUrlResponse>;
|
|
490
490
|
/** POST test/resume */
|
|
491
|
-
resumeFlow(userTestResultId: string, resumed?: boolean): Promise<SafeAPIResponse<ResumeFlowResult
|
|
491
|
+
resumeFlow(userTestResultId: string, resumed?: boolean): Promise<APIResponse<SafeAPIResponse<ResumeFlowResult>>>;
|
|
492
492
|
/** POST test/answers */
|
|
493
|
-
submitAnswers(submission: SubmitAnswersRequest): Promise<SafeAPIResponse<EntityReferenceData
|
|
493
|
+
submitAnswers(submission: SubmitAnswersRequest): Promise<APIResponse<SafeAPIResponse<EntityReferenceData>>>;
|
|
494
494
|
/** POST test/finalize */
|
|
495
495
|
finalizeTest(userTestResultId: string): Promise<APIResponse<unknown>>;
|
|
496
|
-
protected executeSafe<T>(operation: string, request: () => Promise<SafeAPIResponse<T>>): Promise<SafeAPIResponse<T>>;
|
|
497
|
-
private isSafeApiResponse;
|
|
498
496
|
private getAuthHeaders;
|
|
499
497
|
private url;
|
|
500
498
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -444,7 +444,7 @@ declare class HCSafeCDXClient extends HCBaseConnector {
|
|
|
444
444
|
* Returns test profiles configured for the authenticated patient's account.
|
|
445
445
|
* TenantId is resolved by the backend from the authenticated patient context.
|
|
446
446
|
*/
|
|
447
|
-
listTestProfilesByAccount(includeRegisterTestDetails?: boolean): Promise<SafeAPIResponse<TestProfileByAccountItem[]
|
|
447
|
+
listTestProfilesByAccount(includeRegisterTestDetails?: boolean): Promise<APIResponse<SafeAPIResponse<TestProfileByAccountItem[]>>>;
|
|
448
448
|
/**
|
|
449
449
|
* POST upload/url
|
|
450
450
|
* Requests a pre-signed URL used to upload a test image.
|
|
@@ -470,31 +470,29 @@ declare class HCSafeCDXClient extends HCBaseConnector {
|
|
|
470
470
|
*/
|
|
471
471
|
getCvmlResults(imageOfCaptureId: string): Promise<GetCvmlResultsResponse>;
|
|
472
472
|
/** POST test/result/pending — returns pending test results excluding the given statuses. */
|
|
473
|
-
listPendingResults(excludeStatus?: string): Promise<SafeAPIResponse<TestResultSummary[]
|
|
473
|
+
listPendingResults(excludeStatus?: string): Promise<APIResponse<SafeAPIResponse<TestResultSummary[]>>>;
|
|
474
474
|
/** POST test/result/last — returns the most recent test result. */
|
|
475
|
-
getLastResults(excludeStatus?: string): Promise<SafeAPIResponse<TestResultDetails
|
|
475
|
+
getLastResults(excludeStatus?: string): Promise<APIResponse<SafeAPIResponse<TestResultDetails>>>;
|
|
476
476
|
/** POST test/result/history — returns all test results excluding the given statuses. */
|
|
477
|
-
listTestHistory(excludeStatus?: string): Promise<SafeAPIResponse<TestResultSummary[]
|
|
477
|
+
listTestHistory(excludeStatus?: string): Promise<APIResponse<SafeAPIResponse<TestResultSummary[]>>>;
|
|
478
478
|
/**
|
|
479
479
|
* POST test/result/details
|
|
480
480
|
* Returns full details for a single test result.
|
|
481
481
|
*/
|
|
482
482
|
getResultDetails(userTestResultId: string): Promise<GetResultDetailsResponse>;
|
|
483
483
|
/** POST test/result/pdf — returns the PDF report for a test result. */
|
|
484
|
-
getResultPdf(userTestResultId: string): Promise<SafeAPIResponse<string
|
|
484
|
+
getResultPdf(userTestResultId: string): Promise<APIResponse<SafeAPIResponse<string>>>;
|
|
485
485
|
/**
|
|
486
486
|
* POST test/result/image/capture
|
|
487
487
|
* Returns a URL to capture an image for the given test result.
|
|
488
488
|
*/
|
|
489
489
|
getImageCaptureUrl(userTestResultId: string): Promise<GetImageCaptureUrlResponse>;
|
|
490
490
|
/** POST test/resume */
|
|
491
|
-
resumeFlow(userTestResultId: string, resumed?: boolean): Promise<SafeAPIResponse<ResumeFlowResult
|
|
491
|
+
resumeFlow(userTestResultId: string, resumed?: boolean): Promise<APIResponse<SafeAPIResponse<ResumeFlowResult>>>;
|
|
492
492
|
/** POST test/answers */
|
|
493
|
-
submitAnswers(submission: SubmitAnswersRequest): Promise<SafeAPIResponse<EntityReferenceData
|
|
493
|
+
submitAnswers(submission: SubmitAnswersRequest): Promise<APIResponse<SafeAPIResponse<EntityReferenceData>>>;
|
|
494
494
|
/** POST test/finalize */
|
|
495
495
|
finalizeTest(userTestResultId: string): Promise<APIResponse<unknown>>;
|
|
496
|
-
protected executeSafe<T>(operation: string, request: () => Promise<SafeAPIResponse<T>>): Promise<SafeAPIResponse<T>>;
|
|
497
|
-
private isSafeApiResponse;
|
|
498
496
|
private getAuthHeaders;
|
|
499
497
|
private url;
|
|
500
498
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/client.ts
|
|
2
|
-
import { HCBaseConnector,
|
|
2
|
+
import { HCBaseConnector, ConfigError, ValidationError, errorFromHttpStatus } from "@healthcloudai/hc-http";
|
|
3
3
|
var ENV_HOST = {
|
|
4
4
|
dev: "dev-api-hcs.healthcloud-services.com",
|
|
5
5
|
uat: "uat-api-hcs.healthcloud-services.com",
|
|
@@ -38,7 +38,7 @@ var HCSafeCDXClient = class extends HCBaseConnector {
|
|
|
38
38
|
* Resolves the SafeCDX test profile associated with a GTIN barcode.
|
|
39
39
|
*/
|
|
40
40
|
async getTestProfileByGTIN(gtin) {
|
|
41
|
-
const resolvedGtin = this.requireValue(gtin, "GTIN");
|
|
41
|
+
const resolvedGtin = this.requireValue(gtin, "GTIN", "gtin");
|
|
42
42
|
return this.execute(
|
|
43
43
|
"getTestProfileByGTIN",
|
|
44
44
|
() => this.http.get(
|
|
@@ -57,7 +57,7 @@ var HCSafeCDXClient = class extends HCBaseConnector {
|
|
|
57
57
|
const request = {
|
|
58
58
|
Data: { IncludeRegisterTestDetails: includeRegisterTestDetails }
|
|
59
59
|
};
|
|
60
|
-
return this.
|
|
60
|
+
return this.execute(
|
|
61
61
|
"listTestProfilesByAccount",
|
|
62
62
|
() => this.http.post(
|
|
63
63
|
this.url("test/profiles/by-account"),
|
|
@@ -74,9 +74,9 @@ var HCSafeCDXClient = class extends HCBaseConnector {
|
|
|
74
74
|
* Requests a pre-signed URL used to upload a test image.
|
|
75
75
|
*/
|
|
76
76
|
async createUploadUrl(userTestResultId, gtin, imageType = "jpg") {
|
|
77
|
-
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID");
|
|
78
|
-
const resolvedGtin = this.requireValue(gtin, "GTIN");
|
|
79
|
-
const resolvedImageType = this.requireValue(imageType, "Image type");
|
|
77
|
+
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID", "userTestResultId");
|
|
78
|
+
const resolvedGtin = this.requireValue(gtin, "GTIN", "gtin");
|
|
79
|
+
const resolvedImageType = this.requireValue(imageType, "Image type", "imageType");
|
|
80
80
|
const request = {
|
|
81
81
|
Data: {
|
|
82
82
|
Gtin: resolvedGtin,
|
|
@@ -102,10 +102,10 @@ var HCSafeCDXClient = class extends HCBaseConnector {
|
|
|
102
102
|
* The pre-signed URL embeds credentials; no Authorization header is needed.
|
|
103
103
|
*/
|
|
104
104
|
async uploadImage(preSignedURL, image, contentType = "image/jpeg") {
|
|
105
|
-
const resolvedPreSignedURL = this.requireValue(preSignedURL, "Pre-signed URL");
|
|
106
|
-
const resolvedContentType = this.requireValue(contentType, "Content type");
|
|
105
|
+
const resolvedPreSignedURL = this.requireValue(preSignedURL, "Pre-signed URL", "preSignedURL");
|
|
106
|
+
const resolvedContentType = this.requireValue(contentType, "Content type", "contentType");
|
|
107
107
|
if (image == null) {
|
|
108
|
-
throw new ValidationError({ message: "Image is required.", code: "INVALID_INPUT" });
|
|
108
|
+
throw new ValidationError({ message: "Image is required.", code: "INVALID_INPUT", param: "image" });
|
|
109
109
|
}
|
|
110
110
|
const response = await fetch(resolvedPreSignedURL, {
|
|
111
111
|
method: "PUT",
|
|
@@ -119,10 +119,8 @@ var HCSafeCDXClient = class extends HCBaseConnector {
|
|
|
119
119
|
} catch {
|
|
120
120
|
body = void 0;
|
|
121
121
|
}
|
|
122
|
-
throw
|
|
123
|
-
|
|
124
|
-
code: response.status >= 500 ? "SERVER_ERROR" : "UNKNOWN_ERROR",
|
|
125
|
-
statusCode: response.status,
|
|
122
|
+
throw errorFromHttpStatus(response.status, {
|
|
123
|
+
operationName: "uploadImage",
|
|
126
124
|
backendMessage: body,
|
|
127
125
|
details: { status: response.status, body }
|
|
128
126
|
});
|
|
@@ -136,15 +134,15 @@ var HCSafeCDXClient = class extends HCBaseConnector {
|
|
|
136
134
|
* Updates the CVML processing status for an image capture.
|
|
137
135
|
*/
|
|
138
136
|
async updateCvmlStatus(imageOfCaptureId, cvmlStatus) {
|
|
139
|
-
const resolvedImageOfCaptureId = this.requireValue(imageOfCaptureId, "Image capture ID");
|
|
140
|
-
const resolvedCvmlStatus = this.requireValue(cvmlStatus, "CVML status");
|
|
137
|
+
const resolvedImageOfCaptureId = this.requireValue(imageOfCaptureId, "Image capture ID", "imageOfCaptureId");
|
|
138
|
+
const resolvedCvmlStatus = this.requireValue(cvmlStatus, "CVML status", "cvmlStatus");
|
|
141
139
|
const request = {
|
|
142
140
|
Data: {
|
|
143
141
|
ImageOfCaptureId: resolvedImageOfCaptureId,
|
|
144
142
|
CvmlStatus: resolvedCvmlStatus
|
|
145
143
|
}
|
|
146
144
|
};
|
|
147
|
-
return this.
|
|
145
|
+
return this.execute(
|
|
148
146
|
"updateCvmlStatus",
|
|
149
147
|
() => this.http.post(this.url("cvml/status"), request, this.getAuthHeaders())
|
|
150
148
|
);
|
|
@@ -154,8 +152,8 @@ var HCSafeCDXClient = class extends HCBaseConnector {
|
|
|
154
152
|
* Returns the CVML analysis results for an image capture.
|
|
155
153
|
*/
|
|
156
154
|
async getCvmlResults(imageOfCaptureId) {
|
|
157
|
-
const resolvedImageOfCaptureId = this.requireValue(imageOfCaptureId, "Image capture ID");
|
|
158
|
-
return this.
|
|
155
|
+
const resolvedImageOfCaptureId = this.requireValue(imageOfCaptureId, "Image capture ID", "imageOfCaptureId");
|
|
156
|
+
return this.execute(
|
|
159
157
|
"getCvmlResults",
|
|
160
158
|
() => this.http.get(
|
|
161
159
|
this.url("cvml/results", { imageOfCaptureId: resolvedImageOfCaptureId }),
|
|
@@ -171,7 +169,7 @@ var HCSafeCDXClient = class extends HCBaseConnector {
|
|
|
171
169
|
const request = {
|
|
172
170
|
Data: { ExcludeStatus: excludeStatus }
|
|
173
171
|
};
|
|
174
|
-
return this.
|
|
172
|
+
return this.execute(
|
|
175
173
|
"listPendingResults",
|
|
176
174
|
() => this.http.post(this.url("test/result/pending"), request, this.getAuthHeaders())
|
|
177
175
|
);
|
|
@@ -181,7 +179,7 @@ var HCSafeCDXClient = class extends HCBaseConnector {
|
|
|
181
179
|
const request = {
|
|
182
180
|
Data: { ExcludeStatus: excludeStatus }
|
|
183
181
|
};
|
|
184
|
-
return this.
|
|
182
|
+
return this.execute(
|
|
185
183
|
"getLastResults",
|
|
186
184
|
() => this.http.post(this.url("test/result/last"), request, this.getAuthHeaders())
|
|
187
185
|
);
|
|
@@ -191,7 +189,7 @@ var HCSafeCDXClient = class extends HCBaseConnector {
|
|
|
191
189
|
const request = {
|
|
192
190
|
Data: { ExcludeStatus: excludeStatus }
|
|
193
191
|
};
|
|
194
|
-
return this.
|
|
192
|
+
return this.execute(
|
|
195
193
|
"listTestHistory",
|
|
196
194
|
() => this.http.post(this.url("test/result/history"), request, this.getAuthHeaders())
|
|
197
195
|
);
|
|
@@ -201,22 +199,22 @@ var HCSafeCDXClient = class extends HCBaseConnector {
|
|
|
201
199
|
* Returns full details for a single test result.
|
|
202
200
|
*/
|
|
203
201
|
async getResultDetails(userTestResultId) {
|
|
204
|
-
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID");
|
|
202
|
+
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID", "userTestResultId");
|
|
205
203
|
const request = {
|
|
206
204
|
Data: { UserTestResultId: resolvedUserTestResultId }
|
|
207
205
|
};
|
|
208
|
-
return this.
|
|
206
|
+
return this.execute(
|
|
209
207
|
"getResultDetails",
|
|
210
208
|
() => this.http.post(this.url("test/result/details"), request, this.getAuthHeaders())
|
|
211
209
|
);
|
|
212
210
|
}
|
|
213
211
|
/** POST test/result/pdf — returns the PDF report for a test result. */
|
|
214
212
|
async getResultPdf(userTestResultId) {
|
|
215
|
-
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID");
|
|
213
|
+
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID", "userTestResultId");
|
|
216
214
|
const request = {
|
|
217
215
|
Data: { UserTestResultId: resolvedUserTestResultId }
|
|
218
216
|
};
|
|
219
|
-
return this.
|
|
217
|
+
return this.execute(
|
|
220
218
|
"getResultPdf",
|
|
221
219
|
() => this.http.post(this.url("test/result/pdf"), request, this.getAuthHeaders())
|
|
222
220
|
);
|
|
@@ -226,11 +224,11 @@ var HCSafeCDXClient = class extends HCBaseConnector {
|
|
|
226
224
|
* Returns a URL to capture an image for the given test result.
|
|
227
225
|
*/
|
|
228
226
|
async getImageCaptureUrl(userTestResultId) {
|
|
229
|
-
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID");
|
|
227
|
+
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID", "userTestResultId");
|
|
230
228
|
const request = {
|
|
231
229
|
Data: { UserTestResultId: resolvedUserTestResultId }
|
|
232
230
|
};
|
|
233
|
-
return this.
|
|
231
|
+
return this.execute(
|
|
234
232
|
"getImageCaptureUrl",
|
|
235
233
|
() => this.http.post(this.url("test/result/image/capture"), request, this.getAuthHeaders())
|
|
236
234
|
);
|
|
@@ -240,18 +238,18 @@ var HCSafeCDXClient = class extends HCBaseConnector {
|
|
|
240
238
|
// -------------------------------------------------------------------------
|
|
241
239
|
/** POST test/resume */
|
|
242
240
|
async resumeFlow(userTestResultId, resumed = true) {
|
|
243
|
-
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID");
|
|
241
|
+
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID", "userTestResultId");
|
|
244
242
|
const request = {
|
|
245
243
|
Data: { UserTestResultId: resolvedUserTestResultId, Resumed: resumed }
|
|
246
244
|
};
|
|
247
|
-
return this.
|
|
245
|
+
return this.execute(
|
|
248
246
|
"resumeFlow",
|
|
249
247
|
() => this.http.post(this.url("test/resume"), request, this.getAuthHeaders())
|
|
250
248
|
);
|
|
251
249
|
}
|
|
252
250
|
/** POST test/answers */
|
|
253
251
|
async submitAnswers(submission) {
|
|
254
|
-
const resolvedId = this.requireValue(submission == null ? void 0 : submission.UserTestResultId, "User test result ID");
|
|
252
|
+
const resolvedId = this.requireValue(submission == null ? void 0 : submission.UserTestResultId, "User test result ID", "UserTestResultId");
|
|
255
253
|
if (!(submission == null ? void 0 : submission.Result) || submission.Result.length === 0) {
|
|
256
254
|
throw new ValidationError({
|
|
257
255
|
message: "At least one answer result is required.",
|
|
@@ -262,14 +260,14 @@ var HCSafeCDXClient = class extends HCBaseConnector {
|
|
|
262
260
|
const request = {
|
|
263
261
|
Data: { ...submission, UserTestResultId: resolvedId }
|
|
264
262
|
};
|
|
265
|
-
return this.
|
|
263
|
+
return this.execute(
|
|
266
264
|
"submitAnswers",
|
|
267
265
|
() => this.http.post(this.url("test/answers"), request, this.getAuthHeaders())
|
|
268
266
|
);
|
|
269
267
|
}
|
|
270
268
|
/** POST test/finalize */
|
|
271
269
|
async finalizeTest(userTestResultId) {
|
|
272
|
-
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID");
|
|
270
|
+
const resolvedUserTestResultId = this.requireValue(userTestResultId, "User test result ID", "userTestResultId");
|
|
273
271
|
const request = {
|
|
274
272
|
Data: { UserTestResultId: resolvedUserTestResultId }
|
|
275
273
|
};
|
|
@@ -281,38 +279,6 @@ var HCSafeCDXClient = class extends HCBaseConnector {
|
|
|
281
279
|
// -------------------------------------------------------------------------
|
|
282
280
|
// Private Helpers
|
|
283
281
|
// -------------------------------------------------------------------------
|
|
284
|
-
async executeSafe(operation, request) {
|
|
285
|
-
var _a;
|
|
286
|
-
let response;
|
|
287
|
-
try {
|
|
288
|
-
response = await request();
|
|
289
|
-
} catch (err) {
|
|
290
|
-
if (err instanceof APIError) throw err;
|
|
291
|
-
if (err instanceof Error) {
|
|
292
|
-
throw new APIError({ message: `${operation}: ${err.message}`, code: "UNKNOWN_ERROR", details: err });
|
|
293
|
-
}
|
|
294
|
-
throw new APIError({ message: `${operation}: unexpected runtime failure`, code: "UNKNOWN_ERROR", details: err });
|
|
295
|
-
}
|
|
296
|
-
if (response == null) {
|
|
297
|
-
throw new APIError({ message: `${operation}: empty response received`, code: "EMPTY_RESPONSE", details: response });
|
|
298
|
-
}
|
|
299
|
-
if (!this.isSafeApiResponse(response)) {
|
|
300
|
-
throw new APIError({ message: `${operation}: invalid SafeCDX response structure`, code: "INVALID_RESPONSE", details: response });
|
|
301
|
-
}
|
|
302
|
-
if (!response.success) {
|
|
303
|
-
throw new HCServiceError(
|
|
304
|
-
operation,
|
|
305
|
-
(_a = response.message) != null ? _a : "Backend returned success: false",
|
|
306
|
-
response
|
|
307
|
-
);
|
|
308
|
-
}
|
|
309
|
-
return response;
|
|
310
|
-
}
|
|
311
|
-
isSafeApiResponse(value) {
|
|
312
|
-
if (!value || typeof value !== "object") return false;
|
|
313
|
-
const r = value;
|
|
314
|
-
return "success" in r && typeof r.success === "boolean" && "data" in r && "message" in r && "code" in r && typeof r.code === "number";
|
|
315
|
-
}
|
|
316
282
|
getAuthHeaders() {
|
|
317
283
|
return { ...this.getHeaders(), ...this.auth.getAuthHeader() };
|
|
318
284
|
}
|
|
@@ -323,17 +289,17 @@ var HCSafeCDXClient = class extends HCBaseConnector {
|
|
|
323
289
|
|
|
324
290
|
// src/errors.ts
|
|
325
291
|
import {
|
|
326
|
-
APIError
|
|
292
|
+
APIError,
|
|
327
293
|
ConfigError as ConfigError2,
|
|
328
|
-
HCServiceError
|
|
294
|
+
HCServiceError,
|
|
329
295
|
NetworkError,
|
|
330
296
|
ValidationError as ValidationError2
|
|
331
297
|
} from "@healthcloudai/hc-http";
|
|
332
298
|
export {
|
|
333
|
-
|
|
299
|
+
APIError,
|
|
334
300
|
ConfigError2 as ConfigError,
|
|
335
301
|
HCSafeCDXClient,
|
|
336
|
-
|
|
302
|
+
HCServiceError,
|
|
337
303
|
NetworkError,
|
|
338
304
|
ValidationError2 as ValidationError
|
|
339
305
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@healthcloudai/hc-safe-cdx",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"description": "Healthcheck Safe CDX connector.",
|
|
5
5
|
"author": "Healthcheck Systems Inc",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,8 +33,8 @@
|
|
|
33
33
|
"prepublishOnly": "npm run build"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@healthcloudai/hc-http": "^0.2.
|
|
37
|
-
"@healthcloudai/hc-login-connector": "^0.3.
|
|
36
|
+
"@healthcloudai/hc-http": "^0.2.1",
|
|
37
|
+
"@healthcloudai/hc-login-connector": "^0.3.1"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
40
|
"react-native": ">=0.70.0"
|