@ovok/core 0.3.7 → 0.3.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -89,6 +89,48 @@ const alerts = await client.listCarehubMedicalNotifications({ count: 25 });
89
89
  CareHub is intentionally represented as typed application APIs rather than changing the FHIR
90
90
  observation save/offline behavior used by native integrations.
91
91
 
92
+ ## Application APIs
93
+
94
+ The client also exposes typed application APIs for consent signatures, document upload credentials,
95
+ document download endpoints, CMS content, LiveKit video calls, translation, AI chat, and AI FHIR
96
+ search. These methods are additive and do not change the native observation or offline contracts.
97
+
98
+ ```ts
99
+ const content = await client.searchContent("blog", "en-US", { search: "welcome" });
100
+ const appointment = await client.createVideoCallAppointment({
101
+ start: "2026-01-01T10:00:00.000Z",
102
+ end: "2026-01-01T11:00:00.000Z",
103
+ comment: "Check-in",
104
+ videoCallParticipants: [{ email: "patient@example.com" }],
105
+ });
106
+ const translation = await client.translate({
107
+ sourceLanguage: "en",
108
+ targetLanguage: "de",
109
+ text: ["Welcome"],
110
+ });
111
+ ```
112
+
113
+ Document download methods return the backend endpoint URL so applications can use it in media or
114
+ download elements; the backend remains responsible for authorization and signed redirects.
115
+
116
+ ## React hooks
117
+
118
+ The package exports additive hooks for capability discovery, project configuration, CareHub lists,
119
+ telemetry, and notifications. Every request hook returns `data`, `loading`, `error`, and `reload`.
120
+
121
+ ```tsx
122
+ const { data: patients, loading, error } = useCarehubPatients({
123
+ residentState: "active",
124
+ });
125
+
126
+ const saveSettings = useOvokMutation((client, settings: OvokProjectSettings) =>
127
+ client.updateProjectSetting("PATIENT_LOGIN_ENABLED", settings.settings.PATIENT_LOGIN_ENABLED),
128
+ );
129
+ ```
130
+
131
+ Hooks are additive to the existing `OvokProvider`, observation hooks, auth methods, and offline
132
+ queue. Billing remains outside the SDK contract.
133
+
92
134
  ## Offline measurements
93
135
 
94
136
  Pass a durable Medplum storage adapter and opt in to queue measurements while offline:
@@ -0,0 +1,53 @@
1
+ import { OvokClient } from "../ovok-client";
2
+ import { OvokChatMessage, OvokChatMessageInput, OvokChatMessageQuery, OvokChatMessagesResponse, OvokChatSession, OvokChatSessionQuery, OvokChatSessionsResponse, OvokConsentSignatureResponse, OvokContent, OvokContentBody, OvokContentQuery, OvokContentSearchResponse, OvokCreateChatSession, OvokDocumentFile, OvokDocumentMetadataUpdate, OvokDocumentReplacement, OvokDocumentSearchQuery, OvokDocumentSearchResponse, OvokDocumentUploadRequest, OvokMappedContentSearchResponse, OvokTranslationRequest, OvokTranslationResponse, OvokVideoCallAccess, OvokVideoCallAppointment, OvokVideoCallAppointmentInput, OvokVideoCallAppointmentQuery, OvokVideoCallGuestAccess, OvokVideoCallMailRequest, OvokVideoCallMailResponse } from "./types";
3
+ export declare function requestConsentSignature(this: OvokClient, consentId: string): Promise<OvokConsentSignatureResponse>;
4
+ export declare function createDocumentUpload(this: OvokClient, body: OvokDocumentUploadRequest): Promise<OvokDocumentFile>;
5
+ export declare function listDocuments(this: OvokClient, params?: OvokDocumentSearchQuery): Promise<OvokDocumentSearchResponse>;
6
+ /** Returns the authenticated document endpoint; navigating/fetching it follows the backend redirect. */
7
+ export declare function getDocumentDownloadUrl(this: OvokClient, documentId: string, params?: {
8
+ width?: string | number;
9
+ height?: string | number;
10
+ fit?: string;
11
+ }): Promise<string>;
12
+ /** Returns a public document endpoint for use in an image, download, or media element. */
13
+ export declare function getPublicDocumentDownloadUrl(this: OvokClient, token: string, params?: {
14
+ width?: string | number;
15
+ height?: string | number;
16
+ fit?: string;
17
+ }): Promise<string>;
18
+ export declare function deleteDocument(this: OvokClient, documentId: string): Promise<{
19
+ message: string;
20
+ }>;
21
+ export declare function updateDocumentMetadata(this: OvokClient, documentId: string, body: OvokDocumentMetadataUpdate): Promise<OvokDocumentFile>;
22
+ export declare function generateDocumentReplacementUpload(this: OvokClient, documentId: string, body: OvokDocumentReplacement): Promise<OvokDocumentFile>;
23
+ export declare function searchMappedContent(this: OvokClient, type: string, language: string, params?: OvokContentQuery): Promise<OvokMappedContentSearchResponse>;
24
+ export declare function copyContentsFromParent(this: OvokClient, type: string, language: string): Promise<{
25
+ success: boolean;
26
+ }>;
27
+ export declare function copyContentFromParent(this: OvokClient, type: string, language: string, key: string): Promise<{
28
+ success: boolean;
29
+ }>;
30
+ export declare function createContent(this: OvokClient, type: string, language: string, body: OvokContentBody): Promise<OvokContent>;
31
+ export declare function updateContent(this: OvokClient, type: string, language: string, key: string, body: OvokContentBody): Promise<OvokContent>;
32
+ export declare function getContent(this: OvokClient, type: string, language: string, key: string): Promise<OvokContent>;
33
+ export declare function deleteContent(this: OvokClient, type: string, language: string, key: string): Promise<void>;
34
+ export declare function searchContent(this: OvokClient, type: string, language: string, params?: OvokContentQuery): Promise<OvokContentSearchResponse>;
35
+ export declare function createVideoCallAppointment(this: OvokClient, body: OvokVideoCallAppointmentInput): Promise<OvokVideoCallAppointment>;
36
+ export declare function updateVideoCallAppointment(this: OvokClient, appointmentId: string, body: OvokVideoCallAppointmentInput): Promise<OvokVideoCallAppointment>;
37
+ export declare function listVideoCallAppointments(this: OvokClient, params?: OvokVideoCallAppointmentQuery): Promise<OvokVideoCallAppointment[]>;
38
+ export declare function getVideoCallAccessPermission(this: OvokClient, appointmentId: string): Promise<Record<string, unknown>>;
39
+ export declare function createVideoCallGuestAccess(this: OvokClient, appointmentId: string, body: OvokVideoCallGuestAccess): Promise<OvokVideoCallAccess>;
40
+ export declare function createVideoCallUserAccess(this: OvokClient, appointmentId: string): Promise<OvokVideoCallAccess>;
41
+ export declare function sendVideoCallInvite(this: OvokClient, body: OvokVideoCallMailRequest): Promise<OvokVideoCallMailResponse>;
42
+ export declare function sendVideoCallUpdate(this: OvokClient, body: OvokVideoCallMailRequest): Promise<OvokVideoCallMailResponse>;
43
+ export declare function sendVideoCallCancellation(this: OvokClient, body: OvokVideoCallMailRequest): Promise<OvokVideoCallMailResponse>;
44
+ export declare function sendVideoCallActiveNotification(this: OvokClient, appointmentId: string): Promise<Record<string, unknown>>;
45
+ export declare function translate(this: OvokClient, body: OvokTranslationRequest): Promise<OvokTranslationResponse>;
46
+ export declare function createChatSession(this: OvokClient, body: OvokCreateChatSession): Promise<OvokChatSession>;
47
+ export declare function sendChatMessage(this: OvokClient, sessionId: string, body: OvokChatMessageInput): Promise<OvokChatMessage>;
48
+ export declare function listChatSessions(this: OvokClient, params?: OvokChatSessionQuery): Promise<OvokChatSessionsResponse>;
49
+ export declare function getChatSession(this: OvokClient, sessionId: string, params?: {
50
+ messageCount?: number;
51
+ }): Promise<OvokChatSession>;
52
+ export declare function listChatMessages(this: OvokClient, sessionId: string, params?: OvokChatMessageQuery): Promise<OvokChatMessagesResponse>;
53
+ export declare function searchAIFhir(this: OvokClient, request: Record<string, unknown>): Promise<Record<string, unknown>>;
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ /* eslint-disable max-lines -- the experience facade keeps related app APIs discoverable. */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.requestConsentSignature = requestConsentSignature;
5
+ exports.createDocumentUpload = createDocumentUpload;
6
+ exports.listDocuments = listDocuments;
7
+ exports.getDocumentDownloadUrl = getDocumentDownloadUrl;
8
+ exports.getPublicDocumentDownloadUrl = getPublicDocumentDownloadUrl;
9
+ exports.deleteDocument = deleteDocument;
10
+ exports.updateDocumentMetadata = updateDocumentMetadata;
11
+ exports.generateDocumentReplacementUpload = generateDocumentReplacementUpload;
12
+ exports.searchMappedContent = searchMappedContent;
13
+ exports.copyContentsFromParent = copyContentsFromParent;
14
+ exports.copyContentFromParent = copyContentFromParent;
15
+ exports.createContent = createContent;
16
+ exports.updateContent = updateContent;
17
+ exports.getContent = getContent;
18
+ exports.deleteContent = deleteContent;
19
+ exports.searchContent = searchContent;
20
+ exports.createVideoCallAppointment = createVideoCallAppointment;
21
+ exports.updateVideoCallAppointment = updateVideoCallAppointment;
22
+ exports.listVideoCallAppointments = listVideoCallAppointments;
23
+ exports.getVideoCallAccessPermission = getVideoCallAccessPermission;
24
+ exports.createVideoCallGuestAccess = createVideoCallGuestAccess;
25
+ exports.createVideoCallUserAccess = createVideoCallUserAccess;
26
+ exports.sendVideoCallInvite = sendVideoCallInvite;
27
+ exports.sendVideoCallUpdate = sendVideoCallUpdate;
28
+ exports.sendVideoCallCancellation = sendVideoCallCancellation;
29
+ exports.sendVideoCallActiveNotification = sendVideoCallActiveNotification;
30
+ exports.translate = translate;
31
+ exports.createChatSession = createChatSession;
32
+ exports.sendChatMessage = sendChatMessage;
33
+ exports.listChatSessions = listChatSessions;
34
+ exports.getChatSession = getChatSession;
35
+ exports.listChatMessages = listChatMessages;
36
+ exports.searchAIFhir = searchAIFhir;
37
+ const segment = (value) => encodeURIComponent(value);
38
+ const query = (params) => {
39
+ const values = new URLSearchParams();
40
+ for (const [key, value] of Object.entries(params)) {
41
+ if (value !== undefined) {
42
+ values.set(key, String(value));
43
+ }
44
+ }
45
+ const encoded = values.toString();
46
+ return encoded === "" ? "" : `?${encoded}`;
47
+ };
48
+ const documentUrl = (client, path, params) => `${client.getBaseUrl().replace(/\/$/, "")}${path}${query(params)}`;
49
+ async function requestConsentSignature(consentId) {
50
+ return this.post(`/consent/signature/${segment(consentId)}`);
51
+ }
52
+ async function createDocumentUpload(body) {
53
+ return this.post("/document", body);
54
+ }
55
+ async function listDocuments(params = {}) {
56
+ return this.get(`/document${query(params)}`);
57
+ }
58
+ /** Returns the authenticated document endpoint; navigating/fetching it follows the backend redirect. */
59
+ async function getDocumentDownloadUrl(documentId, params = {}) {
60
+ return documentUrl(this, `/document/${segment(documentId)}`, params);
61
+ }
62
+ /** Returns a public document endpoint for use in an image, download, or media element. */
63
+ async function getPublicDocumentDownloadUrl(token, params = {}) {
64
+ return documentUrl(this, `/document/public/${segment(token)}`, params);
65
+ }
66
+ async function deleteDocument(documentId) {
67
+ return (await this.delete(`/document/${segment(documentId)}`));
68
+ }
69
+ async function updateDocumentMetadata(documentId, body) {
70
+ return (await this.patch(`/document/${segment(documentId)}`, body));
71
+ }
72
+ async function generateDocumentReplacementUpload(documentId, body) {
73
+ return this.post(`/document/${segment(documentId)}`, body);
74
+ }
75
+ async function searchMappedContent(type, language, params = {}) {
76
+ return this.get(`/cms/${segment(type)}/map/${segment(language)}${query(params)}`);
77
+ }
78
+ async function copyContentsFromParent(type, language) {
79
+ return this.post(`/cms/${segment(type)}/${segment(language)}/copy-from-parent-project`);
80
+ }
81
+ async function copyContentFromParent(type, language, key) {
82
+ return this.post(`/cms/${segment(type)}/${segment(language)}/${segment(key)}/copy-from-parent-project`);
83
+ }
84
+ async function createContent(type, language, body) {
85
+ return this.post(`/cms/${segment(type)}/${segment(language)}`, body);
86
+ }
87
+ async function updateContent(type, language, key, body) {
88
+ return (await this.put(`/cms/${segment(type)}/${segment(language)}/${segment(key)}`, body));
89
+ }
90
+ async function getContent(type, language, key) {
91
+ return this.get(`/cms/${segment(type)}/${segment(language)}/${segment(key)}`);
92
+ }
93
+ async function deleteContent(type, language, key) {
94
+ await this.delete(`/cms/${segment(type)}/${segment(language)}/${segment(key)}`);
95
+ }
96
+ async function searchContent(type, language, params = {}) {
97
+ return this.get(`/cms/${segment(type)}/${segment(language)}${query(params)}`);
98
+ }
99
+ async function createVideoCallAppointment(body) {
100
+ return this.post("/video-call/livekit/appointment", body);
101
+ }
102
+ async function updateVideoCallAppointment(appointmentId, body) {
103
+ return (await this.put(`/video-call/livekit/appointment/${segment(appointmentId)}`, body));
104
+ }
105
+ async function listVideoCallAppointments(params = {}) {
106
+ return this.get(`/video-call/livekit/appointment${query(params)}`);
107
+ }
108
+ async function getVideoCallAccessPermission(appointmentId) {
109
+ return this.get(`/video-call/livekit/access-permission/${segment(appointmentId)}`);
110
+ }
111
+ async function createVideoCallGuestAccess(appointmentId, body) {
112
+ return this.post(`/video-call/livekit/guest-access/${segment(appointmentId)}`, body);
113
+ }
114
+ async function createVideoCallUserAccess(appointmentId) {
115
+ return this.post(`/video-call/livekit/user-access/${segment(appointmentId)}`);
116
+ }
117
+ async function sendVideoCallInvite(body) {
118
+ return this.post("/video-call/livekit/mail/invite", body);
119
+ }
120
+ async function sendVideoCallUpdate(body) {
121
+ return this.post("/video-call/livekit/mail/update", body);
122
+ }
123
+ async function sendVideoCallCancellation(body) {
124
+ return this.post("/video-call/livekit/mail/cancel", body);
125
+ }
126
+ async function sendVideoCallActiveNotification(appointmentId) {
127
+ return this.post(`/video-call/livekit/notification/active-call/${segment(appointmentId)}`);
128
+ }
129
+ async function translate(body) {
130
+ return this.post("/ai/translation", body);
131
+ }
132
+ async function createChatSession(body) {
133
+ return this.post("/ai/session", body);
134
+ }
135
+ async function sendChatMessage(sessionId, body) {
136
+ return this.post(`/ai/session/${segment(sessionId)}/message`, body);
137
+ }
138
+ async function listChatSessions(params = {}) {
139
+ return this.get(`/ai/session${query(params)}`);
140
+ }
141
+ async function getChatSession(sessionId, params = {}) {
142
+ return this.get(`/ai/session/${segment(sessionId)}${query(params)}`);
143
+ }
144
+ async function listChatMessages(sessionId, params = {}) {
145
+ return this.get(`/ai/session/${segment(sessionId)}/message${query(params)}`);
146
+ }
147
+ async function searchAIFhir(request) {
148
+ return this.post("/ai/fhir/search", request);
149
+ }
@@ -0,0 +1,207 @@
1
+ export type OvokConsentSignatureResponse = {
2
+ numberOfPages: number;
3
+ title: string;
4
+ author: string;
5
+ subject: string;
6
+ documentId: string;
7
+ email: string;
8
+ };
9
+ export type OvokDocumentUploadRequest = {
10
+ fileName: string;
11
+ contentType: string;
12
+ isPublic?: boolean;
13
+ };
14
+ export type OvokDocumentUploadOptions = {
15
+ url: string;
16
+ fields: Record<string, string>;
17
+ };
18
+ export type OvokDocumentFile = {
19
+ id: string;
20
+ meta?: {
21
+ lastUpdated: string;
22
+ };
23
+ author?: {
24
+ reference?: string;
25
+ display?: string;
26
+ };
27
+ fileName?: string;
28
+ contentType?: string;
29
+ uploadOptions?: OvokDocumentUploadOptions;
30
+ publicToken?: string;
31
+ };
32
+ export type OvokDocumentSearchQuery = {
33
+ _count?: number;
34
+ _offset?: number;
35
+ _sort?: string;
36
+ };
37
+ export type OvokDocumentSearchResponse = {
38
+ total: number;
39
+ resources: OvokDocumentFile[];
40
+ };
41
+ export type OvokDocumentMetadataUpdate = {
42
+ fileName?: string;
43
+ isPublic?: boolean;
44
+ contentType?: string;
45
+ };
46
+ export type OvokDocumentReplacement = {
47
+ fileName: string;
48
+ contentType: string;
49
+ isPublic?: boolean;
50
+ };
51
+ export type OvokContentType = "blog" | "video" | "audio" | "template" | "export-template";
52
+ export type OvokContentSection = {
53
+ title?: string;
54
+ text?: string;
55
+ extension?: Record<string, string>;
56
+ code?: string[];
57
+ };
58
+ export type OvokContent = {
59
+ id?: string;
60
+ title: string;
61
+ author: {
62
+ reference: string;
63
+ display?: string;
64
+ };
65
+ key: string;
66
+ language: string;
67
+ date: string;
68
+ projectId?: string;
69
+ type: OvokContentType;
70
+ code?: string;
71
+ category?: string[];
72
+ section?: OvokContentSection[];
73
+ };
74
+ export type OvokContentBody = Pick<OvokContent, "title" | "category" | "section" | "code">;
75
+ export type OvokContentQuery = {
76
+ search?: string;
77
+ code?: string;
78
+ _count?: number;
79
+ _offset?: number;
80
+ };
81
+ export type OvokContentSearchResponse = {
82
+ total: number;
83
+ resources: OvokContent[];
84
+ };
85
+ export type OvokMappedContent = {
86
+ source?: OvokContent;
87
+ target?: OvokContent;
88
+ };
89
+ export type OvokMappedContentSearchResponse = {
90
+ total: number;
91
+ resources: OvokMappedContent[];
92
+ };
93
+ export type OvokVideoCallAppointmentInput = {
94
+ id?: string;
95
+ start: string;
96
+ end: string;
97
+ comment: string;
98
+ description?: string;
99
+ videoCallParticipants: {
100
+ email: string;
101
+ }[];
102
+ };
103
+ export type OvokVideoCallAppointmentStatus = "proposed" | "pending" | "booked" | "arrived" | "fulfilled" | "cancelled" | "noshow" | "entered-in-error" | "checked-in" | "waitlist";
104
+ export type OvokVideoCallAppointment = {
105
+ id: string;
106
+ resourceType: "Appointment";
107
+ status: OvokVideoCallAppointmentStatus;
108
+ start: string;
109
+ end: string;
110
+ comment: string;
111
+ description?: string;
112
+ videoCallParticipants: {
113
+ email: string;
114
+ status: "accepted" | "declined" | "tentative" | "needs-action";
115
+ profileRef: string;
116
+ }[];
117
+ passphrase: string;
118
+ };
119
+ export type OvokVideoCallAppointmentQuery = {
120
+ startDate?: string;
121
+ endDate?: string;
122
+ };
123
+ export type OvokVideoCallGuestAccess = {
124
+ guestEmail: string;
125
+ };
126
+ export type OvokVideoCallAccess = {
127
+ videoCallUrl: string;
128
+ livekitJwt: string;
129
+ passphrase: string;
130
+ };
131
+ export type OvokVideoCallMailRequest = {
132
+ appointmentId: string;
133
+ emailRecipients: {
134
+ email: string;
135
+ profileRef: string;
136
+ }[];
137
+ };
138
+ export type OvokVideoCallMailResponse = {
139
+ appointmentId: string;
140
+ emailRecipientsResult: {
141
+ email: string;
142
+ profileRef: string;
143
+ isEmailSent: boolean;
144
+ }[];
145
+ };
146
+ export type OvokTranslationRequest = {
147
+ sourceLanguage: string;
148
+ targetLanguage: string;
149
+ text: string[];
150
+ };
151
+ export type OvokTranslationResponse = OvokTranslationRequest;
152
+ export type OvokChatMessage = {
153
+ reference: string;
154
+ sender: string;
155
+ content: string;
156
+ sentAt: string;
157
+ mode: "assistant" | "user" | "system";
158
+ };
159
+ export type OvokChatAssistant = {
160
+ system: string;
161
+ context?: string[];
162
+ history?: number;
163
+ participant: string;
164
+ };
165
+ export type OvokCreateChatSession = {
166
+ assistant: OvokChatAssistant;
167
+ participant: string;
168
+ title?: string;
169
+ messages: {
170
+ sender: string;
171
+ content: string;
172
+ mode?: "assistant" | "user" | "system";
173
+ }[];
174
+ };
175
+ export type OvokChatSession = {
176
+ reference?: string;
177
+ participant: string;
178
+ title?: string;
179
+ assistant: OvokChatAssistant;
180
+ messages?: OvokChatMessage[];
181
+ };
182
+ export type OvokChatSessionsResponse = {
183
+ sessions: OvokChatSession[];
184
+ };
185
+ export type OvokChatMessagesResponse = {
186
+ messages: OvokChatMessage[];
187
+ };
188
+ export type OvokChatSessionQuery = {
189
+ _id?: string;
190
+ _sort?: "-sent" | "sent";
191
+ _count?: number;
192
+ _offset?: number;
193
+ messageCount?: number;
194
+ };
195
+ export type OvokChatMessageInput = {
196
+ content: string;
197
+ sender: string;
198
+ mode?: "assistant" | "user" | "system";
199
+ replyTo?: string;
200
+ };
201
+ export type OvokChatMessageQuery = {
202
+ _sort?: "-sent" | "sent";
203
+ _count?: number;
204
+ _offset?: number;
205
+ };
206
+ export type OvokAIFhirRequest = Record<string, unknown>;
207
+ export type OvokAIFhirResponse = Record<string, unknown>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -6,6 +6,7 @@ import * as authMethods from "./auth/methods";
6
6
  import * as botMethods from "./bot/methods";
7
7
  import * as carehubMethods from "./carehub/methods";
8
8
  import * as aiMethods from "./chat/ai/methods";
9
+ import * as experienceMethods from "./experience/methods";
9
10
  import * as observationMethods from "./observation/methods";
10
11
  import { GenerateObservationBodyParams } from "./observation/types/generate-observation-body/GenerateObservationBodyParams";
11
12
  import { OfflineMeasurementFlushOptions, OfflineMeasurementFlushResult, OfflineMeasurementQueueOptions } from "./offline";
@@ -56,7 +57,7 @@ export declare class OvokClient extends MedplumClient {
56
57
  */
57
58
  getSubscriptionManager(): SubscriptionManager;
58
59
  }
59
- type Methods = typeof authMethods & typeof observationMethods & typeof questionnaireResponseMethods & typeof aiMethods & typeof aiFhirMethods & typeof botMethods & typeof carehubMethods & typeof platformMethods;
60
+ type Methods = typeof authMethods & typeof observationMethods & typeof questionnaireResponseMethods & typeof aiMethods & typeof aiFhirMethods & typeof botMethods & typeof carehubMethods & typeof platformMethods & typeof experienceMethods;
60
61
  type Omitted<T> = Omit<T, "executeBot">;
61
62
  declare module "./ovok-client" {
62
63
  interface OvokClient extends Omitted<Methods> {
@@ -43,6 +43,7 @@ const botMethods = __importStar(require("./bot/methods"));
43
43
  const carehubMethods = __importStar(require("./carehub/methods"));
44
44
  const aiMethods = __importStar(require("./chat/ai/methods"));
45
45
  const rate_limit_error_1 = require("./errors/rate-limit-error");
46
+ const experienceMethods = __importStar(require("./experience/methods"));
46
47
  const observationMethods = __importStar(require("./observation/methods"));
47
48
  const observation_bundle_utils_1 = require("./observation/observation-bundle-utils");
48
49
  const offline_1 = require("./offline");
@@ -69,6 +70,7 @@ class OvokClient extends core_1.MedplumClient {
69
70
  this.bindMethods(botMethods);
70
71
  this.bindMethods(carehubMethods);
71
72
  this.bindMethods(platformMethods);
73
+ this.bindMethods(experienceMethods);
72
74
  this.clientStorage = config.storage;
73
75
  this.offlineQueueOptions = (_b = config.offlineQueue) !== null && _b !== void 0 ? _b : {};
74
76
  }
@@ -33,7 +33,38 @@ exports.OVOK_CORE_API_REQUIREMENTS = {
33
33
  { method: "DELETE", path: "/auth/delete", group: "Auth" },
34
34
  { method: "POST", path: "/ai/session", group: "AI" },
35
35
  { method: "POST", path: "/ai/fhir/search", group: "AI" },
36
+ { method: "GET", path: "/ai/session", group: "AI" },
37
+ { method: "GET", path: "/ai/session/:id", group: "AI" },
38
+ { method: "GET", path: "/ai/session/:id/message", group: "AI" },
39
+ { method: "POST", path: "/ai/session/:id/message", group: "AI" },
40
+ { method: "POST", path: "/ai/translation", group: "AI" },
36
41
  { method: "POST", path: "/bots", group: "Bots" },
42
+ { method: "POST", path: "/consent/signature/:consentId", group: "Consent" },
43
+ { method: "POST", path: "/document", group: "Documents" },
44
+ { method: "GET", path: "/document", group: "Documents" },
45
+ { method: "GET", path: "/document/public/:token", group: "Documents" },
46
+ { method: "GET", path: "/document/:id", group: "Documents" },
47
+ { method: "DELETE", path: "/document/:id", group: "Documents" },
48
+ { method: "PATCH", path: "/document/:id", group: "Documents" },
49
+ { method: "POST", path: "/document/:id", group: "Documents" },
50
+ { method: "GET", path: "/cms/:type/map/:language", group: "Content" },
51
+ { method: "POST", path: "/cms/:type/:language/copy-from-parent-project", group: "Content" },
52
+ { method: "POST", path: "/cms/:type/:language/:key/copy-from-parent-project", group: "Content" },
53
+ { method: "POST", path: "/cms/:type/:language", group: "Content" },
54
+ { method: "PUT", path: "/cms/:type/:language/:key", group: "Content" },
55
+ { method: "GET", path: "/cms/:type/:language/:key", group: "Content" },
56
+ { method: "DELETE", path: "/cms/:type/:language/:key", group: "Content" },
57
+ { method: "GET", path: "/cms/:type/:language", group: "Content" },
58
+ { method: "GET", path: "/video-call/livekit/access-permission/:appointmentId", group: "Video" },
59
+ { method: "POST", path: "/video-call/livekit/guest-access/:appointmentId", group: "Video" },
60
+ { method: "POST", path: "/video-call/livekit/user-access/:appointmentId", group: "Video" },
61
+ { method: "POST", path: "/video-call/livekit/appointment", group: "Video" },
62
+ { method: "PUT", path: "/video-call/livekit/appointment/:appointmentId", group: "Video" },
63
+ { method: "GET", path: "/video-call/livekit/appointment", group: "Video" },
64
+ { method: "POST", path: "/video-call/livekit/mail/invite", group: "Video" },
65
+ { method: "POST", path: "/video-call/livekit/mail/update", group: "Video" },
66
+ { method: "POST", path: "/video-call/livekit/mail/cancel", group: "Video" },
67
+ { method: "POST", path: "/video-call/livekit/notification/active-call/:appointmentId", group: "Video" },
37
68
  { method: "GET", path: "/accounts", group: "Accounts" },
38
69
  { method: "GET", path: "/v1/projects", group: "Projects" },
39
70
  { method: "POST", path: "/v1/projects", group: "Projects" },
@@ -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.3.6",
51
+ version: "0.3.8",
52
52
  },
53
53
  fhirVersion: "4.0.1",
54
54
  format: ["json"],
@@ -0,0 +1,39 @@
1
+ import { CapabilityStatement } from "@medplum/fhirtypes";
2
+ import { CarehubDeviceListItem, CarehubDeviceListQuery, CarehubDeviceTelemetry, CarehubNotificationsQuery, CarehubNotificationsResponse, CarehubPage, CarehubPatientListItem, CarehubPatientListQuery, CarehubRecentNotificationsResponse } from "../client/carehub/types";
3
+ import { OvokClient, OvokFhirVersion } from "../client/ovok-client";
4
+ import { OvokAdministeredProject, OvokProjectFeatures, OvokProjectSettings } from "../client/platform/types";
5
+ import { OvokPublicApiEndpoint } from "../conformance/capability";
6
+ export type OvokRequestState<T> = {
7
+ data: T | undefined;
8
+ loading: boolean;
9
+ error: Error | undefined;
10
+ reload: () => void;
11
+ };
12
+ export type OvokMutationState<TParams, TData> = {
13
+ data: TData | undefined;
14
+ loading: boolean;
15
+ error: Error | undefined;
16
+ mutate: (params: TParams) => Promise<TData>;
17
+ reset: () => void;
18
+ };
19
+ /**
20
+ * Small request primitive for the typed Ovok hooks. It deliberately does not
21
+ * add a cache or retry policy: MedplumClient already owns request caching and
22
+ * the host app owns the retry policy appropriate to its screen.
23
+ */
24
+ export declare function useOvokRequest<T>(load: () => Promise<T>, enabled?: boolean): OvokRequestState<T>;
25
+ /** Generic mutation hook for any typed OvokClient method. */
26
+ export declare function useOvokMutation<TParams, TData>(mutateRequest: (client: OvokClient, params: TParams) => Promise<TData>): OvokMutationState<TParams, TData>;
27
+ export declare const useCapabilityStatement: (version?: OvokFhirVersion) => OvokRequestState<CapabilityStatement>;
28
+ export declare const usePublicApiEndpoints: (version?: OvokFhirVersion) => OvokRequestState<OvokPublicApiEndpoint[]>;
29
+ export declare const useAdministeredProjects: (params?: {
30
+ page?: number;
31
+ count?: number;
32
+ }) => OvokRequestState<CarehubPage<OvokAdministeredProject>>;
33
+ export declare const useProjectSettings: () => OvokRequestState<OvokProjectSettings>;
34
+ export declare const useProjectFeatures: () => OvokRequestState<OvokProjectFeatures>;
35
+ export declare const useCarehubPatients: (params?: CarehubPatientListQuery) => OvokRequestState<CarehubPage<CarehubPatientListItem>>;
36
+ export declare const useCarehubDevices: (params?: CarehubDeviceListQuery) => OvokRequestState<CarehubPage<CarehubDeviceListItem>>;
37
+ export declare const useCarehubDeviceTelemetry: (deviceId?: string) => OvokRequestState<CarehubDeviceTelemetry>;
38
+ export declare const useCarehubNotifications: (params?: CarehubNotificationsQuery) => OvokRequestState<CarehubNotificationsResponse>;
39
+ export declare const useRecentCarehubNotifications: (count?: number) => OvokRequestState<CarehubRecentNotificationsResponse>;
@@ -0,0 +1,179 @@
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.useRecentCarehubNotifications = exports.useCarehubNotifications = exports.useCarehubDeviceTelemetry = exports.useCarehubDevices = exports.useCarehubPatients = exports.useProjectFeatures = exports.useProjectSettings = exports.useAdministeredProjects = exports.usePublicApiEndpoints = exports.useCapabilityStatement = void 0;
38
+ exports.useOvokRequest = useOvokRequest;
39
+ exports.useOvokMutation = useOvokMutation;
40
+ const React = __importStar(require("react"));
41
+ const index_1 = require("./index");
42
+ const toError = (error) => error instanceof Error ? error : new Error(String(error));
43
+ /**
44
+ * Small request primitive for the typed Ovok hooks. It deliberately does not
45
+ * add a cache or retry policy: MedplumClient already owns request caching and
46
+ * the host app owns the retry policy appropriate to its screen.
47
+ */
48
+ function useOvokRequest(load, enabled = true) {
49
+ const [data, setData] = React.useState();
50
+ const [error, setError] = React.useState();
51
+ const [loading, setLoading] = React.useState(enabled);
52
+ const [revision, setRevision] = React.useState(0);
53
+ React.useEffect(() => {
54
+ let disposed = false;
55
+ if (!enabled) {
56
+ setLoading(false);
57
+ setError(undefined);
58
+ return () => {
59
+ disposed = true;
60
+ };
61
+ }
62
+ setLoading(true);
63
+ setError(undefined);
64
+ load()
65
+ .then((value) => {
66
+ if (!disposed) {
67
+ setData(value);
68
+ setLoading(false);
69
+ }
70
+ })
71
+ .catch((reason) => {
72
+ if (!disposed) {
73
+ setError(toError(reason));
74
+ setLoading(false);
75
+ }
76
+ });
77
+ return () => {
78
+ disposed = true;
79
+ };
80
+ }, [enabled, load, revision]);
81
+ const reload = React.useCallback(() => setRevision((value) => value + 1), []);
82
+ return { data, loading, error, reload };
83
+ }
84
+ /** Generic mutation hook for any typed OvokClient method. */
85
+ function useOvokMutation(mutateRequest) {
86
+ const client = (0, index_1.useClient)();
87
+ const [data, setData] = React.useState();
88
+ const [error, setError] = React.useState();
89
+ const [loading, setLoading] = React.useState(false);
90
+ const mutate = React.useCallback(async (params) => {
91
+ setLoading(true);
92
+ setError(undefined);
93
+ try {
94
+ const value = await mutateRequest(client, params);
95
+ setData(value);
96
+ return value;
97
+ }
98
+ catch (reason) {
99
+ const requestError = toError(reason);
100
+ setError(requestError);
101
+ throw requestError;
102
+ }
103
+ finally {
104
+ setLoading(false);
105
+ }
106
+ }, [client, mutateRequest]);
107
+ const reset = React.useCallback(() => {
108
+ setData(undefined);
109
+ setError(undefined);
110
+ setLoading(false);
111
+ }, []);
112
+ return { data, loading, error, mutate, reset };
113
+ }
114
+ const useCapabilityStatement = (version = "R4") => {
115
+ const client = (0, index_1.useClient)();
116
+ const load = React.useCallback(() => client.getCapabilityStatement(version), [client, version]);
117
+ return useOvokRequest(load);
118
+ };
119
+ exports.useCapabilityStatement = useCapabilityStatement;
120
+ const usePublicApiEndpoints = (version = "R4") => {
121
+ const client = (0, index_1.useClient)();
122
+ const load = React.useCallback(() => client.getPublicApiEndpoints(version), [client, version]);
123
+ return useOvokRequest(load);
124
+ };
125
+ exports.usePublicApiEndpoints = usePublicApiEndpoints;
126
+ const useAdministeredProjects = (params = {}) => {
127
+ const client = (0, index_1.useClient)();
128
+ const serialized = JSON.stringify(params);
129
+ const load = React.useCallback(() => client.listAdministeredProjects(params), [client, serialized]);
130
+ return useOvokRequest(load);
131
+ };
132
+ exports.useAdministeredProjects = useAdministeredProjects;
133
+ const useProjectSettings = () => {
134
+ const client = (0, index_1.useClient)();
135
+ const load = React.useCallback(() => client.getProjectSettings(), [client]);
136
+ return useOvokRequest(load);
137
+ };
138
+ exports.useProjectSettings = useProjectSettings;
139
+ const useProjectFeatures = () => {
140
+ const client = (0, index_1.useClient)();
141
+ const load = React.useCallback(() => client.getProjectFeatures(), [client]);
142
+ return useOvokRequest(load);
143
+ };
144
+ exports.useProjectFeatures = useProjectFeatures;
145
+ const useCarehubPatients = (params = {}) => {
146
+ const client = (0, index_1.useClient)();
147
+ const serialized = JSON.stringify(params);
148
+ const load = React.useCallback(() => client.listCarehubPatients(params), [client, serialized]);
149
+ return useOvokRequest(load);
150
+ };
151
+ exports.useCarehubPatients = useCarehubPatients;
152
+ const useCarehubDevices = (params = {}) => {
153
+ const client = (0, index_1.useClient)();
154
+ const serialized = JSON.stringify(params);
155
+ const load = React.useCallback(() => client.listCarehubDevices(params), [client, serialized]);
156
+ return useOvokRequest(load);
157
+ };
158
+ exports.useCarehubDevices = useCarehubDevices;
159
+ const useCarehubDeviceTelemetry = (deviceId) => {
160
+ const client = (0, index_1.useClient)();
161
+ const load = React.useCallback(() => deviceId
162
+ ? client.getCarehubDeviceTelemetry(deviceId)
163
+ : Promise.reject(new Error("deviceId is required")), [client, deviceId]);
164
+ return useOvokRequest(load, deviceId !== undefined);
165
+ };
166
+ exports.useCarehubDeviceTelemetry = useCarehubDeviceTelemetry;
167
+ const useCarehubNotifications = (params = {}) => {
168
+ const client = (0, index_1.useClient)();
169
+ const serialized = JSON.stringify(params);
170
+ const load = React.useCallback(() => client.listCarehubNotifications(params), [client, serialized]);
171
+ return useOvokRequest(load);
172
+ };
173
+ exports.useCarehubNotifications = useCarehubNotifications;
174
+ const useRecentCarehubNotifications = (count) => {
175
+ const client = (0, index_1.useClient)();
176
+ const load = React.useCallback(() => client.getRecentCarehubNotifications(count), [client, count]);
177
+ return useOvokRequest(load);
178
+ };
179
+ exports.useRecentCarehubNotifications = useRecentCarehubNotifications;
@@ -6,3 +6,4 @@ export declare const OvokProvider: (props: React.PropsWithChildren<{
6
6
  client: OvokClient;
7
7
  }>) => React.JSX.Element;
8
8
  export { observationsToMeasurements, useEcgRecording, useObservations, useSaveMeasurement, useUrineTests, } from "./observation-hooks";
9
+ export { useAdministeredProjects, useCarehubDeviceTelemetry, useCarehubDevices, useCarehubNotifications, useCarehubPatients, useCapabilityStatement, useOvokMutation, useOvokRequest, useProjectFeatures, useProjectSettings, usePublicApiEndpoints, useRecentCarehubNotifications, } from "./api-hooks";
@@ -34,7 +34,7 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  };
35
35
  })();
36
36
  Object.defineProperty(exports, "__esModule", { value: true });
37
- 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;
37
+ exports.useRecentCarehubNotifications = exports.usePublicApiEndpoints = exports.useProjectSettings = exports.useProjectFeatures = exports.useOvokRequest = exports.useOvokMutation = exports.useCapabilityStatement = exports.useCarehubPatients = exports.useCarehubNotifications = exports.useCarehubDevices = exports.useCarehubDeviceTelemetry = 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
  /*
39
39
  * The only React-dependent module in the package.
40
40
  *
@@ -76,3 +76,16 @@ Object.defineProperty(exports, "useEcgRecording", { enumerable: true, get: funct
76
76
  Object.defineProperty(exports, "useObservations", { enumerable: true, get: function () { return observation_hooks_1.useObservations; } });
77
77
  Object.defineProperty(exports, "useSaveMeasurement", { enumerable: true, get: function () { return observation_hooks_1.useSaveMeasurement; } });
78
78
  Object.defineProperty(exports, "useUrineTests", { enumerable: true, get: function () { return observation_hooks_1.useUrineTests; } });
79
+ var api_hooks_1 = require("./api-hooks");
80
+ Object.defineProperty(exports, "useAdministeredProjects", { enumerable: true, get: function () { return api_hooks_1.useAdministeredProjects; } });
81
+ Object.defineProperty(exports, "useCarehubDeviceTelemetry", { enumerable: true, get: function () { return api_hooks_1.useCarehubDeviceTelemetry; } });
82
+ Object.defineProperty(exports, "useCarehubDevices", { enumerable: true, get: function () { return api_hooks_1.useCarehubDevices; } });
83
+ Object.defineProperty(exports, "useCarehubNotifications", { enumerable: true, get: function () { return api_hooks_1.useCarehubNotifications; } });
84
+ Object.defineProperty(exports, "useCarehubPatients", { enumerable: true, get: function () { return api_hooks_1.useCarehubPatients; } });
85
+ Object.defineProperty(exports, "useCapabilityStatement", { enumerable: true, get: function () { return api_hooks_1.useCapabilityStatement; } });
86
+ Object.defineProperty(exports, "useOvokMutation", { enumerable: true, get: function () { return api_hooks_1.useOvokMutation; } });
87
+ Object.defineProperty(exports, "useOvokRequest", { enumerable: true, get: function () { return api_hooks_1.useOvokRequest; } });
88
+ Object.defineProperty(exports, "useProjectFeatures", { enumerable: true, get: function () { return api_hooks_1.useProjectFeatures; } });
89
+ Object.defineProperty(exports, "useProjectSettings", { enumerable: true, get: function () { return api_hooks_1.useProjectSettings; } });
90
+ Object.defineProperty(exports, "usePublicApiEndpoints", { enumerable: true, get: function () { return api_hooks_1.usePublicApiEndpoints; } });
91
+ Object.defineProperty(exports, "useRecentCarehubNotifications", { enumerable: true, get: function () { return api_hooks_1.useRecentCarehubNotifications; } });
package/dist/index.d.ts CHANGED
@@ -937,3 +937,4 @@ export * from "./conformance/api-requirements";
937
937
  export * from "./conformance/capability";
938
938
  export * from "./client/platform/types";
939
939
  export * from "./client/carehub/types";
940
+ export * from "./client/experience/types";
package/dist/index.js CHANGED
@@ -60,3 +60,4 @@ __exportStar(require("./conformance/api-requirements"), exports);
60
60
  __exportStar(require("./conformance/capability"), exports);
61
61
  __exportStar(require("./client/platform/types"), exports);
62
62
  __exportStar(require("./client/carehub/types"), exports);
63
+ __exportStar(require("./client/experience/types"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ovok/core",
3
- "version": "0.3.7",
3
+ "version": "0.3.9",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",