@aurabase/aurabase-js 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (343) hide show
  1. package/README.md +26 -795
  2. package/{packages/aurabase/dist/AuraClient-DAtDbfPB.d.ts → dist/AuraClient-BcFE8u1v.d.cts} +1 -1
  3. package/{packages/aurabase/dist/AuraClient-DAtDbfPB.d.cts → dist/AuraClient-BcFE8u1v.d.ts} +1 -1
  4. package/{packages/aurabase/dist → dist}/index.d.cts +1 -1
  5. package/{packages/aurabase/dist → dist}/index.d.ts +1 -1
  6. package/{packages/aurabase/dist → dist}/ssr.d.cts +1 -1
  7. package/{packages/aurabase/dist → dist}/ssr.d.ts +1 -1
  8. package/package.json +72 -82
  9. package/.changeset/config.json +0 -11
  10. package/CHANGELOG.md +0 -30
  11. package/packages/ai/LICENSE +0 -21
  12. package/packages/ai/README.md +0 -106
  13. package/packages/ai/dist/index.cjs +0 -229
  14. package/packages/ai/dist/index.d.cts +0 -139
  15. package/packages/ai/dist/index.d.ts +0 -139
  16. package/packages/ai/dist/index.js +0 -226
  17. package/packages/ai/node_modules/.bin/esbuild +0 -19
  18. package/packages/ai/node_modules/.bin/tsc +0 -22
  19. package/packages/ai/node_modules/.bin/tsserver +0 -22
  20. package/packages/ai/node_modules/.bin/tsup +0 -22
  21. package/packages/ai/node_modules/.bin/tsup-node +0 -22
  22. package/packages/ai/node_modules/.bin/vite +0 -22
  23. package/packages/ai/node_modules/.bin/vitest +0 -22
  24. package/packages/ai/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  25. package/packages/ai/package.json +0 -61
  26. package/packages/ai/src/AiService.ts +0 -226
  27. package/packages/ai/src/index.ts +0 -18
  28. package/packages/ai/src/sse.ts +0 -141
  29. package/packages/ai/src/types.ts +0 -30
  30. package/packages/ai/tests/chat-stream.test.ts +0 -151
  31. package/packages/ai/tests/rag-namespaces.test.ts +0 -54
  32. package/packages/ai/tests/sse.test.ts +0 -69
  33. package/packages/ai/tsconfig.json +0 -5
  34. package/packages/ai/tsup.config.ts +0 -11
  35. package/packages/aurabase/LICENSE +0 -21
  36. package/packages/aurabase/README.md +0 -64
  37. package/packages/aurabase/node_modules/.bin/esbuild +0 -19
  38. package/packages/aurabase/node_modules/.bin/tsc +0 -22
  39. package/packages/aurabase/node_modules/.bin/tsserver +0 -22
  40. package/packages/aurabase/node_modules/.bin/tsup +0 -22
  41. package/packages/aurabase/node_modules/.bin/tsup-node +0 -22
  42. package/packages/aurabase/node_modules/.bin/vite +0 -22
  43. package/packages/aurabase/node_modules/.bin/vitest +0 -22
  44. package/packages/aurabase/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  45. package/packages/aurabase/package.json +0 -80
  46. package/packages/aurabase/src/AuraClient.ts +0 -237
  47. package/packages/aurabase/src/index.ts +0 -152
  48. package/packages/aurabase/src/ssr.ts +0 -156
  49. package/packages/aurabase/tests/ai-streaming-rag-e2e.test.ts +0 -82
  50. package/packages/aurabase/tests/ai.test.ts +0 -111
  51. package/packages/aurabase/tests/auth-admin.test.ts +0 -515
  52. package/packages/aurabase/tests/auth-e2e.test.ts +0 -135
  53. package/packages/aurabase/tests/auth-hardening.test.ts +0 -206
  54. package/packages/aurabase/tests/auth.test.ts +0 -947
  55. package/packages/aurabase/tests/database.test.ts +0 -230
  56. package/packages/aurabase/tests/db-types-e2e.test.ts +0 -217
  57. package/packages/aurabase/tests/dispose.test.ts +0 -23
  58. package/packages/aurabase/tests/foreign-token.e2e.test.ts +0 -129
  59. package/packages/aurabase/tests/functions.test.ts +0 -107
  60. package/packages/aurabase/tests/integration.test.ts +0 -413
  61. package/packages/aurabase/tests/live-production-validation.js +0 -241
  62. package/packages/aurabase/tests/live-sdk-production-validation.js +0 -293
  63. package/packages/aurabase/tests/mocks.ts +0 -139
  64. package/packages/aurabase/tests/notifications.test.ts +0 -314
  65. package/packages/aurabase/tests/observability-backup.test.ts +0 -186
  66. package/packages/aurabase/tests/observability-hook.test.ts +0 -130
  67. package/packages/aurabase/tests/production-robustness.test.ts +0 -268
  68. package/packages/aurabase/tests/public-api-surface.test.ts +0 -53
  69. package/packages/aurabase/tests/query-builder.test.ts +0 -329
  70. package/packages/aurabase/tests/readme-smoke-e2e.test.ts +0 -231
  71. package/packages/aurabase/tests/realtime-filter-e2e.test.ts +0 -344
  72. package/packages/aurabase/tests/refresh-locks.test.ts +0 -210
  73. package/packages/aurabase/tests/retry-option.test.ts +0 -17
  74. package/packages/aurabase/tests/rpc-e2e.test.ts +0 -254
  75. package/packages/aurabase/tests/rs256-local-e2e.test.ts +0 -114
  76. package/packages/aurabase/tests/rt-alias-public-e2e.test.ts +0 -235
  77. package/packages/aurabase/tests/rt-http-broadcast-e2e.test.ts +0 -124
  78. package/packages/aurabase/tests/service-role-guard.test.ts +0 -99
  79. package/packages/aurabase/tests/ssr.test.ts +0 -91
  80. package/packages/aurabase/tests/storage-backend-e2e.test.ts +0 -481
  81. package/packages/aurabase/tests/storage-sdk-parity-e2e.test.ts +0 -104
  82. package/packages/aurabase/tests/storage-transform-e2e.test.ts +0 -684
  83. package/packages/aurabase/tests/storage.test.ts +0 -55
  84. package/packages/aurabase/tests/types/client-generic.test-d.ts +0 -79
  85. package/packages/aurabase/tests/types/docs-snippets.test-d.ts +0 -571
  86. package/packages/aurabase/tests/types/error-code.test-d.ts +0 -53
  87. package/packages/aurabase/tsconfig.json +0 -5
  88. package/packages/aurabase/tsconfig.test-d.json +0 -5
  89. package/packages/aurabase/tsup.config.ts +0 -11
  90. package/packages/aurabase/vitest.config.ts +0 -16
  91. package/packages/aurabase/vitest.e2e.config.ts +0 -9
  92. package/packages/auth/LICENSE +0 -21
  93. package/packages/auth/README.md +0 -215
  94. package/packages/auth/dist/index.cjs +0 -1175
  95. package/packages/auth/dist/index.d.cts +0 -397
  96. package/packages/auth/dist/index.d.ts +0 -397
  97. package/packages/auth/dist/index.js +0 -1170
  98. package/packages/auth/node_modules/.bin/esbuild +0 -19
  99. package/packages/auth/node_modules/.bin/tsc +0 -22
  100. package/packages/auth/node_modules/.bin/tsserver +0 -22
  101. package/packages/auth/node_modules/.bin/tsup +0 -22
  102. package/packages/auth/node_modules/.bin/tsup-node +0 -22
  103. package/packages/auth/node_modules/.bin/vite +0 -22
  104. package/packages/auth/node_modules/.bin/vitest +0 -22
  105. package/packages/auth/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  106. package/packages/auth/package.json +0 -61
  107. package/packages/auth/src/AuthAdminService.ts +0 -149
  108. package/packages/auth/src/AuthService.ts +0 -1166
  109. package/packages/auth/src/SessionManager.ts +0 -92
  110. package/packages/auth/src/index.ts +0 -17
  111. package/packages/auth/src/jwks.ts +0 -337
  112. package/packages/auth/src/pkce.ts +0 -27
  113. package/packages/auth/src/types.ts +0 -89
  114. package/packages/auth/tests/auth-lifecycle.test.ts +0 -149
  115. package/packages/auth/tests/detect-session.test.ts +0 -361
  116. package/packages/auth/tests/getclaims.test.ts +0 -780
  117. package/packages/auth/tests/is-mfa-challenge.test.ts +0 -27
  118. package/packages/auth/tests/password-recovery.test.ts +0 -124
  119. package/packages/auth/tests/pkce.test.ts +0 -192
  120. package/packages/auth/tests/session-manager.test.ts +0 -103
  121. package/packages/auth/tests/set-session.test.ts +0 -139
  122. package/packages/auth/tests/verify-otp.test.ts +0 -153
  123. package/packages/auth/tsconfig.json +0 -5
  124. package/packages/auth/tsup.config.ts +0 -11
  125. package/packages/core/LICENSE +0 -21
  126. package/packages/core/README.md +0 -132
  127. package/packages/core/dist/index.cjs +0 -695
  128. package/packages/core/dist/index.d.cts +0 -1137
  129. package/packages/core/dist/index.d.ts +0 -1137
  130. package/packages/core/dist/index.js +0 -673
  131. package/packages/core/node_modules/.bin/esbuild +0 -22
  132. package/packages/core/node_modules/.bin/tsc +0 -22
  133. package/packages/core/node_modules/.bin/tsserver +0 -22
  134. package/packages/core/node_modules/.bin/tsup +0 -22
  135. package/packages/core/node_modules/.bin/tsup-node +0 -22
  136. package/packages/core/node_modules/.bin/vite +0 -22
  137. package/packages/core/node_modules/.bin/vitest +0 -22
  138. package/packages/core/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  139. package/packages/core/package.json +0 -57
  140. package/packages/core/src/AuraError.ts +0 -89
  141. package/packages/core/src/BaseService.ts +0 -44
  142. package/packages/core/src/client.ts +0 -34
  143. package/packages/core/src/cookie-utils.ts +0 -42
  144. package/packages/core/src/fetch.ts +0 -435
  145. package/packages/core/src/index.ts +0 -22
  146. package/packages/core/src/retry.ts +0 -63
  147. package/packages/core/src/serialize.ts +0 -6
  148. package/packages/core/src/stores/BaseAuthStore.ts +0 -164
  149. package/packages/core/src/stores/LocalAuthStore.ts +0 -199
  150. package/packages/core/src/types.ts +0 -1042
  151. package/packages/core/tests/auth-store.test.ts +0 -300
  152. package/packages/core/tests/error-code.test.ts +0 -61
  153. package/packages/core/tests/error.test.ts +0 -24
  154. package/packages/core/tests/fetch.test.ts +0 -286
  155. package/packages/core/tests/mocks.ts +0 -139
  156. package/packages/core/tests/observability.test.ts +0 -86
  157. package/packages/core/tests/refresh-hardening.test.ts +0 -164
  158. package/packages/core/tests/refresh-observability.test.ts +0 -111
  159. package/packages/core/tests/retry.test.ts +0 -106
  160. package/packages/core/tests/serialize.test.ts +0 -12
  161. package/packages/core/tests/timeout.test.ts +0 -79
  162. package/packages/core/tsconfig.json +0 -5
  163. package/packages/core/tsup.config.ts +0 -11
  164. package/packages/db/LICENSE +0 -21
  165. package/packages/db/README.md +0 -152
  166. package/packages/db/VENDORED.md +0 -93
  167. package/packages/db/dist/index.cjs +0 -544
  168. package/packages/db/dist/index.d.cts +0 -1111
  169. package/packages/db/dist/index.d.ts +0 -1111
  170. package/packages/db/dist/index.js +0 -541
  171. package/packages/db/node_modules/.bin/esbuild +0 -19
  172. package/packages/db/node_modules/.bin/tsc +0 -22
  173. package/packages/db/node_modules/.bin/tsserver +0 -22
  174. package/packages/db/node_modules/.bin/tsup +0 -22
  175. package/packages/db/node_modules/.bin/tsup-node +0 -22
  176. package/packages/db/node_modules/.bin/vite +0 -22
  177. package/packages/db/node_modules/.bin/vitest +0 -22
  178. package/packages/db/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  179. package/packages/db/package.json +0 -62
  180. package/packages/db/src/DatabaseService.ts +0 -170
  181. package/packages/db/src/QueryBuilder.ts +0 -830
  182. package/packages/db/src/index.ts +0 -2
  183. package/packages/db/src/pgrst-types/common/common.ts +0 -86
  184. package/packages/db/src/pgrst-types/common/rpc.ts +0 -151
  185. package/packages/db/src/pgrst-types/feature-flags.ts +0 -20
  186. package/packages/db/src/pgrst-types/types.ts +0 -134
  187. package/packages/db/src/select-query-parser/parser.ts +0 -479
  188. package/packages/db/src/select-query-parser/result.ts +0 -553
  189. package/packages/db/src/select-query-parser/types.ts +0 -132
  190. package/packages/db/src/select-query-parser/utils.ts +0 -707
  191. package/packages/db/tests/filters.test.ts +0 -81
  192. package/packages/db/tests/mutations-filtered.e2e.test.ts +0 -132
  193. package/packages/db/tests/mutations-filtered.test.ts +0 -188
  194. package/packages/db/tests/order.test.ts +0 -45
  195. package/packages/db/tests/rpc.test.ts +0 -41
  196. package/packages/db/tests/scale/build-large-schema.ts +0 -94
  197. package/packages/db/tests/scale/scale-compile.test.ts +0 -167
  198. package/packages/db/tests/schema.test.ts +0 -77
  199. package/packages/db/tests/single-accept.e2e.test.ts +0 -123
  200. package/packages/db/tests/single.test.ts +0 -211
  201. package/packages/db/tests/types/filters.test-d.ts +0 -52
  202. package/packages/db/tests/types/fixtures.ts +0 -40
  203. package/packages/db/tests/types/from-views.test-d.ts +0 -18
  204. package/packages/db/tests/types/mutations.test-d.ts +0 -23
  205. package/packages/db/tests/types/rpc.test-d.ts +0 -60
  206. package/packages/db/tests/types/schema-shape.test-d.ts +0 -8
  207. package/packages/db/tests/types/select-inference.test-d.ts +0 -38
  208. package/packages/db/tests/vendored/fixtures.ts +0 -83
  209. package/packages/db/tests/vendored/get-result.test-d.ts +0 -75
  210. package/packages/db/tsconfig.json +0 -5
  211. package/packages/db/tsconfig.test-d.json +0 -5
  212. package/packages/db/tsup.config.ts +0 -11
  213. package/packages/db/vitest.config.ts +0 -8
  214. package/packages/functions/LICENSE +0 -21
  215. package/packages/functions/README.md +0 -96
  216. package/packages/functions/dist/index.cjs +0 -173
  217. package/packages/functions/dist/index.d.cts +0 -81
  218. package/packages/functions/dist/index.d.ts +0 -81
  219. package/packages/functions/dist/index.js +0 -168
  220. package/packages/functions/node_modules/.bin/esbuild +0 -19
  221. package/packages/functions/node_modules/.bin/tsc +0 -22
  222. package/packages/functions/node_modules/.bin/tsserver +0 -22
  223. package/packages/functions/node_modules/.bin/tsup +0 -22
  224. package/packages/functions/node_modules/.bin/tsup-node +0 -22
  225. package/packages/functions/node_modules/.bin/vite +0 -22
  226. package/packages/functions/node_modules/.bin/vitest +0 -22
  227. package/packages/functions/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  228. package/packages/functions/package.json +0 -60
  229. package/packages/functions/src/FunctionsService.ts +0 -188
  230. package/packages/functions/src/errors.ts +0 -70
  231. package/packages/functions/src/index.ts +0 -6
  232. package/packages/functions/tests/invoke.test.ts +0 -97
  233. package/packages/functions/tests/response-type-errors.test.ts +0 -135
  234. package/packages/functions/tsconfig.json +0 -5
  235. package/packages/functions/tsup.config.ts +0 -11
  236. package/packages/gen/LICENSE +0 -21
  237. package/packages/gen/README.md +0 -84
  238. package/packages/gen/dist/cli.cjs +0 -334
  239. package/packages/gen/dist/cli.d.cts +0 -1
  240. package/packages/gen/dist/cli.d.ts +0 -1
  241. package/packages/gen/dist/cli.js +0 -332
  242. package/packages/gen/dist/index.cjs +0 -257
  243. package/packages/gen/dist/index.d.cts +0 -12
  244. package/packages/gen/dist/index.d.ts +0 -12
  245. package/packages/gen/dist/index.js +0 -255
  246. package/packages/gen/node_modules/.bin/esbuild +0 -19
  247. package/packages/gen/node_modules/.bin/tsc +0 -22
  248. package/packages/gen/node_modules/.bin/tsserver +0 -22
  249. package/packages/gen/node_modules/.bin/tsup +0 -22
  250. package/packages/gen/node_modules/.bin/tsup-node +0 -22
  251. package/packages/gen/node_modules/.bin/vite +0 -22
  252. package/packages/gen/node_modules/.bin/vitest +0 -22
  253. package/packages/gen/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  254. package/packages/gen/package.json +0 -66
  255. package/packages/gen/src/cli.ts +0 -67
  256. package/packages/gen/src/generate.ts +0 -0
  257. package/packages/gen/src/index.ts +0 -2
  258. package/packages/gen/tests/compile.test.ts +0 -213
  259. package/packages/gen/tests/e2e.test.ts +0 -130
  260. package/packages/gen/tests/generate.test.ts +0 -396
  261. package/packages/gen/tsconfig.json +0 -5
  262. package/packages/gen/tsup.config.ts +0 -11
  263. package/packages/notifications/LICENSE +0 -21
  264. package/packages/notifications/README.md +0 -134
  265. package/packages/notifications/dist/index.cjs +0 -128
  266. package/packages/notifications/dist/index.d.cts +0 -81
  267. package/packages/notifications/dist/index.d.ts +0 -81
  268. package/packages/notifications/dist/index.js +0 -125
  269. package/packages/notifications/node_modules/.bin/esbuild +0 -19
  270. package/packages/notifications/node_modules/.bin/tsc +0 -22
  271. package/packages/notifications/node_modules/.bin/tsserver +0 -22
  272. package/packages/notifications/node_modules/.bin/tsup +0 -22
  273. package/packages/notifications/node_modules/.bin/tsup-node +0 -22
  274. package/packages/notifications/node_modules/.bin/vite +0 -22
  275. package/packages/notifications/node_modules/.bin/vitest +0 -22
  276. package/packages/notifications/package.json +0 -60
  277. package/packages/notifications/src/NotificationsService.ts +0 -230
  278. package/packages/notifications/src/index.ts +0 -19
  279. package/packages/notifications/tsconfig.json +0 -5
  280. package/packages/notifications/tsup.config.ts +0 -11
  281. package/packages/realtime/LICENSE +0 -21
  282. package/packages/realtime/README.md +0 -183
  283. package/packages/realtime/dist/index.cjs +0 -977
  284. package/packages/realtime/dist/index.d.cts +0 -259
  285. package/packages/realtime/dist/index.d.ts +0 -259
  286. package/packages/realtime/dist/index.js +0 -973
  287. package/packages/realtime/node_modules/.bin/esbuild +0 -19
  288. package/packages/realtime/node_modules/.bin/tsc +0 -22
  289. package/packages/realtime/node_modules/.bin/tsserver +0 -22
  290. package/packages/realtime/node_modules/.bin/tsup +0 -22
  291. package/packages/realtime/node_modules/.bin/tsup-node +0 -22
  292. package/packages/realtime/node_modules/.bin/vite +0 -22
  293. package/packages/realtime/node_modules/.bin/vitest +0 -22
  294. package/packages/realtime/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  295. package/packages/realtime/package.json +0 -60
  296. package/packages/realtime/src/AuraChannel.ts +0 -485
  297. package/packages/realtime/src/HeartbeatManager.ts +0 -73
  298. package/packages/realtime/src/RealtimeService.ts +0 -505
  299. package/packages/realtime/src/columnFilter.ts +0 -301
  300. package/packages/realtime/src/index.ts +0 -4
  301. package/packages/realtime/tests/ack-routing.test.ts +0 -81
  302. package/packages/realtime/tests/column-filter.test.ts +0 -144
  303. package/packages/realtime/tests/dispatch.test.ts +0 -191
  304. package/packages/realtime/tests/heartbeat.test.ts +0 -67
  305. package/packages/realtime/tests/http-broadcast.test.ts +0 -68
  306. package/packages/realtime/tests/realtime-token.test.ts +0 -43
  307. package/packages/realtime/tests/reconnect-race.test.ts +0 -149
  308. package/packages/realtime/tests/ref-id.test.ts +0 -34
  309. package/packages/realtime/tests/set-auth.test.ts +0 -70
  310. package/packages/realtime/tsconfig.json +0 -5
  311. package/packages/realtime/tsup.config.ts +0 -11
  312. package/packages/storage/LICENSE +0 -21
  313. package/packages/storage/README.md +0 -141
  314. package/packages/storage/dist/index.cjs +0 -333
  315. package/packages/storage/dist/index.d.cts +0 -185
  316. package/packages/storage/dist/index.d.ts +0 -185
  317. package/packages/storage/dist/index.js +0 -329
  318. package/packages/storage/node_modules/.bin/esbuild +0 -19
  319. package/packages/storage/node_modules/.bin/tsc +0 -22
  320. package/packages/storage/node_modules/.bin/tsserver +0 -22
  321. package/packages/storage/node_modules/.bin/tsup +0 -22
  322. package/packages/storage/node_modules/.bin/tsup-node +0 -22
  323. package/packages/storage/node_modules/.bin/vite +0 -22
  324. package/packages/storage/node_modules/.bin/vitest +0 -22
  325. package/packages/storage/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  326. package/packages/storage/package.json +0 -60
  327. package/packages/storage/src/DownloadBuilder.ts +0 -60
  328. package/packages/storage/src/StorageService.ts +0 -323
  329. package/packages/storage/src/index.ts +0 -2
  330. package/packages/storage/src/path.ts +0 -35
  331. package/packages/storage/src/transform.ts +0 -15
  332. package/packages/storage/tests/download.test.ts +0 -64
  333. package/packages/storage/tests/parity.test.ts +0 -154
  334. package/packages/storage/tests/path.test.ts +0 -87
  335. package/packages/storage/tests/transform.test.ts +0 -79
  336. package/packages/storage/tsconfig.json +0 -5
  337. package/packages/storage/tsup.config.ts +0 -11
  338. package/pnpm-workspace.yaml +0 -24
  339. package/tsconfig.base.json +0 -15
  340. /package/{packages/aurabase/dist → dist}/index.cjs +0 -0
  341. /package/{packages/aurabase/dist → dist}/index.js +0 -0
  342. /package/{packages/aurabase/dist → dist}/ssr.cjs +0 -0
  343. /package/{packages/aurabase/dist → dist}/ssr.js +0 -0
@@ -1,139 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // FetchMock -- intercepts globalThis.fetch for deterministic SDK tests
3
- // ---------------------------------------------------------------------------
4
-
5
- export interface RequestMock {
6
- method: string
7
- url: string | RegExp
8
- replyCode: number
9
- replyBody?: unknown
10
- replyHeaders?: Record<string, string>
11
- }
12
-
13
- export interface FetchCall {
14
- url: string
15
- method: string
16
- headers: Headers
17
- body?: unknown
18
- }
19
-
20
- export class FetchMock {
21
- private originalFetch?: typeof fetch
22
- private mocks: RequestMock[] = []
23
- calls: FetchCall[] = []
24
-
25
- /** Register a mock response. */
26
- on(mock: RequestMock): void {
27
- this.mocks.push(mock)
28
- }
29
-
30
- /** Replace globalThis.fetch with the mock implementation. */
31
- init(): void {
32
- this.originalFetch = globalThis.fetch
33
- globalThis.fetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {
34
- const url = typeof input === 'string' ? input : input.toString()
35
- const method = (init?.method ?? 'GET').toUpperCase()
36
- const headers = new Headers(init?.headers)
37
- let body: unknown
38
- if (typeof init?.body === 'string') {
39
- try {
40
- body = JSON.parse(init.body)
41
- } catch {
42
- body = init.body
43
- }
44
- } else {
45
- body = init?.body
46
- }
47
- this.calls.push({ url, method, headers, body })
48
-
49
- for (const mock of this.mocks) {
50
- const urlMatch =
51
- mock.url instanceof RegExp ? mock.url.test(url) : mock.url === url
52
- if (urlMatch && mock.method.toUpperCase() === method) {
53
- return new Response(
54
- mock.replyBody !== undefined ? JSON.stringify(mock.replyBody) : null,
55
- {
56
- status: mock.replyCode,
57
- headers: {
58
- 'Content-Type': 'application/json',
59
- ...mock.replyHeaders,
60
- },
61
- },
62
- )
63
- }
64
- }
65
-
66
- throw new Error(`FetchMock: no mock for ${method} ${url}`)
67
- }
68
- }
69
-
70
- /** Restore the original globalThis.fetch. */
71
- restore(): void {
72
- if (this.originalFetch) {
73
- globalThis.fetch = this.originalFetch
74
- }
75
- }
76
-
77
- /** Remove all registered mocks. */
78
- clearMocks(): void {
79
- this.mocks = []
80
- this.calls = []
81
- }
82
- }
83
-
84
- // ---------------------------------------------------------------------------
85
- // Helpers -- reusable test data factories
86
- // ---------------------------------------------------------------------------
87
-
88
- import type { User, TokenPair } from '../src/types'
89
-
90
- /** Build a fake JWT whose payload encodes the given exp (seconds since epoch). */
91
- export function fakeJwt(exp: number): string {
92
- const header = btoa(JSON.stringify({ alg: 'HS256', typ: 'JWT' }))
93
- .replace(/\+/g, '-')
94
- .replace(/\//g, '_')
95
- .replace(/=+$/, '')
96
- const payload = btoa(JSON.stringify({ sub: 'user-1', exp }))
97
- .replace(/\+/g, '-')
98
- .replace(/\//g, '_')
99
- .replace(/=+$/, '')
100
- const sig = 'fake_sig'
101
- return `${header}.${payload}.${sig}`
102
- }
103
-
104
- /** A JWT that expires far in the future. */
105
- export function validJwt(): string {
106
- return fakeJwt(Math.floor(Date.now() / 1000) + 3600)
107
- }
108
-
109
- /** A JWT that is already expired. */
110
- export function expiredJwt(): string {
111
- return fakeJwt(Math.floor(Date.now() / 1000) - 60)
112
- }
113
-
114
- export function fakeUser(overrides: Partial<User> = {}): User {
115
- return {
116
- id: 'user-1',
117
- email: 'test@example.com',
118
- role: 'authenticated',
119
- email_verified: true,
120
- is_banned: false,
121
- is_anonymous: false,
122
- mfa_enabled: false,
123
- user_metadata: {},
124
- app_metadata: {},
125
- created_at: '2025-01-01T00:00:00Z',
126
- ...overrides,
127
- }
128
- }
129
-
130
- export function fakeTokenPair(overrides: Partial<TokenPair> = {}): TokenPair {
131
- return {
132
- access_token: validJwt(),
133
- refresh_token: 'rt_fake_refresh',
134
- token_type: 'bearer',
135
- expires_in: 3600,
136
- user: fakeUser(),
137
- ...overrides,
138
- }
139
- }
@@ -1,86 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // emitAuraEvent (LOT 3, finding I8) -- observability hook helper
3
- // ---------------------------------------------------------------------------
4
-
5
- import { describe, it, expect, vi, afterEach } from 'vitest'
6
- import { emitAuraEvent, type AuraObservabilityEvent } from '../src/types'
7
-
8
- afterEach(() => {
9
- vi.restoreAllMocks()
10
- })
11
-
12
- describe('emitAuraEvent', () => {
13
- it('appelle onEvent avec l’événement tel quel', () => {
14
- const received: AuraObservabilityEvent[] = []
15
- const event: AuraObservabilityEvent = { kind: 'timeout', url: 'http://x/y' }
16
- emitAuraEvent((e) => received.push(e), false, event)
17
- expect(received).toEqual([event])
18
- })
19
-
20
- it('ne fait rien si onEvent est undefined (pas de throw)', () => {
21
- expect(() => emitAuraEvent(undefined, false, { kind: 'refresh-success' })).not.toThrow()
22
- })
23
-
24
- it('NE THROW JAMAIS si le hook onEvent lève une exception', () => {
25
- const boom = () => {
26
- throw new Error('consumer hook boom')
27
- }
28
- expect(() =>
29
- emitAuraEvent(boom, false, { kind: 'refresh-discarded', reason: 'test' }),
30
- ).not.toThrow()
31
- })
32
-
33
- it('debug:true journalise via console.debug en plus du hook', () => {
34
- const spy = vi.spyOn(console, 'debug').mockImplementation(() => {})
35
- const received: AuraObservabilityEvent[] = []
36
- const event: AuraObservabilityEvent = { kind: 'jwks-fetch-failed', baseUrl: 'http://x' }
37
- emitAuraEvent((e) => received.push(e), true, event)
38
- expect(spy).toHaveBeenCalledWith('[aurabase]', event)
39
- expect(received).toEqual([event])
40
- })
41
-
42
- it('debug:true SANS onEvent journalise quand même via console.debug', () => {
43
- const spy = vi.spyOn(console, 'debug').mockImplementation(() => {})
44
- emitAuraEvent(undefined, true, { kind: 'storage-blocked', op: 'setItem' })
45
- expect(spy).toHaveBeenCalledTimes(1)
46
- })
47
-
48
- it('debug:false (ou omis) ne journalise pas', () => {
49
- const spy = vi.spyOn(console, 'debug').mockImplementation(() => {})
50
- emitAuraEvent(() => {}, false, { kind: 'refresh-success' })
51
- expect(spy).not.toHaveBeenCalled()
52
- })
53
-
54
- it('minor 6a : RÉDIGE la query/fragment de `url` (retry/timeout) — pas de fuite de capacité bearer', () => {
55
- const received: AuraObservabilityEvent[] = []
56
- emitAuraEvent((e) => received.push(e), false, {
57
- kind: 'retry',
58
- attempt: 1,
59
- url: 'https://api.host/v1/db/proj/rest/posts?apikey=aura_sk_secret&token=abc#frag',
60
- })
61
- const got = received[0] as { kind: string; url: string }
62
- expect(got.url).toBe('https://api.host/v1/db/proj/rest/posts')
63
- expect(got.url).not.toContain('apikey')
64
- expect(got.url).not.toContain('token')
65
- expect(got.url).not.toContain('#')
66
- })
67
-
68
- it('minor 6a : `url` sans query est inchangée ; `baseUrl` (jwks) jamais touché', () => {
69
- const received: AuraObservabilityEvent[] = []
70
- emitAuraEvent((e) => received.push(e), false, { kind: 'timeout', url: 'http://x/y' })
71
- emitAuraEvent((e) => received.push(e), false, { kind: 'jwks-fetch-failed', baseUrl: 'http://x' })
72
- expect((received[0] as { url: string }).url).toBe('http://x/y')
73
- expect((received[1] as { baseUrl: string }).baseUrl).toBe('http://x')
74
- })
75
-
76
- it('une exception dans console.debug ne casse pas non plus l’émission', () => {
77
- vi.spyOn(console, 'debug').mockImplementation(() => {
78
- throw new Error('console boom')
79
- })
80
- const received: AuraObservabilityEvent[] = []
81
- expect(() =>
82
- emitAuraEvent((e) => received.push(e), true, { kind: 'refresh-success' }),
83
- ).not.toThrow()
84
- expect(received).toHaveLength(1)
85
- })
86
- })
@@ -1,164 +0,0 @@
1
- import { describe, it, expect, vi, afterEach } from 'vitest'
2
- import { refreshOnce } from '../src/fetch'
3
- import { BaseAuthStore } from '../src/stores/BaseAuthStore'
4
- import type { AuraClientLike } from '../src/client'
5
- import { fakeTokenPair, fakeUser, validJwt } from './mocks'
6
-
7
- afterEach(() => vi.useRealTimers())
8
-
9
- function client(fetchFn: typeof globalThis.fetch, store = new BaseAuthStore()): AuraClientLike {
10
- store.save(validJwt(), 'rt_current', fakeUser())
11
- return {
12
- baseUrl: 'http://x',
13
- projectId: 'p',
14
- apiKey: 'k',
15
- fetchFn,
16
- authStore: store,
17
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
- auth: { refreshSession: async () => ({ data: null, error: null }) as any },
19
- }
20
- }
21
-
22
- describe('BaseAuthStore.removalEpoch', () => {
23
- it('incrémente à chaque clear()', () => {
24
- const s = new BaseAuthStore()
25
- expect(s.removalEpoch).toBe(0)
26
- s.clear()
27
- expect(s.removalEpoch).toBe(1)
28
- s.clear()
29
- expect(s.removalEpoch).toBe(2)
30
- })
31
- })
32
-
33
- describe('commit-guard : refresh jeté si clear() concurrent', () => {
34
- it('ne sauvegarde pas les tokens si la session a été vidée pendant le refresh', async () => {
35
- const store = new BaseAuthStore()
36
- let resolveFetch: (r: Response) => void
37
- const fetchFn = vi.fn().mockImplementation(
38
- () => new Promise<Response>((res) => { resolveFetch = res }),
39
- )
40
- const c = client(fetchFn as unknown as typeof globalThis.fetch, store)
41
- const p = refreshOnce(c)
42
- store.clear() // un signOut arrive pendant l'await du fetch
43
- resolveFetch!(
44
- new Response(JSON.stringify(fakeTokenPair({ refresh_token: 'rt_new' })), {
45
- status: 200,
46
- headers: { 'Content-Type': 'application/json' },
47
- }),
48
- )
49
- const res = await p
50
- expect(res.error?.status).toBe(409)
51
- expect(res.error?.code).toBe('refresh_discarded')
52
- expect(store.token).toBeNull() // pas ressuscité
53
- })
54
- })
55
-
56
- describe('proactive-preserve + commit-guard (sans cooldown)', () => {
57
- it('échec transitoire (5xx) préserve la session ET ne cache PAS (2e refresh re-tape le réseau)', async () => {
58
- const store = new BaseAuthStore()
59
- store.save(validJwt(), 'rt_stable', fakeUser())
60
- const fetchFn = vi.fn().mockResolvedValue(
61
- new Response(JSON.stringify({ error: { code: 'server_error', message: 'boom' } }), {
62
- status: 500,
63
- headers: { 'Content-Type': 'application/json' },
64
- }),
65
- )
66
- const c = {
67
- baseUrl: 'http://x', projectId: 'p', apiKey: 'k',
68
- fetchFn: fetchFn as unknown as typeof globalThis.fetch, authStore: store,
69
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
70
- auth: { refreshSession: async () => ({ data: null, error: null }) as any },
71
- } as AuraClientLike
72
- const r1 = await refreshOnce(c)
73
- expect(r1.error).toBeTruthy()
74
- expect(store.token).not.toBeNull() // 5xx transitoire → session PRÉSERVÉE
75
- const r2 = await refreshOnce(c)
76
- expect(r2.error).toBeTruthy()
77
- expect(fetchFn).toHaveBeenCalledTimes(2) // PAS de cooldown → 2e re-tape le réseau
78
- })
79
-
80
- it('FIX1 succès : un signIn concurrent (rt différent) n’est PAS écrasé par le refresh de l’ancien token', async () => {
81
- const store = new BaseAuthStore()
82
- store.save(validJwt(), 'rt_old', fakeUser())
83
- let resolveFetch!: (r: Response) => void
84
- const fetchFn = vi.fn().mockImplementation(() => new Promise<Response>((res) => { resolveFetch = res }))
85
- const c = {
86
- baseUrl: 'http://x', projectId: 'p', apiKey: 'k',
87
- fetchFn: fetchFn as unknown as typeof globalThis.fetch, authStore: store,
88
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
89
- auth: { refreshSession: async () => ({ data: null, error: null }) as any },
90
- } as AuraClientLike
91
- const p = refreshOnce(c)
92
- store.save(validJwt(), 'rt_new', fakeUser()) // signIn concurrent
93
- resolveFetch(new Response(JSON.stringify(fakeTokenPair({ refresh_token: 'rt_rotated' })), {
94
- status: 200, headers: { 'Content-Type': 'application/json' },
95
- }))
96
- const r = await p
97
- expect(r.error?.code).toBe('refresh_discarded')
98
- expect(store.refreshToken).toBe('rt_new') // session neuve PRÉSERVÉE
99
- })
100
-
101
- it('FIX1 échec : un signIn concurrent n’est PAS effacé par un 401 sur l’ancien token', async () => {
102
- const store = new BaseAuthStore()
103
- store.save(validJwt(), 'rt_old', fakeUser())
104
- let resolveFetch!: (r: Response) => void
105
- const fetchFn = vi.fn().mockImplementation(() => new Promise<Response>((res) => { resolveFetch = res }))
106
- const c = {
107
- baseUrl: 'http://x', projectId: 'p', apiKey: 'k',
108
- fetchFn: fetchFn as unknown as typeof globalThis.fetch, authStore: store,
109
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
110
- auth: { refreshSession: async () => ({ data: null, error: null }) as any },
111
- } as AuraClientLike
112
- const p = refreshOnce(c)
113
- store.save(validJwt(), 'rt_new', fakeUser()) // signIn concurrent
114
- resolveFetch(new Response(JSON.stringify({ error: { code: 'invalid_grant', message: 'revoked' } }), {
115
- status: 401, headers: { 'Content-Type': 'application/json' },
116
- }))
117
- await p
118
- expect(store.token).not.toBeNull() // NON effacée
119
- expect(store.refreshToken).toBe('rt_new') // session neuve intacte
120
- })
121
-
122
- it('rejet définitif (401) → session détruite', async () => {
123
- const store = new BaseAuthStore()
124
- store.save(validJwt(), 'rt_x', fakeUser())
125
- const fetchFn = vi.fn().mockResolvedValue(
126
- new Response(JSON.stringify({ error: { code: 'invalid_grant', message: 'revoked' } }), {
127
- status: 401,
128
- headers: { 'Content-Type': 'application/json' },
129
- }),
130
- )
131
- const c = {
132
- baseUrl: 'http://x',
133
- projectId: 'p',
134
- apiKey: 'k',
135
- fetchFn: fetchFn as unknown as typeof globalThis.fetch,
136
- authStore: store,
137
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
138
- auth: { refreshSession: async () => ({ data: null, error: null }) as any },
139
- } as AuraClientLike
140
- const r = await refreshOnce(c)
141
- expect(r.error?.status).toBe(401)
142
- expect(store.token).toBeNull() // session morte
143
- })
144
- })
145
-
146
- describe('FIX4 : corps de succès non-JSON', () => {
147
- it('un 200 au corps non-JSON renvoie invalid_response (pas de throw) et préserve la session', async () => {
148
- const store = new BaseAuthStore()
149
- const fetchFn = vi.fn().mockResolvedValue(
150
- // 200 OK mais corps HTML (proxy mal configuré) → res.json() throw.
151
- new Response('<html>Service Unavailable</html>', {
152
- status: 200,
153
- headers: { 'Content-Type': 'text/html' },
154
- }),
155
- )
156
- const c = client(fetchFn as unknown as typeof globalThis.fetch, store)
157
- // Ne doit PAS rejeter : refreshOnce renvoie toujours un AuraResponse.
158
- const r = await refreshOnce(c)
159
- expect(r.data).toBeNull()
160
- expect(r.error?.code).toBe('invalid_response')
161
- // Un succès illisible n'est pas un rejet définitif → session préservée.
162
- expect(store.token).not.toBeNull()
163
- })
164
- })
@@ -1,111 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Observabilité du refresh (LOT 3, finding I8) : refresh-success / refresh-discarded
3
- // ---------------------------------------------------------------------------
4
- //
5
- // NOTE : n'utilise PAS le pattern `resolveFetch` manuel de `refresh-hardening.test.ts`
6
- // (pré-existant, flaky indépendamment de ce lot — cf. Web Locks LOT 2). On s'appuie
7
- // à la place sur `mockResolvedValue` (le fetch est déjà résolu, mais `await` cède
8
- // quand même la main le temps d'un microtask), ce qui suffit à ouvrir la fenêtre de
9
- // course nécessaire au test `refresh-discarded` sans dépendre d'un timing fragile.
10
-
11
- import { describe, it, expect, afterEach, vi } from 'vitest'
12
- import { refreshOnce } from '../src/fetch'
13
- import { BaseAuthStore } from '../src/stores/BaseAuthStore'
14
- import type { AuraClientLike } from '../src/client'
15
- import { fakeTokenPair, fakeUser, validJwt } from './mocks'
16
- import type { AuraObservabilityEvent } from '../src/types'
17
-
18
- afterEach(() => vi.useRealTimers())
19
-
20
- function client(
21
- fetchFn: typeof globalThis.fetch,
22
- onEvent: (e: AuraObservabilityEvent) => void,
23
- store = new BaseAuthStore(),
24
- ): AuraClientLike {
25
- store.save(validJwt(), 'rt_current', fakeUser())
26
- return {
27
- baseUrl: 'http://x',
28
- projectId: 'p',
29
- apiKey: 'k',
30
- fetchFn,
31
- authStore: store,
32
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
33
- auth: { refreshSession: async () => ({ data: null, error: null }) as any },
34
- onEvent,
35
- }
36
- }
37
-
38
- describe('refreshOnce — observabilité (onEvent)', () => {
39
- it('émet {kind:"refresh-success"} quand le refresh aboutit', async () => {
40
- const events: AuraObservabilityEvent[] = []
41
- const fetchFn = vi.fn().mockResolvedValue(
42
- new Response(JSON.stringify(fakeTokenPair({ refresh_token: 'rt_new' })), {
43
- status: 200,
44
- headers: { 'Content-Type': 'application/json' },
45
- }),
46
- )
47
- const store = new BaseAuthStore()
48
- const c = client(fetchFn as unknown as typeof globalThis.fetch, (e) => events.push(e), store)
49
- // rt_current doit correspondre au refresh_token utilisé par doRefresh (posé par client()).
50
- const res = await refreshOnce(c)
51
- expect(res.error).toBeNull()
52
- expect(events).toContainEqual({ kind: 'refresh-success' })
53
- })
54
-
55
- it('émet {kind:"refresh-discarded", reason} quand la session change pendant le refresh (commit-guard)', async () => {
56
- const events: AuraObservabilityEvent[] = []
57
- const store = new BaseAuthStore()
58
- let resolveFetch!: (r: Response) => void
59
- const fetchFn = vi.fn().mockImplementation(
60
- () => new Promise<Response>((res) => { resolveFetch = res }),
61
- )
62
- const c = client(fetchFn as unknown as typeof globalThis.fetch, (e) => events.push(e), store)
63
- const p = refreshOnce(c)
64
- // NOTE (à jour) : `withRefreshLock` est GATÉ sur `window` — hors navigateur (ces
65
- // tests s'exécutent sous Node SANS `window`), `navigator.locks` n'est PAS utilisé
66
- // même s'il existe (Node ≥21) ; `doRefresh` s'exécute donc directement (single-flight
67
- // in-process seul). On garde néanmoins `waitFor` (robuste au timing des microtasks)
68
- // pour laisser `doRefresh` atteindre `await client.fetchFn(...)` (donc `resolveFetch`
69
- // assigné) avant d'intercaler le `clear()` concurrent.
70
- await vi.waitFor(() => expect(fetchFn).toHaveBeenCalled(), { timeout: 2000, interval: 5 })
71
- store.clear() // un signOut concurrent s'intercale avant la résolution du fetch
72
- resolveFetch(
73
- new Response(JSON.stringify(fakeTokenPair({ refresh_token: 'rt_new_from_server' })), {
74
- status: 200,
75
- headers: { 'Content-Type': 'application/json' },
76
- }),
77
- )
78
- const res = await p
79
- expect(res.error?.code).toBe('refresh_discarded')
80
- const discarded = events.find((e) => e.kind === 'refresh-discarded')
81
- expect(discarded).toBeDefined()
82
- expect((discarded as { kind: 'refresh-discarded'; reason: string }).reason).toEqual(
83
- expect.any(String),
84
- )
85
- // Pas de refresh-success émis dans ce scénario.
86
- expect(events.some((e) => e.kind === 'refresh-success')).toBe(false)
87
- })
88
-
89
- it('onEvent absent (undefined) : aucun throw, comportement inchangé', async () => {
90
- const fetchFn = vi.fn().mockResolvedValue(
91
- new Response(JSON.stringify(fakeTokenPair({ refresh_token: 'rt_new' })), {
92
- status: 200,
93
- headers: { 'Content-Type': 'application/json' },
94
- }),
95
- )
96
- const store = new BaseAuthStore()
97
- store.save(validJwt(), 'rt_current', fakeUser())
98
- const c: AuraClientLike = {
99
- baseUrl: 'http://x',
100
- projectId: 'p',
101
- apiKey: 'k',
102
- fetchFn: fetchFn as unknown as typeof globalThis.fetch,
103
- authStore: store,
104
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
105
- auth: { refreshSession: async () => ({ data: null, error: null }) as any },
106
- // onEvent volontairement omis
107
- }
108
- const res = await refreshOnce(c)
109
- expect(res.error).toBeNull()
110
- })
111
- })
@@ -1,106 +0,0 @@
1
- import { describe, it, expect, vi, afterEach } from 'vitest'
2
- import {
3
- isRetryableStatus,
4
- isRetryableMethod,
5
- computeBackoff,
6
- parseRetryAfter,
7
- abortableSleep,
8
- isAbortError,
9
- DEFAULT_MAX_RETRIES,
10
- } from '../src/retry'
11
-
12
- describe('retry — prédicats', () => {
13
- it('isRetryableStatus', () => {
14
- for (const s of [408, 429, 502, 503, 504]) expect(isRetryableStatus(s)).toBe(true)
15
- for (const s of [200, 400, 401, 404, 500, 501]) expect(isRetryableStatus(s)).toBe(false)
16
- })
17
- it('isRetryableMethod (insensible à la casse)', () => {
18
- for (const m of ['GET', 'get', 'HEAD', 'head']) expect(isRetryableMethod(m)).toBe(true)
19
- for (const m of ['POST', 'PATCH', 'DELETE', 'PUT']) expect(isRetryableMethod(m)).toBe(false)
20
- })
21
- it('DEFAULT_MAX_RETRIES vaut 3', () => {
22
- expect(DEFAULT_MAX_RETRIES).toBe(3)
23
- })
24
- })
25
-
26
- describe('computeBackoff — full jitter', () => {
27
- it('borne = min(500·2^attempt, 10000)', () => {
28
- expect(computeBackoff(0, () => 1)).toBe(500)
29
- expect(computeBackoff(1, () => 1)).toBe(1000)
30
- expect(computeBackoff(2, () => 1)).toBe(2000)
31
- expect(computeBackoff(10, () => 1)).toBe(10000) // plafonné
32
- })
33
- it('rand=0 → 0', () => {
34
- expect(computeBackoff(3, () => 0)).toBe(0)
35
- })
36
- it('valeur ∈ [0, borne]', () => {
37
- const v = computeBackoff(2, () => 0.5)
38
- expect(v).toBeGreaterThanOrEqual(0)
39
- expect(v).toBeLessThanOrEqual(2000)
40
- })
41
- })
42
-
43
- describe('parseRetryAfter', () => {
44
- it('secondes → ms', () => {
45
- expect(parseRetryAfter('5')).toBe(5000)
46
- expect(parseRetryAfter('0')).toBe(0)
47
- })
48
- it('HTTP-date → delta ms (now injecté)', () => {
49
- const now = 1_000_000_000_000
50
- const future = new Date(now + 3000).toUTCString()
51
- expect(parseRetryAfter(future, now)).toBe(3000)
52
- })
53
- it('date passée → 0 (jamais négatif)', () => {
54
- const now = 1_000_000_000_000
55
- const past = new Date(now - 5000).toUTCString()
56
- expect(parseRetryAfter(past, now)).toBe(0)
57
- })
58
- it('null ou garbage → null', () => {
59
- expect(parseRetryAfter(null)).toBeNull()
60
- expect(parseRetryAfter('not-a-date')).toBeNull()
61
- })
62
- })
63
-
64
- describe('abortableSleep', () => {
65
- afterEach(() => vi.useRealTimers())
66
- it('résout après le délai', async () => {
67
- vi.useFakeTimers()
68
- let done = false
69
- const p = abortableSleep(1000).then(() => {
70
- done = true
71
- })
72
- await vi.advanceTimersByTimeAsync(999)
73
- expect(done).toBe(false)
74
- await vi.advanceTimersByTimeAsync(1)
75
- await p
76
- expect(done).toBe(true)
77
- })
78
- it('signal déjà aborté → résout immédiatement', async () => {
79
- const ac = new AbortController()
80
- ac.abort()
81
- await expect(abortableSleep(100000, ac.signal)).resolves.toBeUndefined()
82
- })
83
- it('abort pendant l’attente → résout tôt (sans rejeter)', async () => {
84
- vi.useFakeTimers()
85
- const ac = new AbortController()
86
- let done = false
87
- const p = abortableSleep(100000, ac.signal).then(() => {
88
- done = true
89
- })
90
- ac.abort()
91
- await p
92
- expect(done).toBe(true)
93
- })
94
- })
95
-
96
- describe('isAbortError', () => {
97
- it('reconnaît AbortError', () => {
98
- expect(isAbortError({ name: 'AbortError' })).toBe(true)
99
- expect(isAbortError(new DOMException('x', 'AbortError'))).toBe(true)
100
- })
101
- it('rejette le reste', () => {
102
- expect(isAbortError(new Error('boom'))).toBe(false)
103
- expect(isAbortError(null)).toBe(false)
104
- expect(isAbortError('AbortError')).toBe(false)
105
- })
106
- })
@@ -1,12 +0,0 @@
1
- import { describe, it, expect } from 'vitest'
2
- import { serializeBody } from '../src/serialize'
3
-
4
- describe('serializeBody', () => {
5
- it('sérialise un objet normal', () => {
6
- expect(serializeBody({ a: 1, b: 'x' })).toBe('{"a":1,"b":"x"}')
7
- })
8
- it('convertit les bigint en string (pas de TypeError)', () => {
9
- expect(serializeBody({ id: 10n })).toBe('{"id":"10"}')
10
- expect(serializeBody({ big: 9007199254740993n })).toBe('{"big":"9007199254740993"}')
11
- })
12
- })