@ovok/core 0.4.46 → 0.4.48

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
@@ -628,30 +628,58 @@ turning the feature on; an unmapped email can still produce the uniform 202
628
628
  response without sending a message. `useUpdatePatientSharingSettings()` is the
629
629
  corresponding mutation hook.
630
630
 
631
- `listPatientSharing()` returns `outgoing`, `incoming`, and `practitioners`;
632
- the latter lists active shares of a patient's whole record with practitioners.
633
- For compatibility with older servers, the SDK defaults a missing `practitioners`
634
- array to `[]`. Listing is patient-only (403 for another profile).
631
+ `listPatientSharing()` returns `outgoing`, `incoming`, `practitioners`,
632
+ `relatedPersons`, and `received`. `practitioners` lists active shares of a patient's
633
+ whole record with practitioners; `relatedPersons` lists the Observation codes a
634
+ patient shares with carers. `received` is for a signed-in carer: the shares patients
635
+ gave them, each with the sharing patient and its `codes`. A carer gets only
636
+ `received`, and a patient always gets an empty `received`. For compatibility with
637
+ older servers, the SDK defaults any missing `practitioners`, `relatedPersons` or
638
+ `received` array to `[]`. Listing is for patients and carers; a practitioner gets 403.
635
639
  `revokePatientSharing(consentId)` uses the existing DELETE route
636
- to end a share immediately or decline a pending invite. It returns 204; 404
637
- (`Share not found.`) means the caller is not a party, and a code-less 409
638
- (`This share kept changing; try again.`) can be retried after reloading. A
640
+ to end a share immediately or decline a pending invite. A carer calls it with a
641
+ `received` share's `consentId` to leave that share. It returns 204; 404
642
+ (`Share not found.`) means the caller is not a party, and a 409 means the share
643
+ already ended or kept changing; reload the list and retry. A
639
644
  practitioner's whole-record share has no measurement-code list.
640
645
 
641
- Invitations use four client methods, all backed by `/v1/invites/*`:
646
+ Invitations are named by purpose, all backed by `/v1/invites/*`:
642
647
 
643
648
  ```typescript
644
- await client.invitePractitioner({ email, firstName, lastName }); // patient invites practitioner
645
- await client.invitePatient({ email, firstName, lastName }); // practitioner invites patient
646
- await client.acceptPractitionerInvite({ inviteId, code });
647
- await client.acceptPatientInvite({ inviteId, code });
648
-
649
- // Or dispatch acceptance using the signed-in profile:
649
+ // A patient shares their record with a practitioner…
650
+ await client.shareRecord({ recipient: "practitioner", email, firstName, lastName });
651
+ // …or shares some Observation codes with a carer (a related person).
652
+ await client.shareRecord({ recipient: "related-person", email, firstName, lastName, codes: ["8480-6"] });
653
+ await client.acceptRecordShare({ inviteId, code }); // practitioner or existing carer, signed in
654
+ await client.acceptRecordShare({ inviteId, code, password }); // new carer, signed out
655
+
656
+ // A practitioner invites a patient into their care.
657
+ await client.inviteToCare({ email, firstName, lastName });
658
+ await client.acceptCareInvite({ inviteId, code }); // patient, signed in
659
+
660
+ // Or dispatch acceptance using the signed-in Practitioner or Patient profile:
650
661
  await client.acceptInvite({ inviteId, code });
651
662
  ```
652
663
 
653
- `useInvitePractitioner()`, `useInvitePatient()`, and `useAcceptInvite()` provide
654
- React mutation states. The invite methods always return `{ status: "sent" }`
664
+ `useShareRecord()`, `useAcceptRecordShare()`, `useInviteToCare()`,
665
+ `useAcceptCareInvite()`, and `useAcceptInvite()` provide React mutation states.
666
+
667
+ `invitePractitioner()`, `invitePatient()`, `acceptPractitionerInvite()`,
668
+ `acceptPatientInvite()`, `useInvitePractitioner()`, and `useInvitePatient()` are
669
+ deprecated. Their routes (`/v1/invites/practitioner`, `/v1/invites/patient` and
670
+ their `/accept` routes) sunset on 2026-12-01; move to `shareRecord()`,
671
+ `inviteToCare()`, `acceptRecordShare()`, and `acceptCareInvite()` before then.
672
+
673
+ A carer accepts a record share from the patient app. A carer new to the project
674
+ accepts signed out and sends a `password`; that creates their account, and they
675
+ then sign in with `login({ type: "RelatedPerson", email, password, tenantCode })`.
676
+ There is no carer registration route. A 422 `password_required` means the invite
677
+ needs a password; a 409 `address_has_account` means the address already has an
678
+ account, so the patient must send a new invite. Carer sharing needs patient
679
+ sharing enabled and `RELATED_PERSON_INVITATION_ENABLED` not set to `false`; carer
680
+ sign-in needs `RELATED_PERSON_LOGIN_ENABLED` not set to `false`. Map the
681
+ `RELATED_PERSON_INVITED` and `RELATED_PERSON_RECORD_SHARED` email templates
682
+ before inviting carers. The invite methods always return `{ status: "sent" }`
655
683
  (HTTP 202), whether or not an email is ultimately sent. Show only “If that
656
684
  address can be invited, an email is on its way”; the response must not reveal
657
685
  whether the address has an account. Both names are trimmed by Core, and email
@@ -666,7 +694,9 @@ invite can also fail with 401 (no session), 403 (feature/role gate), 422 (invali
666
694
  body), 409 `invitation_not_configured` (missing default policy),
667
695
  `app_url_not_configured` (missing audience app URL), or
668
696
  `practitioner_without_access_policy` (a full-access practitioner cannot be
669
- narrowed to a share policy). A code-less 409 means another invite for the same
697
+ narrowed to a share policy). Accepting a record share can also return 409
698
+ `related_person_without_access_policy` or `sharing_not_configured` (patient
699
+ sharing lost its template; turn it on again). A code-less 409 means another invite for the same
670
700
  address or practitioner is still being written; offer retry. A 429 means the
671
701
  inviter has 20 pending invites. Use
672
702
  `readOvokError(error)` and `OVOK_INVITE_ERROR_CODES` to branch on stable codes.
@@ -675,7 +705,7 @@ inviter has 20 pending invites. Use
675
705
 
676
706
  Every app that can receive invitations needs a page at
677
707
  `<app URL>/accept-invite?invite=<uuid>&code=<secret>`. Practitioner links use
678
- `PRACTITIONER_APP_URL`; patient links use `PATIENT_APP_URL`. The secret is valid
708
+ `PRACTITIONER_APP_URL`; patient and carer links use `PATIENT_APP_URL`. The secret is valid
679
709
  for seven days. `parseAcceptInviteLink(url)` returns a body only when the UUID and
680
710
  16–128 character code are present and valid; otherwise show “This link is
681
711
  incomplete” and make no request. Once parsed, remove the code from the address
@@ -684,7 +714,8 @@ bar/history and do not send it to logs or analytics.
684
714
  If the visitor is signed out, send them through sign-in and restore the link on
685
715
  return. There is no preview endpoint. Once signed in, call `acceptInvite()`; it
686
716
  chooses the route from the `Patient` or `Practitioner` profile and rejects other
687
- profile types. Never accept on page load. For a patient accepting, explain that
717
+ profile types. Carers call `acceptRecordShare()` directly: signed in when they
718
+ already have an account, otherwise signed out with a new password. Never accept on page load. For a patient accepting, explain that
688
719
  their whole record will be shared and wait for an explicit Accept action. A
689
720
  patient can decline with `revokePatientSharing(inviteId)`; practitioners have no
690
721
  decline route and can ignore the link. After a successful acceptance, show who
@@ -7,7 +7,7 @@ type ExchangeCodeProps = {
7
7
  codeVerifier: string;
8
8
  requestOptions?: MedplumRequestOptions;
9
9
  } & ({
10
- type: "Patient";
10
+ type: "Patient" | "RelatedPerson";
11
11
  } | {
12
12
  type: "Practitioner";
13
13
  tenantCode: string;
@@ -9,7 +9,7 @@ const exchangeCode = async ({ ...props }) => {
9
9
  tenantCode: props.tenantCode,
10
10
  }, undefined, props.requestOptions);
11
11
  }
12
- return props.client.post("auth/tenant/Patient/login/token", {
12
+ return props.client.post(`auth/tenant/${props.type}/login/token`, {
13
13
  sessionCode: props.sessionCode,
14
14
  codeVerifier: props.codeVerifier,
15
15
  }, undefined, props.requestOptions);
@@ -2,5 +2,5 @@ import { StartLoginResponse } from "./types/StartLoginResponse";
2
2
  export declare const handleTenantCode: ({ profiles, tenantCode, type, }: {
3
3
  profiles: StartLoginResponse["profiles"];
4
4
  tenantCode?: string;
5
- type: "Practitioner" | "Patient";
5
+ type: "Practitioner" | "Patient" | "RelatedPerson";
6
6
  }) => string;
@@ -60,7 +60,7 @@ async function login(body, requestOptions) {
60
60
  });
61
61
  const exchange = (sessionCode) => (0, exchange_code_1.exchangeCode)({
62
62
  client: this,
63
- type: "Patient",
63
+ type: body.type,
64
64
  sessionCode,
65
65
  codeVerifier,
66
66
  requestOptions,
@@ -68,6 +68,6 @@ async function login(body, requestOptions) {
68
68
  if (startResponse.nextStep === "mfa") {
69
69
  return mfaStep(this, body.type, startResponse.loginId, exchange, requestOptions);
70
70
  }
71
- (0, handle_tenant_code_1.handleTenantCode)({ profiles: startResponse.profiles, tenantCode: body.tenantCode, type: "Patient" });
71
+ (0, handle_tenant_code_1.handleTenantCode)({ profiles: startResponse.profiles, tenantCode: body.tenantCode, type: body.type });
72
72
  return exchange(startResponse.sessionCode);
73
73
  }
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.startLogin = void 0;
4
4
  const startLogin = async ({ client, body, codeChallenge, requestOptions, }) => {
5
- if (body.type === "Patient") {
6
- return client.post("auth/tenant/Patient/login/start", {
5
+ if (body.type !== "Practitioner") {
6
+ return client.post(`auth/tenant/${body.type}/login/start`, {
7
7
  email: body.email,
8
8
  password: body.password,
9
9
  codeChallenge,
@@ -12,5 +12,11 @@ export type PractitionerLoginBody = LoginCredentials & {
12
12
  /** Selects a project when the person belongs to multiple projects. */
13
13
  tenantCode?: string;
14
14
  };
15
- export type LoginBody = PatientLoginBody | PractitionerLoginBody;
15
+ /** A carer; their account comes only from accepting a record-share invite. */
16
+ export type RelatedPersonLoginBody = LoginCredentials & {
17
+ type: "RelatedPerson";
18
+ /** The tenant code to log in to. */
19
+ tenantCode: string;
20
+ };
21
+ export type LoginBody = PatientLoginBody | PractitionerLoginBody | RelatedPersonLoginBody;
16
22
  export {};
@@ -6,7 +6,7 @@ export interface ResetPasswordBody {
6
6
  /**
7
7
  * The type of user to reset the password for
8
8
  */
9
- type: "Patient" | "Practitioner";
9
+ type: "Patient" | "Practitioner" | "RelatedPerson";
10
10
  /**
11
11
  * The client ID to use for the request
12
12
  */
@@ -1,9 +1,22 @@
1
1
  import type { MedplumRequestOptions } from "@medplum/core";
2
2
  import { OvokClient } from "../ovok-client";
3
3
  import { PatientSharingPractitionerShare } from "../patient-sharing/types";
4
- import { AcceptInviteBody, InviteBody, InviteSent } from "./types";
4
+ import { AcceptInviteBody, AcceptRecordShareBody, InviteBody, InviteSent, RecordShareAccepted, RecordShareBody } from "./types";
5
+ /** A patient shares their record with a practitioner, or with a carer (a related person) for some codes. */
6
+ export declare function shareRecord(this: OvokClient, body: RecordShareBody, requestOptions?: MedplumRequestOptions): Promise<InviteSent>;
7
+ /** Accepts a record share; a carer new to the project accepts signed out with a `password`. */
8
+ export declare function acceptRecordShare(this: OvokClient, body: AcceptRecordShareBody, requestOptions?: MedplumRequestOptions): Promise<RecordShareAccepted>;
9
+ /** A practitioner invites a patient into their care. */
10
+ export declare function inviteToCare(this: OvokClient, body: InviteBody, requestOptions?: MedplumRequestOptions): Promise<InviteSent>;
11
+ /** The signed-in patient accepts a practitioner's care invite. */
12
+ export declare function acceptCareInvite(this: OvokClient, body: AcceptInviteBody, requestOptions?: MedplumRequestOptions): Promise<PatientSharingPractitionerShare>;
13
+ /** @deprecated Use shareRecord({ recipient: "practitioner", ... }); the route sunsets on 2026-12-01. */
5
14
  export declare function invitePractitioner(this: OvokClient, body: InviteBody, requestOptions?: MedplumRequestOptions): Promise<InviteSent>;
15
+ /** @deprecated Use inviteToCare; the route sunsets on 2026-12-01. */
6
16
  export declare function invitePatient(this: OvokClient, body: InviteBody, requestOptions?: MedplumRequestOptions): Promise<InviteSent>;
17
+ /** @deprecated Use acceptRecordShare; the route sunsets on 2026-12-01. */
7
18
  export declare function acceptPractitionerInvite(this: OvokClient, body: AcceptInviteBody, requestOptions?: MedplumRequestOptions): Promise<PatientSharingPractitionerShare>;
19
+ /** @deprecated Use acceptCareInvite; the route sunsets on 2026-12-01. */
8
20
  export declare function acceptPatientInvite(this: OvokClient, body: AcceptInviteBody, requestOptions?: MedplumRequestOptions): Promise<PatientSharingPractitionerShare>;
21
+ /** Accepts as the signed-in practitioner (a record share) or patient (a care invite). */
9
22
  export declare function acceptInvite(this: OvokClient, body: AcceptInviteBody, requestOptions?: MedplumRequestOptions): Promise<PatientSharingPractitionerShare>;
@@ -1,32 +1,64 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.shareRecord = shareRecord;
4
+ exports.acceptRecordShare = acceptRecordShare;
5
+ exports.inviteToCare = inviteToCare;
6
+ exports.acceptCareInvite = acceptCareInvite;
3
7
  exports.invitePractitioner = invitePractitioner;
4
8
  exports.invitePatient = invitePatient;
5
9
  exports.acceptPractitionerInvite = acceptPractitionerInvite;
6
10
  exports.acceptPatientInvite = acceptPatientInvite;
7
11
  exports.acceptInvite = acceptInvite;
8
12
  const request_options_1 = require("../request-options");
13
+ /** A patient shares their record with a practitioner, or with a carer (a related person) for some codes. */
14
+ function shareRecord(body, requestOptions) {
15
+ return this.post("/v1/invites/record-share", body, undefined, requestOptions);
16
+ }
17
+ /** Accepts a record share; a carer new to the project accepts signed out with a `password`. */
18
+ function acceptRecordShare(body, requestOptions) {
19
+ return this.post("/v1/invites/record-share/accept", body, undefined, requestOptions)
20
+ .then((result) => {
21
+ this.invalidateUrl("/v1/patient-sharing/shares");
22
+ return result;
23
+ });
24
+ }
25
+ /** A practitioner invites a patient into their care. */
26
+ function inviteToCare(body, requestOptions) {
27
+ return this.post("/v1/invites/care", body, undefined, requestOptions);
28
+ }
29
+ /** The signed-in patient accepts a practitioner's care invite. */
30
+ function acceptCareInvite(body, requestOptions) {
31
+ return this.post("/v1/invites/care/accept", body, undefined, requestOptions)
32
+ .then((result) => {
33
+ this.invalidateUrl("/v1/patient-sharing/shares");
34
+ return result;
35
+ });
36
+ }
37
+ /** @deprecated Use shareRecord({ recipient: "practitioner", ... }); the route sunsets on 2026-12-01. */
9
38
  function invitePractitioner(body, requestOptions) {
10
39
  return this.post("/v1/invites/practitioner", body, undefined, requestOptions);
11
40
  }
41
+ /** @deprecated Use inviteToCare; the route sunsets on 2026-12-01. */
12
42
  function invitePatient(body, requestOptions) {
13
43
  return this.post("/v1/invites/patient", body, undefined, requestOptions);
14
44
  }
45
+ /** @deprecated Use acceptRecordShare; the route sunsets on 2026-12-01. */
15
46
  function acceptPractitionerInvite(body, requestOptions) {
16
47
  return this.post("/v1/invites/practitioner/accept", body, undefined, requestOptions);
17
48
  }
49
+ /** @deprecated Use acceptCareInvite; the route sunsets on 2026-12-01. */
18
50
  function acceptPatientInvite(body, requestOptions) {
19
51
  return this.post("/v1/invites/patient/accept", body, undefined, requestOptions);
20
52
  }
53
+ /** Accepts as the signed-in practitioner (a record share) or patient (a care invite). */
21
54
  function acceptInvite(body, requestOptions) {
22
55
  var _a;
23
56
  const resourceType = (_a = this.getProfile()) === null || _a === void 0 ? void 0 : _a.resourceType;
24
- if (resourceType !== "Practitioner" && resourceType !== "Patient") {
25
- throw new Error("Accepting an invite requires a signed-in Patient or Practitioner profile.");
57
+ if (resourceType === "Practitioner") {
58
+ return this.acceptRecordShare(body, ...(0, request_options_1.optionalArg)(requestOptions));
26
59
  }
27
- const accept = resourceType === "Practitioner" ? this.acceptPractitionerInvite : this.acceptPatientInvite;
28
- return accept.call(this, body, ...(0, request_options_1.optionalArg)(requestOptions)).then((result) => {
29
- this.invalidateUrl("/v1/patient-sharing/shares");
30
- return result;
31
- });
60
+ if (resourceType === "Patient") {
61
+ return this.acceptCareInvite(body, ...(0, request_options_1.optionalArg)(requestOptions));
62
+ }
63
+ throw new Error("Accepting an invite requires a signed-in Patient or Practitioner profile.");
32
64
  }
@@ -1,9 +1,16 @@
1
- import { PatientSharingPractitionerShare } from "../patient-sharing/types";
1
+ import { PatientSharingPractitionerShare, PatientSharingRelatedPersonShare } from "../patient-sharing/types";
2
2
  export type InviteBody = {
3
3
  email: string;
4
4
  firstName: string;
5
5
  lastName: string;
6
6
  };
7
+ export type RecordShareBody = (InviteBody & {
8
+ recipient: "practitioner";
9
+ }) | (InviteBody & {
10
+ recipient: "related-person";
11
+ /** The Observation codes the carer may read: 1 to 100. */
12
+ codes: string[];
13
+ });
7
14
  export type InviteSent = {
8
15
  status: "sent";
9
16
  };
@@ -11,9 +18,18 @@ export type AcceptInviteBody = {
11
18
  inviteId: string;
12
19
  code: string;
13
20
  };
21
+ export type AcceptRecordShareBody = AcceptInviteBody & {
22
+ /** Only for a carer whose account the invite creates; they accept signed out. */
23
+ password?: string | null;
24
+ };
14
25
  export type AcceptInviteResult = PatientSharingPractitionerShare;
26
+ export type RecordShareAccepted = PatientSharingPractitionerShare | PatientSharingRelatedPersonShare;
15
27
  export declare const OVOK_INVITE_ERROR_CODES: {
16
28
  readonly invitationNotConfigured: "invitation_not_configured";
17
29
  readonly appUrlNotConfigured: "app_url_not_configured";
18
30
  readonly practitionerWithoutAccessPolicy: "practitioner_without_access_policy";
31
+ readonly relatedPersonWithoutAccessPolicy: "related_person_without_access_policy";
32
+ readonly addressHasAccount: "address_has_account";
33
+ readonly passwordRequired: "password_required";
34
+ readonly sharingNotConfigured: "sharing_not_configured";
19
35
  };
@@ -5,4 +5,8 @@ exports.OVOK_INVITE_ERROR_CODES = {
5
5
  invitationNotConfigured: "invitation_not_configured",
6
6
  appUrlNotConfigured: "app_url_not_configured",
7
7
  practitionerWithoutAccessPolicy: "practitioner_without_access_policy",
8
+ relatedPersonWithoutAccessPolicy: "related_person_without_access_policy",
9
+ addressHasAccount: "address_has_account",
10
+ passwordRequired: "password_required",
11
+ sharingNotConfigured: "sharing_not_configured",
8
12
  };
@@ -18,10 +18,12 @@ function redeemPatientSharingInvite(body, requestOptions) {
18
18
  }
19
19
  function listPatientSharing(requestOptions) {
20
20
  return this.get("/v1/patient-sharing/shares", ...(0, request_options_1.optionalArg)(requestOptions)).then((shares) => {
21
- var _a;
21
+ var _a, _b, _c;
22
22
  return ({
23
23
  ...shares,
24
24
  practitioners: (_a = shares.practitioners) !== null && _a !== void 0 ? _a : [],
25
+ relatedPersons: (_b = shares.relatedPersons) !== null && _b !== void 0 ? _b : [],
26
+ received: (_c = shares.received) !== null && _c !== void 0 ? _c : [],
25
27
  });
26
28
  });
27
29
  }
@@ -25,10 +25,25 @@ export type PatientSharingPractitionerShare = {
25
25
  startedAt: string | null;
26
26
  endsAt: string | null;
27
27
  };
28
+ /** Observation codes a patient shares with a related person (a carer). */
29
+ export type PatientSharingRelatedPersonShare = {
30
+ consentId: string;
31
+ sharer: PatientSharingParty;
32
+ relatedPerson: {
33
+ relatedPersonId: string;
34
+ name: string | null;
35
+ };
36
+ codes: string[];
37
+ startedAt: string | null;
38
+ endsAt: string | null;
39
+ };
28
40
  export type PatientSharingShares = {
29
41
  outgoing: PatientSharingShare[];
30
42
  incoming: PatientSharingShare[];
31
43
  practitioners: PatientSharingPractitionerShare[];
44
+ relatedPersons: PatientSharingRelatedPersonShare[];
45
+ /** For a signed-in carer: the shares patients gave them. Empty for a patient. */
46
+ received: PatientSharingRelatedPersonShare[];
32
47
  };
33
48
  export type CreatePatientSharingInvite = {
34
49
  codes: string[];
@@ -21,6 +21,10 @@ exports.OVOK_CORE_API_REQUIREMENTS = {
21
21
  { method: "POST", path: "/auth/tenant/Patient/login/token", group: "Auth" },
22
22
  { method: "POST", path: "/auth/tenant/Practitioner/login/token", group: "Auth" },
23
23
  { method: "POST", path: "/auth/tenant/Practitioner/login/mfa", group: "Auth" },
24
+ { method: "POST", path: "/auth/tenant/Patient/login/mfa", group: "Auth" },
25
+ { method: "POST", path: "/auth/tenant/RelatedPerson/login/start", group: "Auth" },
26
+ { method: "POST", path: "/auth/tenant/RelatedPerson/login/token", group: "Auth" },
27
+ { method: "POST", path: "/auth/tenant/RelatedPerson/login/mfa", group: "Auth" },
24
28
  { method: "POST", path: "/auth/tenant/Patient/register", group: "Auth" },
25
29
  { method: "POST", path: "/auth/tenant/Practitioner/register", group: "Auth" },
26
30
  { method: "POST", path: "/auth/external/google", group: "Auth" },
@@ -91,6 +95,11 @@ exports.OVOK_CORE_API_REQUIREMENTS = {
91
95
  { method: "DELETE", path: "/v1/patient-sharing/shares/:consentId", group: "PatientSharing" },
92
96
  { method: "POST", path: "/v1/patient-sharing/invites", group: "PatientSharing" },
93
97
  { method: "POST", path: "/v1/patient-sharing/invites/redeem", group: "PatientSharing" },
98
+ { method: "POST", path: "/v1/invites/record-share", group: "Invites" },
99
+ { method: "POST", path: "/v1/invites/record-share/accept", group: "Invites" },
100
+ { method: "POST", path: "/v1/invites/care", group: "Invites" },
101
+ { method: "POST", path: "/v1/invites/care/accept", group: "Invites" },
102
+ // Deprecated: sunset on 2026-12-01, used only by the deprecated invite methods.
94
103
  { method: "POST", path: "/v1/invites/practitioner", group: "Invites" },
95
104
  { method: "POST", path: "/v1/invites/patient", group: "Invites" },
96
105
  { method: "POST", path: "/v1/invites/practitioner/accept", group: "Invites" },
@@ -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.46",
51
+ version: "0.4.48",
52
52
  },
53
53
  fhirVersion: "4.0.1",
54
54
  format: ["json"],
@@ -18,7 +18,7 @@ export { useRecentAlarms, useRecentOutOfBed, useRecentSlimNotifications, useSlim
18
18
  export { useCreateNotificationNote, useCreateSignalsAlertNote, useCreateSignalsRawAlertNote, useDeleteNotificationNote, useDeleteSignalsNote, useNotificationNotes, useSignalsAlertNotes, useSignalsRawAlertNotes, useUpdateNotificationNote, useUpdateSignalsNote, } from "./notification-note-hooks";
19
19
  export { useAcknowledgeSlimAlarm, useAcknowledgeSlimMedicalNotification, } from "./notification-ack-hooks";
20
20
  export { useCmsDocument, useCmsDocuments, useLegalPage, useReleaseNotes, useTranslations, } from "./cms-hooks";
21
- export { useAcceptInvite, useInvitePatient, useInvitePractitioner, } from "./invites-hooks";
21
+ export { useAcceptCareInvite, useAcceptInvite, useAcceptRecordShare, useInvitePatient, useInvitePractitioner, useInviteToCare, useShareRecord, } 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
24
  export { useAuthorizeWearableConnection, useCreateWearableProvider, useDeleteWearableConnection, useDeleteWearableProvider, useUpdateWearableProvider, useWearableConnections, useWearableProviders, } from "./wearables-hooks";
@@ -35,8 +35,8 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  })();
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
- 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.useWearableProviders = exports.useWearableConnections = exports.useUpdateWearableProvider = exports.useDeleteWearableProvider = exports.useDeleteWearableConnection = exports.useCreateWearableProvider = exports.useAuthorizeWearableConnection = exports.useUpdatePatientSharingSettings = exports.useRevokePatientSharing = exports.useRedeemPatientSharingInvite = void 0;
38
+ 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.useShareRecord = exports.useInviteToCare = exports.useInvitePractitioner = exports.useInvitePatient = exports.useAcceptRecordShare = exports.useAcceptInvite = exports.useAcceptCareInvite = 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.useWearableProviders = exports.useWearableConnections = exports.useUpdateWearableProvider = exports.useDeleteWearableProvider = exports.useDeleteWearableConnection = exports.useCreateWearableProvider = exports.useAuthorizeWearableConnection = exports.useUpdatePatientSharingSettings = exports.useRevokePatientSharing = exports.useRedeemPatientSharingInvite = exports.usePatientSharingSettings = exports.usePatientSharing = exports.useCreatePatientSharingInvite = exports.useSubmitQuestionnaireResponse = void 0;
40
40
  /*
41
41
  * The only React-dependent module in the package.
42
42
  *
@@ -149,9 +149,13 @@ Object.defineProperty(exports, "useLegalPage", { enumerable: true, get: function
149
149
  Object.defineProperty(exports, "useReleaseNotes", { enumerable: true, get: function () { return cms_hooks_1.useReleaseNotes; } });
150
150
  Object.defineProperty(exports, "useTranslations", { enumerable: true, get: function () { return cms_hooks_1.useTranslations; } });
151
151
  var invites_hooks_1 = require("./invites-hooks");
152
+ Object.defineProperty(exports, "useAcceptCareInvite", { enumerable: true, get: function () { return invites_hooks_1.useAcceptCareInvite; } });
152
153
  Object.defineProperty(exports, "useAcceptInvite", { enumerable: true, get: function () { return invites_hooks_1.useAcceptInvite; } });
154
+ Object.defineProperty(exports, "useAcceptRecordShare", { enumerable: true, get: function () { return invites_hooks_1.useAcceptRecordShare; } });
153
155
  Object.defineProperty(exports, "useInvitePatient", { enumerable: true, get: function () { return invites_hooks_1.useInvitePatient; } });
154
156
  Object.defineProperty(exports, "useInvitePractitioner", { enumerable: true, get: function () { return invites_hooks_1.useInvitePractitioner; } });
157
+ Object.defineProperty(exports, "useInviteToCare", { enumerable: true, get: function () { return invites_hooks_1.useInviteToCare; } });
158
+ Object.defineProperty(exports, "useShareRecord", { enumerable: true, get: function () { return invites_hooks_1.useShareRecord; } });
155
159
  var patient_hooks_1 = require("./patient-hooks");
156
160
  Object.defineProperty(exports, "useCurrentPatientProfile", { enumerable: true, get: function () { return patient_hooks_1.useCurrentPatientProfile; } });
157
161
  Object.defineProperty(exports, "useExtractQuestionnaireObservations", { enumerable: true, get: function () { return patient_hooks_1.useExtractQuestionnaireObservations; } });
@@ -1,5 +1,11 @@
1
- import { AcceptInviteBody, AcceptInviteResult, InviteBody, InviteSent } from "../client/invites";
1
+ import { AcceptInviteBody, AcceptInviteResult, AcceptRecordShareBody, InviteBody, InviteSent, RecordShareAccepted, RecordShareBody } from "../client/invites";
2
2
  import { OvokMutationState } from "./api-hooks";
3
+ export declare const useShareRecord: () => OvokMutationState<RecordShareBody, InviteSent>;
4
+ export declare const useInviteToCare: () => OvokMutationState<InviteBody, InviteSent>;
5
+ export declare const useAcceptRecordShare: () => OvokMutationState<AcceptRecordShareBody, RecordShareAccepted>;
6
+ export declare const useAcceptCareInvite: () => OvokMutationState<AcceptInviteBody, AcceptInviteResult>;
7
+ /** @deprecated Use useShareRecord with `recipient: "practitioner"`; the route sunsets on 2026-12-01. */
3
8
  export declare const useInvitePractitioner: () => OvokMutationState<InviteBody, InviteSent>;
9
+ /** @deprecated Use useInviteToCare; the route sunsets on 2026-12-01. */
4
10
  export declare const useInvitePatient: () => OvokMutationState<InviteBody, InviteSent>;
5
11
  export declare const useAcceptInvite: () => OvokMutationState<AcceptInviteBody, AcceptInviteResult>;
@@ -1,11 +1,29 @@
1
1
  "use strict";
2
2
  "use client";
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.useAcceptInvite = exports.useInvitePatient = exports.useInvitePractitioner = void 0;
4
+ exports.useAcceptInvite = exports.useInvitePatient = exports.useInvitePractitioner = exports.useAcceptCareInvite = exports.useAcceptRecordShare = exports.useInviteToCare = exports.useShareRecord = void 0;
5
5
  const api_hooks_1 = require("./api-hooks");
6
6
  const notification_invalidation_1 = require("./notification-invalidation");
7
+ const useShareRecord = () => (0, api_hooks_1.useOvokMutation)((client, body) => client.shareRecord(body));
8
+ exports.useShareRecord = useShareRecord;
9
+ const useInviteToCare = () => (0, api_hooks_1.useOvokMutation)((client, body) => client.inviteToCare(body));
10
+ exports.useInviteToCare = useInviteToCare;
11
+ const useAcceptRecordShare = () => (0, api_hooks_1.useOvokMutation)(async (client, body) => {
12
+ const result = await client.acceptRecordShare(body);
13
+ (0, notification_invalidation_1.notifyNotificationChanges)(client, { type: "patient-sharing" });
14
+ return result;
15
+ });
16
+ exports.useAcceptRecordShare = useAcceptRecordShare;
17
+ const useAcceptCareInvite = () => (0, api_hooks_1.useOvokMutation)(async (client, body) => {
18
+ const result = await client.acceptCareInvite(body);
19
+ (0, notification_invalidation_1.notifyNotificationChanges)(client, { type: "patient-sharing" });
20
+ return result;
21
+ });
22
+ exports.useAcceptCareInvite = useAcceptCareInvite;
23
+ /** @deprecated Use useShareRecord with `recipient: "practitioner"`; the route sunsets on 2026-12-01. */
7
24
  const useInvitePractitioner = () => (0, api_hooks_1.useOvokMutation)((client, body) => client.invitePractitioner(body));
8
25
  exports.useInvitePractitioner = useInvitePractitioner;
26
+ /** @deprecated Use useInviteToCare; the route sunsets on 2026-12-01. */
9
27
  const useInvitePatient = () => (0, api_hooks_1.useOvokMutation)((client, body) => client.invitePatient(body));
10
28
  exports.useInvitePatient = useInvitePatient;
11
29
  const useAcceptInvite = () => (0, api_hooks_1.useOvokMutation)(async (client, body) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ovok/core",
3
- "version": "0.4.46",
3
+ "version": "0.4.48",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",