@everfur/sdk 0.12.1 → 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.
Files changed (268) hide show
  1. package/CHANGELOG.md +166 -0
  2. package/README.md +2 -1
  3. package/dist/{Chat-CbyZ1vAX.d.cts → Chat.d-DUNTfzqC.d.ts} +170 -8
  4. package/dist/{Chat-CgYQdfqi.d.ts → Chat.d-Dts8u_1a.d.cts} +170 -8
  5. package/dist/{DepthViews-CaQUyCHK.d.ts → DepthViews.d-BIp599lz.d.cts} +1 -1
  6. package/dist/{DepthViews-CCz4ig0u.d.ts → DepthViews.d-BMU2jFPw.d.cts} +1 -1
  7. package/dist/{DepthViews-D3OiIK_x.d.cts → DepthViews.d-Ce2Zhnrb.d.ts} +1 -1
  8. package/dist/{DepthViews-iGZi4_WK.d.cts → DepthViews.d-CubkMPbU.d.ts} +1 -1
  9. package/dist/{ErrorPolicyPort-10s3HJCt.d.cts → ErrorPolicyPort.d-68yrE3BE.d.ts} +1 -1
  10. package/dist/{ErrorPolicyPort-C3nNSS_j.d.ts → ErrorPolicyPort.d-DirW9hgO.d.cts} +1 -1
  11. package/dist/{EverfurError-DeBqRpQV.d.cts → EverfurError.d-8NHtlgzA.d.cts} +11 -1
  12. package/dist/{EverfurError-DeBqRpQV.d.ts → EverfurError.d-8NHtlgzA.d.ts} +11 -1
  13. package/dist/{EverfurResult-ClPTS0P2.d.ts → EverfurResult.d-BFH-3s6E.d.cts} +1 -1
  14. package/dist/{EverfurResult-COlXj1wq.d.cts → EverfurResult.d-D_-254ZY.d.ts} +1 -1
  15. package/dist/{IntakeMedia-BH0fYDT2.d.cts → IntakeMedia.d-4a89XrP7.d.ts} +1 -1
  16. package/dist/{IntakeMedia-B-_vA9ZB.d.cts → IntakeMedia.d-DGxrhgIW.d.ts} +1 -1
  17. package/dist/{IntakeMedia-CIoTXAWs.d.ts → IntakeMedia.d-DUPR4lVM.d.cts} +1 -1
  18. package/dist/{IntakeMedia-Bavl7E4Z.d.ts → IntakeMedia.d-JJCUvQu7.d.cts} +1 -1
  19. package/dist/LifecyclePort.d-Cr1p33a7.d.cts +23 -0
  20. package/dist/LifecyclePort.d-Cr1p33a7.d.ts +23 -0
  21. package/dist/{PhotoController-vzY5bfY_.d.ts → PhotoController.d-BzCJOE7e.d.cts} +2 -2
  22. package/dist/{PhotoController-3l7MT9jA.d.cts → PhotoController.d-D0XiUUOl.d.ts} +2 -2
  23. package/dist/animations/index.cjs +4 -1
  24. package/dist/animations/index.d.cts +24 -24
  25. package/dist/animations/index.d.ts +24 -24
  26. package/dist/animations/index.js +4 -1
  27. package/dist/{attachments-DkMrKCIU.d.ts → attachments.d-Bp2qbHxn.d.cts} +22 -26
  28. package/dist/{attachments-CTJK0jQ4.d.ts → attachments.d-D1yhJjcZ.d.ts} +4 -4
  29. package/dist/{attachments-DXBETOrV.d.cts → attachments.d-DisnvB9R.d.cts} +4 -4
  30. package/dist/{attachments-BOk3hEAM.d.cts → attachments.d-Djy9z_0Z.d.ts} +22 -26
  31. package/dist/{bookingCopy-C_a45T4-.d.ts → bookingCopy.d-BJF6gd1A.d.ts} +24 -9
  32. package/dist/{bookingCopy-CHYGYHe0.d.cts → bookingCopy.d-BlBmhAJc.d.cts} +24 -9
  33. package/dist/{branding-DJf4h12Q.d.ts → branding.d-DI8S400y.d.cts} +9 -2
  34. package/dist/{branding-BCfwLj0h.d.cts → branding.d-OIGLbQeM.d.ts} +9 -2
  35. package/dist/{callRoom-BhIdadyV.d.cts → callRoom.d-B1DoYdJe.d.cts} +1 -1
  36. package/dist/{callRoom-B92eH_ij.d.ts → callRoom.d-Dqm1rUqT.d.ts} +1 -1
  37. package/dist/{casesRepository-C8KJmlxE.d.cts → casesRepository.d-CT2LTicS.d.cts} +3 -3
  38. package/dist/{casesRepository-iAi5qWnx.d.ts → casesRepository.d-UsWOz9bv.d.ts} +3 -3
  39. package/dist/chat/index.cjs +131 -57
  40. package/dist/chat/index.d.cts +18 -16
  41. package/dist/chat/index.d.ts +18 -16
  42. package/dist/chat/index.js +132 -58
  43. package/dist/client/index.cjs +14 -10
  44. package/dist/client/index.d.cts +19 -18
  45. package/dist/client/index.d.ts +19 -18
  46. package/dist/client/index.js +14 -10
  47. package/dist/{config-C9zhanL-.d.cts → config.d-BR3DT9ho.d.cts} +3 -3
  48. package/dist/{config-C5iPNKDj.d.ts → config.d-Dy6igYlH.d.ts} +3 -3
  49. package/dist/consent/index.cjs +4 -1
  50. package/dist/consent/index.d.cts +10 -10
  51. package/dist/consent/index.d.ts +10 -10
  52. package/dist/consent/index.js +4 -1
  53. package/dist/{context-BUIrC20Z.d.ts → context.d-Cwks0p3C.d.cts} +15 -15
  54. package/dist/{context-D_bcpHDA.d.cts → context.d-QcCgguzA.d.ts} +15 -15
  55. package/dist/{copy-KbCU9fen.d.ts → copy.d-CiMn2IIt.d.ts} +6 -6
  56. package/dist/{copy-BE31T2jR.d.cts → copy.d-DLJTyRfT.d.cts} +6 -6
  57. package/dist/core/index.cjs +16 -13
  58. package/dist/core/index.d.cts +33 -29
  59. package/dist/core/index.d.ts +33 -29
  60. package/dist/core/index.js +16 -13
  61. package/dist/{depth-DNxDieoO.d.cts → depth.d-CjPGVPDL.d.cts} +9 -115
  62. package/dist/{depth-DDKGfFaB.d.ts → depth.d-OSALbYM7.d.ts} +9 -115
  63. package/dist/{entitlementRepository-C1_wXIE3.d.cts → entitlementRepository.d-CVQa1DA1.d.cts} +10 -5
  64. package/dist/{entitlementRepository-CYtdIGfH.d.ts → entitlementRepository.d-Cf3LbTwD.d.ts} +10 -5
  65. package/dist/features.d-fNsGcg0R.d.cts +108 -0
  66. package/dist/features.d-fNsGcg0R.d.ts +108 -0
  67. package/dist/focus.d-DMg2ngHI.d.ts +1178 -0
  68. package/dist/focus.d-az9cqUz3.d.cts +1178 -0
  69. package/dist/health-plan/index.cjs +370 -0
  70. package/dist/health-plan/index.d.cts +251 -0
  71. package/dist/health-plan/index.d.ts +251 -0
  72. package/dist/health-plan/index.js +370 -0
  73. package/dist/idempotency.d-D461_DPD.d.cts +910 -0
  74. package/dist/idempotency.d-WpXx9zQo.d.ts +910 -0
  75. package/dist/{identity-BqeaN8An.d.ts → identity.d-60LeJt_s.d.cts} +3 -3
  76. package/dist/{identity-gjurBi7m.d.cts → identity.d-DzTijonw.d.ts} +3 -3
  77. package/dist/index.cjs +140 -66
  78. package/dist/index.d.cts +31 -29
  79. package/dist/index.d.ts +31 -29
  80. package/dist/index.js +141 -67
  81. package/dist/{models-A4A5S7AG.d.cts → models.d-BagXhafD.d.ts} +8 -3
  82. package/dist/{models-CnXY5LuO.d.ts → models.d-BnLm3VAA.d.cts} +8 -3
  83. package/dist/notifications/index.cjs +4 -1
  84. package/dist/notifications/index.d.cts +9 -9
  85. package/dist/notifications/index.d.ts +9 -9
  86. package/dist/notifications/index.js +4 -1
  87. package/dist/optInView.d-CEyHR6PK.d.cts +325 -0
  88. package/dist/optInView.d-acKpV8V2.d.ts +325 -0
  89. package/dist/parse.d-C8CXyS58.d.ts +210 -0
  90. package/dist/parse.d-tEzufgJX.d.cts +210 -0
  91. package/dist/{pets-CfutxNs9.d.cts → pets.d-C_53_fzo.d.ts} +3 -3
  92. package/dist/{pets-LIGadUtr.d.ts → pets.d-NbJvP_kh.d.cts} +3 -3
  93. package/dist/{petsRepository-Cqpd3hLU.d.cts → petsRepository.d-BuGHymNx.d.ts} +4 -4
  94. package/dist/{petsRepository-CoRa3C_U.d.ts → petsRepository.d-lp1BHRqM.d.cts} +4 -4
  95. package/dist/photo/index.cjs +5 -2
  96. package/dist/photo/index.d.cts +9 -9
  97. package/dist/photo/index.d.ts +9 -9
  98. package/dist/photo/index.js +5 -2
  99. package/dist/{ports-BN6RHF9W.d.cts → ports.d-BX4f4UsB.d.cts} +14 -1
  100. package/dist/{ports-BN6RHF9W.d.ts → ports.d-BX4f4UsB.d.ts} +14 -1
  101. package/dist/{ports-gJ3faaWz.d.cts → ports.d-CEROoqnA.d.cts} +16 -10
  102. package/dist/{ports-CVi3n0re.d.ts → ports.d-COIyN624.d.ts} +16 -10
  103. package/dist/presentation.d-DMbdad7G.d.cts +90 -0
  104. package/dist/presentation.d-DMbdad7G.d.ts +90 -0
  105. package/dist/records/depth/index.cjs +10 -7
  106. package/dist/records/depth/index.d.cts +14 -12
  107. package/dist/records/depth/index.d.ts +14 -12
  108. package/dist/records/depth/index.js +10 -7
  109. package/dist/records/index.cjs +224 -62
  110. package/dist/records/index.d.cts +159 -20
  111. package/dist/records/index.d.ts +159 -20
  112. package/dist/records/index.js +224 -62
  113. package/dist/recordsAsk.d-C5CGSi3j.d.cts +14 -0
  114. package/dist/recordsAsk.d-C5CGSi3j.d.ts +14 -0
  115. package/dist/{requestFunnel-BYzlyaC0.d.ts → requestFunnel.d-CXUMPw1K.d.ts} +5 -5
  116. package/dist/{requestFunnel-DLZpiFD3.d.cts → requestFunnel.d-DWQQpjFR.d.cts} +5 -5
  117. package/dist/{resolve-D4Ywz5OS.d.ts → resolve.d-jI8FmBj3.d.cts} +3 -3
  118. package/dist/{resolve-D4Ywz5OS.d.cts → resolve.d-jI8FmBj3.d.ts} +3 -3
  119. package/dist/{runtimeTypes-BxxCKMn8.d.cts → runtimeTypes.d-4yFNNuYR.d.ts} +20 -13
  120. package/dist/{runtimeTypes-Doa_xxSa.d.ts → runtimeTypes.d-D6N_fhxx.d.cts} +20 -13
  121. package/dist/server/events/index.cjs +6 -3
  122. package/dist/server/events/index.d.cts +51 -9
  123. package/dist/server/events/index.d.ts +51 -9
  124. package/dist/server/events/index.js +6 -3
  125. package/dist/server/index.cjs +11 -6
  126. package/dist/server/index.d.cts +152 -8
  127. package/dist/server/index.d.ts +152 -8
  128. package/dist/server/index.js +11 -6
  129. package/dist/sheetCopy.d-CAhLOxjc.d.cts +4 -0
  130. package/dist/sheetCopy.d-CAhLOxjc.d.ts +4 -0
  131. package/dist/sheetSeam.d-Cviqk89n.d.ts +45 -0
  132. package/dist/sheetSeam.d-DCS3LW8g.d.cts +45 -0
  133. package/dist/shop/index.cjs +262 -0
  134. package/dist/shop/index.d.cts +193 -0
  135. package/dist/shop/index.d.ts +193 -0
  136. package/dist/shop/index.js +262 -0
  137. package/dist/televet/booking/index.cjs +15 -12
  138. package/dist/televet/booking/index.d.cts +36 -22
  139. package/dist/televet/booking/index.d.ts +36 -22
  140. package/dist/televet/booking/index.js +15 -12
  141. package/dist/televet/call/index.d.cts +5 -5
  142. package/dist/televet/call/index.d.ts +5 -5
  143. package/dist/televet/index.cjs +6 -3
  144. package/dist/televet/index.d.cts +12 -12
  145. package/dist/televet/index.d.ts +12 -12
  146. package/dist/televet/index.js +6 -3
  147. package/dist/{televetGlobal-C5dTUACe.d.cts → televetGlobal.d-CC-DrqkQ.d.ts} +7 -2
  148. package/dist/{televetGlobal-CnjrfhT4.d.ts → televetGlobal.d-CKwDCbmN.d.cts} +7 -2
  149. package/dist/testing/index.cjs +6 -3
  150. package/dist/testing/index.d.cts +3 -3
  151. package/dist/testing/index.d.ts +3 -3
  152. package/dist/testing/index.js +6 -3
  153. package/dist/testing/rn/index.cjs +4 -1
  154. package/dist/testing/rn/index.d.cts +23 -22
  155. package/dist/testing/rn/index.d.ts +23 -22
  156. package/dist/testing/rn/index.js +4 -1
  157. package/dist/testing/web/index.cjs +4 -1
  158. package/dist/testing/web/index.d.cts +23 -22
  159. package/dist/testing/web/index.d.ts +23 -22
  160. package/dist/testing/web/index.js +4 -1
  161. package/dist/texting/index.cjs +158 -0
  162. package/dist/texting/index.d.cts +36 -0
  163. package/dist/texting/index.d.ts +36 -0
  164. package/dist/texting/index.js +158 -0
  165. package/dist/threadOptions.d-B1pTMmDF.d.cts +260 -0
  166. package/dist/threadOptions.d-B1pTMmDF.d.ts +260 -0
  167. package/dist/{timelineRows-CGOlC_Q9.d.ts → timelineRows.d-BNxgzYRW.d.cts} +1 -1
  168. package/dist/{timelineRows-Beun96e2.d.cts → timelineRows.d-CU5GvvLk.d.ts} +1 -1
  169. package/dist/{tokens-DLj8OnLH.d.cts → tokens.d-DarDaV39.d.cts} +10 -2
  170. package/dist/{tokens-DLj8OnLH.d.ts → tokens.d-DarDaV39.d.ts} +10 -2
  171. package/dist/{typeStyle-BxVyF71R.d.ts → typeStyle.d-Bl8pzbBy.d.cts} +2 -2
  172. package/dist/{typeStyle-DJedEu14.d.cts → typeStyle.d-C1HBRAI3.d.ts} +2 -2
  173. package/dist/{uploadTransport-C6kGP1Kd.d.ts → uploadTransport.d-CWL7CdWP.d.cts} +1 -1
  174. package/dist/{uploadTransport-BM_pnEWj.d.cts → uploadTransport.d-EGoUl7gX.d.ts} +1 -1
  175. package/dist/usePresentation.d-D6qsFzBz.d.cts +9 -0
  176. package/dist/usePresentation.d-DuGQe_Do.d.ts +9 -0
  177. package/dist/useRecords.d-Cb-36SF5.d.cts +121 -0
  178. package/dist/useRecords.d-aQTzQZoV.d.ts +121 -0
  179. package/dist/{useRecordsDepth-hR94debv.d.ts → useRecordsDepth.d-DFcCfiXm.d.ts} +8 -20
  180. package/dist/{useRecordsDepth-DRrJntjt.d.cts → useRecordsDepth.d-sAq2Qkhr.d.cts} +8 -20
  181. package/dist/{useVetVisit-DmWa7lt1.d.ts → useVetVisit.d-BtdwhmgD.d.cts} +15 -4
  182. package/dist/{useVetVisit-PtBjNwZr.d.cts → useVetVisit.d-DoYQimyt.d.ts} +15 -4
  183. package/dist/video/index.cjs +5 -2
  184. package/dist/video/index.d.cts +7 -7
  185. package/dist/video/index.d.ts +7 -7
  186. package/dist/video/index.js +5 -2
  187. package/dist/{view-C_B5U04g.d.ts → view.d-C-SNpDJX.d.ts} +10 -122
  188. package/dist/{view-VvLEdXP4.d.cts → view.d-Dps5C8-s.d.cts} +10 -122
  189. package/dist/web/consent/index.cjs +4 -1
  190. package/dist/web/consent/index.d.cts +10 -10
  191. package/dist/web/consent/index.d.ts +10 -10
  192. package/dist/web/consent/index.js +4 -1
  193. package/dist/web/health-plan/index.cjs +414 -0
  194. package/dist/web/health-plan/index.d.cts +335 -0
  195. package/dist/web/health-plan/index.d.ts +335 -0
  196. package/dist/web/health-plan/index.js +414 -0
  197. package/dist/web/index.cjs +149 -82
  198. package/dist/web/index.d.cts +152 -38
  199. package/dist/web/index.d.ts +152 -38
  200. package/dist/web/index.js +149 -82
  201. package/dist/web/notifications/index.cjs +15 -3
  202. package/dist/web/notifications/index.d.cts +39 -209
  203. package/dist/web/notifications/index.d.ts +39 -209
  204. package/dist/web/notifications/index.js +15 -3
  205. package/dist/web/records/depth/index.cjs +10 -7
  206. package/dist/web/records/depth/index.d.cts +14 -12
  207. package/dist/web/records/depth/index.d.ts +14 -12
  208. package/dist/web/records/depth/index.js +10 -7
  209. package/dist/web/records/index.cjs +94 -68
  210. package/dist/web/records/index.d.cts +66 -21
  211. package/dist/web/records/index.d.ts +66 -21
  212. package/dist/web/records/index.js +94 -68
  213. package/dist/web/records/upload/index.d.cts +2 -2
  214. package/dist/web/records/upload/index.d.ts +2 -2
  215. package/dist/web/records-sheet/index.cjs +278 -0
  216. package/dist/web/records-sheet/index.d.cts +102 -0
  217. package/dist/web/records-sheet/index.d.ts +102 -0
  218. package/dist/web/records-sheet/index.js +278 -0
  219. package/dist/web/shop/index.cjs +301 -0
  220. package/dist/web/shop/index.d.cts +42 -0
  221. package/dist/web/shop/index.d.ts +42 -0
  222. package/dist/web/shop/index.js +301 -0
  223. package/dist/web/televet/booking/index.cjs +15 -12
  224. package/dist/web/televet/booking/index.d.cts +37 -23
  225. package/dist/web/televet/booking/index.d.ts +37 -23
  226. package/dist/web/televet/booking/index.js +15 -12
  227. package/dist/web/televet/call/index.d.cts +4 -4
  228. package/dist/web/televet/call/index.d.ts +4 -4
  229. package/dist/web/televet/index.cjs +6 -3
  230. package/dist/web/televet/index.d.cts +12 -12
  231. package/dist/web/televet/index.d.ts +12 -12
  232. package/dist/web/televet/index.js +6 -3
  233. package/dist/web/texting/index.cjs +157 -0
  234. package/dist/web/texting/index.d.cts +36 -0
  235. package/dist/web/texting/index.d.ts +36 -0
  236. package/dist/web/texting/index.js +157 -0
  237. package/health-plan/package.json +8 -0
  238. package/package.json +106 -4
  239. package/shop/package.json +8 -0
  240. package/texting/package.json +8 -0
  241. package/web/health-plan/native-blocked.cjs +12 -0
  242. package/web/health-plan/package.json +8 -0
  243. package/web/records-sheet/native-blocked.cjs +12 -0
  244. package/web/records-sheet/package.json +8 -0
  245. package/web/shop/native-blocked.cjs +12 -0
  246. package/web/shop/package.json +8 -0
  247. package/web/texting/native-blocked.cjs +12 -0
  248. package/web/texting/package.json +8 -0
  249. /package/dist/{CameraPort-Cv31Pz7g.d.cts → CameraPort.d-Cv31Pz7g.d.cts} +0 -0
  250. /package/dist/{CameraPort-Cv31Pz7g.d.ts → CameraPort.d-Cv31Pz7g.d.ts} +0 -0
  251. /package/dist/{TelemetryPort-BDNr00hu.d.cts → TelemetryPort.d-BDNr00hu.d.cts} +0 -0
  252. /package/dist/{TelemetryPort-BDNr00hu.d.ts → TelemetryPort.d-BDNr00hu.d.ts} +0 -0
  253. /package/dist/{cacheEpoch-DknKn3S0.d.cts → cacheEpoch.d-DknKn3S0.d.cts} +0 -0
  254. /package/dist/{cacheEpoch-DknKn3S0.d.ts → cacheEpoch.d-DknKn3S0.d.ts} +0 -0
  255. /package/dist/{callCopy-Bw6oZT54.d.cts → callCopy.d-Bw6oZT54.d.cts} +0 -0
  256. /package/dist/{callCopy-Bw6oZT54.d.ts → callCopy.d-Bw6oZT54.d.ts} +0 -0
  257. /package/dist/{ids-B2GAAifq.d.cts → ids.d-B2GAAifq.d.cts} +0 -0
  258. /package/dist/{ids-B2GAAifq.d.ts → ids.d-B2GAAifq.d.ts} +0 -0
  259. /package/dist/{optionalModule-DbJmsq5f.d.cts → optionalModule.d-DbJmsq5f.d.cts} +0 -0
  260. /package/dist/{optionalModule-DbJmsq5f.d.ts → optionalModule.d-DbJmsq5f.d.ts} +0 -0
  261. /package/dist/{profile-CSs1wlXT.d.cts → profile.d-CSs1wlXT.d.cts} +0 -0
  262. /package/dist/{profile-CSs1wlXT.d.ts → profile.d-CSs1wlXT.d.ts} +0 -0
  263. /package/dist/{projection-CeIUsbSk.d.cts → projection.d-CeIUsbSk.d.cts} +0 -0
  264. /package/dist/{projection-CeIUsbSk.d.ts → projection.d-CeIUsbSk.d.ts} +0 -0
  265. /package/dist/{species-BXAIMh7I.d.cts → species.d-BXAIMh7I.d.cts} +0 -0
  266. /package/dist/{species-BXAIMh7I.d.ts → species.d-BXAIMh7I.d.ts} +0 -0
  267. /package/dist/{visitIntent-D7_yVp1I.d.cts → visitIntent.d-D7_yVp1I.d.cts} +0 -0
  268. /package/dist/{visitIntent-D7_yVp1I.d.ts → visitIntent.d-D7_yVp1I.d.ts} +0 -0
@@ -0,0 +1,325 @@
1
+ import { E as EverfurError } from './EverfurError.d-8NHtlgzA.cjs';
2
+ import { E as EverfurResult } from './EverfurResult.d-BFH-3s6E.cjs';
3
+ import { R as RequestFunnel } from './requestFunnel.d-DWQQpjFR.cjs';
4
+ import { A as AuthContext } from './identity.d-60LeJt_s.cjs';
5
+ import { P as PetRef, U as UserRef } from './ids.d-B2GAAifq.cjs';
6
+ import { E as ErrorPolicyPort } from './ErrorPolicyPort.d-DirW9hgO.cjs';
7
+
8
+ /** The marker a placeholder string carries, so a test (and a reviewer) can find every one. */
9
+ declare const COPY_PLACEHOLDER_PREFIX = "[copy needed: ";
10
+ declare const TEXTING_COPY: Readonly<{
11
+ loading: "Loading";
12
+ retry: "Try again";
13
+ signedOut: "Sign in required";
14
+ phoneLabel: "Mobile number";
15
+ phoneHint: "We'll text a 6-digit code to confirm it's you.";
16
+ phoneInvalid: "That doesn't look like a valid number. Check it and the country, then try again.";
17
+ consentRequired: "Please agree to receive SMS messages to continue.";
18
+ sendCode: "Send code";
19
+ sendingCode: "Sending code";
20
+ codeTitle: "Enter your code";
21
+ /** Followed by the number, which is data, not copy. */
22
+ codeSentTo: "We texted a 6-digit code to";
23
+ codeLabel: "6-digit code";
24
+ codeInvalidFormat: "Enter all 6 digits of the code.";
25
+ confirmCode: "Verify";
26
+ confirmingCode: "Verifying";
27
+ verificationInvalid: "That code is no longer valid. Request a new one.";
28
+ /** everfur-frontend app/product/sms-chat/copy.ts:73, for a code refused after its `expires_at`. */
29
+ codeExpired: "This code has expired. Request a new one.";
30
+ requestNewCode: "Request a new code";
31
+ /** everfur-frontend app/product/sms-chat/copy.ts:74, for 429 `verification_phone_limit` (this number's daily codes). */
32
+ noResendsLeft: "You've requested the maximum number of codes. Please try again later or contact support.";
33
+ changeNumber: "Use a different number";
34
+ defaultPetLabel: "Default pet for SMS";
35
+ noPetSelected: "Choose a pet";
36
+ savePet: "Save";
37
+ savingPet: "Saving";
38
+ petSaved: "Saved";
39
+ petIneligible: "That pet can't be selected anymore. Please choose another.";
40
+ optedOutTitle: "SMS paused";
41
+ verifiedTitle: "SMS Chat is on";
42
+ disable: "Turn off SMS Chat";
43
+ disabling: "Turning off";
44
+ disableConfirmTitle: "Turn off SMS Chat?";
45
+ disableConfirmBody: "We'll stop texting this number. You can turn it back on anytime.";
46
+ disableConfirm: "Turn off";
47
+ disableCancel: "Keep it on";
48
+ unavailableTitle: "SMS Chat isn't available yet";
49
+ unavailableBody: "We're still setting it up. Check back soon.";
50
+ phoneAlreadyLinked: "This number is already linked to another Everfur account. Contact support and we'll move it for you.";
51
+ providerFailed: "We couldn't send the text. Please try again.";
52
+ genericFailure: "That didn't go through. Please try again.";
53
+ /** Followed by the request id, for a support conversation. */
54
+ supportReference: "Support reference:";
55
+ /**
56
+ * 403 `phone_country_not_allowed`, a valid number from a country the tenant does not text. The consumer screen
57
+ * refuses a valid number whose own country is outside its list (everfur-frontend app/product/sms-chat/phone.ts:36)
58
+ * with this line (`phoneInvalid`, copy.ts:60, via SmsChatEnrollment.tsx:78-80), which points at the country.
59
+ */
60
+ phoneCountryNotAllowed: "That doesn't look like a valid number. Check it and the country, then try again.";
61
+ /**
62
+ * 429 `verification_tenant_limit`, the tenant's hourly ceiling on codes: not the member's doing, and it clears.
63
+ * everfur-frontend app/product/sms-chat/copy.ts:109 `temporarilyUnavailable` (everfur-mobile copy.ts:108).
64
+ */
65
+ verificationBusy: "SMS Chat is temporarily unavailable. Please try again in a few minutes.";
66
+ /**
67
+ * The label in front of the tenant profile's help contact, so the line reads "Help: hello@everfur.com" exactly as
68
+ * the owner-approved HELP reply does (EFBackend sms_chat_reply_copy.py:262 and :276, and the partner default
69
+ * partner_sms_profile.py:101).
70
+ */
71
+ helpContactLabel: "Help:";
72
+ /**
73
+ * The button that starts a new opt-in after a member opted out. The consumer's own "start SMS Chat" control:
74
+ * everfur-frontend copy.ts:118 `promptAccept`, the /sms page call to action (SmsOptInPage.tsx:75), everfur-mobile
75
+ * copy.ts:121.
76
+ */
77
+ reenroll: "Turn on SMS Chat";
78
+ /**
79
+ * The opted-out body for a member who turned texts off in the app (not by texting STOP, which keeps the brand STOP
80
+ * line). The consumer's approved words for that same choice: everfur-frontend copy.ts:98 `disableConfirmBody`
81
+ * (everfur-mobile copy.ts:102).
82
+ */
83
+ optedOutByMemberBody: "We'll stop texting this number. You can turn it back on anytime.";
84
+ codeWrong: "That code didn't work. Check it and try again.";
85
+ }>;
86
+ /** ADAPTED from the consumer deck: "Everfur" becomes the tenant's brand name. Listed for approval. */
87
+ declare const TEXTING_BRAND_COPY: Readonly<{
88
+ /** consumer `introTitle`: 'Chat with Everfur by text' */
89
+ introTitle: (brand: string) => string;
90
+ /** consumer `introBody` */
91
+ introBody: (brand: string) => string;
92
+ /** consumer `statusActive`: 'You can text Everfur anytime from this number.' */
93
+ statusActive: (brand: string) => string;
94
+ /** consumer `optedOutBody` */
95
+ optedOutBody: (brand: string) => string;
96
+ }>;
97
+ /** Every placeholder key in `TEXTING_COPY`, so the list a reviewer approves cannot drift from the file. */
98
+ declare const TEXTING_COPY_PLACEHOLDERS: readonly (keyof typeof TEXTING_COPY)[];
99
+ /** Every string the texting opt-in shows that a partner may reword (`EverfurTextingOptIn copy=`). */
100
+ type TextingCopy = {
101
+ readonly [K in keyof typeof TEXTING_COPY]: string;
102
+ };
103
+ /** The brand-named lines (`EverfurTextingOptIn brandCopy=`): each takes the tenant's brand name. */
104
+ type TextingBrandCopy = {
105
+ readonly [K in keyof typeof TEXTING_BRAND_COPY]: (brand: string) => string;
106
+ };
107
+
108
+ /** The tenant's public texting profile, exactly as the console published it. */
109
+ interface EverfurTextingProfile {
110
+ /** The name the texts, the consent words and the STOP/HELP replies use. */
111
+ readonly brandName: string;
112
+ /** The consent words the member ticks, verbatim. The server stores a digest of exactly these words. */
113
+ readonly consentText: string;
114
+ /** The version of `consentText`; sent back with the verification so the grant names what the member saw. */
115
+ readonly consentVersion: string;
116
+ /** Where a member gets help (a phone, an address or a URL as the tenant set it), or null. */
117
+ readonly helpContact: string | null;
118
+ /**
119
+ * EFBackend's `status_is_live`. There is no tester-only stage any more: a draft or live tenant admits every member,
120
+ * and only a tenant staff suspended refuses each number with `sms_not_live`, which the surface words as SMS Chat
121
+ * not being available. The surface draws no banner of its own for this flag.
122
+ */
123
+ readonly isLive: boolean;
124
+ }
125
+ /**
126
+ * Parse an untrusted `sms_profile_public` blob. Null when it is absent or carries no brand, consent words or
127
+ * consent version (the three things an opt-in cannot do without). `status_is_live` reads true only for the
128
+ * literal `true`: a missing flag is the not-live side, which refuses more, never less. Never throws.
129
+ */
130
+ declare function parseTextingProfile(raw: unknown): EverfurTextingProfile | null;
131
+ /**
132
+ * A +1 (United States or Canada) number as E.164, or null. Takes what a member types: `(415) 555-0134`,
133
+ * `415.555.0134`, `1 415 555 0134` or `+1 415 555 0134`. A North American number is ten digits whose area code and
134
+ * exchange both start 2 to 9; anything else (another country code, too few digits, letters) is null, so the
135
+ * surface refuses it before the wire instead of spending a verification on it.
136
+ */
137
+ declare function toTextingE164(input: string): string | null;
138
+ /** True for a string already in E.164 form (`+` and 8 to 15 digits). */
139
+ declare function isE164(value: unknown): value is string;
140
+
141
+ /** The identity states the server reports. An unknown value reads as `none`: nothing on record we can explain. */
142
+ declare const EVERFUR_TEXTING_STATUSES: readonly ["none", "pending", "verified", "opted_out"];
143
+ type EverfurTextingStatus = (typeof EVERFUR_TEXTING_STATUSES)[number];
144
+ /** The member's texting identity. The raw number never comes back; `phoneMasked` is what Everfur shows anywhere. */
145
+ interface EverfurTextingIdentity {
146
+ readonly status: EverfurTextingStatus;
147
+ readonly phoneMasked: string | null;
148
+ /** The consent version on record, or null. */
149
+ readonly consentVersion: string | null;
150
+ /** The pet texts are about, or null when none is chosen. */
151
+ readonly selectedPetRef: PetRef | null;
152
+ }
153
+ /** An outstanding code, as the server issued it. */
154
+ interface EverfurTextingChallenge {
155
+ readonly challengeId: string;
156
+ /** ISO 8601, or null when the server did not say. */
157
+ readonly expiresAt: string | null;
158
+ /**
159
+ * How many wrong codes the server still accepts for this challenge, as it said when it issued the code
160
+ * (`attempts_remaining`), or null when it did not say. The controller counts it down on each refused code.
161
+ */
162
+ readonly attemptsRemaining: number | null;
163
+ }
164
+ interface EverfurTextingVerificationInput {
165
+ /** E.164 (`+14155550134`). `toTextingE164` turns what a member typed into this. */
166
+ readonly phoneE164: string;
167
+ /** The tenant profile's `consentVersion`: the words the member ticked. The server refuses any other. */
168
+ readonly consentVersion: string;
169
+ }
170
+ /** A code is digits only; the consumer screen asks for six. */
171
+ declare const TEXTING_CODE_PATTERN: RegExp;
172
+ interface TextingRepository {
173
+ /** `GET /widget/v1/me/sms-identity`. Settles; never throws. */
174
+ read(opts?: {
175
+ readonly signal?: AbortSignal;
176
+ }): Promise<EverfurResult<EverfurTextingIdentity>>;
177
+ /** `POST .../verification`: text a code to the number. Sent once, never replayed. */
178
+ startVerification(input: EverfurTextingVerificationInput): Promise<EverfurResult<EverfurTextingChallenge>>;
179
+ /** `POST .../verification/confirm`: spend the code. Sent once, never replayed. */
180
+ confirmVerification(challengeId: string, code: string): Promise<EverfurResult<EverfurTextingIdentity>>;
181
+ /** `PUT .../selected-pet`: the pet texts are about. */
182
+ selectPet(petRef: PetRef): Promise<EverfurResult<EverfurTextingIdentity>>;
183
+ /** `DELETE /widget/v1/me/sms-identity`: withdraw consent and stop texts. As available as opting in. */
184
+ optOut(): Promise<EverfurResult<EverfurTextingIdentity>>;
185
+ }
186
+ /** The part of the runtime this repository needs (`useEverfurContext().runtime` satisfies it). */
187
+ interface TextingRuntime {
188
+ readonly isDisposed: boolean;
189
+ readonly registry: {
190
+ readonly services: {
191
+ authFor(userRef: UserRef | null): AuthContext;
192
+ readonly errorPolicy: ErrorPolicyPort | undefined;
193
+ };
194
+ };
195
+ }
196
+ /** The lower seam: one auth context, or an already-built funnel (tests). */
197
+ interface TextingRepositoryDeps {
198
+ readonly auth: AuthContext;
199
+ readonly errorPolicy?: ErrorPolicyPort;
200
+ readonly funnel?: RequestFunnel;
201
+ }
202
+ /** The reason codes a surface branches on, by meaning. Read with `textingReasonOf`. */
203
+ type EverfurTextingReason = 'not_live' | 'code_invalid' | 'phone_linked' | 'pet_ineligible' | 'no_identity' | 'consent_changed' | 'session_required' | 'country_not_allowed' | 'phone_code_limit' | 'tenant_code_limit';
204
+ /** Which texting refusal an error is, or null for any other failure. */
205
+ declare function textingReasonOf(error: EverfurError | null | undefined): EverfurTextingReason | null;
206
+ /** The allowlist mapper for one identity body. `status` is REQUIRED: a body without one is not an identity. */
207
+ declare function textingIdentityFromWire(raw: unknown): EverfurTextingIdentity | null;
208
+ /** The repository over the runtime under your provider. Auth is read at CALL time; a disposed runtime sends nothing. */
209
+ declare function createTextingRepository(runtime: TextingRuntime): TextingRepository;
210
+ /** The same repository over one auth context (or an injected funnel). Internal seam, for deterministic tests. */
211
+ declare function createTextingRepositoryOver(deps: TextingRepositoryDeps): TextingRepository;
212
+
213
+ type TextingPhase = 'loading' | 'failed' | 'enroll' | 'requesting' | 'code' | 'confirming' | 'verified' | 'optingOut' | 'optedOut';
214
+ /** What a refused code most likely was. See the header. */
215
+ type TextingCodeRefusal = 'wrong' | 'expired' | 'spent';
216
+ /** Which verb a refusal belongs to, so a surface retries the right thing. */
217
+ type TextingAction = 'read' | 'start' | 'confirm' | 'selectPet' | 'optOut';
218
+ interface TextingSnapshot {
219
+ readonly phase: TextingPhase;
220
+ /** The identity as the server last reported it, or null before the first read. */
221
+ readonly identity: EverfurTextingIdentity | null;
222
+ /** The outstanding code, while one is out. */
223
+ readonly challenge: EverfurTextingChallenge | null;
224
+ /** The number the current code went to (what the member typed, as E.164), for "request a new code". */
225
+ readonly phoneE164: string | null;
226
+ /** The last refusal, or null. `error.displayMessage` is safe to show. */
227
+ readonly error: EverfurError | null;
228
+ readonly failedAction: TextingAction | null;
229
+ /** For a refused code (`failedAction` 'confirm'), what it most likely was; null otherwise. */
230
+ readonly codeRefusal: TextingCodeRefusal | null;
231
+ /** True while a pet choice is being saved. */
232
+ readonly savingPet: boolean;
233
+ /**
234
+ * True while `requesting` is a new code for the code step ("Request a new code"), so a surface keeps the code step
235
+ * on screen with its link busy instead of flipping back to the number (audit 2026-10-20). False for a first send.
236
+ */
237
+ readonly resending: boolean;
238
+ }
239
+ declare class TextingController {
240
+ private readonly repository;
241
+ private readonly now;
242
+ private snapshot;
243
+ private readonly listeners;
244
+ /** Bumped by every step change; a settlement for an older generation is dropped. */
245
+ private generation;
246
+ private consentVersion;
247
+ private disposed;
248
+ /** `now` is the clock a refused code is judged against (epoch ms); tests pass their own. */
249
+ constructor(repository: TextingRepository, now?: () => number);
250
+ readonly subscribe: (listener: () => void) => (() => void);
251
+ readonly getSnapshot: () => TextingSnapshot;
252
+ private set;
253
+ /** Read the member's identity (the first load, and the way out of `failed`). */
254
+ load(): Promise<void>;
255
+ /** Text a code to `phoneE164` for the consent words of `consentVersion`. */
256
+ start(phoneE164: string, consentVersion: string): Promise<boolean>;
257
+ /** Text a new code to the same number. */
258
+ resend(): Promise<boolean>;
259
+ /** Check the code the member typed. */
260
+ confirm(code: string): Promise<boolean>;
261
+ /** Back to the number step ("use a different number"); any code in flight is abandoned. */
262
+ changeNumber(): void;
263
+ /** From `optedOut`, start a new opt-in. Withdrawing never locks a member out of coming back. */
264
+ reenroll(): void;
265
+ /** Choose the pet texts are about. The step does not change; only `savingPet` and the identity do. */
266
+ selectPet(petRef: PetRef): Promise<boolean>;
267
+ /** Withdraw consent and stop texts. */
268
+ optOut(): Promise<boolean>;
269
+ /** Stop notifying; any settlement after this is dropped. */
270
+ dispose(): void;
271
+ }
272
+
273
+ type EverfurTextingViewStatus = 'signedOut' | 'unavailable' | TextingSnapshot['phase'];
274
+ interface EverfurTextingState {
275
+ readonly status: EverfurTextingViewStatus;
276
+ /** The tenant's public texting profile, or null when it has none. */
277
+ readonly profile: EverfurTextingProfile | null;
278
+ /** The controller's snapshot (identity, outstanding code, last refusal). */
279
+ readonly snapshot: TextingSnapshot;
280
+ /** Text a code to what the member typed. Refuses (settles false) for a number `validateTextingPhone` rejects. */
281
+ start(phone: string): Promise<boolean>;
282
+ resend(): Promise<boolean>;
283
+ confirm(code: string): Promise<boolean>;
284
+ changeNumber(): void;
285
+ reenroll(): void;
286
+ selectPet(petRef: PetRef): Promise<boolean>;
287
+ optOut(): Promise<boolean>;
288
+ /** Read the identity again (the way out of `failed`). */
289
+ refresh(): Promise<void>;
290
+ }
291
+ /** Why a member's input is not ready to send, or null when it is. */
292
+ type EverfurTextingInputProblem = 'phoneInvalid' | 'consentRequired' | 'codeInvalidFormat';
293
+ /** The opt-in's pre-flight: a +1 number and a ticked consent box, before any request is spent. */
294
+ declare function validateTextingEnroll(phone: string, consented: boolean): EverfurTextingInputProblem | null;
295
+ /** The surface asks for six digits, as the consumer screen does. */
296
+ declare const TEXTING_UI_CODE_LENGTH = 6;
297
+ declare function validateTextingCode(code: string): EverfurTextingInputProblem | null;
298
+ /** The tenant's parsed texting profile, or null. Re-parses only when the verdict carries a new blob. */
299
+ declare function useEverfurTextingProfile(): EverfurTextingProfile | null;
300
+ /** The texting repository bound to the runtime under your provider, for a partner's own UI. */
301
+ declare function useEverfurTextingRepository(): TextingRepository;
302
+ /** The member's texting opt-in, step by step. `EverfurTextingOptIn` renders it on either host. */
303
+ declare function useEverfurTexting(): EverfurTextingState;
304
+
305
+ /**
306
+ * The line for a refused step. The consumer deck's own words per refusal; never the raw server message. For a refused
307
+ * code, pass the snapshot's `codeRefusal` so a typo, an expired code and a used-up code read differently; without it
308
+ * (or when the controller could not tell) the line is the deck's generic "request a new one".
309
+ */
310
+ declare function textingErrorText(error: EverfurError, action: TextingAction | null, codeRefusal?: TextingCodeRefusal | null, copy?: TextingCopy): string;
311
+ /** The support line under a refusal, when the server named the request. Null otherwise. */
312
+ declare function textingSupportText(error: EverfurError, copy?: TextingCopy): string | null;
313
+ /** The line for input the surface refused before any request. */
314
+ declare function textingInputProblemText(problem: EverfurTextingInputProblem, copy?: TextingCopy): string;
315
+ /**
316
+ * The opted-out body: the brand STOP line for a member who texted STOP, the consumer's turn-off line for one who
317
+ * turned texts off in the app. The server tells them apart without a field of its own: an in-app turn-off revokes the
318
+ * identity, so `opted_out` comes back with no number (and the SDK's own turn-off settles to that shape), while a STOP
319
+ * keeps the live identity and its masked number (EFBackend partner_sms_identity.py `partner_status`).
320
+ */
321
+ declare function textingOptedOutBody(identity: EverfurTextingIdentity | null, brand: string, copy?: TextingCopy, brandCopy?: TextingBrandCopy): string;
322
+ /** A +1 E.164 number as a member reads it: `+14155550134` becomes `(415) 555-0134`. Anything else is unchanged. */
323
+ declare function formatTextingPhone(e164: string | null): string;
324
+
325
+ export { isE164 as A, parseTextingProfile as B, COPY_PLACEHOLDER_PREFIX as C, textingErrorText as D, type EverfurTextingViewStatus as E, textingIdentityFromWire as F, textingInputProblemText as G, textingOptedOutBody as H, textingReasonOf as I, textingSupportText as J, toTextingE164 as K, useEverfurTexting as L, useEverfurTextingProfile as M, useEverfurTextingRepository as N, validateTextingCode as O, validateTextingEnroll as P, type TextingCopy as T, type TextingBrandCopy as a, EVERFUR_TEXTING_STATUSES as b, type EverfurTextingChallenge as c, type EverfurTextingIdentity as d, type EverfurTextingInputProblem as e, type EverfurTextingProfile as f, type EverfurTextingReason as g, type EverfurTextingState as h, type EverfurTextingStatus as i, type EverfurTextingVerificationInput as j, TEXTING_BRAND_COPY as k, TEXTING_CODE_PATTERN as l, TEXTING_COPY as m, TEXTING_COPY_PLACEHOLDERS as n, TEXTING_UI_CODE_LENGTH as o, type TextingAction as p, type TextingCodeRefusal as q, TextingController as r, type TextingPhase as s, type TextingRepository as t, type TextingRepositoryDeps as u, type TextingRuntime as v, type TextingSnapshot as w, createTextingRepository as x, createTextingRepositoryOver as y, formatTextingPhone as z };
@@ -0,0 +1,325 @@
1
+ import { E as EverfurError } from './EverfurError.d-8NHtlgzA.js';
2
+ import { E as EverfurResult } from './EverfurResult.d-D_-254ZY.js';
3
+ import { R as RequestFunnel } from './requestFunnel.d-CXUMPw1K.js';
4
+ import { A as AuthContext } from './identity.d-DzTijonw.js';
5
+ import { P as PetRef, U as UserRef } from './ids.d-B2GAAifq.js';
6
+ import { E as ErrorPolicyPort } from './ErrorPolicyPort.d-68yrE3BE.js';
7
+
8
+ /** The marker a placeholder string carries, so a test (and a reviewer) can find every one. */
9
+ declare const COPY_PLACEHOLDER_PREFIX = "[copy needed: ";
10
+ declare const TEXTING_COPY: Readonly<{
11
+ loading: "Loading";
12
+ retry: "Try again";
13
+ signedOut: "Sign in required";
14
+ phoneLabel: "Mobile number";
15
+ phoneHint: "We'll text a 6-digit code to confirm it's you.";
16
+ phoneInvalid: "That doesn't look like a valid number. Check it and the country, then try again.";
17
+ consentRequired: "Please agree to receive SMS messages to continue.";
18
+ sendCode: "Send code";
19
+ sendingCode: "Sending code";
20
+ codeTitle: "Enter your code";
21
+ /** Followed by the number, which is data, not copy. */
22
+ codeSentTo: "We texted a 6-digit code to";
23
+ codeLabel: "6-digit code";
24
+ codeInvalidFormat: "Enter all 6 digits of the code.";
25
+ confirmCode: "Verify";
26
+ confirmingCode: "Verifying";
27
+ verificationInvalid: "That code is no longer valid. Request a new one.";
28
+ /** everfur-frontend app/product/sms-chat/copy.ts:73, for a code refused after its `expires_at`. */
29
+ codeExpired: "This code has expired. Request a new one.";
30
+ requestNewCode: "Request a new code";
31
+ /** everfur-frontend app/product/sms-chat/copy.ts:74, for 429 `verification_phone_limit` (this number's daily codes). */
32
+ noResendsLeft: "You've requested the maximum number of codes. Please try again later or contact support.";
33
+ changeNumber: "Use a different number";
34
+ defaultPetLabel: "Default pet for SMS";
35
+ noPetSelected: "Choose a pet";
36
+ savePet: "Save";
37
+ savingPet: "Saving";
38
+ petSaved: "Saved";
39
+ petIneligible: "That pet can't be selected anymore. Please choose another.";
40
+ optedOutTitle: "SMS paused";
41
+ verifiedTitle: "SMS Chat is on";
42
+ disable: "Turn off SMS Chat";
43
+ disabling: "Turning off";
44
+ disableConfirmTitle: "Turn off SMS Chat?";
45
+ disableConfirmBody: "We'll stop texting this number. You can turn it back on anytime.";
46
+ disableConfirm: "Turn off";
47
+ disableCancel: "Keep it on";
48
+ unavailableTitle: "SMS Chat isn't available yet";
49
+ unavailableBody: "We're still setting it up. Check back soon.";
50
+ phoneAlreadyLinked: "This number is already linked to another Everfur account. Contact support and we'll move it for you.";
51
+ providerFailed: "We couldn't send the text. Please try again.";
52
+ genericFailure: "That didn't go through. Please try again.";
53
+ /** Followed by the request id, for a support conversation. */
54
+ supportReference: "Support reference:";
55
+ /**
56
+ * 403 `phone_country_not_allowed`, a valid number from a country the tenant does not text. The consumer screen
57
+ * refuses a valid number whose own country is outside its list (everfur-frontend app/product/sms-chat/phone.ts:36)
58
+ * with this line (`phoneInvalid`, copy.ts:60, via SmsChatEnrollment.tsx:78-80), which points at the country.
59
+ */
60
+ phoneCountryNotAllowed: "That doesn't look like a valid number. Check it and the country, then try again.";
61
+ /**
62
+ * 429 `verification_tenant_limit`, the tenant's hourly ceiling on codes: not the member's doing, and it clears.
63
+ * everfur-frontend app/product/sms-chat/copy.ts:109 `temporarilyUnavailable` (everfur-mobile copy.ts:108).
64
+ */
65
+ verificationBusy: "SMS Chat is temporarily unavailable. Please try again in a few minutes.";
66
+ /**
67
+ * The label in front of the tenant profile's help contact, so the line reads "Help: hello@everfur.com" exactly as
68
+ * the owner-approved HELP reply does (EFBackend sms_chat_reply_copy.py:262 and :276, and the partner default
69
+ * partner_sms_profile.py:101).
70
+ */
71
+ helpContactLabel: "Help:";
72
+ /**
73
+ * The button that starts a new opt-in after a member opted out. The consumer's own "start SMS Chat" control:
74
+ * everfur-frontend copy.ts:118 `promptAccept`, the /sms page call to action (SmsOptInPage.tsx:75), everfur-mobile
75
+ * copy.ts:121.
76
+ */
77
+ reenroll: "Turn on SMS Chat";
78
+ /**
79
+ * The opted-out body for a member who turned texts off in the app (not by texting STOP, which keeps the brand STOP
80
+ * line). The consumer's approved words for that same choice: everfur-frontend copy.ts:98 `disableConfirmBody`
81
+ * (everfur-mobile copy.ts:102).
82
+ */
83
+ optedOutByMemberBody: "We'll stop texting this number. You can turn it back on anytime.";
84
+ codeWrong: "That code didn't work. Check it and try again.";
85
+ }>;
86
+ /** ADAPTED from the consumer deck: "Everfur" becomes the tenant's brand name. Listed for approval. */
87
+ declare const TEXTING_BRAND_COPY: Readonly<{
88
+ /** consumer `introTitle`: 'Chat with Everfur by text' */
89
+ introTitle: (brand: string) => string;
90
+ /** consumer `introBody` */
91
+ introBody: (brand: string) => string;
92
+ /** consumer `statusActive`: 'You can text Everfur anytime from this number.' */
93
+ statusActive: (brand: string) => string;
94
+ /** consumer `optedOutBody` */
95
+ optedOutBody: (brand: string) => string;
96
+ }>;
97
+ /** Every placeholder key in `TEXTING_COPY`, so the list a reviewer approves cannot drift from the file. */
98
+ declare const TEXTING_COPY_PLACEHOLDERS: readonly (keyof typeof TEXTING_COPY)[];
99
+ /** Every string the texting opt-in shows that a partner may reword (`EverfurTextingOptIn copy=`). */
100
+ type TextingCopy = {
101
+ readonly [K in keyof typeof TEXTING_COPY]: string;
102
+ };
103
+ /** The brand-named lines (`EverfurTextingOptIn brandCopy=`): each takes the tenant's brand name. */
104
+ type TextingBrandCopy = {
105
+ readonly [K in keyof typeof TEXTING_BRAND_COPY]: (brand: string) => string;
106
+ };
107
+
108
+ /** The tenant's public texting profile, exactly as the console published it. */
109
+ interface EverfurTextingProfile {
110
+ /** The name the texts, the consent words and the STOP/HELP replies use. */
111
+ readonly brandName: string;
112
+ /** The consent words the member ticks, verbatim. The server stores a digest of exactly these words. */
113
+ readonly consentText: string;
114
+ /** The version of `consentText`; sent back with the verification so the grant names what the member saw. */
115
+ readonly consentVersion: string;
116
+ /** Where a member gets help (a phone, an address or a URL as the tenant set it), or null. */
117
+ readonly helpContact: string | null;
118
+ /**
119
+ * EFBackend's `status_is_live`. There is no tester-only stage any more: a draft or live tenant admits every member,
120
+ * and only a tenant staff suspended refuses each number with `sms_not_live`, which the surface words as SMS Chat
121
+ * not being available. The surface draws no banner of its own for this flag.
122
+ */
123
+ readonly isLive: boolean;
124
+ }
125
+ /**
126
+ * Parse an untrusted `sms_profile_public` blob. Null when it is absent or carries no brand, consent words or
127
+ * consent version (the three things an opt-in cannot do without). `status_is_live` reads true only for the
128
+ * literal `true`: a missing flag is the not-live side, which refuses more, never less. Never throws.
129
+ */
130
+ declare function parseTextingProfile(raw: unknown): EverfurTextingProfile | null;
131
+ /**
132
+ * A +1 (United States or Canada) number as E.164, or null. Takes what a member types: `(415) 555-0134`,
133
+ * `415.555.0134`, `1 415 555 0134` or `+1 415 555 0134`. A North American number is ten digits whose area code and
134
+ * exchange both start 2 to 9; anything else (another country code, too few digits, letters) is null, so the
135
+ * surface refuses it before the wire instead of spending a verification on it.
136
+ */
137
+ declare function toTextingE164(input: string): string | null;
138
+ /** True for a string already in E.164 form (`+` and 8 to 15 digits). */
139
+ declare function isE164(value: unknown): value is string;
140
+
141
+ /** The identity states the server reports. An unknown value reads as `none`: nothing on record we can explain. */
142
+ declare const EVERFUR_TEXTING_STATUSES: readonly ["none", "pending", "verified", "opted_out"];
143
+ type EverfurTextingStatus = (typeof EVERFUR_TEXTING_STATUSES)[number];
144
+ /** The member's texting identity. The raw number never comes back; `phoneMasked` is what Everfur shows anywhere. */
145
+ interface EverfurTextingIdentity {
146
+ readonly status: EverfurTextingStatus;
147
+ readonly phoneMasked: string | null;
148
+ /** The consent version on record, or null. */
149
+ readonly consentVersion: string | null;
150
+ /** The pet texts are about, or null when none is chosen. */
151
+ readonly selectedPetRef: PetRef | null;
152
+ }
153
+ /** An outstanding code, as the server issued it. */
154
+ interface EverfurTextingChallenge {
155
+ readonly challengeId: string;
156
+ /** ISO 8601, or null when the server did not say. */
157
+ readonly expiresAt: string | null;
158
+ /**
159
+ * How many wrong codes the server still accepts for this challenge, as it said when it issued the code
160
+ * (`attempts_remaining`), or null when it did not say. The controller counts it down on each refused code.
161
+ */
162
+ readonly attemptsRemaining: number | null;
163
+ }
164
+ interface EverfurTextingVerificationInput {
165
+ /** E.164 (`+14155550134`). `toTextingE164` turns what a member typed into this. */
166
+ readonly phoneE164: string;
167
+ /** The tenant profile's `consentVersion`: the words the member ticked. The server refuses any other. */
168
+ readonly consentVersion: string;
169
+ }
170
+ /** A code is digits only; the consumer screen asks for six. */
171
+ declare const TEXTING_CODE_PATTERN: RegExp;
172
+ interface TextingRepository {
173
+ /** `GET /widget/v1/me/sms-identity`. Settles; never throws. */
174
+ read(opts?: {
175
+ readonly signal?: AbortSignal;
176
+ }): Promise<EverfurResult<EverfurTextingIdentity>>;
177
+ /** `POST .../verification`: text a code to the number. Sent once, never replayed. */
178
+ startVerification(input: EverfurTextingVerificationInput): Promise<EverfurResult<EverfurTextingChallenge>>;
179
+ /** `POST .../verification/confirm`: spend the code. Sent once, never replayed. */
180
+ confirmVerification(challengeId: string, code: string): Promise<EverfurResult<EverfurTextingIdentity>>;
181
+ /** `PUT .../selected-pet`: the pet texts are about. */
182
+ selectPet(petRef: PetRef): Promise<EverfurResult<EverfurTextingIdentity>>;
183
+ /** `DELETE /widget/v1/me/sms-identity`: withdraw consent and stop texts. As available as opting in. */
184
+ optOut(): Promise<EverfurResult<EverfurTextingIdentity>>;
185
+ }
186
+ /** The part of the runtime this repository needs (`useEverfurContext().runtime` satisfies it). */
187
+ interface TextingRuntime {
188
+ readonly isDisposed: boolean;
189
+ readonly registry: {
190
+ readonly services: {
191
+ authFor(userRef: UserRef | null): AuthContext;
192
+ readonly errorPolicy: ErrorPolicyPort | undefined;
193
+ };
194
+ };
195
+ }
196
+ /** The lower seam: one auth context, or an already-built funnel (tests). */
197
+ interface TextingRepositoryDeps {
198
+ readonly auth: AuthContext;
199
+ readonly errorPolicy?: ErrorPolicyPort;
200
+ readonly funnel?: RequestFunnel;
201
+ }
202
+ /** The reason codes a surface branches on, by meaning. Read with `textingReasonOf`. */
203
+ type EverfurTextingReason = 'not_live' | 'code_invalid' | 'phone_linked' | 'pet_ineligible' | 'no_identity' | 'consent_changed' | 'session_required' | 'country_not_allowed' | 'phone_code_limit' | 'tenant_code_limit';
204
+ /** Which texting refusal an error is, or null for any other failure. */
205
+ declare function textingReasonOf(error: EverfurError | null | undefined): EverfurTextingReason | null;
206
+ /** The allowlist mapper for one identity body. `status` is REQUIRED: a body without one is not an identity. */
207
+ declare function textingIdentityFromWire(raw: unknown): EverfurTextingIdentity | null;
208
+ /** The repository over the runtime under your provider. Auth is read at CALL time; a disposed runtime sends nothing. */
209
+ declare function createTextingRepository(runtime: TextingRuntime): TextingRepository;
210
+ /** The same repository over one auth context (or an injected funnel). Internal seam, for deterministic tests. */
211
+ declare function createTextingRepositoryOver(deps: TextingRepositoryDeps): TextingRepository;
212
+
213
+ type TextingPhase = 'loading' | 'failed' | 'enroll' | 'requesting' | 'code' | 'confirming' | 'verified' | 'optingOut' | 'optedOut';
214
+ /** What a refused code most likely was. See the header. */
215
+ type TextingCodeRefusal = 'wrong' | 'expired' | 'spent';
216
+ /** Which verb a refusal belongs to, so a surface retries the right thing. */
217
+ type TextingAction = 'read' | 'start' | 'confirm' | 'selectPet' | 'optOut';
218
+ interface TextingSnapshot {
219
+ readonly phase: TextingPhase;
220
+ /** The identity as the server last reported it, or null before the first read. */
221
+ readonly identity: EverfurTextingIdentity | null;
222
+ /** The outstanding code, while one is out. */
223
+ readonly challenge: EverfurTextingChallenge | null;
224
+ /** The number the current code went to (what the member typed, as E.164), for "request a new code". */
225
+ readonly phoneE164: string | null;
226
+ /** The last refusal, or null. `error.displayMessage` is safe to show. */
227
+ readonly error: EverfurError | null;
228
+ readonly failedAction: TextingAction | null;
229
+ /** For a refused code (`failedAction` 'confirm'), what it most likely was; null otherwise. */
230
+ readonly codeRefusal: TextingCodeRefusal | null;
231
+ /** True while a pet choice is being saved. */
232
+ readonly savingPet: boolean;
233
+ /**
234
+ * True while `requesting` is a new code for the code step ("Request a new code"), so a surface keeps the code step
235
+ * on screen with its link busy instead of flipping back to the number (audit 2026-10-20). False for a first send.
236
+ */
237
+ readonly resending: boolean;
238
+ }
239
+ declare class TextingController {
240
+ private readonly repository;
241
+ private readonly now;
242
+ private snapshot;
243
+ private readonly listeners;
244
+ /** Bumped by every step change; a settlement for an older generation is dropped. */
245
+ private generation;
246
+ private consentVersion;
247
+ private disposed;
248
+ /** `now` is the clock a refused code is judged against (epoch ms); tests pass their own. */
249
+ constructor(repository: TextingRepository, now?: () => number);
250
+ readonly subscribe: (listener: () => void) => (() => void);
251
+ readonly getSnapshot: () => TextingSnapshot;
252
+ private set;
253
+ /** Read the member's identity (the first load, and the way out of `failed`). */
254
+ load(): Promise<void>;
255
+ /** Text a code to `phoneE164` for the consent words of `consentVersion`. */
256
+ start(phoneE164: string, consentVersion: string): Promise<boolean>;
257
+ /** Text a new code to the same number. */
258
+ resend(): Promise<boolean>;
259
+ /** Check the code the member typed. */
260
+ confirm(code: string): Promise<boolean>;
261
+ /** Back to the number step ("use a different number"); any code in flight is abandoned. */
262
+ changeNumber(): void;
263
+ /** From `optedOut`, start a new opt-in. Withdrawing never locks a member out of coming back. */
264
+ reenroll(): void;
265
+ /** Choose the pet texts are about. The step does not change; only `savingPet` and the identity do. */
266
+ selectPet(petRef: PetRef): Promise<boolean>;
267
+ /** Withdraw consent and stop texts. */
268
+ optOut(): Promise<boolean>;
269
+ /** Stop notifying; any settlement after this is dropped. */
270
+ dispose(): void;
271
+ }
272
+
273
+ type EverfurTextingViewStatus = 'signedOut' | 'unavailable' | TextingSnapshot['phase'];
274
+ interface EverfurTextingState {
275
+ readonly status: EverfurTextingViewStatus;
276
+ /** The tenant's public texting profile, or null when it has none. */
277
+ readonly profile: EverfurTextingProfile | null;
278
+ /** The controller's snapshot (identity, outstanding code, last refusal). */
279
+ readonly snapshot: TextingSnapshot;
280
+ /** Text a code to what the member typed. Refuses (settles false) for a number `validateTextingPhone` rejects. */
281
+ start(phone: string): Promise<boolean>;
282
+ resend(): Promise<boolean>;
283
+ confirm(code: string): Promise<boolean>;
284
+ changeNumber(): void;
285
+ reenroll(): void;
286
+ selectPet(petRef: PetRef): Promise<boolean>;
287
+ optOut(): Promise<boolean>;
288
+ /** Read the identity again (the way out of `failed`). */
289
+ refresh(): Promise<void>;
290
+ }
291
+ /** Why a member's input is not ready to send, or null when it is. */
292
+ type EverfurTextingInputProblem = 'phoneInvalid' | 'consentRequired' | 'codeInvalidFormat';
293
+ /** The opt-in's pre-flight: a +1 number and a ticked consent box, before any request is spent. */
294
+ declare function validateTextingEnroll(phone: string, consented: boolean): EverfurTextingInputProblem | null;
295
+ /** The surface asks for six digits, as the consumer screen does. */
296
+ declare const TEXTING_UI_CODE_LENGTH = 6;
297
+ declare function validateTextingCode(code: string): EverfurTextingInputProblem | null;
298
+ /** The tenant's parsed texting profile, or null. Re-parses only when the verdict carries a new blob. */
299
+ declare function useEverfurTextingProfile(): EverfurTextingProfile | null;
300
+ /** The texting repository bound to the runtime under your provider, for a partner's own UI. */
301
+ declare function useEverfurTextingRepository(): TextingRepository;
302
+ /** The member's texting opt-in, step by step. `EverfurTextingOptIn` renders it on either host. */
303
+ declare function useEverfurTexting(): EverfurTextingState;
304
+
305
+ /**
306
+ * The line for a refused step. The consumer deck's own words per refusal; never the raw server message. For a refused
307
+ * code, pass the snapshot's `codeRefusal` so a typo, an expired code and a used-up code read differently; without it
308
+ * (or when the controller could not tell) the line is the deck's generic "request a new one".
309
+ */
310
+ declare function textingErrorText(error: EverfurError, action: TextingAction | null, codeRefusal?: TextingCodeRefusal | null, copy?: TextingCopy): string;
311
+ /** The support line under a refusal, when the server named the request. Null otherwise. */
312
+ declare function textingSupportText(error: EverfurError, copy?: TextingCopy): string | null;
313
+ /** The line for input the surface refused before any request. */
314
+ declare function textingInputProblemText(problem: EverfurTextingInputProblem, copy?: TextingCopy): string;
315
+ /**
316
+ * The opted-out body: the brand STOP line for a member who texted STOP, the consumer's turn-off line for one who
317
+ * turned texts off in the app. The server tells them apart without a field of its own: an in-app turn-off revokes the
318
+ * identity, so `opted_out` comes back with no number (and the SDK's own turn-off settles to that shape), while a STOP
319
+ * keeps the live identity and its masked number (EFBackend partner_sms_identity.py `partner_status`).
320
+ */
321
+ declare function textingOptedOutBody(identity: EverfurTextingIdentity | null, brand: string, copy?: TextingCopy, brandCopy?: TextingBrandCopy): string;
322
+ /** A +1 E.164 number as a member reads it: `+14155550134` becomes `(415) 555-0134`. Anything else is unchanged. */
323
+ declare function formatTextingPhone(e164: string | null): string;
324
+
325
+ export { isE164 as A, parseTextingProfile as B, COPY_PLACEHOLDER_PREFIX as C, textingErrorText as D, type EverfurTextingViewStatus as E, textingIdentityFromWire as F, textingInputProblemText as G, textingOptedOutBody as H, textingReasonOf as I, textingSupportText as J, toTextingE164 as K, useEverfurTexting as L, useEverfurTextingProfile as M, useEverfurTextingRepository as N, validateTextingCode as O, validateTextingEnroll as P, type TextingCopy as T, type TextingBrandCopy as a, EVERFUR_TEXTING_STATUSES as b, type EverfurTextingChallenge as c, type EverfurTextingIdentity as d, type EverfurTextingInputProblem as e, type EverfurTextingProfile as f, type EverfurTextingReason as g, type EverfurTextingState as h, type EverfurTextingStatus as i, type EverfurTextingVerificationInput as j, TEXTING_BRAND_COPY as k, TEXTING_CODE_PATTERN as l, TEXTING_COPY as m, TEXTING_COPY_PLACEHOLDERS as n, TEXTING_UI_CODE_LENGTH as o, type TextingAction as p, type TextingCodeRefusal as q, TextingController as r, type TextingPhase as s, type TextingRepository as t, type TextingRepositoryDeps as u, type TextingRuntime as v, type TextingSnapshot as w, createTextingRepository as x, createTextingRepositoryOver as y, formatTextingPhone as z };