@everfur/sdk 0.12.0 → 0.13.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 +174 -0
- package/README.md +2 -1
- package/dist/{Chat-BOG0SXKV.d.cts → Chat.d-DUNTfzqC.d.ts} +170 -8
- package/dist/{Chat-CIolBgjJ.d.ts → Chat.d-Dts8u_1a.d.cts} +170 -8
- package/dist/{DepthViews-BR6VQ3Ta.d.cts → DepthViews.d-BIp599lz.d.cts} +1 -1
- package/dist/{DepthViews-280t3BcQ.d.ts → DepthViews.d-BMU2jFPw.d.cts} +1 -1
- package/dist/{DepthViews-DlBuFsgN.d.ts → DepthViews.d-Ce2Zhnrb.d.ts} +1 -1
- package/dist/{DepthViews-BTbF_DJY.d.cts → DepthViews.d-CubkMPbU.d.ts} +1 -1
- package/dist/{ErrorPolicyPort-10s3HJCt.d.cts → ErrorPolicyPort.d-68yrE3BE.d.ts} +1 -1
- package/dist/{ErrorPolicyPort-C3nNSS_j.d.ts → ErrorPolicyPort.d-DirW9hgO.d.cts} +1 -1
- package/dist/{EverfurError-DeBqRpQV.d.cts → EverfurError.d-8NHtlgzA.d.cts} +11 -1
- package/dist/{EverfurError-DeBqRpQV.d.ts → EverfurError.d-8NHtlgzA.d.ts} +11 -1
- package/dist/{EverfurResult-ClPTS0P2.d.ts → EverfurResult.d-BFH-3s6E.d.cts} +1 -1
- package/dist/{EverfurResult-COlXj1wq.d.cts → EverfurResult.d-D_-254ZY.d.ts} +1 -1
- package/dist/{IntakeMedia-BH0fYDT2.d.cts → IntakeMedia.d-4a89XrP7.d.ts} +1 -1
- package/dist/{IntakeMedia-B-_vA9ZB.d.cts → IntakeMedia.d-DGxrhgIW.d.ts} +1 -1
- package/dist/{IntakeMedia-CIoTXAWs.d.ts → IntakeMedia.d-DUPR4lVM.d.cts} +1 -1
- package/dist/{IntakeMedia-Bavl7E4Z.d.ts → IntakeMedia.d-JJCUvQu7.d.cts} +1 -1
- package/dist/LifecyclePort.d-Cr1p33a7.d.cts +23 -0
- package/dist/LifecyclePort.d-Cr1p33a7.d.ts +23 -0
- package/dist/{PhotoController-vzY5bfY_.d.ts → PhotoController.d-BzCJOE7e.d.cts} +2 -2
- package/dist/{PhotoController-3l7MT9jA.d.cts → PhotoController.d-D0XiUUOl.d.ts} +2 -2
- package/dist/animations/index.cjs +5 -1
- package/dist/animations/index.d.cts +24 -24
- package/dist/animations/index.d.ts +24 -24
- package/dist/animations/index.js +5 -1
- package/dist/{attachments-CGxvnYu4.d.ts → attachments.d-Bp2qbHxn.d.cts} +22 -26
- package/dist/{attachments-CWNj1ZkM.d.ts → attachments.d-D1yhJjcZ.d.ts} +4 -4
- package/dist/{attachments-waXcJWCp.d.cts → attachments.d-DisnvB9R.d.cts} +4 -4
- package/dist/{attachments-B6h4cJU-.d.cts → attachments.d-Djy9z_0Z.d.ts} +22 -26
- package/dist/{bookingCopy-CjPKeg75.d.ts → bookingCopy.d-BJF6gd1A.d.ts} +24 -9
- package/dist/{bookingCopy-8aEU6ZmR.d.cts → bookingCopy.d-BlBmhAJc.d.cts} +24 -9
- package/dist/{branding-DJf4h12Q.d.ts → branding.d-DI8S400y.d.cts} +9 -2
- package/dist/{branding-BCfwLj0h.d.cts → branding.d-OIGLbQeM.d.ts} +9 -2
- package/dist/{callRoom-BhIdadyV.d.cts → callRoom.d-B1DoYdJe.d.cts} +1 -1
- package/dist/{callRoom-B92eH_ij.d.ts → callRoom.d-Dqm1rUqT.d.ts} +1 -1
- package/dist/{casesRepository-CGdhvzTu.d.cts → casesRepository.d-CT2LTicS.d.cts} +3 -3
- package/dist/{casesRepository-ZG9Sg0e4.d.ts → casesRepository.d-UsWOz9bv.d.ts} +3 -3
- package/dist/chat/index.cjs +132 -57
- package/dist/chat/index.d.cts +18 -16
- package/dist/chat/index.d.ts +18 -16
- package/dist/chat/index.js +133 -58
- package/dist/client/index.cjs +15 -10
- package/dist/client/index.d.cts +19 -18
- package/dist/client/index.d.ts +19 -18
- package/dist/client/index.js +15 -10
- package/dist/{config-B0p6Lygh.d.cts → config.d-BR3DT9ho.d.cts} +3 -3
- package/dist/{config-DmFAZJOx.d.ts → config.d-Dy6igYlH.d.ts} +3 -3
- package/dist/consent/index.cjs +5 -1
- package/dist/consent/index.d.cts +10 -10
- package/dist/consent/index.d.ts +10 -10
- package/dist/consent/index.js +5 -1
- package/dist/{context-BNreNLtL.d.ts → context.d-Cwks0p3C.d.cts} +15 -15
- package/dist/{context-BgS2a57J.d.cts → context.d-QcCgguzA.d.ts} +15 -15
- package/dist/{copy-DLJriGQS.d.ts → copy.d-CiMn2IIt.d.ts} +6 -6
- package/dist/{copy-lWp-Lkv5.d.cts → copy.d-DLJTyRfT.d.cts} +6 -6
- package/dist/core/index.cjs +17 -13
- package/dist/core/index.d.cts +33 -29
- package/dist/core/index.d.ts +33 -29
- package/dist/core/index.js +17 -13
- package/dist/{depth-BYb3RXoA.d.cts → depth.d-CjPGVPDL.d.cts} +9 -115
- package/dist/{depth-COz-sSG5.d.ts → depth.d-OSALbYM7.d.ts} +9 -115
- package/dist/{entitlementRepository-D-Lse67w.d.cts → entitlementRepository.d-CVQa1DA1.d.cts} +10 -5
- package/dist/{entitlementRepository-CrTOP_-o.d.ts → entitlementRepository.d-Cf3LbTwD.d.ts} +10 -5
- package/dist/features.d-fNsGcg0R.d.cts +108 -0
- package/dist/features.d-fNsGcg0R.d.ts +108 -0
- package/dist/focus.d-DMg2ngHI.d.ts +1178 -0
- package/dist/focus.d-az9cqUz3.d.cts +1178 -0
- package/dist/health-plan/index.cjs +370 -0
- package/dist/health-plan/index.d.cts +251 -0
- package/dist/health-plan/index.d.ts +251 -0
- package/dist/health-plan/index.js +370 -0
- package/dist/idempotency.d-D461_DPD.d.cts +910 -0
- package/dist/idempotency.d-WpXx9zQo.d.ts +910 -0
- package/dist/{identity-Cw07BKZp.d.ts → identity.d-60LeJt_s.d.cts} +3 -3
- package/dist/{identity-DFVGYn1o.d.cts → identity.d-DzTijonw.d.ts} +3 -3
- package/dist/index.cjs +141 -66
- package/dist/index.d.cts +31 -29
- package/dist/index.d.ts +31 -29
- package/dist/index.js +142 -67
- package/dist/{models-A4A5S7AG.d.cts → models.d-BagXhafD.d.ts} +8 -3
- package/dist/{models-CnXY5LuO.d.ts → models.d-BnLm3VAA.d.cts} +8 -3
- package/dist/notifications/index.cjs +5 -1
- package/dist/notifications/index.d.cts +9 -9
- package/dist/notifications/index.d.ts +9 -9
- package/dist/notifications/index.js +5 -1
- package/dist/optInView.d-CEyHR6PK.d.cts +325 -0
- package/dist/optInView.d-acKpV8V2.d.ts +325 -0
- package/dist/parse.d-C8CXyS58.d.ts +210 -0
- package/dist/parse.d-tEzufgJX.d.cts +210 -0
- package/dist/{pets-BYALZTSu.d.ts → pets.d-C_53_fzo.d.ts} +3 -3
- package/dist/{pets-CcyPQS-H.d.cts → pets.d-NbJvP_kh.d.cts} +3 -3
- package/dist/{petsRepository-B_Q1gFkE.d.cts → petsRepository.d-BuGHymNx.d.ts} +4 -4
- package/dist/{petsRepository-518QkPxH.d.ts → petsRepository.d-lp1BHRqM.d.cts} +4 -4
- package/dist/photo/index.cjs +6 -2
- package/dist/photo/index.d.cts +9 -9
- package/dist/photo/index.d.ts +9 -9
- package/dist/photo/index.js +6 -2
- package/dist/{ports-BN6RHF9W.d.ts → ports.d-BX4f4UsB.d.cts} +14 -1
- package/dist/{ports-BN6RHF9W.d.cts → ports.d-BX4f4UsB.d.ts} +14 -1
- package/dist/{ports-RuNJmBA-.d.cts → ports.d-CEROoqnA.d.cts} +16 -10
- package/dist/{ports-DmQeMArX.d.ts → ports.d-COIyN624.d.ts} +16 -10
- package/dist/presentation.d-DMbdad7G.d.cts +90 -0
- package/dist/presentation.d-DMbdad7G.d.ts +90 -0
- package/dist/records/depth/index.cjs +11 -7
- package/dist/records/depth/index.d.cts +14 -12
- package/dist/records/depth/index.d.ts +14 -12
- package/dist/records/depth/index.js +11 -7
- package/dist/records/index.cjs +225 -62
- package/dist/records/index.d.cts +159 -20
- package/dist/records/index.d.ts +159 -20
- package/dist/records/index.js +225 -62
- package/dist/recordsAsk.d-C5CGSi3j.d.cts +14 -0
- package/dist/recordsAsk.d-C5CGSi3j.d.ts +14 -0
- package/dist/{requestFunnel-B9fdXMi5.d.ts → requestFunnel.d-CXUMPw1K.d.ts} +5 -5
- package/dist/{requestFunnel-BBjNNwc9.d.cts → requestFunnel.d-DWQQpjFR.d.cts} +5 -5
- package/dist/{resolve-D4Ywz5OS.d.ts → resolve.d-jI8FmBj3.d.cts} +3 -3
- package/dist/{resolve-D4Ywz5OS.d.cts → resolve.d-jI8FmBj3.d.ts} +3 -3
- package/dist/{runtimeTypes-CstDBX8w.d.cts → runtimeTypes.d-4yFNNuYR.d.ts} +20 -13
- package/dist/{runtimeTypes-N_K4BVZB.d.ts → runtimeTypes.d-D6N_fhxx.d.cts} +20 -13
- package/dist/server/events/index.cjs +7 -3
- package/dist/server/events/index.d.cts +51 -9
- package/dist/server/events/index.d.ts +51 -9
- package/dist/server/events/index.js +7 -3
- package/dist/server/index.cjs +12 -6
- package/dist/server/index.d.cts +152 -8
- package/dist/server/index.d.ts +152 -8
- package/dist/server/index.js +12 -6
- package/dist/sheetCopy.d-CAhLOxjc.d.cts +4 -0
- package/dist/sheetCopy.d-CAhLOxjc.d.ts +4 -0
- package/dist/sheetSeam.d-Cviqk89n.d.ts +45 -0
- package/dist/sheetSeam.d-DCS3LW8g.d.cts +45 -0
- package/dist/shop/index.cjs +262 -0
- package/dist/shop/index.d.cts +193 -0
- package/dist/shop/index.d.ts +193 -0
- package/dist/shop/index.js +262 -0
- package/dist/televet/booking/index.cjs +16 -12
- package/dist/televet/booking/index.d.cts +36 -22
- package/dist/televet/booking/index.d.ts +36 -22
- package/dist/televet/booking/index.js +16 -12
- package/dist/televet/call/index.d.cts +5 -5
- package/dist/televet/call/index.d.ts +5 -5
- package/dist/televet/index.cjs +7 -3
- package/dist/televet/index.d.cts +12 -12
- package/dist/televet/index.d.ts +12 -12
- package/dist/televet/index.js +7 -3
- package/dist/{televetGlobal-C5dTUACe.d.cts → televetGlobal.d-CC-DrqkQ.d.ts} +7 -2
- package/dist/{televetGlobal-CnjrfhT4.d.ts → televetGlobal.d-CKwDCbmN.d.cts} +7 -2
- package/dist/testing/index.cjs +7 -3
- package/dist/testing/index.d.cts +3 -3
- package/dist/testing/index.d.ts +3 -3
- package/dist/testing/index.js +7 -3
- package/dist/testing/rn/index.cjs +5 -1
- package/dist/testing/rn/index.d.cts +23 -22
- package/dist/testing/rn/index.d.ts +23 -22
- package/dist/testing/rn/index.js +5 -1
- package/dist/testing/web/index.cjs +5 -1
- package/dist/testing/web/index.d.cts +23 -22
- package/dist/testing/web/index.d.ts +23 -22
- package/dist/testing/web/index.js +5 -1
- package/dist/texting/index.cjs +158 -0
- package/dist/texting/index.d.cts +36 -0
- package/dist/texting/index.d.ts +36 -0
- package/dist/texting/index.js +158 -0
- package/dist/threadOptions.d-B1pTMmDF.d.cts +260 -0
- package/dist/threadOptions.d-B1pTMmDF.d.ts +260 -0
- package/dist/{timelineRows-7yjHyh8i.d.ts → timelineRows.d-BNxgzYRW.d.cts} +1 -1
- package/dist/{timelineRows-WvnL-Lds.d.cts → timelineRows.d-CU5GvvLk.d.ts} +1 -1
- package/dist/{tokens-DLj8OnLH.d.cts → tokens.d-DarDaV39.d.cts} +10 -2
- package/dist/{tokens-DLj8OnLH.d.ts → tokens.d-DarDaV39.d.ts} +10 -2
- package/dist/{typeStyle-BxVyF71R.d.ts → typeStyle.d-Bl8pzbBy.d.cts} +2 -2
- package/dist/{typeStyle-DJedEu14.d.cts → typeStyle.d-C1HBRAI3.d.ts} +2 -2
- package/dist/{uploadTransport-BM_pnEWj.d.cts → uploadTransport.d-CWL7CdWP.d.cts} +1 -1
- package/dist/{uploadTransport-C6kGP1Kd.d.ts → uploadTransport.d-EGoUl7gX.d.ts} +1 -1
- package/dist/usePresentation.d-D6qsFzBz.d.cts +9 -0
- package/dist/usePresentation.d-DuGQe_Do.d.ts +9 -0
- package/dist/useRecords.d-Cb-36SF5.d.cts +121 -0
- package/dist/useRecords.d-aQTzQZoV.d.ts +121 -0
- package/dist/{useRecordsDepth-Bp6L4M5P.d.ts → useRecordsDepth.d-DFcCfiXm.d.ts} +8 -20
- package/dist/{useRecordsDepth-DPdAK_81.d.cts → useRecordsDepth.d-sAq2Qkhr.d.cts} +8 -20
- package/dist/{useVetVisit-DmWa7lt1.d.ts → useVetVisit.d-BtdwhmgD.d.cts} +15 -4
- package/dist/{useVetVisit-PtBjNwZr.d.cts → useVetVisit.d-DoYQimyt.d.ts} +15 -4
- package/dist/video/index.cjs +6 -2
- package/dist/video/index.d.cts +7 -7
- package/dist/video/index.d.ts +7 -7
- package/dist/video/index.js +6 -2
- package/dist/{view-C6go2uUt.d.ts → view.d-C-SNpDJX.d.ts} +10 -122
- package/dist/{view-CiF_HVFQ.d.cts → view.d-Dps5C8-s.d.cts} +10 -122
- package/dist/web/consent/index.cjs +5 -1
- package/dist/web/consent/index.d.cts +10 -10
- package/dist/web/consent/index.d.ts +10 -10
- package/dist/web/consent/index.js +5 -1
- package/dist/web/health-plan/index.cjs +414 -0
- package/dist/web/health-plan/index.d.cts +335 -0
- package/dist/web/health-plan/index.d.ts +335 -0
- package/dist/web/health-plan/index.js +414 -0
- package/dist/web/index.cjs +150 -82
- package/dist/web/index.d.cts +152 -38
- package/dist/web/index.d.ts +152 -38
- package/dist/web/index.js +150 -82
- package/dist/web/notifications/index.cjs +16 -3
- package/dist/web/notifications/index.d.cts +39 -209
- package/dist/web/notifications/index.d.ts +39 -209
- package/dist/web/notifications/index.js +16 -3
- package/dist/web/records/depth/index.cjs +11 -7
- package/dist/web/records/depth/index.d.cts +14 -12
- package/dist/web/records/depth/index.d.ts +14 -12
- package/dist/web/records/depth/index.js +11 -7
- package/dist/web/records/index.cjs +95 -68
- package/dist/web/records/index.d.cts +66 -21
- package/dist/web/records/index.d.ts +66 -21
- package/dist/web/records/index.js +95 -68
- package/dist/web/records/upload/index.d.cts +2 -2
- package/dist/web/records/upload/index.d.ts +2 -2
- package/dist/web/records-sheet/index.cjs +278 -0
- package/dist/web/records-sheet/index.d.cts +102 -0
- package/dist/web/records-sheet/index.d.ts +102 -0
- package/dist/web/records-sheet/index.js +278 -0
- package/dist/web/shop/index.cjs +301 -0
- package/dist/web/shop/index.d.cts +42 -0
- package/dist/web/shop/index.d.ts +42 -0
- package/dist/web/shop/index.js +301 -0
- package/dist/web/televet/booking/index.cjs +16 -12
- package/dist/web/televet/booking/index.d.cts +37 -23
- package/dist/web/televet/booking/index.d.ts +37 -23
- package/dist/web/televet/booking/index.js +16 -12
- package/dist/web/televet/call/index.d.cts +4 -4
- package/dist/web/televet/call/index.d.ts +4 -4
- package/dist/web/televet/index.cjs +7 -3
- package/dist/web/televet/index.d.cts +12 -12
- package/dist/web/televet/index.d.ts +12 -12
- package/dist/web/televet/index.js +7 -3
- package/dist/web/texting/index.cjs +157 -0
- package/dist/web/texting/index.d.cts +36 -0
- package/dist/web/texting/index.d.ts +36 -0
- package/dist/web/texting/index.js +157 -0
- package/health-plan/package.json +8 -0
- package/package.json +106 -4
- package/shop/package.json +8 -0
- package/texting/package.json +8 -0
- package/web/health-plan/native-blocked.cjs +12 -0
- package/web/health-plan/package.json +8 -0
- package/web/records-sheet/native-blocked.cjs +12 -0
- package/web/records-sheet/package.json +8 -0
- package/web/shop/native-blocked.cjs +12 -0
- package/web/shop/package.json +8 -0
- package/web/texting/native-blocked.cjs +12 -0
- package/web/texting/package.json +8 -0
- /package/dist/{CameraPort-Cv31Pz7g.d.cts → CameraPort.d-Cv31Pz7g.d.cts} +0 -0
- /package/dist/{CameraPort-Cv31Pz7g.d.ts → CameraPort.d-Cv31Pz7g.d.ts} +0 -0
- /package/dist/{TelemetryPort-BDNr00hu.d.cts → TelemetryPort.d-BDNr00hu.d.cts} +0 -0
- /package/dist/{TelemetryPort-BDNr00hu.d.ts → TelemetryPort.d-BDNr00hu.d.ts} +0 -0
- /package/dist/{cacheEpoch-DknKn3S0.d.cts → cacheEpoch.d-DknKn3S0.d.cts} +0 -0
- /package/dist/{cacheEpoch-DknKn3S0.d.ts → cacheEpoch.d-DknKn3S0.d.ts} +0 -0
- /package/dist/{callCopy-Bw6oZT54.d.cts → callCopy.d-Bw6oZT54.d.cts} +0 -0
- /package/dist/{callCopy-Bw6oZT54.d.ts → callCopy.d-Bw6oZT54.d.ts} +0 -0
- /package/dist/{ids-B2GAAifq.d.cts → ids.d-B2GAAifq.d.cts} +0 -0
- /package/dist/{ids-B2GAAifq.d.ts → ids.d-B2GAAifq.d.ts} +0 -0
- /package/dist/{optionalModule-DbJmsq5f.d.cts → optionalModule.d-DbJmsq5f.d.cts} +0 -0
- /package/dist/{optionalModule-DbJmsq5f.d.ts → optionalModule.d-DbJmsq5f.d.ts} +0 -0
- /package/dist/{profile-CSs1wlXT.d.cts → profile.d-CSs1wlXT.d.cts} +0 -0
- /package/dist/{profile-CSs1wlXT.d.ts → profile.d-CSs1wlXT.d.ts} +0 -0
- /package/dist/{projection-CeIUsbSk.d.cts → projection.d-CeIUsbSk.d.cts} +0 -0
- /package/dist/{projection-CeIUsbSk.d.ts → projection.d-CeIUsbSk.d.ts} +0 -0
- /package/dist/{species-BXAIMh7I.d.cts → species.d-BXAIMh7I.d.cts} +0 -0
- /package/dist/{species-BXAIMh7I.d.ts → species.d-BXAIMh7I.d.ts} +0 -0
- /package/dist/{visitIntent-D7_yVp1I.d.cts → visitIntent.d-D7_yVp1I.d.cts} +0 -0
- /package/dist/{visitIntent-D7_yVp1I.d.ts → visitIntent.d-D7_yVp1I.d.ts} +0 -0
|
@@ -0,0 +1,1178 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { P as PetRef, U as UserRef } from './ids.d-B2GAAifq.cjs';
|
|
3
|
+
import { E as EverfurError } from './EverfurError.d-8NHtlgzA.cjs';
|
|
4
|
+
import { L as LifecyclePort } from './LifecyclePort.d-Cr1p33a7.cjs';
|
|
5
|
+
import { E as EverfurResult } from './EverfurResult.d-BFH-3s6E.cjs';
|
|
6
|
+
import { R as RequestFunnel } from './requestFunnel.d-DWQQpjFR.cjs';
|
|
7
|
+
import { A as AuthContext } from './identity.d-60LeJt_s.cjs';
|
|
8
|
+
import { E as ErrorPolicyPort } from './ErrorPolicyPort.d-DirW9hgO.cjs';
|
|
9
|
+
|
|
10
|
+
/** Where a reason comes from. An unknown kind reads as `profile` (a fact about the pet). */
|
|
11
|
+
declare const HEALTH_PLAN_REASON_KINDS: readonly ["dna", "records", "inside", "profile"];
|
|
12
|
+
type HealthPlanReasonKind = (typeof HEALTH_PLAN_REASON_KINDS)[number];
|
|
13
|
+
interface HealthPlanReason {
|
|
14
|
+
readonly kind: HealthPlanReasonKind;
|
|
15
|
+
/** The partner's catalog text or an Everfur fact, verbatim. */
|
|
16
|
+
readonly text: string;
|
|
17
|
+
}
|
|
18
|
+
/** One product in a pet's plan. */
|
|
19
|
+
interface HealthPlanItem {
|
|
20
|
+
readonly productId: string;
|
|
21
|
+
/** The partner's own SKU: what `onCheckout` hands back so the partner's cart can find it. */
|
|
22
|
+
readonly partnerSku: string | null;
|
|
23
|
+
readonly title: string;
|
|
24
|
+
readonly description: string | null;
|
|
25
|
+
/** The partner's catalog category (`Supplement`), up to 60 characters, or null. */
|
|
26
|
+
readonly category: string | null;
|
|
27
|
+
/** The price as a number in `currency` units, or null when the catalog carries none. */
|
|
28
|
+
readonly price: number | null;
|
|
29
|
+
/** ISO 4217 (`USD`), or null. */
|
|
30
|
+
readonly currency: string | null;
|
|
31
|
+
/** https only; anything else is dropped. */
|
|
32
|
+
readonly imageUrl: string | null;
|
|
33
|
+
/** The partner's product page, https only, or null. */
|
|
34
|
+
readonly url: string | null;
|
|
35
|
+
readonly reasons: readonly HealthPlanReason[];
|
|
36
|
+
/** Whether the member has this item in the plan. */
|
|
37
|
+
readonly inPlan: boolean;
|
|
38
|
+
/** A demo product, labelled as a sample wherever it is drawn. */
|
|
39
|
+
readonly sample: boolean;
|
|
40
|
+
}
|
|
41
|
+
interface HealthPlan {
|
|
42
|
+
readonly petRef: PetRef;
|
|
43
|
+
/** The plan title the tenant's template rendered for this pet, or null. */
|
|
44
|
+
readonly headline: string | null;
|
|
45
|
+
readonly items: readonly HealthPlanItem[];
|
|
46
|
+
/** ISO 8601, or null. */
|
|
47
|
+
readonly updatedAt: string | null;
|
|
48
|
+
/**
|
|
49
|
+
* Wire `tracking_texts_enabled`: Everfur texts the owner when the partner sets tracking. Absent on the wire reads as
|
|
50
|
+
* false. Optional here so a host's own plan objects keep compiling.
|
|
51
|
+
*/
|
|
52
|
+
readonly trackingTextsEnabled?: boolean;
|
|
53
|
+
}
|
|
54
|
+
interface HealthPlanRepository {
|
|
55
|
+
/** `GET /widget/v1/pets/{pet_ref}/plan`. Settles; never throws. */
|
|
56
|
+
read(petRef: PetRef, opts?: {
|
|
57
|
+
readonly signal?: AbortSignal;
|
|
58
|
+
}): Promise<EverfurResult<HealthPlan>>;
|
|
59
|
+
/** `PUT .../plan/items/{product_id}`. Settles the plan the server returned, or null for an empty answer. */
|
|
60
|
+
addItem(petRef: PetRef, productId: string): Promise<EverfurResult<HealthPlan | null>>;
|
|
61
|
+
/** `DELETE .../plan/items/{product_id}`. Settles the plan the server returned, or null for an empty answer. */
|
|
62
|
+
removeItem(petRef: PetRef, productId: string): Promise<EverfurResult<HealthPlan | null>>;
|
|
63
|
+
}
|
|
64
|
+
/** The part of the runtime this repository needs (`useEverfurContext().runtime` satisfies it). */
|
|
65
|
+
interface HealthPlanRuntime {
|
|
66
|
+
readonly isDisposed: boolean;
|
|
67
|
+
readonly registry: {
|
|
68
|
+
readonly services: {
|
|
69
|
+
authFor(userRef: UserRef | null): AuthContext;
|
|
70
|
+
readonly errorPolicy: ErrorPolicyPort | undefined;
|
|
71
|
+
};
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
interface HealthPlanRepositoryDeps {
|
|
75
|
+
readonly auth: AuthContext;
|
|
76
|
+
readonly errorPolicy?: ErrorPolicyPort;
|
|
77
|
+
readonly funnel?: RequestFunnel;
|
|
78
|
+
}
|
|
79
|
+
/** The allowlist mapper for one plan body. `items` must be a list; a row that is not an item is dropped. */
|
|
80
|
+
declare function healthPlanFromWire(raw: unknown, petRef: PetRef): HealthPlan | null;
|
|
81
|
+
/** The repository over the runtime under your provider. Auth is read at CALL time; a disposed runtime sends nothing. */
|
|
82
|
+
declare function createHealthPlanRepository(runtime: HealthPlanRuntime): HealthPlanRepository;
|
|
83
|
+
/** The same repository over one auth context (or an injected funnel). Internal seam, for deterministic tests. */
|
|
84
|
+
declare function createHealthPlanRepositoryOver(deps: HealthPlanRepositoryDeps): HealthPlanRepository;
|
|
85
|
+
|
|
86
|
+
type EverfurHealthPlanStatus = 'signedOut' | 'noPet' | 'loading' | 'failed' | 'empty' | 'ready';
|
|
87
|
+
/** The member's cart: the items in the plan, and their total when one can honestly be given. */
|
|
88
|
+
interface HealthPlanCart {
|
|
89
|
+
readonly items: readonly HealthPlanItem[];
|
|
90
|
+
readonly count: number;
|
|
91
|
+
/**
|
|
92
|
+
* The sum of the priced items, or null when any item has no price or the items do not share one currency
|
|
93
|
+
* (a total across currencies is a number nobody can pay).
|
|
94
|
+
*/
|
|
95
|
+
readonly subtotal: number | null;
|
|
96
|
+
/** The shared currency of `subtotal`, or null. */
|
|
97
|
+
readonly currency: string | null;
|
|
98
|
+
}
|
|
99
|
+
interface EverfurHealthPlanOptions {
|
|
100
|
+
/** The pet whose plan to show. Omit it and the provider's active pet is used. */
|
|
101
|
+
readonly petRef?: PetRef | null;
|
|
102
|
+
/**
|
|
103
|
+
* The host's lifecycle signals: coming back to the foreground re-reads a plan shown for more than a minute, quietly
|
|
104
|
+
* (the plan stays on screen). Absent, only `refreshKey` and `refresh()` re-read.
|
|
105
|
+
*/
|
|
106
|
+
readonly lifecycle?: LifecyclePort | null;
|
|
107
|
+
/** Change it to re-read the plan now, quietly (for example after your checkout completed). */
|
|
108
|
+
readonly refreshKey?: string | number;
|
|
109
|
+
}
|
|
110
|
+
interface EverfurHealthPlanState {
|
|
111
|
+
readonly status: EverfurHealthPlanStatus;
|
|
112
|
+
readonly petRef: PetRef | null;
|
|
113
|
+
readonly plan: HealthPlan | null;
|
|
114
|
+
readonly cart: HealthPlanCart;
|
|
115
|
+
/** Product ids whose add or remove is in flight. */
|
|
116
|
+
readonly pending: readonly string[];
|
|
117
|
+
/** The last refused write per product id. */
|
|
118
|
+
readonly itemErrors: Readonly<Record<string, EverfurError>>;
|
|
119
|
+
/** The refused read, or null. */
|
|
120
|
+
readonly error: EverfurError | null;
|
|
121
|
+
/** Put an item in the plan (`true`) or take it out (`false`). Optimistic; rolls back on a refusal. */
|
|
122
|
+
setInPlan(productId: string, inPlan: boolean): Promise<boolean>;
|
|
123
|
+
refresh(): Promise<void>;
|
|
124
|
+
}
|
|
125
|
+
/** The cart a plan makes. Pure, so a partner's own cart UI reads the same totals. */
|
|
126
|
+
declare function healthPlanCart(plan: HealthPlan | null): HealthPlanCart;
|
|
127
|
+
/**
|
|
128
|
+
* A price as the member reads it: the platform's own currency format (`$19.99`), or `USD 19.99` where the runtime
|
|
129
|
+
* has no formatter for that currency. Null for an item with no price; the surface shows none rather than `$0`.
|
|
130
|
+
* `locale` picks the number format (omit it for the platform default). With `format.dropZeroCents` a whole amount
|
|
131
|
+
* reads without minor units (`$39`); a non-whole one keeps them (`$29.99`).
|
|
132
|
+
*/
|
|
133
|
+
declare function formatHealthPlanPrice(amount: number | null, currency: string | null, locale?: string, format?: Pick<HealthPlanPriceFormat, 'dropZeroCents'>): string | null;
|
|
134
|
+
/** `formatHealthPlanPrice` with a page's `priceFormat` option. */
|
|
135
|
+
declare function formatHealthPlanPriceWith(amount: number | null, currency: string | null, format?: HealthPlanPriceFormat): string | null;
|
|
136
|
+
/** The Health Plan repository bound to the runtime under your provider, for a partner's own UI. */
|
|
137
|
+
declare function useEverfurHealthPlanRepository(): HealthPlanRepository;
|
|
138
|
+
/** One pet's Health Plan and the member's cart. `EverfurHealthPlan` renders it on either host. */
|
|
139
|
+
declare function useEverfurHealthPlan(options?: EverfurHealthPlanOptions): EverfurHealthPlanState;
|
|
140
|
+
|
|
141
|
+
/** Where a product's picture sits on its card. */
|
|
142
|
+
type HealthPlanImageVariant = 'wide' | 'thumbnail';
|
|
143
|
+
/** How a product's reasons are drawn. */
|
|
144
|
+
type HealthPlanReasonVariant = 'pills' | 'rows';
|
|
145
|
+
/** When the page draws the cart bar. */
|
|
146
|
+
type HealthPlanCartBarVisibility = 'whenItems' | 'always';
|
|
147
|
+
/** Where the cart bar lives: stuck to the foot of the page, or nowhere on the page (the host docks its own). */
|
|
148
|
+
type HealthPlanCartBarPlacement = 'sticky' | 'none';
|
|
149
|
+
/** The size of a product card's add control: a named size, or the pill's height in px. */
|
|
150
|
+
type HealthPlanAddButtonSize = 'full' | 'compact' | number;
|
|
151
|
+
/** How a product in the cart shows: "Added" with a Remove link, or the add pill held pressed. */
|
|
152
|
+
type HealthPlanAddedVariant = 'link' | 'pressed';
|
|
153
|
+
/** How a product's category reads: body text, or the reason-row label face (mono, uppercase). */
|
|
154
|
+
type HealthPlanCategoryVariant = 'text' | 'label';
|
|
155
|
+
/** A shadow of the partner's own, painted the same way on both hosts. Lengths are px. */
|
|
156
|
+
interface HealthPlanShadow {
|
|
157
|
+
/** Any colour the theme parser reads (`#RRGGBB`, `rgba(...)`). */
|
|
158
|
+
readonly color: string;
|
|
159
|
+
readonly offsetX?: number;
|
|
160
|
+
readonly offsetY: number;
|
|
161
|
+
readonly blur: number;
|
|
162
|
+
/** 0..1, multiplied into the colour's own alpha. Default 1. */
|
|
163
|
+
readonly opacity?: number;
|
|
164
|
+
}
|
|
165
|
+
/** A card shadow: `true` for the SDK's soft one, a CSS shadow string, or a `HealthPlanShadow`. */
|
|
166
|
+
type HealthPlanCardShadow = boolean | string | HealthPlanShadow;
|
|
167
|
+
/** A font weight a card text accepts. */
|
|
168
|
+
type HealthPlanFontWeight = 400 | 500 | 600 | 700 | 800 | 900;
|
|
169
|
+
/** How a price reads. Prices always go through `Intl.NumberFormat` with the item's own currency. */
|
|
170
|
+
interface HealthPlanPriceFormat {
|
|
171
|
+
/** A BCP 47 locale for the number format. Omit it and the platform's default locale is used. */
|
|
172
|
+
readonly locale?: string;
|
|
173
|
+
/** True to drop zero minor units on a whole amount (`$39` instead of `$39.00`). A non-whole amount keeps them. */
|
|
174
|
+
readonly dropZeroCents?: boolean;
|
|
175
|
+
}
|
|
176
|
+
declare const HEALTH_PLAN_LAYOUT_DEFAULTS: Readonly<{
|
|
177
|
+
imageVariant: HealthPlanImageVariant;
|
|
178
|
+
reasonVariant: HealthPlanReasonVariant;
|
|
179
|
+
cartBarVisibility: HealthPlanCartBarVisibility;
|
|
180
|
+
cartBarPlacement: HealthPlanCartBarPlacement;
|
|
181
|
+
addButtonSize: HealthPlanAddButtonSize;
|
|
182
|
+
addedVariant: HealthPlanAddedVariant;
|
|
183
|
+
categoryVariant: HealthPlanCategoryVariant;
|
|
184
|
+
showCategory: false;
|
|
185
|
+
cardShadow: false;
|
|
186
|
+
cardBorder: true;
|
|
187
|
+
}>;
|
|
188
|
+
/** True when the page should draw the cart bar for a cart of `count` items. */
|
|
189
|
+
declare function showHealthPlanCartBar(visibility: HealthPlanCartBarVisibility | undefined, count: number): boolean;
|
|
190
|
+
/**
|
|
191
|
+
* What a partner's header and footer nodes are handed: the pet, its plan and the member's cart, as the page draws
|
|
192
|
+
* them. `cart.items` are the products in the plan, `cart.count` how many, `cart.subtotal` their sum (null when the
|
|
193
|
+
* currencies differ or a price is missing).
|
|
194
|
+
*/
|
|
195
|
+
interface HealthPlanHeaderContext {
|
|
196
|
+
readonly petRef: PetRef | null;
|
|
197
|
+
readonly plan: HealthPlan | null;
|
|
198
|
+
readonly cart: HealthPlanCart;
|
|
199
|
+
/**
|
|
200
|
+
* Put a product in the plan (`true`) or take it out (`false`), through the same optimistic write the cards use:
|
|
201
|
+
* the card flips at once and a refusal puts it back. Resolves true when the server accepted it.
|
|
202
|
+
*/
|
|
203
|
+
readonly setInPlan: (productId: string, inPlan: boolean) => Promise<boolean>;
|
|
204
|
+
/** Put every product not yet in the plan into it. Resolves true when every write was accepted. */
|
|
205
|
+
readonly addAll: () => Promise<boolean>;
|
|
206
|
+
}
|
|
207
|
+
/** The same context, named for the page footer. */
|
|
208
|
+
type HealthPlanPageContext = HealthPlanHeaderContext;
|
|
209
|
+
/** The card options `HealthPlanItemCard` takes, on both hosts. */
|
|
210
|
+
interface HealthPlanCardOptions {
|
|
211
|
+
/** True to draw the product's category above its name. Default false. */
|
|
212
|
+
readonly showCategory?: boolean;
|
|
213
|
+
/**
|
|
214
|
+
* A shadow under the card: `true` for the SDK's soft one (the theme's shadow colour at 8%), a CSS shadow string
|
|
215
|
+
* (`0 1px 3px rgba(38,37,35,.06)`; React Native reads the first shadow's offset, blur and colour), or a
|
|
216
|
+
* `HealthPlanShadow`. Default none.
|
|
217
|
+
*/
|
|
218
|
+
readonly cardShadow?: HealthPlanCardShadow;
|
|
219
|
+
/** False to drop the card's hairline edge. Default true. */
|
|
220
|
+
readonly cardBorder?: boolean;
|
|
221
|
+
/** `'full'` (default, 44 high), `'compact'` (32 high), or the pill's height in px. The tap area stays 44. */
|
|
222
|
+
readonly addButtonSize?: HealthPlanAddButtonSize;
|
|
223
|
+
/** The add control's font size in px. Default: body for a pill 40 or taller, else caption. */
|
|
224
|
+
readonly addButtonFontSize?: number;
|
|
225
|
+
/** `'link'` (default): "Added" and a Remove link. `'pressed'`: the pill stays, pressed; a tap removes it. */
|
|
226
|
+
readonly addedVariant?: HealthPlanAddedVariant;
|
|
227
|
+
/** `'text'` (default) or `'label'` (the reason-row label face). Only read with `showCategory`. */
|
|
228
|
+
readonly categoryVariant?: HealthPlanCategoryVariant;
|
|
229
|
+
/** The card's inner padding in px. Default the theme's `space.lg`. */
|
|
230
|
+
readonly cardPadding?: number;
|
|
231
|
+
/** The product name's size (px) and weight. Default body size, bold. */
|
|
232
|
+
readonly itemTitleSize?: number;
|
|
233
|
+
readonly itemTitleWeight?: HealthPlanFontWeight;
|
|
234
|
+
/** The price's size (px) and weight. Default body size, bold. */
|
|
235
|
+
readonly priceSize?: number;
|
|
236
|
+
readonly priceWeight?: HealthPlanFontWeight;
|
|
237
|
+
/** The reason text's size (px). Default caption size. */
|
|
238
|
+
readonly reasonTextSize?: number;
|
|
239
|
+
/** The label column of `'rows'` reasons in px. Default sized to the longest label (web) or 72 (React Native). */
|
|
240
|
+
readonly reasonLabelWidth?: number;
|
|
241
|
+
/** The space between a reason row's label and its text in px. Default the theme's `space.lg`. */
|
|
242
|
+
readonly reasonGap?: number;
|
|
243
|
+
}
|
|
244
|
+
/** The layout props `EverfurHealthPlan` takes on both hosts. Paint stays the theme's. */
|
|
245
|
+
interface HealthPlanLayoutProps extends HealthPlanCardOptions {
|
|
246
|
+
/** Where each product's picture sits. Default `'wide'`. */
|
|
247
|
+
readonly imageVariant?: HealthPlanImageVariant;
|
|
248
|
+
/** How each product's reasons are drawn. Default `'pills'`. */
|
|
249
|
+
readonly reasonVariant?: HealthPlanReasonVariant;
|
|
250
|
+
/** When the cart bar is drawn. Default `'whenItems'`. */
|
|
251
|
+
readonly cartBarVisibility?: HealthPlanCartBarVisibility;
|
|
252
|
+
/** How prices and the subtotal read. */
|
|
253
|
+
readonly priceFormat?: HealthPlanPriceFormat;
|
|
254
|
+
/**
|
|
255
|
+
* Your own node between the plan title and the products (a summary or risk card of yours). Drawn on the plan and
|
|
256
|
+
* on the empty plan. A throw while rendering it draws nothing in its place.
|
|
257
|
+
*/
|
|
258
|
+
readonly renderHeader?: (context: HealthPlanHeaderContext) => ReactNode;
|
|
259
|
+
/** Your own node at the foot of each product card, above its control. A throw draws nothing in its place. */
|
|
260
|
+
readonly renderItemFooter?: (item: HealthPlanItem) => ReactNode;
|
|
261
|
+
/**
|
|
262
|
+
* Your own node after the products, before the cart bar (totals, an upsell row, fine print). Drawn on the plan only.
|
|
263
|
+
* A throw draws nothing in its place.
|
|
264
|
+
*/
|
|
265
|
+
readonly renderFooter?: (context: HealthPlanPageContext) => ReactNode;
|
|
266
|
+
/** The plan title's font size in px. Default the theme's heading size. */
|
|
267
|
+
readonly titleSize?: number;
|
|
268
|
+
/** The space under the plan title in px. Default the section gap. */
|
|
269
|
+
readonly titleGap?: number;
|
|
270
|
+
/** The space between the page's blocks in px. Default the theme's `space.lg`. */
|
|
271
|
+
readonly sectionGap?: number;
|
|
272
|
+
/** Where the cart bar lives. Default `'sticky'`. With `'none'`, wrap the page and your bar in `HealthPlanCartScope`. */
|
|
273
|
+
readonly cartBarPlacement?: HealthPlanCartBarPlacement;
|
|
274
|
+
/** The plan title's line height as a ratio of its size (1.15 reads tight). Default the theme's snug ratio. */
|
|
275
|
+
readonly titleLineHeight?: number;
|
|
276
|
+
/**
|
|
277
|
+
* Your own node between two products (a group label such as a list heading), drawn before the product at `index`
|
|
278
|
+
* (1 and up; never before the first). Return null for no node. A throw draws nothing in its place.
|
|
279
|
+
*/
|
|
280
|
+
readonly renderBetweenItems?: (index: number, item: HealthPlanItem) => ReactNode;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* True for a refusal because the session is not a SIGNED member session: the plan routes answer a publishable-key or
|
|
284
|
+
* unsigned caller 403 `session_required` (EFBackend partner_shop_widget_router.py). A retry cannot help, so the
|
|
285
|
+
* surface shows the sign-in line and no retry.
|
|
286
|
+
*/
|
|
287
|
+
declare function isHealthPlanSessionRequired(error: EverfurError | null): boolean;
|
|
288
|
+
|
|
289
|
+
/** The icons the layout draws. `renderIcon` lets the host draw its own; the SDK has a plain default for each. */
|
|
290
|
+
type HealthPlanFocusIcon = 'shield' | 'arrow' | 'check' | 'star' | 'truck' | 'refresh' | 'card' | 'alert' | 'x' | 'chat' | 'repeat' | 'calendar' | 'flame' | 'box' | 'cart' | 'minus' | 'plus' | 'chev' | 'pulse' | 'file' | 'kit' | 'dna' | 'heart' | 'bottle' | 'harness' | 'ramp';
|
|
291
|
+
/** One free tip of the routine. Tips are numbered in order and never checked off. */
|
|
292
|
+
interface HealthPlanFocusStep {
|
|
293
|
+
readonly title: string;
|
|
294
|
+
readonly body?: string;
|
|
295
|
+
/** Where the tip comes from ("From her vet records"). */
|
|
296
|
+
readonly source?: string;
|
|
297
|
+
/** The card's tint, a `tip:<tone>` class for a host that styles parts (Raph v3 draws the tips as tinted cards). */
|
|
298
|
+
readonly tone?: 'y' | 'c' | 'g' | 'r';
|
|
299
|
+
/** The icon beside the tip's number. */
|
|
300
|
+
readonly icon?: HealthPlanFocusIcon;
|
|
301
|
+
}
|
|
302
|
+
/** One review of the product, word for word from the partner's store. */
|
|
303
|
+
interface HealthPlanFocusReview {
|
|
304
|
+
/** Whole stars, 1..5. */
|
|
305
|
+
readonly stars: number;
|
|
306
|
+
readonly text: string;
|
|
307
|
+
/** Who wrote it ("Robin"). */
|
|
308
|
+
readonly by: string;
|
|
309
|
+
}
|
|
310
|
+
/** Another offer of the partner's, after the plan ("Another dog at home?"). The words and prices are the host's. */
|
|
311
|
+
interface HealthPlanFocusExtra {
|
|
312
|
+
/** Your id for it, handed back to `onExtra`. */
|
|
313
|
+
readonly key: string;
|
|
314
|
+
readonly title: string;
|
|
315
|
+
readonly body?: string;
|
|
316
|
+
/** The price as you show it ("$75") and, struck, the usual price ("$139"). */
|
|
317
|
+
readonly price?: string;
|
|
318
|
+
readonly was?: string;
|
|
319
|
+
/** A small tag beside the price ("Illustrative"). */
|
|
320
|
+
readonly tag?: string;
|
|
321
|
+
/** https or a same-origin path; drawn in place of `icon`. */
|
|
322
|
+
readonly imageUrl?: string;
|
|
323
|
+
readonly icon?: HealthPlanFocusIcon;
|
|
324
|
+
/** A modifier kind for the row (`extra:<kind>`) and for its title (`extraTitle:<kind>`). */
|
|
325
|
+
readonly kind?: string;
|
|
326
|
+
/** The button's words before ("Add a kit") and after ("Added to cart") it is pressed. */
|
|
327
|
+
readonly action: string;
|
|
328
|
+
readonly added: string;
|
|
329
|
+
/**
|
|
330
|
+
* The Everfur product this offer is, when it is one of the pet's plan items. With the shop on (`shop: true`), its
|
|
331
|
+
* button puts that item in the cart (and reads "View cart" once it is in). Without one, the button is `onExtra`'s.
|
|
332
|
+
*/
|
|
333
|
+
readonly productId?: string;
|
|
334
|
+
}
|
|
335
|
+
/** One step of a tracker (an order's, a test kit's). The words and dates are the host's or the server's. */
|
|
336
|
+
interface HealthPlanTrackStep {
|
|
337
|
+
readonly title: string;
|
|
338
|
+
/** The line under it: a date, or "Expected Dec 8". */
|
|
339
|
+
readonly detail?: string;
|
|
340
|
+
/** `done` draws the check, `now` the current step; anything else is still ahead. */
|
|
341
|
+
readonly state?: 'done' | 'now' | 'next';
|
|
342
|
+
/** A tag after the line (a demo marks a made-up date "Illustrative"). */
|
|
343
|
+
readonly tag?: string;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* What the page says while the pet's plan cannot be made yet (the partner's test results are not back yet). With it, the page
|
|
347
|
+
* draws its title, this card and the partner's other offers only: no focus, routine, pick or signs. The words and the
|
|
348
|
+
* kit's tracker are the partner's (Everfur does not know where a kit is).
|
|
349
|
+
*/
|
|
350
|
+
interface HealthPlanFocusWait {
|
|
351
|
+
readonly kicker: string;
|
|
352
|
+
readonly title: string;
|
|
353
|
+
readonly icon?: HealthPlanFocusIcon;
|
|
354
|
+
readonly track?: readonly HealthPlanTrackStep[];
|
|
355
|
+
/** The heading over the rows ("What her plan will hold"). */
|
|
356
|
+
readonly heading?: string;
|
|
357
|
+
readonly rows?: readonly {
|
|
358
|
+
readonly icon: HealthPlanFocusIcon;
|
|
359
|
+
readonly label: string;
|
|
360
|
+
readonly text: string;
|
|
361
|
+
}[];
|
|
362
|
+
/** The line with the chat icon under the rows ("We'll text you when it's ready."). */
|
|
363
|
+
readonly note?: string;
|
|
364
|
+
/** The button under it; drawn only with `onWaitAction`. */
|
|
365
|
+
readonly action?: string;
|
|
366
|
+
}
|
|
367
|
+
interface HealthPlanFocusReasonRow {
|
|
368
|
+
/** The chip word ("Record", "Ask"). */
|
|
369
|
+
readonly chip: string;
|
|
370
|
+
/** A modifier kind for the chip class (`chip:<kind>`). */
|
|
371
|
+
readonly kind?: string;
|
|
372
|
+
readonly title: string;
|
|
373
|
+
readonly body?: string;
|
|
374
|
+
}
|
|
375
|
+
interface HealthPlanFocusSign {
|
|
376
|
+
readonly title: string;
|
|
377
|
+
readonly body: string;
|
|
378
|
+
/** An emergency sign: drawn with the alert icon and the `sign:urgent` modifier. */
|
|
379
|
+
readonly urgent?: boolean;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Everything the focus layout says about the pet. Every string is the host's (or the backend page's), drawn verbatim.
|
|
383
|
+
* `focus`, `routine` and `signs` are optional: a section that is absent is not drawn.
|
|
384
|
+
*/
|
|
385
|
+
interface HealthPlanFocusDesign {
|
|
386
|
+
readonly eyebrow?: string;
|
|
387
|
+
readonly title: string;
|
|
388
|
+
readonly subtitle?: string;
|
|
389
|
+
/** https or a same-origin path; the pet's photo beside the title. */
|
|
390
|
+
readonly headImageUrl?: string;
|
|
391
|
+
readonly byline?: {
|
|
392
|
+
readonly name: string;
|
|
393
|
+
readonly role?: string;
|
|
394
|
+
readonly imageUrl?: string;
|
|
395
|
+
};
|
|
396
|
+
readonly focus?: {
|
|
397
|
+
readonly kicker: string;
|
|
398
|
+
readonly sources?: readonly {
|
|
399
|
+
readonly label: string;
|
|
400
|
+
readonly kind?: string;
|
|
401
|
+
}[];
|
|
402
|
+
readonly title: string;
|
|
403
|
+
/** The risk line: a bold lead and the rest of the sentence. `kind` picks the dot modifier. */
|
|
404
|
+
readonly risk?: {
|
|
405
|
+
readonly lead: string;
|
|
406
|
+
readonly body?: string;
|
|
407
|
+
readonly kind?: string;
|
|
408
|
+
};
|
|
409
|
+
readonly odds?: {
|
|
410
|
+
readonly label: string;
|
|
411
|
+
readonly tag?: string;
|
|
412
|
+
readonly from: string;
|
|
413
|
+
readonly to: string;
|
|
414
|
+
readonly toLabel?: string;
|
|
415
|
+
};
|
|
416
|
+
/** The vet's line. With `imageUrl`, a host that styles parts gets the one-row form: photo, then the kicker in bold before the text. */
|
|
417
|
+
readonly quote?: {
|
|
418
|
+
readonly kicker: string;
|
|
419
|
+
readonly tag?: string;
|
|
420
|
+
readonly text: string;
|
|
421
|
+
readonly imageUrl?: string;
|
|
422
|
+
};
|
|
423
|
+
/** The strip that jumps to the product. Its kicker is `copy.jumpKicker`. */
|
|
424
|
+
readonly jump?: {
|
|
425
|
+
readonly title: string;
|
|
426
|
+
readonly go: string;
|
|
427
|
+
};
|
|
428
|
+
};
|
|
429
|
+
readonly routine?: {
|
|
430
|
+
readonly title: string;
|
|
431
|
+
/** The line beside the title ("5 free tips"). */
|
|
432
|
+
readonly label?: string;
|
|
433
|
+
readonly steps: readonly HealthPlanFocusStep[];
|
|
434
|
+
};
|
|
435
|
+
readonly pick: {
|
|
436
|
+
readonly title: string;
|
|
437
|
+
/**
|
|
438
|
+
* The plan item to recommend: the item with this Everfur product id, else the item with `partnerSku` (your own
|
|
439
|
+
* catalog id, the same in every environment). Neither found or given: the plan's first item.
|
|
440
|
+
*/
|
|
441
|
+
readonly productId?: string;
|
|
442
|
+
readonly partnerSku?: string;
|
|
443
|
+
/** The rating as the partner shows it ("4.4") and its label ("· 92 reviews"). */
|
|
444
|
+
readonly rating?: {
|
|
445
|
+
readonly value: string;
|
|
446
|
+
readonly label?: string;
|
|
447
|
+
};
|
|
448
|
+
/** One line under the product name. Defaults to the catalog description. */
|
|
449
|
+
readonly line?: string;
|
|
450
|
+
/** Real reviews under the stars, word for word from your store. `label` names where they come from. */
|
|
451
|
+
readonly reviews?: {
|
|
452
|
+
readonly label: string;
|
|
453
|
+
readonly items: readonly HealthPlanFocusReview[];
|
|
454
|
+
};
|
|
455
|
+
/** The line under the product in the checkout and manage sheets ("For her back · 1 chew a day"). Defaults to `line`. */
|
|
456
|
+
readonly checkoutLine?: string;
|
|
457
|
+
/** Why it fits, one row per real signal; `score` is the count line under them ("3 of 3 signals fit Georgia", "3/3"). */
|
|
458
|
+
readonly why?: {
|
|
459
|
+
readonly title: string;
|
|
460
|
+
readonly rows: readonly HealthPlanFocusReasonRow[];
|
|
461
|
+
readonly score?: {
|
|
462
|
+
readonly text: string;
|
|
463
|
+
readonly value: string;
|
|
464
|
+
};
|
|
465
|
+
};
|
|
466
|
+
readonly dose?: {
|
|
467
|
+
readonly title: string;
|
|
468
|
+
readonly stats: readonly {
|
|
469
|
+
readonly value: string;
|
|
470
|
+
readonly label: string;
|
|
471
|
+
}[];
|
|
472
|
+
readonly note?: string;
|
|
473
|
+
};
|
|
474
|
+
readonly ingredients?: {
|
|
475
|
+
readonly label?: string;
|
|
476
|
+
readonly items: readonly string[];
|
|
477
|
+
};
|
|
478
|
+
/** A line under the buy button with the flame icon, on a true number of the partner's ("Built on <a count your data backs>"). Hidden once subscribed. */
|
|
479
|
+
readonly proof?: string;
|
|
480
|
+
readonly trust?: readonly {
|
|
481
|
+
readonly icon: HealthPlanFocusIcon;
|
|
482
|
+
readonly label: string;
|
|
483
|
+
}[];
|
|
484
|
+
/** The "Why this product?" link. Drawn only with `onMore`. */
|
|
485
|
+
readonly more?: string;
|
|
486
|
+
readonly fine?: string;
|
|
487
|
+
/** The check-in question the started screen names ("how's she moving?"). */
|
|
488
|
+
readonly checkin?: string;
|
|
489
|
+
};
|
|
490
|
+
readonly signs?: {
|
|
491
|
+
readonly title: string;
|
|
492
|
+
readonly items: readonly HealthPlanFocusSign[];
|
|
493
|
+
};
|
|
494
|
+
/** What to ask at the checkup. With `signs` it sits in the signs section under its own kicker; alone, it is a section. */
|
|
495
|
+
readonly checkup?: {
|
|
496
|
+
readonly title: string;
|
|
497
|
+
readonly questions: readonly string[];
|
|
498
|
+
readonly add: string;
|
|
499
|
+
readonly added: string;
|
|
500
|
+
};
|
|
501
|
+
/** The partner's other offers, last ("More from <your brand>"). Drawn only with `onExtra`. */
|
|
502
|
+
readonly extras?: {
|
|
503
|
+
readonly title: string;
|
|
504
|
+
readonly items: readonly HealthPlanFocusExtra[];
|
|
505
|
+
};
|
|
506
|
+
readonly fine?: string;
|
|
507
|
+
/** Checkout rows ("Ships to" / "Home, on file with <your brand>"). The partner knows these; Everfur does not. */
|
|
508
|
+
readonly checkoutRows?: readonly {
|
|
509
|
+
readonly icon: HealthPlanFocusIcon;
|
|
510
|
+
readonly label: string;
|
|
511
|
+
readonly value: string;
|
|
512
|
+
}[];
|
|
513
|
+
/** The plan cannot be made yet: draw this card in place of the plan (see `HealthPlanFocusWait`). */
|
|
514
|
+
readonly wait?: HealthPlanFocusWait;
|
|
515
|
+
readonly copy?: Partial<HealthPlanFocusCopy>;
|
|
516
|
+
}
|
|
517
|
+
/** Facts the copy functions receive, all formatted from the server's answers. */
|
|
518
|
+
interface HealthPlanFocusPrices {
|
|
519
|
+
readonly petName: string | null;
|
|
520
|
+
readonly productName: string;
|
|
521
|
+
/** The first box as the member reads it (`$23.99`), or the box price when no offer applies. */
|
|
522
|
+
readonly first: string | null;
|
|
523
|
+
/** The regular box price (`$29.99`). */
|
|
524
|
+
readonly box: string | null;
|
|
525
|
+
/** One box, no renewal (`$28.49`), or the box price when there is no one-box discount. */
|
|
526
|
+
readonly once: string | null;
|
|
527
|
+
/** The one-box discount, 0 when none. */
|
|
528
|
+
readonly onceDiscountPercent: number;
|
|
529
|
+
readonly intervalDays: number;
|
|
530
|
+
readonly discountPercent: number;
|
|
531
|
+
readonly offer: boolean;
|
|
532
|
+
}
|
|
533
|
+
/** The words the SDK says about buying. Defaults: Raph's v3 design, 2026-10-16. */
|
|
534
|
+
interface HealthPlanFocusCopy {
|
|
535
|
+
readonly jumpKicker: (p: HealthPlanFocusPrices, subscribed: boolean) => string;
|
|
536
|
+
readonly optionsLabel: string;
|
|
537
|
+
readonly subscribe: string;
|
|
538
|
+
readonly bestValue: string;
|
|
539
|
+
readonly subscribeLine: (p: HealthPlanFocusPrices) => string;
|
|
540
|
+
readonly priceLine: (p: HealthPlanFocusPrices) => string;
|
|
541
|
+
readonly once: string;
|
|
542
|
+
readonly onceLine: (p: HealthPlanFocusPrices) => string;
|
|
543
|
+
readonly buyOnce: (p: HealthPlanFocusPrices) => string;
|
|
544
|
+
readonly subscribed: string;
|
|
545
|
+
readonly subscribedLine: (p: HealthPlanFocusPrices, nextBox: string | null) => string;
|
|
546
|
+
readonly manage: string;
|
|
547
|
+
readonly checkoutKicker: string;
|
|
548
|
+
readonly checkoutTitle: (p: HealthPlanFocusPrices) => string;
|
|
549
|
+
readonly checkoutOffer: (p: HealthPlanFocusPrices) => string;
|
|
550
|
+
readonly shipsEvery: string;
|
|
551
|
+
readonly days: (n: number) => string;
|
|
552
|
+
readonly buyOnceOption: string;
|
|
553
|
+
readonly checkoutGo: (p: HealthPlanFocusPrices, subscribe: boolean, today: string) => string;
|
|
554
|
+
readonly renews: (p: HealthPlanFocusPrices) => string;
|
|
555
|
+
readonly onceFine: string;
|
|
556
|
+
/** The checkout's Buy once line under its price. */
|
|
557
|
+
readonly onceOffer: (p: HealthPlanFocusPrices) => string;
|
|
558
|
+
/** Appended to the checkout's fine print (a sandbox says nothing is charged). Empty by default. */
|
|
559
|
+
readonly checkoutNote: string;
|
|
560
|
+
readonly close: string;
|
|
561
|
+
readonly startedTitle: (p: HealthPlanFocusPrices) => string;
|
|
562
|
+
/** The started screen's title after a one-box order. */
|
|
563
|
+
readonly orderedTitle: (p: HealthPlanFocusPrices) => string;
|
|
564
|
+
readonly startedWhat: (p: HealthPlanFocusPrices) => string;
|
|
565
|
+
/** A line under the started title (a sandbox says nothing was charged). Empty by default. */
|
|
566
|
+
readonly startedNote: string;
|
|
567
|
+
readonly startedSteps: string;
|
|
568
|
+
readonly tomorrow: string;
|
|
569
|
+
readonly firstBoxShips: string;
|
|
570
|
+
/**
|
|
571
|
+
* Added after `firstBoxShips` and `placedShips`, and the order screen's `trackingByText` is drawn, only when Everfur
|
|
572
|
+
* texts the tracking number for this partner (the plan page's `tracking_texts_enabled`, or `trackingTexts`).
|
|
573
|
+
*/
|
|
574
|
+
readonly trackingComesByText: string;
|
|
575
|
+
readonly checkin: (question: string | null) => string;
|
|
576
|
+
readonly refill: string;
|
|
577
|
+
readonly nextBoxShips: (p: HealthPlanFocusPrices) => string;
|
|
578
|
+
readonly startedDone: string;
|
|
579
|
+
readonly manageKicker: string;
|
|
580
|
+
readonly manageTitle: (p: HealthPlanFocusPrices) => string;
|
|
581
|
+
readonly skip: string;
|
|
582
|
+
readonly cancel: string;
|
|
583
|
+
readonly skipped: (p: HealthPlanFocusPrices, nextBox: string | null) => string;
|
|
584
|
+
readonly cancelled: (p: HealthPlanFocusPrices) => string;
|
|
585
|
+
readonly orders: string;
|
|
586
|
+
/** The host header's title over each pushed screen (`onOverlayChange` hands it over). */
|
|
587
|
+
readonly startedHeader: string;
|
|
588
|
+
readonly placedHeader: string;
|
|
589
|
+
readonly cartCheckoutTitle: string;
|
|
590
|
+
/** Appended to an Everfur order's fine print (a sandbox says nothing was charged). Empty by default. */
|
|
591
|
+
readonly orderNote: string;
|
|
592
|
+
/** The cart button's label: `count` items in it, 0 when empty. */
|
|
593
|
+
readonly cartLabel: (count: number) => string;
|
|
594
|
+
/** The pick's button with the shop on, at the price of the picked way to buy. */
|
|
595
|
+
readonly addToCart: (price: string) => string;
|
|
596
|
+
readonly viewCart: string;
|
|
597
|
+
/** The toast when the pick goes in the cart. */
|
|
598
|
+
readonly addedToCart: (p: HealthPlanFocusPrices, subscription: boolean) => string;
|
|
599
|
+
readonly removedFromCart: (productName: string) => string;
|
|
600
|
+
readonly cartTitle: string;
|
|
601
|
+
readonly cartEmptyTitle: string;
|
|
602
|
+
readonly cartEmptyBody: (p: HealthPlanFocusPrices) => string;
|
|
603
|
+
readonly seeOrders: string;
|
|
604
|
+
readonly quantityLabel: (productName: string) => string;
|
|
605
|
+
readonly fewer: string;
|
|
606
|
+
readonly more: string;
|
|
607
|
+
readonly remove: string;
|
|
608
|
+
/** Under a subscription line's price. */
|
|
609
|
+
readonly cartSubLine: (p: HealthPlanFocusPrices) => string;
|
|
610
|
+
/** Under a one-box line's price; `subscribed`: the pet's plan already ships this product. */
|
|
611
|
+
readonly cartOnceLine: (p: HealthPlanFocusPrices, subscribed: boolean) => string;
|
|
612
|
+
readonly cartModeLabel: (productName: string) => string;
|
|
613
|
+
readonly cartModeSubscribe: (p: HealthPlanFocusPrices) => string;
|
|
614
|
+
readonly cartModeOnce: (p: HealthPlanFocusPrices) => string;
|
|
615
|
+
readonly subtotal: string;
|
|
616
|
+
readonly shipping: string;
|
|
617
|
+
/** The shipping row's value; empty (the default) leaves the row out, as Everfur's checkout prices no shipping. */
|
|
618
|
+
readonly shippingValue: string;
|
|
619
|
+
/** A tag beside "Shipping" (a demo marks it "Illustrative"). Empty by default. */
|
|
620
|
+
readonly shippingTag: string;
|
|
621
|
+
readonly total: string;
|
|
622
|
+
readonly dueToday: string;
|
|
623
|
+
readonly thenRenews: (p: HealthPlanFocusPrices) => string;
|
|
624
|
+
readonly renewsEvery: (p: HealthPlanFocusPrices) => string;
|
|
625
|
+
readonly checkoutCart: (total: string) => string;
|
|
626
|
+
/**
|
|
627
|
+
* Under the cart's Checkout button when it cannot check out: the cart is off for this partner (the server answered
|
|
628
|
+
* `cart_disabled`), so Everfur's checkout takes one product, one box, per order. Also the toast when that answer
|
|
629
|
+
* comes. Empty by default (copy owed by design): the button is disabled either way, and the toast is the error's
|
|
630
|
+
* own line.
|
|
631
|
+
*/
|
|
632
|
+
readonly cartOneAtATime: string;
|
|
633
|
+
/**
|
|
634
|
+
* In the cart checkout's fine print when the cart holds a subscription and other items: a subscription checks out
|
|
635
|
+
* on its own, so this checkout takes the other items and the subscription stays in the cart. Empty by default (copy
|
|
636
|
+
* owed by design).
|
|
637
|
+
*/
|
|
638
|
+
readonly cartSubscriptionApart: string;
|
|
639
|
+
readonly cartItemSubscription: (p: HealthPlanFocusPrices) => string;
|
|
640
|
+
readonly cartItemQuantity: (quantity: number) => string;
|
|
641
|
+
readonly placeOrder: (total: string, subscribe: boolean) => string;
|
|
642
|
+
/** The cart checkout's fine print; `p` is the subscription line's, or null with none. */
|
|
643
|
+
readonly cartFine: (p: HealthPlanFocusPrices | null) => string;
|
|
644
|
+
readonly placedSteps: string;
|
|
645
|
+
readonly placedShips: string;
|
|
646
|
+
/** The order placed screen's last row, beside the expected delivery day (drawn only when the day is known). */
|
|
647
|
+
readonly placedArrives: string;
|
|
648
|
+
readonly viewOrder: string;
|
|
649
|
+
readonly herSubscription: string;
|
|
650
|
+
readonly nextBox: (day: string) => string;
|
|
651
|
+
readonly everyDays: (days: number) => string;
|
|
652
|
+
/** The orders list's heading, after the subscription card or alone. */
|
|
653
|
+
readonly ordersHeading: (afterSubscription: boolean) => string;
|
|
654
|
+
/** Under the orders list and an order (a demo says its dates are illustrative). Empty by default. */
|
|
655
|
+
readonly ordersFine: string;
|
|
656
|
+
readonly ordersEmptyTitle: string;
|
|
657
|
+
readonly ordersEmptyBody: (p: HealthPlanFocusPrices) => string;
|
|
658
|
+
/**
|
|
659
|
+
* The button under the orders list that reads the next page. Empty by default (copy owed by design): the next page
|
|
660
|
+
* then loads as the list's end scrolls into view, with no button.
|
|
661
|
+
*/
|
|
662
|
+
readonly moreOrders: string;
|
|
663
|
+
/** The order steps, in order: ordered, shipped, out for delivery, delivered. */
|
|
664
|
+
readonly orderSteps: readonly [string, string, string, string];
|
|
665
|
+
readonly subscriptionBox: string;
|
|
666
|
+
readonly orderTitle: (number: string | null) => string;
|
|
667
|
+
readonly arrivesBy: (day: string) => string;
|
|
668
|
+
readonly deliveredOn: (day: string) => string;
|
|
669
|
+
readonly expected: (day: string) => string;
|
|
670
|
+
readonly tracking: string;
|
|
671
|
+
readonly trackingByText: string;
|
|
672
|
+
readonly trackOn: (carrier: string) => string;
|
|
673
|
+
/**
|
|
674
|
+
* The tracking link's label when the order has a tracking link but no carrier name. Empty by default (copy owed by
|
|
675
|
+
* design): the link is then not drawn.
|
|
676
|
+
*/
|
|
677
|
+
readonly trackLink: string;
|
|
678
|
+
readonly inThisOrder: string;
|
|
679
|
+
readonly orderItemLine: (quantity: number, subscriptionBox: boolean) => string;
|
|
680
|
+
readonly paidWith: string;
|
|
681
|
+
readonly buyAgain: string;
|
|
682
|
+
readonly orderHelp: string;
|
|
683
|
+
readonly addWeightTitle: string;
|
|
684
|
+
readonly addWeightBody: string;
|
|
685
|
+
readonly connectRecordsTitle: string;
|
|
686
|
+
readonly connectRecordsBody: string;
|
|
687
|
+
readonly weightKicker: string;
|
|
688
|
+
readonly weightTitle: (p: HealthPlanFocusPrices) => string;
|
|
689
|
+
readonly weightBody: string;
|
|
690
|
+
readonly weightField: string;
|
|
691
|
+
readonly weightUnit: string;
|
|
692
|
+
/** The unit beside the field with `weightUnit: 'kg'`. */
|
|
693
|
+
readonly weightUnitKg: string;
|
|
694
|
+
readonly weightError: string;
|
|
695
|
+
/** The error for a weight in kilograms that does not read. */
|
|
696
|
+
readonly weightErrorKg: string;
|
|
697
|
+
readonly weightSave: string;
|
|
698
|
+
readonly weightSaved: (pounds: string) => string;
|
|
699
|
+
readonly weightSavedKg: (kilograms: string) => string;
|
|
700
|
+
/** A payment that failed or a checkout that expired: the cart opens again with its items and this line. */
|
|
701
|
+
readonly checkoutFailed: string;
|
|
702
|
+
}
|
|
703
|
+
/** The steps an order goes through, in order. */
|
|
704
|
+
type HealthPlanOrderStatus = 'ordered' | 'shipped' | 'out_for_delivery' | 'delivered';
|
|
705
|
+
/**
|
|
706
|
+
* An order from the partner's own shop (its kits, its tests), handed in by the host so the member's orders read as
|
|
707
|
+
* one list. Everything in it is the partner's: Everfur draws it and never changes it. Everfur's own orders (a box
|
|
708
|
+
* bought through its checkout) are read from Everfur and need nothing here.
|
|
709
|
+
*/
|
|
710
|
+
interface HealthPlanShopOrder {
|
|
711
|
+
/** Stable id; also the order number shown when `number` is absent and the host wants one. */
|
|
712
|
+
readonly key: string;
|
|
713
|
+
/** The partner's order number ("EMB-31907"). */
|
|
714
|
+
readonly number?: string;
|
|
715
|
+
readonly status: HealthPlanOrderStatus;
|
|
716
|
+
/** ISO dates per step, in `HealthPlanOrderStatus` order: a done step's date, or a later step's expected date. */
|
|
717
|
+
readonly dates?: readonly (string | null)[];
|
|
718
|
+
readonly items: readonly {
|
|
719
|
+
readonly title: string;
|
|
720
|
+
readonly quantity: number;
|
|
721
|
+
/** The line's total, in `currency`. */
|
|
722
|
+
readonly price: number;
|
|
723
|
+
readonly imageUrl?: string;
|
|
724
|
+
readonly icon?: HealthPlanFocusIcon;
|
|
725
|
+
}[];
|
|
726
|
+
readonly currency: string;
|
|
727
|
+
/** A subscription's box ("Subscription box" pill). */
|
|
728
|
+
readonly subscriptionBox?: boolean;
|
|
729
|
+
readonly carrier?: string;
|
|
730
|
+
readonly trackingNumber?: string;
|
|
731
|
+
/** A tag beside the tracking number (a demo marks it "Illustrative"). */
|
|
732
|
+
readonly trackingTag?: string;
|
|
733
|
+
/** Where "Track on {carrier}" goes; without it the button is not drawn. */
|
|
734
|
+
readonly trackingUrl?: string;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
type HealthPlanSubscriptionStatus = 'active' | 'cancelled';
|
|
738
|
+
/** One step still ahead on a subscription's schedule. The surface writes the words; these are the facts. */
|
|
739
|
+
interface HealthPlanSubscriptionStep {
|
|
740
|
+
readonly step: 'first_box_ships' | 'checkin' | 'refill_reminder' | 'next_box_ships';
|
|
741
|
+
/** ISO `YYYY-MM-DD`, a UTC calendar date. */
|
|
742
|
+
readonly on: string;
|
|
743
|
+
}
|
|
744
|
+
interface HealthPlanSubscriptionRenewal {
|
|
745
|
+
readonly amount: number;
|
|
746
|
+
readonly currency: string;
|
|
747
|
+
readonly intervalDays: number;
|
|
748
|
+
}
|
|
749
|
+
interface HealthPlanSubscription {
|
|
750
|
+
readonly subscriptionId: string;
|
|
751
|
+
readonly productId: string;
|
|
752
|
+
readonly title: string | null;
|
|
753
|
+
readonly status: HealthPlanSubscriptionStatus;
|
|
754
|
+
readonly intervalDays: number;
|
|
755
|
+
readonly intervalOptions: readonly number[];
|
|
756
|
+
readonly currency: string;
|
|
757
|
+
readonly boxPrice: number;
|
|
758
|
+
/** The CURRENT run's first box. */
|
|
759
|
+
readonly firstBoxPrice: number;
|
|
760
|
+
readonly offerApplied: boolean;
|
|
761
|
+
/** ISO `YYYY-MM-DD`, or null when cancelled. */
|
|
762
|
+
readonly nextBoxDate: string | null;
|
|
763
|
+
readonly renewal: HealthPlanSubscriptionRenewal | null;
|
|
764
|
+
readonly timeline: readonly HealthPlanSubscriptionStep[];
|
|
765
|
+
}
|
|
766
|
+
interface HealthPlanSubscriptionSupply {
|
|
767
|
+
readonly unitsPerBox: number;
|
|
768
|
+
readonly unitLabel: string | null;
|
|
769
|
+
readonly unitsPerDay: number;
|
|
770
|
+
readonly supplyDays: number;
|
|
771
|
+
readonly doseBasis: 'weight' | 'assumed';
|
|
772
|
+
}
|
|
773
|
+
/** Buy once: one box, no renewal. `price` is the box price less the one-box discount (the server's figure). */
|
|
774
|
+
interface HealthPlanOneBoxOffer {
|
|
775
|
+
readonly price: number;
|
|
776
|
+
readonly discountPercent: number;
|
|
777
|
+
}
|
|
778
|
+
/** Where a one-box order is on its way. Only the partner moves it; it may also move back to correct a mistake. */
|
|
779
|
+
type HealthPlanOrderTrackingStatus = 'ordered' | 'shipped' | 'delivered';
|
|
780
|
+
/**
|
|
781
|
+
* A one-box order's tracking, as the partner wrote it. Every field but `status` is null until the partner sends it,
|
|
782
|
+
* and a value that fails the server's own rules (control or bidi characters, a tracking url that is not plain https)
|
|
783
|
+
* reads as null here too.
|
|
784
|
+
*/
|
|
785
|
+
interface HealthPlanOrderTracking {
|
|
786
|
+
readonly status: HealthPlanOrderTrackingStatus;
|
|
787
|
+
readonly orderNumber: string | null;
|
|
788
|
+
readonly carrier: string | null;
|
|
789
|
+
readonly trackingNumber: string | null;
|
|
790
|
+
/** An `https://` url with no spaces and no `@`; open it in a new tab with `rel="noopener noreferrer"`. */
|
|
791
|
+
readonly trackingUrl: string | null;
|
|
792
|
+
/** ISO date-time. */
|
|
793
|
+
readonly shippedAt: string | null;
|
|
794
|
+
/** ISO `YYYY-MM-DD`, a calendar date. */
|
|
795
|
+
readonly estimatedDelivery: string | null;
|
|
796
|
+
/** The server time of the partner's last write (ISO date-time). */
|
|
797
|
+
readonly updatedAt: string | null;
|
|
798
|
+
}
|
|
799
|
+
/** One recorded one-box order. The partner charges and ships it; Everfur never charges. */
|
|
800
|
+
interface HealthPlanOneBoxOrder {
|
|
801
|
+
readonly orderId: string;
|
|
802
|
+
readonly productId: string;
|
|
803
|
+
readonly title: string | null;
|
|
804
|
+
readonly currency: string;
|
|
805
|
+
readonly boxPrice: number;
|
|
806
|
+
/** The price of ONE box. */
|
|
807
|
+
readonly price: number;
|
|
808
|
+
readonly discountPercent: number;
|
|
809
|
+
/** ISO `YYYY-MM-DD`. */
|
|
810
|
+
readonly shipsOn: string | null;
|
|
811
|
+
/** When it was recorded (ISO date-time), from the orders list; absent from an older server. */
|
|
812
|
+
readonly createdAt?: string | null;
|
|
813
|
+
/** How many boxes (1..10). Absent from an older server, which means one. */
|
|
814
|
+
readonly quantity?: number;
|
|
815
|
+
/** `price` x `quantity`, the server's figure. Absent from an older server, which means `price`. */
|
|
816
|
+
readonly total?: number;
|
|
817
|
+
/** Absent from an older server, which knows only that the order was recorded. */
|
|
818
|
+
readonly tracking?: HealthPlanOrderTracking;
|
|
819
|
+
}
|
|
820
|
+
/** One page of a pet's one-box orders, newest first. */
|
|
821
|
+
interface HealthPlanOneBoxOrderPage {
|
|
822
|
+
readonly orders: readonly HealthPlanOneBoxOrder[];
|
|
823
|
+
/** Pass it as `cursor` for the next page; null on the last page. */
|
|
824
|
+
readonly nextCursor: string | null;
|
|
825
|
+
}
|
|
826
|
+
interface HealthPlanOneBoxOrderPageOptions {
|
|
827
|
+
/** 1..50; default 50. */
|
|
828
|
+
readonly limit?: number;
|
|
829
|
+
/** The `nextCursor` of the previous page. */
|
|
830
|
+
readonly cursor?: string;
|
|
831
|
+
}
|
|
832
|
+
interface HealthPlanSubscriptionQuote {
|
|
833
|
+
readonly productId: string;
|
|
834
|
+
readonly currency: string;
|
|
835
|
+
readonly boxPrice: number;
|
|
836
|
+
readonly firstBoxPrice: number;
|
|
837
|
+
readonly firstBoxDiscountPercent: number;
|
|
838
|
+
readonly offerApplies: boolean;
|
|
839
|
+
/** Buy once. Null from a server older than contract v2: the surface then hands a one-time buy to the partner. */
|
|
840
|
+
readonly oneBox: HealthPlanOneBoxOffer | null;
|
|
841
|
+
readonly intervalOptions: readonly number[];
|
|
842
|
+
readonly defaultIntervalDays: number;
|
|
843
|
+
readonly supply: HealthPlanSubscriptionSupply | null;
|
|
844
|
+
readonly firstBoxShipsOn: string | null;
|
|
845
|
+
/** The member's existing active or cancelled row for this pet and product, or null. */
|
|
846
|
+
readonly subscription: HealthPlanSubscription | null;
|
|
847
|
+
}
|
|
848
|
+
interface HealthPlanSubscriptionRepository {
|
|
849
|
+
quote(petRef: PetRef, productId: string): Promise<EverfurResult<HealthPlanSubscriptionQuote>>;
|
|
850
|
+
list(petRef: PetRef): Promise<EverfurResult<readonly HealthPlanSubscription[]>>;
|
|
851
|
+
create(petRef: PetRef, productId: string, intervalDays?: number): Promise<EverfurResult<HealthPlanSubscription>>;
|
|
852
|
+
changeInterval(petRef: PetRef, subscriptionId: string, intervalDays: number): Promise<EverfurResult<HealthPlanSubscription>>;
|
|
853
|
+
skip(petRef: PetRef, subscriptionId: string): Promise<EverfurResult<HealthPlanSubscription>>;
|
|
854
|
+
cancel(petRef: PetRef, subscriptionId: string): Promise<EverfurResult<HealthPlanSubscription>>;
|
|
855
|
+
restart(petRef: PetRef, subscriptionId: string, intervalDays?: number): Promise<EverfurResult<HealthPlanSubscription>>;
|
|
856
|
+
/**
|
|
857
|
+
* Buy one box. `tapKey` names the member's one confirm tap: pass the same value on a retry of that tap and the
|
|
858
|
+
* server answers with the same order instead of recording a second one. Omitted, each call is a new order.
|
|
859
|
+
*/
|
|
860
|
+
buyOneBox(petRef: PetRef, productId: string, tapKey?: string): Promise<EverfurResult<HealthPlanOneBoxOrder>>;
|
|
861
|
+
/** The pet's one-box orders, newest first. Optional so a host's own repository keeps compiling; absent, no orders list. */
|
|
862
|
+
listOneBoxOrders?(petRef: PetRef): Promise<EverfurResult<readonly HealthPlanOneBoxOrder[]>>;
|
|
863
|
+
/**
|
|
864
|
+
* One page of the pet's one-box orders, newest first. Optional like `listOneBoxOrders`; absent, the surface reads
|
|
865
|
+
* that one list instead. A cursor that is no longer this pet's answers `reasonCode` `invalid_cursor` (422): start
|
|
866
|
+
* again without one.
|
|
867
|
+
*/
|
|
868
|
+
listOneBoxOrderPage?(petRef: PetRef, opts?: HealthPlanOneBoxOrderPageOptions): Promise<EverfurResult<HealthPlanOneBoxOrderPage>>;
|
|
869
|
+
}
|
|
870
|
+
/** A 404 on a subscription route: the switch is off, or the product is not subscribable. */
|
|
871
|
+
declare function isHealthPlanSubscriptionUnavailable(error: EverfurError | null | undefined): boolean;
|
|
872
|
+
/** The allowlist mapper for one Subscription body; null when a required fact is missing. */
|
|
873
|
+
declare function healthPlanSubscriptionFromWire(raw: unknown): HealthPlanSubscription | null;
|
|
874
|
+
/** The allowlist mapper for one OneBoxOrder body; null when a required fact is missing. */
|
|
875
|
+
declare function healthPlanOneBoxOrderFromWire(raw: unknown): HealthPlanOneBoxOrder | null;
|
|
876
|
+
/**
|
|
877
|
+
* The allowlist mapper for an order's `tracking` (always sent by a current server); null when absent or not an
|
|
878
|
+
* object (an older server). An unknown status reads as `ordered`, the one step every order has.
|
|
879
|
+
*/
|
|
880
|
+
declare function healthPlanOrderTrackingFromWire(raw: unknown): HealthPlanOrderTracking | null;
|
|
881
|
+
/** The allowlist mapper for one page of the orders list; null when `orders` is not a list. */
|
|
882
|
+
declare function healthPlanOneBoxOrderPageFromWire(raw: unknown): HealthPlanOneBoxOrderPage | null;
|
|
883
|
+
/** The allowlist mapper for one quote body; null when a required fact is missing. */
|
|
884
|
+
declare function healthPlanSubscriptionQuoteFromWire(raw: unknown): HealthPlanSubscriptionQuote | null;
|
|
885
|
+
/** The repository over one auth context (or an injected funnel). */
|
|
886
|
+
declare function createHealthPlanSubscriptionRepositoryOver(deps: HealthPlanRepositoryDeps): Required<HealthPlanSubscriptionRepository>;
|
|
887
|
+
/** The repository over the runtime under your provider. Auth is read at CALL time; a disposed runtime sends nothing. */
|
|
888
|
+
declare function createHealthPlanSubscriptionRepository(runtime: HealthPlanRuntime): Required<HealthPlanSubscriptionRepository>;
|
|
889
|
+
|
|
890
|
+
/** Whose checkout runs Buy and Subscribe: Everfur's Stripe Checkout, or the partner's own (today's handoff). */
|
|
891
|
+
type HealthPlanCheckoutProvider = 'everfur_stripe' | 'partner';
|
|
892
|
+
type HealthPlanPurchase = 'one_box' | 'subscription';
|
|
893
|
+
type HealthPlanCheckoutStatus = 'pending' | 'paid' | 'expired' | 'failed';
|
|
894
|
+
/** The pet facts the page was built from. */
|
|
895
|
+
interface HealthPlanPagePet {
|
|
896
|
+
readonly name: string | null;
|
|
897
|
+
readonly species: string | null;
|
|
898
|
+
readonly sex: 'female' | 'male' | null;
|
|
899
|
+
readonly breed: string | null;
|
|
900
|
+
readonly weightKg: number | null;
|
|
901
|
+
readonly weightLb: number | null;
|
|
902
|
+
}
|
|
903
|
+
interface HealthPlanPage {
|
|
904
|
+
readonly petRef: PetRef;
|
|
905
|
+
readonly pet: HealthPlanPagePet;
|
|
906
|
+
readonly checkout: HealthPlanCheckoutProvider;
|
|
907
|
+
/** The focus layout's content, or null when the plan has no items for this pet. */
|
|
908
|
+
readonly page: HealthPlanFocusDesign | null;
|
|
909
|
+
/**
|
|
910
|
+
* True only when the page draws a condition template the Medical Director reviewed (`vet_reviewed`). The focus
|
|
911
|
+
* layout draws the vet byline only then. Absent: false.
|
|
912
|
+
*/
|
|
913
|
+
readonly vetReviewed?: boolean;
|
|
914
|
+
/**
|
|
915
|
+
* True only when Everfur texts the member the tracking number once the partner sets it (`tracking_texts_enabled`).
|
|
916
|
+
* The "tracking comes by text" lines are drawn only then. Absent: false.
|
|
917
|
+
*/
|
|
918
|
+
readonly trackingTextsEnabled?: boolean;
|
|
919
|
+
}
|
|
920
|
+
interface HealthPlanCheckoutRequest {
|
|
921
|
+
readonly productId: string;
|
|
922
|
+
readonly purchase: HealthPlanPurchase;
|
|
923
|
+
/** Subscriptions only: one of the quote's interval options. */
|
|
924
|
+
readonly intervalDays?: number;
|
|
925
|
+
/** Where Stripe sends the member back after paying, and after backing out. Absolute http(s). */
|
|
926
|
+
readonly successUrl: string;
|
|
927
|
+
readonly cancelUrl: string;
|
|
928
|
+
}
|
|
929
|
+
/** One cart line for the cart checkout. Each product at most once; a subscription line is quantity 1 and alone. */
|
|
930
|
+
interface HealthPlanCheckoutItem {
|
|
931
|
+
readonly productId: string;
|
|
932
|
+
readonly purchase: HealthPlanPurchase;
|
|
933
|
+
/** Subscriptions only. */
|
|
934
|
+
readonly intervalDays?: number;
|
|
935
|
+
/** 1..10, default 1. */
|
|
936
|
+
readonly quantity?: number;
|
|
937
|
+
}
|
|
938
|
+
/** The cart checkout: 1..10 lines in one Stripe Checkout. */
|
|
939
|
+
interface HealthPlanCartCheckoutRequest {
|
|
940
|
+
readonly items: readonly HealthPlanCheckoutItem[];
|
|
941
|
+
readonly successUrl: string;
|
|
942
|
+
readonly cancelUrl: string;
|
|
943
|
+
}
|
|
944
|
+
/**
|
|
945
|
+
* Why the server refused a checkout start, when it said so (a 409's `detail`): `cart_disabled` (the cart switch is
|
|
946
|
+
* off for this tenant: buy one product at a time), `cart_has_subscription` (check the subscription out on its own),
|
|
947
|
+
* or the older refusals.
|
|
948
|
+
*/
|
|
949
|
+
type HealthPlanCheckoutRefusal = 'cart_disabled' | 'cart_has_subscription' | 'cart_currency_mixed' | 'sample_product' | 'partner_endpoint_missing' | 'checkout_pending' | 'already_subscribed';
|
|
950
|
+
/**
|
|
951
|
+
* The refusal a checkout start's 409 named, or null. The route answers `{"detail": "<token>"}`, which reaches the SDK
|
|
952
|
+
* as the error's server message (or its `reasonCode`); only the tokens above are recognised, so free text never is.
|
|
953
|
+
*/
|
|
954
|
+
declare function healthPlanCheckoutRefusal(error: EverfurError | null | undefined): HealthPlanCheckoutRefusal | null;
|
|
955
|
+
interface HealthPlanCheckoutSession {
|
|
956
|
+
readonly checkoutId: string;
|
|
957
|
+
/** The Stripe Checkout page to send the member to (https). */
|
|
958
|
+
readonly url: string;
|
|
959
|
+
}
|
|
960
|
+
interface HealthPlanCheckoutState {
|
|
961
|
+
readonly status: HealthPlanCheckoutStatus;
|
|
962
|
+
readonly purchase: HealthPlanPurchase;
|
|
963
|
+
/** The first one-box order, once the server has one (`orders[0]`). */
|
|
964
|
+
readonly order: HealthPlanOneBoxOrder | null;
|
|
965
|
+
/** Every one-box order the checkout made, in cart line order; empty until paid (and from an older server). */
|
|
966
|
+
readonly orders: readonly HealthPlanOneBoxOrder[];
|
|
967
|
+
/** The subscription, once the server has one. */
|
|
968
|
+
readonly subscription: HealthPlanSubscription | null;
|
|
969
|
+
}
|
|
970
|
+
interface HealthPlanPageRepository {
|
|
971
|
+
/** `GET .../plan/page`. Settles; never throws. */
|
|
972
|
+
getPage(petRef: PetRef, opts?: {
|
|
973
|
+
readonly signal?: AbortSignal;
|
|
974
|
+
}): Promise<EverfurResult<HealthPlanPage>>;
|
|
975
|
+
/**
|
|
976
|
+
* `POST .../plan/checkout`. `idempotencyKey` names the member's one tap: the same value on a retry answers with the
|
|
977
|
+
* same session.
|
|
978
|
+
*/
|
|
979
|
+
startCheckout(petRef: PetRef, body: HealthPlanCheckoutRequest, idempotencyKey: string): Promise<EverfurResult<HealthPlanCheckoutSession>>;
|
|
980
|
+
/**
|
|
981
|
+
* `POST .../plan/checkout` in the cart form (`items`). Optional so a host's own repository keeps compiling; absent,
|
|
982
|
+
* the surface checks out one product at a time. A refusal names its reason through `healthPlanCheckoutRefusal`.
|
|
983
|
+
*/
|
|
984
|
+
startCartCheckout?(petRef: PetRef, body: HealthPlanCartCheckoutRequest, idempotencyKey: string): Promise<EverfurResult<HealthPlanCheckoutSession>>;
|
|
985
|
+
/** `GET .../plan/checkout/{checkout_id}`. */
|
|
986
|
+
getCheckout(petRef: PetRef, checkoutId: string): Promise<EverfurResult<HealthPlanCheckoutState>>;
|
|
987
|
+
}
|
|
988
|
+
/**
|
|
989
|
+
* The allowlist mapper for one plan page (`page` of the page route). Null when the page has no title or no pick:
|
|
990
|
+
* the layout cannot be drawn without them. The SDK's buying words (`copy`) are never read from the wire.
|
|
991
|
+
*/
|
|
992
|
+
declare function healthPlanFocusDesignFromWire(raw: unknown): HealthPlanFocusDesign | null;
|
|
993
|
+
/** The allowlist mapper for one page-route body. Null when it is not a page answer (no `page` key at all). */
|
|
994
|
+
declare function healthPlanPageFromWire(raw: unknown, petRef: PetRef): HealthPlanPage | null;
|
|
995
|
+
/** The allowlist mapper for one checkout-start body; null without an id or an https url. */
|
|
996
|
+
declare function healthPlanCheckoutSessionFromWire(raw: unknown): HealthPlanCheckoutSession | null;
|
|
997
|
+
/** The allowlist mapper for one checkout-status body; null without a known status and purchase. */
|
|
998
|
+
declare function healthPlanCheckoutStateFromWire(raw: unknown): HealthPlanCheckoutState | null;
|
|
999
|
+
/** The repository over one auth context (or an injected funnel). */
|
|
1000
|
+
declare function createHealthPlanPageRepositoryOver(deps: HealthPlanRepositoryDeps): HealthPlanPageRepository;
|
|
1001
|
+
/** The repository over the runtime under your provider. Auth is read at CALL time; a disposed runtime sends nothing. */
|
|
1002
|
+
declare function createHealthPlanPageRepository(runtime: HealthPlanRuntime): HealthPlanPageRepository;
|
|
1003
|
+
|
|
1004
|
+
/** What a docked bar needs, as the plan page last published it. */
|
|
1005
|
+
interface HealthPlanCartDock {
|
|
1006
|
+
/** The member's cart: the items in the plan, their count and subtotal. */
|
|
1007
|
+
readonly cart: HealthPlanCart;
|
|
1008
|
+
/** True while an add or remove is in flight (draw the checkout control disabled). */
|
|
1009
|
+
readonly busy: boolean;
|
|
1010
|
+
/** The pet whose plan the page shows, or null. */
|
|
1011
|
+
readonly petRef: PetRef | null;
|
|
1012
|
+
/** The plan the page shows, or null before it loads. */
|
|
1013
|
+
readonly plan: HealthPlan | null;
|
|
1014
|
+
/** Adds (`true`) or removes (`false`) one product, as the page's own control does. Resolves true when it took. */
|
|
1015
|
+
readonly setInPlan: (productId: string, inPlan: boolean) => Promise<boolean>;
|
|
1016
|
+
/** Adds every product not yet in the plan. Resolves true when every add took. */
|
|
1017
|
+
readonly addAll: () => Promise<boolean>;
|
|
1018
|
+
}
|
|
1019
|
+
interface HealthPlanCartScopeProps {
|
|
1020
|
+
readonly children?: ReactNode;
|
|
1021
|
+
}
|
|
1022
|
+
/** The scope a plan page with `cartBarPlacement: 'none'` publishes its cart to. Wrap the page and your bar in it. */
|
|
1023
|
+
declare function HealthPlanCartScope({ children }: HealthPlanCartScopeProps): ReactNode;
|
|
1024
|
+
/** The cart the plan page in the nearest `HealthPlanCartScope` published, or null (no scope, or no page yet). */
|
|
1025
|
+
declare function useHealthPlanCartDock(): HealthPlanCartDock | null;
|
|
1026
|
+
|
|
1027
|
+
declare const HEALTH_PLAN_COPY: Readonly<{
|
|
1028
|
+
loading: "Loading";
|
|
1029
|
+
retry: "Try again";
|
|
1030
|
+
signedOut: "Sign in required";
|
|
1031
|
+
addToCart: "Add to cart";
|
|
1032
|
+
added: "Added";
|
|
1033
|
+
remove: "Remove";
|
|
1034
|
+
checkout: "Checkout";
|
|
1035
|
+
subtotal: "Subtotal";
|
|
1036
|
+
sample: "Sample";
|
|
1037
|
+
cartEmpty: "Your cart is empty.";
|
|
1038
|
+
choosePet: "Choose a pet";
|
|
1039
|
+
emptyTitle: "";
|
|
1040
|
+
emptyBody: "";
|
|
1041
|
+
emptyAsk: "";
|
|
1042
|
+
}>;
|
|
1043
|
+
/** The Health Plan's empty state words (Q1). Each is '' by default: an empty title and body draw nothing. */
|
|
1044
|
+
interface HealthPlanEmptyCopy {
|
|
1045
|
+
readonly emptyTitle: string;
|
|
1046
|
+
readonly emptyBody: string;
|
|
1047
|
+
/** The empty state's Ask button. */
|
|
1048
|
+
readonly emptyAsk: string;
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* The reason labels, one per kind. An empty label is not drawn (the reason's text still is). `profile` (a pet profile
|
|
1052
|
+
* fact) has no source yet; `dna` names one partner's product, so the SDK leaves it to that partner (Q3).
|
|
1053
|
+
*/
|
|
1054
|
+
declare const HEALTH_PLAN_REASON_LABELS: Readonly<Record<HealthPlanReasonKind, string>>;
|
|
1055
|
+
/** ADAPTED from Raph. Listed for approval. */
|
|
1056
|
+
declare const HEALTH_PLAN_TEMPLATES: Readonly<{
|
|
1057
|
+
/** Raph: "Georgia's care plan". Used only when the plan carries no `headline` of the tenant's own. */
|
|
1058
|
+
planTitle: (petName: string) => string;
|
|
1059
|
+
/** Raph: "<brand> cart" (his demo named the partner). */
|
|
1060
|
+
cartLabel: (brand: string) => string;
|
|
1061
|
+
}>;
|
|
1062
|
+
/** Every key still waiting on Raph's words (empty, so not drawn), so the list a reviewer approves cannot drift from the file. */
|
|
1063
|
+
declare const HEALTH_PLAN_COPY_PLACEHOLDERS: readonly string[];
|
|
1064
|
+
|
|
1065
|
+
type HealthPlanPagePhase = 'idle' | 'loading' | 'failed' | 'ready';
|
|
1066
|
+
interface HealthPlanPageOptions {
|
|
1067
|
+
readonly petRef: PetRef | null;
|
|
1068
|
+
/** False skips the read. Defaults to true. */
|
|
1069
|
+
readonly enabled?: boolean;
|
|
1070
|
+
/** A repository of your own (tests, a stub backend). Defaults to the one over the provider's runtime. */
|
|
1071
|
+
readonly repository?: HealthPlanPageRepository;
|
|
1072
|
+
/** Coming back to the foreground re-reads a page shown for more than a minute, quietly. Absent, it does not. */
|
|
1073
|
+
readonly lifecycle?: LifecyclePort | null;
|
|
1074
|
+
/** Change it to re-read the page now, quietly. */
|
|
1075
|
+
readonly refreshKey?: string | number;
|
|
1076
|
+
}
|
|
1077
|
+
interface HealthPlanPageState {
|
|
1078
|
+
readonly phase: HealthPlanPagePhase;
|
|
1079
|
+
/** The answer for `petRef`, or null until it lands. */
|
|
1080
|
+
readonly page: HealthPlanPage | null;
|
|
1081
|
+
readonly error: EverfurError | null;
|
|
1082
|
+
/** True when the read answered not found: this pet has no plan page. `phase` is then `ready` and `page` null. */
|
|
1083
|
+
readonly missing: boolean;
|
|
1084
|
+
refresh(): Promise<void>;
|
|
1085
|
+
}
|
|
1086
|
+
/** The plan page repository bound to the runtime under your provider. */
|
|
1087
|
+
declare function useHealthPlanPageRepository(): HealthPlanPageRepository;
|
|
1088
|
+
/** One pet's Health Plan page. Re-read when the pet changes. */
|
|
1089
|
+
declare function useHealthPlanPage(options: HealthPlanPageOptions): HealthPlanPageState;
|
|
1090
|
+
|
|
1091
|
+
type HealthPlanPhase = 'idle' | 'loading' | 'failed' | 'ready';
|
|
1092
|
+
interface HealthPlanSnapshot {
|
|
1093
|
+
readonly phase: HealthPlanPhase;
|
|
1094
|
+
readonly petRef: PetRef | null;
|
|
1095
|
+
readonly plan: HealthPlan | null;
|
|
1096
|
+
/** Product ids whose add or remove is in flight. */
|
|
1097
|
+
readonly pending: readonly string[];
|
|
1098
|
+
/** The last refused write per product id. */
|
|
1099
|
+
readonly itemErrors: Readonly<Record<string, EverfurError>>;
|
|
1100
|
+
/** The refused read, or null. */
|
|
1101
|
+
readonly error: EverfurError | null;
|
|
1102
|
+
}
|
|
1103
|
+
declare class HealthPlanController {
|
|
1104
|
+
private readonly repository;
|
|
1105
|
+
private snapshot;
|
|
1106
|
+
private readonly listeners;
|
|
1107
|
+
private generation;
|
|
1108
|
+
/** Bumped by every add or remove, so a quiet re-read that started before one never overwrites it. */
|
|
1109
|
+
private writes;
|
|
1110
|
+
/** Bumped by every quiet re-read, so an older one that settles after a newer one never overwrites it. */
|
|
1111
|
+
private revalidations;
|
|
1112
|
+
/** A host refresh asked for while a write was in flight: the quiet re-read runs once the last write settles. */
|
|
1113
|
+
private refreshAfterWrites;
|
|
1114
|
+
private disposed;
|
|
1115
|
+
constructor(repository: HealthPlanRepository);
|
|
1116
|
+
readonly subscribe: (listener: () => void) => (() => void);
|
|
1117
|
+
readonly getSnapshot: () => HealthPlanSnapshot;
|
|
1118
|
+
private set;
|
|
1119
|
+
/** Read the plan for `petRef` (null clears to `idle`). A different pet drops the old plan before the read lands. */
|
|
1120
|
+
load(petRef: PetRef | null): Promise<void>;
|
|
1121
|
+
/**
|
|
1122
|
+
* Re-read the shown plan WITHOUT a loading state (a member coming back to a page that sat open, a host's
|
|
1123
|
+
* `refreshKey`). Only from `ready` with nothing in flight; the answer replaces the plan only while the same pet is
|
|
1124
|
+
* shown and no add, remove or full read happened meanwhile. A refused re-read keeps the plan on screen.
|
|
1125
|
+
*/
|
|
1126
|
+
revalidate(): Promise<void>;
|
|
1127
|
+
/**
|
|
1128
|
+
* The host says the plan changed (its `refreshKey`), so the request is never dropped: from `ready` a quiet
|
|
1129
|
+
* re-read, held until the last add or remove in flight settles; from `failed` or `loading` a full read for the
|
|
1130
|
+
* shown pet (there is no plan to keep on screen, and a read in flight may predate the change).
|
|
1131
|
+
*/
|
|
1132
|
+
refresh(): Promise<void>;
|
|
1133
|
+
private settleWrite;
|
|
1134
|
+
/** Put an item in the plan (`true`) or take it out (`false`). Settles true when the server accepted it. */
|
|
1135
|
+
setInPlan(productId: string, inPlan: boolean): Promise<boolean>;
|
|
1136
|
+
dispose(): void;
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
/** A named element of the focus layout. Pass a class for it in `classNames` and its inline default is dropped. */
|
|
1140
|
+
type HealthPlanFocusPart = 'root' | 'head' | 'eyebrow' | 'serif' | 'headImage' | 'by' | 'byOk' | 'need' | 'needKicker' | 'sources' | 'source' | 'needRisk' | 'dot' | 'odds' | 'oddsKicker' | 'oddsNumbers' | 'tag' | 'says' | 'saysKicker' | 'jump' | 'jumpGo' | 'steps' | 'stepsHead' | 'n' | 'list' | 'tip' | 'tipN' | 'tipTop' | 'section' | 'sectionTitle' | 'pick' | 'others' | 'other' | 'otherCategory' | 'pickTop' | 'pickImage' | 'stars' | 'pickLine' | 'reviews' | 'review' | 'reviewStars' | 'score' | 'why' | 'mini' | 'chip' | 'dose' | 'ingredients' | 'opts' | 'opt' | 'optText' | 'optTag' | 'price' | 'optPrice' | 'buy' | 'button' | 'proof' | 'trust' | 'on' | 'onIcon' | 'more' | 'fine' | 'sign' | 'questionsKicker' | 'questions' | 'add' | 'extras' | 'extrasTitle' | 'extra' | 'extraIcon' | 'extraTitle' | 'extraPrice' | 'extraGo' | 'pageFine' | 'stateOn' | 'scrim' | 'sheet' | 'sheetGrab' | 'sheetTop' | 'sheetKicker' | 'sheetClose' | 'srOnly' | 'co' | 'coProd' | 'coProdImage' | 'coProdTitle' | 'coOpts' | 'coOpt' | 'coHit' | 'radio' | 'coPrice' | 'coWhen' | 'coKey' | 'coEvery' | 'coRows' | 'buttonLarge' | 'buttonGhost' | 'coFine' | 'mgCancel' | 'started' | 'startedScroll' | 'done' | 'doneCheck' | 'doneTitle' | 'doneWhen' | 'doneWho' | 'next' | 'nextIcon' | 'foot' | 'toast' | 'tools' | 'toolsEnd' | 'ordersButton' | 'cartButton' | 'cartCount' | 'askRow' | 'askRowIcon' | 'wait' | 'waitTop' | 'waitTile' | 'waitKey' | 'waitText' | 'track' | 'trackDot' | 'push' | 'shop' | 'shopTitle' | 'shopSub' | 'shopKey' | 'shopCard' | 'shopItems' | 'shopItem' | 'shopItemImage' | 'shopItemPrice' | 'shopItemActions' | 'stepper' | 'shopRemove' | 'shopMode' | 'summary' | 'shopFine' | 'shopEmpty' | 'shopTile' | 'shopLink' | 'shopActions' | 'subCard' | 'orderList' | 'order' | 'orderTop' | 'orderPill' | 'orderNo' | 'orderWhat' | 'orderMeta' | 'orderPics' | 'carrier' | 'carrierIcon' | 'carrierWait' | 'buttonSmall' | 'coItems' | 'weightField' | 'weightInput' | 'weightUnit' | 'weightError' | 'weightActions' | 'summaryRow' | 'trackStep' | 'shopTag' | 'sheetBody';
|
|
1141
|
+
/**
|
|
1142
|
+
* Classes per part. A key `part:kind` adds a modifier class for one kind of a part (`sign:urgent`, `chip:rec`,
|
|
1143
|
+
* `source:dna`, `dot:risk`, `opt:once`, `extra:kit`); the kinds come from the design rows.
|
|
1144
|
+
*/
|
|
1145
|
+
type HealthPlanFocusClassNames = Readonly<Partial<Record<HealthPlanFocusPart, string>>> & Readonly<Record<string, string | undefined>>;
|
|
1146
|
+
|
|
1147
|
+
/**
|
|
1148
|
+
* The words for the pet in the buying copy: "her" for a female, "his" for a male, else the pet's name ("Georgia's"),
|
|
1149
|
+
* else "your pet" (the SDK's existing fallback, CHAT_COPY.emptyTitlePetFallback).
|
|
1150
|
+
*/
|
|
1151
|
+
interface HealthPlanPetWords {
|
|
1152
|
+
/** The name mid-sentence: "Georgia", else "your pet". */
|
|
1153
|
+
readonly name: string;
|
|
1154
|
+
/** The name at a sentence's start: "Georgia", else "Your pet". */
|
|
1155
|
+
readonly Name: string;
|
|
1156
|
+
/** "her", "his", "Georgia's", "your pet's". */
|
|
1157
|
+
readonly poss: string;
|
|
1158
|
+
/** The same at a sentence's start. */
|
|
1159
|
+
readonly Poss: string;
|
|
1160
|
+
/** "her", "him", "Georgia", "your pet". */
|
|
1161
|
+
readonly obj: string;
|
|
1162
|
+
}
|
|
1163
|
+
/** The pet's words from the plan page's `name` and `sex`. Pure. */
|
|
1164
|
+
declare function healthPlanPetWords(name: string | null | undefined, sex: 'female' | 'male' | null | undefined): HealthPlanPetWords;
|
|
1165
|
+
/**
|
|
1166
|
+
* The buying words for one pet: Raph's (the v3 design of 2026-10-16 and round 5 of 2026-10-20) with "her" taken
|
|
1167
|
+
* from the pet (`healthPlanPetWords`). The prices' `petName`, when set, names the pet in the lines that use its name.
|
|
1168
|
+
*/
|
|
1169
|
+
declare function healthPlanFocusCopyFor(pet: {
|
|
1170
|
+
readonly name?: string | null;
|
|
1171
|
+
readonly sex?: 'female' | 'male' | null;
|
|
1172
|
+
}): HealthPlanFocusCopy;
|
|
1173
|
+
/** The buying words for a female pet: Raph's own, word for word. `EverfurHealthPlan` builds them from the pet's sex. */
|
|
1174
|
+
declare const HEALTH_PLAN_FOCUS_COPY: HealthPlanFocusCopy;
|
|
1175
|
+
/** A UTC calendar date (`2026-10-30`) as a short day (`Oct 30`). */
|
|
1176
|
+
declare function formatHealthPlanDay(iso: string | null, locale?: string): string | null;
|
|
1177
|
+
|
|
1178
|
+
export { type HealthPlanOneBoxOffer as $, type HealthPlanAddedVariant as A, type HealthPlanCardShadow as B, type HealthPlanCartBarPlacement as C, type HealthPlanCartBarVisibility as D, type EverfurHealthPlanOptions as E, type HealthPlanCartCheckoutRequest as F, type HealthPlanCartDock as G, type HealthPlanFocusCopy as H, HealthPlanCartScope as I, type HealthPlanCartScopeProps as J, type HealthPlanCategoryVariant as K, type HealthPlanCheckoutItem as L, type HealthPlanCheckoutRefusal as M, type HealthPlanCheckoutRequest as N, type HealthPlanCheckoutSession as O, type HealthPlanCheckoutState as P, type HealthPlanCheckoutStatus as Q, HealthPlanController as R, type HealthPlanFocusExtra as S, type HealthPlanFocusPrices as T, type HealthPlanFocusReasonRow as U, type HealthPlanFocusReview as V, type HealthPlanFocusSign as W, type HealthPlanFocusStep as X, type HealthPlanFocusWait as Y, type HealthPlanFontWeight as Z, type HealthPlanHeaderContext as _, type HealthPlanFocusIcon as a, type HealthPlanOneBoxOrderPage as a0, type HealthPlanOneBoxOrderPageOptions as a1, type HealthPlanOrderStatus as a2, type HealthPlanOrderTracking as a3, type HealthPlanOrderTrackingStatus as a4, type HealthPlanPage as a5, type HealthPlanPageContext as a6, type HealthPlanPageOptions as a7, type HealthPlanPagePet as a8, type HealthPlanPagePhase as a9, healthPlanCheckoutStateFromWire as aA, healthPlanFocusDesignFromWire as aB, healthPlanFromWire as aC, healthPlanPageFromWire as aD, isHealthPlanSessionRequired as aE, showHealthPlanCartBar as aF, useEverfurHealthPlan as aG, useEverfurHealthPlanRepository as aH, useHealthPlanCartDock as aI, useHealthPlanPage as aJ, useHealthPlanPageRepository as aK, type HealthPlanFocusClassNames as aL, type HealthPlanEmptyCopy as aM, type HealthPlanFocusPart as aN, type HealthPlanPetWords as aO, createHealthPlanSubscriptionRepository as aP, createHealthPlanSubscriptionRepositoryOver as aQ, healthPlanFocusCopyFor as aR, healthPlanOneBoxOrderFromWire as aS, healthPlanOneBoxOrderPageFromWire as aT, healthPlanOrderTrackingFromWire as aU, healthPlanPetWords as aV, healthPlanSubscriptionFromWire as aW, healthPlanSubscriptionQuoteFromWire as aX, isHealthPlanSubscriptionUnavailable as aY, type HealthPlanPageState as aa, type HealthPlanPhase as ab, type HealthPlanPurchase as ac, type HealthPlanReason as ad, type HealthPlanReasonKind as ae, type HealthPlanRepository as af, type HealthPlanRepositoryDeps as ag, type HealthPlanRuntime as ah, type HealthPlanShadow as ai, type HealthPlanSnapshot as aj, type HealthPlanSubscriptionQuote as ak, type HealthPlanSubscriptionRenewal as al, type HealthPlanSubscriptionStatus as am, type HealthPlanSubscriptionStep as an, type HealthPlanSubscriptionSupply as ao, type HealthPlanTrackStep as ap, createHealthPlanPageRepository as aq, createHealthPlanPageRepositoryOver as ar, createHealthPlanRepository as as, createHealthPlanRepositoryOver as at, formatHealthPlanDay as au, formatHealthPlanPrice as av, formatHealthPlanPriceWith as aw, healthPlanCart as ax, healthPlanCheckoutRefusal as ay, healthPlanCheckoutSessionFromWire as az, type HealthPlanFocusDesign as b, type HealthPlanItem as c, type HealthPlanSubscription as d, type HealthPlanOneBoxOrder as e, type HealthPlanSubscriptionRepository as f, type HealthPlanPageRepository as g, type HealthPlanShopOrder as h, type HealthPlanCheckoutProvider as i, type HealthPlanPriceFormat as j, type HealthPlanLayoutProps as k, type HealthPlanCardOptions as l, type HealthPlanImageVariant as m, type HealthPlanReasonVariant as n, type HealthPlanCart as o, type EverfurHealthPlanState as p, type EverfurHealthPlanStatus as q, HEALTH_PLAN_COPY as r, HEALTH_PLAN_COPY_PLACEHOLDERS as s, HEALTH_PLAN_FOCUS_COPY as t, HEALTH_PLAN_LAYOUT_DEFAULTS as u, HEALTH_PLAN_REASON_KINDS as v, HEALTH_PLAN_REASON_LABELS as w, HEALTH_PLAN_TEMPLATES as x, type HealthPlan as y, type HealthPlanAddButtonSize as z };
|