@healthcloudai/hc-safe-cdx 0.2.0 → 0.2.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/dist/index.js CHANGED
@@ -32,10 +32,10 @@ function buildUrl(baseUrl, route, query) {
32
32
  return url.toString();
33
33
  }
34
34
  var HCSafeCDXClient = class {
35
- constructor(httpClient, authClient) {
35
+ constructor(httpClient, loginClient) {
36
36
  this.http = httpClient;
37
- this.auth = authClient;
38
- this.baseUrl = buildSafeCdxBaseUrl(authClient.getEnvironment());
37
+ this.loginClient = loginClient;
38
+ this.baseUrl = buildSafeCdxBaseUrl(loginClient.getEnvironment());
39
39
  }
40
40
  setApiKey(headerName, value) {
41
41
  const trimmedHeaderName = headerName == null ? void 0 : headerName.trim();
@@ -49,38 +49,12 @@ var HCSafeCDXClient = class {
49
49
  this.apiKeyHeaderName = trimmedHeaderName;
50
50
  this.apiKeyValue = trimmedValue;
51
51
  }
52
- // ---------------------------------------------------------------------------
53
- // Private helpers
54
- // ---------------------------------------------------------------------------
55
- getAuthHeaders() {
56
- return {
57
- ...this.auth.getAuthHeader(),
58
- ...this.getApiKeyHeader()
59
- };
60
- }
61
- getJsonHeaders() {
62
- return {
63
- ...this.getAuthHeaders(),
64
- "Content-Type": "application/json"
65
- };
66
- }
67
- getApiKeyHeader() {
68
- if (!this.apiKeyHeaderName || !this.apiKeyValue) {
69
- return {};
70
- }
71
- return {
72
- [this.apiKeyHeaderName]: this.apiKeyValue
73
- };
74
- }
75
- url(route, query) {
76
- return buildUrl(this.baseUrl, route, query);
77
- }
78
- // ---------------------------------------------------------------------------
79
- // Scan
80
- // ---------------------------------------------------------------------------
52
+ // -------------------------------------------------------------------------
53
+ // Test Profiles
54
+ // -------------------------------------------------------------------------
81
55
  /**
82
56
  * GET gs1/:gtin
83
- * Resolves a test profile by GTIN barcode and creates a UserTestResultId.
57
+ * Resolves the SafeCDX test profile associated with a GTIN barcode.
84
58
  */
85
59
  async getTestProfileByGTIN(gtin) {
86
60
  return this.http.get(
@@ -88,18 +62,17 @@ var HCSafeCDXClient = class {
88
62
  this.getAuthHeaders()
89
63
  );
90
64
  }
91
- // ---------------------------------------------------------------------------
92
- // Test Profiles
93
- // ---------------------------------------------------------------------------
94
65
  /**
95
- * POST test/profiles/by-account
96
- * Lists all test profiles available to the authenticated account.
97
- */
98
- async getTestProfilesByAccount(payload = {
99
- IncludeRegisterTestDetails: true
100
- }) {
66
+ * POST test/profiles/by-account
67
+
68
+ *
69
+ * TenantId is resolved by the backend from the authenticated patient context.
70
+ */
71
+ async getTestProfilesByAccount(includeRegisterTestDetails = true) {
101
72
  const request = {
102
- Data: payload
73
+ Data: {
74
+ IncludeRegisterTestDetails: includeRegisterTestDetails
75
+ }
103
76
  };
104
77
  return this.http.post(
105
78
  this.url("test/profiles/by-account"),
@@ -107,24 +80,22 @@ var HCSafeCDXClient = class {
107
80
  this.getJsonHeaders()
108
81
  );
109
82
  }
110
- // ---------------------------------------------------------------------------
111
- // Upload
112
- // ---------------------------------------------------------------------------
83
+ // -------------------------------------------------------------------------
84
+ // Image Upload
85
+ // -------------------------------------------------------------------------
113
86
  /**
114
87
  * POST upload/url
115
- * Requests a pre-signed S3 URL for image upload.
116
- * Use the returned Data.preSignedURL and Data.Metadata.UploadId in the next steps.
88
+ * Requests a pre-signed URL used to upload a test image.
117
89
  */
118
- async createUploadUrl(userTestResultId, gtin, imageType) {
119
- const payload = {
120
- Gtin: gtin,
121
- UserTestResultId: userTestResultId,
122
- Metadata: {
123
- ImageType: imageType != null ? imageType : "jpg"
124
- }
125
- };
90
+ async createUploadUrl(userTestResultId, gtin, imageType = "jpg") {
126
91
  const request = {
127
- Data: payload
92
+ Data: {
93
+ Gtin: gtin,
94
+ UserTestResultId: userTestResultId,
95
+ Metadata: {
96
+ ImageType: imageType
97
+ }
98
+ }
128
99
  };
129
100
  return this.http.post(
130
101
  this.url("upload/url"),
@@ -133,11 +104,11 @@ var HCSafeCDXClient = class {
133
104
  );
134
105
  }
135
106
  /**
136
- * PUT preSignedURL — direct S3 upload, not a SafeCDX API route.
137
- * preSignedURL comes from createUploadUrl() response: Data.preSignedURL.
107
+ * PUT preSignedURL
108
+ * Uploads the image directly to the pre-signed storage URL.
138
109
  *
139
- * This intentionally does not use the shared HttpClient because the existing
140
- * HttpClient.put() is JSON-oriented and stringifies the request body.
110
+ * This request does not call a SafeCDX API route and does not send
111
+ * authenticated Health Cloud headers.
141
112
  */
142
113
  async uploadImage(preSignedURL, image, contentType = "image/jpeg") {
143
114
  const response = await fetch(preSignedURL, {
@@ -152,200 +123,154 @@ var HCSafeCDXClient = class {
152
123
  try {
153
124
  body = (await response.text()).slice(0, 500);
154
125
  } catch {
126
+ body = void 0;
155
127
  }
156
- throw new SafeCDXError(
157
- `Image upload failed with HTTP ${response.status}.`,
158
- {
159
- status: response.status,
160
- body
161
- }
162
- );
128
+ throw new SafeCDXError(`Image upload failed with HTTP ${response.status}.`, {
129
+ status: response.status,
130
+ body
131
+ });
163
132
  }
164
133
  }
165
- // ---------------------------------------------------------------------------
134
+ // -------------------------------------------------------------------------
166
135
  // CVML
167
- // ---------------------------------------------------------------------------
136
+ // -------------------------------------------------------------------------
168
137
  /**
169
138
  * POST cvml/status
170
- * Updates the ML processing status for a captured image.
171
- * NOTE: Returns raw service result — no ApiResponse wrapper on this endpoint.
139
+ * Returns the direct SafeCDX response without an outer APIResponse wrapper.
172
140
  */
173
141
  async updateCvmlStatus(imageOfCaptureId, cvmlStatus) {
174
- const payload = {
175
- ImageOfCaptureId: imageOfCaptureId,
176
- CvmlStatus: cvmlStatus
177
- };
178
142
  const request = {
179
- Data: payload
143
+ Data: {
144
+ ImageOfCaptureId: imageOfCaptureId,
145
+ CvmlStatus: cvmlStatus
146
+ }
180
147
  };
181
- return this.http.post(
182
- this.url("cvml/status"),
183
- request,
184
- this.getJsonHeaders()
185
- );
148
+ return this.http.post(this.url("cvml/status"), request, this.getJsonHeaders());
186
149
  }
187
150
  /**
188
151
  * GET cvml/results
189
- * Polls ML analysis results for a captured image.
190
- * NOTE: Returns raw service result — no ApiResponse wrapper on this endpoint.
152
+ * Returns the direct SafeCDX response without an outer APIResponse wrapper.
191
153
  */
192
154
  async getCvmlResults(imageOfCaptureId) {
193
- return this.http.get(
194
- this.url("cvml/results", {
195
- imageOfCaptureId
196
- }),
197
- this.getAuthHeaders()
198
- );
155
+ return this.http.get(this.url("cvml/results", { imageOfCaptureId }), this.getAuthHeaders());
199
156
  }
200
- // ---------------------------------------------------------------------------
157
+ // -------------------------------------------------------------------------
201
158
  // Test Results
202
- // ---------------------------------------------------------------------------
203
- /**
204
- * POST test/result/pending
205
- * Returns test results in a pending/incomplete state.
206
- */
207
- async getPendingResults(payload = {
208
- ExcludeStatus: "Invalid,Canceled"
209
- }) {
159
+ // -------------------------------------------------------------------------
160
+ /** POST test/result/pending */
161
+ async getPendingResults(excludeStatus = "Invalid,Canceled") {
210
162
  const request = {
211
- Data: payload
163
+ Data: {
164
+ ExcludeStatus: excludeStatus
165
+ }
212
166
  };
213
- return this.http.post(
214
- this.url("test/result/pending"),
215
- request,
216
- this.getJsonHeaders()
217
- );
167
+ return this.http.post(this.url("test/result/pending"), request, this.getJsonHeaders());
218
168
  }
219
- /**
220
- * POST test/result/last
221
- * Returns the most recent test result for the authenticated patient.
222
- */
223
- async getLastResults(payload = {
224
- ExcludeStatus: "Invalid"
225
- }) {
169
+ /** POST test/result/last */
170
+ async getLastResults(excludeStatus = "Invalid") {
226
171
  const request = {
227
- Data: payload
172
+ Data: {
173
+ ExcludeStatus: excludeStatus
174
+ }
228
175
  };
229
- return this.http.post(
230
- this.url("test/result/last"),
231
- request,
232
- this.getJsonHeaders()
233
- );
176
+ return this.http.post(this.url("test/result/last"), request, this.getJsonHeaders());
234
177
  }
235
- /**
236
- * POST test/result/history
237
- * Returns the full test history for the authenticated patient.
238
- */
239
- async getTestHistory(payload = {
240
- ExcludeStatus: "Invalid"
241
- }) {
178
+ /** POST test/result/history */
179
+ async getTestHistory(excludeStatus = "Invalid") {
242
180
  const request = {
243
- Data: payload
181
+ Data: {
182
+ ExcludeStatus: excludeStatus
183
+ }
244
184
  };
245
- return this.http.post(
246
- this.url("test/result/history"),
247
- request,
248
- this.getJsonHeaders()
249
- );
185
+ return this.http.post(this.url("test/result/history"), request, this.getJsonHeaders());
250
186
  }
251
187
  /**
252
188
  * POST test/result/details
253
- * Returns detailed result data for a specific test attempt.
254
- * NOTE: Returns raw service result — no ApiResponse wrapper on this endpoint.
189
+ * Returns the direct SafeCDX response without an outer APIResponse wrapper.
255
190
  */
256
191
  async getResultDetails(userTestResultId) {
257
- const payload = {
258
- UserTestResultId: userTestResultId
259
- };
260
192
  const request = {
261
- Data: payload
193
+ Data: {
194
+ UserTestResultId: userTestResultId
195
+ }
262
196
  };
263
- return this.http.post(
264
- this.url("test/result/details"),
265
- request,
266
- this.getJsonHeaders()
267
- );
197
+ return this.http.post(this.url("test/result/details"), request, this.getJsonHeaders());
268
198
  }
269
- /**
270
- * POST test/result/pdf
271
- * Requests the PDF result for a specific test result.
272
- */
273
- async getResultPdf(payload) {
199
+ /** POST test/result/pdf */
200
+ async getResultPdf(userTestResultId) {
274
201
  const request = {
275
- Data: payload
202
+ Data: {
203
+ UserTestResultId: userTestResultId
204
+ }
276
205
  };
277
- return this.http.post(
278
- this.url("test/result/pdf"),
279
- request,
280
- this.getJsonHeaders()
281
- );
206
+ return this.http.post(this.url("test/result/pdf"), request, this.getJsonHeaders());
282
207
  }
283
208
  /**
284
209
  * POST test/result/image/capture
285
- * Requests image capture data for a specific test result.
286
- * NOTE: Returns raw service result — no ApiResponse wrapper on this endpoint.
210
+ * Returns the direct SafeCDX response without an outer APIResponse wrapper.
287
211
  */
288
212
  async getImageCaptureUrl(userTestResultId) {
289
- const payload = {
290
- UserTestResultId: userTestResultId
291
- };
292
213
  const request = {
293
- Data: payload
214
+ Data: {
215
+ UserTestResultId: userTestResultId
216
+ }
294
217
  };
295
- return this.http.post(
296
- this.url("test/result/image/capture"),
297
- request,
298
- this.getJsonHeaders()
299
- );
218
+ return this.http.post(this.url("test/result/image/capture"), request, this.getJsonHeaders());
300
219
  }
301
- // ---------------------------------------------------------------------------
220
+ // -------------------------------------------------------------------------
302
221
  // Resume / Answers / Finalize
303
- // ---------------------------------------------------------------------------
304
- /**
305
- * POST test/resume
306
- * Marks a test attempt as resumed (or not).
307
- */
222
+ // -------------------------------------------------------------------------
223
+ /** POST test/resume */
308
224
  async resumeFlow(userTestResultId, resumed = true) {
309
- const payload = {
310
- UserTestResultId: userTestResultId,
311
- Resumed: resumed
312
- };
313
225
  const request = {
314
- Data: payload
226
+ Data: {
227
+ UserTestResultId: userTestResultId,
228
+ Resumed: resumed
229
+ }
315
230
  };
316
- return this.http.post(
317
- this.url("test/resume"),
318
- request,
319
- this.getJsonHeaders()
320
- );
231
+ return this.http.post(this.url("test/resume"), request, this.getJsonHeaders());
321
232
  }
322
- /**
323
- * POST test/answers
324
- * Submits analyte answers for a test attempt.
325
- */
326
- async submitAnswers(payload) {
233
+ /** POST test/answers */
234
+ async submitAnswers(submission) {
327
235
  const request = {
328
- Data: payload
236
+ Data: submission
329
237
  };
330
- return this.http.post(
331
- this.url("test/answers"),
332
- request,
333
- this.getJsonHeaders()
334
- );
238
+ return this.http.post(this.url("test/answers"), request, this.getJsonHeaders());
335
239
  }
336
- /**
337
- * POST test/finalize
338
- * Finalizes a test by UserTestResultId.
339
- */
340
- async finalizeTest(payload) {
240
+ /** POST test/finalize */
241
+ async finalizeTest(userTestResultId) {
341
242
  const request = {
342
- Data: payload
243
+ Data: {
244
+ UserTestResultId: userTestResultId
245
+ }
343
246
  };
344
- return this.http.post(
345
- this.url("test/finalize"),
346
- request,
347
- this.getJsonHeaders()
348
- );
247
+ return this.http.post(this.url("test/finalize"), request, this.getJsonHeaders());
248
+ }
249
+ // -------------------------------------------------------------------------
250
+ // Private Helpers
251
+ // -------------------------------------------------------------------------
252
+ getAuthHeaders() {
253
+ return {
254
+ ...this.loginClient.getAuthHeader(),
255
+ ...this.getApiKeyHeader()
256
+ };
257
+ }
258
+ getJsonHeaders() {
259
+ return {
260
+ ...this.getAuthHeaders(),
261
+ "Content-Type": "application/json"
262
+ };
263
+ }
264
+ getApiKeyHeader() {
265
+ if (!this.apiKeyHeaderName || !this.apiKeyValue) {
266
+ return {};
267
+ }
268
+ return {
269
+ [this.apiKeyHeaderName]: this.apiKeyValue
270
+ };
271
+ }
272
+ url(route, query) {
273
+ return buildUrl(this.baseUrl, route, query);
349
274
  }
350
275
  };
351
276
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@healthcloudai/hc-safe-cdx",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Healthcheck Safe CDX connector.",
5
5
  "author": "Healthcheck Systems Inc",
6
6
  "license": "MIT",