@healthcloudai/hc-settings-connector 0.0.14 → 0.2.0

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 CHANGED
@@ -1,4 +1,3 @@
1
- ````md
2
1
  # Healthcheck Settings Connector
3
2
 
4
3
  This connector gives authenticated patients access to account information and document flows used in your application. It includes dashboard information, profile image management, identification document processing, insurance information, and account deactivation.
@@ -31,7 +30,7 @@ npm install @healthcloudai/hc-settings-connector \
31
30
  ## Import
32
31
 
33
32
  ```ts
34
- import { HCSupportClient } from "@healthcloudai/hc-settings-connector";
33
+ import { HCSettingsClient } from "@healthcloudai/hc-settings-connector";
35
34
  import { HCLoginClient } from "@healthcloudai/hc-login-connector";
36
35
  import { FetchClient } from "@healthcloudai/hc-http";
37
36
  ```
@@ -114,40 +113,59 @@ console.log(dashboard);
114
113
  {
115
114
  "Data": {
116
115
  "Record": {
117
- "Status": 0,
116
+ "Status": 1,
118
117
  "Sex": "Male",
119
118
  "GenderIdentity": "Male",
120
119
  "HasInsurance": true,
121
120
  "HasIDCard": true,
122
121
  "HasSelfie": true,
123
- "Flags": {
124
- "IsVerified": "true",
125
- "NeedsInsurance": "false"
126
- }
122
+ "Flags": null,
123
+ "FirstName": "John",
124
+ "LastName": "Smith",
125
+ "MiddleName": null,
126
+ "BirthDate": "1990-01-01T00:00:00",
127
+ "Email": "john.smith@example.com",
128
+ "Phone": "+15555550123",
129
+ "Gender": "Male",
130
+ "Race": "White",
131
+ "Ethnicity": "",
132
+ "CRMID": null,
133
+ "AppleUserId": null,
134
+ "Address": {
135
+ "StreetAndNumber": "1 Main St",
136
+ "Extension": null,
137
+ "City": "Springfield",
138
+ "State": "IL",
139
+ "PostalCode": "62701",
140
+ "Country": "US"
141
+ },
142
+ "Attributes": {
143
+ "AthenaPatientID": "patient-id-example",
144
+ "AthenaGuarantorFirstName": "John",
145
+ "AthenaGuarantorLastName": "Smith",
146
+ "AthenaCountryCode": "USA",
147
+ "AthenaDepartmentId": "1",
148
+ "AthenaEmailExists": "True",
149
+ "AthenaTestPatient": "False",
150
+ "PatientImageURL": "https://storage.example.com/selfie_example.jpg",
151
+ "CompositeID": "tenant-id/john.smith@example.com",
152
+ "Insurance": "EXAMPLE INSURANCE"
153
+ },
154
+ "CompositeID": "tenant-id/john.smith@example.com",
155
+ "FHIRID": "fhir-id-example",
156
+ "AthenaID": "patient-id-example",
157
+ "Created": "0001-01-01T00:00:00",
158
+ "Modified": "0001-01-01T00:00:00",
159
+ "CreatedByID": null,
160
+ "ModifiedByID": null,
161
+ "IsDeactivated": false,
162
+ "TenantID": "test-tenant",
163
+ "ID": "record-uuid-example"
127
164
  },
128
- "Encounters": [
129
- {
130
- "FHIRID": "test-fhir-id-001",
131
- "AthenaID": "test-athena-id-001",
132
- "Status": 0,
133
- "Patient": null,
134
- "EncounterClass": "ambulatory",
135
- "EHR": "athena",
136
- "EHRType": "Athena Health",
137
- "EHRVisitName": "Office Visit",
138
- "EHRAppointmentID": "test-appointment-id-001",
139
- "EHRProviderID": "test-provider-id-001",
140
- "EHRProviderName": "Test Provider",
141
- "EHRDate": "04/22/2026",
142
- "EHRStatus": "Finished",
143
- "EHRStage": "completed"
144
- }
145
- ],
165
+ "Encounters": null,
146
166
  "EHR": "athena",
147
167
  "PendingActions": [
148
- "ADD_INSURANCE",
149
- "ADD_ID",
150
- "IMPORT_VITALS"
168
+ "TAKE_TEST"
151
169
  ]
152
170
  },
153
171
  "IsOK": true,
@@ -567,14 +585,14 @@ console.log(response);
567
585
  Public signature:
568
586
 
569
587
  ```ts
570
- settingsClient.getInsurances()
588
+ settingsClient.listInsurances()
571
589
  ```
572
590
 
573
591
  Returns insurance records associated with the authenticated patient.
574
592
 
575
593
  ```ts
576
594
  const insurances =
577
- await settingsClient.getInsurances();
595
+ await settingsClient.listInsurances();
578
596
 
579
597
  console.log(insurances);
580
598
  ```
@@ -711,3 +729,56 @@ console.log(response);
711
729
 
712
730
  ```
713
731
  ```
732
+
733
+
734
+ ---
735
+
736
+ ## Prerequisites
737
+
738
+ `HCLoginClient` must be configured and the patient must be logged in before calling any method on this connector.
739
+
740
+ ```ts
741
+ import { HCLoginClient } from "@healthcloudai/hc-login-connector";
742
+ import { FetchClient } from "@healthcloudai/hc-http";
743
+
744
+ const httpClient = new FetchClient();
745
+ const loginClient = new HCLoginClient(httpClient);
746
+
747
+ loginClient.configure("healthcheck", "dev");
748
+ await loginClient.login("patient@example.com", "ExamplePassword123!");
749
+ ```
750
+
751
+ See the [hc-login-connector](../hc-login-connector) documentation for the full authentication flow.
752
+
753
+ ---
754
+
755
+ ## Error Handling
756
+
757
+ All methods throw errors that extend `APIError` from `@healthcloudai/hc-http`.
758
+
759
+ Backend business failures (`IsOK: false`) are thrown as `HCServiceError`.
760
+
761
+ ```ts
762
+ import { HCServiceError, APIError } from "@healthcloudai/hc-http";
763
+
764
+ try {
765
+ const result = await client.someMethod();
766
+ } catch (err) {
767
+ if (err instanceof HCServiceError) {
768
+ console.error("Backend error:", err.backendMessage);
769
+ } else if (err instanceof APIError) {
770
+ console.error("SDK error:", err.message, err.code);
771
+ }
772
+ }
773
+ ```
774
+
775
+
776
+ ---
777
+
778
+ ## getDashboard vs getPatientHeader
779
+
780
+ `HCSettingsClient.getDashboard()` calls `/api/patient/dashboard` and returns a full patient dashboard including record, encounters, EHR type, and pending actions.
781
+
782
+ `HCLoginClient.getPatientHeader()` calls `/api/patient/header` and returns a lighter patient header used after login to quickly check patient state.
783
+
784
+ These are different endpoints returning different data shapes. Neither is a duplicate of the other.
package/dist/index.cjs CHANGED
@@ -20,277 +20,253 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- AuthError: () => AuthError,
24
- ConfigError: () => ConfigError,
23
+ APIError: () => import_hc_http2.APIError,
24
+ ConfigError: () => import_hc_http2.ConfigError,
25
+ HCServiceError: () => import_hc_http2.HCServiceError,
25
26
  HCSettingsClient: () => HCSettingsClient,
26
- HttpError: () => HttpError,
27
- UserStatus: () => UserStatus
27
+ NetworkError: () => import_hc_http2.NetworkError,
28
+ UserStatus: () => UserStatus,
29
+ ValidationError: () => import_hc_http2.ValidationError
28
30
  });
29
31
  module.exports = __toCommonJS(index_exports);
30
32
 
31
- // src/errors.ts
32
- var ConfigError = class extends Error {
33
- constructor(message) {
34
- super(message);
35
- this.name = "ConfigError";
36
- }
37
- };
38
- var AuthError = class extends Error {
39
- constructor(message) {
40
- super(message);
41
- this.name = "AuthError";
42
- }
43
- };
44
- var HttpError = class extends Error {
45
- constructor(status, message) {
46
- super(message);
47
- this.name = "HttpError";
48
- this.status = status;
49
- }
50
- };
51
-
52
33
  // src/client.ts
53
- var HCSettingsClient = class {
34
+ var import_hc_http = require("@healthcloudai/hc-http");
35
+ var HCSettingsClient = class extends import_hc_http.HCBaseConnector {
54
36
  constructor(httpClient, loginClient) {
55
- this.httpClient = httpClient;
56
- this.loginClient = loginClient;
57
- }
58
- setApiKey(headerName, value) {
59
- const trimmedHeaderName = headerName == null ? void 0 : headerName.trim();
60
- const trimmedValue = value == null ? void 0 : value.trim();
61
- if (!trimmedHeaderName) {
62
- throw new ConfigError(
63
- "API key header name is required."
64
- );
65
- }
66
- if (!trimmedValue) {
67
- throw new ConfigError(
68
- "API key value is required."
69
- );
70
- }
71
- this.apiKeyHeaderName = trimmedHeaderName;
72
- this.apiKeyValue = trimmedValue;
37
+ super(httpClient);
38
+ this.auth = loginClient;
73
39
  }
74
40
  // ===========================================================================
75
41
  // Dashboard
76
42
  // ===========================================================================
43
+ /**
44
+ * Returns the patient dashboard including record, encounters, and pending actions.
45
+ */
77
46
  async getDashboard() {
78
- return this.httpClient.get(
79
- `${this.getBaseUrl()}/patient/dashboard`,
80
- this.getAuthHeaders()
47
+ return this.execute(
48
+ "getDashboard",
49
+ () => this.http.get(
50
+ `${this.auth.getBaseUrl()}/api/patient/dashboard`,
51
+ this.getAuthHeaders()
52
+ )
81
53
  );
82
54
  }
83
55
  // ===========================================================================
84
56
  // User image
85
57
  // ===========================================================================
58
+ /**
59
+ * Returns a canned (pre-signed) URL for uploading the patient profile image.
60
+ * Extension must be a valid file extension such as "jpg" or "png".
61
+ */
86
62
  async getUserImageCannedUrl(extension) {
87
- const resolvedExtension = this.requireValue(
88
- extension,
89
- "extension"
90
- );
63
+ const resolvedExtension = this.requireValue(extension, "Extension");
91
64
  const requestPayload = {
92
- Data: {
93
- Extension: resolvedExtension
94
- }
65
+ Data: { Extension: resolvedExtension }
95
66
  };
96
- return this.httpClient.put(
97
- `${this.getBaseUrl()}/patient/image/cannedurl`,
98
- requestPayload,
99
- this.getJsonHeaders()
67
+ return this.execute(
68
+ "getUserImageCannedUrl",
69
+ () => this.http.put(
70
+ `${this.auth.getBaseUrl()}/api/patient/image/cannedurl`,
71
+ requestPayload,
72
+ this.getAuthHeaders()
73
+ )
100
74
  );
101
75
  }
76
+ /**
77
+ * Updates the patient's profile image by confirming the uploaded file name.
78
+ */
102
79
  async updateUserImage(fileName) {
103
- const resolvedFileName = this.requireValue(
104
- fileName,
105
- "fileName"
106
- );
80
+ const resolvedFileName = this.requireValue(fileName, "File name");
107
81
  const requestPayload = {
108
- Data: {
109
- FileName: resolvedFileName
110
- }
82
+ Data: { FileName: resolvedFileName }
111
83
  };
112
- return this.httpClient.put(
113
- `${this.getBaseUrl()}/patient/image/url`,
114
- requestPayload,
115
- this.getJsonHeaders()
84
+ return this.execute(
85
+ "updateUserImage",
86
+ () => this.http.put(
87
+ `${this.auth.getBaseUrl()}/api/patient/image/url`,
88
+ requestPayload,
89
+ this.getAuthHeaders()
90
+ )
116
91
  );
117
92
  }
118
93
  // ===========================================================================
119
94
  // Identification
120
95
  // ===========================================================================
96
+ /**
97
+ * Returns a canned URL for uploading the patient's driving licence image.
98
+ */
121
99
  async getDrivingLicenseCannedUrl(extension) {
122
- const resolvedExtension = this.requireValue(
123
- extension,
124
- "extension"
125
- );
100
+ const resolvedExtension = this.requireValue(extension, "Extension");
126
101
  const requestPayload = {
127
- Data: {
128
- Extension: resolvedExtension
129
- }
102
+ Data: { Extension: resolvedExtension }
130
103
  };
131
- return this.httpClient.put(
132
- `${this.getBaseUrl()}/patient/id/cannedurl`,
133
- requestPayload,
134
- this.getJsonHeaders()
104
+ return this.execute(
105
+ "getDrivingLicenseCannedUrl",
106
+ () => this.http.put(
107
+ `${this.auth.getBaseUrl()}/api/patient/id/cannedurl`,
108
+ requestPayload,
109
+ this.getAuthHeaders()
110
+ )
135
111
  );
136
112
  }
113
+ /**
114
+ * Submits a driving licence file for OCR capture.
115
+ * fileKey is the storage key of the uploaded image.
116
+ */
137
117
  async captureDrivingLicense(fileKey) {
138
- const resolvedFileKey = this.requireValue(
139
- fileKey,
140
- "fileKey"
141
- );
118
+ const resolvedFileKey = this.requireValue(fileKey, "File key");
142
119
  const requestPayload = {
143
- Data: {
144
- Type: "identification",
145
- FileID: resolvedFileKey
146
- }
120
+ Data: { Type: "identification", FileID: resolvedFileKey }
147
121
  };
148
- return this.httpClient.post(
149
- `${this.getBaseUrl()}/patient/capture`,
150
- requestPayload,
151
- this.getJsonHeaders()
122
+ return this.execute(
123
+ "captureDrivingLicense",
124
+ () => this.http.post(
125
+ `${this.auth.getBaseUrl()}/api/patient/capture`,
126
+ requestPayload,
127
+ this.getAuthHeaders()
128
+ )
152
129
  );
153
130
  }
131
+ /**
132
+ * Submits a base64-encoded driving licence image to the EHR.
133
+ */
154
134
  async submitDrivingLicense(image) {
155
- const resolvedImage = this.requireValue(
156
- image,
157
- "image"
158
- );
135
+ const resolvedImage = this.requireValue(image, "Image");
159
136
  const requestPayload = {
160
- Data: {
161
- Image: resolvedImage
162
- }
137
+ Data: { Image: resolvedImage }
163
138
  };
164
- return this.httpClient.put(
165
- `${this.getBaseUrl()}/ehr/patient/drivinglicense`,
166
- requestPayload,
167
- this.getJsonHeaders()
139
+ return this.execute(
140
+ "submitDrivingLicense",
141
+ () => this.http.put(
142
+ `${this.auth.getBaseUrl()}/api/ehr/patient/drivinglicense`,
143
+ requestPayload,
144
+ this.getAuthHeaders()
145
+ )
168
146
  );
169
147
  }
170
148
  // ===========================================================================
171
149
  // Insurance
172
150
  // ===========================================================================
151
+ /**
152
+ * Returns a canned URL for uploading the insurance card image.
153
+ */
173
154
  async getInsuranceCannedUrl(extension) {
174
- const resolvedExtension = this.requireValue(
175
- extension,
176
- "extension"
177
- );
155
+ const resolvedExtension = this.requireValue(extension, "Extension");
178
156
  const requestPayload = {
179
- Data: {
180
- Extension: resolvedExtension
181
- }
157
+ Data: { Extension: resolvedExtension }
182
158
  };
183
- return this.httpClient.put(
184
- `${this.getBaseUrl()}/patient/insurance/cannedurl`,
185
- requestPayload,
186
- this.getJsonHeaders()
159
+ return this.execute(
160
+ "getInsuranceCannedUrl",
161
+ () => this.http.put(
162
+ `${this.auth.getBaseUrl()}/api/patient/insurance/cannedurl`,
163
+ requestPayload,
164
+ this.getAuthHeaders()
165
+ )
187
166
  );
188
167
  }
168
+ /**
169
+ * Submits an insurance card image for OCR capture.
170
+ * fileKey is the storage key of the uploaded image.
171
+ */
189
172
  async captureInsurance(fileKey) {
190
- const resolvedFileKey = this.requireValue(
191
- fileKey,
192
- "fileKey"
193
- );
173
+ const resolvedFileKey = this.requireValue(fileKey, "File key");
194
174
  const requestPayload = {
195
- Data: {
196
- Type: "healthinsurance",
197
- FileID: resolvedFileKey
198
- }
175
+ Data: { Type: "healthinsurance", FileID: resolvedFileKey }
199
176
  };
200
- return this.httpClient.post(
201
- `${this.getBaseUrl()}/patient/capture`,
202
- requestPayload,
203
- this.getJsonHeaders()
177
+ return this.execute(
178
+ "captureInsurance",
179
+ () => this.http.post(
180
+ `${this.auth.getBaseUrl()}/api/patient/capture`,
181
+ requestPayload,
182
+ this.getAuthHeaders()
183
+ )
204
184
  );
205
185
  }
186
+ /**
187
+ * Creates or updates the patient's insurance coverage record.
188
+ */
206
189
  async submitInsurance(coverage) {
207
190
  if (!coverage) {
208
- throw new ConfigError(
209
- "Insurance coverage data is required."
210
- );
191
+ throw new import_hc_http.ValidationError({
192
+ message: "Insurance coverage data is required.",
193
+ code: "INVALID_INPUT",
194
+ param: "coverage"
195
+ });
211
196
  }
212
197
  const requestPayload = {
213
198
  Data: coverage
214
199
  };
215
- return this.httpClient.put(
216
- `${this.getBaseUrl()}/patient/coverage`,
217
- requestPayload,
218
- this.getJsonHeaders()
200
+ return this.execute(
201
+ "submitInsurance",
202
+ () => this.http.put(
203
+ `${this.auth.getBaseUrl()}/api/patient/coverage`,
204
+ requestPayload,
205
+ this.getAuthHeaders()
206
+ )
219
207
  );
220
208
  }
221
- async getInsurances() {
222
- return this.httpClient.get(
223
- `${this.getBaseUrl()}/ehr/patient/insurances`,
224
- this.getAuthHeaders()
209
+ /**
210
+ * Returns all insurance records for the authenticated patient.
211
+ */
212
+ async listInsurances() {
213
+ return this.execute(
214
+ "listInsurances",
215
+ () => this.http.get(
216
+ `${this.auth.getBaseUrl()}/api/ehr/patient/insurances`,
217
+ this.getAuthHeaders()
218
+ )
225
219
  );
226
220
  }
227
221
  // ===========================================================================
228
222
  // User photo capture
229
223
  // ===========================================================================
224
+ /**
225
+ * Submits a user photo (selfie) for capture.
226
+ * fileKey is the storage key of the uploaded image.
227
+ */
230
228
  async captureUserPhoto(fileKey) {
231
- const resolvedFileKey = this.requireValue(
232
- fileKey,
233
- "fileKey"
234
- );
229
+ const resolvedFileKey = this.requireValue(fileKey, "File key");
235
230
  const requestPayload = {
236
- Data: {
237
- Type: "userphoto",
238
- FileID: resolvedFileKey
239
- }
231
+ Data: { Type: "userphoto", FileID: resolvedFileKey }
240
232
  };
241
- return this.httpClient.post(
242
- `${this.getBaseUrl()}/patient/capture`,
243
- requestPayload,
244
- this.getJsonHeaders()
233
+ return this.execute(
234
+ "captureUserPhoto",
235
+ () => this.http.post(
236
+ `${this.auth.getBaseUrl()}/api/patient/capture`,
237
+ requestPayload,
238
+ this.getAuthHeaders()
239
+ )
245
240
  );
246
241
  }
247
242
  // ===========================================================================
248
243
  // Account
249
244
  // ===========================================================================
250
- async deactivateUser() {
251
- return this.httpClient.put(
252
- `${this.getBaseUrl()}/patient/deactivate`,
253
- void 0,
254
- this.getJsonHeaders()
245
+ /**
246
+ * Soft-deactivates the current patient account.
247
+ * The patient record is not permanently deleted.
248
+ */
249
+ async deactivateCurrentPatient() {
250
+ return this.execute(
251
+ "deactivateCurrentPatient",
252
+ () => this.http.put(
253
+ `${this.auth.getBaseUrl()}/api/patient/deactivate`,
254
+ void 0,
255
+ this.getAuthHeaders()
256
+ )
255
257
  );
256
258
  }
257
259
  // ===========================================================================
258
- // Helpers
260
+ // Private
259
261
  // ===========================================================================
260
- getBaseUrl() {
261
- return this.loginClient.getBaseUrl();
262
- }
263
262
  getAuthHeaders() {
264
- return {
265
- ...this.loginClient.getAuthHeader(),
266
- ...this.getApiKeyHeader()
267
- };
268
- }
269
- getJsonHeaders() {
270
- return {
271
- ...this.getAuthHeaders(),
272
- "Content-Type": "application/json"
273
- };
274
- }
275
- getApiKeyHeader() {
276
- if (!this.apiKeyHeaderName || !this.apiKeyValue) {
277
- return {};
278
- }
279
- return {
280
- [this.apiKeyHeaderName]: this.apiKeyValue
281
- };
282
- }
283
- requireValue(value, parameterName) {
284
- const trimmedValue = value == null ? void 0 : value.trim();
285
- if (!trimmedValue) {
286
- throw new ConfigError(
287
- `${parameterName} is required.`
288
- );
289
- }
290
- return trimmedValue;
263
+ return { ...this.getHeaders(), ...this.auth.getAuthHeader() };
291
264
  }
292
265
  };
293
266
 
267
+ // src/errors.ts
268
+ var import_hc_http2 = require("@healthcloudai/hc-http");
269
+
294
270
  // src/types.ts
295
271
  var UserStatus = /* @__PURE__ */ ((UserStatus2) => {
296
272
  UserStatus2[UserStatus2["INACTIVE"] = 0] = "INACTIVE";
@@ -300,9 +276,11 @@ var UserStatus = /* @__PURE__ */ ((UserStatus2) => {
300
276
  })(UserStatus || {});
301
277
  // Annotate the CommonJS export names for ESM import in node:
302
278
  0 && (module.exports = {
303
- AuthError,
279
+ APIError,
304
280
  ConfigError,
281
+ HCServiceError,
305
282
  HCSettingsClient,
306
- HttpError,
307
- UserStatus
283
+ NetworkError,
284
+ UserStatus,
285
+ ValidationError
308
286
  });
package/dist/index.d.cts CHANGED
@@ -1,14 +1,7 @@
1
1
  import { HCLoginClient } from '@healthcloudai/hc-login-connector';
2
- import { HttpClient } from '@healthcloudai/hc-http';
2
+ import { HCBaseConnector, HttpClient, APIResponse } from '@healthcloudai/hc-http';
3
+ export { APIError, APIResponse, ConfigError, HCServiceError, NetworkError, ValidationError } from '@healthcloudai/hc-http';
3
4
 
4
- interface APIRequest<T> {
5
- Data: T;
6
- }
7
- interface APIResponse<T> {
8
- Data: T | null;
9
- IsOK: boolean;
10
- ErrorMessage: string | null;
11
- }
12
5
  interface UserImage {
13
6
  ImageURL: string | null;
14
7
  FileName: string | null;
@@ -120,41 +113,63 @@ interface InsuranceRecord {
120
113
  Image?: string | null;
121
114
  }
122
115
 
123
- declare class HCSettingsClient {
124
- private readonly httpClient;
125
- private readonly loginClient;
126
- private apiKeyHeaderName?;
127
- private apiKeyValue?;
116
+ declare class HCSettingsClient extends HCBaseConnector {
117
+ private readonly auth;
128
118
  constructor(httpClient: HttpClient, loginClient: HCLoginClient);
129
- setApiKey(headerName: string, value: string): void;
119
+ /**
120
+ * Returns the patient dashboard including record, encounters, and pending actions.
121
+ */
130
122
  getDashboard(): Promise<APIResponse<PatientDashboard>>;
123
+ /**
124
+ * Returns a canned (pre-signed) URL for uploading the patient profile image.
125
+ * Extension must be a valid file extension such as "jpg" or "png".
126
+ */
131
127
  getUserImageCannedUrl(extension: string): Promise<APIResponse<UserImage>>;
128
+ /**
129
+ * Updates the patient's profile image by confirming the uploaded file name.
130
+ */
132
131
  updateUserImage(fileName: string): Promise<APIResponse<boolean>>;
132
+ /**
133
+ * Returns a canned URL for uploading the patient's driving licence image.
134
+ */
133
135
  getDrivingLicenseCannedUrl(extension: string): Promise<APIResponse<UserImage>>;
136
+ /**
137
+ * Submits a driving licence file for OCR capture.
138
+ * fileKey is the storage key of the uploaded image.
139
+ */
134
140
  captureDrivingLicense(fileKey: string): Promise<APIResponse<CaptureResult<IdentificationCaptureData>>>;
141
+ /**
142
+ * Submits a base64-encoded driving licence image to the EHR.
143
+ */
135
144
  submitDrivingLicense(image: string): Promise<APIResponse<string>>;
145
+ /**
146
+ * Returns a canned URL for uploading the insurance card image.
147
+ */
136
148
  getInsuranceCannedUrl(extension: string): Promise<APIResponse<UserImage>>;
149
+ /**
150
+ * Submits an insurance card image for OCR capture.
151
+ * fileKey is the storage key of the uploaded image.
152
+ */
137
153
  captureInsurance(fileKey: string): Promise<APIResponse<CaptureResult<InsuranceCaptureData>>>;
154
+ /**
155
+ * Creates or updates the patient's insurance coverage record.
156
+ */
138
157
  submitInsurance(coverage: CoverageData): Promise<APIResponse<InsuranceRecord>>;
139
- getInsurances(): Promise<APIResponse<InsuranceRecord[]>>;
158
+ /**
159
+ * Returns all insurance records for the authenticated patient.
160
+ */
161
+ listInsurances(): Promise<APIResponse<InsuranceRecord[]>>;
162
+ /**
163
+ * Submits a user photo (selfie) for capture.
164
+ * fileKey is the storage key of the uploaded image.
165
+ */
140
166
  captureUserPhoto(fileKey: string): Promise<APIResponse<CaptureResult<UserPhotoCaptureData>>>;
141
- deactivateUser(): Promise<APIResponse<boolean>>;
142
- private getBaseUrl;
167
+ /**
168
+ * Soft-deactivates the current patient account.
169
+ * The patient record is not permanently deleted.
170
+ */
171
+ deactivateCurrentPatient(): Promise<APIResponse<boolean>>;
143
172
  private getAuthHeaders;
144
- private getJsonHeaders;
145
- private getApiKeyHeader;
146
- private requireValue;
147
- }
148
-
149
- declare class ConfigError extends Error {
150
- constructor(message: string);
151
- }
152
- declare class AuthError extends Error {
153
- constructor(message: string);
154
- }
155
- declare class HttpError extends Error {
156
- status: number;
157
- constructor(status: number, message: string);
158
173
  }
159
174
 
160
- export { type APIRequest, type APIResponse, AuthError, type CaptureResult, type CaptureType, ConfigError, type CoverageData, type Encounter, HCSettingsClient, HttpError, type IdentificationCaptureData, type InsuranceCaptureData, type InsuranceRecord, type PatientDashboard, type PatientRecord, type UserImage, type UserPhotoCaptureData, UserStatus };
175
+ export { type CaptureResult, type CaptureType, type CoverageData, type Encounter, HCSettingsClient, type IdentificationCaptureData, type InsuranceCaptureData, type InsuranceRecord, type PatientDashboard, type PatientRecord, type UserImage, type UserPhotoCaptureData, UserStatus };
package/dist/index.d.ts CHANGED
@@ -1,14 +1,7 @@
1
1
  import { HCLoginClient } from '@healthcloudai/hc-login-connector';
2
- import { HttpClient } from '@healthcloudai/hc-http';
2
+ import { HCBaseConnector, HttpClient, APIResponse } from '@healthcloudai/hc-http';
3
+ export { APIError, APIResponse, ConfigError, HCServiceError, NetworkError, ValidationError } from '@healthcloudai/hc-http';
3
4
 
4
- interface APIRequest<T> {
5
- Data: T;
6
- }
7
- interface APIResponse<T> {
8
- Data: T | null;
9
- IsOK: boolean;
10
- ErrorMessage: string | null;
11
- }
12
5
  interface UserImage {
13
6
  ImageURL: string | null;
14
7
  FileName: string | null;
@@ -120,41 +113,63 @@ interface InsuranceRecord {
120
113
  Image?: string | null;
121
114
  }
122
115
 
123
- declare class HCSettingsClient {
124
- private readonly httpClient;
125
- private readonly loginClient;
126
- private apiKeyHeaderName?;
127
- private apiKeyValue?;
116
+ declare class HCSettingsClient extends HCBaseConnector {
117
+ private readonly auth;
128
118
  constructor(httpClient: HttpClient, loginClient: HCLoginClient);
129
- setApiKey(headerName: string, value: string): void;
119
+ /**
120
+ * Returns the patient dashboard including record, encounters, and pending actions.
121
+ */
130
122
  getDashboard(): Promise<APIResponse<PatientDashboard>>;
123
+ /**
124
+ * Returns a canned (pre-signed) URL for uploading the patient profile image.
125
+ * Extension must be a valid file extension such as "jpg" or "png".
126
+ */
131
127
  getUserImageCannedUrl(extension: string): Promise<APIResponse<UserImage>>;
128
+ /**
129
+ * Updates the patient's profile image by confirming the uploaded file name.
130
+ */
132
131
  updateUserImage(fileName: string): Promise<APIResponse<boolean>>;
132
+ /**
133
+ * Returns a canned URL for uploading the patient's driving licence image.
134
+ */
133
135
  getDrivingLicenseCannedUrl(extension: string): Promise<APIResponse<UserImage>>;
136
+ /**
137
+ * Submits a driving licence file for OCR capture.
138
+ * fileKey is the storage key of the uploaded image.
139
+ */
134
140
  captureDrivingLicense(fileKey: string): Promise<APIResponse<CaptureResult<IdentificationCaptureData>>>;
141
+ /**
142
+ * Submits a base64-encoded driving licence image to the EHR.
143
+ */
135
144
  submitDrivingLicense(image: string): Promise<APIResponse<string>>;
145
+ /**
146
+ * Returns a canned URL for uploading the insurance card image.
147
+ */
136
148
  getInsuranceCannedUrl(extension: string): Promise<APIResponse<UserImage>>;
149
+ /**
150
+ * Submits an insurance card image for OCR capture.
151
+ * fileKey is the storage key of the uploaded image.
152
+ */
137
153
  captureInsurance(fileKey: string): Promise<APIResponse<CaptureResult<InsuranceCaptureData>>>;
154
+ /**
155
+ * Creates or updates the patient's insurance coverage record.
156
+ */
138
157
  submitInsurance(coverage: CoverageData): Promise<APIResponse<InsuranceRecord>>;
139
- getInsurances(): Promise<APIResponse<InsuranceRecord[]>>;
158
+ /**
159
+ * Returns all insurance records for the authenticated patient.
160
+ */
161
+ listInsurances(): Promise<APIResponse<InsuranceRecord[]>>;
162
+ /**
163
+ * Submits a user photo (selfie) for capture.
164
+ * fileKey is the storage key of the uploaded image.
165
+ */
140
166
  captureUserPhoto(fileKey: string): Promise<APIResponse<CaptureResult<UserPhotoCaptureData>>>;
141
- deactivateUser(): Promise<APIResponse<boolean>>;
142
- private getBaseUrl;
167
+ /**
168
+ * Soft-deactivates the current patient account.
169
+ * The patient record is not permanently deleted.
170
+ */
171
+ deactivateCurrentPatient(): Promise<APIResponse<boolean>>;
143
172
  private getAuthHeaders;
144
- private getJsonHeaders;
145
- private getApiKeyHeader;
146
- private requireValue;
147
- }
148
-
149
- declare class ConfigError extends Error {
150
- constructor(message: string);
151
- }
152
- declare class AuthError extends Error {
153
- constructor(message: string);
154
- }
155
- declare class HttpError extends Error {
156
- status: number;
157
- constructor(status: number, message: string);
158
173
  }
159
174
 
160
- export { type APIRequest, type APIResponse, AuthError, type CaptureResult, type CaptureType, ConfigError, type CoverageData, type Encounter, HCSettingsClient, HttpError, type IdentificationCaptureData, type InsuranceCaptureData, type InsuranceRecord, type PatientDashboard, type PatientRecord, type UserImage, type UserPhotoCaptureData, UserStatus };
175
+ export { type CaptureResult, type CaptureType, type CoverageData, type Encounter, HCSettingsClient, type IdentificationCaptureData, type InsuranceCaptureData, type InsuranceRecord, type PatientDashboard, type PatientRecord, type UserImage, type UserPhotoCaptureData, UserStatus };
package/dist/index.js CHANGED
@@ -1,266 +1,246 @@
1
- // src/errors.ts
2
- var ConfigError = class extends Error {
3
- constructor(message) {
4
- super(message);
5
- this.name = "ConfigError";
6
- }
7
- };
8
- var AuthError = class extends Error {
9
- constructor(message) {
10
- super(message);
11
- this.name = "AuthError";
12
- }
13
- };
14
- var HttpError = class extends Error {
15
- constructor(status, message) {
16
- super(message);
17
- this.name = "HttpError";
18
- this.status = status;
19
- }
20
- };
21
-
22
1
  // src/client.ts
23
- var HCSettingsClient = class {
2
+ import { HCBaseConnector, ValidationError } from "@healthcloudai/hc-http";
3
+ var HCSettingsClient = class extends HCBaseConnector {
24
4
  constructor(httpClient, loginClient) {
25
- this.httpClient = httpClient;
26
- this.loginClient = loginClient;
27
- }
28
- setApiKey(headerName, value) {
29
- const trimmedHeaderName = headerName == null ? void 0 : headerName.trim();
30
- const trimmedValue = value == null ? void 0 : value.trim();
31
- if (!trimmedHeaderName) {
32
- throw new ConfigError(
33
- "API key header name is required."
34
- );
35
- }
36
- if (!trimmedValue) {
37
- throw new ConfigError(
38
- "API key value is required."
39
- );
40
- }
41
- this.apiKeyHeaderName = trimmedHeaderName;
42
- this.apiKeyValue = trimmedValue;
5
+ super(httpClient);
6
+ this.auth = loginClient;
43
7
  }
44
8
  // ===========================================================================
45
9
  // Dashboard
46
10
  // ===========================================================================
11
+ /**
12
+ * Returns the patient dashboard including record, encounters, and pending actions.
13
+ */
47
14
  async getDashboard() {
48
- return this.httpClient.get(
49
- `${this.getBaseUrl()}/patient/dashboard`,
50
- this.getAuthHeaders()
15
+ return this.execute(
16
+ "getDashboard",
17
+ () => this.http.get(
18
+ `${this.auth.getBaseUrl()}/api/patient/dashboard`,
19
+ this.getAuthHeaders()
20
+ )
51
21
  );
52
22
  }
53
23
  // ===========================================================================
54
24
  // User image
55
25
  // ===========================================================================
26
+ /**
27
+ * Returns a canned (pre-signed) URL for uploading the patient profile image.
28
+ * Extension must be a valid file extension such as "jpg" or "png".
29
+ */
56
30
  async getUserImageCannedUrl(extension) {
57
- const resolvedExtension = this.requireValue(
58
- extension,
59
- "extension"
60
- );
31
+ const resolvedExtension = this.requireValue(extension, "Extension");
61
32
  const requestPayload = {
62
- Data: {
63
- Extension: resolvedExtension
64
- }
33
+ Data: { Extension: resolvedExtension }
65
34
  };
66
- return this.httpClient.put(
67
- `${this.getBaseUrl()}/patient/image/cannedurl`,
68
- requestPayload,
69
- this.getJsonHeaders()
35
+ return this.execute(
36
+ "getUserImageCannedUrl",
37
+ () => this.http.put(
38
+ `${this.auth.getBaseUrl()}/api/patient/image/cannedurl`,
39
+ requestPayload,
40
+ this.getAuthHeaders()
41
+ )
70
42
  );
71
43
  }
44
+ /**
45
+ * Updates the patient's profile image by confirming the uploaded file name.
46
+ */
72
47
  async updateUserImage(fileName) {
73
- const resolvedFileName = this.requireValue(
74
- fileName,
75
- "fileName"
76
- );
48
+ const resolvedFileName = this.requireValue(fileName, "File name");
77
49
  const requestPayload = {
78
- Data: {
79
- FileName: resolvedFileName
80
- }
50
+ Data: { FileName: resolvedFileName }
81
51
  };
82
- return this.httpClient.put(
83
- `${this.getBaseUrl()}/patient/image/url`,
84
- requestPayload,
85
- this.getJsonHeaders()
52
+ return this.execute(
53
+ "updateUserImage",
54
+ () => this.http.put(
55
+ `${this.auth.getBaseUrl()}/api/patient/image/url`,
56
+ requestPayload,
57
+ this.getAuthHeaders()
58
+ )
86
59
  );
87
60
  }
88
61
  // ===========================================================================
89
62
  // Identification
90
63
  // ===========================================================================
64
+ /**
65
+ * Returns a canned URL for uploading the patient's driving licence image.
66
+ */
91
67
  async getDrivingLicenseCannedUrl(extension) {
92
- const resolvedExtension = this.requireValue(
93
- extension,
94
- "extension"
95
- );
68
+ const resolvedExtension = this.requireValue(extension, "Extension");
96
69
  const requestPayload = {
97
- Data: {
98
- Extension: resolvedExtension
99
- }
70
+ Data: { Extension: resolvedExtension }
100
71
  };
101
- return this.httpClient.put(
102
- `${this.getBaseUrl()}/patient/id/cannedurl`,
103
- requestPayload,
104
- this.getJsonHeaders()
72
+ return this.execute(
73
+ "getDrivingLicenseCannedUrl",
74
+ () => this.http.put(
75
+ `${this.auth.getBaseUrl()}/api/patient/id/cannedurl`,
76
+ requestPayload,
77
+ this.getAuthHeaders()
78
+ )
105
79
  );
106
80
  }
81
+ /**
82
+ * Submits a driving licence file for OCR capture.
83
+ * fileKey is the storage key of the uploaded image.
84
+ */
107
85
  async captureDrivingLicense(fileKey) {
108
- const resolvedFileKey = this.requireValue(
109
- fileKey,
110
- "fileKey"
111
- );
86
+ const resolvedFileKey = this.requireValue(fileKey, "File key");
112
87
  const requestPayload = {
113
- Data: {
114
- Type: "identification",
115
- FileID: resolvedFileKey
116
- }
88
+ Data: { Type: "identification", FileID: resolvedFileKey }
117
89
  };
118
- return this.httpClient.post(
119
- `${this.getBaseUrl()}/patient/capture`,
120
- requestPayload,
121
- this.getJsonHeaders()
90
+ return this.execute(
91
+ "captureDrivingLicense",
92
+ () => this.http.post(
93
+ `${this.auth.getBaseUrl()}/api/patient/capture`,
94
+ requestPayload,
95
+ this.getAuthHeaders()
96
+ )
122
97
  );
123
98
  }
99
+ /**
100
+ * Submits a base64-encoded driving licence image to the EHR.
101
+ */
124
102
  async submitDrivingLicense(image) {
125
- const resolvedImage = this.requireValue(
126
- image,
127
- "image"
128
- );
103
+ const resolvedImage = this.requireValue(image, "Image");
129
104
  const requestPayload = {
130
- Data: {
131
- Image: resolvedImage
132
- }
105
+ Data: { Image: resolvedImage }
133
106
  };
134
- return this.httpClient.put(
135
- `${this.getBaseUrl()}/ehr/patient/drivinglicense`,
136
- requestPayload,
137
- this.getJsonHeaders()
107
+ return this.execute(
108
+ "submitDrivingLicense",
109
+ () => this.http.put(
110
+ `${this.auth.getBaseUrl()}/api/ehr/patient/drivinglicense`,
111
+ requestPayload,
112
+ this.getAuthHeaders()
113
+ )
138
114
  );
139
115
  }
140
116
  // ===========================================================================
141
117
  // Insurance
142
118
  // ===========================================================================
119
+ /**
120
+ * Returns a canned URL for uploading the insurance card image.
121
+ */
143
122
  async getInsuranceCannedUrl(extension) {
144
- const resolvedExtension = this.requireValue(
145
- extension,
146
- "extension"
147
- );
123
+ const resolvedExtension = this.requireValue(extension, "Extension");
148
124
  const requestPayload = {
149
- Data: {
150
- Extension: resolvedExtension
151
- }
125
+ Data: { Extension: resolvedExtension }
152
126
  };
153
- return this.httpClient.put(
154
- `${this.getBaseUrl()}/patient/insurance/cannedurl`,
155
- requestPayload,
156
- this.getJsonHeaders()
127
+ return this.execute(
128
+ "getInsuranceCannedUrl",
129
+ () => this.http.put(
130
+ `${this.auth.getBaseUrl()}/api/patient/insurance/cannedurl`,
131
+ requestPayload,
132
+ this.getAuthHeaders()
133
+ )
157
134
  );
158
135
  }
136
+ /**
137
+ * Submits an insurance card image for OCR capture.
138
+ * fileKey is the storage key of the uploaded image.
139
+ */
159
140
  async captureInsurance(fileKey) {
160
- const resolvedFileKey = this.requireValue(
161
- fileKey,
162
- "fileKey"
163
- );
141
+ const resolvedFileKey = this.requireValue(fileKey, "File key");
164
142
  const requestPayload = {
165
- Data: {
166
- Type: "healthinsurance",
167
- FileID: resolvedFileKey
168
- }
143
+ Data: { Type: "healthinsurance", FileID: resolvedFileKey }
169
144
  };
170
- return this.httpClient.post(
171
- `${this.getBaseUrl()}/patient/capture`,
172
- requestPayload,
173
- this.getJsonHeaders()
145
+ return this.execute(
146
+ "captureInsurance",
147
+ () => this.http.post(
148
+ `${this.auth.getBaseUrl()}/api/patient/capture`,
149
+ requestPayload,
150
+ this.getAuthHeaders()
151
+ )
174
152
  );
175
153
  }
154
+ /**
155
+ * Creates or updates the patient's insurance coverage record.
156
+ */
176
157
  async submitInsurance(coverage) {
177
158
  if (!coverage) {
178
- throw new ConfigError(
179
- "Insurance coverage data is required."
180
- );
159
+ throw new ValidationError({
160
+ message: "Insurance coverage data is required.",
161
+ code: "INVALID_INPUT",
162
+ param: "coverage"
163
+ });
181
164
  }
182
165
  const requestPayload = {
183
166
  Data: coverage
184
167
  };
185
- return this.httpClient.put(
186
- `${this.getBaseUrl()}/patient/coverage`,
187
- requestPayload,
188
- this.getJsonHeaders()
168
+ return this.execute(
169
+ "submitInsurance",
170
+ () => this.http.put(
171
+ `${this.auth.getBaseUrl()}/api/patient/coverage`,
172
+ requestPayload,
173
+ this.getAuthHeaders()
174
+ )
189
175
  );
190
176
  }
191
- async getInsurances() {
192
- return this.httpClient.get(
193
- `${this.getBaseUrl()}/ehr/patient/insurances`,
194
- this.getAuthHeaders()
177
+ /**
178
+ * Returns all insurance records for the authenticated patient.
179
+ */
180
+ async listInsurances() {
181
+ return this.execute(
182
+ "listInsurances",
183
+ () => this.http.get(
184
+ `${this.auth.getBaseUrl()}/api/ehr/patient/insurances`,
185
+ this.getAuthHeaders()
186
+ )
195
187
  );
196
188
  }
197
189
  // ===========================================================================
198
190
  // User photo capture
199
191
  // ===========================================================================
192
+ /**
193
+ * Submits a user photo (selfie) for capture.
194
+ * fileKey is the storage key of the uploaded image.
195
+ */
200
196
  async captureUserPhoto(fileKey) {
201
- const resolvedFileKey = this.requireValue(
202
- fileKey,
203
- "fileKey"
204
- );
197
+ const resolvedFileKey = this.requireValue(fileKey, "File key");
205
198
  const requestPayload = {
206
- Data: {
207
- Type: "userphoto",
208
- FileID: resolvedFileKey
209
- }
199
+ Data: { Type: "userphoto", FileID: resolvedFileKey }
210
200
  };
211
- return this.httpClient.post(
212
- `${this.getBaseUrl()}/patient/capture`,
213
- requestPayload,
214
- this.getJsonHeaders()
201
+ return this.execute(
202
+ "captureUserPhoto",
203
+ () => this.http.post(
204
+ `${this.auth.getBaseUrl()}/api/patient/capture`,
205
+ requestPayload,
206
+ this.getAuthHeaders()
207
+ )
215
208
  );
216
209
  }
217
210
  // ===========================================================================
218
211
  // Account
219
212
  // ===========================================================================
220
- async deactivateUser() {
221
- return this.httpClient.put(
222
- `${this.getBaseUrl()}/patient/deactivate`,
223
- void 0,
224
- this.getJsonHeaders()
213
+ /**
214
+ * Soft-deactivates the current patient account.
215
+ * The patient record is not permanently deleted.
216
+ */
217
+ async deactivateCurrentPatient() {
218
+ return this.execute(
219
+ "deactivateCurrentPatient",
220
+ () => this.http.put(
221
+ `${this.auth.getBaseUrl()}/api/patient/deactivate`,
222
+ void 0,
223
+ this.getAuthHeaders()
224
+ )
225
225
  );
226
226
  }
227
227
  // ===========================================================================
228
- // Helpers
228
+ // Private
229
229
  // ===========================================================================
230
- getBaseUrl() {
231
- return this.loginClient.getBaseUrl();
232
- }
233
230
  getAuthHeaders() {
234
- return {
235
- ...this.loginClient.getAuthHeader(),
236
- ...this.getApiKeyHeader()
237
- };
238
- }
239
- getJsonHeaders() {
240
- return {
241
- ...this.getAuthHeaders(),
242
- "Content-Type": "application/json"
243
- };
244
- }
245
- getApiKeyHeader() {
246
- if (!this.apiKeyHeaderName || !this.apiKeyValue) {
247
- return {};
248
- }
249
- return {
250
- [this.apiKeyHeaderName]: this.apiKeyValue
251
- };
252
- }
253
- requireValue(value, parameterName) {
254
- const trimmedValue = value == null ? void 0 : value.trim();
255
- if (!trimmedValue) {
256
- throw new ConfigError(
257
- `${parameterName} is required.`
258
- );
259
- }
260
- return trimmedValue;
231
+ return { ...this.getHeaders(), ...this.auth.getAuthHeader() };
261
232
  }
262
233
  };
263
234
 
235
+ // src/errors.ts
236
+ import {
237
+ APIError,
238
+ ConfigError,
239
+ HCServiceError,
240
+ NetworkError,
241
+ ValidationError as ValidationError2
242
+ } from "@healthcloudai/hc-http";
243
+
264
244
  // src/types.ts
265
245
  var UserStatus = /* @__PURE__ */ ((UserStatus2) => {
266
246
  UserStatus2[UserStatus2["INACTIVE"] = 0] = "INACTIVE";
@@ -269,9 +249,11 @@ var UserStatus = /* @__PURE__ */ ((UserStatus2) => {
269
249
  return UserStatus2;
270
250
  })(UserStatus || {});
271
251
  export {
272
- AuthError,
252
+ APIError,
273
253
  ConfigError,
254
+ HCServiceError,
274
255
  HCSettingsClient,
275
- HttpError,
276
- UserStatus
256
+ NetworkError,
257
+ UserStatus,
258
+ ValidationError2 as ValidationError
277
259
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@healthcloudai/hc-settings-connector",
3
- "version": "0.0.14",
3
+ "version": "0.2.0",
4
4
  "description": "Healthcheck Settings SDK with TypeScript",
5
5
  "author": "Healthcheck Systems Inc",
6
6
  "license": "MIT",
@@ -36,8 +36,8 @@
36
36
  },
37
37
  "dependencies": {
38
38
  "axios": "^1.13.4",
39
- "@healthcloudai/hc-login-connector": "^0.1.0",
40
- "@healthcloudai/hc-http": "^0.0.6"
39
+ "@healthcloudai/hc-login-connector": "^0.3.0",
40
+ "@healthcloudai/hc-http": "^0.2.0"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "react-native": ">=0.70.0"