@aurabase/aurabase-js 0.3.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 (344) hide show
  1. package/.changeset/config.json +11 -0
  2. package/CHANGELOG.md +30 -0
  3. package/LICENSE +21 -0
  4. package/README.md +833 -0
  5. package/package.json +90 -0
  6. package/packages/ai/LICENSE +21 -0
  7. package/packages/ai/README.md +106 -0
  8. package/packages/ai/dist/index.cjs +229 -0
  9. package/packages/ai/dist/index.d.cts +139 -0
  10. package/packages/ai/dist/index.d.ts +139 -0
  11. package/packages/ai/dist/index.js +226 -0
  12. package/packages/ai/node_modules/.bin/esbuild +19 -0
  13. package/packages/ai/node_modules/.bin/tsc +22 -0
  14. package/packages/ai/node_modules/.bin/tsserver +22 -0
  15. package/packages/ai/node_modules/.bin/tsup +22 -0
  16. package/packages/ai/node_modules/.bin/tsup-node +22 -0
  17. package/packages/ai/node_modules/.bin/vite +22 -0
  18. package/packages/ai/node_modules/.bin/vitest +22 -0
  19. package/packages/ai/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  20. package/packages/ai/package.json +61 -0
  21. package/packages/ai/src/AiService.ts +226 -0
  22. package/packages/ai/src/index.ts +18 -0
  23. package/packages/ai/src/sse.ts +141 -0
  24. package/packages/ai/src/types.ts +30 -0
  25. package/packages/ai/tests/chat-stream.test.ts +151 -0
  26. package/packages/ai/tests/rag-namespaces.test.ts +54 -0
  27. package/packages/ai/tests/sse.test.ts +69 -0
  28. package/packages/ai/tsconfig.json +5 -0
  29. package/packages/ai/tsup.config.ts +11 -0
  30. package/packages/aurabase/LICENSE +21 -0
  31. package/packages/aurabase/README.md +64 -0
  32. package/packages/aurabase/dist/AuraClient-DAtDbfPB.d.cts +77 -0
  33. package/packages/aurabase/dist/AuraClient-DAtDbfPB.d.ts +77 -0
  34. package/packages/aurabase/dist/index.cjs +237 -0
  35. package/packages/aurabase/dist/index.d.cts +46 -0
  36. package/packages/aurabase/dist/index.d.ts +46 -0
  37. package/packages/aurabase/dist/index.js +177 -0
  38. package/packages/aurabase/dist/ssr.cjs +224 -0
  39. package/packages/aurabase/dist/ssr.d.cts +65 -0
  40. package/packages/aurabase/dist/ssr.d.ts +65 -0
  41. package/packages/aurabase/dist/ssr.js +214 -0
  42. package/packages/aurabase/node_modules/.bin/esbuild +19 -0
  43. package/packages/aurabase/node_modules/.bin/tsc +22 -0
  44. package/packages/aurabase/node_modules/.bin/tsserver +22 -0
  45. package/packages/aurabase/node_modules/.bin/tsup +22 -0
  46. package/packages/aurabase/node_modules/.bin/tsup-node +22 -0
  47. package/packages/aurabase/node_modules/.bin/vite +22 -0
  48. package/packages/aurabase/node_modules/.bin/vitest +22 -0
  49. package/packages/aurabase/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  50. package/packages/aurabase/package.json +80 -0
  51. package/packages/aurabase/src/AuraClient.ts +237 -0
  52. package/packages/aurabase/src/index.ts +152 -0
  53. package/packages/aurabase/src/ssr.ts +156 -0
  54. package/packages/aurabase/tests/ai-streaming-rag-e2e.test.ts +82 -0
  55. package/packages/aurabase/tests/ai.test.ts +111 -0
  56. package/packages/aurabase/tests/auth-admin.test.ts +515 -0
  57. package/packages/aurabase/tests/auth-e2e.test.ts +135 -0
  58. package/packages/aurabase/tests/auth-hardening.test.ts +206 -0
  59. package/packages/aurabase/tests/auth.test.ts +947 -0
  60. package/packages/aurabase/tests/database.test.ts +230 -0
  61. package/packages/aurabase/tests/db-types-e2e.test.ts +217 -0
  62. package/packages/aurabase/tests/dispose.test.ts +23 -0
  63. package/packages/aurabase/tests/foreign-token.e2e.test.ts +129 -0
  64. package/packages/aurabase/tests/functions.test.ts +107 -0
  65. package/packages/aurabase/tests/integration.test.ts +413 -0
  66. package/packages/aurabase/tests/live-production-validation.js +241 -0
  67. package/packages/aurabase/tests/live-sdk-production-validation.js +293 -0
  68. package/packages/aurabase/tests/mocks.ts +139 -0
  69. package/packages/aurabase/tests/notifications.test.ts +314 -0
  70. package/packages/aurabase/tests/observability-backup.test.ts +186 -0
  71. package/packages/aurabase/tests/observability-hook.test.ts +130 -0
  72. package/packages/aurabase/tests/production-robustness.test.ts +268 -0
  73. package/packages/aurabase/tests/public-api-surface.test.ts +53 -0
  74. package/packages/aurabase/tests/query-builder.test.ts +329 -0
  75. package/packages/aurabase/tests/readme-smoke-e2e.test.ts +231 -0
  76. package/packages/aurabase/tests/realtime-filter-e2e.test.ts +344 -0
  77. package/packages/aurabase/tests/refresh-locks.test.ts +210 -0
  78. package/packages/aurabase/tests/retry-option.test.ts +17 -0
  79. package/packages/aurabase/tests/rpc-e2e.test.ts +254 -0
  80. package/packages/aurabase/tests/rs256-local-e2e.test.ts +114 -0
  81. package/packages/aurabase/tests/rt-alias-public-e2e.test.ts +235 -0
  82. package/packages/aurabase/tests/rt-http-broadcast-e2e.test.ts +124 -0
  83. package/packages/aurabase/tests/service-role-guard.test.ts +99 -0
  84. package/packages/aurabase/tests/ssr.test.ts +91 -0
  85. package/packages/aurabase/tests/storage-backend-e2e.test.ts +481 -0
  86. package/packages/aurabase/tests/storage-sdk-parity-e2e.test.ts +104 -0
  87. package/packages/aurabase/tests/storage-transform-e2e.test.ts +684 -0
  88. package/packages/aurabase/tests/storage.test.ts +55 -0
  89. package/packages/aurabase/tests/types/client-generic.test-d.ts +79 -0
  90. package/packages/aurabase/tests/types/docs-snippets.test-d.ts +571 -0
  91. package/packages/aurabase/tests/types/error-code.test-d.ts +53 -0
  92. package/packages/aurabase/tsconfig.json +5 -0
  93. package/packages/aurabase/tsconfig.test-d.json +5 -0
  94. package/packages/aurabase/tsup.config.ts +11 -0
  95. package/packages/aurabase/vitest.config.ts +16 -0
  96. package/packages/aurabase/vitest.e2e.config.ts +9 -0
  97. package/packages/auth/LICENSE +21 -0
  98. package/packages/auth/README.md +215 -0
  99. package/packages/auth/dist/index.cjs +1175 -0
  100. package/packages/auth/dist/index.d.cts +397 -0
  101. package/packages/auth/dist/index.d.ts +397 -0
  102. package/packages/auth/dist/index.js +1170 -0
  103. package/packages/auth/node_modules/.bin/esbuild +19 -0
  104. package/packages/auth/node_modules/.bin/tsc +22 -0
  105. package/packages/auth/node_modules/.bin/tsserver +22 -0
  106. package/packages/auth/node_modules/.bin/tsup +22 -0
  107. package/packages/auth/node_modules/.bin/tsup-node +22 -0
  108. package/packages/auth/node_modules/.bin/vite +22 -0
  109. package/packages/auth/node_modules/.bin/vitest +22 -0
  110. package/packages/auth/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  111. package/packages/auth/package.json +61 -0
  112. package/packages/auth/src/AuthAdminService.ts +149 -0
  113. package/packages/auth/src/AuthService.ts +1166 -0
  114. package/packages/auth/src/SessionManager.ts +92 -0
  115. package/packages/auth/src/index.ts +17 -0
  116. package/packages/auth/src/jwks.ts +337 -0
  117. package/packages/auth/src/pkce.ts +27 -0
  118. package/packages/auth/src/types.ts +89 -0
  119. package/packages/auth/tests/auth-lifecycle.test.ts +149 -0
  120. package/packages/auth/tests/detect-session.test.ts +361 -0
  121. package/packages/auth/tests/getclaims.test.ts +780 -0
  122. package/packages/auth/tests/is-mfa-challenge.test.ts +27 -0
  123. package/packages/auth/tests/password-recovery.test.ts +124 -0
  124. package/packages/auth/tests/pkce.test.ts +192 -0
  125. package/packages/auth/tests/session-manager.test.ts +103 -0
  126. package/packages/auth/tests/set-session.test.ts +139 -0
  127. package/packages/auth/tests/verify-otp.test.ts +153 -0
  128. package/packages/auth/tsconfig.json +5 -0
  129. package/packages/auth/tsup.config.ts +11 -0
  130. package/packages/core/LICENSE +21 -0
  131. package/packages/core/README.md +132 -0
  132. package/packages/core/dist/index.cjs +695 -0
  133. package/packages/core/dist/index.d.cts +1137 -0
  134. package/packages/core/dist/index.d.ts +1137 -0
  135. package/packages/core/dist/index.js +673 -0
  136. package/packages/core/node_modules/.bin/esbuild +22 -0
  137. package/packages/core/node_modules/.bin/tsc +22 -0
  138. package/packages/core/node_modules/.bin/tsserver +22 -0
  139. package/packages/core/node_modules/.bin/tsup +22 -0
  140. package/packages/core/node_modules/.bin/tsup-node +22 -0
  141. package/packages/core/node_modules/.bin/vite +22 -0
  142. package/packages/core/node_modules/.bin/vitest +22 -0
  143. package/packages/core/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  144. package/packages/core/package.json +57 -0
  145. package/packages/core/src/AuraError.ts +89 -0
  146. package/packages/core/src/BaseService.ts +44 -0
  147. package/packages/core/src/client.ts +34 -0
  148. package/packages/core/src/cookie-utils.ts +42 -0
  149. package/packages/core/src/fetch.ts +435 -0
  150. package/packages/core/src/index.ts +22 -0
  151. package/packages/core/src/retry.ts +63 -0
  152. package/packages/core/src/serialize.ts +6 -0
  153. package/packages/core/src/stores/BaseAuthStore.ts +164 -0
  154. package/packages/core/src/stores/LocalAuthStore.ts +199 -0
  155. package/packages/core/src/types.ts +1042 -0
  156. package/packages/core/tests/auth-store.test.ts +300 -0
  157. package/packages/core/tests/error-code.test.ts +61 -0
  158. package/packages/core/tests/error.test.ts +24 -0
  159. package/packages/core/tests/fetch.test.ts +286 -0
  160. package/packages/core/tests/mocks.ts +139 -0
  161. package/packages/core/tests/observability.test.ts +86 -0
  162. package/packages/core/tests/refresh-hardening.test.ts +164 -0
  163. package/packages/core/tests/refresh-observability.test.ts +111 -0
  164. package/packages/core/tests/retry.test.ts +106 -0
  165. package/packages/core/tests/serialize.test.ts +12 -0
  166. package/packages/core/tests/timeout.test.ts +79 -0
  167. package/packages/core/tsconfig.json +5 -0
  168. package/packages/core/tsup.config.ts +11 -0
  169. package/packages/db/LICENSE +21 -0
  170. package/packages/db/README.md +152 -0
  171. package/packages/db/VENDORED.md +93 -0
  172. package/packages/db/dist/index.cjs +544 -0
  173. package/packages/db/dist/index.d.cts +1111 -0
  174. package/packages/db/dist/index.d.ts +1111 -0
  175. package/packages/db/dist/index.js +541 -0
  176. package/packages/db/node_modules/.bin/esbuild +19 -0
  177. package/packages/db/node_modules/.bin/tsc +22 -0
  178. package/packages/db/node_modules/.bin/tsserver +22 -0
  179. package/packages/db/node_modules/.bin/tsup +22 -0
  180. package/packages/db/node_modules/.bin/tsup-node +22 -0
  181. package/packages/db/node_modules/.bin/vite +22 -0
  182. package/packages/db/node_modules/.bin/vitest +22 -0
  183. package/packages/db/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  184. package/packages/db/package.json +62 -0
  185. package/packages/db/src/DatabaseService.ts +170 -0
  186. package/packages/db/src/QueryBuilder.ts +830 -0
  187. package/packages/db/src/index.ts +2 -0
  188. package/packages/db/src/pgrst-types/common/common.ts +86 -0
  189. package/packages/db/src/pgrst-types/common/rpc.ts +151 -0
  190. package/packages/db/src/pgrst-types/feature-flags.ts +20 -0
  191. package/packages/db/src/pgrst-types/types.ts +134 -0
  192. package/packages/db/src/select-query-parser/parser.ts +479 -0
  193. package/packages/db/src/select-query-parser/result.ts +553 -0
  194. package/packages/db/src/select-query-parser/types.ts +132 -0
  195. package/packages/db/src/select-query-parser/utils.ts +707 -0
  196. package/packages/db/tests/filters.test.ts +81 -0
  197. package/packages/db/tests/mutations-filtered.e2e.test.ts +132 -0
  198. package/packages/db/tests/mutations-filtered.test.ts +188 -0
  199. package/packages/db/tests/order.test.ts +45 -0
  200. package/packages/db/tests/rpc.test.ts +41 -0
  201. package/packages/db/tests/scale/build-large-schema.ts +94 -0
  202. package/packages/db/tests/scale/scale-compile.test.ts +167 -0
  203. package/packages/db/tests/schema.test.ts +77 -0
  204. package/packages/db/tests/single-accept.e2e.test.ts +123 -0
  205. package/packages/db/tests/single.test.ts +211 -0
  206. package/packages/db/tests/types/filters.test-d.ts +52 -0
  207. package/packages/db/tests/types/fixtures.ts +40 -0
  208. package/packages/db/tests/types/from-views.test-d.ts +18 -0
  209. package/packages/db/tests/types/mutations.test-d.ts +23 -0
  210. package/packages/db/tests/types/rpc.test-d.ts +60 -0
  211. package/packages/db/tests/types/schema-shape.test-d.ts +8 -0
  212. package/packages/db/tests/types/select-inference.test-d.ts +38 -0
  213. package/packages/db/tests/vendored/fixtures.ts +83 -0
  214. package/packages/db/tests/vendored/get-result.test-d.ts +75 -0
  215. package/packages/db/tsconfig.json +5 -0
  216. package/packages/db/tsconfig.test-d.json +5 -0
  217. package/packages/db/tsup.config.ts +11 -0
  218. package/packages/db/vitest.config.ts +8 -0
  219. package/packages/functions/LICENSE +21 -0
  220. package/packages/functions/README.md +96 -0
  221. package/packages/functions/dist/index.cjs +173 -0
  222. package/packages/functions/dist/index.d.cts +81 -0
  223. package/packages/functions/dist/index.d.ts +81 -0
  224. package/packages/functions/dist/index.js +168 -0
  225. package/packages/functions/node_modules/.bin/esbuild +19 -0
  226. package/packages/functions/node_modules/.bin/tsc +22 -0
  227. package/packages/functions/node_modules/.bin/tsserver +22 -0
  228. package/packages/functions/node_modules/.bin/tsup +22 -0
  229. package/packages/functions/node_modules/.bin/tsup-node +22 -0
  230. package/packages/functions/node_modules/.bin/vite +22 -0
  231. package/packages/functions/node_modules/.bin/vitest +22 -0
  232. package/packages/functions/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  233. package/packages/functions/package.json +60 -0
  234. package/packages/functions/src/FunctionsService.ts +188 -0
  235. package/packages/functions/src/errors.ts +70 -0
  236. package/packages/functions/src/index.ts +6 -0
  237. package/packages/functions/tests/invoke.test.ts +97 -0
  238. package/packages/functions/tests/response-type-errors.test.ts +135 -0
  239. package/packages/functions/tsconfig.json +5 -0
  240. package/packages/functions/tsup.config.ts +11 -0
  241. package/packages/gen/LICENSE +21 -0
  242. package/packages/gen/README.md +84 -0
  243. package/packages/gen/dist/cli.cjs +334 -0
  244. package/packages/gen/dist/cli.d.cts +1 -0
  245. package/packages/gen/dist/cli.d.ts +1 -0
  246. package/packages/gen/dist/cli.js +332 -0
  247. package/packages/gen/dist/index.cjs +257 -0
  248. package/packages/gen/dist/index.d.cts +12 -0
  249. package/packages/gen/dist/index.d.ts +12 -0
  250. package/packages/gen/dist/index.js +255 -0
  251. package/packages/gen/node_modules/.bin/esbuild +19 -0
  252. package/packages/gen/node_modules/.bin/tsc +22 -0
  253. package/packages/gen/node_modules/.bin/tsserver +22 -0
  254. package/packages/gen/node_modules/.bin/tsup +22 -0
  255. package/packages/gen/node_modules/.bin/tsup-node +22 -0
  256. package/packages/gen/node_modules/.bin/vite +22 -0
  257. package/packages/gen/node_modules/.bin/vitest +22 -0
  258. package/packages/gen/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  259. package/packages/gen/package.json +66 -0
  260. package/packages/gen/src/cli.ts +67 -0
  261. package/packages/gen/src/generate.ts +0 -0
  262. package/packages/gen/src/index.ts +2 -0
  263. package/packages/gen/tests/compile.test.ts +213 -0
  264. package/packages/gen/tests/e2e.test.ts +130 -0
  265. package/packages/gen/tests/generate.test.ts +396 -0
  266. package/packages/gen/tsconfig.json +5 -0
  267. package/packages/gen/tsup.config.ts +11 -0
  268. package/packages/notifications/LICENSE +21 -0
  269. package/packages/notifications/README.md +134 -0
  270. package/packages/notifications/dist/index.cjs +128 -0
  271. package/packages/notifications/dist/index.d.cts +81 -0
  272. package/packages/notifications/dist/index.d.ts +81 -0
  273. package/packages/notifications/dist/index.js +125 -0
  274. package/packages/notifications/node_modules/.bin/esbuild +19 -0
  275. package/packages/notifications/node_modules/.bin/tsc +22 -0
  276. package/packages/notifications/node_modules/.bin/tsserver +22 -0
  277. package/packages/notifications/node_modules/.bin/tsup +22 -0
  278. package/packages/notifications/node_modules/.bin/tsup-node +22 -0
  279. package/packages/notifications/node_modules/.bin/vite +22 -0
  280. package/packages/notifications/node_modules/.bin/vitest +22 -0
  281. package/packages/notifications/package.json +60 -0
  282. package/packages/notifications/src/NotificationsService.ts +230 -0
  283. package/packages/notifications/src/index.ts +19 -0
  284. package/packages/notifications/tsconfig.json +5 -0
  285. package/packages/notifications/tsup.config.ts +11 -0
  286. package/packages/realtime/LICENSE +21 -0
  287. package/packages/realtime/README.md +183 -0
  288. package/packages/realtime/dist/index.cjs +977 -0
  289. package/packages/realtime/dist/index.d.cts +259 -0
  290. package/packages/realtime/dist/index.d.ts +259 -0
  291. package/packages/realtime/dist/index.js +973 -0
  292. package/packages/realtime/node_modules/.bin/esbuild +19 -0
  293. package/packages/realtime/node_modules/.bin/tsc +22 -0
  294. package/packages/realtime/node_modules/.bin/tsserver +22 -0
  295. package/packages/realtime/node_modules/.bin/tsup +22 -0
  296. package/packages/realtime/node_modules/.bin/tsup-node +22 -0
  297. package/packages/realtime/node_modules/.bin/vite +22 -0
  298. package/packages/realtime/node_modules/.bin/vitest +22 -0
  299. package/packages/realtime/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  300. package/packages/realtime/package.json +60 -0
  301. package/packages/realtime/src/AuraChannel.ts +485 -0
  302. package/packages/realtime/src/HeartbeatManager.ts +73 -0
  303. package/packages/realtime/src/RealtimeService.ts +505 -0
  304. package/packages/realtime/src/columnFilter.ts +301 -0
  305. package/packages/realtime/src/index.ts +4 -0
  306. package/packages/realtime/tests/ack-routing.test.ts +81 -0
  307. package/packages/realtime/tests/column-filter.test.ts +144 -0
  308. package/packages/realtime/tests/dispatch.test.ts +191 -0
  309. package/packages/realtime/tests/heartbeat.test.ts +67 -0
  310. package/packages/realtime/tests/http-broadcast.test.ts +68 -0
  311. package/packages/realtime/tests/realtime-token.test.ts +43 -0
  312. package/packages/realtime/tests/reconnect-race.test.ts +149 -0
  313. package/packages/realtime/tests/ref-id.test.ts +34 -0
  314. package/packages/realtime/tests/set-auth.test.ts +70 -0
  315. package/packages/realtime/tsconfig.json +5 -0
  316. package/packages/realtime/tsup.config.ts +11 -0
  317. package/packages/storage/LICENSE +21 -0
  318. package/packages/storage/README.md +141 -0
  319. package/packages/storage/dist/index.cjs +333 -0
  320. package/packages/storage/dist/index.d.cts +185 -0
  321. package/packages/storage/dist/index.d.ts +185 -0
  322. package/packages/storage/dist/index.js +329 -0
  323. package/packages/storage/node_modules/.bin/esbuild +19 -0
  324. package/packages/storage/node_modules/.bin/tsc +22 -0
  325. package/packages/storage/node_modules/.bin/tsserver +22 -0
  326. package/packages/storage/node_modules/.bin/tsup +22 -0
  327. package/packages/storage/node_modules/.bin/tsup-node +22 -0
  328. package/packages/storage/node_modules/.bin/vite +22 -0
  329. package/packages/storage/node_modules/.bin/vitest +22 -0
  330. package/packages/storage/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
  331. package/packages/storage/package.json +60 -0
  332. package/packages/storage/src/DownloadBuilder.ts +60 -0
  333. package/packages/storage/src/StorageService.ts +323 -0
  334. package/packages/storage/src/index.ts +2 -0
  335. package/packages/storage/src/path.ts +35 -0
  336. package/packages/storage/src/transform.ts +15 -0
  337. package/packages/storage/tests/download.test.ts +64 -0
  338. package/packages/storage/tests/parity.test.ts +154 -0
  339. package/packages/storage/tests/path.test.ts +87 -0
  340. package/packages/storage/tests/transform.test.ts +79 -0
  341. package/packages/storage/tsconfig.json +5 -0
  342. package/packages/storage/tsup.config.ts +11 -0
  343. package/pnpm-workspace.yaml +24 -0
  344. package/tsconfig.base.json +15 -0
@@ -0,0 +1,107 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest'
2
+ import { AuraClient } from '../src/AuraClient'
3
+ import { FetchMock, fakeTokenPair } from './mocks'
4
+
5
+ const BASE = 'http://localhost:8080'
6
+ const PROJECT = '00000000-0000-0000-0000-000000000001'
7
+ const PREFIX = `${BASE}/v1/functions/${PROJECT}`
8
+
9
+ let fetchMock: FetchMock
10
+ let client: AuraClient
11
+
12
+ beforeEach(() => {
13
+ fetchMock = new FetchMock()
14
+ fetchMock.init()
15
+ client = new AuraClient(BASE, PROJECT, 'aura_anon_test', {
16
+ auth: { persistSession: false },
17
+ })
18
+ const tp = fakeTokenPair()
19
+ client.authStore.save(tp.access_token, tp.refresh_token, tp.user)
20
+ })
21
+
22
+ afterEach(() => {
23
+ fetchMock.restore()
24
+ fetchMock.clearMocks()
25
+ })
26
+
27
+ describe('FunctionsService route contract', () => {
28
+ it('lists and gets functions through backend routes', async () => {
29
+ fetchMock.on({ method: 'GET', url: PREFIX, replyCode: 200, replyBody: { data: [] } })
30
+ fetchMock.on({
31
+ method: 'GET',
32
+ url: `${PREFIX}/hello`,
33
+ replyCode: 200,
34
+ replyBody: { data: { id: 'fn-1', name: 'hello' } },
35
+ })
36
+
37
+ await client.functions.list()
38
+ await client.functions.get('hello')
39
+
40
+ expect(fetchMock.calls[0].url).toBe(PREFIX)
41
+ expect(fetchMock.calls[1].url).toBe(`${PREFIX}/hello`)
42
+ })
43
+
44
+ it('invokes a function at /{name}/invoke and wraps the request body', async () => {
45
+ fetchMock.on({
46
+ method: 'POST',
47
+ url: `${PREFIX}/hello/invoke`,
48
+ replyCode: 200,
49
+ replyBody: { data: { status: 200 } },
50
+ })
51
+
52
+ await client.functions.invoke('hello', {
53
+ body: { name: 'Ada' },
54
+ method: 'POST',
55
+ path: '/welcome',
56
+ headers: { 'x-test': '1' },
57
+ })
58
+
59
+ expect(fetchMock.calls[0].url).toBe(`${PREFIX}/hello/invoke`)
60
+ expect(fetchMock.calls[0].body).toEqual({
61
+ method: 'POST',
62
+ path: '/welcome',
63
+ headers: { 'x-test': '1' },
64
+ body: { name: 'Ada' },
65
+ })
66
+ })
67
+
68
+ it('uses status and limit query params for jobs', async () => {
69
+ fetchMock.on({
70
+ method: 'GET',
71
+ url: `${PREFIX}/jobs?status=pending&limit=10`,
72
+ replyCode: 200,
73
+ replyBody: { data: [] },
74
+ })
75
+
76
+ await client.functions.listJobs({ status: 'pending', limit: 10 })
77
+
78
+ expect(fetchMock.calls[0].url).toBe(`${PREFIX}/jobs?status=pending&limit=10`)
79
+ })
80
+
81
+ it('creates and deletes cron jobs by name', async () => {
82
+ fetchMock.on({
83
+ method: 'POST',
84
+ url: `${PREFIX}/cron`,
85
+ replyCode: 200,
86
+ replyBody: { data: { name: 'nightly' } },
87
+ })
88
+ fetchMock.on({
89
+ method: 'DELETE',
90
+ url: `${PREFIX}/cron/nightly`,
91
+ replyCode: 204,
92
+ })
93
+
94
+ await client.functions.createCronJob('nightly', '0 0 * * * *', 'hello', {
95
+ payload: { ok: true },
96
+ })
97
+ await client.functions.deleteCronJob('nightly')
98
+
99
+ expect(fetchMock.calls[0].body).toEqual({
100
+ name: 'nightly',
101
+ schedule: '0 0 * * * *',
102
+ function_name: 'hello',
103
+ payload: { ok: true },
104
+ })
105
+ expect(fetchMock.calls[1].url).toBe(`${PREFIX}/cron/nightly`)
106
+ })
107
+ })
@@ -0,0 +1,413 @@
1
+ import { describe, it, expect, beforeAll, afterAll } from 'vitest'
2
+ import { createClient } from '../src/index'
3
+
4
+ const GATEWAY_URL = 'http://localhost:8080'
5
+ const MGMT_URL = 'http://localhost:8090'
6
+
7
+ describe('Tests d\'intégration du SDK JS en conditions réelles (E2E)', () => {
8
+ let devToken: string
9
+ let projectId: string
10
+ let anonKey: string
11
+ let serviceKey: string
12
+
13
+ // Identifiants développeur console générés dynamiquement
14
+ const runId = Math.random().toString(36).substring(2, 10)
15
+ const devEmail = `integration-dev-${runId}@aurabase.dev`
16
+ const devPassword = 'DevPasswordE2E123!'
17
+ const projectName = `integration-proj-${runId}`
18
+
19
+ // Identifiants utilisateur final
20
+ const endUserEmail = `enduser-${runId}@example.com`
21
+ const endUserPassword = 'EndUserPassword123!'
22
+ const otherUserEmail = `other-${runId}@example.com`
23
+ const otherUserPassword = 'OtherPassword123!'
24
+
25
+ beforeAll(async () => {
26
+ // 1. Enregistrement du développeur sur la console
27
+ const regRes = await fetch(`${MGMT_URL}/v1/control/accounts/register`, {
28
+ method: 'POST',
29
+ headers: { 'Content-Type': 'application/json' },
30
+ body: JSON.stringify({ email: devEmail, password: devPassword }),
31
+ })
32
+ expect(regRes.status).toBe(200)
33
+ const regData = await regRes.json()
34
+ devToken = regData.data.access_token
35
+ expect(devToken).toBeDefined()
36
+
37
+ // 2. Création dynamique d'une organisation
38
+ const orgRes = await fetch(`${MGMT_URL}/v1/control/orgs`, {
39
+ method: 'POST',
40
+ headers: {
41
+ 'Authorization': `Bearer ${devToken}`,
42
+ 'Content-Type': 'application/json',
43
+ },
44
+ body: JSON.stringify({ name: 'Integration Org', slug: `integration-org-${runId}` }),
45
+ })
46
+ expect(orgRes.status).toBeLessThan(300)
47
+ const orgData = await orgRes.json()
48
+ const orgId = orgData.id
49
+ expect(orgId).toBeDefined()
50
+
51
+ // 3. Création du projet temporaire via l'organisation
52
+ const projRes = await fetch(`${MGMT_URL}/v1/control/orgs/${orgId}/projects`, {
53
+ method: 'POST',
54
+ headers: {
55
+ 'Authorization': `Bearer ${devToken}`,
56
+ 'Content-Type': 'application/json',
57
+ },
58
+ body: JSON.stringify({ name: projectName, engine: 'postgres', region: 'eu-west-1' }),
59
+ })
60
+ expect(projRes.status).toBe(202) // 202 ACCEPTED
61
+ const projData = await projRes.json()
62
+ projectId = projData.id
63
+ expect(projectId).toBeDefined()
64
+
65
+ // Attente active du provisioning du projet (status = active)
66
+ let active = false
67
+ for (let i = 0; i < 50; i++) {
68
+ const statusRes = await fetch(`${MGMT_URL}/v1/control/projects/${projectId}`, {
69
+ headers: { 'Authorization': `Bearer ${devToken}` },
70
+ })
71
+ const statusData = await statusRes.json()
72
+ if (statusData && statusData.status === 'active') {
73
+ active = true
74
+ break
75
+ }
76
+ await new Promise((resolve) => setTimeout(resolve, 1500))
77
+ }
78
+ expect(active).toBe(true)
79
+
80
+ // Récupération des clés API initiales (avec retry en cas de KEYS_PENDING / 404)
81
+ let keysRes: Response | null = null
82
+ for (let i = 0; i < 15; i++) {
83
+ keysRes = await fetch(`${MGMT_URL}/v1/control/projects/${projectId}/initial-keys`, {
84
+ headers: { 'Authorization': `Bearer ${devToken}` },
85
+ })
86
+ if (keysRes.status === 200) {
87
+ break
88
+ }
89
+ await new Promise((resolve) => setTimeout(resolve, 1000))
90
+ }
91
+ expect(keysRes).not.toBeNull()
92
+ expect(keysRes!.status).toBe(200)
93
+ const keysData = await keysRes!.json()
94
+ const keys = keysData.data || keysData
95
+ anonKey = keys.find((k: any) => k.scope === 'anon').key
96
+ serviceKey = keys.find((k: any) => k.scope === 'service_role').key
97
+ expect(anonKey).toBeDefined()
98
+ expect(serviceKey).toBeDefined()
99
+
100
+ // 4. Création de la table 'todos' avec RLS active
101
+ const tableDef = {
102
+ name: 'todos',
103
+ columns: [
104
+ {
105
+ name: 'id',
106
+ col_type: 'uuid',
107
+ nullable: false,
108
+ unique: true,
109
+ default_val: 'gen_random_uuid()',
110
+ references: null
111
+ },
112
+ {
113
+ name: 'title',
114
+ col_type: 'text',
115
+ nullable: false,
116
+ unique: false,
117
+ default_val: null,
118
+ references: null
119
+ },
120
+ {
121
+ name: 'completed',
122
+ col_type: 'bool',
123
+ nullable: false,
124
+ unique: false,
125
+ default_val: 'false',
126
+ references: null
127
+ },
128
+ {
129
+ name: 'owner_id',
130
+ col_type: 'text',
131
+ nullable: false,
132
+ unique: false,
133
+ default_val: null,
134
+ references: null
135
+ }
136
+ ],
137
+ primary_key: 'id',
138
+ indexes: [],
139
+ rls_enabled: true,
140
+ realtime_enabled: true
141
+ }
142
+
143
+ const tableRes = await fetch(`${MGMT_URL}/v1/db/${projectId}/schema/tables`, {
144
+ method: 'POST',
145
+ headers: {
146
+ 'Authorization': `Bearer ${devToken}`,
147
+ 'Content-Type': 'application/json',
148
+ },
149
+ body: JSON.stringify(tableDef),
150
+ })
151
+ expect(tableRes.status).toBe(200)
152
+
153
+ // 5. Création de la policy RLS (propriétaire uniquement)
154
+ const policyDef = {
155
+ name: 'todos_owner_policy',
156
+ table: 'todos',
157
+ command: 'ALL',
158
+ using_expr: 'auth.uid()::text = owner_id',
159
+ check_expr: 'auth.uid()::text = owner_id'
160
+ }
161
+
162
+ const policyRes = await fetch(`${MGMT_URL}/v1/db/${projectId}/policies`, {
163
+ method: 'POST',
164
+ headers: {
165
+ 'Authorization': `Bearer ${devToken}`,
166
+ 'Content-Type': 'application/json',
167
+ },
168
+ body: JSON.stringify(policyDef),
169
+ })
170
+ expect(policyRes.status).toBe(200)
171
+
172
+ // 6. Attente de l'indexation PostgREST (statut 200 OK garanti et réponse JSON sous forme de tableau ou de enveloppe data)
173
+ let ready = false
174
+ for (let i = 0; i < 30; i++) {
175
+ const probeRes = await fetch(`${GATEWAY_URL}/v1/db/${projectId}/todos`, {
176
+ headers: { 'apikey': anonKey },
177
+ })
178
+ const status = probeRes.status
179
+ let bodyText = ''
180
+ try {
181
+ bodyText = await probeRes.text()
182
+ } catch (e) {}
183
+ console.log(`[PROBE LOOP ${i}] HTTP STATUS:`, status, 'BODY:', bodyText)
184
+
185
+ // On s'assure que la Gateway ou PostgREST répond avec un succès (soit un tableau [], soit un objet enveloppe {"data":[]})
186
+ if (status === 200 && (bodyText.trim().startsWith('[') || bodyText.includes('"data":'))) {
187
+ ready = true
188
+ break
189
+ }
190
+ await new Promise((resolve) => setTimeout(resolve, 1500))
191
+ }
192
+ expect(ready).toBe(true)
193
+
194
+ // Attendre 3 secondes supplémentaires de sécurité pour garantir la stabilisation complète du cache PostgREST
195
+ await new Promise((resolve) => setTimeout(resolve, 3000))
196
+ }, 50000)
197
+
198
+ afterAll(async () => {
199
+ // Suppression propre du projet de test
200
+ if (projectId && devToken) {
201
+ const delRes = await fetch(`${MGMT_URL}/v1/control/projects/${projectId}`, {
202
+ method: 'DELETE',
203
+ headers: { 'Authorization': `Bearer ${devToken}` },
204
+ })
205
+ expect(delRes.status).toBe(204) // NO CONTENT
206
+ }
207
+ })
208
+
209
+ it('devrait inscrire et connecter un utilisateur final avec succès', async () => {
210
+ const client = createClient(GATEWAY_URL, projectId, anonKey, {
211
+ auth: { persistSession: false },
212
+ })
213
+
214
+ // Inscription utilisateur principal
215
+ const signUpRes = await client.auth.signUp({
216
+ email: endUserEmail,
217
+ password: endUserPassword,
218
+ })
219
+ expect(signUpRes.error).toBeNull()
220
+ expect(signUpRes.data?.user).toBeDefined()
221
+ expect(signUpRes.data?.user?.email).toBe(endUserEmail)
222
+
223
+ // Inscription du second utilisateur (pour tester l'isolation RLS plus tard)
224
+ const signUpOtherRes = await client.auth.signUp({
225
+ email: otherUserEmail,
226
+ password: otherUserPassword,
227
+ })
228
+ expect(signUpOtherRes.error).toBeNull()
229
+
230
+ // Connexion
231
+ const signInRes = await client.auth.signInWithPassword({
232
+ email: endUserEmail,
233
+ password: endUserPassword,
234
+ })
235
+ expect(signInRes.error).toBeNull()
236
+ expect(signInRes.data?.access_token).toBeDefined()
237
+
238
+ // Récupération de l'utilisateur courant
239
+ const userRes = await client.auth.getUser()
240
+ expect(userRes.error).toBeNull()
241
+ expect(userRes.data?.email).toBe(endUserEmail)
242
+ })
243
+
244
+ it('devrait exécuter des requêtes CRUD avec RLS et valider l\'isolation des données', async () => {
245
+ const client = createClient(GATEWAY_URL, projectId, anonKey, {
246
+ auth: { persistSession: false },
247
+ })
248
+
249
+ // Se connecter en tant qu'utilisateur principal
250
+ await client.auth.signInWithPassword({
251
+ email: endUserEmail,
252
+ password: endUserPassword,
253
+ })
254
+
255
+ const user = (await client.auth.getUser()).data
256
+ expect(user).toBeDefined()
257
+ const userId = user!.id
258
+
259
+ // 1. Insertion de todo
260
+ const insertRes = await client.db.from('todos').insert({
261
+ title: 'Tester le SDK en conditions réelles',
262
+ completed: false,
263
+ owner_id: userId,
264
+ })
265
+ if (insertRes.error) {
266
+ console.log('DEBUG INSERT ERROR DETAIL:', JSON.stringify(insertRes.error, null, 2))
267
+ }
268
+ expect(insertRes.error).toBeNull()
269
+
270
+ // 2. Sélection de todo
271
+ const selectRes = await client.db.from('todos').select('*')
272
+ expect(selectRes.error).toBeNull()
273
+ expect(selectRes.data).toBeInstanceOf(Array)
274
+ expect(selectRes.data!.length).toBe(1)
275
+ expect(selectRes.data![0].title).toBe('Tester le SDK en conditions réelles')
276
+
277
+ const todoId = selectRes.data![0].id
278
+ expect(todoId).toBeDefined()
279
+
280
+ // 3. Vérification de l'isolation RLS : l'accès anonyme (sans JWT) doit retourner 0 lignes
281
+ const anonClient = createClient(GATEWAY_URL, projectId, anonKey, {
282
+ auth: { persistSession: false },
283
+ })
284
+ const anonSelectRes = await anonClient.db.from('todos').select('*')
285
+ expect(anonSelectRes.error).toBeNull()
286
+ expect(anonSelectRes.data).toBeInstanceOf(Array)
287
+ expect(anonSelectRes.data!.length).toBe(0)
288
+
289
+ // 4. Vérification de l'isolation RLS : un autre utilisateur connecté doit obtenir 0 lignes
290
+ const otherClient = createClient(GATEWAY_URL, projectId, anonKey, {
291
+ auth: { persistSession: false },
292
+ })
293
+ await otherClient.auth.signInWithPassword({
294
+ email: otherUserEmail,
295
+ password: otherUserPassword,
296
+ })
297
+ const otherSelectRes = await otherClient.db.from('todos').select('*')
298
+ expect(otherSelectRes.error).toBeNull()
299
+ expect(otherSelectRes.data).toBeInstanceOf(Array)
300
+ expect(otherSelectRes.data!.length).toBe(0)
301
+
302
+ // 5. Mise à jour de todo (l'utilisateur principal modifie son propre todo)
303
+ const updateRes = await client.db.from('todos').update(todoId, {
304
+ completed: true,
305
+ })
306
+ expect(updateRes.error).toBeNull()
307
+
308
+ const selectUpdatedRes = await client.db.from('todos').select('*')
309
+ expect(selectUpdatedRes.data![0].completed).toBe(true)
310
+
311
+ // 6. Suppression de todo
312
+ const deleteRes = await client.db.from('todos').delete(todoId)
313
+ expect(deleteRes.error).toBeNull()
314
+
315
+ const selectDeletedRes = await client.db.from('todos').select('*')
316
+ expect(selectDeletedRes.data!.length).toBe(0)
317
+ })
318
+
319
+ it('devrait exécuter des requêtes SQL brutes et rejeter les requêtes non autorisées', async () => {
320
+ const client = createClient(GATEWAY_URL, projectId, anonKey, {
321
+ auth: { persistSession: false },
322
+ })
323
+
324
+ await client.auth.signInWithPassword({
325
+ email: endUserEmail,
326
+ password: endUserPassword,
327
+ })
328
+
329
+ const user = (await client.auth.getUser()).data
330
+ const userId = user!.id
331
+
332
+ // Insérer un todo temporaire pour la requête SQL
333
+ const sqlInsert = await client.db.from('todos').insert({
334
+ title: 'SQL Todo',
335
+ completed: false,
336
+ owner_id: userId,
337
+ })
338
+ if (sqlInsert.error) {
339
+ console.log('DEBUG SQL INSERT ERROR:', JSON.stringify(sqlInsert.error, null, 2))
340
+ }
341
+
342
+ // Requête SQL autorisée
343
+ const sqlRes = await client.db.sql<any[]>('SELECT title FROM todos WHERE owner_id = $1', [userId])
344
+ expect(sqlRes.error).toBeNull()
345
+ expect(sqlRes.data).toBeDefined()
346
+ expect(sqlRes.data!.length).toBe(1)
347
+ expect(sqlRes.data![0].title).toBe('SQL Todo')
348
+
349
+ // Requête SQL non autorisée vers pg_catalog (rejetée par l'AST de la gateway)
350
+ const forbiddenSqlRes = await client.db.sql('SELECT * FROM pg_catalog.pg_tables')
351
+ expect(forbiddenSqlRes.error).not.toBeNull()
352
+ expect(forbiddenSqlRes.error?.message).toMatch(/non autorisées|interdit|rejetée|pg_catalog/)
353
+ })
354
+
355
+ it('devrait manipuler le service Storage (buckets et objets) avec succès', async () => {
356
+ // La gestion des buckets (create/delete) exige une clé service_role côté gateway ;
357
+ // ce test valide les méthodes storage du SDK de bout en bout, on utilise donc un
358
+ // client service_role (la RLS storage est testée ailleurs).
359
+ const client = createClient(GATEWAY_URL, projectId, serviceKey, {
360
+ auth: { persistSession: false },
361
+ })
362
+
363
+ const bucketName = `integration-bucket-${runId}`
364
+ const fileName = 'test-file.txt'
365
+ const fileContent = 'Bonjour Aurabase E2E'
366
+
367
+ // 1. Création de bucket
368
+ const bucketCreateRes = await client.storage.createBucket(bucketName, {
369
+ public: true,
370
+ })
371
+ expect(bucketCreateRes.error).toBeNull()
372
+ expect(bucketCreateRes.data?.name).toBe(bucketName)
373
+
374
+ // 2. Téléversement de fichier (upload)
375
+ const blob = new Blob([fileContent], { type: 'text/plain' })
376
+ const uploadRes = await client.storage.upload(bucketName, fileName, blob, {
377
+ contentType: 'text/plain',
378
+ })
379
+ expect(uploadRes.error).toBeNull()
380
+ expect(uploadRes.data?.key).toBeDefined()
381
+
382
+ // `data.key` est déjà relative au bucket (contrat SDK : réutilisable directement).
383
+ // Robuste : strippe un éventuel préfixe bucket si le backend en ajoutait un.
384
+ const uploadedKey = uploadRes.data!.key
385
+ const objectPath = uploadedKey.startsWith(`${bucketName}/`)
386
+ ? uploadedKey.slice(bucketName.length + 1)
387
+ : uploadedKey
388
+ expect(objectPath).toBeTruthy()
389
+
390
+ // 3. Récupération des métadonnées
391
+ const metaRes = await client.storage.getMetadata(bucketName, objectPath)
392
+ expect(metaRes.error).toBeNull()
393
+ // Note : `getMetadata` renvoie la clé préfixée du bucket alors qu'`upload` renvoie la clé
394
+ // nue (incohérence de format backend, à harmoniser) → on vérifie l'inclusion, pas l'égalité.
395
+ expect((metaRes.data as any)?.key).toContain(uploadedKey)
396
+
397
+ // 4. Téléchargement et vérification du contenu
398
+ const downloadRes = await client.storage.download(bucketName, objectPath)
399
+ expect(downloadRes.error).toBeNull()
400
+ expect(downloadRes.data).toBeInstanceOf(Blob)
401
+
402
+ const textContent = await downloadRes.data!.text()
403
+ expect(textContent).toBe(fileContent)
404
+
405
+ // 5. Suppression du fichier
406
+ const removeRes = await client.storage.remove(bucketName, [objectPath])
407
+ expect(removeRes.error).toBeNull()
408
+
409
+ // 6. Suppression du bucket
410
+ const bucketDeleteRes = await client.storage.deleteBucket(bucketName)
411
+ expect(bucketDeleteRes.error).toBeNull()
412
+ })
413
+ })