@spare-technologies/spare-link 0.1.0-beta.1 → 1.0.1

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 (568) hide show
  1. package/README.md +119 -63
  2. package/lib/commonjs/core/models/payment-return-params.js +245 -20
  3. package/lib/commonjs/core/models/payment-return-params.js.map +1 -1
  4. package/lib/commonjs/core/models/pending-session-record.js +2 -0
  5. package/lib/commonjs/core/models/pending-session-record.js.map +1 -0
  6. package/lib/commonjs/core/services/hosted-flow-controller.js +333 -0
  7. package/lib/commonjs/core/services/hosted-flow-controller.js.map +1 -0
  8. package/lib/commonjs/core/services/hosted-flow-state.js +96 -0
  9. package/lib/commonjs/core/services/hosted-flow-state.js.map +1 -0
  10. package/lib/commonjs/index.js +42 -164
  11. package/lib/commonjs/index.js.map +1 -1
  12. package/lib/commonjs/internal/bank-redirect.js +20 -9
  13. package/lib/commonjs/internal/bank-redirect.js.map +1 -1
  14. package/lib/commonjs/internal/hosted/bridge-message.js +107 -0
  15. package/lib/commonjs/internal/hosted/bridge-message.js.map +1 -0
  16. package/lib/commonjs/internal/hosted/hosted-url.js +41 -0
  17. package/lib/commonjs/internal/hosted/hosted-url.js.map +1 -0
  18. package/lib/commonjs/internal/index.js +0 -7
  19. package/lib/commonjs/internal/index.js.map +1 -1
  20. package/lib/commonjs/internal/redact-uri.js +59 -15
  21. package/lib/commonjs/internal/redact-uri.js.map +1 -1
  22. package/lib/commonjs/internal/secure-store-pending-session-store.js +20 -25
  23. package/lib/commonjs/internal/secure-store-pending-session-store.js.map +1 -1
  24. package/lib/commonjs/internal/url-parts.js +145 -0
  25. package/lib/commonjs/internal/url-parts.js.map +1 -0
  26. package/lib/commonjs/public/index.js +0 -37
  27. package/lib/commonjs/public/index.js.map +1 -1
  28. package/lib/commonjs/public/payment-result.js +16 -4
  29. package/lib/commonjs/public/payment-result.js.map +1 -1
  30. package/lib/commonjs/public/recovery-result.js +7 -18
  31. package/lib/commonjs/public/recovery-result.js.map +1 -1
  32. package/lib/commonjs/public/spare-link-config.js +41 -16
  33. package/lib/commonjs/public/spare-link-config.js.map +1 -1
  34. package/lib/commonjs/public/spare-link-event.js +27 -33
  35. package/lib/commonjs/public/spare-link-event.js.map +1 -1
  36. package/lib/commonjs/public/spare-link-instance.js +67 -77
  37. package/lib/commonjs/public/spare-link-instance.js.map +1 -1
  38. package/lib/commonjs/public/spare-link-session.js +2 -9
  39. package/lib/commonjs/public/spare-link-session.js.map +1 -1
  40. package/lib/commonjs/public/spare-link.js +0 -12
  41. package/lib/commonjs/public/spare-link.js.map +1 -1
  42. package/lib/commonjs/ui/hooks/{use-payment-flow-state.js → use-hosted-flow-state.js} +4 -4
  43. package/lib/commonjs/ui/hooks/use-hosted-flow-state.js.map +1 -0
  44. package/lib/commonjs/ui/hosted/hosted-payment-page.js +177 -0
  45. package/lib/commonjs/ui/hosted/hosted-payment-page.js.map +1 -0
  46. package/lib/commonjs/ui/hosted/hosted-payment-webview.js +168 -0
  47. package/lib/commonjs/ui/hosted/hosted-payment-webview.js.map +1 -0
  48. package/lib/commonjs/ui/screens/index.js +3 -17
  49. package/lib/commonjs/ui/screens/index.js.map +1 -1
  50. package/lib/commonjs/ui/screens/page-unavailable-screen.js +101 -0
  51. package/lib/commonjs/ui/screens/page-unavailable-screen.js.map +1 -0
  52. package/lib/commonjs/ui/spare-link-host.js +220 -234
  53. package/lib/commonjs/ui/spare-link-host.js.map +1 -1
  54. package/lib/commonjs/ui/widgets/index.js +3 -10
  55. package/lib/commonjs/ui/widgets/index.js.map +1 -1
  56. package/lib/commonjs/version.js +1 -1
  57. package/lib/commonjs/version.js.map +1 -1
  58. package/lib/module/core/models/payment-return-params.js +235 -20
  59. package/lib/module/core/models/payment-return-params.js.map +1 -1
  60. package/lib/module/core/models/pending-session-record.js +2 -0
  61. package/lib/module/core/models/pending-session-record.js.map +1 -0
  62. package/lib/module/core/services/hosted-flow-controller.js +328 -0
  63. package/lib/module/core/services/hosted-flow-controller.js.map +1 -0
  64. package/lib/module/core/services/hosted-flow-state.js +91 -0
  65. package/lib/module/core/services/hosted-flow-state.js.map +1 -0
  66. package/lib/module/index.js +8 -22
  67. package/lib/module/index.js.map +1 -1
  68. package/lib/module/internal/bank-redirect.js +20 -9
  69. package/lib/module/internal/bank-redirect.js.map +1 -1
  70. package/lib/module/internal/hosted/bridge-message.js +104 -0
  71. package/lib/module/internal/hosted/bridge-message.js.map +1 -0
  72. package/lib/module/internal/hosted/hosted-url.js +36 -0
  73. package/lib/module/internal/hosted/hosted-url.js.map +1 -0
  74. package/lib/module/internal/index.js +0 -1
  75. package/lib/module/internal/index.js.map +1 -1
  76. package/lib/module/internal/redact-uri.js +59 -15
  77. package/lib/module/internal/redact-uri.js.map +1 -1
  78. package/lib/module/internal/secure-store-pending-session-store.js +20 -25
  79. package/lib/module/internal/secure-store-pending-session-store.js.map +1 -1
  80. package/lib/module/internal/url-parts.js +139 -0
  81. package/lib/module/internal/url-parts.js.map +1 -0
  82. package/lib/module/public/index.js +2 -3
  83. package/lib/module/public/index.js.map +1 -1
  84. package/lib/module/public/payment-result.js +16 -4
  85. package/lib/module/public/payment-result.js.map +1 -1
  86. package/lib/module/public/recovery-result.js +7 -17
  87. package/lib/module/public/recovery-result.js.map +1 -1
  88. package/lib/module/public/spare-link-config.js +42 -15
  89. package/lib/module/public/spare-link-config.js.map +1 -1
  90. package/lib/module/public/spare-link-event.js +27 -33
  91. package/lib/module/public/spare-link-event.js.map +1 -1
  92. package/lib/module/public/spare-link-instance.js +68 -72
  93. package/lib/module/public/spare-link-instance.js.map +1 -1
  94. package/lib/module/public/spare-link-session.js +2 -9
  95. package/lib/module/public/spare-link-session.js.map +1 -1
  96. package/lib/module/public/spare-link.js +1 -1
  97. package/lib/module/public/spare-link.js.map +1 -1
  98. package/lib/module/ui/hooks/{use-payment-flow-state.js → use-hosted-flow-state.js} +3 -3
  99. package/lib/module/ui/hooks/use-hosted-flow-state.js.map +1 -0
  100. package/lib/module/ui/hosted/hosted-payment-page.js +175 -0
  101. package/lib/module/ui/hosted/hosted-payment-page.js.map +1 -0
  102. package/lib/module/ui/hosted/hosted-payment-webview.js +163 -0
  103. package/lib/module/ui/hosted/hosted-payment-webview.js.map +1 -0
  104. package/lib/module/ui/screens/index.js +1 -3
  105. package/lib/module/ui/screens/index.js.map +1 -1
  106. package/lib/module/ui/screens/page-unavailable-screen.js +97 -0
  107. package/lib/module/ui/screens/page-unavailable-screen.js.map +1 -0
  108. package/lib/module/ui/spare-link-host.js +221 -236
  109. package/lib/module/ui/spare-link-host.js.map +1 -1
  110. package/lib/module/ui/widgets/index.js +1 -2
  111. package/lib/module/ui/widgets/index.js.map +1 -1
  112. package/lib/module/version.js +1 -1
  113. package/lib/module/version.js.map +1 -1
  114. package/lib/typescript/commonjs/core/models/index.d.ts +1 -123
  115. package/lib/typescript/commonjs/core/models/index.d.ts.map +1 -1
  116. package/lib/typescript/commonjs/core/models/payment-return-params.d.ts +91 -8
  117. package/lib/typescript/commonjs/core/models/payment-return-params.d.ts.map +1 -1
  118. package/lib/typescript/commonjs/core/models/pending-session-record.d.ts +11 -0
  119. package/lib/typescript/commonjs/core/models/pending-session-record.d.ts.map +1 -0
  120. package/lib/typescript/commonjs/core/services/hosted-flow-controller.d.ts +119 -0
  121. package/lib/typescript/commonjs/core/services/hosted-flow-controller.d.ts.map +1 -0
  122. package/lib/typescript/commonjs/core/services/hosted-flow-state.d.ts +75 -0
  123. package/lib/typescript/commonjs/core/services/hosted-flow-state.d.ts.map +1 -0
  124. package/lib/typescript/commonjs/index.d.ts +5 -14
  125. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  126. package/lib/typescript/commonjs/internal/bank-redirect.d.ts.map +1 -1
  127. package/lib/typescript/commonjs/internal/hosted/bridge-message.d.ts +44 -0
  128. package/lib/typescript/commonjs/internal/hosted/bridge-message.d.ts.map +1 -0
  129. package/lib/typescript/commonjs/internal/hosted/hosted-url.d.ts +30 -0
  130. package/lib/typescript/commonjs/internal/hosted/hosted-url.d.ts.map +1 -0
  131. package/lib/typescript/commonjs/internal/index.d.ts +0 -1
  132. package/lib/typescript/commonjs/internal/index.d.ts.map +1 -1
  133. package/lib/typescript/commonjs/internal/redact-uri.d.ts +21 -1
  134. package/lib/typescript/commonjs/internal/redact-uri.d.ts.map +1 -1
  135. package/lib/typescript/commonjs/internal/secure-store-pending-session-store.d.ts +3 -2
  136. package/lib/typescript/commonjs/internal/secure-store-pending-session-store.d.ts.map +1 -1
  137. package/lib/typescript/commonjs/internal/url-parts.d.ts +46 -0
  138. package/lib/typescript/commonjs/internal/url-parts.d.ts.map +1 -0
  139. package/lib/typescript/commonjs/public/index.d.ts +4 -6
  140. package/lib/typescript/commonjs/public/index.d.ts.map +1 -1
  141. package/lib/typescript/commonjs/public/payment-result.d.ts +50 -12
  142. package/lib/typescript/commonjs/public/payment-result.d.ts.map +1 -1
  143. package/lib/typescript/commonjs/public/recovery-result.d.ts +11 -20
  144. package/lib/typescript/commonjs/public/recovery-result.d.ts.map +1 -1
  145. package/lib/typescript/commonjs/public/spare-link-config.d.ts +13 -31
  146. package/lib/typescript/commonjs/public/spare-link-config.d.ts.map +1 -1
  147. package/lib/typescript/commonjs/public/spare-link-event.d.ts +29 -31
  148. package/lib/typescript/commonjs/public/spare-link-event.d.ts.map +1 -1
  149. package/lib/typescript/commonjs/public/spare-link-host-api.d.ts +1 -12
  150. package/lib/typescript/commonjs/public/spare-link-host-api.d.ts.map +1 -1
  151. package/lib/typescript/commonjs/public/spare-link-instance.d.ts +26 -20
  152. package/lib/typescript/commonjs/public/spare-link-instance.d.ts.map +1 -1
  153. package/lib/typescript/commonjs/public/spare-link-session.d.ts +3 -8
  154. package/lib/typescript/commonjs/public/spare-link-session.d.ts.map +1 -1
  155. package/lib/typescript/commonjs/public/spare-link.d.ts +1 -1
  156. package/lib/typescript/commonjs/public/spare-link.d.ts.map +1 -1
  157. package/lib/typescript/commonjs/ui/hooks/use-hosted-flow-state.d.ts +9 -0
  158. package/lib/typescript/commonjs/ui/hooks/use-hosted-flow-state.d.ts.map +1 -0
  159. package/lib/typescript/commonjs/ui/hosted/hosted-payment-page.d.ts +17 -0
  160. package/lib/typescript/commonjs/ui/hosted/hosted-payment-page.d.ts.map +1 -0
  161. package/lib/typescript/commonjs/ui/hosted/hosted-payment-webview.d.ts +43 -0
  162. package/lib/typescript/commonjs/ui/hosted/hosted-payment-webview.d.ts.map +1 -0
  163. package/lib/typescript/commonjs/ui/screens/index.d.ts +1 -3
  164. package/lib/typescript/commonjs/ui/screens/index.d.ts.map +1 -1
  165. package/lib/typescript/commonjs/ui/screens/page-unavailable-screen.d.ts +18 -0
  166. package/lib/typescript/commonjs/ui/screens/page-unavailable-screen.d.ts.map +1 -0
  167. package/lib/typescript/commonjs/ui/spare-link-host.d.ts +4 -5
  168. package/lib/typescript/commonjs/ui/spare-link-host.d.ts.map +1 -1
  169. package/lib/typescript/commonjs/ui/widgets/index.d.ts +1 -2
  170. package/lib/typescript/commonjs/ui/widgets/index.d.ts.map +1 -1
  171. package/lib/typescript/commonjs/version.d.ts +1 -1
  172. package/lib/typescript/commonjs/version.d.ts.map +1 -1
  173. package/lib/typescript/module/core/models/index.d.ts +1 -123
  174. package/lib/typescript/module/core/models/index.d.ts.map +1 -1
  175. package/lib/typescript/module/core/models/payment-return-params.d.ts +91 -8
  176. package/lib/typescript/module/core/models/payment-return-params.d.ts.map +1 -1
  177. package/lib/typescript/module/core/models/pending-session-record.d.ts +11 -0
  178. package/lib/typescript/module/core/models/pending-session-record.d.ts.map +1 -0
  179. package/lib/typescript/module/core/services/hosted-flow-controller.d.ts +119 -0
  180. package/lib/typescript/module/core/services/hosted-flow-controller.d.ts.map +1 -0
  181. package/lib/typescript/module/core/services/hosted-flow-state.d.ts +75 -0
  182. package/lib/typescript/module/core/services/hosted-flow-state.d.ts.map +1 -0
  183. package/lib/typescript/module/index.d.ts +5 -14
  184. package/lib/typescript/module/index.d.ts.map +1 -1
  185. package/lib/typescript/module/internal/bank-redirect.d.ts.map +1 -1
  186. package/lib/typescript/module/internal/hosted/bridge-message.d.ts +44 -0
  187. package/lib/typescript/module/internal/hosted/bridge-message.d.ts.map +1 -0
  188. package/lib/typescript/module/internal/hosted/hosted-url.d.ts +30 -0
  189. package/lib/typescript/module/internal/hosted/hosted-url.d.ts.map +1 -0
  190. package/lib/typescript/module/internal/index.d.ts +0 -1
  191. package/lib/typescript/module/internal/index.d.ts.map +1 -1
  192. package/lib/typescript/module/internal/redact-uri.d.ts +21 -1
  193. package/lib/typescript/module/internal/redact-uri.d.ts.map +1 -1
  194. package/lib/typescript/module/internal/secure-store-pending-session-store.d.ts +3 -2
  195. package/lib/typescript/module/internal/secure-store-pending-session-store.d.ts.map +1 -1
  196. package/lib/typescript/module/internal/url-parts.d.ts +46 -0
  197. package/lib/typescript/module/internal/url-parts.d.ts.map +1 -0
  198. package/lib/typescript/module/public/index.d.ts +4 -6
  199. package/lib/typescript/module/public/index.d.ts.map +1 -1
  200. package/lib/typescript/module/public/payment-result.d.ts +50 -12
  201. package/lib/typescript/module/public/payment-result.d.ts.map +1 -1
  202. package/lib/typescript/module/public/recovery-result.d.ts +11 -20
  203. package/lib/typescript/module/public/recovery-result.d.ts.map +1 -1
  204. package/lib/typescript/module/public/spare-link-config.d.ts +13 -31
  205. package/lib/typescript/module/public/spare-link-config.d.ts.map +1 -1
  206. package/lib/typescript/module/public/spare-link-event.d.ts +29 -31
  207. package/lib/typescript/module/public/spare-link-event.d.ts.map +1 -1
  208. package/lib/typescript/module/public/spare-link-host-api.d.ts +1 -12
  209. package/lib/typescript/module/public/spare-link-host-api.d.ts.map +1 -1
  210. package/lib/typescript/module/public/spare-link-instance.d.ts +26 -20
  211. package/lib/typescript/module/public/spare-link-instance.d.ts.map +1 -1
  212. package/lib/typescript/module/public/spare-link-session.d.ts +3 -8
  213. package/lib/typescript/module/public/spare-link-session.d.ts.map +1 -1
  214. package/lib/typescript/module/public/spare-link.d.ts +1 -1
  215. package/lib/typescript/module/public/spare-link.d.ts.map +1 -1
  216. package/lib/typescript/module/ui/hooks/use-hosted-flow-state.d.ts +9 -0
  217. package/lib/typescript/module/ui/hooks/use-hosted-flow-state.d.ts.map +1 -0
  218. package/lib/typescript/module/ui/hosted/hosted-payment-page.d.ts +17 -0
  219. package/lib/typescript/module/ui/hosted/hosted-payment-page.d.ts.map +1 -0
  220. package/lib/typescript/module/ui/hosted/hosted-payment-webview.d.ts +43 -0
  221. package/lib/typescript/module/ui/hosted/hosted-payment-webview.d.ts.map +1 -0
  222. package/lib/typescript/module/ui/screens/index.d.ts +1 -3
  223. package/lib/typescript/module/ui/screens/index.d.ts.map +1 -1
  224. package/lib/typescript/module/ui/screens/page-unavailable-screen.d.ts +18 -0
  225. package/lib/typescript/module/ui/screens/page-unavailable-screen.d.ts.map +1 -0
  226. package/lib/typescript/module/ui/spare-link-host.d.ts +4 -5
  227. package/lib/typescript/module/ui/spare-link-host.d.ts.map +1 -1
  228. package/lib/typescript/module/ui/widgets/index.d.ts +1 -2
  229. package/lib/typescript/module/ui/widgets/index.d.ts.map +1 -1
  230. package/lib/typescript/module/version.d.ts +1 -1
  231. package/lib/typescript/module/version.d.ts.map +1 -1
  232. package/package.json +24 -22
  233. package/plugins/with-spare-link.js +6 -26
  234. package/src/core/models/index.ts +1 -139
  235. package/src/core/models/payment-return-params.ts +269 -21
  236. package/src/core/models/pending-session-record.ts +10 -0
  237. package/src/core/services/hosted-flow-controller.ts +374 -0
  238. package/src/core/services/hosted-flow-state.ts +123 -0
  239. package/src/index.ts +20 -89
  240. package/src/internal/bank-redirect.ts +23 -9
  241. package/src/internal/hosted/bridge-message.ts +106 -0
  242. package/src/internal/hosted/hosted-url.ts +33 -0
  243. package/src/internal/index.ts +0 -1
  244. package/src/internal/redact-uri.ts +69 -15
  245. package/src/internal/secure-store-pending-session-store.ts +28 -49
  246. package/src/internal/url-parts.ts +134 -0
  247. package/src/public/index.ts +2 -24
  248. package/src/public/payment-result.ts +50 -12
  249. package/src/public/recovery-result.ts +16 -25
  250. package/src/public/spare-link-config.ts +56 -43
  251. package/src/public/spare-link-event.ts +33 -42
  252. package/src/public/spare-link-host-api.ts +1 -14
  253. package/src/public/spare-link-instance.ts +57 -65
  254. package/src/public/spare-link-session.ts +4 -16
  255. package/src/public/spare-link.ts +1 -1
  256. package/src/ui/hooks/use-hosted-flow-state.ts +16 -0
  257. package/src/ui/hosted/hosted-payment-page.tsx +178 -0
  258. package/src/ui/hosted/hosted-payment-webview.tsx +164 -0
  259. package/src/ui/screens/index.ts +4 -6
  260. package/src/ui/screens/page-unavailable-screen.tsx +94 -0
  261. package/src/ui/spare-link-host.tsx +227 -247
  262. package/src/ui/widgets/index.ts +1 -2
  263. package/src/version.ts +1 -1
  264. package/CHANGELOG.md +0 -25
  265. package/lib/commonjs/core/client/link-api-client.js +0 -297
  266. package/lib/commonjs/core/client/link-api-client.js.map +0 -1
  267. package/lib/commonjs/core/errors/payment-api-error.js +0 -35
  268. package/lib/commonjs/core/errors/payment-api-error.js.map +0 -1
  269. package/lib/commonjs/core/models/link-session-status.js +0 -14
  270. package/lib/commonjs/core/models/link-session-status.js.map +0 -1
  271. package/lib/commonjs/core/models/payment-type.js +0 -45
  272. package/lib/commonjs/core/models/payment-type.js.map +0 -1
  273. package/lib/commonjs/core/models/wire-mappers.js +0 -277
  274. package/lib/commonjs/core/models/wire-mappers.js.map +0 -1
  275. package/lib/commonjs/core/services/consent-presenter.js +0 -150
  276. package/lib/commonjs/core/services/consent-presenter.js.map +0 -1
  277. package/lib/commonjs/core/services/execute-resume-if-needed.js +0 -216
  278. package/lib/commonjs/core/services/execute-resume-if-needed.js.map +0 -1
  279. package/lib/commonjs/core/services/multi-payment-rules-presenter.js +0 -151
  280. package/lib/commonjs/core/services/multi-payment-rules-presenter.js.map +0 -1
  281. package/lib/commonjs/core/services/payment-flow-controller.js +0 -547
  282. package/lib/commonjs/core/services/payment-flow-controller.js.map +0 -1
  283. package/lib/commonjs/core/services/payment-flow-state.js +0 -110
  284. package/lib/commonjs/core/services/payment-flow-state.js.map +0 -1
  285. package/lib/commonjs/core/services/payment-result-mapper.js +0 -49
  286. package/lib/commonjs/core/services/payment-result-mapper.js.map +0 -1
  287. package/lib/commonjs/core/services/presentation-utils.js +0 -11
  288. package/lib/commonjs/core/services/presentation-utils.js.map +0 -1
  289. package/lib/commonjs/core/services/redirect-buffer.js +0 -40
  290. package/lib/commonjs/core/services/redirect-buffer.js.map +0 -1
  291. package/lib/commonjs/core/services/user-friendly-messages.js +0 -46
  292. package/lib/commonjs/core/services/user-friendly-messages.js.map +0 -1
  293. package/lib/commonjs/internal/telemetry-collector.js +0 -80
  294. package/lib/commonjs/internal/telemetry-collector.js.map +0 -1
  295. package/lib/commonjs/public/constants.js +0 -21
  296. package/lib/commonjs/public/constants.js.map +0 -1
  297. package/lib/commonjs/public/spare-link-callbacks.js +0 -6
  298. package/lib/commonjs/public/spare-link-callbacks.js.map +0 -1
  299. package/lib/commonjs/ui/consent/charge-bearer-display.js +0 -99
  300. package/lib/commonjs/ui/consent/charge-bearer-display.js.map +0 -1
  301. package/lib/commonjs/ui/consent/consent-accordion.js +0 -94
  302. package/lib/commonjs/ui/consent/consent-accordion.js.map +0 -1
  303. package/lib/commonjs/ui/consent/consent-summary-section.js +0 -27
  304. package/lib/commonjs/ui/consent/consent-summary-section.js.map +0 -1
  305. package/lib/commonjs/ui/consent/cop-information.js +0 -168
  306. package/lib/commonjs/ui/consent/cop-information.js.map +0 -1
  307. package/lib/commonjs/ui/consent/international-payment-summary.js +0 -98
  308. package/lib/commonjs/ui/consent/international-payment-summary.js.map +0 -1
  309. package/lib/commonjs/ui/consent/label-value-rows.js +0 -59
  310. package/lib/commonjs/ui/consent/label-value-rows.js.map +0 -1
  311. package/lib/commonjs/ui/consent/multi-payment-rules-list.js +0 -130
  312. package/lib/commonjs/ui/consent/multi-payment-rules-list.js.map +0 -1
  313. package/lib/commonjs/ui/consent/multi-payment-summary.js +0 -99
  314. package/lib/commonjs/ui/consent/multi-payment-summary.js.map +0 -1
  315. package/lib/commonjs/ui/consent/single-payment-summary.js +0 -158
  316. package/lib/commonjs/ui/consent/single-payment-summary.js.map +0 -1
  317. package/lib/commonjs/ui/consent/terms-link.js +0 -35
  318. package/lib/commonjs/ui/consent/terms-link.js.map +0 -1
  319. package/lib/commonjs/ui/hooks/use-payment-flow-state.js.map +0 -1
  320. package/lib/commonjs/ui/payment-flow-page.js +0 -235
  321. package/lib/commonjs/ui/payment-flow-page.js.map +0 -1
  322. package/lib/commonjs/ui/screens/bank-selection-screen.js +0 -215
  323. package/lib/commonjs/ui/screens/bank-selection-screen.js.map +0 -1
  324. package/lib/commonjs/ui/screens/consent-details-screen.js +0 -124
  325. package/lib/commonjs/ui/screens/consent-details-screen.js.map +0 -1
  326. package/lib/commonjs/ui/screens/mandate-setup-success-screen.js +0 -79
  327. package/lib/commonjs/ui/screens/mandate-setup-success-screen.js.map +0 -1
  328. package/lib/commonjs/ui/widgets/layout-w-header.js +0 -106
  329. package/lib/commonjs/ui/widgets/layout-w-header.js.map +0 -1
  330. package/lib/commonjs/ui/widgets/stepper.js +0 -124
  331. package/lib/commonjs/ui/widgets/stepper.js.map +0 -1
  332. package/lib/module/core/client/link-api-client.js +0 -292
  333. package/lib/module/core/client/link-api-client.js.map +0 -1
  334. package/lib/module/core/errors/payment-api-error.js +0 -29
  335. package/lib/module/core/errors/payment-api-error.js.map +0 -1
  336. package/lib/module/core/models/link-session-status.js +0 -10
  337. package/lib/module/core/models/link-session-status.js.map +0 -1
  338. package/lib/module/core/models/payment-type.js +0 -36
  339. package/lib/module/core/models/payment-type.js.map +0 -1
  340. package/lib/module/core/models/wire-mappers.js +0 -263
  341. package/lib/module/core/models/wire-mappers.js.map +0 -1
  342. package/lib/module/core/services/consent-presenter.js +0 -140
  343. package/lib/module/core/services/consent-presenter.js.map +0 -1
  344. package/lib/module/core/services/execute-resume-if-needed.js +0 -211
  345. package/lib/module/core/services/execute-resume-if-needed.js.map +0 -1
  346. package/lib/module/core/services/multi-payment-rules-presenter.js +0 -146
  347. package/lib/module/core/services/multi-payment-rules-presenter.js.map +0 -1
  348. package/lib/module/core/services/payment-flow-controller.js +0 -544
  349. package/lib/module/core/services/payment-flow-controller.js.map +0 -1
  350. package/lib/module/core/services/payment-flow-state.js +0 -106
  351. package/lib/module/core/services/payment-flow-state.js.map +0 -1
  352. package/lib/module/core/services/payment-result-mapper.js +0 -45
  353. package/lib/module/core/services/payment-result-mapper.js.map +0 -1
  354. package/lib/module/core/services/presentation-utils.js +0 -7
  355. package/lib/module/core/services/presentation-utils.js.map +0 -1
  356. package/lib/module/core/services/redirect-buffer.js +0 -33
  357. package/lib/module/core/services/redirect-buffer.js.map +0 -1
  358. package/lib/module/core/services/user-friendly-messages.js +0 -42
  359. package/lib/module/core/services/user-friendly-messages.js.map +0 -1
  360. package/lib/module/internal/telemetry-collector.js +0 -75
  361. package/lib/module/internal/telemetry-collector.js.map +0 -1
  362. package/lib/module/public/constants.js +0 -17
  363. package/lib/module/public/constants.js.map +0 -1
  364. package/lib/module/public/spare-link-callbacks.js +0 -4
  365. package/lib/module/public/spare-link-callbacks.js.map +0 -1
  366. package/lib/module/ui/consent/charge-bearer-display.js +0 -95
  367. package/lib/module/ui/consent/charge-bearer-display.js.map +0 -1
  368. package/lib/module/ui/consent/consent-accordion.js +0 -90
  369. package/lib/module/ui/consent/consent-accordion.js.map +0 -1
  370. package/lib/module/ui/consent/consent-summary-section.js +0 -23
  371. package/lib/module/ui/consent/consent-summary-section.js.map +0 -1
  372. package/lib/module/ui/consent/cop-information.js +0 -165
  373. package/lib/module/ui/consent/cop-information.js.map +0 -1
  374. package/lib/module/ui/consent/international-payment-summary.js +0 -94
  375. package/lib/module/ui/consent/international-payment-summary.js.map +0 -1
  376. package/lib/module/ui/consent/label-value-rows.js +0 -55
  377. package/lib/module/ui/consent/label-value-rows.js.map +0 -1
  378. package/lib/module/ui/consent/multi-payment-rules-list.js +0 -125
  379. package/lib/module/ui/consent/multi-payment-rules-list.js.map +0 -1
  380. package/lib/module/ui/consent/multi-payment-summary.js +0 -95
  381. package/lib/module/ui/consent/multi-payment-summary.js.map +0 -1
  382. package/lib/module/ui/consent/single-payment-summary.js +0 -154
  383. package/lib/module/ui/consent/single-payment-summary.js.map +0 -1
  384. package/lib/module/ui/consent/terms-link.js +0 -31
  385. package/lib/module/ui/consent/terms-link.js.map +0 -1
  386. package/lib/module/ui/hooks/use-payment-flow-state.js.map +0 -1
  387. package/lib/module/ui/payment-flow-page.js +0 -232
  388. package/lib/module/ui/payment-flow-page.js.map +0 -1
  389. package/lib/module/ui/screens/bank-selection-screen.js +0 -211
  390. package/lib/module/ui/screens/bank-selection-screen.js.map +0 -1
  391. package/lib/module/ui/screens/consent-details-screen.js +0 -120
  392. package/lib/module/ui/screens/consent-details-screen.js.map +0 -1
  393. package/lib/module/ui/screens/mandate-setup-success-screen.js +0 -75
  394. package/lib/module/ui/screens/mandate-setup-success-screen.js.map +0 -1
  395. package/lib/module/ui/widgets/layout-w-header.js +0 -102
  396. package/lib/module/ui/widgets/layout-w-header.js.map +0 -1
  397. package/lib/module/ui/widgets/stepper.js +0 -120
  398. package/lib/module/ui/widgets/stepper.js.map +0 -1
  399. package/lib/typescript/commonjs/core/client/link-api-client.d.ts +0 -70
  400. package/lib/typescript/commonjs/core/client/link-api-client.d.ts.map +0 -1
  401. package/lib/typescript/commonjs/core/errors/payment-api-error.d.ts +0 -15
  402. package/lib/typescript/commonjs/core/errors/payment-api-error.d.ts.map +0 -1
  403. package/lib/typescript/commonjs/core/models/link-session-status.d.ts +0 -6
  404. package/lib/typescript/commonjs/core/models/link-session-status.d.ts.map +0 -1
  405. package/lib/typescript/commonjs/core/models/payment-type.d.ts +0 -18
  406. package/lib/typescript/commonjs/core/models/payment-type.d.ts.map +0 -1
  407. package/lib/typescript/commonjs/core/models/wire-mappers.d.ts +0 -19
  408. package/lib/typescript/commonjs/core/models/wire-mappers.d.ts.map +0 -1
  409. package/lib/typescript/commonjs/core/services/consent-presenter.d.ts +0 -67
  410. package/lib/typescript/commonjs/core/services/consent-presenter.d.ts.map +0 -1
  411. package/lib/typescript/commonjs/core/services/execute-resume-if-needed.d.ts +0 -32
  412. package/lib/typescript/commonjs/core/services/execute-resume-if-needed.d.ts.map +0 -1
  413. package/lib/typescript/commonjs/core/services/multi-payment-rules-presenter.d.ts +0 -9
  414. package/lib/typescript/commonjs/core/services/multi-payment-rules-presenter.d.ts.map +0 -1
  415. package/lib/typescript/commonjs/core/services/payment-flow-controller.d.ts +0 -146
  416. package/lib/typescript/commonjs/core/services/payment-flow-controller.d.ts.map +0 -1
  417. package/lib/typescript/commonjs/core/services/payment-flow-state.d.ts +0 -64
  418. package/lib/typescript/commonjs/core/services/payment-flow-state.d.ts.map +0 -1
  419. package/lib/typescript/commonjs/core/services/payment-result-mapper.d.ts +0 -5
  420. package/lib/typescript/commonjs/core/services/payment-result-mapper.d.ts.map +0 -1
  421. package/lib/typescript/commonjs/core/services/presentation-utils.d.ts +0 -5
  422. package/lib/typescript/commonjs/core/services/presentation-utils.d.ts.map +0 -1
  423. package/lib/typescript/commonjs/core/services/redirect-buffer.d.ts +0 -6
  424. package/lib/typescript/commonjs/core/services/redirect-buffer.d.ts.map +0 -1
  425. package/lib/typescript/commonjs/core/services/user-friendly-messages.d.ts +0 -6
  426. package/lib/typescript/commonjs/core/services/user-friendly-messages.d.ts.map +0 -1
  427. package/lib/typescript/commonjs/internal/telemetry-collector.d.ts +0 -2
  428. package/lib/typescript/commonjs/internal/telemetry-collector.d.ts.map +0 -1
  429. package/lib/typescript/commonjs/public/constants.d.ts +0 -12
  430. package/lib/typescript/commonjs/public/constants.d.ts.map +0 -1
  431. package/lib/typescript/commonjs/public/spare-link-callbacks.d.ts +0 -14
  432. package/lib/typescript/commonjs/public/spare-link-callbacks.d.ts.map +0 -1
  433. package/lib/typescript/commonjs/ui/consent/charge-bearer-display.d.ts +0 -5
  434. package/lib/typescript/commonjs/ui/consent/charge-bearer-display.d.ts.map +0 -1
  435. package/lib/typescript/commonjs/ui/consent/consent-accordion.d.ts +0 -10
  436. package/lib/typescript/commonjs/ui/consent/consent-accordion.d.ts.map +0 -1
  437. package/lib/typescript/commonjs/ui/consent/consent-summary-section.d.ts +0 -6
  438. package/lib/typescript/commonjs/ui/consent/consent-summary-section.d.ts.map +0 -1
  439. package/lib/typescript/commonjs/ui/consent/cop-information.d.ts +0 -6
  440. package/lib/typescript/commonjs/ui/consent/cop-information.d.ts.map +0 -1
  441. package/lib/typescript/commonjs/ui/consent/international-payment-summary.d.ts +0 -6
  442. package/lib/typescript/commonjs/ui/consent/international-payment-summary.d.ts.map +0 -1
  443. package/lib/typescript/commonjs/ui/consent/label-value-rows.d.ts +0 -10
  444. package/lib/typescript/commonjs/ui/consent/label-value-rows.d.ts.map +0 -1
  445. package/lib/typescript/commonjs/ui/consent/multi-payment-rules-list.d.ts +0 -15
  446. package/lib/typescript/commonjs/ui/consent/multi-payment-rules-list.d.ts.map +0 -1
  447. package/lib/typescript/commonjs/ui/consent/multi-payment-summary.d.ts +0 -6
  448. package/lib/typescript/commonjs/ui/consent/multi-payment-summary.d.ts.map +0 -1
  449. package/lib/typescript/commonjs/ui/consent/single-payment-summary.d.ts +0 -6
  450. package/lib/typescript/commonjs/ui/consent/single-payment-summary.d.ts.map +0 -1
  451. package/lib/typescript/commonjs/ui/consent/terms-link.d.ts +0 -2
  452. package/lib/typescript/commonjs/ui/consent/terms-link.d.ts.map +0 -1
  453. package/lib/typescript/commonjs/ui/hooks/use-payment-flow-state.d.ts +0 -9
  454. package/lib/typescript/commonjs/ui/hooks/use-payment-flow-state.d.ts.map +0 -1
  455. package/lib/typescript/commonjs/ui/payment-flow-page.d.ts +0 -20
  456. package/lib/typescript/commonjs/ui/payment-flow-page.d.ts.map +0 -1
  457. package/lib/typescript/commonjs/ui/screens/bank-selection-screen.d.ts +0 -15
  458. package/lib/typescript/commonjs/ui/screens/bank-selection-screen.d.ts.map +0 -1
  459. package/lib/typescript/commonjs/ui/screens/consent-details-screen.d.ts +0 -13
  460. package/lib/typescript/commonjs/ui/screens/consent-details-screen.d.ts.map +0 -1
  461. package/lib/typescript/commonjs/ui/screens/mandate-setup-success-screen.d.ts +0 -10
  462. package/lib/typescript/commonjs/ui/screens/mandate-setup-success-screen.d.ts.map +0 -1
  463. package/lib/typescript/commonjs/ui/widgets/layout-w-header.d.ts +0 -20
  464. package/lib/typescript/commonjs/ui/widgets/layout-w-header.d.ts.map +0 -1
  465. package/lib/typescript/commonjs/ui/widgets/stepper.d.ts +0 -15
  466. package/lib/typescript/commonjs/ui/widgets/stepper.d.ts.map +0 -1
  467. package/lib/typescript/module/core/client/link-api-client.d.ts +0 -70
  468. package/lib/typescript/module/core/client/link-api-client.d.ts.map +0 -1
  469. package/lib/typescript/module/core/errors/payment-api-error.d.ts +0 -15
  470. package/lib/typescript/module/core/errors/payment-api-error.d.ts.map +0 -1
  471. package/lib/typescript/module/core/models/link-session-status.d.ts +0 -6
  472. package/lib/typescript/module/core/models/link-session-status.d.ts.map +0 -1
  473. package/lib/typescript/module/core/models/payment-type.d.ts +0 -18
  474. package/lib/typescript/module/core/models/payment-type.d.ts.map +0 -1
  475. package/lib/typescript/module/core/models/wire-mappers.d.ts +0 -19
  476. package/lib/typescript/module/core/models/wire-mappers.d.ts.map +0 -1
  477. package/lib/typescript/module/core/services/consent-presenter.d.ts +0 -67
  478. package/lib/typescript/module/core/services/consent-presenter.d.ts.map +0 -1
  479. package/lib/typescript/module/core/services/execute-resume-if-needed.d.ts +0 -32
  480. package/lib/typescript/module/core/services/execute-resume-if-needed.d.ts.map +0 -1
  481. package/lib/typescript/module/core/services/multi-payment-rules-presenter.d.ts +0 -9
  482. package/lib/typescript/module/core/services/multi-payment-rules-presenter.d.ts.map +0 -1
  483. package/lib/typescript/module/core/services/payment-flow-controller.d.ts +0 -146
  484. package/lib/typescript/module/core/services/payment-flow-controller.d.ts.map +0 -1
  485. package/lib/typescript/module/core/services/payment-flow-state.d.ts +0 -64
  486. package/lib/typescript/module/core/services/payment-flow-state.d.ts.map +0 -1
  487. package/lib/typescript/module/core/services/payment-result-mapper.d.ts +0 -5
  488. package/lib/typescript/module/core/services/payment-result-mapper.d.ts.map +0 -1
  489. package/lib/typescript/module/core/services/presentation-utils.d.ts +0 -5
  490. package/lib/typescript/module/core/services/presentation-utils.d.ts.map +0 -1
  491. package/lib/typescript/module/core/services/redirect-buffer.d.ts +0 -6
  492. package/lib/typescript/module/core/services/redirect-buffer.d.ts.map +0 -1
  493. package/lib/typescript/module/core/services/user-friendly-messages.d.ts +0 -6
  494. package/lib/typescript/module/core/services/user-friendly-messages.d.ts.map +0 -1
  495. package/lib/typescript/module/internal/telemetry-collector.d.ts +0 -2
  496. package/lib/typescript/module/internal/telemetry-collector.d.ts.map +0 -1
  497. package/lib/typescript/module/public/constants.d.ts +0 -12
  498. package/lib/typescript/module/public/constants.d.ts.map +0 -1
  499. package/lib/typescript/module/public/spare-link-callbacks.d.ts +0 -14
  500. package/lib/typescript/module/public/spare-link-callbacks.d.ts.map +0 -1
  501. package/lib/typescript/module/ui/consent/charge-bearer-display.d.ts +0 -5
  502. package/lib/typescript/module/ui/consent/charge-bearer-display.d.ts.map +0 -1
  503. package/lib/typescript/module/ui/consent/consent-accordion.d.ts +0 -10
  504. package/lib/typescript/module/ui/consent/consent-accordion.d.ts.map +0 -1
  505. package/lib/typescript/module/ui/consent/consent-summary-section.d.ts +0 -6
  506. package/lib/typescript/module/ui/consent/consent-summary-section.d.ts.map +0 -1
  507. package/lib/typescript/module/ui/consent/cop-information.d.ts +0 -6
  508. package/lib/typescript/module/ui/consent/cop-information.d.ts.map +0 -1
  509. package/lib/typescript/module/ui/consent/international-payment-summary.d.ts +0 -6
  510. package/lib/typescript/module/ui/consent/international-payment-summary.d.ts.map +0 -1
  511. package/lib/typescript/module/ui/consent/label-value-rows.d.ts +0 -10
  512. package/lib/typescript/module/ui/consent/label-value-rows.d.ts.map +0 -1
  513. package/lib/typescript/module/ui/consent/multi-payment-rules-list.d.ts +0 -15
  514. package/lib/typescript/module/ui/consent/multi-payment-rules-list.d.ts.map +0 -1
  515. package/lib/typescript/module/ui/consent/multi-payment-summary.d.ts +0 -6
  516. package/lib/typescript/module/ui/consent/multi-payment-summary.d.ts.map +0 -1
  517. package/lib/typescript/module/ui/consent/single-payment-summary.d.ts +0 -6
  518. package/lib/typescript/module/ui/consent/single-payment-summary.d.ts.map +0 -1
  519. package/lib/typescript/module/ui/consent/terms-link.d.ts +0 -2
  520. package/lib/typescript/module/ui/consent/terms-link.d.ts.map +0 -1
  521. package/lib/typescript/module/ui/hooks/use-payment-flow-state.d.ts +0 -9
  522. package/lib/typescript/module/ui/hooks/use-payment-flow-state.d.ts.map +0 -1
  523. package/lib/typescript/module/ui/payment-flow-page.d.ts +0 -20
  524. package/lib/typescript/module/ui/payment-flow-page.d.ts.map +0 -1
  525. package/lib/typescript/module/ui/screens/bank-selection-screen.d.ts +0 -15
  526. package/lib/typescript/module/ui/screens/bank-selection-screen.d.ts.map +0 -1
  527. package/lib/typescript/module/ui/screens/consent-details-screen.d.ts +0 -13
  528. package/lib/typescript/module/ui/screens/consent-details-screen.d.ts.map +0 -1
  529. package/lib/typescript/module/ui/screens/mandate-setup-success-screen.d.ts +0 -10
  530. package/lib/typescript/module/ui/screens/mandate-setup-success-screen.d.ts.map +0 -1
  531. package/lib/typescript/module/ui/widgets/layout-w-header.d.ts +0 -20
  532. package/lib/typescript/module/ui/widgets/layout-w-header.d.ts.map +0 -1
  533. package/lib/typescript/module/ui/widgets/stepper.d.ts +0 -15
  534. package/lib/typescript/module/ui/widgets/stepper.d.ts.map +0 -1
  535. package/src/core/client/link-api-client.ts +0 -414
  536. package/src/core/errors/payment-api-error.ts +0 -35
  537. package/src/core/models/link-session-status.ts +0 -7
  538. package/src/core/models/payment-type.ts +0 -54
  539. package/src/core/models/wire-mappers.ts +0 -315
  540. package/src/core/services/consent-presenter.ts +0 -213
  541. package/src/core/services/execute-resume-if-needed.ts +0 -243
  542. package/src/core/services/multi-payment-rules-presenter.ts +0 -158
  543. package/src/core/services/payment-flow-controller.ts +0 -607
  544. package/src/core/services/payment-flow-state.ts +0 -124
  545. package/src/core/services/payment-result-mapper.ts +0 -41
  546. package/src/core/services/presentation-utils.ts +0 -4
  547. package/src/core/services/redirect-buffer.ts +0 -34
  548. package/src/core/services/user-friendly-messages.ts +0 -39
  549. package/src/internal/telemetry-collector.ts +0 -90
  550. package/src/public/constants.ts +0 -14
  551. package/src/public/spare-link-callbacks.ts +0 -20
  552. package/src/ui/consent/charge-bearer-display.tsx +0 -68
  553. package/src/ui/consent/consent-accordion.tsx +0 -89
  554. package/src/ui/consent/consent-summary-section.tsx +0 -19
  555. package/src/ui/consent/cop-information.tsx +0 -121
  556. package/src/ui/consent/international-payment-summary.tsx +0 -83
  557. package/src/ui/consent/label-value-rows.tsx +0 -50
  558. package/src/ui/consent/multi-payment-rules-list.tsx +0 -138
  559. package/src/ui/consent/multi-payment-summary.tsx +0 -82
  560. package/src/ui/consent/single-payment-summary.tsx +0 -123
  561. package/src/ui/consent/terms-link.tsx +0 -27
  562. package/src/ui/hooks/use-payment-flow-state.ts +0 -16
  563. package/src/ui/payment-flow-page.tsx +0 -254
  564. package/src/ui/screens/bank-selection-screen.tsx +0 -209
  565. package/src/ui/screens/consent-details-screen.tsx +0 -106
  566. package/src/ui/screens/mandate-setup-success-screen.tsx +0 -72
  567. package/src/ui/widgets/layout-w-header.tsx +0 -89
  568. package/src/ui/widgets/stepper.tsx +0 -126
@@ -1,16 +1,18 @@
1
1
  import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
- import { ActivityIndicator, Modal, SafeAreaView, StyleSheet, View } from 'react-native';
2
+ import { ActivityIndicator, Modal, StyleSheet, View } from 'react-native';
3
+ // `react-native`'s own SafeAreaView applies nothing on Android, which left the
4
+ // hosted page's header under the status bar there. This one insets both platforms.
5
+ import { SafeAreaView } from 'react-native-safe-area-context';
3
6
  import { enableScreens } from 'react-native-screens';
4
- import { LinkApiClient } from '../core/client/link-api-client';
5
- import { isPaymentReturnCallbackUri } from '../core/models/payment-return-params';
6
- import { executeResumeIfNeeded } from '../core/services/execute-resume-if-needed';
7
- import { PaymentFlowController } from '../core/services/payment-flow-controller';
7
+ import {
8
+ type PaymentReturnReport,
9
+ isPaymentReturnCallbackUri,
10
+ readPaymentReturn,
11
+ } from '../core/models/payment-return-params';
12
+ import { type BankLauncher, HostedFlowController } from '../core/services/hosted-flow-controller';
8
13
  import type { PendingSessionStore } from '../core/services/pending-session-store';
9
- import { setBufferedRedirect } from '../core/services/redirect-buffer';
10
- import { userFriendlyMessageFor } from '../core/services/user-friendly-messages';
11
- import { launchBankRedirect as defaultLaunchBankRedirect } from '../internal/bank-redirect';
12
14
  import { createLogger } from '../internal/logger';
13
- import { collectTelemetry } from '../internal/telemetry-collector';
15
+ import { redactPaymentReturnUri } from '../internal/redact-uri';
14
16
  import type { PaymentResult } from '../public/payment-result';
15
17
  import {
16
18
  paymentAbandoned,
@@ -19,10 +21,9 @@ import {
19
21
  paymentSuccess,
20
22
  } from '../public/payment-result';
21
23
  import type { RecoveryResult } from '../public/recovery-result';
22
- import { tenantCountryCode } from '../public/spare-link-config';
23
- import { type SpareLinkEventType, SpareLinkEvents } from '../public/spare-link-event';
24
- import { type SpareLink, mapHostRecovery, noRecovery } from '../public/spare-link-instance';
25
- import { PaymentFlowPage } from './payment-flow-page';
24
+ import { SpareLinkEvents } from '../public/spare-link-event';
25
+ import { type SpareLink, noRecovery } from '../public/spare-link-instance';
26
+ import { HostedPaymentPage } from './hosted/hosted-payment-page';
26
27
  import { Colors } from './theme';
27
28
  import { useLinkFonts } from './theme/fonts';
28
29
  import { ModalDismissButton } from './widgets/modal-dismiss-button';
@@ -32,10 +33,9 @@ enableScreens();
32
33
  const log = createLogger('SpareLinkHost');
33
34
 
34
35
  interface ActiveFlow {
35
- controller: PaymentFlowController;
36
- linkToken: string;
36
+ controller: HostedFlowController;
37
+ reference: string;
37
38
  resolve: (result: PaymentResult) => void;
38
- onSessionLoaded?: (linkSessionId: string) => void;
39
39
  }
40
40
 
41
41
  export interface SpareLinkHostProps {
@@ -46,14 +46,15 @@ export interface SpareLinkHostProps {
46
46
  * When omitted, uses `spareLink.pendingSessionStore`.
47
47
  */
48
48
  pendingSessionStore?: PendingSessionStore;
49
- launchBankRedirect?: (args: { authorizationUrl: string; mobileAppUrl?: string }) => Promise<void>;
49
+ /** Override how a bank authorization URL is opened. Tests inject a fake. */
50
+ launchBankRedirect?: BankLauncher;
50
51
  showDismissButton?: boolean;
51
52
  children?: React.ReactNode;
52
53
  }
53
54
 
54
55
  /**
55
56
  * Host component that mounts the SDK modal and connects a {@link SpareLink}
56
- * instance — Flutter-aligned integration (one instance, one host).
57
+ * instance — one instance, one host.
57
58
  */
58
59
  export function SpareLinkHost(props: SpareLinkHostProps): JSX.Element {
59
60
  const { spareLink, showDismissButton = true, launchBankRedirect } = props;
@@ -62,37 +63,38 @@ export function SpareLinkHost(props: SpareLinkHostProps): JSX.Element {
62
63
  const [active, setActive] = useState<ActiveFlow | null>(null);
63
64
  const activeRef = useRef<ActiveFlow | null>(null);
64
65
 
66
+ /** A return that arrived before there was a flow to give it to. */
67
+ const bufferedRedirect = useRef<string | null>(null);
68
+
65
69
  useEffect(() => {
66
70
  activeRef.current = active;
67
71
  }, [active]);
68
72
 
69
- const emitMappedEvent = useCallback(
70
- (linkToken: string, event: SpareLinkEventType, linkSessionId?: string) => {
71
- switch (event) {
72
- case 'sessionLoaded':
73
- spareLink.emitEvent(SpareLinkEvents.sessionLoaded(linkToken, linkSessionId));
74
- break;
75
- case 'consentStarted':
76
- spareLink.emitEvent(SpareLinkEvents.consentStarted(linkToken));
77
- break;
78
- case 'redirectToBank':
79
- spareLink.emitEvent(SpareLinkEvents.redirectToBank(linkToken));
80
- break;
81
- case 'bankCallbackReceived':
82
- spareLink.emitEvent(SpareLinkEvents.bankCallbackReceived(linkToken));
83
- break;
84
- default:
85
- break;
86
- }
87
- },
88
- [spareLink],
89
- );
73
+ /**
74
+ * Serializes every write to the pending-session store.
75
+ *
76
+ * The store is pluggable, so it cannot be assumed to order its own writes: a
77
+ * `clear` overtaking a slow `save` would leave a record for a payment that has
78
+ * already resolved, and the next cold start would offer to recover it.
79
+ */
80
+ const persistQueue = useRef<Promise<unknown>>(Promise.resolve());
81
+ const enqueuePersist = useCallback((op: () => Promise<void>): Promise<void> => {
82
+ const next = persistQueue.current.then(op, op);
83
+ // Kept un-rejected so one failure does not poison the queue behind it.
84
+ persistQueue.current = next.catch(() => undefined);
85
+ return next;
86
+ }, []);
87
+
88
+ const clearPending = useCallback(() => {
89
+ if (!pendingSessionStore) return;
90
+ void enqueuePersist(() => pendingSessionStore.clear()).catch(() => {
91
+ log.warning('could not clear the pending payment — continuing');
92
+ });
93
+ }, [pendingSessionStore, enqueuePersist]);
90
94
 
91
95
  const close = useCallback(
92
96
  (flow: ActiveFlow, result: PaymentResult) => {
93
- void pendingSessionStore?.clear().catch(() => {
94
- log.warning('close: pendingSessionStore.clear() failed — continuing');
95
- });
97
+ clearPending();
96
98
  flow.resolve(result);
97
99
  flow.controller.dispose();
98
100
  if (activeRef.current === flow) {
@@ -100,22 +102,46 @@ export function SpareLinkHost(props: SpareLinkHostProps): JSX.Element {
100
102
  setActive(null);
101
103
  }
102
104
  },
103
- [pendingSessionStore],
105
+ [clearPending],
104
106
  );
105
107
 
108
+ /** Maps a resolved flow onto the result the caller awaits. */
109
+ const resultFor = useCallback((flow: ActiveFlow): PaymentResult => {
110
+ const s = flow.controller.state;
111
+ const base = {
112
+ reference: s.reference,
113
+ ...reportedFields(s.report),
114
+ resolvedAtMs: Date.now(),
115
+ };
116
+ switch (s.phase) {
117
+ case 'succeeded':
118
+ return paymentSuccess(base);
119
+ case 'cancelled':
120
+ return paymentCancelled(base);
121
+ case 'failed':
122
+ return paymentFailed({ ...base, errorCode: s.errorCode ?? 'internal_error' });
123
+ default:
124
+ // Anything else resolving is the payer leaving mid-flow, which may still
125
+ // complete at the bank — so it is reported as unresolved, not as a failure.
126
+ return paymentAbandoned(base);
127
+ }
128
+ }, []);
129
+
130
+ const onResolved = useCallback(() => {
131
+ const current = activeRef.current;
132
+ if (!current) return;
133
+ close(current, resultFor(current));
134
+ }, [close, resultFor]);
135
+
106
136
  const startFlow = useCallback(
107
- (args: {
108
- linkToken: string;
109
- resolve: (result: PaymentResult) => void;
110
- onSessionLoaded?: (linkSessionId: string) => void;
111
- }) => {
137
+ (args: { reference: string; resolve: (result: PaymentResult) => void }) => {
112
138
  if (activeRef.current) {
113
- log.warning('start: a payment flow is already in progress — rejecting concurrent call');
139
+ log.warning('start: a payment is already in progress — rejecting concurrent call');
114
140
  args.resolve(
115
141
  paymentFailed({
116
- linkToken: args.linkToken,
142
+ reference: args.reference,
117
143
  errorCode: 'concurrent_start',
118
- message: 'A payment flow is already in progress.',
144
+ message: 'A payment is already in progress.',
119
145
  resolvedAtMs: Date.now(),
120
146
  }),
121
147
  );
@@ -123,159 +149,142 @@ export function SpareLinkHost(props: SpareLinkHostProps): JSX.Element {
123
149
  }
124
150
 
125
151
  log.info(`start: tenant=${spareLink.tenant}, environment=${spareLink.environment}`);
126
- const controller = new PaymentFlowController({
127
- sessionToken: args.linkToken,
128
- environment: spareLink.environment,
129
- apiClient: new LinkApiClient({
130
- baseUrl: spareLink.resolvedBaseUrl,
131
- tenant: tenantCountryCode(spareLink.tenant),
132
- ...(spareLink.fetch ? { fetch: spareLink.fetch } : {}),
133
- ...(spareLink.requestTimeoutMs !== undefined
134
- ? { requestTimeoutMs: spareLink.requestTimeoutMs }
135
- : {}),
136
- }),
137
- collectTelemetry,
138
- ...(pendingSessionStore ? { pendingSessionStore } : {}),
139
- onEvent: (event) => {
140
- emitMappedEvent(args.linkToken, event as SpareLinkEventType);
141
- if (event === 'sessionLoaded') {
142
- const linkSessionId = controller.state.linkSessionId;
143
- if (linkSessionId) {
144
- args.onSessionLoaded?.(linkSessionId);
145
- }
146
- }
147
- },
152
+
153
+ const controller = new HostedFlowController({
154
+ reference: args.reference,
155
+ ...(launchBankRedirect ? { bankLauncher: launchBankRedirect } : {}),
148
156
  });
149
157
 
150
158
  const flow: ActiveFlow = {
151
159
  controller,
152
- linkToken: args.linkToken,
160
+ reference: args.reference,
153
161
  resolve: args.resolve,
154
- ...(args.onSessionLoaded ? { onSessionLoaded: args.onSessionLoaded } : {}),
155
162
  };
156
- activeRef.current = flow;
157
- setActive(flow);
158
163
 
159
- void controller.hydrate().catch((err) => {
160
- log.severe(`start: hydration failed — ${err instanceof Error ? err.message : String(err)}`);
161
- close(
162
- flow,
163
- paymentFailed({
164
- linkToken: args.linkToken,
165
- errorCode: 'hydration_error',
166
- message: 'Unable to load payment session. Please try again.',
167
- resolvedAtMs: Date.now(),
168
- }),
169
- );
164
+ controller.subscribe(() => {
165
+ const phase = controller.state.phase;
166
+ if (phase === 'hosted') {
167
+ spareLink.emitEvent(SpareLinkEvents.pageReady(args.reference));
168
+ } else if (phase === 'redirecting') {
169
+ spareLink.emitEvent(SpareLinkEvents.redirectToBank(args.reference));
170
+ }
170
171
  });
172
+
173
+ // Claimed synchronously so a second `start` in the same tick is rejected by
174
+ // the guard above rather than racing this one.
175
+ activeRef.current = flow;
176
+
177
+ // Recorded *before* the page is presented, so the payer cannot reach their
178
+ // bank on a payment a cold start would not know about. A store that cannot
179
+ // write is not a reason to refuse the payment.
180
+ const present = () => {
181
+ if (activeRef.current !== flow) return;
182
+ setActive(flow);
183
+
184
+ // A return can beat the page onto the screen when the app was resumed
185
+ // rather than launched, so replay one that arrived before there was a flow.
186
+ const buffered = bufferedRedirect.current;
187
+ if (buffered) {
188
+ bufferedRedirect.current = null;
189
+ controller.handleReturn(buffered);
190
+ }
191
+ };
192
+
193
+ if (!pendingSessionStore) {
194
+ present();
195
+ return;
196
+ }
197
+
198
+ void enqueuePersist(() => pendingSessionStore.save({ reference: args.reference }))
199
+ .catch(() => {
200
+ log.warning('could not record the pending payment — continuing');
201
+ })
202
+ .finally(present);
171
203
  },
172
- [spareLink, pendingSessionStore, emitMappedEvent, close],
204
+ [spareLink, pendingSessionStore, launchBankRedirect, enqueuePersist],
173
205
  );
174
206
 
175
207
  const handleRedirect = useCallback(
176
208
  async (uri: URL | string): Promise<boolean> => {
177
- const current = activeRef.current;
178
209
  const asString = typeof uri === 'string' ? uri : uri.toString();
210
+ log.info(`handleRedirect: ${redactPaymentReturnUri(asString)}`);
211
+
212
+ if (!isPaymentReturnCallbackUri(asString)) return false;
213
+
214
+ const current = activeRef.current;
179
215
  if (!current) {
180
- if (!isPaymentReturnCallbackUri(asString)) {
181
- log.fine('handleRedirect: URI does not belong to payment flow — ignoring');
182
- return false;
183
- }
184
- setBufferedRedirect(asString);
185
- log.info('handleRedirect: no active controller — buffering URI for recovery');
216
+ log.info('handleRedirect: no active payment — holding for recovery');
217
+ bufferedRedirect.current = asString;
186
218
  return true;
187
219
  }
188
- if (!isPaymentReturnCallbackUri(asString)) {
189
- log.fine('handleRedirect: URI does not belong to payment flow — ignoring');
190
- return false;
191
- }
192
- log.info('handleRedirect: forwarding to controller');
193
- try {
194
- current.controller.handleCallback(uri);
195
- spareLink.emitEvent(SpareLinkEvents.bankCallbackReceived(current.linkToken));
196
- return true;
197
- } catch {
198
- return false;
199
- }
200
- },
201
- [spareLink],
202
- );
203
220
 
204
- const openRecoveryFlow = useCallback(
205
- (args: {
206
- controller: PaymentFlowController;
207
- linkToken: string;
208
- resolve?: (result: PaymentResult) => void;
209
- }) => {
210
- if (activeRef.current) {
211
- args.controller.dispose();
212
- return;
213
- }
214
- const flow: ActiveFlow = {
215
- controller: args.controller,
216
- linkToken: args.linkToken,
217
- resolve:
218
- args.resolve ??
219
- (() => {
220
- /* recovery UI only */
221
- }),
222
- };
223
- activeRef.current = flow;
224
- setActive(flow);
225
- spareLink.emitEvent(SpareLinkEvents.initialized(args.linkToken));
221
+ spareLink.emitEvent(SpareLinkEvents.bankCallbackReceived(current.reference));
222
+ current.controller.handleReturn(asString);
223
+ return true;
226
224
  },
227
225
  [spareLink],
228
226
  );
229
227
 
230
228
  const resumeIfNeeded = useCallback(async (): Promise<RecoveryResult> => {
231
- if (!pendingSessionStore) {
229
+ if (activeRef.current) return noRecovery('flowAlreadyActive');
230
+ if (!pendingSessionStore) return noRecovery('persistenceUnavailable');
231
+
232
+ let record: { reference: string } | null = null;
233
+ try {
234
+ record = await pendingSessionStore.load();
235
+ } catch {
236
+ log.warning('resumeIfNeeded: could not read the pending payment');
232
237
  return noRecovery('persistenceUnavailable');
233
238
  }
234
- if (activeRef.current) {
235
- return noRecovery('flowAlreadyActive');
236
- }
237
239
 
238
- let flowOpened = false;
239
- let openedLinkToken: string | undefined;
240
-
241
- const terminal = await executeResumeIfNeeded(
242
- {
243
- config: {
244
- environment: spareLink.environment,
245
- tenant: spareLink.tenant,
246
- ...(spareLink.baseUrl ? { baseUrl: spareLink.baseUrl } : {}),
247
- ...(spareLink.fetch ? { fetch: spareLink.fetch } : {}),
248
- ...(spareLink.requestTimeoutMs !== undefined
249
- ? { requestTimeoutMs: spareLink.requestTimeoutMs }
250
- : {}),
251
- },
252
- },
253
- {
254
- pendingSessionStore,
255
- isFlowActive: () => activeRef.current != null,
256
- openRecoveryFlow: ({ controller, config }) => {
257
- flowOpened = true;
258
- openedLinkToken = config.linkToken;
259
- openRecoveryFlow({
260
- controller,
261
- linkToken: config.linkToken,
262
- resolve: (result) => {
263
- spareLink.emitTerminal(result);
264
- },
265
- });
266
- },
267
- },
268
- );
240
+ if (!record) return noRecovery('noPendingSession');
269
241
 
270
- if (terminal) {
271
- spareLink.emitTerminal(terminal);
272
- return { kind: 'recovered', result: terminal };
273
- }
274
- if (flowOpened && openedLinkToken) {
275
- return mapHostRecovery({ kind: 'inProgress', linkToken: openedLinkToken });
242
+ const buffered = bufferedRedirect.current;
243
+ if (buffered) {
244
+ const { outcome, report } = readPaymentReturn(buffered);
245
+
246
+ // The buffered link is only this payment's if it says so. Pairing whatever
247
+ // arrived with whatever was persisted is how a callback for one payment
248
+ // resolves another.
249
+ if (report.reference !== undefined && report.reference !== record.reference) {
250
+ log.warning('resumeIfNeeded: the buffered return names a different payment — keeping it');
251
+ return noRecovery('outcomeUnknown', record.reference);
252
+ }
253
+
254
+ bufferedRedirect.current = null;
255
+ clearPending();
256
+
257
+ const base = {
258
+ reference: record.reference,
259
+ ...reportedFields(report),
260
+ resolvedAtMs: Date.now(),
261
+ };
262
+
263
+ // A return that did not say what happened is not a failure — the backend
264
+ // holds the outcome, which is what `outcomeUnknown` tells the caller.
265
+ if (outcome === 'unknown') {
266
+ log.info('resumeIfNeeded: the buffered return did not say what happened');
267
+ return noRecovery('outcomeUnknown', record.reference);
268
+ }
269
+
270
+ const result: PaymentResult =
271
+ outcome === 'processed'
272
+ ? paymentSuccess(base)
273
+ : paymentFailed({
274
+ ...base,
275
+ errorCode: report.errorCode ?? 'authorize_failed',
276
+ });
277
+
278
+ spareLink.emitTerminal(result);
279
+ return { kind: 'recovered', result };
276
280
  }
277
- return noRecovery('noPendingSession');
278
- }, [pendingSessionStore, spareLink, openRecoveryFlow]);
281
+
282
+ log.info(
283
+ 'resumeIfNeeded: a payment was pending and no return arrived — the backend holds the outcome',
284
+ );
285
+ clearPending();
286
+ return noRecovery('outcomeUnknown', record.reference);
287
+ }, [pendingSessionStore, spareLink, clearPending]);
279
288
 
280
289
  useEffect(() => {
281
290
  const detach = spareLink._attachHost({
@@ -287,67 +296,34 @@ export function SpareLinkHost(props: SpareLinkHostProps): JSX.Element {
287
296
  return detach;
288
297
  }, [spareLink, startFlow, handleRedirect, resumeIfNeeded]);
289
298
 
290
- const onResolved = useCallback(() => {
299
+ /**
300
+ * A dismiss mid-flow means the payer left, which the caller must hear about — a
301
+ * silent close would strand whoever is awaiting the result.
302
+ */
303
+ const onDismissPressed = useCallback(() => {
291
304
  const current = activeRef.current;
292
305
  if (!current) return;
293
- const s = current.controller.state;
294
- let result: PaymentResult;
295
- switch (s.phase) {
296
- case 'succeeded':
297
- result = paymentSuccess({
298
- linkToken: current.linkToken,
299
- ...(s.exchangeCode ? { exchangeCode: s.exchangeCode } : {}),
300
- ...(s.linkSessionId ? { linkSessionId: s.linkSessionId } : {}),
301
- ...(s.merchantRef ? { merchantRef: s.merchantRef } : {}),
302
- ...(s.selectedProvider ? { bankId: s.selectedProvider.id } : {}),
303
- ...(s.session?.request?.type ? { paymentType: s.session.request.type } : {}),
304
- resolvedAtMs: Date.now(),
305
- });
306
- break;
307
- case 'failed': {
308
- const errorCode = s.errorCode ?? 'unknown_error';
309
- result = paymentFailed({
310
- linkToken: current.linkToken,
311
- errorCode,
312
- message: userFriendlyMessageFor(errorCode),
313
- resolvedAtMs: Date.now(),
314
- });
315
- break;
316
- }
317
- case 'cancelled':
318
- result = paymentCancelled({
319
- linkToken: current.linkToken,
320
- resolvedAtMs: Date.now(),
321
- });
322
- break;
323
- default:
324
- result = paymentAbandoned({
325
- linkToken: current.linkToken,
326
- resolvedAtMs: Date.now(),
327
- });
328
- break;
329
- }
330
- close(current, result);
331
- }, [close]);
306
+ current.controller.abandon();
307
+ close(current, resultFor(current));
308
+ }, [close, resultFor]);
332
309
 
333
- const onDismissPressed = useCallback(() => {
334
- const current = activeRef.current;
335
- if (!current) {
336
- onResolved();
337
- return;
310
+ const modalBody = useMemo(() => {
311
+ if (!active) return null;
312
+ if (!fontsLoaded) {
313
+ return (
314
+ <View style={styles.fontLoading}>
315
+ <ActivityIndicator size="large" color={Colors.spareBlue} />
316
+ </View>
317
+ );
338
318
  }
339
- spareLink.emitEvent(
340
- SpareLinkEvents.abandoned(
341
- paymentAbandoned({ linkToken: current.linkToken, resolvedAtMs: Date.now() }),
342
- ),
319
+ return (
320
+ <HostedPaymentPage
321
+ controller={active.controller}
322
+ baseUrl={spareLink.resolvedBaseUrl}
323
+ onResolved={onResolved}
324
+ />
343
325
  );
344
- void current.controller.cancel().finally(onResolved);
345
- }, [onResolved, spareLink]);
346
-
347
- const launcher = useMemo(
348
- () => launchBankRedirect ?? defaultLaunchBankRedirect,
349
- [launchBankRedirect],
350
- );
326
+ }, [active, fontsLoaded, spareLink, onResolved]);
351
327
 
352
328
  return (
353
329
  <>
@@ -366,21 +342,7 @@ export function SpareLinkHost(props: SpareLinkHostProps): JSX.Element {
366
342
  testID="spare-link-modal-root"
367
343
  >
368
344
  <ModalDismissButton visible={showDismissButton} onPress={onDismissPressed} />
369
- {active ? (
370
- <View style={styles.flowWrap}>
371
- {fontsLoaded ? (
372
- <PaymentFlowPage
373
- controller={active.controller}
374
- onResolved={onResolved}
375
- launchBankRedirect={launcher}
376
- />
377
- ) : (
378
- <View style={styles.fontLoading}>
379
- <ActivityIndicator size="large" color={Colors.spareBlue} />
380
- </View>
381
- )}
382
- </View>
383
- ) : null}
345
+ {active ? <View style={styles.flowWrap}>{modalBody}</View> : null}
384
346
  </SafeAreaView>
385
347
  </Modal>
386
348
  </>
@@ -392,3 +354,21 @@ const styles = StyleSheet.create({
392
354
  flowWrap: { flex: 1 },
393
355
  fontLoading: { flex: 1, alignItems: 'center', justifyContent: 'center' },
394
356
  });
357
+
358
+ /**
359
+ * Lifts what the return reported onto the result the caller awaits.
360
+ *
361
+ * `errorCode` is not among them: a failure's code has a fallback the report does
362
+ * not, so it is set where the failure is built.
363
+ */
364
+ function reportedFields(report: PaymentReturnReport | undefined) {
365
+ if (!report) return {};
366
+ return {
367
+ ...(report.merchantRef ? { merchantRef: report.merchantRef } : {}),
368
+ ...(report.paymentId ? { paymentId: report.paymentId } : {}),
369
+ ...(report.mandateId ? { mandateId: report.mandateId } : {}),
370
+ ...(report.signature ? { signature: report.signature } : {}),
371
+ ...(report.errorReason ? { errorReason: report.errorReason } : {}),
372
+ ...(report.errorDescription ? { message: report.errorDescription } : {}),
373
+ };
374
+ }
@@ -1,5 +1,4 @@
1
- export { CustomStepper, type CustomStepperProps } from './stepper';
2
- export { LayoutWHeader, type LayoutWHeaderProps } from './layout-w-header';
3
1
  export { Footer, type FooterProps } from './footer';
4
2
  export { GradientSpinner, type GradientSpinnerProps } from './gradient-spinner';
5
3
  export { HandoffScreenLayout, type HandoffScreenLayoutProps } from './handoff-screen-layout';
4
+ export { ModalDismissButton, type ModalDismissButtonProps } from './modal-dismiss-button';
package/src/version.ts CHANGED
@@ -6,4 +6,4 @@
6
6
  * `changeset version`). The src/index.ts smoke test asserts this matches
7
7
  * package.json's version.
8
8
  */
9
- export const SDK_VERSION = '0.1.0-beta.1' as const;
9
+ export const SDK_VERSION = '1.0.1' as const;
package/CHANGELOG.md DELETED
@@ -1,25 +0,0 @@
1
- # @spare-technologies/spare-link
2
-
3
- ## 0.1.0-beta.1
4
-
5
- ### Patch Changes
6
-
7
- - [#4](https://github.com/spare-technologies/link-rn/pull/4) [`af05ad2`](https://github.com/spare-technologies/link-rn/commit/af05ad2372b2c96c619f7fc9c06c9085768a406b) Thanks [@bkmehata](https://github.com/bkmehata)! - Clean up published docs and package metadata.
8
-
9
- - Fix the `LICENSE` link in the README so it resolves inside the published package.
10
- - Remove README references to an internal-only test package that consumers can't install, plus a stale changelog section describing a removed API.
11
- - Drop an internal, dev-only entry from the published `package.json` dependency list.
12
-
13
- ## 0.1.0-beta.0
14
-
15
- ### Minor Changes
16
-
17
- - [#1](https://github.com/spare-technologies/link-rn/pull/1) [`bc3040c`](https://github.com/spare-technologies/link-rn/commit/bc3040c58ab63934d81f1ead0083293f2e0ed164) Thanks [@bdspare](https://github.com/bdspare)! - Initial public beta of `@spare-technologies/spare-link` — the React Native SDK for Spare Link open-banking payments.
18
-
19
- - Instance-based API: construct one `SpareLink`, mount one `<SpareLinkHost>`, and call `spareLink.start({ linkToken })` — `session.result` resolves to a discriminated `PaymentResult` (`success | cancelled | failed | abandoned`).
20
- - 9-phase `PaymentFlowController` with a 5-minute awaiting-callback timeout, single/multi-payment (mandate) and international consent UIs, and Confirmation-of-Payee gating.
21
- - Cold-start recovery via `spareLink.resumeIfNeeded()` returning a typed `RecoveryResult` (`recovered | awaitingUser | none`), backed by `SecureStorePendingSessionStore` (capped at 3 attempts via `kMaxRecoveryAttempts`).
22
- - `LinkApiClient` with full header parity (`x-link-token`, `X-Tenant`, stable `Idempotency-Key`), retry on 408/502/503, and a 15s default timeout.
23
- - Deep-link wiring via `useSpareLinkDeepLinks(spareLink)` and `spareLink.handleRedirect(uri)`.
24
- - Expo config plugin (`@spare-technologies/spare-link/expo-plugin`) shipping iOS + Android permission and deep-link setup.
25
- - Ships compiled CommonJS + ESM + TypeScript declarations, with `src` retained for Metro consumers.