@ovok/core 0.4.30 → 0.4.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client/ai-fhir/methods/AIFhirResources.d.ts +2 -1
- package/dist/client/ai-fhir/methods/AIFhirResources.js +2 -2
- package/dist/client/auth/methods/appleLogin.d.ts +2 -1
- package/dist/client/auth/methods/appleLogin.js +2 -2
- package/dist/client/auth/methods/changePassword.d.ts +2 -1
- package/dist/client/auth/methods/changePassword.js +2 -2
- package/dist/client/auth/methods/getSessions.d.ts +2 -1
- package/dist/client/auth/methods/getSessions.js +2 -2
- package/dist/client/auth/methods/googleLogin.d.ts +2 -1
- package/dist/client/auth/methods/googleLogin.js +2 -2
- package/dist/client/auth/methods/index.d.ts +1 -0
- package/dist/client/auth/methods/index.js +1 -0
- package/dist/client/auth/methods/login.d.ts +6 -2
- package/dist/client/auth/methods/login.js +60 -44
- package/dist/client/auth/methods/logout.d.ts +2 -1
- package/dist/client/auth/methods/logout.js +2 -2
- package/dist/client/auth/methods/refetchProfile.d.ts +2 -1
- package/dist/client/auth/methods/refetchProfile.js +3 -4
- package/dist/client/auth/methods/register.d.ts +2 -1
- package/dist/client/auth/methods/register.js +2 -2
- package/dist/client/auth/methods/registerPractitioner.d.ts +2 -1
- package/dist/client/auth/methods/registerPractitioner.js +2 -2
- package/dist/client/auth/methods/reloadSession.d.ts +7 -0
- package/dist/client/auth/methods/reloadSession.js +23 -0
- package/dist/client/auth/methods/requestDeleteUser.d.ts +2 -1
- package/dist/client/auth/methods/requestDeleteUser.js +5 -5
- package/dist/client/auth/methods/resetPassword.d.ts +2 -1
- package/dist/client/auth/methods/resetPassword.js +2 -2
- package/dist/client/auth/methods/revokeSessions.d.ts +2 -1
- package/dist/client/auth/methods/revokeSessions.js +2 -2
- package/dist/client/auth/methods/setPasswordFromReset.d.ts +2 -1
- package/dist/client/auth/methods/setPasswordFromReset.js +2 -2
- package/dist/client/auth/types/LoginBody.d.ts +10 -20
- package/dist/client/auth/types/LoginError.d.ts +15 -0
- package/dist/client/auth/types/LoginError.js +15 -0
- package/dist/client/bot/methods/executeBot.d.ts +2 -1
- package/dist/client/bot/methods/executeBot.js +2 -2
- package/dist/client/change-history/methods.d.ts +2 -1
- package/dist/client/change-history/methods.js +2 -2
- package/dist/client/chat/ai/methods/createAiSession.d.ts +2 -1
- package/dist/client/chat/ai/methods/createAiSession.js +2 -2
- package/dist/client/cms/methods.d.ts +6 -5
- package/dist/client/cms/methods.js +10 -10
- package/dist/client/consent/methods.d.ts +5 -4
- package/dist/client/consent/methods.js +8 -8
- package/dist/client/email/methods.d.ts +2 -1
- package/dist/client/email/methods.js +2 -2
- package/dist/client/errors/ovok-error-utils.d.ts +7 -0
- package/dist/client/errors/ovok-error-utils.js +49 -5
- package/dist/client/errors/ovok-error.d.ts +4 -0
- package/dist/client/errors/ovok-error.js +17 -4
- package/dist/client/errors/rate-limit-error.js +5 -3
- package/dist/client/experience/methods.d.ts +32 -31
- package/dist/client/experience/methods.js +62 -62
- package/dist/client/invites/methods.d.ts +6 -5
- package/dist/client/invites/methods.js +11 -11
- package/dist/client/notifications/methods.d.ts +6 -5
- package/dist/client/notifications/methods.js +10 -10
- package/dist/client/notifications/types.d.ts +92 -11
- package/dist/client/observation/methods/getLatestObservationsByCodes.d.ts +2 -1
- package/dist/client/observation/methods/getLatestObservationsByCodes.js +4 -4
- package/dist/client/offline/offline-measurement-queue.d.ts +4 -3
- package/dist/client/offline/offline-measurement-queue.js +6 -6
- package/dist/client/ovok-client.d.ts +28 -11
- package/dist/client/ovok-client.js +353 -31
- package/dist/client/patient/methods.d.ts +24 -23
- package/dist/client/patient/methods.js +49 -49
- package/dist/client/patient-sharing/methods.d.ts +7 -6
- package/dist/client/patient-sharing/methods.js +12 -12
- package/dist/client/platform/methods.d.ts +24 -23
- package/dist/client/platform/methods.js +46 -46
- package/dist/client/questionnaire-response/methods/createQuestionnaireResponseWithObservations.d.ts +2 -1
- package/dist/client/questionnaire-response/methods/createQuestionnaireResponseWithObservations.js +2 -2
- package/dist/client/questionnaire-response/methods/extractQuestionnaireObservations.d.ts +2 -1
- package/dist/client/questionnaire-response/methods/extractQuestionnaireObservations.js +2 -2
- package/dist/client/questionnaire-response/methods/populateQuestionnaire.d.ts +2 -1
- package/dist/client/questionnaire-response/methods/populateQuestionnaire.js +2 -2
- package/dist/client/questionnaire-response/methods/submitQuestionnaireResponse.d.ts +2 -1
- package/dist/client/questionnaire-response/methods/submitQuestionnaireResponse.js +2 -2
- package/dist/client/signals/methods.d.ts +22 -21
- package/dist/client/signals/methods.js +42 -42
- package/dist/client/slim/methods.d.ts +93 -57
- package/dist/client/slim/methods.js +295 -108
- package/dist/client/slim/paging.d.ts +18 -0
- package/dist/client/slim/paging.js +57 -0
- package/dist/client/slim/types.d.ts +370 -3
- package/dist/conformance/api-requirements.js +22 -0
- package/dist/conformance/capability-requirements.js +1 -1
- package/dist/hooks/account-hooks.js +7 -7
- package/dist/hooks/api-hooks.d.ts +5 -2
- package/dist/hooks/api-hooks.js +39 -16
- package/dist/hooks/cms-hooks.js +3 -3
- package/dist/hooks/email-hooks.js +1 -1
- package/dist/hooks/experience-hooks.js +5 -5
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/index.js +5 -3
- package/dist/hooks/notification-ack-hooks.d.ts +2 -1
- package/dist/hooks/notification-hooks.d.ts +4 -2
- package/dist/hooks/notification-hooks.js +11 -23
- package/dist/hooks/notification-invalidation.d.ts +3 -2
- package/dist/hooks/notification-invalidation.js +10 -1
- package/dist/hooks/notification-note-hooks.js +3 -3
- package/dist/hooks/observation-hooks.d.ts +5 -1
- package/dist/hooks/observation-hooks.js +6 -6
- package/dist/hooks/patient-hooks.js +18 -18
- package/dist/hooks/patient-sharing-hooks.js +2 -2
- package/dist/hooks/platform-hooks.js +3 -3
- package/dist/hooks/poll-hooks.d.ts +14 -0
- package/dist/hooks/poll-hooks.js +127 -0
- package/dist/hooks/signals-alert-hooks.d.ts +5 -20
- package/dist/hooks/signals-alert-hooks.js +38 -34
- package/dist/hooks/signals-alert-item-hooks.d.ts +19 -0
- package/dist/hooks/signals-alert-item-hooks.js +62 -0
- package/dist/hooks/signals-hooks.js +2 -2
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -1
- package/dist/utils/auth/exchange-code.d.ts +2 -0
- package/dist/utils/auth/exchange-code.js +2 -2
- package/dist/utils/auth/handle-tenant-code.d.ts +1 -1
- package/dist/utils/auth/handle-tenant-code.js +13 -4
- package/dist/utils/auth/start-login.d.ts +3 -1
- package/dist/utils/auth/start-login.js +3 -3
- package/package.json +1 -1
|
@@ -47,6 +47,7 @@ const cmsMethods = __importStar(require("./cms/methods"));
|
|
|
47
47
|
const consentMethods = __importStar(require("./consent/methods"));
|
|
48
48
|
const emailMethods = __importStar(require("./email"));
|
|
49
49
|
const ovok_error_1 = require("./errors/ovok-error");
|
|
50
|
+
const ovok_error_utils_1 = require("./errors/ovok-error-utils");
|
|
50
51
|
const rate_limit_error_1 = require("./errors/rate-limit-error");
|
|
51
52
|
const experienceMethods = __importStar(require("./experience/methods"));
|
|
52
53
|
const inviteMethods = __importStar(require("./invites/methods"));
|
|
@@ -64,6 +65,127 @@ const slimMethods = __importStar(require("./slim/methods"));
|
|
|
64
65
|
exports.MAX_CONDITIONAL_OBSERVATION_ENTRIES = 8;
|
|
65
66
|
var observation_bundle_utils_2 = require("./observation/observation-bundle-utils");
|
|
66
67
|
Object.defineProperty(exports, "MAX_OBSERVATION_BUNDLE_BYTES", { enumerable: true, get: function () { return observation_bundle_utils_2.MAX_OBSERVATION_BUNDLE_BYTES; } });
|
|
68
|
+
const retryAfterMs = (response) => {
|
|
69
|
+
var _a, _b;
|
|
70
|
+
const value = (_b = (_a = response.headers) === null || _a === void 0 ? void 0 : _a.get) === null || _b === void 0 ? void 0 : _b.call(_a, "Retry-After");
|
|
71
|
+
if (!value) {
|
|
72
|
+
return undefined;
|
|
73
|
+
}
|
|
74
|
+
const seconds = Number(value);
|
|
75
|
+
if (Number.isFinite(seconds)) {
|
|
76
|
+
return Math.max(0, seconds * 1000);
|
|
77
|
+
}
|
|
78
|
+
const date = Date.parse(value);
|
|
79
|
+
return Number.isFinite(date) ? Math.max(0, date - Date.now()) : undefined;
|
|
80
|
+
};
|
|
81
|
+
const timeoutError = () => {
|
|
82
|
+
const error = new Error("The request timed out.");
|
|
83
|
+
error.name = "TimeoutError";
|
|
84
|
+
return error;
|
|
85
|
+
};
|
|
86
|
+
const withHttpErrorMetadata = async (response) => {
|
|
87
|
+
var _a, _b;
|
|
88
|
+
if (response.ok || typeof response.clone !== "function") {
|
|
89
|
+
return response;
|
|
90
|
+
}
|
|
91
|
+
let bodyText = "";
|
|
92
|
+
let body;
|
|
93
|
+
try {
|
|
94
|
+
bodyText = await response.clone().text();
|
|
95
|
+
body = JSON.parse(bodyText);
|
|
96
|
+
}
|
|
97
|
+
catch (_c) {
|
|
98
|
+
body = undefined;
|
|
99
|
+
}
|
|
100
|
+
const outcome = body && typeof body === "object" && body.resourceType === "OperationOutcome"
|
|
101
|
+
? body
|
|
102
|
+
: undefined;
|
|
103
|
+
const envelope = body && typeof body === "object" ? body : undefined;
|
|
104
|
+
const nestedError = (envelope === null || envelope === void 0 ? void 0 : envelope.error) && typeof envelope.error === "object"
|
|
105
|
+
? envelope.error
|
|
106
|
+
: undefined;
|
|
107
|
+
const safeResponse = envelope
|
|
108
|
+
? Object.fromEntries(Object.entries(envelope).filter(([key]) => ["code", "error", "message", "requestId", "retryAfterSec", "status", "statusCode", "errors", "missing"].includes(key)))
|
|
109
|
+
: { message: typeof body === "string" ? body : response.statusText };
|
|
110
|
+
const status = response.status;
|
|
111
|
+
const retryAfter = (_a = retryAfterMs(response)) !== null && _a !== void 0 ? _a : (typeof (envelope === null || envelope === void 0 ? void 0 : envelope.retryAfterSec) === "number" ? envelope.retryAfterSec * 1000 : undefined);
|
|
112
|
+
const requestId = (_b = response.headers.get("x-request-id")) !== null && _b !== void 0 ? _b : (typeof (envelope === null || envelope === void 0 ? void 0 : envelope.requestId) === "string" ? envelope.requestId : undefined);
|
|
113
|
+
const message = typeof (envelope === null || envelope === void 0 ? void 0 : envelope.message) === "string"
|
|
114
|
+
? envelope.message
|
|
115
|
+
: typeof (nestedError === null || nestedError === void 0 ? void 0 : nestedError.message) === "string"
|
|
116
|
+
? nestedError.message
|
|
117
|
+
: response.statusText || `HTTP ${status}`;
|
|
118
|
+
const extensions = [];
|
|
119
|
+
const addMetadata = (url, value, kind) => {
|
|
120
|
+
if (value !== undefined) {
|
|
121
|
+
extensions.push({ url, [`value${kind}`]: value });
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
addMetadata("status", status, "Integer");
|
|
125
|
+
addMetadata("requestId", requestId, "String");
|
|
126
|
+
addMetadata("retryAfterMs", retryAfter, "Integer");
|
|
127
|
+
if (!outcome) {
|
|
128
|
+
extensions.push({ url: "response", valueString: JSON.stringify(safeResponse) });
|
|
129
|
+
}
|
|
130
|
+
const enrichedOutcome = outcome !== null && outcome !== void 0 ? outcome : {
|
|
131
|
+
resourceType: "OperationOutcome",
|
|
132
|
+
id: "ovok-http-error",
|
|
133
|
+
issue: [{
|
|
134
|
+
severity: "error",
|
|
135
|
+
code: status === 429 ? "throttled" : "exception",
|
|
136
|
+
details: { text: bodyText || message },
|
|
137
|
+
}],
|
|
138
|
+
};
|
|
139
|
+
const existingExtensions = Array.isArray(enrichedOutcome.extension)
|
|
140
|
+
? enrichedOutcome.extension
|
|
141
|
+
: [];
|
|
142
|
+
enrichedOutcome.extension = [
|
|
143
|
+
...existingExtensions,
|
|
144
|
+
{ url: ovok_error_utils_1.OVOK_HTTP_ERROR_EXTENSION_URL, extension: extensions },
|
|
145
|
+
];
|
|
146
|
+
const headers = new Headers(response.headers);
|
|
147
|
+
headers.delete("content-length");
|
|
148
|
+
headers.set("content-type", "application/fhir+json");
|
|
149
|
+
return new Response(JSON.stringify(enrichedOutcome), {
|
|
150
|
+
status,
|
|
151
|
+
statusText: response.statusText,
|
|
152
|
+
headers,
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
const waitForRetry = (milliseconds, signal) => new Promise((resolve, reject) => {
|
|
156
|
+
var _a;
|
|
157
|
+
if (signal === null || signal === void 0 ? void 0 : signal.aborted) {
|
|
158
|
+
const error = new Error("Token refresh aborted");
|
|
159
|
+
error.name = "AbortError";
|
|
160
|
+
reject((_a = signal.reason) !== null && _a !== void 0 ? _a : error);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
const timer = setTimeout(() => {
|
|
164
|
+
signal === null || signal === void 0 ? void 0 : signal.removeEventListener("abort", abort);
|
|
165
|
+
resolve();
|
|
166
|
+
}, milliseconds);
|
|
167
|
+
const abort = () => {
|
|
168
|
+
var _a;
|
|
169
|
+
clearTimeout(timer);
|
|
170
|
+
const error = new Error("Token refresh aborted");
|
|
171
|
+
error.name = "AbortError";
|
|
172
|
+
reject((_a = signal === null || signal === void 0 ? void 0 : signal.reason) !== null && _a !== void 0 ? _a : error);
|
|
173
|
+
};
|
|
174
|
+
signal === null || signal === void 0 ? void 0 : signal.addEventListener("abort", abort, { once: true });
|
|
175
|
+
});
|
|
176
|
+
const isTemporaryRefreshFailure = (status) => status === 429 || (status >= 500 && status <= 599);
|
|
177
|
+
const refreshUnavailableError = (response) => {
|
|
178
|
+
const error = new Error("Token refresh is temporarily unavailable");
|
|
179
|
+
error.name = "NetworkError";
|
|
180
|
+
Object.assign(error, { cause: response });
|
|
181
|
+
return error;
|
|
182
|
+
};
|
|
183
|
+
const refreshResponseError = (response) => {
|
|
184
|
+
const error = new Error(`Token refresh returned HTTP ${response.status}`);
|
|
185
|
+
error.name = "TokenRefreshError";
|
|
186
|
+
Object.assign(error, { status: response.status, cause: response });
|
|
187
|
+
return error;
|
|
188
|
+
};
|
|
67
189
|
const isNetworkError = (error) => {
|
|
68
190
|
if (!(error instanceof Error)) {
|
|
69
191
|
return false;
|
|
@@ -75,6 +197,7 @@ const isNetworkError = (error) => {
|
|
|
75
197
|
}
|
|
76
198
|
return isNetworkError(error.cause);
|
|
77
199
|
};
|
|
200
|
+
const isRetrySafePost = (pathname) => pathname === "/ai/fhir/search";
|
|
78
201
|
class OvokClient extends core_1.MedplumClient {
|
|
79
202
|
/**
|
|
80
203
|
* @param config - The configuration for the client.
|
|
@@ -82,30 +205,217 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
82
205
|
*/
|
|
83
206
|
constructor(config) {
|
|
84
207
|
var _a, _b, _c, _d, _e, _f;
|
|
85
|
-
|
|
208
|
+
if (config.requestTimeoutMs !== undefined && (!Number.isFinite(config.requestTimeoutMs) || config.requestTimeoutMs <= 0)) {
|
|
209
|
+
throw new RangeError("requestTimeoutMs must be a positive finite number.");
|
|
210
|
+
}
|
|
211
|
+
const storage = (_a = config.storage) !== null && _a !== void 0 ? _a : new core_1.ClientStorage(new core_1.MemoryStorage(), config.storagePrefix);
|
|
86
212
|
const fetchImplementation = (_b = config.fetch) !== null && _b !== void 0 ? _b : globalThis.fetch.bind(globalThis);
|
|
87
213
|
const baseUrl = (_c = config.baseUrl) !== null && _c !== void 0 ? _c : "https://api.medplum.com/";
|
|
88
214
|
const normalizedBaseUrl = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
|
|
89
215
|
const tokenUrl = new URL((_d = config.tokenUrl) !== null && _d !== void 0 ? _d : "oauth2/token", normalizedBaseUrl).href;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
216
|
+
let unauthenticatedReason;
|
|
217
|
+
let clearActiveLogin = () => undefined;
|
|
218
|
+
let terminalRefreshToken;
|
|
219
|
+
let terminalRefreshError;
|
|
220
|
+
const isTokenRefresh = (url, options) => new URL(url, normalizedBaseUrl).href === tokenUrl &&
|
|
221
|
+
(options === null || options === void 0 ? void 0 : options.method) === "POST" &&
|
|
222
|
+
typeof options.body === "string" &&
|
|
223
|
+
new URLSearchParams(options.body).get("grant_type") === "refresh_token";
|
|
224
|
+
const markActiveAccountExpired = () => {
|
|
225
|
+
var _a, _b;
|
|
226
|
+
const accountId = (_b = (_a = storage.getObject("activeLogin")) === null || _a === void 0 ? void 0 : _a.profile) === null || _b === void 0 ? void 0 : _b.reference;
|
|
227
|
+
if (accountId) {
|
|
228
|
+
(0, account_storage_1.setStoredAccountExpired)(storage, accountId, true);
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
const fetchOnce = async (url, options) => {
|
|
232
|
+
var _a, _b;
|
|
233
|
+
const requestTimeoutMs = config.requestTimeoutMs;
|
|
234
|
+
let response;
|
|
235
|
+
if (requestTimeoutMs === undefined) {
|
|
236
|
+
response = await fetchImplementation(url, options);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
const controller = new AbortController();
|
|
240
|
+
const callerSignal = options === null || options === void 0 ? void 0 : options.signal;
|
|
241
|
+
let timedOut = false;
|
|
242
|
+
const abortFromCaller = () => controller.abort(callerSignal === null || callerSignal === void 0 ? void 0 : callerSignal.reason);
|
|
243
|
+
const timeout = setTimeout(() => {
|
|
244
|
+
timedOut = true;
|
|
245
|
+
controller.abort(timeoutError());
|
|
246
|
+
}, requestTimeoutMs);
|
|
247
|
+
if (callerSignal === null || callerSignal === void 0 ? void 0 : callerSignal.aborted) {
|
|
248
|
+
abortFromCaller();
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
callerSignal === null || callerSignal === void 0 ? void 0 : callerSignal.addEventListener("abort", abortFromCaller, { once: true });
|
|
252
|
+
}
|
|
253
|
+
try {
|
|
254
|
+
response = await fetchImplementation(url, { ...options, signal: controller.signal });
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
if (timedOut) {
|
|
258
|
+
throw timeoutError();
|
|
259
|
+
}
|
|
260
|
+
throw error;
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
clearTimeout(timeout);
|
|
264
|
+
callerSignal === null || callerSignal === void 0 ? void 0 : callerSignal.removeEventListener("abort", abortFromCaller);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
const requestUrl = new URL(url, normalizedBaseUrl);
|
|
268
|
+
if (isTokenRefresh(url, options)) {
|
|
269
|
+
if (response.status === 400) {
|
|
270
|
+
let invalidGrant = false;
|
|
271
|
+
try {
|
|
272
|
+
invalidGrant = (await response.clone().json()).error === "invalid_grant";
|
|
273
|
+
}
|
|
274
|
+
catch (_c) {
|
|
275
|
+
// Do not sign out unless the response confirms that the refresh token was revoked.
|
|
276
|
+
}
|
|
277
|
+
if (!invalidGrant) {
|
|
278
|
+
throw refreshResponseError(response);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
if ([400, 401, 403].includes(response.status)) {
|
|
282
|
+
unauthenticatedReason = {
|
|
283
|
+
type: "refresh-rejected",
|
|
284
|
+
status: response.status,
|
|
285
|
+
};
|
|
286
|
+
markActiveAccountExpired();
|
|
287
|
+
}
|
|
288
|
+
else if (response.ok) {
|
|
100
289
|
const accountId = (_b = (_a = storage.getObject("activeLogin")) === null || _a === void 0 ? void 0 : _a.profile) === null || _b === void 0 ? void 0 : _b.reference;
|
|
101
290
|
if (accountId) {
|
|
102
|
-
(0, account_storage_1.setStoredAccountExpired)(storage, accountId,
|
|
291
|
+
(0, account_storage_1.setStoredAccountExpired)(storage, accountId, false);
|
|
103
292
|
}
|
|
293
|
+
unauthenticatedReason = undefined;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
else if (requestUrl.href === tokenUrl && !response.ok) {
|
|
297
|
+
unauthenticatedReason = {
|
|
298
|
+
type: "authentication-rejected",
|
|
299
|
+
status: response.status,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
else if (response.status === 401) {
|
|
303
|
+
unauthenticatedReason = { type: "request-unauthorized", status: 401 };
|
|
304
|
+
}
|
|
305
|
+
return isTokenRefresh(url, options)
|
|
306
|
+
? response
|
|
307
|
+
: withHttpErrorMetadata(response);
|
|
308
|
+
};
|
|
309
|
+
const fetchWithRefreshRetry = async (url, options) => {
|
|
310
|
+
var _a, _b, _c, _d;
|
|
311
|
+
const requestUrl = new URL(url, normalizedBaseUrl);
|
|
312
|
+
if (!isTokenRefresh(url, options)) {
|
|
313
|
+
const response = await fetchOnce(url, options);
|
|
314
|
+
const sessionEnded = requestUrl.pathname.endsWith("/auth/session/current") && response.status === 401;
|
|
315
|
+
if (sessionEnded) {
|
|
316
|
+
markActiveAccountExpired();
|
|
317
|
+
}
|
|
318
|
+
return response;
|
|
319
|
+
}
|
|
320
|
+
const login = storage.getObject("activeLogin");
|
|
321
|
+
if (terminalRefreshError) {
|
|
322
|
+
if ((login === null || login === void 0 ? void 0 : login.accessToken) && login.accessToken !== terminalRefreshToken) {
|
|
323
|
+
terminalRefreshToken = undefined;
|
|
324
|
+
terminalRefreshError = undefined;
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
throw terminalRefreshError;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
const expiresAt = (login === null || login === void 0 ? void 0 : login.accessToken) ? (0, core_1.tryGetJwtExpiration)(login.accessToken) : undefined;
|
|
331
|
+
const signal = options === null || options === void 0 ? void 0 : options.signal;
|
|
332
|
+
if (expiresAt !== undefined && options) {
|
|
333
|
+
const tokenRequestOptions = options;
|
|
334
|
+
tokenRequestOptions.maxRetries = 0;
|
|
335
|
+
tokenRequestOptions.maxRetryTime = 0;
|
|
336
|
+
}
|
|
337
|
+
if (expiresAt === undefined) {
|
|
338
|
+
const response = await fetchOnce(url, options);
|
|
339
|
+
if (isTemporaryRefreshFailure(response.status)) {
|
|
340
|
+
void ((_a = response.body) === null || _a === void 0 ? void 0 : _a.cancel().catch(() => undefined));
|
|
341
|
+
throw refreshUnavailableError(response);
|
|
104
342
|
}
|
|
105
343
|
return response;
|
|
344
|
+
}
|
|
345
|
+
let attempt = 0;
|
|
346
|
+
let firstAttempt = true;
|
|
347
|
+
let lastResponse;
|
|
348
|
+
let lastNetworkError;
|
|
349
|
+
while (firstAttempt || Date.now() < expiresAt) {
|
|
350
|
+
firstAttempt = false;
|
|
351
|
+
try {
|
|
352
|
+
lastResponse = await fetchOnce(url, options);
|
|
353
|
+
}
|
|
354
|
+
catch (error) {
|
|
355
|
+
if ((signal === null || signal === void 0 ? void 0 : signal.aborted) || !isNetworkError(error)) {
|
|
356
|
+
throw error;
|
|
357
|
+
}
|
|
358
|
+
if (Date.now() >= expiresAt) {
|
|
359
|
+
lastNetworkError = error;
|
|
360
|
+
break;
|
|
361
|
+
}
|
|
362
|
+
lastNetworkError = error;
|
|
363
|
+
const remainingMs = expiresAt - Date.now();
|
|
364
|
+
const backoffMs = Math.min(500 * (2 ** Math.min(attempt, 6)), 30000);
|
|
365
|
+
await waitForRetry(Math.min(backoffMs, remainingMs), signal);
|
|
366
|
+
attempt += 1;
|
|
367
|
+
continue;
|
|
368
|
+
}
|
|
369
|
+
if (!isTemporaryRefreshFailure(lastResponse.status)) {
|
|
370
|
+
return lastResponse;
|
|
371
|
+
}
|
|
372
|
+
const remainingMs = expiresAt - Date.now();
|
|
373
|
+
if (remainingMs <= 0) {
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
const backoffMs = Math.min(500 * (2 ** Math.min(attempt, 6)), 30000);
|
|
377
|
+
const waitMs = Math.min(Math.max((_b = retryAfterMs(lastResponse)) !== null && _b !== void 0 ? _b : 0, backoffMs), remainingMs);
|
|
378
|
+
if (waitMs >= remainingMs) {
|
|
379
|
+
await waitForRetry(remainingMs, signal);
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
void ((_c = lastResponse.body) === null || _c === void 0 ? void 0 : _c.cancel().catch(() => undefined));
|
|
383
|
+
await waitForRetry(waitMs, signal);
|
|
384
|
+
attempt += 1;
|
|
385
|
+
}
|
|
386
|
+
const status = lastResponse === null || lastResponse === void 0 ? void 0 : lastResponse.status;
|
|
387
|
+
const reason = {
|
|
388
|
+
type: "refresh-unavailable",
|
|
389
|
+
...(status === undefined ? {} : { status }),
|
|
390
|
+
};
|
|
391
|
+
unauthenticatedReason = reason;
|
|
392
|
+
markActiveAccountExpired();
|
|
393
|
+
if (lastResponse) {
|
|
394
|
+
return lastResponse;
|
|
395
|
+
}
|
|
396
|
+
terminalRefreshToken = login === null || login === void 0 ? void 0 : login.accessToken;
|
|
397
|
+
terminalRefreshError = lastNetworkError !== null && lastNetworkError !== void 0 ? lastNetworkError : refreshUnavailableError(undefined);
|
|
398
|
+
clearActiveLogin();
|
|
399
|
+
(_d = config.onUnauthenticated) === null || _d === void 0 ? void 0 : _d.call(config, reason);
|
|
400
|
+
unauthenticatedReason = undefined;
|
|
401
|
+
throw terminalRefreshError;
|
|
402
|
+
};
|
|
403
|
+
super({
|
|
404
|
+
...config,
|
|
405
|
+
storage,
|
|
406
|
+
onUnauthenticated: () => {
|
|
407
|
+
var _a;
|
|
408
|
+
const reason = unauthenticatedReason !== null && unauthenticatedReason !== void 0 ? unauthenticatedReason : {
|
|
409
|
+
type: "request-unauthorized",
|
|
410
|
+
status: 401,
|
|
411
|
+
};
|
|
412
|
+
unauthenticatedReason = undefined;
|
|
413
|
+
(_a = config.onUnauthenticated) === null || _a === void 0 ? void 0 : _a.call(config, reason);
|
|
106
414
|
},
|
|
415
|
+
fetch: fetchWithRefreshRetry,
|
|
107
416
|
});
|
|
108
417
|
this.socialLoginClientId = "";
|
|
418
|
+
clearActiveLogin = this.clearActiveLogin.bind(this);
|
|
109
419
|
this.hasExplicitStorageAdapter = config.storage !== undefined;
|
|
110
420
|
this.socialLoginClientId = (_e = config.socialLoginClientId) !== null && _e !== void 0 ? _e : "";
|
|
111
421
|
this.addEventListener("profileRefreshed", () => this.syncSavedAccountProfile());
|
|
@@ -135,6 +445,13 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
135
445
|
this.clientStorage = storage;
|
|
136
446
|
this.offlineQueueOptions = (_f = config.offlineQueue) !== null && _f !== void 0 ? _f : {};
|
|
137
447
|
}
|
|
448
|
+
post(url, body, contentType, options) {
|
|
449
|
+
const pathname = new URL(url.toString(), this.getBaseUrl()).pathname;
|
|
450
|
+
if (!isRetrySafePost(pathname)) {
|
|
451
|
+
options = { ...options, maxRetries: 0, maxRetryTime: 0 };
|
|
452
|
+
}
|
|
453
|
+
return super.post(url, body, contentType, options);
|
|
454
|
+
}
|
|
138
455
|
/** Lists saved accounts without exposing their access or refresh tokens. */
|
|
139
456
|
getSavedAccounts() {
|
|
140
457
|
var _a, _b;
|
|
@@ -186,7 +503,7 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
186
503
|
* Accounts with an expired server session are removed locally; network and service
|
|
187
504
|
* failures retain the account so it can be removed after connectivity returns.
|
|
188
505
|
*/
|
|
189
|
-
async removeAccount(accountId) {
|
|
506
|
+
async removeAccount(accountId, requestOptions) {
|
|
190
507
|
var _a;
|
|
191
508
|
const login = this.getLogin(accountId);
|
|
192
509
|
if (!login) {
|
|
@@ -196,7 +513,7 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
196
513
|
const previousAccountId = (_a = previousLogin === null || previousLogin === void 0 ? void 0 : previousLogin.profile) === null || _a === void 0 ? void 0 : _a.reference;
|
|
197
514
|
try {
|
|
198
515
|
await this.setActiveLogin(login);
|
|
199
|
-
await this.delete("auth/session/current");
|
|
516
|
+
await this.delete("auth/session/current", ...(requestOptions === undefined ? [] : [requestOptions]));
|
|
200
517
|
}
|
|
201
518
|
catch (error) {
|
|
202
519
|
if (this.getExpiredAccountIds().includes(accountId)) {
|
|
@@ -251,34 +568,34 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
251
568
|
}
|
|
252
569
|
}
|
|
253
570
|
/** Saves a measurement immediately, or durably queues it when the opt-in queue is enabled. */
|
|
254
|
-
async saveMeasurement(params) {
|
|
571
|
+
async saveMeasurement(params, requestOptions) {
|
|
255
572
|
const observations = await this.generateObservationBodiesByMeasurement(params);
|
|
256
|
-
return this.saveObservations(observations);
|
|
573
|
+
return this.saveObservations(observations, ...(requestOptions === undefined ? [] : [requestOptions]));
|
|
257
574
|
}
|
|
258
575
|
/** Reads Ovok's composed FHIR and public-route capability statement. */
|
|
259
|
-
async getCapabilityStatement(version = "R4") {
|
|
260
|
-
return this.get(`/fhir/${version}/metadata
|
|
576
|
+
async getCapabilityStatement(version = "R4", requestOptions) {
|
|
577
|
+
return this.get(`/fhir/${version}/metadata`, ...(requestOptions === undefined ? [] : [requestOptions]));
|
|
261
578
|
}
|
|
262
579
|
/** Returns the non-FHIR public routes published by the backend statement. */
|
|
263
|
-
async getPublicApiEndpoints(version = "R4") {
|
|
264
|
-
return (0, capability_1.getOvokPublicApiEndpoints)(await this.getCapabilityStatement(version));
|
|
580
|
+
async getPublicApiEndpoints(version = "R4", requestOptions) {
|
|
581
|
+
return (0, capability_1.getOvokPublicApiEndpoints)(await this.getCapabilityStatement(version, ...(requestOptions === undefined ? [] : [requestOptions])));
|
|
265
582
|
}
|
|
266
583
|
/** Saves observations with conditional creates so a retry cannot create a duplicate. */
|
|
267
|
-
async saveObservations(observations) {
|
|
584
|
+
async saveObservations(observations, requestOptions) {
|
|
268
585
|
const linkedObservations = (0, observation_bundle_utils_1.linkObservationMembers)(observations);
|
|
269
586
|
const queue = this.getOfflineMeasurementQueue();
|
|
270
587
|
if (queue) {
|
|
271
|
-
const { id, flush } = await queue.enqueueAndFlush(linkedObservations);
|
|
588
|
+
const { id, flush } = await queue.enqueueAndFlush(linkedObservations, ...(requestOptions === undefined ? [] : [requestOptions]));
|
|
272
589
|
const response = flush.responses[id];
|
|
273
590
|
return response
|
|
274
591
|
? { status: "saved", response }
|
|
275
592
|
: { status: "queued", queueId: id };
|
|
276
593
|
}
|
|
277
|
-
const response = await this.executeConditionalObservationCreates(linkedObservations);
|
|
594
|
+
const response = await this.executeConditionalObservationCreates(linkedObservations, requestOptions);
|
|
278
595
|
return { status: "saved", response };
|
|
279
596
|
}
|
|
280
597
|
/** Flushes measurements queued while offline. Call this on connectivity/app-resume events. */
|
|
281
|
-
async flushOfflineMeasurementQueue(options = {}) {
|
|
598
|
+
async flushOfflineMeasurementQueue(options = {}, requestOptions) {
|
|
282
599
|
const queue = this.getOfflineMeasurementQueue();
|
|
283
600
|
if (!queue) {
|
|
284
601
|
return {
|
|
@@ -289,7 +606,7 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
289
606
|
responses: {},
|
|
290
607
|
};
|
|
291
608
|
}
|
|
292
|
-
return queue.flush(options);
|
|
609
|
+
return queue.flush(options, ...(requestOptions === undefined ? [] : [requestOptions]));
|
|
293
610
|
}
|
|
294
611
|
getOfflineMeasurementQueue() {
|
|
295
612
|
var _a;
|
|
@@ -299,7 +616,7 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
299
616
|
if (!this.clientStorage || !this.hasExplicitStorageAdapter) {
|
|
300
617
|
throw new Error("Offline measurement queue requires a durable client storage adapter.");
|
|
301
618
|
}
|
|
302
|
-
(_a = this.offlineMeasurementQueue) !== null && _a !== void 0 ? _a : (this.offlineMeasurementQueue = new offline_1.OfflineMeasurementQueue(this.clientStorage, (bundle) => this.executeObservationBundle(bundle), {
|
|
619
|
+
(_a = this.offlineMeasurementQueue) !== null && _a !== void 0 ? _a : (this.offlineMeasurementQueue = new offline_1.OfflineMeasurementQueue(this.clientStorage, (bundle, requestOptions) => this.executeObservationBundle(bundle, ...(requestOptions === undefined ? [] : [requestOptions])), {
|
|
303
620
|
...this.offlineQueueOptions,
|
|
304
621
|
getOwnerKey: () => {
|
|
305
622
|
var _a, _b, _c;
|
|
@@ -325,8 +642,13 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
325
642
|
clear() {
|
|
326
643
|
var _a, _b, _c;
|
|
327
644
|
const storage = this.clientStorage;
|
|
328
|
-
const logins = this.getLogins();
|
|
329
645
|
const activeAccountId = (_b = (_a = this.getActiveLogin()) === null || _a === void 0 ? void 0 : _a.profile) === null || _b === void 0 ? void 0 : _b.reference;
|
|
646
|
+
const logins = this.getLogins().map((login) => {
|
|
647
|
+
var _a;
|
|
648
|
+
return ((_a = login.profile) === null || _a === void 0 ? void 0 : _a.reference) === activeAccountId
|
|
649
|
+
? { ...login, accessToken: "", refreshToken: "" }
|
|
650
|
+
: login;
|
|
651
|
+
});
|
|
330
652
|
const expiredAccountIds = new Set(this.getExpiredAccountIds());
|
|
331
653
|
if (activeAccountId) {
|
|
332
654
|
expiredAccountIds.add(activeAccountId);
|
|
@@ -384,16 +706,16 @@ class OvokClient extends core_1.MedplumClient {
|
|
|
384
706
|
// Keep the saved login available for a later retry if restoration is offline.
|
|
385
707
|
}
|
|
386
708
|
}
|
|
387
|
-
async executeConditionalObservationCreates(observations) {
|
|
709
|
+
async executeConditionalObservationCreates(observations, requestOptions) {
|
|
388
710
|
const entries = observations.map(offline_1.entryForObservation);
|
|
389
711
|
return this.executeObservationBundle({
|
|
390
712
|
resourceType: "Bundle",
|
|
391
713
|
type: "transaction",
|
|
392
714
|
entry: entries,
|
|
393
|
-
});
|
|
715
|
+
}, ...(requestOptions === undefined ? [] : [requestOptions]));
|
|
394
716
|
}
|
|
395
|
-
async executeObservationBundle(bundle) {
|
|
396
|
-
const response = await (0, observation_bundle_utils_1.executeObservationBundle)(bundle, (request) => this.executeBatch(request));
|
|
717
|
+
async executeObservationBundle(bundle, requestOptions) {
|
|
718
|
+
const response = await (0, observation_bundle_utils_1.executeObservationBundle)(bundle, (request) => this.executeBatch(request, ...(requestOptions === undefined ? [] : [requestOptions])));
|
|
397
719
|
this.invalidateSearches("Observation");
|
|
398
720
|
return response;
|
|
399
721
|
}
|
|
@@ -1,25 +1,26 @@
|
|
|
1
|
+
import type { MedplumRequestOptions } from "@medplum/core";
|
|
1
2
|
import { OvokClient } from "../ovok-client";
|
|
2
3
|
import { OvokCurrentPatientProfile, OvokPatientLatestObservationsQuery, OvokPatientObservationBundle, OvokPatientAppointment, OvokPatientCarePlan, OvokPatientDashboard, OvokPatientDashboardQuery, OvokPatientDevice, OvokPatientMeasurement, OvokPatientNotification, OvokPatientQuestionnaire, OvokPatientQuestionnaireResponse, OvokPatientResourceQuery, OvokPatientSchedule, OvokPatientSchedulingQuery, OvokPatientSlot, OvokPatientTelemetryHistory, OvokPatientTelemetryHistoryQuery } from "./types";
|
|
3
|
-
export declare function getCurrentPatientProfile(this: OvokClient): Promise<OvokCurrentPatientProfile>;
|
|
4
|
-
export declare function getPatientLatestObservations(this: OvokClient, params?: OvokPatientLatestObservationsQuery): Promise<OvokPatientObservationBundle>;
|
|
5
|
-
export declare function getPatientDeviceTelemetry(this: OvokClient, deviceId: string): Promise<OvokPatientObservationBundle>;
|
|
6
|
-
export declare function getPatientDeviceTelemetryHistory(this: OvokClient, deviceId: string, params?: OvokPatientTelemetryHistoryQuery): Promise<OvokPatientTelemetryHistory>;
|
|
7
|
-
export declare function listPatientAppointments(this: OvokClient, params?: OvokPatientSchedulingQuery): Promise<OvokPatientAppointment[]>;
|
|
8
|
-
export declare function getPatientAppointment(this: OvokClient, appointmentId: string): Promise<OvokPatientAppointment>;
|
|
9
|
-
export declare function createPatientAppointment(this: OvokClient, appointment: OvokPatientAppointment): Promise<OvokPatientAppointment>;
|
|
10
|
-
export declare function updatePatientAppointment(this: OvokClient, appointment: OvokPatientAppointment): Promise<OvokPatientAppointment>;
|
|
11
|
-
export declare function listPatientSchedules(this: OvokClient, params?: OvokPatientSchedulingQuery): Promise<OvokPatientSchedule[]>;
|
|
12
|
-
export declare function listPatientSlots(this: OvokClient, params?: OvokPatientSchedulingQuery): Promise<OvokPatientSlot[]>;
|
|
13
|
-
export declare function listPatientMeasurementHistory(this: OvokClient, params?: OvokPatientResourceQuery): Promise<OvokPatientMeasurement[]>;
|
|
14
|
-
export declare function getPatientMeasurement(this: OvokClient, measurementId: string): Promise<OvokPatientMeasurement>;
|
|
15
|
-
export declare function listPatientCarePlans(this: OvokClient, params?: OvokPatientResourceQuery): Promise<OvokPatientCarePlan[]>;
|
|
16
|
-
export declare function getPatientCarePlan(this: OvokClient, carePlanId: string): Promise<OvokPatientCarePlan>;
|
|
17
|
-
export declare function listPatientQuestionnaires(this: OvokClient, params?: OvokPatientResourceQuery): Promise<OvokPatientQuestionnaire[]>;
|
|
18
|
-
export declare function getPatientQuestionnaire(this: OvokClient, questionnaireId: string): Promise<OvokPatientQuestionnaire>;
|
|
19
|
-
export declare function listPatientQuestionnaireResponses(this: OvokClient, params?: OvokPatientResourceQuery): Promise<OvokPatientQuestionnaireResponse[]>;
|
|
20
|
-
export declare function getPatientQuestionnaireResponse(this: OvokClient, questionnaireResponseId: string): Promise<OvokPatientQuestionnaireResponse>;
|
|
21
|
-
export declare function listPatientDevices(this: OvokClient, params?: OvokPatientResourceQuery): Promise<OvokPatientDevice[]>;
|
|
22
|
-
export declare function getPatientDevice(this: OvokClient, deviceId: string): Promise<OvokPatientDevice>;
|
|
23
|
-
export declare function listPatientNotifications(this: OvokClient, params?: OvokPatientResourceQuery): Promise<OvokPatientNotification[]>;
|
|
24
|
-
export declare function getPatientNotification(this: OvokClient, notificationId: string): Promise<OvokPatientNotification>;
|
|
25
|
-
export declare function getPatientDashboard(this: OvokClient, params?: OvokPatientDashboardQuery): Promise<OvokPatientDashboard>;
|
|
4
|
+
export declare function getCurrentPatientProfile(this: OvokClient, requestOptions?: MedplumRequestOptions): Promise<OvokCurrentPatientProfile>;
|
|
5
|
+
export declare function getPatientLatestObservations(this: OvokClient, params?: OvokPatientLatestObservationsQuery, requestOptions?: MedplumRequestOptions): Promise<OvokPatientObservationBundle>;
|
|
6
|
+
export declare function getPatientDeviceTelemetry(this: OvokClient, deviceId: string, requestOptions?: MedplumRequestOptions): Promise<OvokPatientObservationBundle>;
|
|
7
|
+
export declare function getPatientDeviceTelemetryHistory(this: OvokClient, deviceId: string, params?: OvokPatientTelemetryHistoryQuery, requestOptions?: MedplumRequestOptions): Promise<OvokPatientTelemetryHistory>;
|
|
8
|
+
export declare function listPatientAppointments(this: OvokClient, params?: OvokPatientSchedulingQuery, requestOptions?: MedplumRequestOptions): Promise<OvokPatientAppointment[]>;
|
|
9
|
+
export declare function getPatientAppointment(this: OvokClient, appointmentId: string, requestOptions?: MedplumRequestOptions): Promise<OvokPatientAppointment>;
|
|
10
|
+
export declare function createPatientAppointment(this: OvokClient, appointment: OvokPatientAppointment, requestOptions?: MedplumRequestOptions): Promise<OvokPatientAppointment>;
|
|
11
|
+
export declare function updatePatientAppointment(this: OvokClient, appointment: OvokPatientAppointment, requestOptions?: MedplumRequestOptions): Promise<OvokPatientAppointment>;
|
|
12
|
+
export declare function listPatientSchedules(this: OvokClient, params?: OvokPatientSchedulingQuery, requestOptions?: MedplumRequestOptions): Promise<OvokPatientSchedule[]>;
|
|
13
|
+
export declare function listPatientSlots(this: OvokClient, params?: OvokPatientSchedulingQuery, requestOptions?: MedplumRequestOptions): Promise<OvokPatientSlot[]>;
|
|
14
|
+
export declare function listPatientMeasurementHistory(this: OvokClient, params?: OvokPatientResourceQuery, requestOptions?: MedplumRequestOptions): Promise<OvokPatientMeasurement[]>;
|
|
15
|
+
export declare function getPatientMeasurement(this: OvokClient, measurementId: string, requestOptions?: MedplumRequestOptions): Promise<OvokPatientMeasurement>;
|
|
16
|
+
export declare function listPatientCarePlans(this: OvokClient, params?: OvokPatientResourceQuery, requestOptions?: MedplumRequestOptions): Promise<OvokPatientCarePlan[]>;
|
|
17
|
+
export declare function getPatientCarePlan(this: OvokClient, carePlanId: string, requestOptions?: MedplumRequestOptions): Promise<OvokPatientCarePlan>;
|
|
18
|
+
export declare function listPatientQuestionnaires(this: OvokClient, params?: OvokPatientResourceQuery, requestOptions?: MedplumRequestOptions): Promise<OvokPatientQuestionnaire[]>;
|
|
19
|
+
export declare function getPatientQuestionnaire(this: OvokClient, questionnaireId: string, requestOptions?: MedplumRequestOptions): Promise<OvokPatientQuestionnaire>;
|
|
20
|
+
export declare function listPatientQuestionnaireResponses(this: OvokClient, params?: OvokPatientResourceQuery, requestOptions?: MedplumRequestOptions): Promise<OvokPatientQuestionnaireResponse[]>;
|
|
21
|
+
export declare function getPatientQuestionnaireResponse(this: OvokClient, questionnaireResponseId: string, requestOptions?: MedplumRequestOptions): Promise<OvokPatientQuestionnaireResponse>;
|
|
22
|
+
export declare function listPatientDevices(this: OvokClient, params?: OvokPatientResourceQuery, requestOptions?: MedplumRequestOptions): Promise<OvokPatientDevice[]>;
|
|
23
|
+
export declare function getPatientDevice(this: OvokClient, deviceId: string, requestOptions?: MedplumRequestOptions): Promise<OvokPatientDevice>;
|
|
24
|
+
export declare function listPatientNotifications(this: OvokClient, params?: OvokPatientResourceQuery, requestOptions?: MedplumRequestOptions): Promise<OvokPatientNotification[]>;
|
|
25
|
+
export declare function getPatientNotification(this: OvokClient, notificationId: string, requestOptions?: MedplumRequestOptions): Promise<OvokPatientNotification>;
|
|
26
|
+
export declare function getPatientDashboard(this: OvokClient, params?: OvokPatientDashboardQuery, requestOptions?: MedplumRequestOptions): Promise<OvokPatientDashboard>;
|