@everfur/sdk 0.1.0 → 0.3.0
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/CHANGELOG.md +648 -1
- package/README.md +58 -23
- package/consent/package.json +8 -0
- package/dist/Chat-DPUD6dnc.d.cts +128 -0
- package/dist/Chat-DwAC2vhB.d.ts +128 -0
- package/dist/DepthViews-DNEM96Se.d.ts +16 -0
- package/dist/DepthViews-DP0R-DhB.d.cts +19 -0
- package/dist/DepthViews-D_3hl4xk.d.ts +19 -0
- package/dist/DepthViews-DbFhR4Du.d.cts +16 -0
- package/dist/ErrorPolicyPort-CNf4uQZP.d.cts +22 -0
- package/dist/ErrorPolicyPort-CwbfmxzJ.d.ts +22 -0
- package/dist/{EverfurResult-D92-uL82.d.cts → EverfurResult-DN9pL2Ab.d.cts} +11 -10
- package/dist/{EverfurResult-D92-uL82.d.ts → EverfurResult-DN9pL2Ab.d.ts} +11 -10
- package/dist/{PhotoController-BItt5M7u.d.cts → PhotoController-3l7MT9jA.d.cts} +1 -1
- package/dist/{PhotoController-D8zMTdcW.d.ts → PhotoController-vzY5bfY_.d.ts} +1 -1
- package/dist/animations/index.cjs +1 -1997
- package/dist/animations/index.d.cts +35 -35
- package/dist/animations/index.d.ts +35 -35
- package/dist/animations/index.js +1 -1972
- package/dist/attachments-5NeobOCd.d.ts +256 -0
- package/dist/attachments-Bw3iMQgu.d.ts +146 -0
- package/dist/attachments-CQgFrEQ7.d.cts +146 -0
- package/dist/attachments-D8T5re7e.d.cts +256 -0
- package/dist/casesRepository-ClLv6qMl.d.ts +188 -0
- package/dist/casesRepository-DHwtGRYY.d.cts +188 -0
- package/dist/chat/index.cjs +1 -1170
- package/dist/chat/index.d.cts +31 -53
- package/dist/chat/index.d.ts +31 -53
- package/dist/chat/index.js +1 -1167
- package/dist/client/index.cjs +9 -2315
- package/dist/client/index.d.cts +77 -15
- package/dist/client/index.d.ts +77 -15
- package/dist/client/index.js +9 -2215
- package/dist/{config-CiJ0PVBB.d.ts → config-CzTZGlfF.d.cts} +63 -25
- package/dist/{config-BSjBdxrZ.d.cts → config-DW60uRb9.d.ts} +63 -25
- package/dist/consent/index.cjs +1 -0
- package/dist/consent/index.d.cts +33 -0
- package/dist/consent/index.d.ts +33 -0
- package/dist/consent/index.js +1 -0
- package/dist/context-DXhqHlPU.d.ts +159 -0
- package/dist/context-XvTzq1tE.d.cts +159 -0
- package/dist/copy-Mjoo91aS.d.ts +198 -0
- package/dist/copy-bKDNigLb.d.cts +198 -0
- package/dist/core/index.cjs +13 -3175
- package/dist/core/index.d.cts +58 -12
- package/dist/core/index.d.ts +58 -12
- package/dist/core/index.js +13 -3163
- package/dist/depth-CErXCU8J.d.cts +502 -0
- package/dist/depth-DjDcJ6kH.d.ts +502 -0
- package/dist/entitlementRepository-DKdXFgTo.d.cts +698 -0
- package/dist/entitlementRepository-DSbzuyAW.d.ts +698 -0
- package/dist/{identity-DK9zORrG.d.ts → identity-BMx2SUOM.d.ts} +19 -6
- package/dist/{identity-Brl-lDd6.d.cts → identity-DI4eVx9S.d.cts} +19 -6
- package/dist/{ids-CJ1S6adf.d.cts → ids-B2GAAifq.d.cts} +1 -1
- package/dist/{ids-CJ1S6adf.d.ts → ids-B2GAAifq.d.ts} +1 -1
- package/dist/index.cjs +12 -4488
- package/dist/index.d.cts +29 -121
- package/dist/index.d.ts +29 -121
- package/dist/index.js +12 -4464
- package/dist/models-B-Uh2LTf.d.ts +214 -0
- package/dist/models-D2EUxPZY.d.cts +214 -0
- package/dist/notifications/index.cjs +2 -0
- package/dist/notifications/index.d.cts +17 -0
- package/dist/notifications/index.d.ts +17 -0
- package/dist/notifications/index.js +2 -0
- package/dist/pets-CtQdRpWo.d.ts +92 -0
- package/dist/pets-aB8q0JyX.d.cts +92 -0
- package/dist/photo/index.cjs +1 -2189
- package/dist/photo/index.d.cts +6 -6
- package/dist/photo/index.d.ts +6 -6
- package/dist/photo/index.js +1 -2186
- package/dist/ports-BN6RHF9W.d.cts +48 -0
- package/dist/ports-BN6RHF9W.d.ts +48 -0
- package/dist/ports-DEBzEhbp.d.cts +386 -0
- package/dist/ports-DMolTRzU.d.ts +386 -0
- package/dist/profile-CSs1wlXT.d.cts +93 -0
- package/dist/profile-CSs1wlXT.d.ts +93 -0
- package/dist/records/depth/index.cjs +2 -0
- package/dist/records/depth/index.d.cts +13 -0
- package/dist/records/depth/index.d.ts +13 -0
- package/dist/records/depth/index.js +2 -0
- package/dist/records/index.cjs +3 -2839
- package/dist/records/index.d.cts +137 -203
- package/dist/records/index.d.ts +137 -203
- package/dist/records/index.js +3 -2833
- package/dist/requestFunnel-CjW7uDuA.d.ts +87 -0
- package/dist/requestFunnel-L-BQfi0z.d.cts +87 -0
- package/dist/{resolve-Dq_4_agU.d.ts → resolve-D4Ywz5OS.d.cts} +10 -4
- package/dist/{resolve-Dq_4_agU.d.cts → resolve-D4Ywz5OS.d.ts} +10 -4
- package/dist/{runtime-BgQnA594.d.cts → runtime-B8s-_hv8.d.cts} +134 -59
- package/dist/{runtime-CBA-LvdM.d.ts → runtime-BR9ysG0J.d.ts} +134 -59
- package/dist/server/events/index.cjs +2 -0
- package/dist/server/events/index.d.cts +550 -0
- package/dist/server/events/index.d.ts +550 -0
- package/dist/server/events/index.js +2 -0
- package/dist/server/index.cjs +2 -533
- package/dist/server/index.d.cts +73 -18
- package/dist/server/index.d.ts +73 -18
- package/dist/server/index.js +2 -530
- package/dist/species-BXAIMh7I.d.cts +9 -0
- package/dist/species-BXAIMh7I.d.ts +9 -0
- package/dist/televet/index.cjs +1 -0
- package/dist/televet/index.d.cts +60 -0
- package/dist/televet/index.d.ts +60 -0
- package/dist/televet/index.js +1 -0
- package/dist/testing/index.cjs +5 -823
- package/dist/testing/index.d.cts +17 -3
- package/dist/testing/index.d.ts +17 -3
- package/dist/testing/index.js +5 -820
- package/dist/testing/rn/index.cjs +1 -449
- package/dist/testing/rn/index.d.cts +17 -29
- package/dist/testing/rn/index.d.ts +17 -29
- package/dist/testing/rn/index.js +1 -444
- package/dist/testing/web/index.cjs +1 -0
- package/dist/testing/web/index.d.cts +131 -0
- package/dist/testing/web/index.d.ts +131 -0
- package/dist/testing/web/index.js +1 -0
- package/dist/timelineRows-CaohZzXS.d.cts +19 -0
- package/dist/timelineRows-DZed6dAM.d.ts +19 -0
- package/dist/typeStyle-0TydiZ1w.d.cts +19 -0
- package/dist/typeStyle-CWMsoe6b.d.ts +19 -0
- package/dist/uploadTransport-D0M0T4hN.d.ts +38 -0
- package/dist/uploadTransport-DKJHs3Yj.d.cts +38 -0
- package/dist/useRecordsDepth-BHBzJ76R.d.cts +237 -0
- package/dist/useRecordsDepth-BU-OhzH6.d.ts +237 -0
- package/dist/useVetVisit-Bc84hWUU.d.cts +187 -0
- package/dist/useVetVisit-CjmMa896.d.ts +187 -0
- package/dist/video/index.cjs +1 -1941
- package/dist/video/index.d.cts +4 -4
- package/dist/video/index.d.ts +4 -4
- package/dist/video/index.js +1 -1938
- package/dist/view-C3qPIXGX.d.cts +310 -0
- package/dist/view-DtSPYpKa.d.ts +310 -0
- package/dist/visitIntent-D7_yVp1I.d.cts +8 -0
- package/dist/visitIntent-D7_yVp1I.d.ts +8 -0
- package/dist/web/consent/index.cjs +1 -0
- package/dist/web/consent/index.d.cts +34 -0
- package/dist/web/consent/index.d.ts +34 -0
- package/dist/web/consent/index.js +1 -0
- package/dist/web/index.cjs +14 -0
- package/dist/web/index.d.cts +217 -0
- package/dist/web/index.d.ts +217 -0
- package/dist/web/index.js +14 -0
- package/dist/web/notifications/index.cjs +2 -0
- package/dist/web/notifications/index.d.cts +213 -0
- package/dist/web/notifications/index.d.ts +213 -0
- package/dist/web/notifications/index.js +2 -0
- package/dist/web/records/depth/index.cjs +2 -0
- package/dist/web/records/depth/index.d.cts +12 -0
- package/dist/web/records/depth/index.d.ts +12 -0
- package/dist/web/records/depth/index.js +2 -0
- package/dist/web/records/index.cjs +4 -0
- package/dist/web/records/index.d.cts +194 -0
- package/dist/web/records/index.d.ts +194 -0
- package/dist/web/records/index.js +4 -0
- package/dist/web/televet/index.cjs +1 -0
- package/dist/web/televet/index.d.cts +50 -0
- package/dist/web/televet/index.d.ts +50 -0
- package/dist/web/televet/index.js +1 -0
- package/notifications/package.json +8 -0
- package/package.json +197 -9
- package/records/depth/package.json +8 -0
- package/server/events/device-blocked.cjs +15 -0
- package/server/events/package.json +9 -0
- package/televet/package.json +8 -0
- package/testing/web/native-blocked.cjs +12 -0
- package/testing/web/package.json +8 -0
- package/web/consent/native-blocked.cjs +12 -0
- package/web/consent/package.json +8 -0
- package/web/native-blocked.cjs +12 -0
- package/web/notifications/native-blocked.cjs +12 -0
- package/web/notifications/package.json +8 -0
- package/web/package.json +8 -0
- package/web/records/depth/native-blocked.cjs +12 -0
- package/web/records/depth/package.json +8 -0
- package/web/records/native-blocked.cjs +12 -0
- package/web/records/package.json +8 -0
- package/web/televet/native-blocked.cjs +12 -0
- package/web/televet/package.json +8 -0
- package/dist/ChatController-CKdBvPj2.d.ts +0 -146
- package/dist/ChatController-CpUMvvZf.d.cts +0 -146
- package/dist/FilePort-BabWrv7I.d.cts +0 -22
- package/dist/FilePort-BabWrv7I.d.ts +0 -22
- package/dist/petsRepository-BEGb97M9.d.cts +0 -326
- package/dist/petsRepository-Bu18r2kK.d.ts +0 -326
- package/dist/requestFunnel-DuUH-kAe.d.cts +0 -28
- package/dist/requestFunnel-dio5OmR9.d.ts +0 -28
package/README.md
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
# @everfur/sdk (React Native)
|
|
1
|
+
# @everfur/sdk (React Native and the web)
|
|
2
2
|
|
|
3
3
|
Drop Everfur's AI vet assistant and pet-health features (records, gait/video, photo checkup, pet-state
|
|
4
|
-
media) into a React Native app. What each of your customers and users can
|
|
5
|
-
Everfur's entitlement control plane and rendered by the SDK, so you gate
|
|
6
|
-
update.
|
|
4
|
+
media) into a React Native app, and the assistant into a website. What each of your customers and users can
|
|
5
|
+
see is decided **server-side** by Everfur's entitlement control plane and rendered by the SDK, so you gate
|
|
6
|
+
features without shipping an app update.
|
|
7
7
|
|
|
8
8
|
- Hexagonal, framework-free core with a thin RN layer; every surface settles (no thrown domain errors).
|
|
9
9
|
- Server-authoritative entitlements: a feature you are not entitled to renders a deliberate off-state, never
|
|
10
10
|
a blank screen, and cannot be force-enabled client-side.
|
|
11
11
|
- The app never holds a secret. See [The security model](#the-security-model).
|
|
12
12
|
|
|
13
|
-
> `0.
|
|
14
|
-
> that mints sessions.
|
|
13
|
+
> `0.3.0`, MIT licensed, public on npm. Requires React Native `>=0.74` (or React `>=18` with `react-dom`
|
|
14
|
+
> for the web entry), and Node `>=18` on the backend that mints sessions.
|
|
15
15
|
|
|
16
16
|
**Getting keys:** Everfur keys are provisioned by the Everfur team during partner onboarding; there is
|
|
17
17
|
no self-serve signup yet. Contact [support@everfur.com](mailto:support@everfur.com) to get set up. The
|
|
@@ -21,7 +21,8 @@ publishable key is designed to ship inside your app; the secret key is not.
|
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
23
|
npm i @everfur/sdk
|
|
24
|
-
#
|
|
24
|
+
# A React Native app installs these itself (react-native and react-native-safe-area-context are declared
|
|
25
|
+
# optional peers, so a web project is not handed them):
|
|
25
26
|
npm i react react-native react-native-safe-area-context
|
|
26
27
|
```
|
|
27
28
|
|
|
@@ -30,17 +31,18 @@ Peer dependencies by capability (install only what you use):
|
|
|
30
31
|
| Capability | Extra peer deps | Notes |
|
|
31
32
|
| --- | --- | --- |
|
|
32
33
|
| chat, entitlements | none | works with react + react-native alone |
|
|
33
|
-
| records |
|
|
34
|
+
| records | Host-supplied document picker and upload transport | The SDK does not import Expo file-system or image-manipulator modules. |
|
|
34
35
|
| video (gait), photo (checkup) | `react-native-vision-camera` | **use `4.x` on RN 0.74**; `5.x` requires the new architecture |
|
|
35
36
|
|
|
36
|
-
The camera
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
The camera peer is optional: if you never mount `./video` or `./photo`, you do not need it.
|
|
38
|
+
`EverfurRecords` accepts the host's picker and upload transport, so use the native modules that fit your
|
|
39
|
+
app (including Expo SDK 57) without an SDK peer-dependency constraint. `react-native-vision-camera` also
|
|
40
|
+
needs its config plugin in `app.json` and a camera usage description.
|
|
39
41
|
|
|
40
42
|
### Bundler resolution
|
|
41
43
|
|
|
42
|
-
No Metro configuration is required. Every subpath (`@everfur/sdk/chat`, `/records`, `/video`, `/photo`,
|
|
43
|
-
`/animations`, `/client`, `/core`, `/testing`, `/testing/rn`) resolves on a stock install. Modern bundlers
|
|
44
|
+
No Metro configuration is required. Every subpath (`@everfur/sdk/chat`, `/records`, `/televet`, `/video`, `/photo`,
|
|
45
|
+
`/animations`, `/client`, `/core`, `/testing`, `/testing/rn`, `/testing/web`) resolves on a stock install. Modern bundlers
|
|
44
46
|
read the package `exports` map; Metro 0.80.x, which ships with Expo 51, defaults to
|
|
45
47
|
`unstable_enablePackageExports: false` and never reads it, so the package also ships classic root-level
|
|
46
48
|
resolution shims for the same subpaths. You do not need to turn package exports on, and turning them on does
|
|
@@ -50,10 +52,33 @@ not change what you get.
|
|
|
50
52
|
`sk_partner_` session minter. If it is ever pulled into an app bundle it throws on import rather than
|
|
51
53
|
shipping the minter to a device. Import it from your server only.
|
|
52
54
|
|
|
55
|
+
### On the web
|
|
56
|
+
|
|
57
|
+
Two ways, one wire contract, documented in
|
|
58
|
+
[docs/partner-integration/13-WEB-INTEGRATION.md](docs/partner-integration/13-WEB-INTEGRATION.md):
|
|
59
|
+
|
|
60
|
+
- **In-page**, for a page whose React tree you own: `import { EverfurProvider, EverfurChat } from
|
|
61
|
+
'@everfur/sdk/web'` (peers: `react`, `react-dom`). The copy-paste shape is
|
|
62
|
+
[`examples/minimal-web.tsx`](examples/minimal-web.tsx). Take the `/web` entry, not the package root: the
|
|
63
|
+
root is the React Native entry and imports `react-native` and `react-native-safe-area-context`, so in a
|
|
64
|
+
browser project it fails to resolve them rather than rendering. The `/web` entries need `react`,
|
|
65
|
+
`react/jsx-runtime` and `zod` and nothing native, which `npm run verify:pack` proves on every CI run by
|
|
66
|
+
importing all seven of them in a React web project.
|
|
67
|
+
- **Frame mode**, for a page you do not fully control (a storefront theme, a CMS page): one `<script
|
|
68
|
+
src="https://sdk.everfur.com/v1/everfur.js">` puts the surface in an iframe on `sdk.everfur.com`, and
|
|
69
|
+
the frame refuses to initialise on any page origin your tenant has not registered. The copy-paste shape
|
|
70
|
+
is [`examples/frame-embed.html`](examples/frame-embed.html).
|
|
71
|
+
|
|
72
|
+
Chat and records are the web surfaces (records on its own subpath and its own frame document, available
|
|
73
|
+
when Everfur enables records for your account); photo and video remain React Native for now. Vet visits (not yet enabled)
|
|
74
|
+
have their own entry on both hosts, `@everfur/sdk/web/televet` and `@everfur/sdk/televet`:
|
|
75
|
+
[docs/partner-integration/16-TELEVET-VISITS.md](docs/partner-integration/16-TELEVET-VISITS.md).
|
|
76
|
+
|
|
53
77
|
## Quickstart
|
|
54
78
|
|
|
55
79
|
Wrap your tree once, high, then drop features in behind a gate. This is the exact shape the reference app
|
|
56
|
-
uses
|
|
80
|
+
uses, for a **React Native** host; a browser host imports the same names from `@everfur/sdk/web` (see [On
|
|
81
|
+
the web](#on-the-web)):
|
|
57
82
|
|
|
58
83
|
```tsx
|
|
59
84
|
import { EverfurProvider, EverfurChat, petRef, userRef } from '@everfur/sdk';
|
|
@@ -80,7 +105,9 @@ export default function App() {
|
|
|
80
105
|
}
|
|
81
106
|
```
|
|
82
107
|
|
|
83
|
-
`getToken` calls **your** backend for a short-lived session token (never a secret in the app)
|
|
108
|
+
`getToken` calls **your** backend for a short-lived session token (never a secret in the app). Your route
|
|
109
|
+
answers with the token as a plain-text body, which is the shape the MCP planner generates and every example
|
|
110
|
+
in the docs uses:
|
|
84
111
|
|
|
85
112
|
```ts
|
|
86
113
|
async function getToken(): Promise<string> {
|
|
@@ -88,13 +115,14 @@ async function getToken(): Promise<string> {
|
|
|
88
115
|
method: 'POST',
|
|
89
116
|
headers: { authorization: `Bearer ${yourAppsUserToken}` },
|
|
90
117
|
});
|
|
91
|
-
|
|
92
|
-
return
|
|
118
|
+
if (!res.ok) throw new Error('session mint failed: ' + res.status);
|
|
119
|
+
return res.text();
|
|
93
120
|
}
|
|
94
121
|
```
|
|
95
122
|
|
|
96
123
|
The SDK calls `getToken` lazily and re-calls it once after a `401`, so a fresh token is always used without
|
|
97
|
-
you managing expiry.
|
|
124
|
+
you managing expiry. Everfur never sees how you signed the person in (OAuth, a JWT, Firebase, Cognito, a
|
|
125
|
+
session, a magic link all work); it needs one stable, opaque, non-guessable id per person as `userRef`. Records lives on its own subpath:
|
|
98
126
|
|
|
99
127
|
```tsx
|
|
100
128
|
import { EverfurRecords } from '@everfur/sdk/records';
|
|
@@ -105,13 +133,16 @@ import { petRef } from '@everfur/sdk';
|
|
|
105
133
|
|
|
106
134
|
## The security model
|
|
107
135
|
|
|
108
|
-
The one rule: **the app never holds a secret.** Two credentials, kept apart
|
|
136
|
+
The one rule: **the app never holds a secret.** Two provisioning credentials, kept apart, plus a read-only
|
|
137
|
+
docs key for tooling. Test mode is a sandbox tenant on the staging API with an ordinary `pk_live_` key
|
|
138
|
+
(`livemode: false` in its entitlements); no deployed environment accepts a `pk_test_` key.
|
|
109
139
|
|
|
110
140
|
| Credential | Where it lives | What it does |
|
|
111
141
|
| --- | --- | --- |
|
|
112
142
|
| Publishable key `pk_live_...` | In the app (`EXPO_PUBLIC_...`). Safe to ship. | Names your tenant. Cannot mint a session or grant a feature by itself. |
|
|
113
143
|
| Partner secret key `sk_partner_...` | **Only** on your server. Never in the app, its bundle, env, git, or logs. | Mints session tokens. Revocable and rotatable without an app release. |
|
|
114
|
-
| Session token (bearer) | App memory, short-lived. | Authenticates one end user; re-minted via your backend on a 401. |
|
|
144
|
+
| Session token (bearer) | App memory, short-lived. | Authenticates one end user; re-minted via your backend on a 401. Signed, holds no secret, 15 minutes by default (1 minute to 1 hour). |
|
|
145
|
+
| Docs key `dk_partner_...` | Only in the MCP server or CLI configuration on a developer machine. | Read-only: fetches the Everfur contract from `GET /partners/contract` and opens no other route. |
|
|
115
146
|
|
|
116
147
|
Your backend exchanges the two provisioning credentials for a short-lived session by calling
|
|
117
148
|
`POST /widget/v1/sessions` with `x-everfur-partner-key: pk_live_...` + `x-everfur-partner-secret-key:
|
|
@@ -141,12 +172,16 @@ off-state, never a blank region.
|
|
|
141
172
|
| Import | Contents |
|
|
142
173
|
| --- | --- |
|
|
143
174
|
| `@everfur/sdk` | `EverfurProvider`, `CapabilityGate`, `EverfurChat`, `useEverfurChat`, `CapabilityName`, error/result types, branded id helpers (`petRef`, `userRef`, `conversationId`) |
|
|
144
|
-
| `@everfur/sdk/records` | `EverfurRecords`, records hooks + types |
|
|
175
|
+
| `@everfur/sdk/records` | `EverfurRecords`, `EverfurClinicRequest`, `EverfurClinicRequestBatch`, `SignaturePad`, records hooks + types |
|
|
176
|
+
| `@everfur/sdk/records/depth`, `@everfur/sdk/web/records/depth` | record depth (the timeline, the withheld record sections, per-document contributions) on their own entries, dark until Everfur enables it per deployment; see [chapter 9](docs/partner-integration/09-GUIDE-RECORDS-AND-CONSENT.md#record-depth-behind-a-separate-switch) |
|
|
145
177
|
| `@everfur/sdk/video` | gait / live-scan surface |
|
|
146
178
|
| `@everfur/sdk/photo` | photo checkup surface |
|
|
147
179
|
| `@everfur/sdk/animations` | server-driven pet-state media surface |
|
|
180
|
+
| `@everfur/sdk/web` | the browser entry: `EverfurProvider`, `CapabilityGate`, `EverfurChat`, `useEverfurChat`, the theme hook, rendered with `react-dom`; withheld from React Native bundles the way `./server` is |
|
|
181
|
+
| `@everfur/sdk/web/records` | records for a browser host: `EverfurRecords`, `useEverfurRecords`, `createWebRecordsUploadTransport`, `fileToHandle`; its own entry, withheld from React Native like `./web`; available when Everfur enables records for the account. Frame mode serves it with `surface: 'records'` (see [chapter 13](docs/partner-integration/13-WEB-INTEGRATION.md)) |
|
|
148
182
|
| `@everfur/sdk/server` | **server-only** `mintPartnerSession` (no React Native resolution; never bundled on-device) |
|
|
149
|
-
| `@everfur/sdk/
|
|
183
|
+
| `@everfur/sdk/server/events` | **server-only, Node only** partner events (preview): `constructEvent` to verify webhooks, `sendPartnerEvent`; see [chapter 15](docs/partner-integration/15-EVENTS-AND-WEBHOOKS.md) |
|
|
184
|
+
| `@everfur/sdk/testing`, `@everfur/sdk/testing/rn`, `@everfur/sdk/testing/web` | test seams (`MockTransport`, `useEverfurTestEntitlements`, ...) for your own tests |
|
|
150
185
|
|
|
151
186
|
`@everfur/sdk/client` and `@everfur/sdk/core` expose the framework-free layers for advanced integrators;
|
|
152
187
|
most apps only need the root entry plus the capability subpaths.
|
|
@@ -154,7 +189,7 @@ most apps only need the root entry plus the capability subpaths.
|
|
|
154
189
|
## Reference app
|
|
155
190
|
|
|
156
191
|
A full, runnable integration (a fictional "Pawtrail" app plus a minimal mint backend that holds the secret)
|
|
157
|
-
lives at [`examples/minimal-integration.tsx`](examples/minimal-integration.tsx) in this repository
|
|
192
|
+
lives at [`examples/minimal-integration.tsx`](examples/minimal-integration.tsx) in this repository; it is
|
|
158
193
|
type-checked by `npm run docs:check`, so it cannot rot. It shows anonymous mode, the two-credential session
|
|
159
194
|
mint, pet registration and sign-out. (A separate `everfur-integration-example-rn` app exists internally but
|
|
160
195
|
is not published anywhere a partner can reach, so do not rely on references to it.) It gates every
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"//": "GENERATED by scripts/subpath-shims.mjs from the package.json \"exports\" map. Do not edit by hand; run `npm run build`.",
|
|
3
|
+
"react-native": "../dist/consent/index.js",
|
|
4
|
+
"module": "../dist/consent/index.js",
|
|
5
|
+
"main": "../dist/consent/index.cjs",
|
|
6
|
+
"types": "../dist/consent/index.d.ts",
|
|
7
|
+
"sideEffects": false
|
|
8
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
import { P as PetRef, C as ConversationId } from './ids-B2GAAifq.cjs';
|
|
4
|
+
import { F as FileHandle } from './ports-BN6RHF9W.cjs';
|
|
5
|
+
import { a as ChatCheckinTarget } from './ports-DEBzEhbp.cjs';
|
|
6
|
+
import { b as WidgetPet, P as PetProfileInput } from './casesRepository-DHwtGRYY.cjs';
|
|
7
|
+
import { U as UrgencyDisplayLevel, L as LifecyclePort, E as EverfurChatDraftStore } from './attachments-D8T5re7e.cjs';
|
|
8
|
+
|
|
9
|
+
/** Where a picked image comes from: the host's photo library, or its camera. */
|
|
10
|
+
type AttachmentSource = 'photo' | 'camera';
|
|
11
|
+
|
|
12
|
+
/** The host's own action for the two vet-care tiers, in place of Everfur's pill. */
|
|
13
|
+
type RenderVetAction = (level: UrgencyDisplayLevel) => ReactNode;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The host's image picker for chat attachments. The SDK depends on no picker or camera module: open your own
|
|
17
|
+
* (for example `expo-image-picker`'s `launchImageLibraryAsync({ mediaTypes: ['images'] })`, or your camera
|
|
18
|
+
* screen) and resolve `null` when the user cancels, else one `FileHandle` or several (a multi-select pick),
|
|
19
|
+
* each with the local `uri`, the image `mimeType` (`image/jpeg`, `image/png`, `image/webp`, `image/heic`,
|
|
20
|
+
* `image/heif`) and `sizeBytes`. The queue validates type and size (10 MiB) before any request.
|
|
21
|
+
*
|
|
22
|
+
* RESIZING AND EXIF ARE YOURS. The consumer app resizes to 1920 px, re-encodes as JPEG 0.85 and strips EXIF
|
|
23
|
+
* (location, device) before an upload; the SDK uploads the bytes at the `uri` as they are, so do the same in
|
|
24
|
+
* `pick` (for example with `expo-image-manipulator`) before resolving.
|
|
25
|
+
*/
|
|
26
|
+
interface EverfurChatAttachments {
|
|
27
|
+
readonly pick: (source: AttachmentSource) => Promise<FileHandle | readonly FileHandle[] | null>;
|
|
28
|
+
/** The sources to offer, one popover tile each; default `['photo']`. */
|
|
29
|
+
readonly sources?: readonly AttachmentSource[];
|
|
30
|
+
/** Images per message; default 1 (the app's composer), at most 5 (the server's cap). */
|
|
31
|
+
readonly maxPerMessage?: number;
|
|
32
|
+
}
|
|
33
|
+
interface EverfurChatProps {
|
|
34
|
+
readonly petRef?: PetRef;
|
|
35
|
+
readonly conversationId?: ConversationId;
|
|
36
|
+
readonly style?: StyleProp<ViewStyle>;
|
|
37
|
+
/**
|
|
38
|
+
* Your own placeholder for the two moments Everfur would otherwise draw a waiting view of its own: the
|
|
39
|
+
* entitlement verdict still pending, and the chat still bootstrapping on a cold mount. Return null to draw
|
|
40
|
+
* nothing. A mount `prepare()` warmed up never reaches either. Absent, Everfur's skeleton and delayed spinner.
|
|
41
|
+
*/
|
|
42
|
+
readonly renderPending?: () => ReactNode;
|
|
43
|
+
/**
|
|
44
|
+
* Your clipboard (for example `expo-clipboard`'s `setStringAsync`). Given, every message gets the app's
|
|
45
|
+
* copy control; absent, no copy control renders (the SDK depends on no clipboard module).
|
|
46
|
+
*/
|
|
47
|
+
readonly onCopy?: (text: string) => Promise<void> | void;
|
|
48
|
+
/** Called after the user picked another pet in the header switcher and the provider re-scoped to it. */
|
|
49
|
+
readonly onPetChange?: (petRef: PetRef) => void;
|
|
50
|
+
/**
|
|
51
|
+
* Your vet-visit preparation screen. Given, the empty thread's `Help me prep for {pet}'s vet visit.` chip
|
|
52
|
+
* routes to it with the pet; absent, that chip is the Everfur vet visit entry inside Chat, shown only
|
|
53
|
+
* while Everfur has it switched on for your tenant, else not shown at all.
|
|
54
|
+
*/
|
|
55
|
+
readonly onVetPrep?: (pet: WidgetPet | null) => void;
|
|
56
|
+
/**
|
|
57
|
+
* Your vet finder. On an `emergency` or `schedule_soon` reply the banner's `Find a vet` pill opens the
|
|
58
|
+
* Everfur vet visit entry when it is on for your tenant, else calls this, else does not render.
|
|
59
|
+
*/
|
|
60
|
+
readonly onFindVet?: (level: UrgencyDisplayLevel) => void;
|
|
61
|
+
/** Your own control in the banner's action slot for those two tiers, in place of the pill. */
|
|
62
|
+
readonly renderVetAction?: RenderVetAction;
|
|
63
|
+
/** Your image picker: given, the composer gets the app's attachment control, previews and lightbox. */
|
|
64
|
+
readonly attachments?: EverfurChatAttachments;
|
|
65
|
+
/**
|
|
66
|
+
* The pet this chat is about, as YOUR system holds it: the whole partner pet body (name, species, breed,
|
|
67
|
+
* age, weight, and every health field, allergies, medications, supplements and conditions included). Given
|
|
68
|
+
* with `petRef`, the surface registers it with Everfur once, before the first conversation, and then names
|
|
69
|
+
* it in the header and the switcher. Nothing is trimmed: what you pass is what is sent.
|
|
70
|
+
*/
|
|
71
|
+
readonly pet?: PetProfileInput;
|
|
72
|
+
/**
|
|
73
|
+
* Your own add-a-pet screen. Given, the switcher gets an `Add another pet` row, and a chat that cannot start
|
|
74
|
+
* because the `petRef` is not registered offers `Add a pet` in place of a retry that could only fail again.
|
|
75
|
+
* Absent, neither control is drawn: the partner plane never shows a route Everfur cannot honour.
|
|
76
|
+
*/
|
|
77
|
+
readonly onAddPet?: () => void;
|
|
78
|
+
/**
|
|
79
|
+
* The check-in a tapped Everfur push is about: the `case` target `parseEverfurNotification` returned. Chat
|
|
80
|
+
* opens that thread on mount, once per target, so a due follow-up question is the first thing the member
|
|
81
|
+
* sees instead of something they would have to find in the history drawer. Absent, chat opens as usual.
|
|
82
|
+
*/
|
|
83
|
+
readonly checkinTarget?: ChatCheckinTarget;
|
|
84
|
+
/**
|
|
85
|
+
* A question to ask on arrival, in a conversation of its own: the prompt one of your own screens built
|
|
86
|
+
* (an Everfur records "Ask Everfur" pill hands you one). It is asked once, after chat has finished
|
|
87
|
+
* opening, and the thread that was on screen is left behind so the answer is not buried in an unrelated
|
|
88
|
+
* conversation. Pass `composerSeed` instead when the user should decide whether to send it.
|
|
89
|
+
*/
|
|
90
|
+
readonly initialAsk?: string;
|
|
91
|
+
/**
|
|
92
|
+
* Text to put in the composer on arrival. It is never sent for the user: they edit it, send it or clear
|
|
93
|
+
* it. Only an empty composer is seeded, so nothing they typed is ever replaced.
|
|
94
|
+
*/
|
|
95
|
+
readonly composerSeed?: string;
|
|
96
|
+
/**
|
|
97
|
+
* Your app's lifecycle signals. Everfur has no socket and no polling here, so a message the platform
|
|
98
|
+
* writes into the thread (a follow-up check-in, a reminder) is not visible until something re-reads it.
|
|
99
|
+
* Tell Everfur when your app comes back to the foreground, when connectivity returns and when a push
|
|
100
|
+
* announced a change, and the thread and the unread dot catch up on that signal alone. Without this, chat
|
|
101
|
+
* refreshes only when the user does something.
|
|
102
|
+
*/
|
|
103
|
+
readonly lifecycle?: LifecyclePort;
|
|
104
|
+
/**
|
|
105
|
+
* Your own storage for an unsent draft. Given, what the user typed and did not send survives leaving this
|
|
106
|
+
* screen; absent, the draft lives in memory for as long as the surface is mounted and nowhere else.
|
|
107
|
+
* Everfur writes a draft down only through this.
|
|
108
|
+
*/
|
|
109
|
+
readonly draftStore?: EverfurChatDraftStore;
|
|
110
|
+
/**
|
|
111
|
+
* The KEY of a return destination your tenant registered with Everfur. Every vet entry inside chat (the
|
|
112
|
+
* header, the urgency banner's pill and the empty thread's vet-prep chip) then sends the user back to your
|
|
113
|
+
* app when the visit ends.
|
|
114
|
+
*/
|
|
115
|
+
readonly vetReturnTo?: string;
|
|
116
|
+
/**
|
|
117
|
+
* The user's US state (for example `'CA'`). Set it and no vet entry is drawn until Everfur confirms a visit
|
|
118
|
+
* is available there, so it is never offered to someone who could not book.
|
|
119
|
+
*/
|
|
120
|
+
readonly vetUsState?: string;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Entitlement-gated, four-state chat surface. Entitlement-OFF renders the CapabilityGate OffState;
|
|
124
|
+
* otherwise the body maps the controller snapshot to exactly one deliberate state.
|
|
125
|
+
*/
|
|
126
|
+
declare function EverfurChat(props: EverfurChatProps): ReactNode;
|
|
127
|
+
|
|
128
|
+
export { type AttachmentSource as A, EverfurChat as E, type RenderVetAction as R, type EverfurChatAttachments as a, type EverfurChatProps as b };
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
import { P as PetRef, C as ConversationId } from './ids-B2GAAifq.js';
|
|
4
|
+
import { F as FileHandle } from './ports-BN6RHF9W.js';
|
|
5
|
+
import { a as ChatCheckinTarget } from './ports-DMolTRzU.js';
|
|
6
|
+
import { b as WidgetPet, P as PetProfileInput } from './casesRepository-ClLv6qMl.js';
|
|
7
|
+
import { U as UrgencyDisplayLevel, L as LifecyclePort, E as EverfurChatDraftStore } from './attachments-5NeobOCd.js';
|
|
8
|
+
|
|
9
|
+
/** Where a picked image comes from: the host's photo library, or its camera. */
|
|
10
|
+
type AttachmentSource = 'photo' | 'camera';
|
|
11
|
+
|
|
12
|
+
/** The host's own action for the two vet-care tiers, in place of Everfur's pill. */
|
|
13
|
+
type RenderVetAction = (level: UrgencyDisplayLevel) => ReactNode;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The host's image picker for chat attachments. The SDK depends on no picker or camera module: open your own
|
|
17
|
+
* (for example `expo-image-picker`'s `launchImageLibraryAsync({ mediaTypes: ['images'] })`, or your camera
|
|
18
|
+
* screen) and resolve `null` when the user cancels, else one `FileHandle` or several (a multi-select pick),
|
|
19
|
+
* each with the local `uri`, the image `mimeType` (`image/jpeg`, `image/png`, `image/webp`, `image/heic`,
|
|
20
|
+
* `image/heif`) and `sizeBytes`. The queue validates type and size (10 MiB) before any request.
|
|
21
|
+
*
|
|
22
|
+
* RESIZING AND EXIF ARE YOURS. The consumer app resizes to 1920 px, re-encodes as JPEG 0.85 and strips EXIF
|
|
23
|
+
* (location, device) before an upload; the SDK uploads the bytes at the `uri` as they are, so do the same in
|
|
24
|
+
* `pick` (for example with `expo-image-manipulator`) before resolving.
|
|
25
|
+
*/
|
|
26
|
+
interface EverfurChatAttachments {
|
|
27
|
+
readonly pick: (source: AttachmentSource) => Promise<FileHandle | readonly FileHandle[] | null>;
|
|
28
|
+
/** The sources to offer, one popover tile each; default `['photo']`. */
|
|
29
|
+
readonly sources?: readonly AttachmentSource[];
|
|
30
|
+
/** Images per message; default 1 (the app's composer), at most 5 (the server's cap). */
|
|
31
|
+
readonly maxPerMessage?: number;
|
|
32
|
+
}
|
|
33
|
+
interface EverfurChatProps {
|
|
34
|
+
readonly petRef?: PetRef;
|
|
35
|
+
readonly conversationId?: ConversationId;
|
|
36
|
+
readonly style?: StyleProp<ViewStyle>;
|
|
37
|
+
/**
|
|
38
|
+
* Your own placeholder for the two moments Everfur would otherwise draw a waiting view of its own: the
|
|
39
|
+
* entitlement verdict still pending, and the chat still bootstrapping on a cold mount. Return null to draw
|
|
40
|
+
* nothing. A mount `prepare()` warmed up never reaches either. Absent, Everfur's skeleton and delayed spinner.
|
|
41
|
+
*/
|
|
42
|
+
readonly renderPending?: () => ReactNode;
|
|
43
|
+
/**
|
|
44
|
+
* Your clipboard (for example `expo-clipboard`'s `setStringAsync`). Given, every message gets the app's
|
|
45
|
+
* copy control; absent, no copy control renders (the SDK depends on no clipboard module).
|
|
46
|
+
*/
|
|
47
|
+
readonly onCopy?: (text: string) => Promise<void> | void;
|
|
48
|
+
/** Called after the user picked another pet in the header switcher and the provider re-scoped to it. */
|
|
49
|
+
readonly onPetChange?: (petRef: PetRef) => void;
|
|
50
|
+
/**
|
|
51
|
+
* Your vet-visit preparation screen. Given, the empty thread's `Help me prep for {pet}'s vet visit.` chip
|
|
52
|
+
* routes to it with the pet; absent, that chip is the Everfur vet visit entry inside Chat, shown only
|
|
53
|
+
* while Everfur has it switched on for your tenant, else not shown at all.
|
|
54
|
+
*/
|
|
55
|
+
readonly onVetPrep?: (pet: WidgetPet | null) => void;
|
|
56
|
+
/**
|
|
57
|
+
* Your vet finder. On an `emergency` or `schedule_soon` reply the banner's `Find a vet` pill opens the
|
|
58
|
+
* Everfur vet visit entry when it is on for your tenant, else calls this, else does not render.
|
|
59
|
+
*/
|
|
60
|
+
readonly onFindVet?: (level: UrgencyDisplayLevel) => void;
|
|
61
|
+
/** Your own control in the banner's action slot for those two tiers, in place of the pill. */
|
|
62
|
+
readonly renderVetAction?: RenderVetAction;
|
|
63
|
+
/** Your image picker: given, the composer gets the app's attachment control, previews and lightbox. */
|
|
64
|
+
readonly attachments?: EverfurChatAttachments;
|
|
65
|
+
/**
|
|
66
|
+
* The pet this chat is about, as YOUR system holds it: the whole partner pet body (name, species, breed,
|
|
67
|
+
* age, weight, and every health field, allergies, medications, supplements and conditions included). Given
|
|
68
|
+
* with `petRef`, the surface registers it with Everfur once, before the first conversation, and then names
|
|
69
|
+
* it in the header and the switcher. Nothing is trimmed: what you pass is what is sent.
|
|
70
|
+
*/
|
|
71
|
+
readonly pet?: PetProfileInput;
|
|
72
|
+
/**
|
|
73
|
+
* Your own add-a-pet screen. Given, the switcher gets an `Add another pet` row, and a chat that cannot start
|
|
74
|
+
* because the `petRef` is not registered offers `Add a pet` in place of a retry that could only fail again.
|
|
75
|
+
* Absent, neither control is drawn: the partner plane never shows a route Everfur cannot honour.
|
|
76
|
+
*/
|
|
77
|
+
readonly onAddPet?: () => void;
|
|
78
|
+
/**
|
|
79
|
+
* The check-in a tapped Everfur push is about: the `case` target `parseEverfurNotification` returned. Chat
|
|
80
|
+
* opens that thread on mount, once per target, so a due follow-up question is the first thing the member
|
|
81
|
+
* sees instead of something they would have to find in the history drawer. Absent, chat opens as usual.
|
|
82
|
+
*/
|
|
83
|
+
readonly checkinTarget?: ChatCheckinTarget;
|
|
84
|
+
/**
|
|
85
|
+
* A question to ask on arrival, in a conversation of its own: the prompt one of your own screens built
|
|
86
|
+
* (an Everfur records "Ask Everfur" pill hands you one). It is asked once, after chat has finished
|
|
87
|
+
* opening, and the thread that was on screen is left behind so the answer is not buried in an unrelated
|
|
88
|
+
* conversation. Pass `composerSeed` instead when the user should decide whether to send it.
|
|
89
|
+
*/
|
|
90
|
+
readonly initialAsk?: string;
|
|
91
|
+
/**
|
|
92
|
+
* Text to put in the composer on arrival. It is never sent for the user: they edit it, send it or clear
|
|
93
|
+
* it. Only an empty composer is seeded, so nothing they typed is ever replaced.
|
|
94
|
+
*/
|
|
95
|
+
readonly composerSeed?: string;
|
|
96
|
+
/**
|
|
97
|
+
* Your app's lifecycle signals. Everfur has no socket and no polling here, so a message the platform
|
|
98
|
+
* writes into the thread (a follow-up check-in, a reminder) is not visible until something re-reads it.
|
|
99
|
+
* Tell Everfur when your app comes back to the foreground, when connectivity returns and when a push
|
|
100
|
+
* announced a change, and the thread and the unread dot catch up on that signal alone. Without this, chat
|
|
101
|
+
* refreshes only when the user does something.
|
|
102
|
+
*/
|
|
103
|
+
readonly lifecycle?: LifecyclePort;
|
|
104
|
+
/**
|
|
105
|
+
* Your own storage for an unsent draft. Given, what the user typed and did not send survives leaving this
|
|
106
|
+
* screen; absent, the draft lives in memory for as long as the surface is mounted and nowhere else.
|
|
107
|
+
* Everfur writes a draft down only through this.
|
|
108
|
+
*/
|
|
109
|
+
readonly draftStore?: EverfurChatDraftStore;
|
|
110
|
+
/**
|
|
111
|
+
* The KEY of a return destination your tenant registered with Everfur. Every vet entry inside chat (the
|
|
112
|
+
* header, the urgency banner's pill and the empty thread's vet-prep chip) then sends the user back to your
|
|
113
|
+
* app when the visit ends.
|
|
114
|
+
*/
|
|
115
|
+
readonly vetReturnTo?: string;
|
|
116
|
+
/**
|
|
117
|
+
* The user's US state (for example `'CA'`). Set it and no vet entry is drawn until Everfur confirms a visit
|
|
118
|
+
* is available there, so it is never offered to someone who could not book.
|
|
119
|
+
*/
|
|
120
|
+
readonly vetUsState?: string;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Entitlement-gated, four-state chat surface. Entitlement-OFF renders the CapabilityGate OffState;
|
|
124
|
+
* otherwise the body maps the controller snapshot to exactly one deliberate state.
|
|
125
|
+
*/
|
|
126
|
+
declare function EverfurChat(props: EverfurChatProps): ReactNode;
|
|
127
|
+
|
|
128
|
+
export { type AttachmentSource as A, EverfurChat as E, type RenderVetAction as R, type EverfurChatAttachments as a, type EverfurChatProps as b };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import { f as RecordsScreenBaseProps } from './useRecordsDepth-BU-OhzH6.js';
|
|
3
|
+
|
|
4
|
+
interface EverfurRecordsDepthProps extends Pick<RecordsScreenBaseProps, 'petRef' | 'petName' | 'onNavigate' | 'onBack'> {
|
|
5
|
+
readonly style?: CSSProperties;
|
|
6
|
+
readonly className?: string;
|
|
7
|
+
}
|
|
8
|
+
interface EverfurDocumentContributionsProps extends EverfurRecordsDepthProps {
|
|
9
|
+
/** A `docId` from the record's `documents`. */
|
|
10
|
+
readonly docId: string;
|
|
11
|
+
}
|
|
12
|
+
declare function EverfurRecordsTimeline({ petRef, style, className, onBack }: EverfurRecordsDepthProps): ReactNode;
|
|
13
|
+
declare function EverfurRecordDepth({ petRef, style, className, onBack }: EverfurRecordsDepthProps): ReactNode;
|
|
14
|
+
declare function EverfurDocumentContributions({ petRef, docId, style, className, onBack }: EverfurDocumentContributionsProps): ReactNode;
|
|
15
|
+
|
|
16
|
+
export { EverfurDocumentContributions as E, type EverfurDocumentContributionsProps as a, EverfurRecordDepth as b, type EverfurRecordsDepthProps as c, EverfurRecordsTimeline as d };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
import { f as RecordsScreenBaseProps } from './useRecordsDepth-BHBzJ76R.cjs';
|
|
4
|
+
|
|
5
|
+
interface EverfurRecordsDepthProps extends Pick<RecordsScreenBaseProps, 'petRef' | 'petName' | 'onNavigate' | 'onBack'> {
|
|
6
|
+
readonly style?: StyleProp<ViewStyle>;
|
|
7
|
+
}
|
|
8
|
+
interface EverfurDocumentContributionsProps extends EverfurRecordsDepthProps {
|
|
9
|
+
/** A `docId` from the record's `documents`. */
|
|
10
|
+
readonly docId: string;
|
|
11
|
+
}
|
|
12
|
+
/** The consumer timeline screen: `Timeline` over visits, vaccines, weights and medications merged newest first. */
|
|
13
|
+
declare function EverfurRecordsTimeline({ petRef, style, onBack }: EverfurRecordsDepthProps): ReactNode;
|
|
14
|
+
/** The four sections the base record withholds: lab work, visits, physical exams and visit notes. */
|
|
15
|
+
declare function EverfurRecordDepth({ petRef, style, onBack }: EverfurRecordsDepthProps): ReactNode;
|
|
16
|
+
/** What one published document contributed to the record, in the record's own row vocabulary. */
|
|
17
|
+
declare function EverfurDocumentContributions({ petRef, docId, style, onBack }: EverfurDocumentContributionsProps): ReactNode;
|
|
18
|
+
|
|
19
|
+
export { EverfurDocumentContributions as E, type EverfurDocumentContributionsProps as a, EverfurRecordDepth as b, type EverfurRecordsDepthProps as c, EverfurRecordsTimeline as d };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
import { f as RecordsScreenBaseProps } from './useRecordsDepth-BU-OhzH6.js';
|
|
4
|
+
|
|
5
|
+
interface EverfurRecordsDepthProps extends Pick<RecordsScreenBaseProps, 'petRef' | 'petName' | 'onNavigate' | 'onBack'> {
|
|
6
|
+
readonly style?: StyleProp<ViewStyle>;
|
|
7
|
+
}
|
|
8
|
+
interface EverfurDocumentContributionsProps extends EverfurRecordsDepthProps {
|
|
9
|
+
/** A `docId` from the record's `documents`. */
|
|
10
|
+
readonly docId: string;
|
|
11
|
+
}
|
|
12
|
+
/** The consumer timeline screen: `Timeline` over visits, vaccines, weights and medications merged newest first. */
|
|
13
|
+
declare function EverfurRecordsTimeline({ petRef, style, onBack }: EverfurRecordsDepthProps): ReactNode;
|
|
14
|
+
/** The four sections the base record withholds: lab work, visits, physical exams and visit notes. */
|
|
15
|
+
declare function EverfurRecordDepth({ petRef, style, onBack }: EverfurRecordsDepthProps): ReactNode;
|
|
16
|
+
/** What one published document contributed to the record, in the record's own row vocabulary. */
|
|
17
|
+
declare function EverfurDocumentContributions({ petRef, docId, style, onBack }: EverfurDocumentContributionsProps): ReactNode;
|
|
18
|
+
|
|
19
|
+
export { EverfurDocumentContributions as E, type EverfurDocumentContributionsProps as a, EverfurRecordDepth as b, type EverfurRecordsDepthProps as c, EverfurRecordsTimeline as d };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import { f as RecordsScreenBaseProps } from './useRecordsDepth-BHBzJ76R.cjs';
|
|
3
|
+
|
|
4
|
+
interface EverfurRecordsDepthProps extends Pick<RecordsScreenBaseProps, 'petRef' | 'petName' | 'onNavigate' | 'onBack'> {
|
|
5
|
+
readonly style?: CSSProperties;
|
|
6
|
+
readonly className?: string;
|
|
7
|
+
}
|
|
8
|
+
interface EverfurDocumentContributionsProps extends EverfurRecordsDepthProps {
|
|
9
|
+
/** A `docId` from the record's `documents`. */
|
|
10
|
+
readonly docId: string;
|
|
11
|
+
}
|
|
12
|
+
declare function EverfurRecordsTimeline({ petRef, style, className, onBack }: EverfurRecordsDepthProps): ReactNode;
|
|
13
|
+
declare function EverfurRecordDepth({ petRef, style, className, onBack }: EverfurRecordsDepthProps): ReactNode;
|
|
14
|
+
declare function EverfurDocumentContributions({ petRef, docId, style, className, onBack }: EverfurDocumentContributionsProps): ReactNode;
|
|
15
|
+
|
|
16
|
+
export { EverfurDocumentContributions as E, type EverfurDocumentContributionsProps as a, EverfurRecordDepth as b, type EverfurRecordsDepthProps as c, EverfurRecordsTimeline as d };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { b as EverfurErrorCode, E as EverfurError } from './EverfurResult-DN9pL2Ab.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Recovery policy. A host may narrow retry ceilings (e.g. a metered plan) but can never widen the SDK's
|
|
5
|
+
* settle-don't-throw contract. `attempt` is 0-based (the first try is attempt 0).
|
|
6
|
+
*/
|
|
7
|
+
interface ErrorPolicyPort {
|
|
8
|
+
/** Whether to retry `code` on this attempt. Default: `isAutoRetryable(code) && attempt < maxAttempts(code)`. */
|
|
9
|
+
shouldRetry(code: EverfurErrorCode, attempt: number): boolean;
|
|
10
|
+
/** Total attempts (the initial try plus retries) before the terminal error surfaces. Default 4. */
|
|
11
|
+
maxAttempts(code: EverfurErrorCode): number;
|
|
12
|
+
/** Observation hook for a handled, product-expected failure. Never rendered, never thrown. */
|
|
13
|
+
onExpectedFailure?(error: EverfurError): void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The shipped default policy (applied when EverfurConfig omits `errorPolicy`). Pure and total.
|
|
17
|
+
* `authExpired` is deliberately NOT auto-retried here: it is a token refresh + single replay handled by the
|
|
18
|
+
* controller / authedSend, not a backoff retry (SPEC-00 §3.2 / §4.3).
|
|
19
|
+
*/
|
|
20
|
+
declare const defaultErrorPolicy: ErrorPolicyPort;
|
|
21
|
+
|
|
22
|
+
export { type ErrorPolicyPort as E, defaultErrorPolicy as d };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { b as EverfurErrorCode, E as EverfurError } from './EverfurResult-DN9pL2Ab.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Recovery policy. A host may narrow retry ceilings (e.g. a metered plan) but can never widen the SDK's
|
|
5
|
+
* settle-don't-throw contract. `attempt` is 0-based (the first try is attempt 0).
|
|
6
|
+
*/
|
|
7
|
+
interface ErrorPolicyPort {
|
|
8
|
+
/** Whether to retry `code` on this attempt. Default: `isAutoRetryable(code) && attempt < maxAttempts(code)`. */
|
|
9
|
+
shouldRetry(code: EverfurErrorCode, attempt: number): boolean;
|
|
10
|
+
/** Total attempts (the initial try plus retries) before the terminal error surfaces. Default 4. */
|
|
11
|
+
maxAttempts(code: EverfurErrorCode): number;
|
|
12
|
+
/** Observation hook for a handled, product-expected failure. Never rendered, never thrown. */
|
|
13
|
+
onExpectedFailure?(error: EverfurError): void;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* The shipped default policy (applied when EverfurConfig omits `errorPolicy`). Pure and total.
|
|
17
|
+
* `authExpired` is deliberately NOT auto-retried here: it is a token refresh + single replay handled by the
|
|
18
|
+
* controller / authedSend, not a backoff retry (SPEC-00 §3.2 / §4.3).
|
|
19
|
+
*/
|
|
20
|
+
declare const defaultErrorPolicy: ErrorPolicyPort;
|
|
21
|
+
|
|
22
|
+
export { type ErrorPolicyPort as E, defaultErrorPolicy as d };
|
|
@@ -131,6 +131,12 @@ interface EverfurError {
|
|
|
131
131
|
readonly requestId?: string;
|
|
132
132
|
/** Site-relative documentation path for the wire code, from the contract registry. No host is implied. */
|
|
133
133
|
readonly docUrl?: string;
|
|
134
|
+
/**
|
|
135
|
+
* The server's stable sub-reason for this failure, when it sent one (for example `pet_not_registered` or
|
|
136
|
+
* `species_unsupported` on the records routes). Safe to branch on, unlike `wireMessage`. Only a lowercase
|
|
137
|
+
* snake_case token is kept; anything else is dropped rather than carried.
|
|
138
|
+
*/
|
|
139
|
+
readonly reasonCode?: string;
|
|
134
140
|
/** raw wire text; telemetry / logs only, NEVER rendered. NON-ENUMERABLE. */
|
|
135
141
|
readonly wireMessage?: string;
|
|
136
142
|
/** Opaque parsed wire payload for debugging (untrusted, unvalidated). NON-ENUMERABLE. */
|
|
@@ -155,20 +161,15 @@ interface MakeEverfurErrorOptions {
|
|
|
155
161
|
* the code exactly as the server sent it; a code that is not in the registry simply yields no docUrl.
|
|
156
162
|
*/
|
|
157
163
|
readonly wireCode?: string | null;
|
|
164
|
+
/** The envelope the wire code arrived in, when known; a code registered on both envelopes resolves to its own row. */
|
|
165
|
+
readonly wireEnvelope?: 'http_envelope' | 'sse_frame';
|
|
158
166
|
/** Untrusted wire text. Carried NON-ENUMERABLY for telemetry; never rendered. */
|
|
159
167
|
readonly wireMessage?: string | null;
|
|
168
|
+
/** The server's `reason_code`, kept only when it is a lowercase snake_case token (see `EverfurError.reasonCode`). */
|
|
169
|
+
readonly reasonCode?: string | null;
|
|
160
170
|
/** Opaque parsed wire payload. Carried NON-ENUMERABLY for debugging; never rendered. */
|
|
161
171
|
readonly raw?: unknown;
|
|
162
172
|
}
|
|
163
|
-
/**
|
|
164
|
-
* Build a normalized, frozen `EverfurError` from a normalized code plus optional wire/HTTP context.
|
|
165
|
-
*
|
|
166
|
-
* `displayMessage` is always the SAFE code-derived string. `retryable` defaults to the code's policy
|
|
167
|
-
* (`isRetryableCode`) unless the caller overrides it, e.g. a frame carrying explicit `retryable:true`.
|
|
168
|
-
* `requestId` and `docUrl` are the two support-facing additions: the id a partner quotes, and the
|
|
169
|
-
* site-relative registry path for the wire code. `wireMessage` and `raw` are carried NON-ENUMERABLY and
|
|
170
|
-
* are dropped when empty.
|
|
171
|
-
*/
|
|
172
173
|
declare function makeEverfurError(code: EverfurErrorCode, opts?: MakeEverfurErrorOptions): EverfurError;
|
|
173
174
|
|
|
174
175
|
/**
|
|
@@ -237,4 +238,4 @@ declare class EverfurConfigError extends Error {
|
|
|
237
238
|
constructor(kind: 'not-initialized' | 'invalid-argument' | 'missing-peer-dependency', message: string);
|
|
238
239
|
}
|
|
239
240
|
|
|
240
|
-
export { AUTO_RETRYABLE_CODES as A, BACKOFF_BASE_MS as B, type
|
|
241
|
+
export { AUTO_RETRYABLE_CODES as A, BACKOFF_BASE_MS as B, type EverfurError as E, MAX_RETRY_ATTEMPTS as M, RETRYABLE_CONTRACT_CODES as R, type EverfurErrorCategory as a, type EverfurErrorCode as b, type EverfurResult as c, EverfurConfigError as d, EverfurThrownError as e, categoryFor as f, isOk as g, isRetryableCode as h, isErr as i, userFacingError as j, BACKOFF_CAP_MS as k, EVERFUR_ERROR_CATEGORIES as l, EVERFUR_ERROR_CODES as m, type MakeEverfurErrorOptions as n, backoffDelayMs as o, canRecreateOnNotFound as p, err as q, fromHttpStatus as r, fromWire as s, isAutoRetryable as t, unwrap as u, makeEverfurError as v, ok as w, shouldRetry as x };
|