@healthcloudai/hc-import-vitals 0.1.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 +229 -0
- package/dist/index.cjs +258 -0
- package/dist/index.d.cts +115 -0
- package/dist/index.d.ts +115 -0
- package/dist/index.js +237 -0
- package/package.json +60 -0
package/README.md
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Healthcheck Import Vitals Connector
|
|
2
|
+
|
|
3
|
+
SDK connector for importing vital signs and retrieving stored vitals from the Healthcheck platform.
|
|
4
|
+
|
|
5
|
+
`HCImportVitalsClient` uses a configured and authenticated `HCLoginClient` for environment resolution and auth headers. The base URL is derived from the login client so it stays in sync with the configured environment.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install @healthcloudai/hc-import-vitals \
|
|
13
|
+
@healthcloudai/hc-login-connector \
|
|
14
|
+
@healthcloudai/hc-http
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Import
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { HCImportVitalsClient } from "@healthcloudai/hc-import-vitals";
|
|
23
|
+
import { HCLoginClient } from "@healthcloudai/hc-login-connector";
|
|
24
|
+
import { FetchClient } from "@healthcloudai/hc-http";
|
|
25
|
+
|
|
26
|
+
import type {
|
|
27
|
+
APIResponse,
|
|
28
|
+
ImportVitalsRequest,
|
|
29
|
+
ImportVitalDBRecord,
|
|
30
|
+
LogVitalsRequest,
|
|
31
|
+
} from "@healthcloudai/hc-import-vitals";
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Setup
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
const httpClient = new FetchClient();
|
|
40
|
+
const loginClient = new HCLoginClient(httpClient);
|
|
41
|
+
|
|
42
|
+
loginClient.configure("healthcheck", "dev");
|
|
43
|
+
await loginClient.login("john.smith@example.com", "ExamplePassword123!");
|
|
44
|
+
|
|
45
|
+
const client = new HCImportVitalsClient(httpClient, loginClient);
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The constructor reads the base URL directly from `loginClient.getBaseUrl()` — no separate environment mapping is needed.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## API Key
|
|
53
|
+
|
|
54
|
+
If the environment requires an API key, configure it once:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
client.setApiKey("x-api-key", process.env.HEALTHCLOUD_API_KEY ?? "");
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Response Format
|
|
63
|
+
|
|
64
|
+
All methods return:
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
APIResponse<T>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
```ts
|
|
71
|
+
export interface APIResponse<T> {
|
|
72
|
+
Data: T | null;
|
|
73
|
+
IsOK: boolean;
|
|
74
|
+
ErrorMessage: string | null;
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Methods
|
|
81
|
+
|
|
82
|
+
### `getVitals(limit?)`
|
|
83
|
+
|
|
84
|
+
Returns stored vital sign records for the authenticated patient.
|
|
85
|
+
|
|
86
|
+
- `limit` — optional, default `50`, max `500`
|
|
87
|
+
|
|
88
|
+
```ts
|
|
89
|
+
await client.getVitals();
|
|
90
|
+
await client.getVitals(5);
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Returns `Promise<APIResponse<ImportVitalDBRecord[]>>`.
|
|
94
|
+
|
|
95
|
+
Example response:
|
|
96
|
+
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"Data": [
|
|
100
|
+
{
|
|
101
|
+
"ID": "EC1FCB0C-26EF-45C6-B1B7-ECD1EDCE4E55",
|
|
102
|
+
"TenantID": "healthcheck",
|
|
103
|
+
"PatientID": "john.smith@example.com",
|
|
104
|
+
"Type": "bloodpressuresystolic",
|
|
105
|
+
"Value": 125,
|
|
106
|
+
"Unit": "mmHg",
|
|
107
|
+
"TimeStamp": "2026-05-27T19:46:17Z",
|
|
108
|
+
"SourceName": "Apple Health (Native)",
|
|
109
|
+
"SourcePlatform": "ios"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"ID": "93BD0AD4-C71B-4CB6-9A6F-A7E62309D28A",
|
|
113
|
+
"TenantID": "healthcheck",
|
|
114
|
+
"PatientID": "john.smith@example.com",
|
|
115
|
+
"Type": "bloodpressurediastolic",
|
|
116
|
+
"Value": 85,
|
|
117
|
+
"Unit": "mmHg",
|
|
118
|
+
"TimeStamp": "2026-05-27T19:46:17Z",
|
|
119
|
+
"SourceName": "Apple Health (Native)",
|
|
120
|
+
"SourcePlatform": "ios"
|
|
121
|
+
}
|
|
122
|
+
],
|
|
123
|
+
"ErrorMessage": null,
|
|
124
|
+
"IsOK": true
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
### `importVitals(vitals)`
|
|
131
|
+
|
|
132
|
+
Imports vital sign records from a connected device. `User.Email` and at least one record are required.
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
await client.importVitals({
|
|
136
|
+
User: {
|
|
137
|
+
Email: "john.smith@example.com",
|
|
138
|
+
},
|
|
139
|
+
Records: [
|
|
140
|
+
{
|
|
141
|
+
Type: "HeartRate",
|
|
142
|
+
Value: 72,
|
|
143
|
+
Unit: "bpm",
|
|
144
|
+
StartDate: "2026-05-29T08:00:00.000Z",
|
|
145
|
+
EndDate: "2026-05-29T08:00:00.000Z",
|
|
146
|
+
SourceName: "Apple Health",
|
|
147
|
+
SourcePlatform: "ios",
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
Type: "BloodPressureSystolic",
|
|
151
|
+
Value: 120,
|
|
152
|
+
Unit: "mmHg",
|
|
153
|
+
StartDate: "2026-05-29T08:00:00.000Z",
|
|
154
|
+
EndDate: "2026-05-29T08:00:00.000Z",
|
|
155
|
+
SourceName: "Apple Health",
|
|
156
|
+
SourcePlatform: "ios",
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
Type: "BloodPressureDiastolic",
|
|
160
|
+
Value: 78,
|
|
161
|
+
Unit: "mmHg",
|
|
162
|
+
StartDate: "2026-05-29T08:00:00.000Z",
|
|
163
|
+
EndDate: "2026-05-29T08:00:00.000Z",
|
|
164
|
+
SourceName: "Apple Health",
|
|
165
|
+
SourcePlatform: "ios",
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
SyncTimestamp: "2026-05-29T08:00:00.000Z",
|
|
169
|
+
DevicePlatform: "ios",
|
|
170
|
+
});
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Returns `Promise<APIResponse<boolean>>`.
|
|
174
|
+
|
|
175
|
+
Example response:
|
|
176
|
+
|
|
177
|
+
```json
|
|
178
|
+
{
|
|
179
|
+
"Data": true,
|
|
180
|
+
"ErrorMessage": null,
|
|
181
|
+
"IsOK": true
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
### `logVitals(logData)`
|
|
188
|
+
|
|
189
|
+
Logs a vitals event. No authorization required — accepts any key-value data.
|
|
190
|
+
|
|
191
|
+
```ts
|
|
192
|
+
await client.logVitals({
|
|
193
|
+
event: "sync-complete",
|
|
194
|
+
source: "mobile-app",
|
|
195
|
+
timestamp: new Date().toISOString(),
|
|
196
|
+
email: "john.smith@example.com",
|
|
197
|
+
});
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Returns `Promise<APIResponse<boolean>>`.
|
|
201
|
+
|
|
202
|
+
Example response:
|
|
203
|
+
|
|
204
|
+
```json
|
|
205
|
+
{
|
|
206
|
+
"Data": true,
|
|
207
|
+
"ErrorMessage": null,
|
|
208
|
+
"IsOK": true
|
|
209
|
+
}
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Method Summary
|
|
215
|
+
|
|
216
|
+
| Method | HTTP | Auth required |
|
|
217
|
+
| --- | --- | --- |
|
|
218
|
+
| `getVitals(limit?)` | GET `/api/imports/vitals` | Yes |
|
|
219
|
+
| `importVitals(vitals)` | POST `/api/imports/vitals` | Yes |
|
|
220
|
+
| `logVitals(logData)` | POST `/api/imports/logs` | No |
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Notes
|
|
225
|
+
|
|
226
|
+
- `getVitals` and `importVitals` require an authenticated patient token.
|
|
227
|
+
- `logVitals` does not require authorization.
|
|
228
|
+
- `Type` values observed from live data: `bloodpressuresystolic`, `bloodpressurediastolic`, `HeartRate` — always send the type exactly as the source device provides it.
|
|
229
|
+
- `SourcePlatform` observed values: `ios`, `manual`.
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
APIError: () => import_hc_http2.APIError,
|
|
24
|
+
ConfigError: () => import_hc_http2.ConfigError,
|
|
25
|
+
HCImportVitalsClient: () => HCImportVitalsClient,
|
|
26
|
+
HCServiceError: () => import_hc_http2.HCServiceError,
|
|
27
|
+
NetworkError: () => import_hc_http2.NetworkError,
|
|
28
|
+
ValidationError: () => import_hc_http2.ValidationError,
|
|
29
|
+
errorFromHttpStatus: () => import_hc_http2.errorFromHttpStatus
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(index_exports);
|
|
32
|
+
|
|
33
|
+
// src/client.ts
|
|
34
|
+
var import_hc_http = require("@healthcloudai/hc-http");
|
|
35
|
+
var HCImportVitalsClient = class {
|
|
36
|
+
constructor(httpClient, loginClient) {
|
|
37
|
+
this.http = httpClient;
|
|
38
|
+
this.auth = loginClient;
|
|
39
|
+
this.baseUrl = loginClient.getBaseUrl();
|
|
40
|
+
}
|
|
41
|
+
setApiKey(headerName, value) {
|
|
42
|
+
const trimmedHeaderName = headerName == null ? void 0 : headerName.trim();
|
|
43
|
+
const trimmedValue = value == null ? void 0 : value.trim();
|
|
44
|
+
if (!trimmedHeaderName) {
|
|
45
|
+
throw new import_hc_http.ConfigError(
|
|
46
|
+
"API key header name is required."
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
if (!trimmedValue) {
|
|
50
|
+
throw new import_hc_http.ConfigError(
|
|
51
|
+
"API key value is required."
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
this.apiKeyHeaderName = trimmedHeaderName;
|
|
55
|
+
this.apiKeyValue = trimmedValue;
|
|
56
|
+
}
|
|
57
|
+
// =========================================================================
|
|
58
|
+
// Import Vitals
|
|
59
|
+
// =========================================================================
|
|
60
|
+
/**
|
|
61
|
+
* Import vital signs from a connected device.
|
|
62
|
+
* Requires PatientAuthorization.
|
|
63
|
+
*
|
|
64
|
+
* @param vitals The vital signs import request
|
|
65
|
+
* @returns Success indicator
|
|
66
|
+
*/
|
|
67
|
+
async importVitals(vitals) {
|
|
68
|
+
var _a, _b;
|
|
69
|
+
if (!vitals) {
|
|
70
|
+
throw new import_hc_http.ValidationError({
|
|
71
|
+
message: "Vitals import request is required.",
|
|
72
|
+
code: "INVALID_INPUT"
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (!((_b = (_a = vitals == null ? void 0 : vitals.User) == null ? void 0 : _a.Email) == null ? void 0 : _b.trim())) {
|
|
76
|
+
throw new import_hc_http.ValidationError({
|
|
77
|
+
message: "User email is required.",
|
|
78
|
+
code: "INVALID_INPUT"
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
if (!(vitals == null ? void 0 : vitals.Records) || vitals.Records.length === 0) {
|
|
82
|
+
throw new import_hc_http.ValidationError({
|
|
83
|
+
message: "At least one vital record is required.",
|
|
84
|
+
code: "INVALID_INPUT"
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return this.execute(
|
|
88
|
+
"importVitals",
|
|
89
|
+
() => this.http.post(
|
|
90
|
+
`${this.baseUrl}/api/imports/vitals`,
|
|
91
|
+
vitals,
|
|
92
|
+
this.headers()
|
|
93
|
+
)
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Get vital signs for current patient.
|
|
98
|
+
* Requires PatientAuthorization.
|
|
99
|
+
*
|
|
100
|
+
* @param limit Maximum number of records to retrieve (default: 50, max: 500)
|
|
101
|
+
* @returns List of vital sign records
|
|
102
|
+
*/
|
|
103
|
+
async getVitals(limit) {
|
|
104
|
+
const queryLimit = limit != null ? limit : 50;
|
|
105
|
+
if (queryLimit <= 0) {
|
|
106
|
+
throw new import_hc_http.ValidationError({
|
|
107
|
+
message: "Limit must be greater than 0.",
|
|
108
|
+
code: "INVALID_INPUT"
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
if (queryLimit > 500) {
|
|
112
|
+
throw new import_hc_http.ValidationError({
|
|
113
|
+
message: "Limit cannot exceed 500.",
|
|
114
|
+
code: "INVALID_INPUT"
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
const qs = new URLSearchParams({ limit: queryLimit.toString() });
|
|
118
|
+
return this.execute(
|
|
119
|
+
"getVitals",
|
|
120
|
+
() => this.http.get(
|
|
121
|
+
`${this.baseUrl}/api/imports/vitals?${qs.toString()}`,
|
|
122
|
+
this.headers()
|
|
123
|
+
)
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
// =========================================================================
|
|
127
|
+
// Log Vitals
|
|
128
|
+
// =========================================================================
|
|
129
|
+
/**
|
|
130
|
+
* Log vital signs data.
|
|
131
|
+
* No authorization required.
|
|
132
|
+
*
|
|
133
|
+
* @param logData Log entry data
|
|
134
|
+
* @returns Success indicator
|
|
135
|
+
*/
|
|
136
|
+
async logVitals(logData) {
|
|
137
|
+
if (!logData) {
|
|
138
|
+
throw new import_hc_http.ValidationError({
|
|
139
|
+
message: "Log data is required.",
|
|
140
|
+
code: "INVALID_INPUT"
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
return this.execute(
|
|
144
|
+
"logVitals",
|
|
145
|
+
() => this.http.post(
|
|
146
|
+
`${this.baseUrl}/api/imports/logs`,
|
|
147
|
+
logData,
|
|
148
|
+
this.headers()
|
|
149
|
+
)
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
// =========================================================================
|
|
153
|
+
// Private
|
|
154
|
+
// =========================================================================
|
|
155
|
+
/**
|
|
156
|
+
* Unified request execution layer.
|
|
157
|
+
* Handles error mapping, response validation, and error transformation.
|
|
158
|
+
*/
|
|
159
|
+
async execute(operation, request) {
|
|
160
|
+
let response;
|
|
161
|
+
try {
|
|
162
|
+
response = await request();
|
|
163
|
+
} catch (err) {
|
|
164
|
+
if (err instanceof import_hc_http.APIError) {
|
|
165
|
+
throw err;
|
|
166
|
+
}
|
|
167
|
+
if (err instanceof Error) {
|
|
168
|
+
throw new import_hc_http.APIError({
|
|
169
|
+
message: `${operation}: ${err.message}`,
|
|
170
|
+
code: "UNKNOWN_ERROR",
|
|
171
|
+
details: err
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
throw new import_hc_http.APIError({
|
|
175
|
+
message: `${operation}: unexpected runtime failure`,
|
|
176
|
+
code: "UNKNOWN_ERROR",
|
|
177
|
+
details: err
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
if (response == null) {
|
|
181
|
+
throw new import_hc_http.APIError({
|
|
182
|
+
message: `${operation}: empty response received`,
|
|
183
|
+
code: "EMPTY_RESPONSE",
|
|
184
|
+
details: response
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
return response;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Extension point for connector-specific backend error handling.
|
|
191
|
+
*/
|
|
192
|
+
mapBackendError(operation, response) {
|
|
193
|
+
return new import_hc_http.HCServiceError(
|
|
194
|
+
operation,
|
|
195
|
+
response.ErrorMessage || "Unknown error",
|
|
196
|
+
response
|
|
197
|
+
);
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Validates response structure against APIResponse contract.
|
|
201
|
+
* Ensures all required fields are present and correctly typed.
|
|
202
|
+
*/
|
|
203
|
+
isApiResponse(value) {
|
|
204
|
+
if (!value || typeof value !== "object") {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
const response = value;
|
|
208
|
+
return "IsOK" in response && typeof response.IsOK === "boolean" && "Data" in response && "ErrorMessage" in response;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Builds authorization headers from login client.
|
|
212
|
+
* Includes standard HTTP headers for API communication.
|
|
213
|
+
*/
|
|
214
|
+
headers() {
|
|
215
|
+
return {
|
|
216
|
+
Accept: "application/json",
|
|
217
|
+
"Content-Type": "application/json",
|
|
218
|
+
...this.auth.getAuthHeader(),
|
|
219
|
+
...this.getApiKeyHeader()
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
getApiKeyHeader() {
|
|
223
|
+
if (!this.apiKeyHeaderName || !this.apiKeyValue) {
|
|
224
|
+
return {};
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
[this.apiKeyHeaderName]: this.apiKeyValue
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Validates and encodes path parameter values.
|
|
232
|
+
* Ensures parameter is non-empty before URL encoding.
|
|
233
|
+
* Throws ValidationError if parameter is missing or empty.
|
|
234
|
+
*/
|
|
235
|
+
encode(value) {
|
|
236
|
+
const trimmed = value == null ? void 0 : value.trim();
|
|
237
|
+
if (!trimmed) {
|
|
238
|
+
throw new import_hc_http.ValidationError({
|
|
239
|
+
message: "Path parameter value is required.",
|
|
240
|
+
code: "INVALID_INPUT"
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
return encodeURIComponent(trimmed);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
// src/errors.ts
|
|
248
|
+
var import_hc_http2 = require("@healthcloudai/hc-http");
|
|
249
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
250
|
+
0 && (module.exports = {
|
|
251
|
+
APIError,
|
|
252
|
+
ConfigError,
|
|
253
|
+
HCImportVitalsClient,
|
|
254
|
+
HCServiceError,
|
|
255
|
+
NetworkError,
|
|
256
|
+
ValidationError,
|
|
257
|
+
errorFromHttpStatus
|
|
258
|
+
});
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { HCLoginClient } from '@healthcloudai/hc-login-connector';
|
|
2
|
+
import { HttpClient, APIError } from '@healthcloudai/hc-http';
|
|
3
|
+
export { APIError, ConfigError, HCServiceError, NetworkError, ValidationError, errorFromHttpStatus } from '@healthcloudai/hc-http';
|
|
4
|
+
|
|
5
|
+
type ISODateString = string;
|
|
6
|
+
interface APIResponse<T> {
|
|
7
|
+
Data: T | null;
|
|
8
|
+
IsOK: boolean;
|
|
9
|
+
ErrorMessage: string | null;
|
|
10
|
+
}
|
|
11
|
+
interface APIRequest<T> {
|
|
12
|
+
Data: T;
|
|
13
|
+
}
|
|
14
|
+
interface ImportVitalsUser {
|
|
15
|
+
TenantID?: string | null;
|
|
16
|
+
Email?: string | null;
|
|
17
|
+
}
|
|
18
|
+
interface ImportVitalRecord {
|
|
19
|
+
Id?: string | null;
|
|
20
|
+
Type?: string | null;
|
|
21
|
+
Value?: number | null;
|
|
22
|
+
Unit?: string | null;
|
|
23
|
+
StartDate?: ISODateString | null;
|
|
24
|
+
EndDate?: ISODateString | null;
|
|
25
|
+
SourceName?: string | null;
|
|
26
|
+
SourcePlatform?: string | null;
|
|
27
|
+
}
|
|
28
|
+
interface ImportVitalsRequest {
|
|
29
|
+
User?: ImportVitalsUser | null;
|
|
30
|
+
Records?: ImportVitalRecord[] | null;
|
|
31
|
+
SyncTimestamp?: ISODateString | null;
|
|
32
|
+
DevicePlatform?: string | null;
|
|
33
|
+
AuthCode?: string | null;
|
|
34
|
+
RedirectURL?: string | null;
|
|
35
|
+
}
|
|
36
|
+
interface ImportVitalDBRecord {
|
|
37
|
+
ID?: string | null;
|
|
38
|
+
TenantID?: string | null;
|
|
39
|
+
PatientID?: string | null;
|
|
40
|
+
Type?: string | null;
|
|
41
|
+
Value?: number | null;
|
|
42
|
+
Unit?: string | null;
|
|
43
|
+
TimeStamp?: ISODateString | null;
|
|
44
|
+
SourceName?: string | null;
|
|
45
|
+
SourcePlatform?: string | null;
|
|
46
|
+
}
|
|
47
|
+
interface GetVitalsResponse {
|
|
48
|
+
vitals: ImportVitalDBRecord[];
|
|
49
|
+
totalCount: number;
|
|
50
|
+
}
|
|
51
|
+
interface LogVitalsRequest {
|
|
52
|
+
[key: string]: any;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
declare class HCImportVitalsClient {
|
|
56
|
+
private readonly http;
|
|
57
|
+
private readonly auth;
|
|
58
|
+
private readonly baseUrl;
|
|
59
|
+
private apiKeyHeaderName?;
|
|
60
|
+
private apiKeyValue?;
|
|
61
|
+
constructor(httpClient: HttpClient, loginClient: HCLoginClient);
|
|
62
|
+
setApiKey(headerName: string, value: string): void;
|
|
63
|
+
/**
|
|
64
|
+
* Import vital signs from a connected device.
|
|
65
|
+
* Requires PatientAuthorization.
|
|
66
|
+
*
|
|
67
|
+
* @param vitals The vital signs import request
|
|
68
|
+
* @returns Success indicator
|
|
69
|
+
*/
|
|
70
|
+
importVitals(vitals: ImportVitalsRequest): Promise<APIResponse<boolean>>;
|
|
71
|
+
/**
|
|
72
|
+
* Get vital signs for current patient.
|
|
73
|
+
* Requires PatientAuthorization.
|
|
74
|
+
*
|
|
75
|
+
* @param limit Maximum number of records to retrieve (default: 50, max: 500)
|
|
76
|
+
* @returns List of vital sign records
|
|
77
|
+
*/
|
|
78
|
+
getVitals(limit?: number): Promise<APIResponse<ImportVitalDBRecord[]>>;
|
|
79
|
+
/**
|
|
80
|
+
* Log vital signs data.
|
|
81
|
+
* No authorization required.
|
|
82
|
+
*
|
|
83
|
+
* @param logData Log entry data
|
|
84
|
+
* @returns Success indicator
|
|
85
|
+
*/
|
|
86
|
+
logVitals(logData: LogVitalsRequest): Promise<APIResponse<boolean>>;
|
|
87
|
+
/**
|
|
88
|
+
* Unified request execution layer.
|
|
89
|
+
* Handles error mapping, response validation, and error transformation.
|
|
90
|
+
*/
|
|
91
|
+
protected execute<T>(operation: string, request: () => Promise<APIResponse<T>>): Promise<APIResponse<T>>;
|
|
92
|
+
/**
|
|
93
|
+
* Extension point for connector-specific backend error handling.
|
|
94
|
+
*/
|
|
95
|
+
protected mapBackendError(operation: string, response: APIResponse<unknown>): APIError;
|
|
96
|
+
/**
|
|
97
|
+
* Validates response structure against APIResponse contract.
|
|
98
|
+
* Ensures all required fields are present and correctly typed.
|
|
99
|
+
*/
|
|
100
|
+
private isApiResponse;
|
|
101
|
+
/**
|
|
102
|
+
* Builds authorization headers from login client.
|
|
103
|
+
* Includes standard HTTP headers for API communication.
|
|
104
|
+
*/
|
|
105
|
+
private headers;
|
|
106
|
+
private getApiKeyHeader;
|
|
107
|
+
/**
|
|
108
|
+
* Validates and encodes path parameter values.
|
|
109
|
+
* Ensures parameter is non-empty before URL encoding.
|
|
110
|
+
* Throws ValidationError if parameter is missing or empty.
|
|
111
|
+
*/
|
|
112
|
+
private encode;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export { type APIRequest, type APIResponse, type GetVitalsResponse, HCImportVitalsClient, type ISODateString, type ImportVitalDBRecord, type ImportVitalRecord, type ImportVitalsRequest, type ImportVitalsUser, type LogVitalsRequest };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { HCLoginClient } from '@healthcloudai/hc-login-connector';
|
|
2
|
+
import { HttpClient, APIError } from '@healthcloudai/hc-http';
|
|
3
|
+
export { APIError, ConfigError, HCServiceError, NetworkError, ValidationError, errorFromHttpStatus } from '@healthcloudai/hc-http';
|
|
4
|
+
|
|
5
|
+
type ISODateString = string;
|
|
6
|
+
interface APIResponse<T> {
|
|
7
|
+
Data: T | null;
|
|
8
|
+
IsOK: boolean;
|
|
9
|
+
ErrorMessage: string | null;
|
|
10
|
+
}
|
|
11
|
+
interface APIRequest<T> {
|
|
12
|
+
Data: T;
|
|
13
|
+
}
|
|
14
|
+
interface ImportVitalsUser {
|
|
15
|
+
TenantID?: string | null;
|
|
16
|
+
Email?: string | null;
|
|
17
|
+
}
|
|
18
|
+
interface ImportVitalRecord {
|
|
19
|
+
Id?: string | null;
|
|
20
|
+
Type?: string | null;
|
|
21
|
+
Value?: number | null;
|
|
22
|
+
Unit?: string | null;
|
|
23
|
+
StartDate?: ISODateString | null;
|
|
24
|
+
EndDate?: ISODateString | null;
|
|
25
|
+
SourceName?: string | null;
|
|
26
|
+
SourcePlatform?: string | null;
|
|
27
|
+
}
|
|
28
|
+
interface ImportVitalsRequest {
|
|
29
|
+
User?: ImportVitalsUser | null;
|
|
30
|
+
Records?: ImportVitalRecord[] | null;
|
|
31
|
+
SyncTimestamp?: ISODateString | null;
|
|
32
|
+
DevicePlatform?: string | null;
|
|
33
|
+
AuthCode?: string | null;
|
|
34
|
+
RedirectURL?: string | null;
|
|
35
|
+
}
|
|
36
|
+
interface ImportVitalDBRecord {
|
|
37
|
+
ID?: string | null;
|
|
38
|
+
TenantID?: string | null;
|
|
39
|
+
PatientID?: string | null;
|
|
40
|
+
Type?: string | null;
|
|
41
|
+
Value?: number | null;
|
|
42
|
+
Unit?: string | null;
|
|
43
|
+
TimeStamp?: ISODateString | null;
|
|
44
|
+
SourceName?: string | null;
|
|
45
|
+
SourcePlatform?: string | null;
|
|
46
|
+
}
|
|
47
|
+
interface GetVitalsResponse {
|
|
48
|
+
vitals: ImportVitalDBRecord[];
|
|
49
|
+
totalCount: number;
|
|
50
|
+
}
|
|
51
|
+
interface LogVitalsRequest {
|
|
52
|
+
[key: string]: any;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
declare class HCImportVitalsClient {
|
|
56
|
+
private readonly http;
|
|
57
|
+
private readonly auth;
|
|
58
|
+
private readonly baseUrl;
|
|
59
|
+
private apiKeyHeaderName?;
|
|
60
|
+
private apiKeyValue?;
|
|
61
|
+
constructor(httpClient: HttpClient, loginClient: HCLoginClient);
|
|
62
|
+
setApiKey(headerName: string, value: string): void;
|
|
63
|
+
/**
|
|
64
|
+
* Import vital signs from a connected device.
|
|
65
|
+
* Requires PatientAuthorization.
|
|
66
|
+
*
|
|
67
|
+
* @param vitals The vital signs import request
|
|
68
|
+
* @returns Success indicator
|
|
69
|
+
*/
|
|
70
|
+
importVitals(vitals: ImportVitalsRequest): Promise<APIResponse<boolean>>;
|
|
71
|
+
/**
|
|
72
|
+
* Get vital signs for current patient.
|
|
73
|
+
* Requires PatientAuthorization.
|
|
74
|
+
*
|
|
75
|
+
* @param limit Maximum number of records to retrieve (default: 50, max: 500)
|
|
76
|
+
* @returns List of vital sign records
|
|
77
|
+
*/
|
|
78
|
+
getVitals(limit?: number): Promise<APIResponse<ImportVitalDBRecord[]>>;
|
|
79
|
+
/**
|
|
80
|
+
* Log vital signs data.
|
|
81
|
+
* No authorization required.
|
|
82
|
+
*
|
|
83
|
+
* @param logData Log entry data
|
|
84
|
+
* @returns Success indicator
|
|
85
|
+
*/
|
|
86
|
+
logVitals(logData: LogVitalsRequest): Promise<APIResponse<boolean>>;
|
|
87
|
+
/**
|
|
88
|
+
* Unified request execution layer.
|
|
89
|
+
* Handles error mapping, response validation, and error transformation.
|
|
90
|
+
*/
|
|
91
|
+
protected execute<T>(operation: string, request: () => Promise<APIResponse<T>>): Promise<APIResponse<T>>;
|
|
92
|
+
/**
|
|
93
|
+
* Extension point for connector-specific backend error handling.
|
|
94
|
+
*/
|
|
95
|
+
protected mapBackendError(operation: string, response: APIResponse<unknown>): APIError;
|
|
96
|
+
/**
|
|
97
|
+
* Validates response structure against APIResponse contract.
|
|
98
|
+
* Ensures all required fields are present and correctly typed.
|
|
99
|
+
*/
|
|
100
|
+
private isApiResponse;
|
|
101
|
+
/**
|
|
102
|
+
* Builds authorization headers from login client.
|
|
103
|
+
* Includes standard HTTP headers for API communication.
|
|
104
|
+
*/
|
|
105
|
+
private headers;
|
|
106
|
+
private getApiKeyHeader;
|
|
107
|
+
/**
|
|
108
|
+
* Validates and encodes path parameter values.
|
|
109
|
+
* Ensures parameter is non-empty before URL encoding.
|
|
110
|
+
* Throws ValidationError if parameter is missing or empty.
|
|
111
|
+
*/
|
|
112
|
+
private encode;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export { type APIRequest, type APIResponse, type GetVitalsResponse, HCImportVitalsClient, type ISODateString, type ImportVitalDBRecord, type ImportVitalRecord, type ImportVitalsRequest, type ImportVitalsUser, type LogVitalsRequest };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
// src/client.ts
|
|
2
|
+
import {
|
|
3
|
+
APIError,
|
|
4
|
+
HCServiceError,
|
|
5
|
+
ValidationError,
|
|
6
|
+
ConfigError
|
|
7
|
+
} from "@healthcloudai/hc-http";
|
|
8
|
+
var HCImportVitalsClient = class {
|
|
9
|
+
constructor(httpClient, loginClient) {
|
|
10
|
+
this.http = httpClient;
|
|
11
|
+
this.auth = loginClient;
|
|
12
|
+
this.baseUrl = loginClient.getBaseUrl();
|
|
13
|
+
}
|
|
14
|
+
setApiKey(headerName, value) {
|
|
15
|
+
const trimmedHeaderName = headerName == null ? void 0 : headerName.trim();
|
|
16
|
+
const trimmedValue = value == null ? void 0 : value.trim();
|
|
17
|
+
if (!trimmedHeaderName) {
|
|
18
|
+
throw new ConfigError(
|
|
19
|
+
"API key header name is required."
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
if (!trimmedValue) {
|
|
23
|
+
throw new ConfigError(
|
|
24
|
+
"API key value is required."
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
this.apiKeyHeaderName = trimmedHeaderName;
|
|
28
|
+
this.apiKeyValue = trimmedValue;
|
|
29
|
+
}
|
|
30
|
+
// =========================================================================
|
|
31
|
+
// Import Vitals
|
|
32
|
+
// =========================================================================
|
|
33
|
+
/**
|
|
34
|
+
* Import vital signs from a connected device.
|
|
35
|
+
* Requires PatientAuthorization.
|
|
36
|
+
*
|
|
37
|
+
* @param vitals The vital signs import request
|
|
38
|
+
* @returns Success indicator
|
|
39
|
+
*/
|
|
40
|
+
async importVitals(vitals) {
|
|
41
|
+
var _a, _b;
|
|
42
|
+
if (!vitals) {
|
|
43
|
+
throw new ValidationError({
|
|
44
|
+
message: "Vitals import request is required.",
|
|
45
|
+
code: "INVALID_INPUT"
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (!((_b = (_a = vitals == null ? void 0 : vitals.User) == null ? void 0 : _a.Email) == null ? void 0 : _b.trim())) {
|
|
49
|
+
throw new ValidationError({
|
|
50
|
+
message: "User email is required.",
|
|
51
|
+
code: "INVALID_INPUT"
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (!(vitals == null ? void 0 : vitals.Records) || vitals.Records.length === 0) {
|
|
55
|
+
throw new ValidationError({
|
|
56
|
+
message: "At least one vital record is required.",
|
|
57
|
+
code: "INVALID_INPUT"
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
return this.execute(
|
|
61
|
+
"importVitals",
|
|
62
|
+
() => this.http.post(
|
|
63
|
+
`${this.baseUrl}/api/imports/vitals`,
|
|
64
|
+
vitals,
|
|
65
|
+
this.headers()
|
|
66
|
+
)
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get vital signs for current patient.
|
|
71
|
+
* Requires PatientAuthorization.
|
|
72
|
+
*
|
|
73
|
+
* @param limit Maximum number of records to retrieve (default: 50, max: 500)
|
|
74
|
+
* @returns List of vital sign records
|
|
75
|
+
*/
|
|
76
|
+
async getVitals(limit) {
|
|
77
|
+
const queryLimit = limit != null ? limit : 50;
|
|
78
|
+
if (queryLimit <= 0) {
|
|
79
|
+
throw new ValidationError({
|
|
80
|
+
message: "Limit must be greater than 0.",
|
|
81
|
+
code: "INVALID_INPUT"
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
if (queryLimit > 500) {
|
|
85
|
+
throw new ValidationError({
|
|
86
|
+
message: "Limit cannot exceed 500.",
|
|
87
|
+
code: "INVALID_INPUT"
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
const qs = new URLSearchParams({ limit: queryLimit.toString() });
|
|
91
|
+
return this.execute(
|
|
92
|
+
"getVitals",
|
|
93
|
+
() => this.http.get(
|
|
94
|
+
`${this.baseUrl}/api/imports/vitals?${qs.toString()}`,
|
|
95
|
+
this.headers()
|
|
96
|
+
)
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
// =========================================================================
|
|
100
|
+
// Log Vitals
|
|
101
|
+
// =========================================================================
|
|
102
|
+
/**
|
|
103
|
+
* Log vital signs data.
|
|
104
|
+
* No authorization required.
|
|
105
|
+
*
|
|
106
|
+
* @param logData Log entry data
|
|
107
|
+
* @returns Success indicator
|
|
108
|
+
*/
|
|
109
|
+
async logVitals(logData) {
|
|
110
|
+
if (!logData) {
|
|
111
|
+
throw new ValidationError({
|
|
112
|
+
message: "Log data is required.",
|
|
113
|
+
code: "INVALID_INPUT"
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
return this.execute(
|
|
117
|
+
"logVitals",
|
|
118
|
+
() => this.http.post(
|
|
119
|
+
`${this.baseUrl}/api/imports/logs`,
|
|
120
|
+
logData,
|
|
121
|
+
this.headers()
|
|
122
|
+
)
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
// =========================================================================
|
|
126
|
+
// Private
|
|
127
|
+
// =========================================================================
|
|
128
|
+
/**
|
|
129
|
+
* Unified request execution layer.
|
|
130
|
+
* Handles error mapping, response validation, and error transformation.
|
|
131
|
+
*/
|
|
132
|
+
async execute(operation, request) {
|
|
133
|
+
let response;
|
|
134
|
+
try {
|
|
135
|
+
response = await request();
|
|
136
|
+
} catch (err) {
|
|
137
|
+
if (err instanceof APIError) {
|
|
138
|
+
throw err;
|
|
139
|
+
}
|
|
140
|
+
if (err instanceof Error) {
|
|
141
|
+
throw new APIError({
|
|
142
|
+
message: `${operation}: ${err.message}`,
|
|
143
|
+
code: "UNKNOWN_ERROR",
|
|
144
|
+
details: err
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
throw new APIError({
|
|
148
|
+
message: `${operation}: unexpected runtime failure`,
|
|
149
|
+
code: "UNKNOWN_ERROR",
|
|
150
|
+
details: err
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
if (response == null) {
|
|
154
|
+
throw new APIError({
|
|
155
|
+
message: `${operation}: empty response received`,
|
|
156
|
+
code: "EMPTY_RESPONSE",
|
|
157
|
+
details: response
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
return response;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Extension point for connector-specific backend error handling.
|
|
164
|
+
*/
|
|
165
|
+
mapBackendError(operation, response) {
|
|
166
|
+
return new HCServiceError(
|
|
167
|
+
operation,
|
|
168
|
+
response.ErrorMessage || "Unknown error",
|
|
169
|
+
response
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Validates response structure against APIResponse contract.
|
|
174
|
+
* Ensures all required fields are present and correctly typed.
|
|
175
|
+
*/
|
|
176
|
+
isApiResponse(value) {
|
|
177
|
+
if (!value || typeof value !== "object") {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
const response = value;
|
|
181
|
+
return "IsOK" in response && typeof response.IsOK === "boolean" && "Data" in response && "ErrorMessage" in response;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Builds authorization headers from login client.
|
|
185
|
+
* Includes standard HTTP headers for API communication.
|
|
186
|
+
*/
|
|
187
|
+
headers() {
|
|
188
|
+
return {
|
|
189
|
+
Accept: "application/json",
|
|
190
|
+
"Content-Type": "application/json",
|
|
191
|
+
...this.auth.getAuthHeader(),
|
|
192
|
+
...this.getApiKeyHeader()
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
getApiKeyHeader() {
|
|
196
|
+
if (!this.apiKeyHeaderName || !this.apiKeyValue) {
|
|
197
|
+
return {};
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
[this.apiKeyHeaderName]: this.apiKeyValue
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Validates and encodes path parameter values.
|
|
205
|
+
* Ensures parameter is non-empty before URL encoding.
|
|
206
|
+
* Throws ValidationError if parameter is missing or empty.
|
|
207
|
+
*/
|
|
208
|
+
encode(value) {
|
|
209
|
+
const trimmed = value == null ? void 0 : value.trim();
|
|
210
|
+
if (!trimmed) {
|
|
211
|
+
throw new ValidationError({
|
|
212
|
+
message: "Path parameter value is required.",
|
|
213
|
+
code: "INVALID_INPUT"
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
return encodeURIComponent(trimmed);
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
|
|
220
|
+
// src/errors.ts
|
|
221
|
+
import {
|
|
222
|
+
APIError as APIError2,
|
|
223
|
+
ConfigError as ConfigError2,
|
|
224
|
+
HCServiceError as HCServiceError2,
|
|
225
|
+
NetworkError,
|
|
226
|
+
ValidationError as ValidationError2,
|
|
227
|
+
errorFromHttpStatus
|
|
228
|
+
} from "@healthcloudai/hc-http";
|
|
229
|
+
export {
|
|
230
|
+
APIError2 as APIError,
|
|
231
|
+
ConfigError2 as ConfigError,
|
|
232
|
+
HCImportVitalsClient,
|
|
233
|
+
HCServiceError2 as HCServiceError,
|
|
234
|
+
NetworkError,
|
|
235
|
+
ValidationError2 as ValidationError,
|
|
236
|
+
errorFromHttpStatus
|
|
237
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@healthcloudai/hc-import-vitals",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "Healthcheck Import Vitals connector SDK with TypeScript",
|
|
5
|
+
"author": "Healthcheck Systems Inc",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"health-cloud",
|
|
9
|
+
"import-vitals",
|
|
10
|
+
"vitals",
|
|
11
|
+
"react-native",
|
|
12
|
+
"typescript",
|
|
13
|
+
"sdk",
|
|
14
|
+
"fetch",
|
|
15
|
+
"axios"
|
|
16
|
+
],
|
|
17
|
+
"type": "module",
|
|
18
|
+
"main": "dist/index.cjs",
|
|
19
|
+
"module": "dist/index.js",
|
|
20
|
+
"types": "dist/index.d.ts",
|
|
21
|
+
"react-native": "dist/index.js",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"import": "./dist/index.js",
|
|
26
|
+
"require": "./dist/index.cjs"
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsup src/index.ts --format esm,cjs --dts --clean",
|
|
34
|
+
"dev": "tsup src/index.ts --watch",
|
|
35
|
+
"lint": "eslint src --ext .ts",
|
|
36
|
+
"prepublishOnly": "npm run build"
|
|
37
|
+
},
|
|
38
|
+
"dependencies": {
|
|
39
|
+
"@healthcloudai/hc-http": "^0.1.0",
|
|
40
|
+
"@healthcloudai/hc-login-connector": "^0.2.0",
|
|
41
|
+
"axios": "^1.13.4"
|
|
42
|
+
},
|
|
43
|
+
"peerDependencies": {
|
|
44
|
+
"react-native": ">=0.70.0"
|
|
45
|
+
},
|
|
46
|
+
"peerDependenciesMeta": {
|
|
47
|
+
"react-native": {
|
|
48
|
+
"optional": true
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/node": "^20.19.30",
|
|
53
|
+
"eslint": "^8.56.0",
|
|
54
|
+
"tsup": "^8.0.0",
|
|
55
|
+
"typescript": "^5.3.0"
|
|
56
|
+
},
|
|
57
|
+
"engines": {
|
|
58
|
+
"node": ">=18"
|
|
59
|
+
}
|
|
60
|
+
}
|