@aurabase/aurabase-js 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (258) hide show
  1. package/package.json +4 -4
  2. package/packages/ai/node_modules/.bin/esbuild +0 -19
  3. package/packages/ai/node_modules/.bin/tsc +0 -22
  4. package/packages/ai/node_modules/.bin/tsserver +0 -22
  5. package/packages/ai/node_modules/.bin/tsup +0 -22
  6. package/packages/ai/node_modules/.bin/tsup-node +0 -22
  7. package/packages/ai/node_modules/.bin/vite +0 -22
  8. package/packages/ai/node_modules/.bin/vitest +0 -22
  9. package/packages/ai/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  10. package/packages/ai/src/AiService.ts +0 -226
  11. package/packages/ai/src/index.ts +0 -18
  12. package/packages/ai/src/sse.ts +0 -141
  13. package/packages/ai/src/types.ts +0 -30
  14. package/packages/ai/tests/chat-stream.test.ts +0 -151
  15. package/packages/ai/tests/rag-namespaces.test.ts +0 -54
  16. package/packages/ai/tests/sse.test.ts +0 -69
  17. package/packages/ai/tsconfig.json +0 -5
  18. package/packages/ai/tsup.config.ts +0 -11
  19. package/packages/aurabase/node_modules/.bin/esbuild +0 -19
  20. package/packages/aurabase/node_modules/.bin/tsc +0 -22
  21. package/packages/aurabase/node_modules/.bin/tsserver +0 -22
  22. package/packages/aurabase/node_modules/.bin/tsup +0 -22
  23. package/packages/aurabase/node_modules/.bin/tsup-node +0 -22
  24. package/packages/aurabase/node_modules/.bin/vite +0 -22
  25. package/packages/aurabase/node_modules/.bin/vitest +0 -22
  26. package/packages/aurabase/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  27. package/packages/aurabase/src/AuraClient.ts +0 -237
  28. package/packages/aurabase/src/index.ts +0 -152
  29. package/packages/aurabase/src/ssr.ts +0 -156
  30. package/packages/aurabase/tests/ai-streaming-rag-e2e.test.ts +0 -82
  31. package/packages/aurabase/tests/ai.test.ts +0 -111
  32. package/packages/aurabase/tests/auth-admin.test.ts +0 -515
  33. package/packages/aurabase/tests/auth-e2e.test.ts +0 -135
  34. package/packages/aurabase/tests/auth-hardening.test.ts +0 -206
  35. package/packages/aurabase/tests/auth.test.ts +0 -947
  36. package/packages/aurabase/tests/database.test.ts +0 -230
  37. package/packages/aurabase/tests/db-types-e2e.test.ts +0 -217
  38. package/packages/aurabase/tests/dispose.test.ts +0 -23
  39. package/packages/aurabase/tests/foreign-token.e2e.test.ts +0 -129
  40. package/packages/aurabase/tests/functions.test.ts +0 -107
  41. package/packages/aurabase/tests/integration.test.ts +0 -413
  42. package/packages/aurabase/tests/live-production-validation.js +0 -241
  43. package/packages/aurabase/tests/live-sdk-production-validation.js +0 -293
  44. package/packages/aurabase/tests/mocks.ts +0 -139
  45. package/packages/aurabase/tests/notifications.test.ts +0 -314
  46. package/packages/aurabase/tests/observability-backup.test.ts +0 -186
  47. package/packages/aurabase/tests/observability-hook.test.ts +0 -130
  48. package/packages/aurabase/tests/production-robustness.test.ts +0 -268
  49. package/packages/aurabase/tests/public-api-surface.test.ts +0 -53
  50. package/packages/aurabase/tests/query-builder.test.ts +0 -329
  51. package/packages/aurabase/tests/readme-smoke-e2e.test.ts +0 -231
  52. package/packages/aurabase/tests/realtime-filter-e2e.test.ts +0 -344
  53. package/packages/aurabase/tests/refresh-locks.test.ts +0 -210
  54. package/packages/aurabase/tests/retry-option.test.ts +0 -17
  55. package/packages/aurabase/tests/rpc-e2e.test.ts +0 -254
  56. package/packages/aurabase/tests/rs256-local-e2e.test.ts +0 -114
  57. package/packages/aurabase/tests/rt-alias-public-e2e.test.ts +0 -235
  58. package/packages/aurabase/tests/rt-http-broadcast-e2e.test.ts +0 -124
  59. package/packages/aurabase/tests/service-role-guard.test.ts +0 -99
  60. package/packages/aurabase/tests/ssr.test.ts +0 -91
  61. package/packages/aurabase/tests/storage-backend-e2e.test.ts +0 -481
  62. package/packages/aurabase/tests/storage-sdk-parity-e2e.test.ts +0 -104
  63. package/packages/aurabase/tests/storage-transform-e2e.test.ts +0 -684
  64. package/packages/aurabase/tests/storage.test.ts +0 -55
  65. package/packages/aurabase/tests/types/client-generic.test-d.ts +0 -79
  66. package/packages/aurabase/tests/types/docs-snippets.test-d.ts +0 -571
  67. package/packages/aurabase/tests/types/error-code.test-d.ts +0 -53
  68. package/packages/aurabase/tsconfig.json +0 -5
  69. package/packages/aurabase/tsconfig.test-d.json +0 -5
  70. package/packages/aurabase/tsup.config.ts +0 -11
  71. package/packages/aurabase/vitest.config.ts +0 -16
  72. package/packages/auth/node_modules/.bin/esbuild +0 -19
  73. package/packages/auth/node_modules/.bin/tsc +0 -22
  74. package/packages/auth/node_modules/.bin/tsserver +0 -22
  75. package/packages/auth/node_modules/.bin/tsup +0 -22
  76. package/packages/auth/node_modules/.bin/tsup-node +0 -22
  77. package/packages/auth/node_modules/.bin/vite +0 -22
  78. package/packages/auth/node_modules/.bin/vitest +0 -22
  79. package/packages/auth/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  80. package/packages/auth/src/AuthAdminService.ts +0 -149
  81. package/packages/auth/src/AuthService.ts +0 -1166
  82. package/packages/auth/src/SessionManager.ts +0 -92
  83. package/packages/auth/src/index.ts +0 -17
  84. package/packages/auth/src/jwks.ts +0 -337
  85. package/packages/auth/src/pkce.ts +0 -27
  86. package/packages/auth/src/types.ts +0 -89
  87. package/packages/auth/tests/auth-lifecycle.test.ts +0 -149
  88. package/packages/auth/tests/detect-session.test.ts +0 -361
  89. package/packages/auth/tests/getclaims.test.ts +0 -780
  90. package/packages/auth/tests/is-mfa-challenge.test.ts +0 -27
  91. package/packages/auth/tests/password-recovery.test.ts +0 -124
  92. package/packages/auth/tests/pkce.test.ts +0 -192
  93. package/packages/auth/tests/session-manager.test.ts +0 -103
  94. package/packages/auth/tests/set-session.test.ts +0 -139
  95. package/packages/auth/tests/verify-otp.test.ts +0 -153
  96. package/packages/auth/tsconfig.json +0 -5
  97. package/packages/auth/tsup.config.ts +0 -11
  98. package/packages/core/node_modules/.bin/esbuild +0 -22
  99. package/packages/core/node_modules/.bin/tsc +0 -22
  100. package/packages/core/node_modules/.bin/tsserver +0 -22
  101. package/packages/core/node_modules/.bin/tsup +0 -22
  102. package/packages/core/node_modules/.bin/tsup-node +0 -22
  103. package/packages/core/node_modules/.bin/vite +0 -22
  104. package/packages/core/node_modules/.bin/vitest +0 -22
  105. package/packages/core/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  106. package/packages/core/src/AuraError.ts +0 -89
  107. package/packages/core/src/BaseService.ts +0 -44
  108. package/packages/core/src/client.ts +0 -34
  109. package/packages/core/src/cookie-utils.ts +0 -42
  110. package/packages/core/src/fetch.ts +0 -435
  111. package/packages/core/src/index.ts +0 -22
  112. package/packages/core/src/retry.ts +0 -63
  113. package/packages/core/src/serialize.ts +0 -6
  114. package/packages/core/src/stores/BaseAuthStore.ts +0 -164
  115. package/packages/core/src/stores/LocalAuthStore.ts +0 -199
  116. package/packages/core/src/types.ts +0 -1042
  117. package/packages/core/tests/auth-store.test.ts +0 -300
  118. package/packages/core/tests/error-code.test.ts +0 -61
  119. package/packages/core/tests/error.test.ts +0 -24
  120. package/packages/core/tests/fetch.test.ts +0 -286
  121. package/packages/core/tests/mocks.ts +0 -139
  122. package/packages/core/tests/observability.test.ts +0 -86
  123. package/packages/core/tests/refresh-hardening.test.ts +0 -164
  124. package/packages/core/tests/refresh-observability.test.ts +0 -111
  125. package/packages/core/tests/retry.test.ts +0 -106
  126. package/packages/core/tests/serialize.test.ts +0 -12
  127. package/packages/core/tests/timeout.test.ts +0 -79
  128. package/packages/core/tsconfig.json +0 -5
  129. package/packages/core/tsup.config.ts +0 -11
  130. package/packages/db/node_modules/.bin/esbuild +0 -19
  131. package/packages/db/node_modules/.bin/tsc +0 -22
  132. package/packages/db/node_modules/.bin/tsserver +0 -22
  133. package/packages/db/node_modules/.bin/tsup +0 -22
  134. package/packages/db/node_modules/.bin/tsup-node +0 -22
  135. package/packages/db/node_modules/.bin/vite +0 -22
  136. package/packages/db/node_modules/.bin/vitest +0 -22
  137. package/packages/db/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  138. package/packages/db/src/DatabaseService.ts +0 -170
  139. package/packages/db/src/QueryBuilder.ts +0 -830
  140. package/packages/db/src/index.ts +0 -2
  141. package/packages/db/src/pgrst-types/common/common.ts +0 -86
  142. package/packages/db/src/pgrst-types/common/rpc.ts +0 -151
  143. package/packages/db/src/pgrst-types/feature-flags.ts +0 -20
  144. package/packages/db/src/pgrst-types/types.ts +0 -134
  145. package/packages/db/src/select-query-parser/parser.ts +0 -479
  146. package/packages/db/src/select-query-parser/result.ts +0 -553
  147. package/packages/db/src/select-query-parser/types.ts +0 -132
  148. package/packages/db/src/select-query-parser/utils.ts +0 -707
  149. package/packages/db/tests/filters.test.ts +0 -81
  150. package/packages/db/tests/mutations-filtered.e2e.test.ts +0 -132
  151. package/packages/db/tests/mutations-filtered.test.ts +0 -188
  152. package/packages/db/tests/order.test.ts +0 -45
  153. package/packages/db/tests/rpc.test.ts +0 -41
  154. package/packages/db/tests/scale/build-large-schema.ts +0 -94
  155. package/packages/db/tests/scale/scale-compile.test.ts +0 -167
  156. package/packages/db/tests/schema.test.ts +0 -77
  157. package/packages/db/tests/single-accept.e2e.test.ts +0 -123
  158. package/packages/db/tests/single.test.ts +0 -211
  159. package/packages/db/tests/types/filters.test-d.ts +0 -52
  160. package/packages/db/tests/types/fixtures.ts +0 -40
  161. package/packages/db/tests/types/from-views.test-d.ts +0 -18
  162. package/packages/db/tests/types/mutations.test-d.ts +0 -23
  163. package/packages/db/tests/types/rpc.test-d.ts +0 -60
  164. package/packages/db/tests/types/schema-shape.test-d.ts +0 -8
  165. package/packages/db/tests/types/select-inference.test-d.ts +0 -38
  166. package/packages/db/tests/vendored/fixtures.ts +0 -83
  167. package/packages/db/tests/vendored/get-result.test-d.ts +0 -75
  168. package/packages/db/tsconfig.json +0 -5
  169. package/packages/db/tsconfig.test-d.json +0 -5
  170. package/packages/db/tsup.config.ts +0 -11
  171. package/packages/db/vitest.config.ts +0 -8
  172. package/packages/functions/node_modules/.bin/esbuild +0 -19
  173. package/packages/functions/node_modules/.bin/tsc +0 -22
  174. package/packages/functions/node_modules/.bin/tsserver +0 -22
  175. package/packages/functions/node_modules/.bin/tsup +0 -22
  176. package/packages/functions/node_modules/.bin/tsup-node +0 -22
  177. package/packages/functions/node_modules/.bin/vite +0 -22
  178. package/packages/functions/node_modules/.bin/vitest +0 -22
  179. package/packages/functions/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  180. package/packages/functions/src/FunctionsService.ts +0 -188
  181. package/packages/functions/src/errors.ts +0 -70
  182. package/packages/functions/src/index.ts +0 -6
  183. package/packages/functions/tests/invoke.test.ts +0 -97
  184. package/packages/functions/tests/response-type-errors.test.ts +0 -135
  185. package/packages/functions/tsconfig.json +0 -5
  186. package/packages/functions/tsup.config.ts +0 -11
  187. package/packages/gen/node_modules/.bin/esbuild +0 -19
  188. package/packages/gen/node_modules/.bin/tsc +0 -22
  189. package/packages/gen/node_modules/.bin/tsserver +0 -22
  190. package/packages/gen/node_modules/.bin/tsup +0 -22
  191. package/packages/gen/node_modules/.bin/tsup-node +0 -22
  192. package/packages/gen/node_modules/.bin/vite +0 -22
  193. package/packages/gen/node_modules/.bin/vitest +0 -22
  194. package/packages/gen/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  195. package/packages/gen/src/cli.ts +0 -67
  196. package/packages/gen/src/generate.ts +0 -0
  197. package/packages/gen/src/index.ts +0 -2
  198. package/packages/gen/tests/compile.test.ts +0 -213
  199. package/packages/gen/tests/e2e.test.ts +0 -130
  200. package/packages/gen/tests/generate.test.ts +0 -396
  201. package/packages/gen/tsconfig.json +0 -5
  202. package/packages/gen/tsup.config.ts +0 -11
  203. package/packages/notifications/node_modules/.bin/esbuild +0 -19
  204. package/packages/notifications/node_modules/.bin/tsc +0 -22
  205. package/packages/notifications/node_modules/.bin/tsserver +0 -22
  206. package/packages/notifications/node_modules/.bin/tsup +0 -22
  207. package/packages/notifications/node_modules/.bin/tsup-node +0 -22
  208. package/packages/notifications/node_modules/.bin/vite +0 -22
  209. package/packages/notifications/node_modules/.bin/vitest +0 -22
  210. package/packages/notifications/src/NotificationsService.ts +0 -230
  211. package/packages/notifications/src/index.ts +0 -19
  212. package/packages/notifications/tsconfig.json +0 -5
  213. package/packages/notifications/tsup.config.ts +0 -11
  214. package/packages/realtime/node_modules/.bin/esbuild +0 -19
  215. package/packages/realtime/node_modules/.bin/tsc +0 -22
  216. package/packages/realtime/node_modules/.bin/tsserver +0 -22
  217. package/packages/realtime/node_modules/.bin/tsup +0 -22
  218. package/packages/realtime/node_modules/.bin/tsup-node +0 -22
  219. package/packages/realtime/node_modules/.bin/vite +0 -22
  220. package/packages/realtime/node_modules/.bin/vitest +0 -22
  221. package/packages/realtime/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  222. package/packages/realtime/src/AuraChannel.ts +0 -485
  223. package/packages/realtime/src/HeartbeatManager.ts +0 -73
  224. package/packages/realtime/src/RealtimeService.ts +0 -505
  225. package/packages/realtime/src/columnFilter.ts +0 -301
  226. package/packages/realtime/src/index.ts +0 -4
  227. package/packages/realtime/tests/ack-routing.test.ts +0 -81
  228. package/packages/realtime/tests/column-filter.test.ts +0 -144
  229. package/packages/realtime/tests/dispatch.test.ts +0 -191
  230. package/packages/realtime/tests/heartbeat.test.ts +0 -67
  231. package/packages/realtime/tests/http-broadcast.test.ts +0 -68
  232. package/packages/realtime/tests/realtime-token.test.ts +0 -43
  233. package/packages/realtime/tests/reconnect-race.test.ts +0 -149
  234. package/packages/realtime/tests/ref-id.test.ts +0 -34
  235. package/packages/realtime/tests/set-auth.test.ts +0 -70
  236. package/packages/realtime/tsconfig.json +0 -5
  237. package/packages/realtime/tsup.config.ts +0 -11
  238. package/packages/storage/node_modules/.bin/esbuild +0 -19
  239. package/packages/storage/node_modules/.bin/tsc +0 -22
  240. package/packages/storage/node_modules/.bin/tsserver +0 -22
  241. package/packages/storage/node_modules/.bin/tsup +0 -22
  242. package/packages/storage/node_modules/.bin/tsup-node +0 -22
  243. package/packages/storage/node_modules/.bin/vite +0 -22
  244. package/packages/storage/node_modules/.bin/vitest +0 -22
  245. package/packages/storage/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +0 -1
  246. package/packages/storage/src/DownloadBuilder.ts +0 -60
  247. package/packages/storage/src/StorageService.ts +0 -323
  248. package/packages/storage/src/index.ts +0 -2
  249. package/packages/storage/src/path.ts +0 -35
  250. package/packages/storage/src/transform.ts +0 -15
  251. package/packages/storage/tests/download.test.ts +0 -64
  252. package/packages/storage/tests/parity.test.ts +0 -154
  253. package/packages/storage/tests/path.test.ts +0 -87
  254. package/packages/storage/tests/transform.test.ts +0 -79
  255. package/packages/storage/tsconfig.json +0 -5
  256. package/packages/storage/tsup.config.ts +0 -11
  257. package/pnpm-workspace.yaml +0 -24
  258. package/tsconfig.base.json +0 -15
@@ -1,231 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // E2E réel de smoke des README (stack live) — Task 6 (chantier H, DX).
3
- //
4
- // Complément du compile-check statique (tests/types/docs-snippets.test-d.ts,
5
- // preuve compile-time) : ce fichier exécute RÉELLEMENT, contre le déploiement
6
- // Docker local (gateway :8080, control :8090), les exemples clés documentés
7
- // dans packages/auth/README.md, packages/db/README.md et
8
- // packages/storage/README.md — preuve runtime que la doc est fidèle au
9
- // comportement observé, pas seulement à la signature TypeScript.
10
- //
11
- // Périmètre volontairement réduit à un flux « smoke » par domaine (pas une
12
- // couverture exhaustive de chaque méthode documentée — c'est le rôle des
13
- // suites unitaires par package) :
14
- // - Auth : signUp → signInWithPassword → getUser (id/email cohérents) →
15
- // signOut. Cleanup authAdmin.deleteUser en finally.
16
- // - DB : table jetable créée via aura.db.sql() (CREATE TABLE + GRANT +
17
- // reload schema PostgREST + délai de démarrage du reload, comme
18
- // db-types-e2e.test.ts) → from(table).insert(...).select(...).single() →
19
- // from(table).select(...).eq(...).single() → vérifie la forme
20
- // réelle de la ligne retournée. Le reload de cache PostgREST étant
21
- // asynchrone, insert/select rejouent sur 503 (reload en cours) ET
22
- // 404 (cache pas encore rechargé) via retryReload, avec skip
23
- // gracieux si le backend reste indisponible après retries.
24
- // Cleanup DROP TABLE en finally.
25
- // - Storage: createBucket (service_role) → upload → download (builder
26
- // paresseux, .text() sur le Blob résolu) → remove →
27
- // deleteBucket. Cleanup deleteBucket en finally.
28
- //
29
- // Gaté par RUN_E2E + credentials (identique à auth-e2e.test.ts /
30
- // db-types-e2e.test.ts) : describe.runIf(RUN) SKIPPE proprement la suite
31
- // entière (pas d'échec) quand les variables d'env manquent — vérifié sans
32
- // RUN_E2E via `pnpm --filter aurabase test`.
33
- // ---------------------------------------------------------------------------
34
-
35
- import { describe, it, expect } from 'vitest'
36
- import { createClient, createAdminClient } from '../src/index'
37
- import type { AuraResponse } from '../src/index'
38
-
39
- const URL = process.env.AURA_E2E_URL
40
- const PROJECT = process.env.AURA_E2E_PROJECT
41
- const ANON = process.env.AURA_E2E_ANON_KEY
42
- const SERVICE = process.env.AURA_E2E_SERVICE_KEY
43
- const RUN = Boolean(process.env.RUN_E2E && URL && PROJECT && ANON && SERVICE)
44
-
45
- /** Statuts transitoires observés sur la stack locale (timeout gateway→service sous charge). */
46
- const TRANSIENT_STATUS = new Set([408, 429, 502, 503, 504])
47
-
48
- /** Rejoue une requête tant qu'elle renvoie un statut transitoire, borné (cf. auth-e2e.test.ts). */
49
- async function retryTransient<T>(fn: () => Promise<AuraResponse<T>>): Promise<AuraResponse<T>> {
50
- let res = await fn()
51
- for (let i = 0; i < 10 && res.error && TRANSIENT_STATUS.has(res.error.status); i++) {
52
- await new Promise((r) => setTimeout(r, 1000))
53
- res = await fn()
54
- }
55
- return res
56
- }
57
-
58
- /** Rejoue une requête tant qu'elle renvoie un statut transitoire (jeu complet
59
- * TRANSIENT_STATUS : 408/429/502/503/504) OU 404 (cache pas encore rechargé — table
60
- * inconnue de PostgREST), borné. Cf. db-types-e2e.test.ts : le reload de cache
61
- * (pg_notify) est ASYNCHRONE — juste après la création d'une table via SQL brut,
62
- * PostgREST peut d'abord renvoyer un 404 (POSTGREST_ERROR, cache pas encore rechargé)
63
- * puis un 503 (reload en cours) avant d'être prêt. Sur stack locale saturée, peut aussi
64
- * voir 408 (timeout gateway = transitoire). Réservé au flux db de setup ci-dessous
65
- * (insert/select juste après CREATE TABLE) — ne pas réutiliser ce 404 élargi ailleurs,
66
- * un 404 hors reload de schéma est une vraie erreur. */
67
- async function retryReload<T>(fn: () => Promise<AuraResponse<T>>): Promise<AuraResponse<T>> {
68
- let res = await fn()
69
- for (let i = 0; i < 20 && (TRANSIENT_STATUS.has(res.error?.status) || res.error?.status === 404); i++) {
70
- await new Promise((r) => setTimeout(r, 1000))
71
- res = await fn()
72
- }
73
- return res
74
- }
75
-
76
- describe.runIf(RUN)('README smoke E2E réel (stack live) — auth / db / storage', () => {
77
- it(
78
- 'auth : signUp → signInWithPassword → getUser (id/email cohérents) → signOut',
79
- async () => {
80
- const client = createClient(URL!, PROJECT!, ANON!)
81
- const admin = createAdminClient(URL!, PROJECT!, SERVICE!)
82
- const suffix = process.env.AURA_E2E_SUFFIX ?? Math.random().toString(36).slice(2, 8)
83
- const email = `readme-smoke-auth-${suffix}@aurabase.dev`
84
- const password = 'ReadmeSmokeAuth123!'
85
-
86
- let userId: string | null = null
87
- try {
88
- // README auth § "Mot de passe"
89
- const signUpRes = await retryTransient(() => client.auth.signUp({ email, password }))
90
- expect(signUpRes.error).toBeNull()
91
-
92
- const signInRes = await retryTransient(() => client.auth.signInWithPassword({ email, password }))
93
- expect(signInRes.error).toBeNull()
94
- const signInData = signInRes.data as { access_token: string; user: { id: string } }
95
- expect(signInData.access_token).toBeTruthy()
96
- userId = signInData.user.id
97
- expect(userId).toBeTruthy()
98
-
99
- // README auth § "Utilisateur, claims, mot de passe" — const { data: user } = await aura.auth.getUser()
100
- const { data: user, error: userError } = await client.auth.getUser()
101
- expect(userError).toBeNull()
102
- expect(user).not.toBeNull()
103
- expect(user!.id).toBe(userId)
104
- expect(user!.email).toBe(email)
105
-
106
- // README auth § "Mot de passe" — await aura.auth.signOut()
107
- const signOutRes = await client.auth.signOut()
108
- expect(signOutRes.error).toBeNull()
109
- } finally {
110
- if (userId) {
111
- try {
112
- await admin.authAdmin.deleteUser(userId)
113
- } catch {
114
- // best-effort cleanup
115
- }
116
- }
117
- }
118
- },
119
- 120_000,
120
- )
121
-
122
- it(
123
- 'db : from(table).insert(...).select(...).single() puis from(table).select(...).eq(...).single()',
124
- async () => {
125
- const client = createClient(URL!, PROJECT!, ANON!)
126
- const suffix = process.env.AURA_E2E_SUFFIX ?? Math.random().toString(36).slice(2, 8)
127
- const table = `e2e_readme_smoke_${suffix}`
128
-
129
- // Table jetable — même mécanique que db-types-e2e.test.ts (SQL brut,
130
- // GRANT large intentionnel, reload du cache de schéma PostgREST).
131
- await client.db.sql(`DROP TABLE IF EXISTS ${table}`)
132
- await client.db.sql(
133
- `CREATE TABLE ${table} (id uuid PRIMARY KEY DEFAULT gen_random_uuid(), title text NOT NULL, published boolean NOT NULL DEFAULT false)`,
134
- )
135
- await client.db.sql(`GRANT ALL ON ${table} TO PUBLIC`)
136
- await client.db.sql(`SELECT pg_notify('pgrst', 'reload schema')`)
137
- // Laisse le reload asynchrone démarrer avant le premier appel — sans ce délai,
138
- // le premier insert tombe quasi systématiquement en 404 (cache pas encore invalidé).
139
- await new Promise((r) => setTimeout(r, 1500))
140
-
141
- try {
142
- // README db § "Mutations — update/delete ciblent par id"
143
- const inserted = await retryReload(() =>
144
- client.db.from(table).insert({ title: 'Hello Aurabase', published: true }).select('id').single(),
145
- )
146
- if (TRANSIENT_STATUS.has(inserted.error?.status) || inserted.error?.status === 404) {
147
- // eslint-disable-next-line no-console
148
- console.warn(
149
- '[readme-smoke-e2e] SKIP db (infra: reload/503/404 persistant après retries sur insert) — ' +
150
- 'NON un succès : assertion runtime db ignorée, pas un défaut de la doc.',
151
- )
152
- return
153
- }
154
- expect(inserted.error).toBeNull()
155
- const id = (inserted.data as { id: string } | null)?.id
156
- expect(id).toBeTruthy()
157
-
158
- // README db § "Select, filtres, embeds"
159
- const selected = await retryReload(() =>
160
- client.db.from(table).select('id,title,published').eq('id', id!).single(),
161
- )
162
- if (TRANSIENT_STATUS.has(selected.error?.status) || selected.error?.status === 404) {
163
- // eslint-disable-next-line no-console
164
- console.warn(
165
- '[readme-smoke-e2e] SKIP db (infra: reload/503/404 persistant après retries sur select) — ' +
166
- 'NON un succès : assertion runtime db ignorée, pas un défaut de la doc.',
167
- )
168
- return
169
- }
170
- expect(selected.error).toBeNull()
171
- const row = selected.data as { id: string; title: string; published: boolean }
172
- expect(row.id).toBe(id)
173
- expect(row.title).toBe('Hello Aurabase')
174
- expect(row.published).toBe(true)
175
- } finally {
176
- await client.db.sql(`DROP TABLE IF EXISTS ${table}`)
177
- }
178
- },
179
- 120_000,
180
- )
181
-
182
- it(
183
- 'storage : createBucket (service_role) → upload → download → remove → deleteBucket',
184
- async () => {
185
- const admin = createAdminClient(URL!, PROJECT!, SERVICE!)
186
- const suffix = process.env.AURA_E2E_SUFFIX ?? Math.random().toString(36).slice(2, 8)
187
- const bucket = `e2e-readme-smoke-${suffix}`
188
- const path = 'readme-smoke.txt'
189
- const content = 'Aurabase README smoke E2E'
190
-
191
- let created = false
192
- try {
193
- // README storage § "Buckets"
194
- const createRes = await retryTransient(() => admin.storage.createBucket(bucket, { public: false }))
195
- expect(createRes.error).toBeNull()
196
- created = true
197
-
198
- // README storage § "Upload, liste, métadonnées"
199
- const uploadRes = await admin.storage.upload(
200
- bucket,
201
- path,
202
- new Blob([content], { type: 'text/plain' }),
203
- { contentType: 'text/plain' },
204
- )
205
- expect(uploadRes.error).toBeNull()
206
- const key = uploadRes.data!.key
207
- expect(key).toBeTruthy()
208
-
209
- // README storage § "Download — builder paresseux"
210
- const { data: blob, error: downloadError } = await admin.storage.download(bucket, key)
211
- expect(downloadError).toBeNull()
212
- expect(blob).not.toBeNull()
213
- const text = await blob!.text()
214
- expect(text).toBe(content)
215
-
216
- // README storage § "Copie, déplacement, suppression"
217
- const removeRes = await admin.storage.remove(bucket, [key])
218
- expect(removeRes.error).toBeNull()
219
- } finally {
220
- if (created) {
221
- try {
222
- await admin.storage.deleteBucket(bucket)
223
- } catch {
224
- // best-effort cleanup
225
- }
226
- }
227
- }
228
- },
229
- 120_000,
230
- )
231
- })
@@ -1,344 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // E2E réel (stack live) — LOT A / Task A2 du plan
3
- // docs/superpowers/plans/2026-07-13-realtime-column-filters.md.
4
- //
5
- // Prouve en conditions réelles que le filtre colonne serveur `aura-realtime`
6
- // (protocol.rs::event_matches_filters, câblé handlers/websocket.rs:~1173) ne
7
- // livre AU CALLBACK que les events postgres_changes dont le `record` (ou
8
- // `old_record` pour DELETE) satisfait le prédicat `filter: 'col=op.value'`.
9
- // Le Lot B (fallback client `columnFilter.ts`) n'est PAS encore implémenté à
10
- // ce stade (AuraChannel._dispatchEvent ne vérifie que schema/table, jamais
11
- // `filter` — cf. packages/realtime/src/AuraChannel.ts:~411-426) : ce test
12
- // isole donc bien le comportement SERVEUR, seul en jeu ici.
13
- //
14
- // ── Mécanisme d'activation realtime d'une table (repéré dans le code) ──────
15
- // Le CDC (`services/aura-realtime/src/cdc/postgres.rs`) ne route que les
16
- // tables listées dans `{project_schema}_platform.realtime_tables WHERE
17
- // enabled = true` (lu par `SubscriptionManager::get_active_realtime_tables`,
18
- // rafraîchi toutes les 3s — `services/aura-realtime/src/cdc/postgres.rs:341`
19
- // `filter_refresh_interval`). Il existe une route HTTP DÉDIÉE côté aura-db
20
- // pour activer/désactiver ça proprement (pas besoin d'INSERT SQL manuel dans
21
- // le schéma platform, verrouillé au master_pool) :
22
- // PUT /v1/db/{project_id}/schema/tables/{table}/realtime
23
- // body: { enabled: true }
24
- // (service_role requis — `require_service_role` via header x-aura-role posé
25
- // par le gateway à partir de la clé API service_role ; voir
26
- // `services/aura-db/src/handlers/schema.rs::toggle_realtime`, routes
27
- // enregistrées dans `services/aura-db/src/main.rs:783/983`)
28
- // Cet endpoint fait aussi `ALTER TABLE ... REPLICA IDENTITY FULL`, nécessaire
29
- // pour que `old_record` soit peuplé sur UPDATE/DELETE. Pas de méthode SDK
30
- // dédiée (comme pour `/settings` storage) → fetch direct authentifié par la
31
- // clé service_role, même pattern que storage-transform-e2e.test.ts.
32
- //
33
- // ── Piège trouvé et évité : `schema` dans le filtre postgres_changes ───────
34
- // Le payload CDC (`build_payload`, cdc/postgres.rs:590-646) porte
35
- // `"schema": change.schema` = le schéma PHYSIQUE `project_<uuid>` (PAS
36
- // littéralement "public"). L'alias `db:public.{table}` (cdc/postgres.rs:528)
37
- // n'est qu'un ALIAS DE ROUTAGE DE TOPIC (permet de s'abonner sans connaître
38
- // le schéma interne) — il ne réécrit PAS le champ `schema` du payload livré.
39
- // Si le filtre `.on('postgres_changes', { schema: 'public', ... })` était
40
- // utilisé, la comparaison stricte `fs != schema` dans `event_matches_filters`
41
- // (protocol.rs) EXCLURAIT alors TOUT event (fail-closed) puisque
42
- // `"public" !== "project_<uuid>"` — et le fallback client (dispatch,
43
- // AuraChannel.ts:423) ferait la même comparaison littérale en second rideau.
44
- // Ce test omet donc volontairement `schema` dans le filtre (le champ est
45
- // `Option<String>` côté serveur ET `schema?: string` côté SDK — absent ⇒
46
- // check sauté, seuls `event`/`table`/`filter` s'appliquent), ce qui isole
47
- // proprement le filtre COLONNE (objet de ce test) de ce défaut d'alias
48
- // séparé (signalé ici, hors scope de A2 — potentiel suivi backlog).
49
- //
50
- // ── Auth WS ──────────────────────────────────────────────────────────────
51
- // `GET /v1/realtime/ws` exige un VRAI JWT en query `?token=` (validate_jwt,
52
- // handlers/websocket.rs:243-249) — une clé anon seule ne suffit pas. Le test
53
- // signUp + signInWithPassword un utilisateur jetable via la clé anon pour
54
- // peupler `authStore.token` avant `realtime.connect()`.
55
- //
56
- // Gaté par RUN_E2E + credentials (identique aux autres *-e2e.test.ts). Le
57
- // run réel n'est PAS lancé ici (pas de creds dans cet environnement) — le
58
- // contrôleur le fera après rebuild `aura-realtime`. Ce fichier doit
59
- // seulement compiler et skip proprement (`describe.runIf`).
60
- // ---------------------------------------------------------------------------
61
-
62
- import { describe, it, expect } from 'vitest'
63
- import { createClient, createAdminClient } from '../src/index'
64
- import type { AuraResponse, RealtimeEvent, RealtimeSubscribeStatus } from '../src/index'
65
-
66
- const URL = process.env.AURA_E2E_URL
67
- const PROJECT = process.env.AURA_E2E_PROJECT
68
- const ANON = process.env.AURA_E2E_ANON_KEY
69
- const SERVICE = process.env.AURA_E2E_SERVICE_KEY
70
- const RUN = Boolean(process.env.RUN_E2E && URL && PROJECT && ANON && SERVICE)
71
-
72
- /** Statuts transitoires observés sur la stack locale (timeout gateway→service sous charge). */
73
- const TRANSIENT_STATUS = new Set([408, 429, 502, 503, 504])
74
-
75
- /** Rejoue une requête (AuraResponse) tant qu'elle renvoie un statut transitoire, borné. */
76
- async function retryTransient<T>(fn: () => Promise<AuraResponse<T>>): Promise<AuraResponse<T>> {
77
- let res = await fn()
78
- for (let i = 0; i < 10 && res.error && TRANSIENT_STATUS.has(res.error.status); i++) {
79
- await new Promise((r) => setTimeout(r, 1000))
80
- res = await fn()
81
- }
82
- return res
83
- }
84
-
85
- /** Rejoue un fetch() brut tant que le statut est transitoire, borné. */
86
- async function retryFetchTransient(fn: () => Promise<Response>): Promise<Response> {
87
- let res = await fn()
88
- for (let i = 0; i < 10 && TRANSIENT_STATUS.has(res.status); i++) {
89
- await new Promise((r) => setTimeout(r, 1000))
90
- res = await fn()
91
- }
92
- return res
93
- }
94
-
95
- function sleep(ms: number): Promise<void> {
96
- return new Promise((r) => setTimeout(r, ms))
97
- }
98
-
99
- type CdcRecord = Record<string, unknown>
100
- interface CdcPayload {
101
- schema: string
102
- table: string
103
- type: 'INSERT' | 'UPDATE' | 'DELETE'
104
- record: CdcRecord
105
- old_record: CdcRecord | null
106
- }
107
-
108
- /**
109
- * Attend le PREMIER statut renvoyé par `channel.subscribe(cb)`, borné dans le temps.
110
- * Retourne `'timeout'` si aucun statut n'arrive (WS/CDC pas prêt) — le test doit alors
111
- * SKIPPER proprement plutôt que d'échouer sur une infra transitoire.
112
- */
113
- function waitForSubscribeStatus(
114
- doSubscribe: (cb: (status: RealtimeSubscribeStatus, err?: Error) => void) => void,
115
- timeoutMs: number,
116
- ): Promise<{ status: RealtimeSubscribeStatus; err?: Error } | 'timeout'> {
117
- return new Promise((resolve) => {
118
- let done = false
119
- const timer = setTimeout(() => {
120
- if (!done) {
121
- done = true
122
- resolve('timeout')
123
- }
124
- }, timeoutMs)
125
- doSubscribe((status, err) => {
126
- if (done) return
127
- done = true
128
- clearTimeout(timer)
129
- resolve({ status, err })
130
- })
131
- })
132
- }
133
-
134
- describe.runIf(RUN)('realtime filtre colonne E2E réel (stack live) — seuls les events matchant sont livrés', () => {
135
- it(
136
- 'eq / gt / AND — le serveur ne délivre que les postgres_changes dont le record matche le filtre',
137
- async () => {
138
- const admin = createAdminClient(URL!, PROJECT!, SERVICE!)
139
- const anon = createClient(URL!, PROJECT!, ANON!)
140
- const suffix = process.env.AURA_E2E_SUFFIX ?? Math.random().toString(36).slice(2, 8)
141
- const table = `rt_${suffix}`
142
- // Le CDC calcule le RLS `allowed_sub_ids` sur le canal GÉNÉRIQUE au schéma
143
- // PHYSIQUE (`project_<uuid>`), pas sur l'alias `db:public.*` (limite backend
144
- // pré-existante : un abonné via l'alias public n'est jamais dans allowed_sub_ids).
145
- // On s'abonne donc au canal générique pour recevoir les events.
146
- const physicalSchema = `project_${PROJECT!.replace(/-/g, '_')}`
147
- const channelName = `db:${physicalSchema}.${table}`
148
- const email = `realtime-filter-e2e-${suffix}@aurabase.dev`
149
- const password = 'EndUserPassword123!'
150
-
151
- let tableCreated = false
152
- let userId: string | null = null
153
-
154
- try {
155
- // -- 1. Setup service_role : table jetable + GRANT + reload PostgREST ----
156
- await admin.db.sql(`DROP TABLE IF EXISTS ${table}`)
157
- const createRes = await admin.db.sql(
158
- `CREATE TABLE ${table} (
159
- id serial PRIMARY KEY,
160
- room_id int NOT NULL,
161
- qty int NOT NULL DEFAULT 0,
162
- name text NOT NULL DEFAULT '',
163
- status text NOT NULL DEFAULT 'open'
164
- )`,
165
- )
166
- if (createRes.error) {
167
- // eslint-disable-next-line no-console
168
- console.warn(
169
- `[realtime-filter-e2e] SKIP (infra: CREATE TABLE a échoué — ${createRes.error.status} ` +
170
- `${createRes.error.message ?? ''}) — table de test indisponible.`,
171
- )
172
- return
173
- }
174
- tableCreated = true
175
- await admin.db.sql(`GRANT ALL ON ${table} TO PUBLIC`)
176
- await admin.db.sql(`SELECT pg_notify('pgrst', 'reload schema')`)
177
-
178
- // -- 2. Activer le realtime CDC pour cette table (service_role) ---------
179
- const enableRes = await retryFetchTransient(() =>
180
- fetch(`${admin.baseUrl}/v1/db/${admin.projectId}/schema/tables/${table}/realtime`, {
181
- method: 'PUT',
182
- headers: { apikey: SERVICE!, 'content-type': 'application/json' },
183
- body: JSON.stringify({ enabled: true }),
184
- }),
185
- )
186
- if (!enableRes.ok) {
187
- // eslint-disable-next-line no-console
188
- console.warn(
189
- `[realtime-filter-e2e] SKIP (infra: PUT .../schema/tables/${table}/realtime → ` +
190
- `${enableRes.status} — activation realtime indisponible dans ce contexte E2E).`,
191
- )
192
- return
193
- }
194
-
195
- // -- 3. Utilisateur jetable (anon key) — le WS exige un vrai JWT --------
196
- const signUpRes = await retryTransient(() => anon.auth.signUp({ email, password }))
197
- if (signUpRes.error && TRANSIENT_STATUS.has(signUpRes.error.status)) {
198
- // eslint-disable-next-line no-console
199
- console.warn(
200
- `[realtime-filter-e2e] SKIP (infra: signUp indisponible après retries — ` +
201
- `${signUpRes.error.status} persistant).`,
202
- )
203
- return
204
- }
205
- expect(signUpRes.error).toBeNull()
206
-
207
- const loginRes = await retryTransient(() => anon.auth.signInWithPassword({ email, password }))
208
- if (loginRes.error && TRANSIENT_STATUS.has(loginRes.error.status)) {
209
- // eslint-disable-next-line no-console
210
- console.warn(
211
- `[realtime-filter-e2e] SKIP (infra: signInWithPassword indisponible après retries — ` +
212
- `${loginRes.error.status} persistant).`,
213
- )
214
- return
215
- }
216
- expect(loginRes.error).toBeNull()
217
- const loginData = loginRes.data as { user: { id: string } } | null
218
- userId = loginData?.user.id ?? null
219
-
220
- // -- 4. Laisser le filtre CDC se rafraîchir (add-tables, ~3s) -----------
221
- await sleep(4000)
222
-
223
- // -- 5. Une seule connexion WS pour les 3 scénarios ---------------------
224
- anon.realtime.connect()
225
-
226
- /**
227
- * Un scénario = un channel FRAIS (même nom `db:public.<table>` — c'est
228
- * l'alias de routage CDC, cf. commentaire en tête de fichier) avec UN SEUL
229
- * listener `postgres_changes` (filtre isolé — pas de faux-négatif dû à un
230
- * OR entre plusieurs filtres coexistant sur le même channel), un INSERT
231
- * de deux lignes (une qui matche, une qui ne matche pas), une fenêtre de
232
- * collecte bornée, puis une assertion stricte. Retourne `false` si le
233
- * scénario doit SKIP (WS/CDC pas prêt) — auquel cas l'appelant arrête tout.
234
- */
235
- async function runScenario(
236
- label: string,
237
- filter: string,
238
- matchingRow: { room_id: number; qty: number; name: string; status: string },
239
- nonMatchingRow: { room_id: number; qty: number; name: string; status: string },
240
- ): Promise<'ok' | 'skip'> {
241
- const received: RealtimeEvent<CdcPayload>[] = []
242
- const channel = anon.channel(channelName)
243
- channel.on(
244
- 'postgres_changes',
245
- // `schema` omis à dessein — voir commentaire en tête de fichier.
246
- { event: '*', table, filter },
247
- (payload) => received.push(payload as RealtimeEvent<CdcPayload>),
248
- )
249
-
250
- const result = await waitForSubscribeStatus((cb) => channel.subscribe(cb), 15_000)
251
- if (result === 'timeout' || result.status !== 'SUBSCRIBED') {
252
- // eslint-disable-next-line no-console
253
- console.warn(
254
- `[realtime-filter-e2e] SKIP scénario ${label} (WS/CDC pas prêt — ` +
255
- `${result === 'timeout' ? 'timeout attente SUBSCRIBED' : `statut ${result.status}`}).`,
256
- )
257
- anon.realtime.removeChannel(channelName)
258
- return 'skip'
259
- }
260
-
261
- const insMatch = await admin.db.sql(
262
- `INSERT INTO ${table} (room_id, qty, name, status) VALUES ($1, $2, $3, $4)`,
263
- [matchingRow.room_id, matchingRow.qty, matchingRow.name, matchingRow.status],
264
- )
265
- expect(insMatch.error).toBeNull()
266
- const insOther = await admin.db.sql(
267
- `INSERT INTO ${table} (room_id, qty, name, status) VALUES ($1, $2, $3, $4)`,
268
- [nonMatchingRow.room_id, nonMatchingRow.qty, nonMatchingRow.name, nonMatchingRow.status],
269
- )
270
- expect(insOther.error).toBeNull()
271
-
272
- // Fenêtre de collecte CDC (poll WAL + refresh add-tables + latence pub/sub).
273
- await sleep(8_000)
274
-
275
- const matches = (r: CdcRecord | null | undefined, expected: typeof matchingRow): boolean =>
276
- !!r && r.room_id === expected.room_id && r.qty === expected.qty
277
-
278
- const gotMatching = received.some((e) => matches(e.payload.record, matchingRow))
279
- const gotNonMatching = received.some((e) => matches(e.payload.record, nonMatchingRow))
280
-
281
- expect(gotMatching).toBe(true)
282
- expect(gotNonMatching).toBe(false)
283
-
284
- anon.realtime.removeChannel(channelName)
285
- return 'ok'
286
- }
287
-
288
- // -- 6. Scénario eq : room_id=eq.42 --------------------------------------
289
- const r1 = await runScenario(
290
- 'eq (room_id=eq.42)',
291
- 'room_id=eq.42',
292
- { room_id: 42, qty: 1, name: 'alpha', status: 'open' },
293
- { room_id: 7, qty: 1, name: 'beta', status: 'open' },
294
- )
295
- if (r1 === 'skip') return
296
-
297
- // -- 7. Scénario gt : qty=gt.5 --------------------------------------------
298
- const r2 = await runScenario(
299
- 'gt (qty=gt.5)',
300
- 'qty=gt.5',
301
- { room_id: 1, qty: 10, name: 'gamma', status: 'open' },
302
- { room_id: 1, qty: 1, name: 'delta', status: 'open' },
303
- )
304
- if (r2 === 'skip') return
305
-
306
- // -- 8. Scénario AND : room_id=eq.42,qty=gt.5 -----------------------------
307
- const r3 = await runScenario(
308
- 'AND (room_id=eq.42,qty=gt.5)',
309
- 'room_id=eq.42,qty=gt.5',
310
- { room_id: 42, qty: 10, name: 'epsilon', status: 'open' },
311
- // Ne matche que la moitié du AND (room_id ok, qty non) — doit rester exclu.
312
- { room_id: 42, qty: 1, name: 'zeta', status: 'open' },
313
- )
314
- if (r3 === 'skip') return
315
- } finally {
316
- try {
317
- anon.realtime.removeAllChannels()
318
- } catch {
319
- // best-effort cleanup
320
- }
321
- try {
322
- anon.realtime.disconnect()
323
- } catch {
324
- // best-effort cleanup
325
- }
326
- if (userId) {
327
- try {
328
- await admin.authAdmin.deleteUser(userId)
329
- } catch {
330
- // best-effort cleanup
331
- }
332
- }
333
- if (tableCreated) {
334
- try {
335
- await admin.db.sql(`DROP TABLE IF EXISTS ${table}`)
336
- } catch {
337
- // best-effort cleanup
338
- }
339
- }
340
- }
341
- },
342
- 120_000,
343
- )
344
- })