@ovok/core 0.4.44 → 0.4.46
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 +7 -4
- package/dist/client/auth/session-http.js +17 -1
- package/dist/client/errors/field-errors.d.ts +2 -0
- package/dist/client/errors/field-errors.js +84 -0
- package/dist/client/errors/ovok-error-utils.d.ts +0 -2
- package/dist/client/errors/ovok-error-utils.js +4 -56
- package/dist/client/errors/ovok-error.d.ts +9 -1
- package/dist/client/errors/ovok-error.js +21 -9
- package/dist/client/errors/problem-code.d.ts +5 -0
- package/dist/client/errors/problem-code.js +54 -0
- package/dist/client/ovok-client.d.ts +2 -1
- package/dist/client/ovok-client.js +2 -0
- package/dist/client/wearables/index.d.ts +2 -0
- package/dist/client/wearables/index.js +18 -0
- package/dist/client/wearables/methods.d.ts +11 -0
- package/dist/client/wearables/methods.js +50 -0
- package/dist/client/wearables/types.d.ts +38 -0
- package/dist/client/wearables/types.js +2 -0
- package/dist/conformance/capability-requirements.js +1 -1
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +9 -1
- package/dist/hooks/wearable-invalidation.d.ts +5 -0
- package/dist/hooks/wearable-invalidation.js +22 -0
- package/dist/hooks/wearables-hooks.d.ts +12 -0
- package/dist/hooks/wearables-hooks.js +79 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@ Core TypeScript SDK for healthcare applications. Provides authentication, AI-FHI
|
|
|
18
18
|
- 🧩 Typed accounts, projects, localization, and patient-observation APIs
|
|
19
19
|
- 🏥 Typed Slim patient, device, telemetry, notification, and monitoring APIs
|
|
20
20
|
- 🚨 Typed Signals thresholds, alerts, and project settings APIs
|
|
21
|
+
- ⌚ Typed cloud wearable-provider configuration and patient connections
|
|
21
22
|
|
|
22
23
|
## Installation
|
|
23
24
|
|
|
@@ -322,8 +323,8 @@ when `nextCursor` is `null`. Feed `noteCount` is nullable: `null` means the coun
|
|
|
322
323
|
zero. Notification notes are practitioner-authored and do not acknowledge or otherwise change an
|
|
323
324
|
alert. After a note mutation, mounted note and alert-feed hooks reload their data.
|
|
324
325
|
|
|
325
|
-
Writes can return `OvokApiError`, which keeps the HTTP status, machine code,
|
|
326
|
-
and any missing-baseline details. In particular, reload the affected record before retrying a 409;
|
|
326
|
+
Writes can return `OvokApiError`, which keeps the HTTP status, machine code, problem `type`, `traceId`,
|
|
327
|
+
validation field errors (each with its `FIELD_*` code), and any missing-baseline details. In particular, reload the affected record before retrying a 409;
|
|
327
328
|
do not automatically replay a stale assignment. A 409 `signals_project_migrating` should be shown
|
|
328
329
|
as a temporary home-migration conflict, not retried in a loop. Threshold writes can return 422
|
|
329
330
|
validation errors or 424 when the baseline has not been collected. Hooks never replay a write with
|
|
@@ -374,7 +375,9 @@ try {
|
|
|
374
375
|
|
|
375
376
|
The client also exposes typed application APIs for consent signatures, document upload credentials,
|
|
376
377
|
document download endpoints, CMS content, LiveKit video calls, translation, AI chat, and AI FHIR
|
|
377
|
-
search. These methods are additive and do not change the
|
|
378
|
+
search, and cloud wearable-provider connections. These methods are additive and do not change the
|
|
379
|
+
native observation or offline contracts. See the [wearable connection guide](docs/integrations/wearable-connections.md)
|
|
380
|
+
for provider setup, patient consent, and the app-return flow.
|
|
378
381
|
|
|
379
382
|
```ts
|
|
380
383
|
const content = await client.searchContent("blog", "en-US", { search: "welcome" });
|
|
@@ -398,7 +401,7 @@ download elements; the backend remains responsible for authorization and signed
|
|
|
398
401
|
|
|
399
402
|
The package exports additive hooks for capability discovery, project configuration, patient profile
|
|
400
403
|
and health data, questionnaires, scheduling resources, Slim lists, telemetry, notifications,
|
|
401
|
-
documents, content, video consultations, and localization. Every request hook returns `data`,
|
|
404
|
+
documents, content, video consultations, wearable connections, and localization. Every request hook returns `data`,
|
|
402
405
|
`loading`, `error`, and `reload`; mutations expose `data`, `loading`, `error`, `mutate`, and `reset`.
|
|
403
406
|
|
|
404
407
|
```tsx
|
|
@@ -24,6 +24,22 @@ const retryAfterMs = async (response) => {
|
|
|
24
24
|
}
|
|
25
25
|
};
|
|
26
26
|
exports.retryAfterMs = retryAfterMs;
|
|
27
|
+
// What `readOvokError` reads from Core's error body: the problem members and the legacy ones kept beside them.
|
|
28
|
+
const PRESERVED_ERROR_KEYS = [
|
|
29
|
+
"type",
|
|
30
|
+
"status",
|
|
31
|
+
"detail",
|
|
32
|
+
"instance",
|
|
33
|
+
"traceId",
|
|
34
|
+
"errors",
|
|
35
|
+
"code",
|
|
36
|
+
"error",
|
|
37
|
+
"message",
|
|
38
|
+
"requestId",
|
|
39
|
+
"retryAfterSec",
|
|
40
|
+
"statusCode",
|
|
41
|
+
"missing",
|
|
42
|
+
];
|
|
27
43
|
const timeoutError = () => (0, ovok_error_utils_1.namedError)("TimeoutError", "The request timed out.");
|
|
28
44
|
const withHttpErrorMetadata = async (response, retry) => {
|
|
29
45
|
var _a;
|
|
@@ -47,7 +63,7 @@ const withHttpErrorMetadata = async (response, retry) => {
|
|
|
47
63
|
? envelope.error
|
|
48
64
|
: undefined;
|
|
49
65
|
const safeResponse = envelope
|
|
50
|
-
? Object.fromEntries(Object.entries(envelope).filter(([key]) =>
|
|
66
|
+
? Object.fromEntries(Object.entries(envelope).filter(([key]) => PRESERVED_ERROR_KEYS.includes(key)))
|
|
51
67
|
: { message: typeof body === "string" ? body : response.statusText };
|
|
52
68
|
const status = response.status;
|
|
53
69
|
const retryAfter = retry ? retry.milliseconds : await (0, exports.retryAfterMs)(response);
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readFieldErrors = readFieldErrors;
|
|
4
|
+
const ovok_error_utils_1 = require("./ovok-error-utils");
|
|
5
|
+
function readEnvelopeErrors(values) {
|
|
6
|
+
return values.flatMap((value) => {
|
|
7
|
+
const record = (0, ovok_error_utils_1.asRecord)(value);
|
|
8
|
+
if (!record || typeof record.message !== "string") {
|
|
9
|
+
return [];
|
|
10
|
+
}
|
|
11
|
+
const path = Array.isArray(record.path)
|
|
12
|
+
? record.path.map((segment) => String(segment))
|
|
13
|
+
: [];
|
|
14
|
+
return [{
|
|
15
|
+
...((0, ovok_error_utils_1.stringValue)(record.code) ? { code: (0, ovok_error_utils_1.stringValue)(record.code) } : {}),
|
|
16
|
+
message: record.message,
|
|
17
|
+
path,
|
|
18
|
+
...((0, ovok_error_utils_1.stringValue)(record.validation)
|
|
19
|
+
? { validation: (0, ovok_error_utils_1.stringValue)(record.validation) }
|
|
20
|
+
: {}),
|
|
21
|
+
}];
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
const samePath = (left, right) => left.join(".") === right.join(".");
|
|
25
|
+
/** Core's problem `errors[]` (`{ field, code, params }`), worded by the legacy message Core sends for the same path. */
|
|
26
|
+
function readProblemErrors(values, worded) {
|
|
27
|
+
return values.flatMap((value) => {
|
|
28
|
+
var _a, _b;
|
|
29
|
+
const record = (0, ovok_error_utils_1.asRecord)(value);
|
|
30
|
+
const code = (0, ovok_error_utils_1.stringValue)(record === null || record === void 0 ? void 0 : record.code);
|
|
31
|
+
if (!record || !code || typeof record.message === "string" || !("field" in record)) {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
const path = typeof record.field === "string" ? record.field.split(".").filter(Boolean) : [];
|
|
35
|
+
const message = (_b = (_a = worded.find((entry) => samePath(entry.path, path))) === null || _a === void 0 ? void 0 : _a.message) !== null && _b !== void 0 ? _b : code;
|
|
36
|
+
return [{ code, message, path }];
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function readFieldErrors(payload) {
|
|
40
|
+
const nested = (0, ovok_error_utils_1.asRecord)(payload === null || payload === void 0 ? void 0 : payload.error);
|
|
41
|
+
const listed = Array.isArray(nested === null || nested === void 0 ? void 0 : nested.errors)
|
|
42
|
+
? nested.errors
|
|
43
|
+
: Array.isArray(payload === null || payload === void 0 ? void 0 : payload.errors)
|
|
44
|
+
? payload.errors
|
|
45
|
+
: [];
|
|
46
|
+
const legacy = readEnvelopeErrors(Array.isArray(payload === null || payload === void 0 ? void 0 : payload.message) ? payload.message : []);
|
|
47
|
+
const problemErrors = readProblemErrors(listed, legacy);
|
|
48
|
+
const listedErrors = readEnvelopeErrors(listed);
|
|
49
|
+
// A problem body lists its fields in `errors[]` and keeps the older `message` list beside it; read either.
|
|
50
|
+
const envelopeErrors = problemErrors.length > 0
|
|
51
|
+
? problemErrors
|
|
52
|
+
: listedErrors.length > 0
|
|
53
|
+
? listedErrors
|
|
54
|
+
: legacy;
|
|
55
|
+
const outcome = Array.isArray(payload === null || payload === void 0 ? void 0 : payload.issue) ? payload.issue : [];
|
|
56
|
+
const nestedEnvelopeErrors = outcome.flatMap((value) => {
|
|
57
|
+
var _a;
|
|
58
|
+
const issue = (0, ovok_error_utils_1.asRecord)(value);
|
|
59
|
+
const details = (0, ovok_error_utils_1.asRecord)(issue === null || issue === void 0 ? void 0 : issue.details);
|
|
60
|
+
const nested = (_a = (0, ovok_error_utils_1.asRecord)((0, ovok_error_utils_1.parseJson)(details === null || details === void 0 ? void 0 : details.text))) !== null && _a !== void 0 ? _a : (0, ovok_error_utils_1.asRecord)((0, ovok_error_utils_1.parseJson)(issue === null || issue === void 0 ? void 0 : issue.diagnostics));
|
|
61
|
+
return nested ? readFieldErrors(nested) : [];
|
|
62
|
+
});
|
|
63
|
+
const outcomeErrors = outcome.flatMap((value) => {
|
|
64
|
+
var _a;
|
|
65
|
+
const issue = (0, ovok_error_utils_1.asRecord)(value);
|
|
66
|
+
const details = (0, ovok_error_utils_1.asRecord)(issue === null || issue === void 0 ? void 0 : issue.details);
|
|
67
|
+
const message = (_a = (0, ovok_error_utils_1.stringValue)(details === null || details === void 0 ? void 0 : details.text)) !== null && _a !== void 0 ? _a : (0, ovok_error_utils_1.stringValue)(issue === null || issue === void 0 ? void 0 : issue.diagnostics);
|
|
68
|
+
if ((issue === null || issue === void 0 ? void 0 : issue.severity) !== "error" || !message) {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
const expressions = Array.isArray(issue.expression)
|
|
72
|
+
? issue.expression
|
|
73
|
+
: Array.isArray(issue.location)
|
|
74
|
+
? issue.location
|
|
75
|
+
: [];
|
|
76
|
+
const path = expressions.flatMap((expression) => typeof expression === "string" ? expression.split(".").filter(Boolean) : []);
|
|
77
|
+
return [{
|
|
78
|
+
...((0, ovok_error_utils_1.stringValue)(issue.code) ? { code: (0, ovok_error_utils_1.stringValue)(issue.code) } : {}),
|
|
79
|
+
message,
|
|
80
|
+
path,
|
|
81
|
+
}];
|
|
82
|
+
});
|
|
83
|
+
return [...envelopeErrors, ...nestedEnvelopeErrors, ...outcomeErrors];
|
|
84
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ValidationError } from "../../types/ValidationError";
|
|
2
1
|
export declare const OVOK_HTTP_ERROR_EXTENSION_URL = "https://api.ovok.com/fhir/StructureDefinition/http-error-metadata";
|
|
3
2
|
/** `reason` itself when it is an Error, else an Error carrying its string form. */
|
|
4
3
|
export declare const toError: (reason: unknown) => Error;
|
|
@@ -8,7 +7,6 @@ export declare const namedError: (name: string, message: string) => Error;
|
|
|
8
7
|
export declare const withCause: <T extends Error>(error: T, cause: unknown) => T;
|
|
9
8
|
export declare const asRecord: (value: unknown) => Record<string, unknown> | undefined;
|
|
10
9
|
export declare function readMessage(payload: Record<string, unknown> | undefined, error: unknown): string;
|
|
11
|
-
export declare function readFieldErrors(payload: Record<string, unknown> | undefined): ValidationError[];
|
|
12
10
|
export declare function codeValue(value: unknown): string | undefined;
|
|
13
11
|
export declare function codeFromOutcome(value: unknown): string | undefined;
|
|
14
12
|
export declare function statusFromOutcome(value: unknown): number | undefined;
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.asRecord = exports.withCause = exports.namedError = exports.toError = exports.OVOK_HTTP_ERROR_EXTENSION_URL = void 0;
|
|
4
4
|
exports.readMessage = readMessage;
|
|
5
|
-
exports.readFieldErrors = readFieldErrors;
|
|
6
5
|
exports.codeValue = codeValue;
|
|
7
6
|
exports.codeFromOutcome = codeFromOutcome;
|
|
8
7
|
exports.statusFromOutcome = statusFromOutcome;
|
|
@@ -37,66 +36,15 @@ function readMessage(payload, error) {
|
|
|
37
36
|
return messages.join("; ");
|
|
38
37
|
}
|
|
39
38
|
}
|
|
39
|
+
const detail = stringValue(payload === null || payload === void 0 ? void 0 : payload.detail);
|
|
40
|
+
if (detail) {
|
|
41
|
+
return detail;
|
|
42
|
+
}
|
|
40
43
|
if (error instanceof Error) {
|
|
41
44
|
return error.message;
|
|
42
45
|
}
|
|
43
46
|
return typeof error === "string" ? error : String(error);
|
|
44
47
|
}
|
|
45
|
-
function readFieldErrors(payload) {
|
|
46
|
-
const messageErrors = Array.isArray(payload === null || payload === void 0 ? void 0 : payload.message) ? payload.message : [];
|
|
47
|
-
const nested = (0, exports.asRecord)(payload === null || payload === void 0 ? void 0 : payload.error);
|
|
48
|
-
const rawErrors = Array.isArray(nested === null || nested === void 0 ? void 0 : nested.errors)
|
|
49
|
-
? nested.errors
|
|
50
|
-
: Array.isArray(payload === null || payload === void 0 ? void 0 : payload.errors)
|
|
51
|
-
? payload.errors
|
|
52
|
-
: messageErrors;
|
|
53
|
-
const envelopeErrors = rawErrors.flatMap((value) => {
|
|
54
|
-
const record = (0, exports.asRecord)(value);
|
|
55
|
-
if (!record || typeof record.message !== "string") {
|
|
56
|
-
return [];
|
|
57
|
-
}
|
|
58
|
-
const path = Array.isArray(record.path)
|
|
59
|
-
? record.path.map((segment) => String(segment))
|
|
60
|
-
: [];
|
|
61
|
-
return [{
|
|
62
|
-
...(stringValue(record.code) ? { code: stringValue(record.code) } : {}),
|
|
63
|
-
message: record.message,
|
|
64
|
-
path,
|
|
65
|
-
...(stringValue(record.validation)
|
|
66
|
-
? { validation: stringValue(record.validation) }
|
|
67
|
-
: {}),
|
|
68
|
-
}];
|
|
69
|
-
});
|
|
70
|
-
const outcome = Array.isArray(payload === null || payload === void 0 ? void 0 : payload.issue) ? payload.issue : [];
|
|
71
|
-
const nestedEnvelopeErrors = outcome.flatMap((value) => {
|
|
72
|
-
var _a;
|
|
73
|
-
const issue = (0, exports.asRecord)(value);
|
|
74
|
-
const details = (0, exports.asRecord)(issue === null || issue === void 0 ? void 0 : issue.details);
|
|
75
|
-
const nested = (_a = (0, exports.asRecord)(parseJson(details === null || details === void 0 ? void 0 : details.text))) !== null && _a !== void 0 ? _a : (0, exports.asRecord)(parseJson(issue === null || issue === void 0 ? void 0 : issue.diagnostics));
|
|
76
|
-
return nested ? readFieldErrors(nested) : [];
|
|
77
|
-
});
|
|
78
|
-
const outcomeErrors = outcome.flatMap((value) => {
|
|
79
|
-
var _a;
|
|
80
|
-
const issue = (0, exports.asRecord)(value);
|
|
81
|
-
const details = (0, exports.asRecord)(issue === null || issue === void 0 ? void 0 : issue.details);
|
|
82
|
-
const message = (_a = stringValue(details === null || details === void 0 ? void 0 : details.text)) !== null && _a !== void 0 ? _a : stringValue(issue === null || issue === void 0 ? void 0 : issue.diagnostics);
|
|
83
|
-
if ((issue === null || issue === void 0 ? void 0 : issue.severity) !== "error" || !message) {
|
|
84
|
-
return [];
|
|
85
|
-
}
|
|
86
|
-
const expressions = Array.isArray(issue.expression)
|
|
87
|
-
? issue.expression
|
|
88
|
-
: Array.isArray(issue.location)
|
|
89
|
-
? issue.location
|
|
90
|
-
: [];
|
|
91
|
-
const path = expressions.flatMap((expression) => typeof expression === "string" ? expression.split(".").filter(Boolean) : []);
|
|
92
|
-
return [{
|
|
93
|
-
...(stringValue(issue.code) ? { code: stringValue(issue.code) } : {}),
|
|
94
|
-
message,
|
|
95
|
-
path,
|
|
96
|
-
}];
|
|
97
|
-
});
|
|
98
|
-
return [...envelopeErrors, ...nestedEnvelopeErrors, ...outcomeErrors];
|
|
99
|
-
}
|
|
100
48
|
function codeValue(value) {
|
|
101
49
|
return typeof value === "string" && /^[a-z][a-z0-9_]+$/.test(value)
|
|
102
50
|
? value
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { ValidationError } from "../../types/ValidationError";
|
|
2
|
-
export { asRecord,
|
|
2
|
+
export { asRecord, readMessage } from "./ovok-error-utils";
|
|
3
|
+
export { readFieldErrors } from "./field-errors";
|
|
3
4
|
export type ParsedOvokError = {
|
|
4
5
|
message: string;
|
|
5
6
|
fieldErrors: ValidationError[];
|
|
6
7
|
};
|
|
7
8
|
export type OvokErrorDetails = ParsedOvokError & {
|
|
8
9
|
status: number | undefined;
|
|
10
|
+
/** The condition the server named; undefined when the error is known only by its status. */
|
|
9
11
|
code: string | undefined;
|
|
12
|
+
/** The problem type URI, `https://docs.ovok.com/errors/<code>`, which also names status-only errors. */
|
|
13
|
+
type?: string;
|
|
14
|
+
/** Equals the `x-trace-id` response header; quote it when reporting an error. */
|
|
15
|
+
traceId?: string;
|
|
10
16
|
requestId?: string;
|
|
11
17
|
retryAfterMs?: number;
|
|
12
18
|
missing: string[];
|
|
@@ -17,6 +23,8 @@ export declare const readOvokError: (error: unknown) => OvokErrorDetails;
|
|
|
17
23
|
export declare class OvokApiError extends Error {
|
|
18
24
|
readonly status: number;
|
|
19
25
|
readonly code: string | undefined;
|
|
26
|
+
readonly type: string | undefined;
|
|
27
|
+
readonly traceId: string | undefined;
|
|
20
28
|
readonly fieldErrors: ValidationError[];
|
|
21
29
|
readonly missing: string[];
|
|
22
30
|
readonly requestId: string | undefined;
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.parseOvokError = exports.OvokApiError = exports.readOvokError = exports.
|
|
3
|
+
exports.parseOvokError = exports.OvokApiError = exports.readOvokError = exports.readFieldErrors = exports.readMessage = exports.asRecord = void 0;
|
|
4
4
|
exports.isOvokApiError = isOvokApiError;
|
|
5
5
|
exports.mapOvokApiError = mapOvokApiError;
|
|
6
|
+
const field_errors_1 = require("./field-errors");
|
|
6
7
|
const ovok_error_utils_1 = require("./ovok-error-utils");
|
|
8
|
+
const problem_code_1 = require("./problem-code");
|
|
7
9
|
var ovok_error_utils_2 = require("./ovok-error-utils");
|
|
8
10
|
Object.defineProperty(exports, "asRecord", { enumerable: true, get: function () { return ovok_error_utils_2.asRecord; } });
|
|
9
|
-
Object.defineProperty(exports, "readFieldErrors", { enumerable: true, get: function () { return ovok_error_utils_2.readFieldErrors; } });
|
|
10
11
|
Object.defineProperty(exports, "readMessage", { enumerable: true, get: function () { return ovok_error_utils_2.readMessage; } });
|
|
12
|
+
var field_errors_2 = require("./field-errors");
|
|
13
|
+
Object.defineProperty(exports, "readFieldErrors", { enumerable: true, get: function () { return field_errors_2.readFieldErrors; } });
|
|
11
14
|
const STATUS_BY_BARE_CODE = {
|
|
12
15
|
INVALID_SETTING_VALUE: 422,
|
|
13
16
|
APP_URL_NOT_ALLOWED: 400,
|
|
@@ -26,11 +29,13 @@ const HTTP_REASON_PHRASES = new Set([
|
|
|
26
29
|
]);
|
|
27
30
|
/** Reads the error details Medplum preserves from Ovok's non-FHIR responses. */
|
|
28
31
|
const readOvokError = (error) => {
|
|
29
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y;
|
|
32
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
|
|
30
33
|
if (error instanceof OvokApiError) {
|
|
31
34
|
return {
|
|
32
35
|
status: error.status,
|
|
33
36
|
code: error.code,
|
|
37
|
+
...(error.type === undefined ? {} : { type: error.type }),
|
|
38
|
+
...(error.traceId === undefined ? {} : { traceId: error.traceId }),
|
|
34
39
|
...(error.requestId === undefined ? {} : { requestId: error.requestId }),
|
|
35
40
|
...(error.retryAfterMs === undefined ? {} : { retryAfterMs: error.retryAfterMs }),
|
|
36
41
|
message: error.message,
|
|
@@ -56,18 +61,23 @@ const readOvokError = (error) => {
|
|
|
56
61
|
&& !HTTP_REASON_PHRASES.has(bareMessage.toLowerCase())
|
|
57
62
|
? bareMessage
|
|
58
63
|
: undefined;
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
const
|
|
64
|
+
const writtenCode = (_h = (0, ovok_error_utils_1.stringValue)(nestedError === null || nestedError === void 0 ? void 0 : nestedError.code)) !== null && _h !== void 0 ? _h : (0, ovok_error_utils_1.codeValue)(payload === null || payload === void 0 ? void 0 : payload.error);
|
|
65
|
+
const type = (0, problem_code_1.problemTypeOf)(payload === null || payload === void 0 ? void 0 : payload.type);
|
|
66
|
+
const code = (_o = (_l = (_k = (_j = (0, problem_code_1.conditionCode)((0, problem_code_1.ownCode)(payload === null || payload === void 0 ? void 0 : payload.code), writtenCode)) !== null && _j !== void 0 ? _j : writtenCode) !== null && _k !== void 0 ? _k : bareCode) !== null && _l !== void 0 ? _l : (0, ovok_error_utils_1.codeFromOutcome)((_m = payload === null || payload === void 0 ? void 0 : payload.outcome) !== null && _m !== void 0 ? _m : payload)) !== null && _o !== void 0 ? _o : (0, problem_code_1.problemCodeOf)(type);
|
|
67
|
+
const traceId = (0, ovok_error_utils_1.stringValue)(payload === null || payload === void 0 ? void 0 : payload.traceId);
|
|
68
|
+
const status = (_w = (_u = (_t = (_s = (_r = (_q = (_p = metadata.status) !== null && _p !== void 0 ? _p : (0, ovok_error_utils_1.numberValue)(root === null || root === void 0 ? void 0 : root.status)) !== null && _q !== void 0 ? _q : (0, ovok_error_utils_1.numberValue)(root === null || root === void 0 ? void 0 : root.statusCode)) !== null && _r !== void 0 ? _r : (0, ovok_error_utils_1.numberValue)(response === null || response === void 0 ? void 0 : response.status)) !== null && _s !== void 0 ? _s : (0, ovok_error_utils_1.numberValue)(payload === null || payload === void 0 ? void 0 : payload.status)) !== null && _t !== void 0 ? _t : (0, ovok_error_utils_1.numberValue)(payload === null || payload === void 0 ? void 0 : payload.statusCode)) !== null && _u !== void 0 ? _u : (0, ovok_error_utils_1.statusFromOutcome)((_v = payload === null || payload === void 0 ? void 0 : payload.outcome) !== null && _v !== void 0 ? _v : payload)) !== null && _w !== void 0 ? _w : (code ? STATUS_BY_BARE_CODE[code] : undefined);
|
|
69
|
+
const fieldErrors = (0, field_errors_1.readFieldErrors)(payload);
|
|
62
70
|
const missing = Array.isArray(payload === null || payload === void 0 ? void 0 : payload.missing)
|
|
63
71
|
? payload.missing.filter((entry) => typeof entry === "string")
|
|
64
72
|
: [];
|
|
65
73
|
const retryAfterSec = (0, ovok_error_utils_1.numberValue)(payload === null || payload === void 0 ? void 0 : payload.retryAfterSec);
|
|
66
|
-
const retryAfterMs = (
|
|
67
|
-
const requestId = (
|
|
74
|
+
const retryAfterMs = (_y = (_x = metadata.retryAfterMs) !== null && _x !== void 0 ? _x : (0, ovok_error_utils_1.numberValue)(payload === null || payload === void 0 ? void 0 : payload.retryAfterMs)) !== null && _y !== void 0 ? _y : (retryAfterSec === undefined ? undefined : retryAfterSec * 1000);
|
|
75
|
+
const requestId = (_z = metadata.requestId) !== null && _z !== void 0 ? _z : (0, ovok_error_utils_1.stringValue)(payload === null || payload === void 0 ? void 0 : payload.requestId);
|
|
68
76
|
return {
|
|
69
77
|
status,
|
|
70
78
|
code,
|
|
79
|
+
...(type === undefined ? {} : { type }),
|
|
80
|
+
...(traceId === undefined ? {} : { traceId }),
|
|
71
81
|
...(requestId === undefined ? {} : { requestId }),
|
|
72
82
|
...(retryAfterMs === undefined ? {} : { retryAfterMs }),
|
|
73
83
|
message: (0, ovok_error_utils_1.readMessage)(payload, error),
|
|
@@ -84,6 +94,8 @@ class OvokApiError extends Error {
|
|
|
84
94
|
this.name = "OvokApiError";
|
|
85
95
|
this.status = (_a = details.status) !== null && _a !== void 0 ? _a : 0;
|
|
86
96
|
this.code = details.code;
|
|
97
|
+
this.type = details.type;
|
|
98
|
+
this.traceId = details.traceId;
|
|
87
99
|
this.fieldErrors = details.fieldErrors;
|
|
88
100
|
this.missing = details.missing;
|
|
89
101
|
this.requestId = details.requestId;
|
|
@@ -103,7 +115,7 @@ function mapOvokApiError(error, options = {}) {
|
|
|
103
115
|
}
|
|
104
116
|
const details = (0, exports.readOvokError)(error);
|
|
105
117
|
const typedStatuses = options.includeAccessErrors
|
|
106
|
-
? [403, 404, 409, 410, 422, 424, 503]
|
|
118
|
+
? [403, 404, 409, 410, 422, 424, 501, 503]
|
|
107
119
|
: [409, 410, 422, 424, 503];
|
|
108
120
|
return typedStatuses.includes((_a = details.status) !== null && _a !== void 0 ? _a : 0)
|
|
109
121
|
? new OvokApiError(details, error)
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const ownCode: (value: unknown) => string | undefined;
|
|
2
|
+
/** Core sends a throw site's code upper-cased in `code` and as written in `error`: keep the written form. */
|
|
3
|
+
export declare const conditionCode: (problemCode: string | undefined, writtenCode: string | undefined) => string | undefined;
|
|
4
|
+
export declare const problemTypeOf: (value: unknown) => string | undefined;
|
|
5
|
+
export declare const problemCodeOf: (type: string | undefined) => string | undefined;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.problemCodeOf = exports.problemTypeOf = exports.conditionCode = exports.ownCode = void 0;
|
|
4
|
+
const ovok_error_utils_1 = require("./ovok-error-utils");
|
|
5
|
+
const PROBLEM_TYPE_PREFIX = "https://docs.ovok.com/errors/";
|
|
6
|
+
// The codes Core gives an error by its status alone: they name no condition, so `code` stays undefined for them.
|
|
7
|
+
const STATUS_ONLY_CODES = new Set([
|
|
8
|
+
"MALFORMED_REQUEST",
|
|
9
|
+
"UNAUTHENTICATED",
|
|
10
|
+
"FORBIDDEN",
|
|
11
|
+
"NOT_FOUND",
|
|
12
|
+
"METHOD_NOT_ALLOWED",
|
|
13
|
+
"NOT_ACCEPTABLE",
|
|
14
|
+
"REQUEST_TIMEOUT",
|
|
15
|
+
"CONFLICT",
|
|
16
|
+
"GONE",
|
|
17
|
+
"PRECONDITION_FAILED",
|
|
18
|
+
"CONTENT_TOO_LARGE",
|
|
19
|
+
"UNSUPPORTED_MEDIA_TYPE",
|
|
20
|
+
"VALIDATION_FAILED",
|
|
21
|
+
"LOCKED",
|
|
22
|
+
"FAILED_DEPENDENCY",
|
|
23
|
+
"PRECONDITION_REQUIRED",
|
|
24
|
+
"TOO_MANY_REQUESTS",
|
|
25
|
+
"INTERNAL_ERROR",
|
|
26
|
+
"NOT_IMPLEMENTED",
|
|
27
|
+
"UPSTREAM_ERROR",
|
|
28
|
+
"SERVICE_UNAVAILABLE",
|
|
29
|
+
"UPSTREAM_TIMEOUT",
|
|
30
|
+
"SERVER_ERROR",
|
|
31
|
+
"CLIENT_ERROR",
|
|
32
|
+
]);
|
|
33
|
+
const ownCode = (value) => {
|
|
34
|
+
const code = (0, ovok_error_utils_1.stringValue)(value);
|
|
35
|
+
return code && !STATUS_ONLY_CODES.has(code) ? code : undefined;
|
|
36
|
+
};
|
|
37
|
+
exports.ownCode = ownCode;
|
|
38
|
+
/** Core sends a throw site's code upper-cased in `code` and as written in `error`: keep the written form. */
|
|
39
|
+
const conditionCode = (problemCode, writtenCode) => problemCode && (writtenCode === null || writtenCode === void 0 ? void 0 : writtenCode.toUpperCase()) === problemCode.toUpperCase() ? writtenCode : problemCode;
|
|
40
|
+
exports.conditionCode = conditionCode;
|
|
41
|
+
const problemTypeOf = (value) => {
|
|
42
|
+
const type = (0, ovok_error_utils_1.stringValue)(value);
|
|
43
|
+
return (type === null || type === void 0 ? void 0 : type.startsWith(PROBLEM_TYPE_PREFIX)) ? type : undefined;
|
|
44
|
+
};
|
|
45
|
+
exports.problemTypeOf = problemTypeOf;
|
|
46
|
+
const problemCodeOf = (type) => {
|
|
47
|
+
const slug = type === null || type === void 0 ? void 0 : type.slice(PROBLEM_TYPE_PREFIX.length);
|
|
48
|
+
if (!slug) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
const code = slug.replace(/-/g, "_").toUpperCase();
|
|
52
|
+
return STATUS_ONLY_CODES.has(code) ? undefined : code;
|
|
53
|
+
};
|
|
54
|
+
exports.problemCodeOf = problemCodeOf;
|
|
@@ -23,6 +23,7 @@ import * as platformMethods from "./platform/methods";
|
|
|
23
23
|
import * as questionnaireResponseMethods from "./questionnaire-response/methods";
|
|
24
24
|
import * as signalsMethods from "./signals/methods";
|
|
25
25
|
import * as slimMethods from "./slim/methods";
|
|
26
|
+
import * as wearableMethods from "./wearables/methods";
|
|
26
27
|
export { MAX_CONDITIONAL_OBSERVATION_ENTRIES, MAX_OBSERVATION_BUNDLE_BYTES, } from "./observation/observation-bundle-utils";
|
|
27
28
|
export type { OvokUnauthenticatedReason } from "./auth/session-fetch";
|
|
28
29
|
export type SaveObservationsResult = {
|
|
@@ -146,7 +147,7 @@ export declare class OvokClient extends MedplumClient {
|
|
|
146
147
|
*/
|
|
147
148
|
getSubscriptionManager(): SubscriptionManager;
|
|
148
149
|
}
|
|
149
|
-
type Methods = typeof authMethods & typeof observationMethods & typeof questionnaireResponseMethods & typeof aiMethods & typeof aiFhirMethods & typeof botMethods & typeof slimMethods & typeof emailMethods & typeof cmsMethods & typeof changeHistoryMethods & typeof consentMethods & typeof platformMethods & typeof experienceMethods & typeof inviteMethods & typeof notificationMethods & typeof patientMethods & typeof patientSharingMethods & typeof signalsMethods;
|
|
150
|
+
type Methods = typeof authMethods & typeof observationMethods & typeof questionnaireResponseMethods & typeof aiMethods & typeof aiFhirMethods & typeof botMethods & typeof slimMethods & typeof emailMethods & typeof cmsMethods & typeof changeHistoryMethods & typeof consentMethods & typeof platformMethods & typeof experienceMethods & typeof inviteMethods & typeof notificationMethods & typeof patientMethods & typeof patientSharingMethods & typeof wearableMethods & typeof signalsMethods;
|
|
150
151
|
type Omitted<T> = Omit<T, "executeBot">;
|
|
151
152
|
declare module "./ovok-client" {
|
|
152
153
|
interface OvokClient extends Omitted<Methods> {
|
|
@@ -66,6 +66,7 @@ const request_options_1 = require("./request-options");
|
|
|
66
66
|
const errors_2 = require("./signals/errors");
|
|
67
67
|
const signalsMethods = __importStar(require("./signals/methods"));
|
|
68
68
|
const slimMethods = __importStar(require("./slim/methods"));
|
|
69
|
+
const wearableMethods = __importStar(require("./wearables/methods"));
|
|
69
70
|
var observation_bundle_utils_2 = require("./observation/observation-bundle-utils");
|
|
70
71
|
Object.defineProperty(exports, "MAX_CONDITIONAL_OBSERVATION_ENTRIES", { enumerable: true, get: function () { return observation_bundle_utils_2.MAX_CONDITIONAL_OBSERVATION_ENTRIES; } });
|
|
71
72
|
Object.defineProperty(exports, "MAX_OBSERVATION_BUNDLE_BYTES", { enumerable: true, get: function () { return observation_bundle_utils_2.MAX_OBSERVATION_BUNDLE_BYTES; } });
|
|
@@ -143,6 +144,7 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
143
144
|
this.bindMethods(notificationMethods, (error) => (0, ovok_error_1.mapOvokApiError)((0, rate_limit_error_1.mapRateLimitError)(error), { includeAccessErrors: true }));
|
|
144
145
|
this.bindMethods(patientMethods);
|
|
145
146
|
this.bindMethods(patientSharingMethods);
|
|
147
|
+
this.bindMethods(wearableMethods, (error) => (0, ovok_error_1.mapOvokApiError)((0, rate_limit_error_1.mapRateLimitError)(error), { includeAccessErrors: true }));
|
|
146
148
|
this.bindMethods(signalsMethods, (error) => {
|
|
147
149
|
const mapped = (0, errors_2.mapSignalsError)((0, rate_limit_error_1.mapRateLimitError)(error), {
|
|
148
150
|
signalsRequest: true,
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./methods"), exports);
|
|
18
|
+
__exportStar(require("./types"), exports);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { MedplumRequestOptions } from "@medplum/core";
|
|
2
|
+
import { OvokClient } from "../ovok-client";
|
|
3
|
+
import { CreateWearableProviderRequest, UpdateWearableProviderRequest, WearableConnectionAuthorization, WearableConnections, WearableProvider, WearableProviderSettings, WearableProviderSettingsList } from "./types";
|
|
4
|
+
export declare function listWearableProviders(this: OvokClient, requestOptions?: MedplumRequestOptions): Promise<WearableProviderSettingsList>;
|
|
5
|
+
export declare function getWearableProvider(this: OvokClient, provider: WearableProvider, requestOptions?: MedplumRequestOptions): Promise<WearableProviderSettings>;
|
|
6
|
+
export declare function createWearableProvider(this: OvokClient, body: CreateWearableProviderRequest, requestOptions?: MedplumRequestOptions): Promise<WearableProviderSettings>;
|
|
7
|
+
export declare function updateWearableProvider(this: OvokClient, provider: WearableProvider, body: UpdateWearableProviderRequest, requestOptions?: MedplumRequestOptions): Promise<WearableProviderSettings>;
|
|
8
|
+
export declare function deleteWearableProvider(this: OvokClient, provider: WearableProvider, requestOptions?: MedplumRequestOptions): Promise<void>;
|
|
9
|
+
export declare function listWearableConnections(this: OvokClient, requestOptions?: MedplumRequestOptions): Promise<WearableConnections>;
|
|
10
|
+
export declare function authorizeWearableConnection(this: OvokClient, provider: WearableProvider, requestOptions?: MedplumRequestOptions): Promise<WearableConnectionAuthorization>;
|
|
11
|
+
export declare function deleteWearableConnection(this: OvokClient, provider: WearableProvider, requestOptions?: MedplumRequestOptions): Promise<void>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listWearableProviders = listWearableProviders;
|
|
4
|
+
exports.getWearableProvider = getWearableProvider;
|
|
5
|
+
exports.createWearableProvider = createWearableProvider;
|
|
6
|
+
exports.updateWearableProvider = updateWearableProvider;
|
|
7
|
+
exports.deleteWearableProvider = deleteWearableProvider;
|
|
8
|
+
exports.listWearableConnections = listWearableConnections;
|
|
9
|
+
exports.authorizeWearableConnection = authorizeWearableConnection;
|
|
10
|
+
exports.deleteWearableConnection = deleteWearableConnection;
|
|
11
|
+
const request_options_1 = require("../request-options");
|
|
12
|
+
const providerPath = (provider) => `/v1/wearables/providers/${encodeURIComponent(provider)}`;
|
|
13
|
+
const connectionPath = (provider) => `/v1/wearables/connections/${encodeURIComponent(provider)}`;
|
|
14
|
+
const invalidateProviderSettings = (client, provider) => {
|
|
15
|
+
client.invalidateUrl("/v1/wearables/providers");
|
|
16
|
+
if (provider) {
|
|
17
|
+
client.invalidateUrl(providerPath(provider));
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
function listWearableProviders(requestOptions) {
|
|
21
|
+
return this.get("/v1/wearables/providers", ...(0, request_options_1.optionalArg)(requestOptions));
|
|
22
|
+
}
|
|
23
|
+
function getWearableProvider(provider, requestOptions) {
|
|
24
|
+
return this.get(providerPath(provider), ...(0, request_options_1.optionalArg)(requestOptions));
|
|
25
|
+
}
|
|
26
|
+
function createWearableProvider(body, requestOptions) {
|
|
27
|
+
return this.post("/v1/wearables/providers", body, undefined, requestOptions).then((settings) => {
|
|
28
|
+
invalidateProviderSettings(this, body.provider);
|
|
29
|
+
return settings;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
async function updateWearableProvider(provider, body, requestOptions) {
|
|
33
|
+
const settings = await this.patch(providerPath(provider), body, ...(0, request_options_1.optionalArg)(requestOptions));
|
|
34
|
+
invalidateProviderSettings(this, provider);
|
|
35
|
+
return settings;
|
|
36
|
+
}
|
|
37
|
+
async function deleteWearableProvider(provider, requestOptions) {
|
|
38
|
+
await this.delete(providerPath(provider), ...(0, request_options_1.optionalArg)(requestOptions));
|
|
39
|
+
invalidateProviderSettings(this, provider);
|
|
40
|
+
}
|
|
41
|
+
function listWearableConnections(requestOptions) {
|
|
42
|
+
return this.get("/v1/wearables/connections", ...(0, request_options_1.optionalArg)(requestOptions));
|
|
43
|
+
}
|
|
44
|
+
function authorizeWearableConnection(provider, requestOptions) {
|
|
45
|
+
return this.post(`${connectionPath(provider)}/authorize`, undefined, undefined, requestOptions);
|
|
46
|
+
}
|
|
47
|
+
async function deleteWearableConnection(provider, requestOptions) {
|
|
48
|
+
await this.delete(connectionPath(provider), ...(0, request_options_1.optionalArg)(requestOptions));
|
|
49
|
+
this.invalidateUrl("/v1/wearables/connections");
|
|
50
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export type WearableProvider = "oura" | "whoop" | "strava" | "withings" | "polar" | "suunto" | "garmin" | "ultrahuman";
|
|
2
|
+
export type WearableErrorCode = "PROVIDER_CONFIGURED" | "PROVIDER_NOT_CONFIGURED" | "SUBSCRIPTION_KEY_REQUIRED" | "SUBSCRIPTION_KEY_NOT_USED" | "PROVIDER_NOT_AVAILABLE" | "APP_URL_NOT_CONFIGURED" | "CONNECTION_NOT_FOUND" | "STATE_STORE_UNAVAILABLE" | "FEATURE_NOT_CONFIGURED" | "PROJECT_CONTEXT_REQUIRED" | "PATIENT_PROFILE_REQUIRED";
|
|
3
|
+
export type WearableProviderSettings = {
|
|
4
|
+
provider: WearableProvider;
|
|
5
|
+
configured: boolean;
|
|
6
|
+
enabled: boolean;
|
|
7
|
+
clientId: string | null;
|
|
8
|
+
redirectUri: string | null;
|
|
9
|
+
};
|
|
10
|
+
export type WearableProviderSettingsList = {
|
|
11
|
+
providers: WearableProviderSettings[];
|
|
12
|
+
};
|
|
13
|
+
export type CreateWearableProviderRequest = {
|
|
14
|
+
provider: WearableProvider;
|
|
15
|
+
clientId: string;
|
|
16
|
+
secret: string;
|
|
17
|
+
subscriptionKey: string | null;
|
|
18
|
+
enabled: boolean;
|
|
19
|
+
};
|
|
20
|
+
export type UpdateWearableProviderRequest = {
|
|
21
|
+
clientId?: string;
|
|
22
|
+
secret?: string;
|
|
23
|
+
subscriptionKey?: string | null;
|
|
24
|
+
enabled?: boolean;
|
|
25
|
+
};
|
|
26
|
+
export type WearableConnection = {
|
|
27
|
+
provider: WearableProvider;
|
|
28
|
+
connection: {
|
|
29
|
+
connectedAt: string;
|
|
30
|
+
} | null;
|
|
31
|
+
};
|
|
32
|
+
export type WearableConnections = {
|
|
33
|
+
connections: WearableConnection[];
|
|
34
|
+
};
|
|
35
|
+
export type WearableConnectionAuthorization = {
|
|
36
|
+
provider: WearableProvider;
|
|
37
|
+
authorizationUrl: string;
|
|
38
|
+
};
|
|
@@ -48,7 +48,7 @@ exports.OVOK_CORE_REQUIREMENTS = {
|
|
|
48
48
|
description: "The FHIR surface a server must provide for the @ovok/core client library's own methods to function.",
|
|
49
49
|
software: {
|
|
50
50
|
name: "@ovok/core",
|
|
51
|
-
version: "0.4.
|
|
51
|
+
version: "0.4.46",
|
|
52
52
|
},
|
|
53
53
|
fhirVersion: "4.0.1",
|
|
54
54
|
format: ["json"],
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -21,4 +21,5 @@ export { useCmsDocument, useCmsDocuments, useLegalPage, useReleaseNotes, useTran
|
|
|
21
21
|
export { useAcceptInvite, useInvitePatient, useInvitePractitioner, } from "./invites-hooks";
|
|
22
22
|
export { useCurrentPatientProfile, useExtractQuestionnaireObservations, usePatientAppointments, usePatientCarePlans, usePatientDevices, usePatientMeasurement, usePatientMeasurementHistory, usePatientDashboard, usePatientLatestObservations, usePatientNotifications, usePatientQuestionnaireResponses, usePatientQuestionnaires, usePatientSchedules, usePatientSlots, usePopulateQuestionnaire, useSubmitQuestionnaireResponse, } from "./patient-hooks";
|
|
23
23
|
export { useCreatePatientSharingInvite, usePatientSharing, usePatientSharingSettings, useRedeemPatientSharingInvite, useRevokePatientSharing, useUpdatePatientSharingSettings, } from "./patient-sharing-hooks";
|
|
24
|
+
export { useAuthorizeWearableConnection, useCreateWearableProvider, useDeleteWearableConnection, useDeleteWearableProvider, useUpdateWearableProvider, useWearableConnections, useWearableProviders, } from "./wearables-hooks";
|
|
24
25
|
export { useAcknowledgeSignalsAlert, useEnableSignalsForPatient, useRemoveSignalsThreshold, useSetSignalsThreshold, useSignalsAlert, useSignalsAlerts, useSignalsSettings, useSignalsThresholds, useUpdateSignalsSettings, } from "./signals-hooks";
|
package/dist/hooks/index.js
CHANGED
|
@@ -36,7 +36,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
36
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
37
|
exports.useSlimPatientThresholdV2 = exports.useSetMedicalConsent = exports.useSetLegalConsent = exports.useRepushUnconfirmedLimits = exports.useMedicalConsent = exports.useLegalConsent = exports.useChangeHistory = exports.useEmailTemplates = exports.useUpdateProjectTextSetting = exports.useUpdateLocalization = exports.useUpdateI18nextDocument = exports.useLocalizations = exports.useLocales = exports.useI18nextDocument = exports.useVideoCallAppointments = exports.useVideoCallAccess = exports.useDocuments = exports.useCreateVideoCallUserAccess = exports.useCreateVideoCallAppointment = exports.useContent = exports.useConsentSignature = exports.useOvokPoll = exports.usePublicApiEndpoints = exports.useProjectSettings = exports.useProjectFeatures = exports.useOvokRequest = exports.useOvokMutation = exports.useCapabilityStatement = exports.useSlimPatients = exports.useSlimDevices = exports.useSlimDeviceTelemetry = exports.useAdministeredProjects = exports.useUrineTests = exports.useSaveMeasurement = exports.useObservations = exports.useEcgRecording = exports.observationsToMeasurements = exports.OvokProvider = exports.useClient = exports.useCachedBinaryUrl = exports.reactContext = exports.useSubscription = exports.useSearchResources = exports.useSearchOne = exports.useSearch = exports.useResource = exports.usePrevious = exports.useMedplumProfile = exports.useMedplumNavigate = exports.useMedplumContext = void 0;
|
|
38
38
|
exports.usePatientSharingSettings = exports.usePatientSharing = exports.useCreatePatientSharingInvite = exports.useSubmitQuestionnaireResponse = exports.usePopulateQuestionnaire = exports.usePatientSlots = exports.usePatientSchedules = exports.usePatientQuestionnaires = exports.usePatientQuestionnaireResponses = exports.usePatientNotifications = exports.usePatientLatestObservations = exports.usePatientDashboard = exports.usePatientMeasurementHistory = exports.usePatientMeasurement = exports.usePatientDevices = exports.usePatientCarePlans = exports.usePatientAppointments = exports.useExtractQuestionnaireObservations = exports.useCurrentPatientProfile = exports.useInvitePractitioner = exports.useInvitePatient = exports.useAcceptInvite = exports.useTranslations = exports.useReleaseNotes = exports.useLegalPage = exports.useCmsDocuments = exports.useCmsDocument = exports.useAcknowledgeSlimMedicalNotification = exports.useAcknowledgeSlimAlarm = exports.useUpdateSignalsNote = exports.useUpdateNotificationNote = exports.useSignalsRawAlertNotes = exports.useSignalsAlertNotes = exports.useNotificationNotes = exports.useDeleteSignalsNote = exports.useDeleteNotificationNote = exports.useCreateSignalsRawAlertNote = exports.useCreateSignalsAlertNote = exports.useCreateNotificationNote = exports.useSlimOutOfBedNotifications = exports.useSlimNotifications = exports.useSlimMedicalNotifications = exports.useSlimAlarms = exports.useRecentSlimNotifications = exports.useRecentOutOfBed = exports.useRecentAlarms = exports.useUpdateSlimThresholdV2 = exports.useUpdateSlimPatientThresholdV2 = exports.useUnconfirmedLimits = exports.useSlimThresholdV2 = void 0;
|
|
39
|
-
exports.useUpdateSignalsSettings = exports.useSignalsThresholds = exports.useSignalsSettings = exports.useSignalsAlerts = exports.useSignalsAlert = exports.useSetSignalsThreshold = exports.useRemoveSignalsThreshold = exports.useEnableSignalsForPatient = exports.useAcknowledgeSignalsAlert = exports.useUpdatePatientSharingSettings = exports.useRevokePatientSharing = exports.useRedeemPatientSharingInvite = void 0;
|
|
39
|
+
exports.useUpdateSignalsSettings = exports.useSignalsThresholds = exports.useSignalsSettings = exports.useSignalsAlerts = exports.useSignalsAlert = exports.useSetSignalsThreshold = exports.useRemoveSignalsThreshold = exports.useEnableSignalsForPatient = exports.useAcknowledgeSignalsAlert = exports.useWearableProviders = exports.useWearableConnections = exports.useUpdateWearableProvider = exports.useDeleteWearableProvider = exports.useDeleteWearableConnection = exports.useCreateWearableProvider = exports.useAuthorizeWearableConnection = exports.useUpdatePatientSharingSettings = exports.useRevokePatientSharing = exports.useRedeemPatientSharingInvite = void 0;
|
|
40
40
|
/*
|
|
41
41
|
* The only React-dependent module in the package.
|
|
42
42
|
*
|
|
@@ -176,6 +176,14 @@ Object.defineProperty(exports, "usePatientSharingSettings", { enumerable: true,
|
|
|
176
176
|
Object.defineProperty(exports, "useRedeemPatientSharingInvite", { enumerable: true, get: function () { return patient_sharing_hooks_1.useRedeemPatientSharingInvite; } });
|
|
177
177
|
Object.defineProperty(exports, "useRevokePatientSharing", { enumerable: true, get: function () { return patient_sharing_hooks_1.useRevokePatientSharing; } });
|
|
178
178
|
Object.defineProperty(exports, "useUpdatePatientSharingSettings", { enumerable: true, get: function () { return patient_sharing_hooks_1.useUpdatePatientSharingSettings; } });
|
|
179
|
+
var wearables_hooks_1 = require("./wearables-hooks");
|
|
180
|
+
Object.defineProperty(exports, "useAuthorizeWearableConnection", { enumerable: true, get: function () { return wearables_hooks_1.useAuthorizeWearableConnection; } });
|
|
181
|
+
Object.defineProperty(exports, "useCreateWearableProvider", { enumerable: true, get: function () { return wearables_hooks_1.useCreateWearableProvider; } });
|
|
182
|
+
Object.defineProperty(exports, "useDeleteWearableConnection", { enumerable: true, get: function () { return wearables_hooks_1.useDeleteWearableConnection; } });
|
|
183
|
+
Object.defineProperty(exports, "useDeleteWearableProvider", { enumerable: true, get: function () { return wearables_hooks_1.useDeleteWearableProvider; } });
|
|
184
|
+
Object.defineProperty(exports, "useUpdateWearableProvider", { enumerable: true, get: function () { return wearables_hooks_1.useUpdateWearableProvider; } });
|
|
185
|
+
Object.defineProperty(exports, "useWearableConnections", { enumerable: true, get: function () { return wearables_hooks_1.useWearableConnections; } });
|
|
186
|
+
Object.defineProperty(exports, "useWearableProviders", { enumerable: true, get: function () { return wearables_hooks_1.useWearableProviders; } });
|
|
179
187
|
var signals_hooks_1 = require("./signals-hooks");
|
|
180
188
|
Object.defineProperty(exports, "useAcknowledgeSignalsAlert", { enumerable: true, get: function () { return signals_hooks_1.useAcknowledgeSignalsAlert; } });
|
|
181
189
|
Object.defineProperty(exports, "useEnableSignalsForPatient", { enumerable: true, get: function () { return signals_hooks_1.useEnableSignalsForPatient; } });
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { OvokClient } from "../client/ovok-client";
|
|
2
|
+
type WearableChange = "providers" | "connections";
|
|
3
|
+
export declare const subscribeToWearableChanges: (client: OvokClient, change: WearableChange, reload: () => void) => (() => void);
|
|
4
|
+
export declare const notifyWearableChanges: (client: OvokClient, change: WearableChange) => void;
|
|
5
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.notifyWearableChanges = exports.subscribeToWearableChanges = void 0;
|
|
4
|
+
const listeners = new WeakMap();
|
|
5
|
+
const subscribeToWearableChanges = (client, change, reload) => {
|
|
6
|
+
var _a;
|
|
7
|
+
const listener = (updated) => {
|
|
8
|
+
if (updated === change) {
|
|
9
|
+
reload();
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
const clientListeners = (_a = listeners.get(client)) !== null && _a !== void 0 ? _a : new Set();
|
|
13
|
+
clientListeners.add(listener);
|
|
14
|
+
listeners.set(client, clientListeners);
|
|
15
|
+
return () => clientListeners.delete(listener);
|
|
16
|
+
};
|
|
17
|
+
exports.subscribeToWearableChanges = subscribeToWearableChanges;
|
|
18
|
+
const notifyWearableChanges = (client, change) => {
|
|
19
|
+
var _a;
|
|
20
|
+
(_a = listeners.get(client)) === null || _a === void 0 ? void 0 : _a.forEach((listener) => listener(change));
|
|
21
|
+
};
|
|
22
|
+
exports.notifyWearableChanges = notifyWearableChanges;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CreateWearableProviderRequest, UpdateWearableProviderRequest, WearableConnectionAuthorization, WearableConnections, WearableProvider, WearableProviderSettings, WearableProviderSettingsList } from "../client/wearables";
|
|
2
|
+
import { OvokMutationState, OvokRequestState } from "./api-hooks";
|
|
3
|
+
export declare const useWearableProviders: () => OvokRequestState<WearableProviderSettingsList>;
|
|
4
|
+
export declare const useWearableConnections: () => OvokRequestState<WearableConnections>;
|
|
5
|
+
export declare const useCreateWearableProvider: () => OvokMutationState<CreateWearableProviderRequest, WearableProviderSettings>;
|
|
6
|
+
export declare const useUpdateWearableProvider: () => OvokMutationState<{
|
|
7
|
+
provider: WearableProvider;
|
|
8
|
+
body: UpdateWearableProviderRequest;
|
|
9
|
+
}, WearableProviderSettings>;
|
|
10
|
+
export declare const useDeleteWearableProvider: () => OvokMutationState<WearableProvider, void>;
|
|
11
|
+
export declare const useAuthorizeWearableConnection: () => OvokMutationState<WearableProvider, WearableConnectionAuthorization>;
|
|
12
|
+
export declare const useDeleteWearableConnection: () => OvokMutationState<WearableProvider, void>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.useDeleteWearableConnection = exports.useAuthorizeWearableConnection = exports.useDeleteWearableProvider = exports.useUpdateWearableProvider = exports.useCreateWearableProvider = exports.useWearableConnections = exports.useWearableProviders = void 0;
|
|
38
|
+
const React = __importStar(require("react"));
|
|
39
|
+
const api_hooks_1 = require("./api-hooks");
|
|
40
|
+
const wearable_invalidation_1 = require("./wearable-invalidation");
|
|
41
|
+
const index_1 = require("./index");
|
|
42
|
+
const useWearableProviders = () => {
|
|
43
|
+
const client = (0, index_1.useClient)();
|
|
44
|
+
const state = (0, api_hooks_1.useOvokClientRequest)((current, signal) => current.listWearableProviders({ signal }));
|
|
45
|
+
React.useEffect(() => (0, wearable_invalidation_1.subscribeToWearableChanges)(client, "providers", state.reload), [client, state.reload]);
|
|
46
|
+
return state;
|
|
47
|
+
};
|
|
48
|
+
exports.useWearableProviders = useWearableProviders;
|
|
49
|
+
const useWearableConnections = () => {
|
|
50
|
+
const client = (0, index_1.useClient)();
|
|
51
|
+
const state = (0, api_hooks_1.useOvokClientRequest)((current, signal) => current.listWearableConnections({ signal }));
|
|
52
|
+
React.useEffect(() => (0, wearable_invalidation_1.subscribeToWearableChanges)(client, "connections", state.reload), [client, state.reload]);
|
|
53
|
+
return state;
|
|
54
|
+
};
|
|
55
|
+
exports.useWearableConnections = useWearableConnections;
|
|
56
|
+
const useCreateWearableProvider = () => (0, api_hooks_1.useOvokMutation)(async (client, body) => {
|
|
57
|
+
const settings = await client.createWearableProvider(body);
|
|
58
|
+
(0, wearable_invalidation_1.notifyWearableChanges)(client, "providers");
|
|
59
|
+
return settings;
|
|
60
|
+
});
|
|
61
|
+
exports.useCreateWearableProvider = useCreateWearableProvider;
|
|
62
|
+
const useUpdateWearableProvider = () => (0, api_hooks_1.useOvokMutation)(async (client, { provider, body }) => {
|
|
63
|
+
const settings = await client.updateWearableProvider(provider, body);
|
|
64
|
+
(0, wearable_invalidation_1.notifyWearableChanges)(client, "providers");
|
|
65
|
+
return settings;
|
|
66
|
+
});
|
|
67
|
+
exports.useUpdateWearableProvider = useUpdateWearableProvider;
|
|
68
|
+
const useDeleteWearableProvider = () => (0, api_hooks_1.useOvokMutation)(async (client, provider) => {
|
|
69
|
+
await client.deleteWearableProvider(provider);
|
|
70
|
+
(0, wearable_invalidation_1.notifyWearableChanges)(client, "providers");
|
|
71
|
+
});
|
|
72
|
+
exports.useDeleteWearableProvider = useDeleteWearableProvider;
|
|
73
|
+
const useAuthorizeWearableConnection = () => (0, api_hooks_1.useOvokMutation)((client, provider) => client.authorizeWearableConnection(provider));
|
|
74
|
+
exports.useAuthorizeWearableConnection = useAuthorizeWearableConnection;
|
|
75
|
+
const useDeleteWearableConnection = () => (0, api_hooks_1.useOvokMutation)(async (client, provider) => {
|
|
76
|
+
await client.deleteWearableConnection(provider);
|
|
77
|
+
(0, wearable_invalidation_1.notifyWearableChanges)(client, "connections");
|
|
78
|
+
});
|
|
79
|
+
exports.useDeleteWearableConnection = useDeleteWearableConnection;
|
package/dist/index.d.ts
CHANGED
|
@@ -958,6 +958,7 @@ export * from "./client/slim/paging";
|
|
|
958
958
|
export * from "./client/experience/types";
|
|
959
959
|
export * from "./client/patient/types";
|
|
960
960
|
export * from "./client/patient-sharing";
|
|
961
|
+
export * from "./client/wearables";
|
|
961
962
|
export { SignalsError, isSignalsError, mapSignalsError } from "./client/signals/errors";
|
|
962
963
|
export * from "./client/storage";
|
|
963
964
|
export * from "./client/questionnaire-response/methods";
|
package/dist/index.js
CHANGED
|
@@ -77,6 +77,7 @@ __exportStar(require("./client/slim/paging"), exports);
|
|
|
77
77
|
__exportStar(require("./client/experience/types"), exports);
|
|
78
78
|
__exportStar(require("./client/patient/types"), exports);
|
|
79
79
|
__exportStar(require("./client/patient-sharing"), exports);
|
|
80
|
+
__exportStar(require("./client/wearables"), exports);
|
|
80
81
|
var errors_1 = require("./client/signals/errors");
|
|
81
82
|
Object.defineProperty(exports, "SignalsError", { enumerable: true, get: function () { return errors_1.SignalsError; } });
|
|
82
83
|
Object.defineProperty(exports, "isSignalsError", { enumerable: true, get: function () { return errors_1.isSignalsError; } });
|