@payez/next-mvp 4.0.1 → 4.0.2

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 (433) hide show
  1. package/dist/api/auth-handler.d.ts +66 -0
  2. package/dist/api/auth-handler.js +397 -0
  3. package/dist/api/index.d.ts +10 -0
  4. package/dist/api/index.js +19 -0
  5. package/dist/api-handlers/account/change-password.d.ts +9 -0
  6. package/dist/api-handlers/account/change-password.js +110 -0
  7. package/dist/api-handlers/account/masked-info.d.ts +2 -0
  8. package/dist/api-handlers/account/masked-info.js +41 -0
  9. package/dist/api-handlers/account/profile.d.ts +3 -0
  10. package/dist/api-handlers/account/profile.js +63 -0
  11. package/dist/api-handlers/account/recovery/initiate.d.ts +2 -0
  12. package/dist/api-handlers/account/recovery/initiate.js +26 -0
  13. package/dist/api-handlers/account/recovery/send-code.d.ts +2 -0
  14. package/dist/api-handlers/account/recovery/send-code.js +28 -0
  15. package/dist/api-handlers/account/recovery/verify-code.d.ts +2 -0
  16. package/dist/api-handlers/account/recovery/verify-code.js +28 -0
  17. package/dist/api-handlers/account/reset-password.d.ts +2 -0
  18. package/dist/api-handlers/account/reset-password.js +26 -0
  19. package/dist/api-handlers/account/send-code.d.ts +24 -0
  20. package/dist/api-handlers/account/send-code.js +60 -0
  21. package/dist/api-handlers/account/update-phone.d.ts +27 -0
  22. package/dist/api-handlers/account/update-phone.js +64 -0
  23. package/dist/api-handlers/account/validate-password.d.ts +17 -0
  24. package/dist/api-handlers/account/validate-password.js +81 -0
  25. package/dist/api-handlers/account/verify-email.d.ts +26 -0
  26. package/dist/api-handlers/account/verify-email.js +106 -0
  27. package/dist/api-handlers/account/verify-sms.d.ts +26 -0
  28. package/dist/api-handlers/account/verify-sms.js +106 -0
  29. package/dist/api-handlers/admin/analytics.d.ts +19 -0
  30. package/dist/api-handlers/admin/analytics.js +378 -0
  31. package/dist/api-handlers/admin/audit.d.ts +19 -0
  32. package/dist/api-handlers/admin/audit.js +213 -0
  33. package/dist/api-handlers/admin/index.d.ts +21 -0
  34. package/dist/api-handlers/admin/index.js +42 -0
  35. package/dist/api-handlers/admin/redis-sessions.d.ts +35 -0
  36. package/dist/api-handlers/admin/redis-sessions.js +203 -0
  37. package/dist/api-handlers/admin/sessions.d.ts +20 -0
  38. package/dist/api-handlers/admin/sessions.js +283 -0
  39. package/dist/api-handlers/admin/site-logs.d.ts +45 -0
  40. package/dist/api-handlers/admin/site-logs.js +317 -0
  41. package/dist/api-handlers/admin/stats.d.ts +20 -0
  42. package/dist/api-handlers/admin/stats.js +239 -0
  43. package/dist/api-handlers/admin/users.d.ts +19 -0
  44. package/dist/api-handlers/admin/users.js +221 -0
  45. package/dist/api-handlers/admin/vibe-data.d.ts +79 -0
  46. package/dist/api-handlers/admin/vibe-data.js +267 -0
  47. package/dist/api-handlers/anon/preferences.d.ts +37 -0
  48. package/dist/api-handlers/anon/preferences.js +96 -0
  49. package/dist/api-handlers/auth/jwks.d.ts +2 -0
  50. package/dist/api-handlers/auth/jwks.js +24 -0
  51. package/dist/api-handlers/auth/login.d.ts +42 -0
  52. package/dist/api-handlers/auth/login.js +178 -0
  53. package/dist/api-handlers/auth/refresh.d.ts +74 -0
  54. package/dist/api-handlers/auth/refresh.js +633 -0
  55. package/dist/api-handlers/auth/signout.d.ts +37 -0
  56. package/dist/api-handlers/auth/signout.js +186 -0
  57. package/dist/api-handlers/auth/status.d.ts +8 -0
  58. package/dist/api-handlers/auth/status.js +23 -0
  59. package/dist/api-handlers/auth/update-session.d.ts +37 -0
  60. package/dist/api-handlers/auth/update-session.js +93 -0
  61. package/dist/api-handlers/auth/validate.d.ts +6 -0
  62. package/dist/api-handlers/auth/validate.js +43 -0
  63. package/dist/api-handlers/auth/verify-code.d.ts +43 -0
  64. package/dist/api-handlers/auth/verify-code.js +90 -0
  65. package/dist/api-handlers/session/refresh-viability.d.ts +14 -0
  66. package/dist/api-handlers/session/refresh-viability.js +39 -0
  67. package/dist/api-handlers/session/viability.d.ts +13 -0
  68. package/dist/api-handlers/session/viability.js +114 -0
  69. package/dist/api-handlers/test/force-expire.d.ts +23 -0
  70. package/dist/api-handlers/test/force-expire.js +59 -0
  71. package/dist/auth/auth-decision.d.ts +39 -0
  72. package/dist/auth/auth-decision.js +182 -0
  73. package/dist/auth/better-auth.d.ts +79 -0
  74. package/dist/auth/better-auth.js +119 -0
  75. package/dist/auth/route-config.d.ts +66 -0
  76. package/dist/auth/route-config.js +190 -0
  77. package/dist/auth/types/auth-types.d.ts +417 -0
  78. package/dist/auth/types/auth-types.js +53 -0
  79. package/dist/auth/types/index.d.ts +6 -0
  80. package/dist/auth/types/index.js +22 -0
  81. package/dist/auth/unauthenticated-routes.d.ts +1 -0
  82. package/dist/auth/unauthenticated-routes.js +19 -0
  83. package/dist/auth/utils/idp-client.d.ts +94 -0
  84. package/dist/auth/utils/idp-client.js +384 -0
  85. package/dist/auth/utils/index.d.ts +5 -0
  86. package/dist/auth/utils/index.js +21 -0
  87. package/dist/auth/utils/token-utils.d.ts +83 -0
  88. package/dist/auth/utils/token-utils.js +218 -0
  89. package/dist/client/AuthContext.d.ts +19 -0
  90. package/dist/client/AuthContext.js +115 -0
  91. package/dist/client/better-auth-client.d.ts +1020 -0
  92. package/dist/client/better-auth-client.js +68 -0
  93. package/dist/client/fetch-with-auth.d.ts +11 -0
  94. package/dist/client/fetch-with-auth.js +44 -0
  95. package/dist/client/fetchWithSession.d.ts +3 -0
  96. package/dist/client/fetchWithSession.js +24 -0
  97. package/dist/client/index.d.ts +9 -0
  98. package/dist/client/index.js +20 -0
  99. package/dist/client/useAnonSession.d.ts +36 -0
  100. package/dist/client/useAnonSession.js +99 -0
  101. package/dist/components/SessionSync.d.ts +13 -0
  102. package/dist/components/SessionSync.js +121 -0
  103. package/dist/components/SignalRHealthCheck.d.ts +10 -0
  104. package/dist/components/SignalRHealthCheck.js +97 -0
  105. package/dist/components/account/MobileNavDrawer.d.ts +32 -0
  106. package/dist/components/account/MobileNavDrawer.js +81 -0
  107. package/dist/components/account/UserAvatarMenu.d.ts +20 -0
  108. package/dist/components/account/UserAvatarMenu.js +91 -0
  109. package/dist/components/account/index.d.ts +9 -0
  110. package/dist/components/account/index.js +13 -0
  111. package/dist/components/admin/AlertSettingsTab.d.ts +48 -0
  112. package/dist/components/admin/AlertSettingsTab.js +351 -0
  113. package/dist/components/admin/AnalyticsTab.d.ts +22 -0
  114. package/dist/components/admin/AnalyticsTab.js +167 -0
  115. package/dist/components/admin/DataBrowserTab.d.ts +19 -0
  116. package/dist/components/admin/DataBrowserTab.js +252 -0
  117. package/dist/components/admin/LoggingSettingsTab.d.ts +73 -0
  118. package/dist/components/admin/LoggingSettingsTab.js +339 -0
  119. package/dist/components/admin/SessionsTab.d.ts +37 -0
  120. package/dist/components/admin/SessionsTab.js +165 -0
  121. package/dist/components/admin/StatsTab.d.ts +53 -0
  122. package/dist/components/admin/StatsTab.js +161 -0
  123. package/dist/components/admin/VibeAdminContext.d.ts +32 -0
  124. package/dist/components/admin/VibeAdminContext.js +38 -0
  125. package/dist/components/admin/VibeAdminLayout.d.ts +11 -0
  126. package/dist/components/admin/VibeAdminLayout.js +71 -0
  127. package/dist/components/admin/index.d.ts +29 -0
  128. package/dist/components/admin/index.js +44 -0
  129. package/dist/components/auth/FederatedAuthSection.d.ts +8 -0
  130. package/dist/components/auth/FederatedAuthSection.js +45 -0
  131. package/dist/components/auth/ModeAwareLoginPage.d.ts +10 -0
  132. package/dist/components/auth/ModeAwareLoginPage.js +42 -0
  133. package/dist/components/auth/ModeAwareSignupPage.d.ts +9 -0
  134. package/dist/components/auth/ModeAwareSignupPage.js +78 -0
  135. package/dist/components/auth/TraditionalAuthSection.d.ts +14 -0
  136. package/dist/components/auth/TraditionalAuthSection.js +20 -0
  137. package/dist/components/recovery/CompleteStep.d.ts +5 -0
  138. package/dist/components/recovery/CompleteStep.js +8 -0
  139. package/dist/components/recovery/InitiateRecoveryStep.d.ts +8 -0
  140. package/dist/components/recovery/InitiateRecoveryStep.js +20 -0
  141. package/dist/components/recovery/SelectMethodStep.d.ts +8 -0
  142. package/dist/components/recovery/SelectMethodStep.js +8 -0
  143. package/dist/components/recovery/SetPasswordStep.d.ts +6 -0
  144. package/dist/components/recovery/SetPasswordStep.js +20 -0
  145. package/dist/components/recovery/VerifyCodeStep.d.ts +10 -0
  146. package/dist/components/recovery/VerifyCodeStep.js +24 -0
  147. package/dist/components/reserved/ReservedRecoveryWarning.d.ts +38 -0
  148. package/dist/components/reserved/ReservedRecoveryWarning.js +92 -0
  149. package/dist/components/reserved/ReservedStatusBox.d.ts +30 -0
  150. package/dist/components/reserved/ReservedStatusBox.js +71 -0
  151. package/dist/components/ui/BetaBadge.d.ts +29 -0
  152. package/dist/components/ui/BetaBadge.js +38 -0
  153. package/dist/components/ui/Footer.d.ts +37 -0
  154. package/dist/components/ui/Footer.js +41 -0
  155. package/dist/config/env.d.ts +66 -0
  156. package/dist/config/env.js +57 -0
  157. package/dist/config/logger.d.ts +57 -0
  158. package/dist/config/logger.js +73 -0
  159. package/dist/config/logging-config.d.ts +30 -0
  160. package/dist/config/logging-config.js +122 -0
  161. package/dist/config/unauthenticated-routes.d.ts +17 -0
  162. package/dist/config/unauthenticated-routes.js +24 -0
  163. package/dist/config/vibe-log-transport.d.ts +81 -0
  164. package/dist/config/vibe-log-transport.js +212 -0
  165. package/dist/edge/internal-api-url.d.ts +53 -0
  166. package/dist/edge/internal-api-url.js +63 -0
  167. package/dist/edge/middleware.d.ts +14 -0
  168. package/dist/edge/middleware.js +32 -0
  169. package/dist/hooks/useAuth.d.ts +23 -0
  170. package/dist/hooks/useAuth.js +83 -0
  171. package/dist/hooks/useAuthSettings.d.ts +59 -0
  172. package/dist/hooks/useAuthSettings.js +93 -0
  173. package/dist/hooks/useAvailableProviders.d.ts +43 -0
  174. package/dist/hooks/useAvailableProviders.js +112 -0
  175. package/dist/hooks/usePasswordValidation.d.ts +27 -0
  176. package/dist/hooks/usePasswordValidation.js +102 -0
  177. package/dist/hooks/useProfile.d.ts +15 -0
  178. package/dist/hooks/useProfile.js +59 -0
  179. package/dist/hooks/usePublicAuthSettings.d.ts +56 -0
  180. package/dist/hooks/usePublicAuthSettings.js +131 -0
  181. package/dist/hooks/useSessionExpiration.d.ts +56 -0
  182. package/dist/hooks/useSessionExpiration.js +72 -0
  183. package/dist/hooks/useViabilitySession.d.ts +75 -0
  184. package/dist/hooks/useViabilitySession.js +269 -0
  185. package/dist/index.d.ts +12 -0
  186. package/dist/index.js +53 -0
  187. package/dist/lib/anon-session.d.ts +74 -0
  188. package/dist/lib/anon-session.js +169 -0
  189. package/dist/lib/api-handler.d.ts +123 -0
  190. package/dist/lib/api-handler.js +478 -0
  191. package/dist/lib/app-slug.d.ts +95 -0
  192. package/dist/lib/app-slug.js +172 -0
  193. package/dist/lib/demo-mode.d.ts +6 -0
  194. package/dist/lib/demo-mode.js +16 -0
  195. package/dist/lib/geolocation.d.ts +64 -0
  196. package/dist/lib/geolocation.js +235 -0
  197. package/dist/lib/idp-client-config.d.ts +75 -0
  198. package/dist/lib/idp-client-config.js +425 -0
  199. package/dist/lib/idp-fetch.d.ts +14 -0
  200. package/dist/lib/idp-fetch.js +91 -0
  201. package/dist/lib/internal-api.d.ts +87 -0
  202. package/dist/lib/internal-api.js +122 -0
  203. package/dist/lib/jwt-decode-client.d.ts +10 -0
  204. package/dist/lib/jwt-decode-client.js +46 -0
  205. package/dist/lib/jwt-decode.d.ts +48 -0
  206. package/dist/lib/jwt-decode.js +57 -0
  207. package/dist/lib/rate-limit-service.d.ts +23 -0
  208. package/dist/lib/rate-limit-service.js +6 -0
  209. package/dist/lib/redis.d.ts +5 -0
  210. package/dist/lib/redis.js +28 -0
  211. package/dist/lib/refresh-token-validator.d.ts +13 -0
  212. package/dist/lib/refresh-token-validator.js +117 -0
  213. package/dist/lib/roles.d.ts +145 -0
  214. package/dist/lib/roles.js +168 -0
  215. package/dist/lib/secret-validation.d.ts +4 -0
  216. package/dist/lib/secret-validation.js +14 -0
  217. package/dist/lib/session-store.d.ts +170 -0
  218. package/dist/lib/session-store.js +545 -0
  219. package/dist/lib/session.d.ts +21 -0
  220. package/dist/lib/session.js +26 -0
  221. package/dist/lib/site-logger.d.ts +214 -0
  222. package/dist/lib/site-logger.js +210 -0
  223. package/dist/lib/standardized-client-api.d.ts +161 -0
  224. package/dist/lib/standardized-client-api.js +791 -0
  225. package/dist/lib/startup-init.d.ts +40 -0
  226. package/dist/lib/startup-init.js +257 -0
  227. package/dist/lib/test-aware-get-token.d.ts +2 -0
  228. package/dist/lib/test-aware-get-token.js +86 -0
  229. package/dist/lib/token-expiry.d.ts +14 -0
  230. package/dist/lib/token-expiry.js +39 -0
  231. package/dist/lib/token-lifecycle.d.ts +78 -0
  232. package/dist/lib/token-lifecycle.js +360 -0
  233. package/dist/lib/types/api-responses.d.ts +128 -0
  234. package/dist/lib/types/api-responses.js +171 -0
  235. package/dist/lib/user-agent-parser.d.ts +50 -0
  236. package/dist/lib/user-agent-parser.js +220 -0
  237. package/dist/logging/api/admin-analytics.d.ts +3 -0
  238. package/dist/logging/api/admin-analytics.js +45 -0
  239. package/dist/logging/api/audit-log.d.ts +3 -0
  240. package/dist/logging/api/audit-log.js +52 -0
  241. package/dist/logging/components/AdminAnalyticsLayout.d.ts +10 -0
  242. package/dist/logging/components/AdminAnalyticsLayout.js +11 -0
  243. package/dist/logging/components/AuditLogViewer.d.ts +7 -0
  244. package/dist/logging/components/AuditLogViewer.js +51 -0
  245. package/dist/logging/components/ErrorMetricsCard.d.ts +7 -0
  246. package/dist/logging/components/ErrorMetricsCard.js +16 -0
  247. package/dist/logging/components/HealthMetricsCard.d.ts +7 -0
  248. package/dist/logging/components/HealthMetricsCard.js +19 -0
  249. package/dist/logging/hooks/useAdminAnalytics.d.ts +24 -0
  250. package/dist/logging/hooks/useAdminAnalytics.js +22 -0
  251. package/dist/logging/hooks/useAuditLog.d.ts +6 -0
  252. package/dist/logging/hooks/useAuditLog.js +25 -0
  253. package/dist/logging/hooks/useErrorMetrics.d.ts +6 -0
  254. package/dist/logging/hooks/useErrorMetrics.js +38 -0
  255. package/dist/logging/hooks/useHealthMetrics.d.ts +6 -0
  256. package/dist/logging/hooks/useHealthMetrics.js +41 -0
  257. package/dist/logging/index.d.ts +11 -0
  258. package/dist/logging/index.js +40 -0
  259. package/dist/logging/types/analytics.d.ts +68 -0
  260. package/dist/logging/types/analytics.js +3 -0
  261. package/dist/logging/types/audit.d.ts +29 -0
  262. package/dist/logging/types/audit.js +2 -0
  263. package/dist/logging/types/index.d.ts +2 -0
  264. package/dist/logging/types/index.js +19 -0
  265. package/dist/middleware/auth-decision.d.ts +33 -0
  266. package/dist/middleware/auth-decision.js +65 -0
  267. package/dist/middleware/create-middleware.d.ts +102 -0
  268. package/dist/middleware/create-middleware.js +469 -0
  269. package/dist/middleware/rbac-check.d.ts +51 -0
  270. package/dist/middleware/rbac-check.js +219 -0
  271. package/dist/middleware/twofa-presets.d.ts +134 -0
  272. package/dist/middleware/twofa-presets.js +175 -0
  273. package/dist/models/DecodedAccessToken.d.ts +17 -0
  274. package/dist/models/DecodedAccessToken.js +2 -0
  275. package/dist/models/SessionModel.d.ts +122 -0
  276. package/dist/models/SessionModel.js +136 -0
  277. package/dist/pages/admin-login/page.d.ts +31 -0
  278. package/dist/pages/admin-login/page.js +73 -0
  279. package/dist/pages/admin-page-permissions/PagePermissionsAdminPage.d.ts +18 -0
  280. package/dist/pages/admin-page-permissions/PagePermissionsAdminPage.js +276 -0
  281. package/dist/pages/admin-page-permissions/index.d.ts +6 -0
  282. package/dist/pages/admin-page-permissions/index.js +13 -0
  283. package/dist/pages/admin-roles/RolesAdminPage.d.ts +16 -0
  284. package/dist/pages/admin-roles/RolesAdminPage.js +261 -0
  285. package/dist/pages/admin-roles/index.d.ts +8 -0
  286. package/dist/pages/admin-roles/index.js +15 -0
  287. package/dist/pages/admin-roles/modals.d.ts +72 -0
  288. package/dist/pages/admin-roles/modals.js +154 -0
  289. package/dist/pages/client-admin/ClientSiteAdminPage.d.ts +79 -0
  290. package/dist/pages/client-admin/ClientSiteAdminPage.js +179 -0
  291. package/dist/pages/client-admin/index.d.ts +32 -0
  292. package/dist/pages/client-admin/index.js +37 -0
  293. package/dist/pages/coming-soon/page.d.ts +8 -0
  294. package/dist/pages/coming-soon/page.js +28 -0
  295. package/dist/pages/login/page.d.ts +22 -0
  296. package/dist/pages/login/page.js +230 -0
  297. package/dist/pages/profile/EnhancedProfilePage.d.ts +13 -0
  298. package/dist/pages/profile/EnhancedProfilePage.js +150 -0
  299. package/dist/pages/profile/index.d.ts +8 -0
  300. package/dist/pages/profile/index.js +16 -0
  301. package/dist/pages/profile/page.d.ts +19 -0
  302. package/dist/pages/profile/page.js +47 -0
  303. package/dist/pages/recovery/page.d.ts +1 -0
  304. package/dist/pages/recovery/page.js +142 -0
  305. package/dist/pages/roles/MyRolesPage.d.ts +24 -0
  306. package/dist/pages/roles/MyRolesPage.js +71 -0
  307. package/dist/pages/roles/components.d.ts +63 -0
  308. package/dist/pages/roles/components.js +108 -0
  309. package/dist/pages/roles/index.d.ts +8 -0
  310. package/dist/pages/roles/index.js +19 -0
  311. package/dist/pages/security/EnhancedSecurityPage.d.ts +14 -0
  312. package/dist/pages/security/EnhancedSecurityPage.js +248 -0
  313. package/dist/pages/security/index.d.ts +8 -0
  314. package/dist/pages/security/index.js +16 -0
  315. package/dist/pages/security/page.d.ts +21 -0
  316. package/dist/pages/security/page.js +212 -0
  317. package/dist/pages/settings/EnhancedSettingsPage.d.ts +46 -0
  318. package/dist/pages/settings/EnhancedSettingsPage.js +231 -0
  319. package/dist/pages/settings/index.d.ts +8 -0
  320. package/dist/pages/settings/index.js +16 -0
  321. package/dist/pages/settings/page.d.ts +7 -0
  322. package/dist/pages/settings/page.js +26 -0
  323. package/dist/pages/showcase/ShowcasePage.d.ts +13 -0
  324. package/dist/pages/showcase/ShowcasePage.js +142 -0
  325. package/dist/pages/showcase/index.d.ts +12 -0
  326. package/dist/pages/showcase/index.js +17 -0
  327. package/dist/pages/test-env/EmergencyLogoutPage.d.ts +14 -0
  328. package/dist/pages/test-env/EmergencyLogoutPage.js +99 -0
  329. package/dist/pages/test-env/JwtInspectPage.d.ts +14 -0
  330. package/dist/pages/test-env/JwtInspectPage.js +116 -0
  331. package/dist/pages/test-env/RefreshTokenPage.d.ts +15 -0
  332. package/dist/pages/test-env/RefreshTokenPage.js +93 -0
  333. package/dist/pages/test-env/TestEnvPage.d.ts +13 -0
  334. package/dist/pages/test-env/TestEnvPage.js +51 -0
  335. package/dist/pages/test-env/index.d.ts +24 -0
  336. package/dist/pages/test-env/index.js +32 -0
  337. package/dist/pages/verify-code/page.d.ts +30 -0
  338. package/dist/pages/verify-code/page.js +412 -0
  339. package/dist/routes/account/index.d.ts +28 -0
  340. package/dist/routes/account/index.js +71 -0
  341. package/dist/routes/account/masked-info.d.ts +33 -0
  342. package/dist/routes/account/masked-info.js +39 -0
  343. package/dist/routes/account/send-code.d.ts +37 -0
  344. package/dist/routes/account/send-code.js +42 -0
  345. package/dist/routes/account/update-phone.d.ts +13 -0
  346. package/dist/routes/account/update-phone.js +17 -0
  347. package/dist/routes/account/verify-email.d.ts +38 -0
  348. package/dist/routes/account/verify-email.js +43 -0
  349. package/dist/routes/account/verify-sms.d.ts +38 -0
  350. package/dist/routes/account/verify-sms.js +43 -0
  351. package/dist/routes/auth/index.d.ts +19 -0
  352. package/dist/routes/auth/index.js +64 -0
  353. package/dist/routes/auth/logout.d.ts +31 -0
  354. package/dist/routes/auth/logout.js +98 -0
  355. package/dist/routes/auth/nextauth.d.ts +22 -0
  356. package/dist/routes/auth/nextauth.js +40 -0
  357. package/dist/routes/auth/refresh.d.ts +30 -0
  358. package/dist/routes/auth/refresh.js +51 -0
  359. package/dist/routes/auth/session.d.ts +43 -0
  360. package/dist/routes/auth/session.js +157 -0
  361. package/dist/routes/auth/settings.d.ts +25 -0
  362. package/dist/routes/auth/settings.js +55 -0
  363. package/dist/routes/auth/viability.d.ts +52 -0
  364. package/dist/routes/auth/viability.js +190 -0
  365. package/dist/routes/index.d.ts +12 -0
  366. package/dist/routes/index.js +54 -0
  367. package/dist/routes/session/index.d.ts +6 -0
  368. package/dist/routes/session/index.js +10 -0
  369. package/dist/routes/session/refresh-viability.d.ts +16 -0
  370. package/dist/routes/session/refresh-viability.js +20 -0
  371. package/dist/server/auth-guard.d.ts +46 -0
  372. package/dist/server/auth-guard.js +128 -0
  373. package/dist/server/auth.d.ts +50 -0
  374. package/dist/server/auth.js +62 -0
  375. package/dist/server/decode-session.d.ts +30 -0
  376. package/dist/server/decode-session.js +78 -0
  377. package/dist/server/slim-middleware.d.ts +23 -0
  378. package/dist/server/slim-middleware.js +89 -0
  379. package/dist/server/with-auth.d.ts +33 -0
  380. package/dist/server/with-auth.js +59 -0
  381. package/dist/services/signalrActivityService.d.ts +44 -0
  382. package/dist/services/signalrActivityService.js +257 -0
  383. package/dist/stores/authStore.d.ts +154 -0
  384. package/dist/stores/authStore.js +1527 -0
  385. package/dist/theme/ThemeProvider.d.ts +14 -0
  386. package/dist/theme/ThemeProvider.js +28 -0
  387. package/dist/theme/default.d.ts +8 -0
  388. package/dist/theme/default.js +33 -0
  389. package/dist/theme/index.d.ts +15 -0
  390. package/dist/theme/index.js +25 -0
  391. package/dist/theme/types.d.ts +56 -0
  392. package/dist/theme/types.js +8 -0
  393. package/dist/theme/useTheme.d.ts +60 -0
  394. package/dist/theme/useTheme.js +63 -0
  395. package/dist/theme/utils.d.ts +13 -0
  396. package/dist/theme/utils.js +39 -0
  397. package/dist/types/api.d.ts +134 -0
  398. package/dist/types/api.js +44 -0
  399. package/dist/types/auth.d.ts +19 -0
  400. package/dist/types/auth.js +2 -0
  401. package/dist/types/logging.d.ts +42 -0
  402. package/dist/types/logging.js +2 -0
  403. package/dist/types/recovery.d.ts +48 -0
  404. package/dist/types/recovery.js +2 -0
  405. package/dist/types/security.d.ts +1 -0
  406. package/dist/types/security.js +2 -0
  407. package/dist/utils/api.d.ts +85 -0
  408. package/dist/utils/api.js +287 -0
  409. package/dist/utils/circuitBreaker.d.ts +43 -0
  410. package/dist/utils/circuitBreaker.js +91 -0
  411. package/dist/utils/error-message.d.ts +1 -0
  412. package/dist/utils/error-message.js +103 -0
  413. package/dist/utils/layout/reservedSpace.d.ts +59 -0
  414. package/dist/utils/layout/reservedSpace.js +102 -0
  415. package/dist/utils/logout.d.ts +14 -0
  416. package/dist/utils/logout.js +32 -0
  417. package/dist/vibe/client.d.ts +261 -0
  418. package/dist/vibe/client.js +445 -0
  419. package/dist/vibe/enterprise-auth.d.ts +106 -0
  420. package/dist/vibe/enterprise-auth.js +173 -0
  421. package/dist/vibe/errors.d.ts +83 -0
  422. package/dist/vibe/errors.js +146 -0
  423. package/dist/vibe/generic.d.ts +234 -0
  424. package/dist/vibe/generic.js +369 -0
  425. package/dist/vibe/hooks/index.d.ts +169 -0
  426. package/dist/vibe/hooks/index.js +252 -0
  427. package/dist/vibe/index.d.ts +25 -0
  428. package/dist/vibe/index.js +72 -0
  429. package/dist/vibe/sessions.d.ts +161 -0
  430. package/dist/vibe/sessions.js +391 -0
  431. package/dist/vibe/types.d.ts +353 -0
  432. package/dist/vibe/types.js +315 -0
  433. package/package.json +1 -1
@@ -0,0 +1,791 @@
1
+ "use strict";
2
+ "use client";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16
+ }) : function(o, v) {
17
+ o["default"] = v;
18
+ });
19
+ var __importStar = (this && this.__importStar) || (function () {
20
+ var ownKeys = function(o) {
21
+ ownKeys = Object.getOwnPropertyNames || function (o) {
22
+ var ar = [];
23
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
+ return ar;
25
+ };
26
+ return ownKeys(o);
27
+ };
28
+ return function (mod) {
29
+ if (mod && mod.__esModule) return mod;
30
+ var result = {};
31
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
+ __setModuleDefault(result, mod);
33
+ return result;
34
+ };
35
+ })();
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.standardizedApi = exports.ApiNetworkError = exports.ApiValidationError = exports.ApiBusinessLogicError = exports.ApiResponseFormatError = void 0;
38
+ exports.isApiSuccess = isApiSuccess;
39
+ exports.isApiPagedSuccess = isApiPagedSuccess;
40
+ exports.isApiError = isApiError;
41
+ exports.extractApiData = extractApiData;
42
+ exports.extractApiItems = extractApiItems;
43
+ // ========================================================================================
44
+ // BULLETPROOF STANDARDIZED CLIENT API - ZERO TOLERANCE FOR BAD RESPONSES
45
+ // ========================================================================================
46
+ // This client API ENFORCES the standardized response format
47
+ // It will BREAK if APIs don't return the expected structure
48
+ // NO MORE GUESSING data.data.data.data - EVER AGAIN!
49
+ // ========================================================================================
50
+ const better_auth_client_1 = require("../client/better-auth-client");
51
+ /** Unwrap Better Auth getSession() to a flat session-like object for backward compat */
52
+ async function getSession() {
53
+ const { data } = await better_auth_client_1.authClient.getSession();
54
+ return data ?? null;
55
+ }
56
+ const api_responses_1 = require("./types/api-responses");
57
+ // ========================================================================================
58
+ // CLIENT API ERROR TYPES
59
+ // ========================================================================================
60
+ /**
61
+ * ERROR THROWN WHEN API RESPONSE FORMAT IS INVALID
62
+ * This means the API is NOT following our standardized format
63
+ */
64
+ class ApiResponseFormatError extends Error {
65
+ endpoint;
66
+ rawResponse;
67
+ constructor(message, endpoint, rawResponse) {
68
+ super(`API_FORMAT_ERROR: ${message}`);
69
+ this.endpoint = endpoint;
70
+ this.rawResponse = rawResponse;
71
+ this.name = 'ApiResponseFormatError';
72
+ }
73
+ }
74
+ exports.ApiResponseFormatError = ApiResponseFormatError;
75
+ /**
76
+ * ERROR THROWN WHEN API RETURNS A STANDARDIZED ERROR RESPONSE
77
+ * This is a properly formatted error from the API
78
+ */
79
+ class ApiBusinessLogicError extends Error {
80
+ errorCode;
81
+ operation;
82
+ details;
83
+ constructor(errorCode, message, operation, details) {
84
+ super(message);
85
+ this.errorCode = errorCode;
86
+ this.operation = operation;
87
+ this.details = details;
88
+ this.name = 'ApiBusinessLogicError';
89
+ }
90
+ }
91
+ exports.ApiBusinessLogicError = ApiBusinessLogicError;
92
+ /**
93
+ * ERROR THROWN WHEN VALIDATION FAILS
94
+ * This is a properly formatted validation error from the API
95
+ */
96
+ class ApiValidationError extends Error {
97
+ operation;
98
+ validationErrors;
99
+ invalidValue;
100
+ primaryField;
101
+ constructor(message, operation, validationErrors, invalidValue, primaryField) {
102
+ super(message);
103
+ this.operation = operation;
104
+ this.validationErrors = validationErrors;
105
+ this.invalidValue = invalidValue;
106
+ this.primaryField = primaryField;
107
+ this.name = 'ApiValidationError';
108
+ }
109
+ }
110
+ exports.ApiValidationError = ApiValidationError;
111
+ /**
112
+ * ERROR THROWN WHEN NETWORK/HTTP ISSUES OCCUR
113
+ */
114
+ class ApiNetworkError extends Error {
115
+ status;
116
+ endpoint;
117
+ constructor(message, status, endpoint) {
118
+ super(`NETWORK_ERROR: ${message}`);
119
+ this.status = status;
120
+ this.endpoint = endpoint;
121
+ this.name = 'ApiNetworkError';
122
+ }
123
+ }
124
+ exports.ApiNetworkError = ApiNetworkError;
125
+ // ========================================================================================
126
+ // AUTHENTICATION STATE MANAGEMENT
127
+ // ========================================================================================
128
+ // Coordinate client-side refresh to avoid duplicate refresh calls racing with
129
+ // server-side middleware or other tabs. Only one refresh runs at a time.
130
+ let refreshInFlight = null;
131
+ // Enhanced redirect logic with grace period and retry attempts
132
+ let authRedirectScheduled = false;
133
+ let lastAuthFailureTime = 0;
134
+ let consecutiveAuthFailures = 0;
135
+ const AUTH_FAILURE_GRACE_PERIOD = 2000; // 2 seconds grace period
136
+ const MAX_AUTH_FAILURES_BEFORE_REDIRECT = 2; // Allow 2 failures before redirect
137
+ const AUTH_FAILURE_RESET_WINDOW = 30000; // Reset failure count after 30 seconds
138
+ // Helper: detect pre-2FA session (session exists, requires 2FA and not completed)
139
+ function isPreTwoFactorSession(session) {
140
+ return !!(session?.user?.requiresTwoFactor && !session?.user?.twoFactorSessionVerified);
141
+ }
142
+ // Reset auth failure state on successful requests
143
+ function resetAuthFailureState() {
144
+ if (consecutiveAuthFailures > 0) {
145
+ console.log(`✅ Resetting auth failure state (was ${consecutiveAuthFailures} failures)`);
146
+ consecutiveAuthFailures = 0;
147
+ lastAuthFailureTime = 0;
148
+ authRedirectScheduled = false;
149
+ }
150
+ }
151
+ function scheduleLoginRedirect(isImmediate = false) {
152
+ if (authRedirectScheduled)
153
+ return;
154
+ const now = Date.now();
155
+ // Reset consecutive failures if enough time has passed
156
+ if (now - lastAuthFailureTime > AUTH_FAILURE_RESET_WINDOW) {
157
+ consecutiveAuthFailures = 0;
158
+ }
159
+ consecutiveAuthFailures++;
160
+ lastAuthFailureTime = now;
161
+ console.warn(`🔴 Auth failure #${consecutiveAuthFailures}, immediate: ${isImmediate}`);
162
+ // Only redirect if we've had multiple failures or if explicitly requested
163
+ if (!isImmediate && consecutiveAuthFailures < MAX_AUTH_FAILURES_BEFORE_REDIRECT) {
164
+ console.log(`⏳ Delaying redirect - only ${consecutiveAuthFailures} failures so far`);
165
+ return;
166
+ }
167
+ authRedirectScheduled = true;
168
+ const redirectFunction = () => {
169
+ try {
170
+ const returnUrl = encodeURIComponent(`${window.location.pathname}${window.location.search}`);
171
+ console.warn(`🔄 Redirecting to login with return URL: ${returnUrl}`);
172
+ window.location.href = `/account-auth/login?returnUrl=${returnUrl}`;
173
+ }
174
+ catch (error) {
175
+ console.error('❌ Error during login redirect:', error);
176
+ // Final fallback
177
+ try {
178
+ window.location.href = '/account-auth/login';
179
+ }
180
+ catch {
181
+ // no-op if window is not available
182
+ }
183
+ }
184
+ };
185
+ if (isImmediate) {
186
+ // Immediate redirect for critical auth failures
187
+ redirectFunction();
188
+ }
189
+ else {
190
+ // Small delay to allow any pending requests to complete
191
+ console.log(`⏳ Scheduling redirect with ${AUTH_FAILURE_GRACE_PERIOD}ms grace period`);
192
+ setTimeout(redirectFunction, AUTH_FAILURE_GRACE_PERIOD);
193
+ }
194
+ }
195
+ // ========================================================================================
196
+ // BULLETPROOF CLIENT API SERVICE
197
+ // ========================================================================================
198
+ class StandardizedClientApiService {
199
+ baseUrl;
200
+ constructor() {
201
+ this.baseUrl = '';
202
+ }
203
+ /**
204
+ * MAKES HTTP REQUEST AND VALIDATES RESPONSE FORMAT
205
+ * This method ENFORCES standardized response format compliance
206
+ * Will throw ApiResponseFormatError if format is invalid
207
+ */
208
+ async makeRequest(endpoint, options = {}, sessionToken) {
209
+ const fullEndpoint = `${this.baseUrl}${endpoint}`;
210
+ try {
211
+ // Use provided token or get from NextAuth session
212
+ const currentSession = await getSession();
213
+ let token = sessionToken || currentSession?.accessToken;
214
+ // Preflight freshness check: if token is near expiry, coordinate refresh BEFORE making request
215
+ const pre2FA = isPreTwoFactorSession(currentSession);
216
+ const hasRefresh = !!currentSession?.refreshToken;
217
+ if (!pre2FA && hasRefresh) {
218
+ try {
219
+ let timeLeft = null;
220
+ if (currentSession?.accessTokenExpires) {
221
+ timeLeft = currentSession.accessTokenExpires - Date.now();
222
+ }
223
+ else if (token) {
224
+ // Fallback decode only if session did not include expiry
225
+ const { jwtDecode } = await Promise.resolve().then(() => __importStar(require('./jwt-decode-client')));
226
+ const decoded = jwtDecode(token);
227
+ const expMs = decoded?.exp ? decoded.exp * 1000 : 0;
228
+ timeLeft = expMs - Date.now();
229
+ }
230
+ // Refresh if <= 60s remaining (or already expired)
231
+ if (timeLeft !== null && !Number.isNaN(timeLeft) && timeLeft <= 60000) {
232
+ console.log(`⏳ Access token expiring soon (${Math.floor(timeLeft / 1000)}s). Coordinating refresh before request...`);
233
+ if (!refreshInFlight) {
234
+ refreshInFlight = (async () => {
235
+ const reqId = crypto.randomUUID();
236
+ const rr = await fetch('/api/auth/refresh', {
237
+ method: 'POST',
238
+ credentials: 'include',
239
+ headers: { 'X-Request-ID': reqId },
240
+ });
241
+ if (rr.ok || rr.status === 409) {
242
+ // ok or in-progress; give it a beat in case of 409
243
+ if (rr.status === 409)
244
+ await new Promise(r => setTimeout(r, 1200));
245
+ return true;
246
+ }
247
+ if (rr.status === 401 || rr.status === 403) {
248
+ scheduleLoginRedirect();
249
+ throw new ApiNetworkError('Authentication failed - unable to refresh session', rr.status, endpoint);
250
+ }
251
+ const et = await rr.text();
252
+ throw new ApiNetworkError(et || 'Token refresh failed', rr.status, endpoint);
253
+ })().finally(() => { refreshInFlight = null; });
254
+ }
255
+ await refreshInFlight;
256
+ const newSessionAfter = await getSession();
257
+ token = newSessionAfter?.accessToken || token;
258
+ }
259
+ }
260
+ catch (preErr) {
261
+ console.warn('Preflight token freshness check failed (continuing to attempt request):', preErr);
262
+ }
263
+ }
264
+ else {
265
+ // Elegantly skip preflight refresh in pre-2FA window or when no refresh token exists
266
+ if (pre2FA) {
267
+ console.log('⏭️ Skipping preflight refresh: 2FA not complete (no refresh allowed yet)');
268
+ }
269
+ else if (!hasRefresh) {
270
+ console.log('⏭️ Skipping preflight refresh: no refresh token present');
271
+ }
272
+ }
273
+ const config = {
274
+ ...options,
275
+ headers: {
276
+ 'Content-Type': 'application/json',
277
+ ...(token && { 'Authorization': `Bearer ${token}` }),
278
+ ...options.headers,
279
+ },
280
+ };
281
+ console.log(`🔄 API Request: ${options.method || 'GET'} ${fullEndpoint}`);
282
+ const response = await fetch(fullEndpoint, config);
283
+ if (!response.ok) {
284
+ // Handle coordination blocking (503) with auto-retry
285
+ if (response.status === 503) {
286
+ console.log('🔄 Got 503 Service Unavailable, attempting auto-retry for coordination...');
287
+ // Parse Retry-After header (in seconds)
288
+ const retryAfterHeader = response.headers.get('Retry-After');
289
+ let retryAfterSeconds = 1; // Default to 1 second
290
+ if (retryAfterHeader && /^\d+$/.test(retryAfterHeader)) {
291
+ retryAfterSeconds = parseInt(retryAfterHeader, 10);
292
+ }
293
+ const baseDelayMs = retryAfterSeconds * 1000;
294
+ const maxRetries = 3;
295
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
296
+ // Add jitter to prevent thundering herd
297
+ const jitterMs = Math.floor(Math.random() * 300) - 150; // ±150ms jitter
298
+ const exponentialBackoff = Math.pow(1.5, attempt - 1); // Mild exponential backoff
299
+ const delayMs = Math.max(100, baseDelayMs * exponentialBackoff + jitterMs);
300
+ console.log(`🔄 503 retry attempt ${attempt}/${maxRetries}, waiting ${delayMs}ms...`);
301
+ await new Promise(resolve => setTimeout(resolve, delayMs));
302
+ try {
303
+ const retryResponse = await fetch(fullEndpoint, config);
304
+ if (retryResponse.ok) {
305
+ console.log(`✅ 503 retry attempt ${attempt} succeeded`);
306
+ const rawData = await retryResponse.json();
307
+ resetAuthFailureState();
308
+ // COMPATIBILITY MODE: Handle both formats
309
+ if (rawData && typeof rawData === 'object' && 'success' in rawData) {
310
+ const validatedResponse = (0, api_responses_1.validateStandardizedResponse)(rawData, endpoint);
311
+ return this.convertToApiResult(validatedResponse);
312
+ }
313
+ else {
314
+ // New format - raw data
315
+ const wrappedResponse = {
316
+ success: true,
317
+ data: rawData,
318
+ message: 'Success',
319
+ operation_code: 'RAW_RESPONSE',
320
+ timestamp: new Date().toISOString()
321
+ };
322
+ return wrappedResponse;
323
+ }
324
+ }
325
+ // If we get another 503, continue retrying
326
+ if (retryResponse.status === 503) {
327
+ console.log(`🔄 503 retry attempt ${attempt} got another 503, will retry...`);
328
+ continue;
329
+ }
330
+ // If we get a different error, break and handle it normally
331
+ console.log(`❌ 503 retry attempt ${attempt} got ${retryResponse.status}, stopping retries`);
332
+ // Fall through to handle the retry response error
333
+ const errorText = await retryResponse.text();
334
+ let errorData;
335
+ try {
336
+ errorData = JSON.parse(errorText);
337
+ if (errorData && typeof errorData === 'object' && 'success' in errorData) {
338
+ // Detect PayEz canonical error envelope and map accordingly
339
+ if (errorData.error && typeof errorData.error === 'object') {
340
+ const reqIdHeader = retryResponse.headers.get('X-Request-ID') || retryResponse.headers.get('X-Correlation-ID');
341
+ const reqIdBody = errorData?.request_id || errorData?.requestId;
342
+ const errorResult = {
343
+ success: false,
344
+ error_code: errorData?.error?.code || errorData?.error_code || errorData?.code || `HTTP_${retryResponse.status}`,
345
+ message: errorData?.error?.message || errorData?.message || `Request failed with status ${retryResponse.status}`,
346
+ operation: endpoint,
347
+ details: (errorData?.error?.details ?? errorData?.details) || undefined,
348
+ ...(reqIdBody || reqIdHeader ? { request_id: (reqIdBody || reqIdHeader) } : {})
349
+ };
350
+ return errorResult;
351
+ }
352
+ // Otherwise attempt to validate as our standardized error shape
353
+ const validatedError = (0, api_responses_1.validateStandardizedResponse)(errorData, endpoint);
354
+ return this.convertToApiResult(validatedError);
355
+ }
356
+ else {
357
+ // New/unknown error format - best-effort mapping
358
+ const reqIdHeader = retryResponse.headers.get('X-Request-ID') || retryResponse.headers.get('X-Correlation-ID');
359
+ const reqIdBody = errorData?.request_id || errorData?.requestId;
360
+ const errorResult = {
361
+ success: false,
362
+ error_code: errorData?.error_code || errorData?.code || `HTTP_${retryResponse.status}`,
363
+ message: errorData?.message || (typeof errorData?.error === 'string' ? errorData.error : errorData?.error?.message) || errorText || `Request failed with status ${retryResponse.status}`,
364
+ operation: endpoint,
365
+ details: (errorData?.error?.details ?? errorData?.details) || undefined,
366
+ ...(reqIdBody || reqIdHeader ? { request_id: (reqIdBody || reqIdHeader) } : {})
367
+ };
368
+ return errorResult;
369
+ }
370
+ }
371
+ catch {
372
+ const reqIdHeader2 = retryResponse.headers.get('X-Request-ID') || retryResponse.headers.get('X-Correlation-ID');
373
+ const errorResult = {
374
+ success: false,
375
+ error_code: `HTTP_${retryResponse.status}`,
376
+ message: errorText || `Request failed with status ${retryResponse.status}`,
377
+ operation: endpoint,
378
+ ...(reqIdHeader2 ? { request_id: reqIdHeader2 } : {})
379
+ };
380
+ return errorResult;
381
+ }
382
+ }
383
+ catch (retryError) {
384
+ console.log(`❌ 503 retry attempt ${attempt} failed with network error:`, retryError);
385
+ if (attempt === maxRetries) {
386
+ // If all retries failed with network errors, throw the original error
387
+ throw new ApiNetworkError('Service temporarily unavailable after retries', 503, endpoint);
388
+ }
389
+ continue;
390
+ }
391
+ }
392
+ // If we got here, all retries failed - fall through to normal error handling
393
+ console.log('❌ All 503 retry attempts exhausted, treating as error');
394
+ }
395
+ // Handle authentication errors with a single refresh+retry
396
+ if (response.status === 401) {
397
+ console.log('🔑 Got 401, checking if we have a session to refresh...');
398
+ // CRITICAL FIX: Check if we actually have a session before attempting refresh
399
+ const currentSession = await getSession();
400
+ if (!currentSession || !currentSession.accessToken) {
401
+ console.log('🚫 No valid session found, redirecting to login instead of refresh');
402
+ scheduleLoginRedirect(true); // Immediate redirect
403
+ throw new ApiNetworkError('Authentication required - no valid session', 401, endpoint);
404
+ }
405
+ // Elegantly gate refresh during pre-2FA or when no refresh token exists
406
+ const pre2FA_now = isPreTwoFactorSession(currentSession);
407
+ const hasRefresh_now = !!currentSession?.refreshToken;
408
+ if (pre2FA_now || !hasRefresh_now) {
409
+ console.log('⏭️ Skipping 401-driven refresh:', {
410
+ reason: pre2FA_now ? 'pre-2FA session' : 'no refresh token',
411
+ requiresTwoFactor: currentSession?.user?.requiresTwoFactor,
412
+ twoFactorVerified: currentSession?.user?.twoFactorSessionVerified,
413
+ hasRefreshToken: hasRefresh_now
414
+ });
415
+ // CRITICAL: Redirect to login immediately if refresh is impossible
416
+ console.log('🚫 Cannot refresh session, redirecting to login');
417
+ scheduleLoginRedirect(true); // Immediate redirect
418
+ throw new ApiNetworkError(pre2FA_now
419
+ ? 'Two-factor authentication required'
420
+ : 'Session expired - refresh token unavailable', 401, endpoint);
421
+ }
422
+ console.log('🔑 Valid session found, attempting token refresh...');
423
+ // Try to refresh the token, but coordinate to avoid double refresh
424
+ if (!refreshInFlight) {
425
+ refreshInFlight = (async () => {
426
+ const reqId = crypto.randomUUID();
427
+ const refreshResponse = await fetch('/api/auth/refresh', {
428
+ method: 'POST',
429
+ credentials: 'include',
430
+ headers: { 'X-Request-ID': reqId },
431
+ });
432
+ if (refreshResponse.ok) {
433
+ console.log('✅ Token refreshed successfully (client-side coordinator)');
434
+ return true;
435
+ }
436
+ // If refresh is already in progress server-side, wait briefly and allow retry
437
+ if (refreshResponse.status === 409) {
438
+ console.log('↪️ Refresh in progress server-side (409). Waiting for completion...');
439
+ await new Promise(r => setTimeout(r, 1500));
440
+ return true;
441
+ }
442
+ // For auth failures, schedule redirect; for others, throw
443
+ if (refreshResponse.status === 401 || refreshResponse.status === 403) {
444
+ scheduleLoginRedirect();
445
+ throw new ApiNetworkError('Authentication failed - unable to refresh session', refreshResponse.status, endpoint);
446
+ }
447
+ const errorText = await refreshResponse.text();
448
+ throw new ApiNetworkError(errorText || 'Token refresh failed', refreshResponse.status, endpoint);
449
+ })().finally(() => { refreshInFlight = null; });
450
+ }
451
+ try {
452
+ await refreshInFlight;
453
+ }
454
+ catch (e) {
455
+ throw e; // bubble up to caller handling
456
+ }
457
+ console.log('🔁 Retrying original request after coordinated refresh...');
458
+ // Get the new session and retry the original request
459
+ const newSession = await getSession();
460
+ const newToken = newSession?.accessToken;
461
+ const retryConfig = {
462
+ ...options,
463
+ headers: {
464
+ 'Content-Type': 'application/json',
465
+ ...(newToken && { 'Authorization': `Bearer ${newToken}` }),
466
+ ...options.headers,
467
+ },
468
+ };
469
+ const retryResponse = await fetch(fullEndpoint, retryConfig);
470
+ if (retryResponse.ok) {
471
+ const rawData = await retryResponse.json();
472
+ // Reset auth failure state on successful retry
473
+ resetAuthFailureState();
474
+ // COMPATIBILITY MODE: Handle both formats in retry as well
475
+ if (rawData && typeof rawData === 'object' && 'success' in rawData) {
476
+ const validatedResponse = (0, api_responses_1.validateStandardizedResponse)(rawData, endpoint);
477
+ return this.convertToApiResult(validatedResponse);
478
+ }
479
+ else {
480
+ // New format - raw data
481
+ console.log(`🔄 Converting raw retry response to standardized format for ${endpoint}`);
482
+ const wrappedResponse = {
483
+ success: true,
484
+ data: rawData,
485
+ message: 'Success',
486
+ operation_code: 'RAW_RESPONSE',
487
+ timestamp: new Date().toISOString()
488
+ };
489
+ return wrappedResponse;
490
+ }
491
+ }
492
+ else {
493
+ // If retry still 401, schedule redirect
494
+ if (retryResponse.status === 401) {
495
+ scheduleLoginRedirect();
496
+ }
497
+ const errorText = await retryResponse.text();
498
+ let errorData;
499
+ try {
500
+ errorData = JSON.parse(errorText);
501
+ // Check if it has the success field (old format)
502
+ if (errorData && typeof errorData === 'object' && 'success' in errorData) {
503
+ // Detect PayEz canonical error envelope and map accordingly
504
+ if (errorData.error && typeof errorData.error === 'object') {
505
+ const reqIdHeader = retryResponse.headers.get('X-Request-ID') || retryResponse.headers.get('X-Correlation-ID');
506
+ const reqIdBody = errorData?.request_id || errorData?.requestId;
507
+ const errorResult = {
508
+ success: false,
509
+ error_code: errorData?.error?.code || errorData?.error_code || errorData?.code || `HTTP_${retryResponse.status}`,
510
+ message: errorData?.error?.message || errorData?.message || `Request failed with status ${retryResponse.status}`,
511
+ operation: endpoint,
512
+ details: (errorData?.error?.details ?? errorData?.details) || undefined,
513
+ ...(reqIdBody || reqIdHeader ? { request_id: (reqIdBody || reqIdHeader) } : {})
514
+ };
515
+ return errorResult;
516
+ }
517
+ const validatedError = (0, api_responses_1.validateStandardizedResponse)(errorData, endpoint);
518
+ return this.convertToApiResult(validatedError);
519
+ }
520
+ else {
521
+ // New format - convert raw error to standardized format
522
+ const reqIdHeader = retryResponse.headers.get('X-Request-ID') || retryResponse.headers.get('X-Correlation-ID');
523
+ const reqIdBody = errorData?.request_id || errorData?.requestId;
524
+ const errorResult = {
525
+ success: false,
526
+ error_code: errorData?.error_code || errorData?.code || `HTTP_${retryResponse.status}`,
527
+ message: errorData?.message || (typeof errorData?.error === 'string' ? errorData.error : errorData?.error?.message) || errorText || `Request failed with status ${retryResponse.status}`,
528
+ operation: endpoint,
529
+ details: (errorData?.error?.details ?? errorData?.details) || undefined,
530
+ ...(reqIdBody || reqIdHeader ? { request_id: (reqIdBody || reqIdHeader) } : {})
531
+ };
532
+ return errorResult;
533
+ }
534
+ }
535
+ catch {
536
+ // If we can't parse the error, create a generic error response
537
+ const reqIdHeader = retryResponse.headers.get('X-Request-ID') || retryResponse.headers.get('X-Correlation-ID');
538
+ const errorResult = {
539
+ success: false,
540
+ error_code: `HTTP_${retryResponse.status}`,
541
+ message: errorText || `Request failed with status ${retryResponse.status}`,
542
+ operation: endpoint,
543
+ ...(reqIdHeader ? { request_id: reqIdHeader } : {})
544
+ };
545
+ return errorResult;
546
+ }
547
+ }
548
+ }
549
+ // Non-401 error: try to parse as standardized error response
550
+ const errorText = await response.text();
551
+ let errorData;
552
+ try {
553
+ errorData = JSON.parse(errorText);
554
+ // Check if it has the success field (old format)
555
+ if (errorData && typeof errorData === 'object' && 'success' in errorData) {
556
+ // Detect PayEz canonical error envelope and map accordingly
557
+ if (errorData.error && typeof errorData.error === 'object') {
558
+ const reqIdHeader = response.headers.get('X-Request-ID') || response.headers.get('X-Correlation-ID');
559
+ const reqIdBody = errorData?.request_id || errorData?.requestId;
560
+ const errorResult = {
561
+ success: false,
562
+ error_code: errorData?.error?.code || errorData?.error_code || errorData?.code || `HTTP_${response.status}`,
563
+ message: errorData?.error?.message || errorData?.message || `Request failed with status ${response.status}`,
564
+ operation: endpoint,
565
+ details: (errorData?.error?.details ?? errorData?.details) || undefined,
566
+ validation_errors: errorData?.validation_errors || undefined,
567
+ ...(reqIdBody || reqIdHeader ? { request_id: (reqIdBody || reqIdHeader) } : {})
568
+ };
569
+ return errorResult;
570
+ }
571
+ const validatedError = (0, api_responses_1.validateStandardizedResponse)(errorData, endpoint);
572
+ return this.convertToApiResult(validatedError);
573
+ }
574
+ else {
575
+ // New format - convert raw error to standardized format
576
+ const reqIdHeader = response.headers.get('X-Request-ID') || response.headers.get('X-Correlation-ID');
577
+ const reqIdBody = errorData?.request_id || errorData?.requestId;
578
+ const errorResult = {
579
+ success: false,
580
+ error_code: errorData?.error_code || errorData?.code || `HTTP_${response.status}`,
581
+ message: errorData?.message || (typeof errorData?.error === 'string' ? errorData.error : errorData?.error?.message) || errorText || `Request failed with status ${response.status}`,
582
+ operation: endpoint,
583
+ details: (errorData?.error?.details ?? errorData?.details) || undefined,
584
+ validation_errors: errorData?.validation_errors || undefined,
585
+ ...(reqIdBody || reqIdHeader ? { request_id: (reqIdBody || reqIdHeader) } : {})
586
+ };
587
+ return errorResult;
588
+ }
589
+ }
590
+ catch (parseError) {
591
+ // If we can't parse the error, create a generic error response
592
+ const reqIdHeader = response.headers.get('X-Request-ID') || response.headers.get('X-Correlation-ID');
593
+ const errorResult = {
594
+ success: false,
595
+ error_code: `HTTP_${response.status}`,
596
+ message: errorText || `Request failed with status ${response.status}`,
597
+ operation: endpoint,
598
+ details: undefined,
599
+ ...(reqIdHeader ? { request_id: reqIdHeader } : {})
600
+ };
601
+ return errorResult;
602
+ }
603
+ }
604
+ // SUCCESS PATH: Parse and validate response
605
+ const rawData = await response.json();
606
+ // Reset auth failure state on successful request
607
+ resetAuthFailureState();
608
+ // COMPATIBILITY MODE: Handle both old envelope format and new raw format
609
+ try {
610
+ // First check if it's the old standardized format with success field
611
+ if (rawData && typeof rawData === 'object' && 'success' in rawData) {
612
+ // Old format - validate as standardized response
613
+ const validatedResponse = (0, api_responses_1.validateStandardizedResponse)(rawData, endpoint);
614
+ return this.convertToApiResult(validatedResponse);
615
+ }
616
+ else {
617
+ // New format - raw data, wrap it in success envelope for compatibility
618
+ console.log(`🔄 Converting raw response to standardized format for ${endpoint}`);
619
+ const wrappedResponse = {
620
+ success: true,
621
+ data: rawData,
622
+ message: 'Success',
623
+ operation_code: 'RAW_RESPONSE',
624
+ timestamp: new Date().toISOString()
625
+ };
626
+ return wrappedResponse;
627
+ }
628
+ }
629
+ catch (validationError) {
630
+ // If response format is invalid, this is a CRITICAL error
631
+ throw new ApiResponseFormatError(validationError instanceof Error ? validationError.message : 'Response format validation failed', endpoint, rawData);
632
+ }
633
+ }
634
+ catch (error) {
635
+ // Re-throw our custom errors as-is
636
+ if (error instanceof ApiResponseFormatError ||
637
+ error instanceof ApiBusinessLogicError ||
638
+ error instanceof ApiValidationError ||
639
+ error instanceof ApiNetworkError) {
640
+ throw error;
641
+ }
642
+ // Wrap unknown errors as network errors
643
+ console.error('❌ API request failed:', error);
644
+ throw new ApiNetworkError(error instanceof Error ? error.message : 'Network error', 0, endpoint);
645
+ }
646
+ }
647
+ /**
648
+ * CONVERTS VALIDATED STANDARDIZED RESPONSE TO CLIENT RESULT
649
+ * This normalizes the response for client consumption
650
+ */
651
+ convertToApiResult(validatedResponse) {
652
+ if ((0, api_responses_1.isSuccessResponse)(validatedResponse)) {
653
+ return {
654
+ success: true,
655
+ data: validatedResponse.data,
656
+ message: validatedResponse.message,
657
+ operation_code: validatedResponse.operation_code,
658
+ timestamp: validatedResponse.timestamp
659
+ };
660
+ }
661
+ if ((0, api_responses_1.isPagedResponse)(validatedResponse)) {
662
+ return {
663
+ success: true,
664
+ items: validatedResponse.data,
665
+ message: validatedResponse.message,
666
+ operation_code: validatedResponse.operation_code,
667
+ pagination: validatedResponse.pagination,
668
+ timestamp: validatedResponse.timestamp
669
+ };
670
+ }
671
+ if ((0, api_responses_1.isErrorResponse)(validatedResponse)) {
672
+ const reqId = validatedResponse?.request_id || validatedResponse?.requestId;
673
+ if (validatedResponse.error_code === 'VALIDATION_ERROR') {
674
+ // Handle validation error
675
+ const valError = validatedResponse;
676
+ return {
677
+ success: false,
678
+ error_code: validatedResponse.error_code,
679
+ message: validatedResponse.message,
680
+ operation: validatedResponse.operation,
681
+ details: validatedResponse.details,
682
+ validation_errors: valError.payload?.validation_errors,
683
+ ...(reqId ? { request_id: reqId } : {})
684
+ };
685
+ }
686
+ else {
687
+ // Handle regular error
688
+ return {
689
+ success: false,
690
+ error_code: validatedResponse.error_code,
691
+ message: validatedResponse.message,
692
+ operation: validatedResponse.operation,
693
+ details: validatedResponse.details,
694
+ ...(reqId ? { request_id: reqId } : {})
695
+ };
696
+ }
697
+ }
698
+ // This should never happen due to validation, but TypeScript requires it
699
+ throw new ApiResponseFormatError('Unknown response type after validation', 'unknown', validatedResponse);
700
+ }
701
+ // ========================================================================================
702
+ // HTTP METHOD WRAPPERS - PUBLIC API
703
+ // ========================================================================================
704
+ /**
705
+ * GET REQUEST - Returns typed result with direct data access
706
+ */
707
+ async get(endpoint, sessionToken) {
708
+ return this.makeRequest(endpoint, { method: 'GET' }, sessionToken);
709
+ }
710
+ /**
711
+ * POST REQUEST - Returns typed result with direct data access
712
+ */
713
+ async post(endpoint, data, sessionToken) {
714
+ return this.makeRequest(endpoint, {
715
+ method: 'POST',
716
+ body: data ? JSON.stringify(data) : undefined,
717
+ }, sessionToken);
718
+ }
719
+ /**
720
+ * PUT REQUEST - Returns typed result with direct data access
721
+ */
722
+ async put(endpoint, data, sessionToken) {
723
+ return this.makeRequest(endpoint, {
724
+ method: 'PUT',
725
+ body: data ? JSON.stringify(data) : undefined,
726
+ }, sessionToken);
727
+ }
728
+ /**
729
+ * DELETE REQUEST - Returns typed result with direct data access
730
+ */
731
+ async delete(endpoint) {
732
+ return this.makeRequest(endpoint, { method: 'DELETE' });
733
+ }
734
+ }
735
+ // ========================================================================================
736
+ // SINGLETON INSTANCE - READY TO USE
737
+ // ========================================================================================
738
+ exports.standardizedApi = new StandardizedClientApiService();
739
+ // ========================================================================================
740
+ // CONVENIENCE HELPER FUNCTIONS
741
+ // ========================================================================================
742
+ /**
743
+ * TYPE-SAFE SUCCESS CHECK
744
+ * Use this to check if API call was successful with proper type narrowing
745
+ */
746
+ function isApiSuccess(result) {
747
+ return result.success === true && 'data' in result;
748
+ }
749
+ /**
750
+ * TYPE-SAFE PAGED SUCCESS CHECK
751
+ * Use this to check if API call was successful paged response with proper type narrowing
752
+ */
753
+ function isApiPagedSuccess(result) {
754
+ return result.success === true && 'items' in result;
755
+ }
756
+ /**
757
+ * TYPE-SAFE ERROR CHECK
758
+ * Use this to check if API call failed with proper type narrowing
759
+ */
760
+ function isApiError(result) {
761
+ return result.success === false;
762
+ }
763
+ /**
764
+ * EXTRACT DATA FROM SUCCESS RESULT
765
+ * Use this to get the data from a successful API call
766
+ * Will throw if result is not successful
767
+ */
768
+ function extractApiData(result) {
769
+ if (isApiSuccess(result)) {
770
+ return result.data;
771
+ }
772
+ if (isApiPagedSuccess(result)) {
773
+ return result.items;
774
+ }
775
+ throw new ApiBusinessLogicError(result.error_code, result.message, result.operation, result.details);
776
+ }
777
+ /**
778
+ * EXTRACT ITEMS FROM PAGED SUCCESS RESULT
779
+ * Use this to get the items array from a successful paged API call
780
+ * Will throw if result is not successful paged response
781
+ */
782
+ function extractApiItems(result) {
783
+ if (isApiPagedSuccess(result)) {
784
+ return result.items;
785
+ }
786
+ if (isApiSuccess(result)) {
787
+ // If it's a regular success but expected paged, data should be array
788
+ return result.data;
789
+ }
790
+ throw new ApiBusinessLogicError(result.error_code, result.message, result.operation, result.details);
791
+ }