@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.
- package/.changeset/config.json +11 -0
- package/CHANGELOG.md +30 -0
- package/LICENSE +21 -0
- package/README.md +833 -0
- package/package.json +90 -0
- package/packages/ai/LICENSE +21 -0
- package/packages/ai/README.md +106 -0
- package/packages/ai/dist/index.cjs +229 -0
- package/packages/ai/dist/index.d.cts +139 -0
- package/packages/ai/dist/index.d.ts +139 -0
- package/packages/ai/dist/index.js +226 -0
- package/packages/ai/node_modules/.bin/esbuild +19 -0
- package/packages/ai/node_modules/.bin/tsc +22 -0
- package/packages/ai/node_modules/.bin/tsserver +22 -0
- package/packages/ai/node_modules/.bin/tsup +22 -0
- package/packages/ai/node_modules/.bin/tsup-node +22 -0
- package/packages/ai/node_modules/.bin/vite +22 -0
- package/packages/ai/node_modules/.bin/vitest +22 -0
- package/packages/ai/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/packages/ai/package.json +61 -0
- package/packages/ai/src/AiService.ts +226 -0
- package/packages/ai/src/index.ts +18 -0
- package/packages/ai/src/sse.ts +141 -0
- package/packages/ai/src/types.ts +30 -0
- package/packages/ai/tests/chat-stream.test.ts +151 -0
- package/packages/ai/tests/rag-namespaces.test.ts +54 -0
- package/packages/ai/tests/sse.test.ts +69 -0
- package/packages/ai/tsconfig.json +5 -0
- package/packages/ai/tsup.config.ts +11 -0
- package/packages/aurabase/LICENSE +21 -0
- package/packages/aurabase/README.md +64 -0
- package/packages/aurabase/dist/AuraClient-DAtDbfPB.d.cts +77 -0
- package/packages/aurabase/dist/AuraClient-DAtDbfPB.d.ts +77 -0
- package/packages/aurabase/dist/index.cjs +237 -0
- package/packages/aurabase/dist/index.d.cts +46 -0
- package/packages/aurabase/dist/index.d.ts +46 -0
- package/packages/aurabase/dist/index.js +177 -0
- package/packages/aurabase/dist/ssr.cjs +224 -0
- package/packages/aurabase/dist/ssr.d.cts +65 -0
- package/packages/aurabase/dist/ssr.d.ts +65 -0
- package/packages/aurabase/dist/ssr.js +214 -0
- package/packages/aurabase/node_modules/.bin/esbuild +19 -0
- package/packages/aurabase/node_modules/.bin/tsc +22 -0
- package/packages/aurabase/node_modules/.bin/tsserver +22 -0
- package/packages/aurabase/node_modules/.bin/tsup +22 -0
- package/packages/aurabase/node_modules/.bin/tsup-node +22 -0
- package/packages/aurabase/node_modules/.bin/vite +22 -0
- package/packages/aurabase/node_modules/.bin/vitest +22 -0
- package/packages/aurabase/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/packages/aurabase/package.json +80 -0
- package/packages/aurabase/src/AuraClient.ts +237 -0
- package/packages/aurabase/src/index.ts +152 -0
- package/packages/aurabase/src/ssr.ts +156 -0
- package/packages/aurabase/tests/ai-streaming-rag-e2e.test.ts +82 -0
- package/packages/aurabase/tests/ai.test.ts +111 -0
- package/packages/aurabase/tests/auth-admin.test.ts +515 -0
- package/packages/aurabase/tests/auth-e2e.test.ts +135 -0
- package/packages/aurabase/tests/auth-hardening.test.ts +206 -0
- package/packages/aurabase/tests/auth.test.ts +947 -0
- package/packages/aurabase/tests/database.test.ts +230 -0
- package/packages/aurabase/tests/db-types-e2e.test.ts +217 -0
- package/packages/aurabase/tests/dispose.test.ts +23 -0
- package/packages/aurabase/tests/foreign-token.e2e.test.ts +129 -0
- package/packages/aurabase/tests/functions.test.ts +107 -0
- package/packages/aurabase/tests/integration.test.ts +413 -0
- package/packages/aurabase/tests/live-production-validation.js +241 -0
- package/packages/aurabase/tests/live-sdk-production-validation.js +293 -0
- package/packages/aurabase/tests/mocks.ts +139 -0
- package/packages/aurabase/tests/notifications.test.ts +314 -0
- package/packages/aurabase/tests/observability-backup.test.ts +186 -0
- package/packages/aurabase/tests/observability-hook.test.ts +130 -0
- package/packages/aurabase/tests/production-robustness.test.ts +268 -0
- package/packages/aurabase/tests/public-api-surface.test.ts +53 -0
- package/packages/aurabase/tests/query-builder.test.ts +329 -0
- package/packages/aurabase/tests/readme-smoke-e2e.test.ts +231 -0
- package/packages/aurabase/tests/realtime-filter-e2e.test.ts +344 -0
- package/packages/aurabase/tests/refresh-locks.test.ts +210 -0
- package/packages/aurabase/tests/retry-option.test.ts +17 -0
- package/packages/aurabase/tests/rpc-e2e.test.ts +254 -0
- package/packages/aurabase/tests/rs256-local-e2e.test.ts +114 -0
- package/packages/aurabase/tests/rt-alias-public-e2e.test.ts +235 -0
- package/packages/aurabase/tests/rt-http-broadcast-e2e.test.ts +124 -0
- package/packages/aurabase/tests/service-role-guard.test.ts +99 -0
- package/packages/aurabase/tests/ssr.test.ts +91 -0
- package/packages/aurabase/tests/storage-backend-e2e.test.ts +481 -0
- package/packages/aurabase/tests/storage-sdk-parity-e2e.test.ts +104 -0
- package/packages/aurabase/tests/storage-transform-e2e.test.ts +684 -0
- package/packages/aurabase/tests/storage.test.ts +55 -0
- package/packages/aurabase/tests/types/client-generic.test-d.ts +79 -0
- package/packages/aurabase/tests/types/docs-snippets.test-d.ts +571 -0
- package/packages/aurabase/tests/types/error-code.test-d.ts +53 -0
- package/packages/aurabase/tsconfig.json +5 -0
- package/packages/aurabase/tsconfig.test-d.json +5 -0
- package/packages/aurabase/tsup.config.ts +11 -0
- package/packages/aurabase/vitest.config.ts +16 -0
- package/packages/aurabase/vitest.e2e.config.ts +9 -0
- package/packages/auth/LICENSE +21 -0
- package/packages/auth/README.md +215 -0
- package/packages/auth/dist/index.cjs +1175 -0
- package/packages/auth/dist/index.d.cts +397 -0
- package/packages/auth/dist/index.d.ts +397 -0
- package/packages/auth/dist/index.js +1170 -0
- package/packages/auth/node_modules/.bin/esbuild +19 -0
- package/packages/auth/node_modules/.bin/tsc +22 -0
- package/packages/auth/node_modules/.bin/tsserver +22 -0
- package/packages/auth/node_modules/.bin/tsup +22 -0
- package/packages/auth/node_modules/.bin/tsup-node +22 -0
- package/packages/auth/node_modules/.bin/vite +22 -0
- package/packages/auth/node_modules/.bin/vitest +22 -0
- package/packages/auth/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/packages/auth/package.json +61 -0
- package/packages/auth/src/AuthAdminService.ts +149 -0
- package/packages/auth/src/AuthService.ts +1166 -0
- package/packages/auth/src/SessionManager.ts +92 -0
- package/packages/auth/src/index.ts +17 -0
- package/packages/auth/src/jwks.ts +337 -0
- package/packages/auth/src/pkce.ts +27 -0
- package/packages/auth/src/types.ts +89 -0
- package/packages/auth/tests/auth-lifecycle.test.ts +149 -0
- package/packages/auth/tests/detect-session.test.ts +361 -0
- package/packages/auth/tests/getclaims.test.ts +780 -0
- package/packages/auth/tests/is-mfa-challenge.test.ts +27 -0
- package/packages/auth/tests/password-recovery.test.ts +124 -0
- package/packages/auth/tests/pkce.test.ts +192 -0
- package/packages/auth/tests/session-manager.test.ts +103 -0
- package/packages/auth/tests/set-session.test.ts +139 -0
- package/packages/auth/tests/verify-otp.test.ts +153 -0
- package/packages/auth/tsconfig.json +5 -0
- package/packages/auth/tsup.config.ts +11 -0
- package/packages/core/LICENSE +21 -0
- package/packages/core/README.md +132 -0
- package/packages/core/dist/index.cjs +695 -0
- package/packages/core/dist/index.d.cts +1137 -0
- package/packages/core/dist/index.d.ts +1137 -0
- package/packages/core/dist/index.js +673 -0
- package/packages/core/node_modules/.bin/esbuild +22 -0
- package/packages/core/node_modules/.bin/tsc +22 -0
- package/packages/core/node_modules/.bin/tsserver +22 -0
- package/packages/core/node_modules/.bin/tsup +22 -0
- package/packages/core/node_modules/.bin/tsup-node +22 -0
- package/packages/core/node_modules/.bin/vite +22 -0
- package/packages/core/node_modules/.bin/vitest +22 -0
- package/packages/core/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/packages/core/package.json +57 -0
- package/packages/core/src/AuraError.ts +89 -0
- package/packages/core/src/BaseService.ts +44 -0
- package/packages/core/src/client.ts +34 -0
- package/packages/core/src/cookie-utils.ts +42 -0
- package/packages/core/src/fetch.ts +435 -0
- package/packages/core/src/index.ts +22 -0
- package/packages/core/src/retry.ts +63 -0
- package/packages/core/src/serialize.ts +6 -0
- package/packages/core/src/stores/BaseAuthStore.ts +164 -0
- package/packages/core/src/stores/LocalAuthStore.ts +199 -0
- package/packages/core/src/types.ts +1042 -0
- package/packages/core/tests/auth-store.test.ts +300 -0
- package/packages/core/tests/error-code.test.ts +61 -0
- package/packages/core/tests/error.test.ts +24 -0
- package/packages/core/tests/fetch.test.ts +286 -0
- package/packages/core/tests/mocks.ts +139 -0
- package/packages/core/tests/observability.test.ts +86 -0
- package/packages/core/tests/refresh-hardening.test.ts +164 -0
- package/packages/core/tests/refresh-observability.test.ts +111 -0
- package/packages/core/tests/retry.test.ts +106 -0
- package/packages/core/tests/serialize.test.ts +12 -0
- package/packages/core/tests/timeout.test.ts +79 -0
- package/packages/core/tsconfig.json +5 -0
- package/packages/core/tsup.config.ts +11 -0
- package/packages/db/LICENSE +21 -0
- package/packages/db/README.md +152 -0
- package/packages/db/VENDORED.md +93 -0
- package/packages/db/dist/index.cjs +544 -0
- package/packages/db/dist/index.d.cts +1111 -0
- package/packages/db/dist/index.d.ts +1111 -0
- package/packages/db/dist/index.js +541 -0
- package/packages/db/node_modules/.bin/esbuild +19 -0
- package/packages/db/node_modules/.bin/tsc +22 -0
- package/packages/db/node_modules/.bin/tsserver +22 -0
- package/packages/db/node_modules/.bin/tsup +22 -0
- package/packages/db/node_modules/.bin/tsup-node +22 -0
- package/packages/db/node_modules/.bin/vite +22 -0
- package/packages/db/node_modules/.bin/vitest +22 -0
- package/packages/db/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/packages/db/package.json +62 -0
- package/packages/db/src/DatabaseService.ts +170 -0
- package/packages/db/src/QueryBuilder.ts +830 -0
- package/packages/db/src/index.ts +2 -0
- package/packages/db/src/pgrst-types/common/common.ts +86 -0
- package/packages/db/src/pgrst-types/common/rpc.ts +151 -0
- package/packages/db/src/pgrst-types/feature-flags.ts +20 -0
- package/packages/db/src/pgrst-types/types.ts +134 -0
- package/packages/db/src/select-query-parser/parser.ts +479 -0
- package/packages/db/src/select-query-parser/result.ts +553 -0
- package/packages/db/src/select-query-parser/types.ts +132 -0
- package/packages/db/src/select-query-parser/utils.ts +707 -0
- package/packages/db/tests/filters.test.ts +81 -0
- package/packages/db/tests/mutations-filtered.e2e.test.ts +132 -0
- package/packages/db/tests/mutations-filtered.test.ts +188 -0
- package/packages/db/tests/order.test.ts +45 -0
- package/packages/db/tests/rpc.test.ts +41 -0
- package/packages/db/tests/scale/build-large-schema.ts +94 -0
- package/packages/db/tests/scale/scale-compile.test.ts +167 -0
- package/packages/db/tests/schema.test.ts +77 -0
- package/packages/db/tests/single-accept.e2e.test.ts +123 -0
- package/packages/db/tests/single.test.ts +211 -0
- package/packages/db/tests/types/filters.test-d.ts +52 -0
- package/packages/db/tests/types/fixtures.ts +40 -0
- package/packages/db/tests/types/from-views.test-d.ts +18 -0
- package/packages/db/tests/types/mutations.test-d.ts +23 -0
- package/packages/db/tests/types/rpc.test-d.ts +60 -0
- package/packages/db/tests/types/schema-shape.test-d.ts +8 -0
- package/packages/db/tests/types/select-inference.test-d.ts +38 -0
- package/packages/db/tests/vendored/fixtures.ts +83 -0
- package/packages/db/tests/vendored/get-result.test-d.ts +75 -0
- package/packages/db/tsconfig.json +5 -0
- package/packages/db/tsconfig.test-d.json +5 -0
- package/packages/db/tsup.config.ts +11 -0
- package/packages/db/vitest.config.ts +8 -0
- package/packages/functions/LICENSE +21 -0
- package/packages/functions/README.md +96 -0
- package/packages/functions/dist/index.cjs +173 -0
- package/packages/functions/dist/index.d.cts +81 -0
- package/packages/functions/dist/index.d.ts +81 -0
- package/packages/functions/dist/index.js +168 -0
- package/packages/functions/node_modules/.bin/esbuild +19 -0
- package/packages/functions/node_modules/.bin/tsc +22 -0
- package/packages/functions/node_modules/.bin/tsserver +22 -0
- package/packages/functions/node_modules/.bin/tsup +22 -0
- package/packages/functions/node_modules/.bin/tsup-node +22 -0
- package/packages/functions/node_modules/.bin/vite +22 -0
- package/packages/functions/node_modules/.bin/vitest +22 -0
- package/packages/functions/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/packages/functions/package.json +60 -0
- package/packages/functions/src/FunctionsService.ts +188 -0
- package/packages/functions/src/errors.ts +70 -0
- package/packages/functions/src/index.ts +6 -0
- package/packages/functions/tests/invoke.test.ts +97 -0
- package/packages/functions/tests/response-type-errors.test.ts +135 -0
- package/packages/functions/tsconfig.json +5 -0
- package/packages/functions/tsup.config.ts +11 -0
- package/packages/gen/LICENSE +21 -0
- package/packages/gen/README.md +84 -0
- package/packages/gen/dist/cli.cjs +334 -0
- package/packages/gen/dist/cli.d.cts +1 -0
- package/packages/gen/dist/cli.d.ts +1 -0
- package/packages/gen/dist/cli.js +332 -0
- package/packages/gen/dist/index.cjs +257 -0
- package/packages/gen/dist/index.d.cts +12 -0
- package/packages/gen/dist/index.d.ts +12 -0
- package/packages/gen/dist/index.js +255 -0
- package/packages/gen/node_modules/.bin/esbuild +19 -0
- package/packages/gen/node_modules/.bin/tsc +22 -0
- package/packages/gen/node_modules/.bin/tsserver +22 -0
- package/packages/gen/node_modules/.bin/tsup +22 -0
- package/packages/gen/node_modules/.bin/tsup-node +22 -0
- package/packages/gen/node_modules/.bin/vite +22 -0
- package/packages/gen/node_modules/.bin/vitest +22 -0
- package/packages/gen/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/packages/gen/package.json +66 -0
- package/packages/gen/src/cli.ts +67 -0
- package/packages/gen/src/generate.ts +0 -0
- package/packages/gen/src/index.ts +2 -0
- package/packages/gen/tests/compile.test.ts +213 -0
- package/packages/gen/tests/e2e.test.ts +130 -0
- package/packages/gen/tests/generate.test.ts +396 -0
- package/packages/gen/tsconfig.json +5 -0
- package/packages/gen/tsup.config.ts +11 -0
- package/packages/notifications/LICENSE +21 -0
- package/packages/notifications/README.md +134 -0
- package/packages/notifications/dist/index.cjs +128 -0
- package/packages/notifications/dist/index.d.cts +81 -0
- package/packages/notifications/dist/index.d.ts +81 -0
- package/packages/notifications/dist/index.js +125 -0
- package/packages/notifications/node_modules/.bin/esbuild +19 -0
- package/packages/notifications/node_modules/.bin/tsc +22 -0
- package/packages/notifications/node_modules/.bin/tsserver +22 -0
- package/packages/notifications/node_modules/.bin/tsup +22 -0
- package/packages/notifications/node_modules/.bin/tsup-node +22 -0
- package/packages/notifications/node_modules/.bin/vite +22 -0
- package/packages/notifications/node_modules/.bin/vitest +22 -0
- package/packages/notifications/package.json +60 -0
- package/packages/notifications/src/NotificationsService.ts +230 -0
- package/packages/notifications/src/index.ts +19 -0
- package/packages/notifications/tsconfig.json +5 -0
- package/packages/notifications/tsup.config.ts +11 -0
- package/packages/realtime/LICENSE +21 -0
- package/packages/realtime/README.md +183 -0
- package/packages/realtime/dist/index.cjs +977 -0
- package/packages/realtime/dist/index.d.cts +259 -0
- package/packages/realtime/dist/index.d.ts +259 -0
- package/packages/realtime/dist/index.js +973 -0
- package/packages/realtime/node_modules/.bin/esbuild +19 -0
- package/packages/realtime/node_modules/.bin/tsc +22 -0
- package/packages/realtime/node_modules/.bin/tsserver +22 -0
- package/packages/realtime/node_modules/.bin/tsup +22 -0
- package/packages/realtime/node_modules/.bin/tsup-node +22 -0
- package/packages/realtime/node_modules/.bin/vite +22 -0
- package/packages/realtime/node_modules/.bin/vitest +22 -0
- package/packages/realtime/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/packages/realtime/package.json +60 -0
- package/packages/realtime/src/AuraChannel.ts +485 -0
- package/packages/realtime/src/HeartbeatManager.ts +73 -0
- package/packages/realtime/src/RealtimeService.ts +505 -0
- package/packages/realtime/src/columnFilter.ts +301 -0
- package/packages/realtime/src/index.ts +4 -0
- package/packages/realtime/tests/ack-routing.test.ts +81 -0
- package/packages/realtime/tests/column-filter.test.ts +144 -0
- package/packages/realtime/tests/dispatch.test.ts +191 -0
- package/packages/realtime/tests/heartbeat.test.ts +67 -0
- package/packages/realtime/tests/http-broadcast.test.ts +68 -0
- package/packages/realtime/tests/realtime-token.test.ts +43 -0
- package/packages/realtime/tests/reconnect-race.test.ts +149 -0
- package/packages/realtime/tests/ref-id.test.ts +34 -0
- package/packages/realtime/tests/set-auth.test.ts +70 -0
- package/packages/realtime/tsconfig.json +5 -0
- package/packages/realtime/tsup.config.ts +11 -0
- package/packages/storage/LICENSE +21 -0
- package/packages/storage/README.md +141 -0
- package/packages/storage/dist/index.cjs +333 -0
- package/packages/storage/dist/index.d.cts +185 -0
- package/packages/storage/dist/index.d.ts +185 -0
- package/packages/storage/dist/index.js +329 -0
- package/packages/storage/node_modules/.bin/esbuild +19 -0
- package/packages/storage/node_modules/.bin/tsc +22 -0
- package/packages/storage/node_modules/.bin/tsserver +22 -0
- package/packages/storage/node_modules/.bin/tsup +22 -0
- package/packages/storage/node_modules/.bin/tsup-node +22 -0
- package/packages/storage/node_modules/.bin/vite +22 -0
- package/packages/storage/node_modules/.bin/vitest +22 -0
- package/packages/storage/node_modules/.vite/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/packages/storage/package.json +60 -0
- package/packages/storage/src/DownloadBuilder.ts +60 -0
- package/packages/storage/src/StorageService.ts +323 -0
- package/packages/storage/src/index.ts +2 -0
- package/packages/storage/src/path.ts +35 -0
- package/packages/storage/src/transform.ts +15 -0
- package/packages/storage/tests/download.test.ts +64 -0
- package/packages/storage/tests/parity.test.ts +154 -0
- package/packages/storage/tests/path.test.ts +87 -0
- package/packages/storage/tests/transform.test.ts +79 -0
- package/packages/storage/tsconfig.json +5 -0
- package/packages/storage/tsup.config.ts +11 -0
- package/pnpm-workspace.yaml +24 -0
- package/tsconfig.base.json +15 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
const require = createRequire(import.meta.url);
|
|
3
|
+
|
|
4
|
+
// URL unique de la Gateway d'Aurabase comme en production
|
|
5
|
+
const API_URL = 'http://localhost:8080';
|
|
6
|
+
|
|
7
|
+
async function run() {
|
|
8
|
+
const runId = Math.random().toString(36).substring(2, 10);
|
|
9
|
+
const email = `live-prod-${runId}@aurabase.dev`;
|
|
10
|
+
const password = 'LiveSecurePassword123!';
|
|
11
|
+
const projectName = `live-project-${runId}`;
|
|
12
|
+
|
|
13
|
+
console.log(`[1] Inscription du compte développeur via la Gateway : ${email}`);
|
|
14
|
+
const regRes = await fetch(`${API_URL}/v1/control/accounts/register`, {
|
|
15
|
+
method: 'POST',
|
|
16
|
+
headers: { 'Content-Type': 'application/json' },
|
|
17
|
+
body: JSON.stringify({ email, password }),
|
|
18
|
+
});
|
|
19
|
+
console.log(`Statut HTTP Inscription : ${regRes.status}`);
|
|
20
|
+
const regData = await regRes.json();
|
|
21
|
+
console.log('Réponse Inscription :', JSON.stringify(regData, null, 2));
|
|
22
|
+
|
|
23
|
+
const devToken = regData.data.access_token;
|
|
24
|
+
if (!devToken) {
|
|
25
|
+
throw new Error("Impossible d'obtenir le token développeur");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
console.log('\n[2] Création de l\'organisation via la Gateway...');
|
|
29
|
+
const orgRes = await fetch(`${API_URL}/v1/control/orgs`, {
|
|
30
|
+
method: 'POST',
|
|
31
|
+
headers: {
|
|
32
|
+
'Authorization': `Bearer ${devToken}`,
|
|
33
|
+
'Content-Type': 'application/json',
|
|
34
|
+
},
|
|
35
|
+
body: JSON.stringify({ name: 'Live Validation Org', slug: `live-org-${runId}` }),
|
|
36
|
+
});
|
|
37
|
+
console.log(`Statut HTTP Org : ${orgRes.status}`);
|
|
38
|
+
const orgData = await orgRes.json();
|
|
39
|
+
console.log('Réponse Org :', JSON.stringify(orgData, null, 2));
|
|
40
|
+
const orgId = orgData.id;
|
|
41
|
+
|
|
42
|
+
console.log('\n[3] Création du projet via la Gateway...');
|
|
43
|
+
const projRes = await fetch(`${API_URL}/v1/control/orgs/${orgId}/projects`, {
|
|
44
|
+
method: 'POST',
|
|
45
|
+
headers: {
|
|
46
|
+
'Authorization': `Bearer ${devToken}`,
|
|
47
|
+
'Content-Type': 'application/json',
|
|
48
|
+
},
|
|
49
|
+
body: JSON.stringify({ name: projectName, engine: 'postgres', region: 'eu-west-1' }),
|
|
50
|
+
});
|
|
51
|
+
console.log(`Statut HTTP Création Projet : ${projRes.status}`);
|
|
52
|
+
const projData = await projRes.json();
|
|
53
|
+
console.log('Réponse Création Projet :', JSON.stringify(projData, null, 2));
|
|
54
|
+
const projectId = projData.id;
|
|
55
|
+
|
|
56
|
+
console.log('\n[4] Attente du provisioning actif du projet via la Gateway...');
|
|
57
|
+
let active = false;
|
|
58
|
+
for (let i = 0; i < 30; i++) {
|
|
59
|
+
const statusRes = await fetch(`${API_URL}/v1/control/projects/${projectId}`, {
|
|
60
|
+
headers: { 'Authorization': `Bearer ${devToken}` },
|
|
61
|
+
});
|
|
62
|
+
const statusData = await statusRes.json();
|
|
63
|
+
console.log(`Vérification ${i+1} : statut = ${statusData.status}`);
|
|
64
|
+
if (statusData && statusData.status === 'active') {
|
|
65
|
+
active = true;
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
69
|
+
}
|
|
70
|
+
if (!active) {
|
|
71
|
+
throw new Error("Le provisioning du projet a expiré");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
console.log('\n[5] Récupération des clés API via la Gateway (avec retry)...');
|
|
75
|
+
let keysData = null;
|
|
76
|
+
for (let i = 0; i < 15; i++) {
|
|
77
|
+
const keysRes = await fetch(`${API_URL}/v1/control/projects/${projectId}/initial-keys`, {
|
|
78
|
+
headers: { 'Authorization': `Bearer ${devToken}` },
|
|
79
|
+
});
|
|
80
|
+
console.log(`Tentative ${i+1} : statut HTTP = ${keysRes.status}`);
|
|
81
|
+
if (keysRes.status === 200) {
|
|
82
|
+
keysData = await keysRes.json();
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
await new Promise((resolve) => setTimeout(resolve, 1500));
|
|
86
|
+
}
|
|
87
|
+
if (!keysData) {
|
|
88
|
+
throw new Error("Impossible de récupérer les clés API initiales (timeout/expiré)");
|
|
89
|
+
}
|
|
90
|
+
console.log('Réponse Clés API :', JSON.stringify(keysData, null, 2));
|
|
91
|
+
const keys = keysData.data || keysData;
|
|
92
|
+
const anonKey = keys.find((k) => k.scope === 'anon').key;
|
|
93
|
+
const serviceKey = keys.find((k) => k.scope === 'service_role').key;
|
|
94
|
+
|
|
95
|
+
console.log('\n[6] Création de la table "live_tasks" via l\'API schéma de la Gateway...');
|
|
96
|
+
const tableDef = {
|
|
97
|
+
name: 'live_tasks',
|
|
98
|
+
columns: [
|
|
99
|
+
{
|
|
100
|
+
name: 'id',
|
|
101
|
+
col_type: 'uuid',
|
|
102
|
+
nullable: false,
|
|
103
|
+
unique: true,
|
|
104
|
+
default_val: 'gen_random_uuid()',
|
|
105
|
+
references: null
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'title',
|
|
109
|
+
col_type: 'text',
|
|
110
|
+
nullable: false,
|
|
111
|
+
unique: false,
|
|
112
|
+
default_val: null,
|
|
113
|
+
references: null
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
name: 'description',
|
|
117
|
+
col_type: 'text',
|
|
118
|
+
nullable: true,
|
|
119
|
+
unique: false,
|
|
120
|
+
default_val: null,
|
|
121
|
+
references: null
|
|
122
|
+
}
|
|
123
|
+
],
|
|
124
|
+
primary_key: 'id',
|
|
125
|
+
indexes: [],
|
|
126
|
+
rls_enabled: true,
|
|
127
|
+
realtime_enabled: true
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const tableRes = await fetch(`${API_URL}/v1/db/${projectId}/schema/tables`, {
|
|
131
|
+
method: 'POST',
|
|
132
|
+
headers: {
|
|
133
|
+
'Authorization': `Bearer ${devToken}`,
|
|
134
|
+
'Content-Type': 'application/json',
|
|
135
|
+
},
|
|
136
|
+
body: JSON.stringify(tableDef),
|
|
137
|
+
});
|
|
138
|
+
console.log(`Statut HTTP Création Table : ${tableRes.status}`);
|
|
139
|
+
const tableData = await tableRes.json();
|
|
140
|
+
console.log('Réponse Création Table :', JSON.stringify(tableData, null, 2));
|
|
141
|
+
|
|
142
|
+
console.log('\n[7] Attente active de la synchronisation PostgREST (Probe loop)...');
|
|
143
|
+
let pgrstReady = false;
|
|
144
|
+
for (let i = 0; i < 20; i++) {
|
|
145
|
+
const probeRes = await fetch(`${API_URL}/v1/db/${projectId}/live_tasks`, {
|
|
146
|
+
headers: { 'apikey': anonKey },
|
|
147
|
+
});
|
|
148
|
+
console.log(`Probe PostgREST ${i+1} : statut HTTP = ${probeRes.status}`);
|
|
149
|
+
if (probeRes.status === 200) {
|
|
150
|
+
pgrstReady = true;
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
await new Promise((resolve) => setTimeout(resolve, 1500));
|
|
154
|
+
}
|
|
155
|
+
if (!pgrstReady) {
|
|
156
|
+
throw new Error("PostgREST n'a pas synchronisé la table live_tasks dans les temps.");
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Petit délai supplémentaire de sécurité pour s'assurer que toutes les instances sont stabilisées
|
|
160
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
161
|
+
|
|
162
|
+
console.log('\n[8] Test d\'écriture (INSERT) à travers la Gateway (avec retry)...');
|
|
163
|
+
let insertData = null;
|
|
164
|
+
let insertStatus = 0;
|
|
165
|
+
for (let i = 0; i < 15; i++) {
|
|
166
|
+
const insertRes = await fetch(`${API_URL}/v1/db/${projectId}/live_tasks`, {
|
|
167
|
+
method: 'POST',
|
|
168
|
+
headers: {
|
|
169
|
+
'apikey': serviceKey,
|
|
170
|
+
'Content-Type': 'application/json',
|
|
171
|
+
'Prefer': 'return=representation'
|
|
172
|
+
},
|
|
173
|
+
body: JSON.stringify({
|
|
174
|
+
title: 'Tâche de production réelle',
|
|
175
|
+
description: 'Ceci est une insertion via la Gateway Aurabase.'
|
|
176
|
+
})
|
|
177
|
+
});
|
|
178
|
+
insertStatus = insertRes.status;
|
|
179
|
+
console.log(`Tentative d'insertion ${i+1} : statut HTTP = ${insertStatus}`);
|
|
180
|
+
if (insertStatus === 201 || insertStatus === 200) {
|
|
181
|
+
insertData = await insertRes.json();
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
185
|
+
}
|
|
186
|
+
if (!insertData) {
|
|
187
|
+
throw new Error(`L'insertion a échoué avec le statut final ${insertStatus}`);
|
|
188
|
+
}
|
|
189
|
+
console.log('Réponse Insertion :', JSON.stringify(insertData, null, 2));
|
|
190
|
+
|
|
191
|
+
console.log('\n[9] Test de lecture (SELECT) à travers la Gateway...');
|
|
192
|
+
const selectRes = await fetch(`${API_URL}/v1/db/${projectId}/live_tasks`, {
|
|
193
|
+
headers: { 'apikey': serviceKey }
|
|
194
|
+
});
|
|
195
|
+
console.log(`Statut HTTP Sélection : ${selectRes.status}`);
|
|
196
|
+
const selectData = await selectRes.json();
|
|
197
|
+
console.log('Réponse Sélection :', JSON.stringify(selectData, null, 2));
|
|
198
|
+
|
|
199
|
+
console.log('\n[10] Test de l\'API d\'observabilité (db-stats) via la Gateway...');
|
|
200
|
+
const statsRes = await fetch(`${API_URL}/v1/db/${projectId}/observability/db-stats`, {
|
|
201
|
+
headers: { 'Authorization': `Bearer ${devToken}` }
|
|
202
|
+
});
|
|
203
|
+
console.log(`Statut HTTP Métriques DB : ${statsRes.status}`);
|
|
204
|
+
const statsData = await statsRes.json();
|
|
205
|
+
console.log('Réponse Métriques DB :', JSON.stringify(statsData, null, 2));
|
|
206
|
+
|
|
207
|
+
console.log('\n[11] Lancement d\'un backup SQL en direct via la Gateway...');
|
|
208
|
+
const backupRes = await fetch(`${API_URL}/v1/db/${projectId}/backups`, {
|
|
209
|
+
method: 'POST',
|
|
210
|
+
headers: {
|
|
211
|
+
'Authorization': `Bearer ${devToken}`,
|
|
212
|
+
'Content-Type': 'application/json',
|
|
213
|
+
},
|
|
214
|
+
body: JSON.stringify({ label: `live_backup_${runId}` })
|
|
215
|
+
});
|
|
216
|
+
console.log(`Statut HTTP Backup : ${backupRes.status}`);
|
|
217
|
+
const backupData = await backupRes.json();
|
|
218
|
+
console.log('Réponse Backup :', JSON.stringify(backupData, null, 2));
|
|
219
|
+
const backupId = backupData.data.id;
|
|
220
|
+
|
|
221
|
+
console.log('\n[12] Liste des backups via la Gateway...');
|
|
222
|
+
const listRes = await fetch(`${API_URL}/v1/db/${projectId}/backups`, {
|
|
223
|
+
headers: { 'Authorization': `Bearer ${devToken}` }
|
|
224
|
+
});
|
|
225
|
+
console.log(`Statut HTTP Liste Backups : ${listRes.status}`);
|
|
226
|
+
const listData = await listRes.json();
|
|
227
|
+
console.log('Réponse Liste Backups (extraits) :', JSON.stringify(listData.data.slice(0, 3), null, 2));
|
|
228
|
+
|
|
229
|
+
console.log('\n[13] Nettoyage en cours via la Gateway (Suppression du projet)...');
|
|
230
|
+
const delRes = await fetch(`${API_URL}/v1/control/projects/${projectId}`, {
|
|
231
|
+
method: 'DELETE',
|
|
232
|
+
headers: { 'Authorization': `Bearer ${devToken}` },
|
|
233
|
+
});
|
|
234
|
+
console.log(`Statut HTTP Suppression Projet : ${delRes.status}`);
|
|
235
|
+
|
|
236
|
+
console.log('\n VALIDATION DE PRODUCTION UNIFIÉE TERMINÉE AVEC SUCCÈS !');
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
run().catch((err) => {
|
|
240
|
+
console.error('Erreur lors de la validation :', err);
|
|
241
|
+
});
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import { createRequire } from 'module';
|
|
2
|
+
const require = createRequire(import.meta.url);
|
|
3
|
+
|
|
4
|
+
import { createClient } from '../dist/index.js';
|
|
5
|
+
|
|
6
|
+
const GATEWAY_URL = 'http://localhost:8080';
|
|
7
|
+
const MGMT_URL = 'http://localhost:8090';
|
|
8
|
+
|
|
9
|
+
async function run() {
|
|
10
|
+
const runId = Math.random().toString(36).substring(2, 10);
|
|
11
|
+
const email = `live-sdk-${runId}@aurabase.dev`;
|
|
12
|
+
const password = 'LiveSecurePassword123!';
|
|
13
|
+
const projectName = `live-sdk-project-${runId}`;
|
|
14
|
+
|
|
15
|
+
console.log(`[1] Inscription d'un nouveau compte développeur : ${email}`);
|
|
16
|
+
const regRes = await fetch(`${MGMT_URL}/v1/control/accounts/register`, {
|
|
17
|
+
method: 'POST',
|
|
18
|
+
headers: { 'Content-Type': 'application/json' },
|
|
19
|
+
body: JSON.stringify({ email, password }),
|
|
20
|
+
});
|
|
21
|
+
console.log(`Statut HTTP Inscription : ${regRes.status}`);
|
|
22
|
+
const regData = await regRes.json();
|
|
23
|
+
console.log('Réponse Inscription :', JSON.stringify(regData, null, 2));
|
|
24
|
+
|
|
25
|
+
const devToken = regData.data.access_token;
|
|
26
|
+
if (!devToken) {
|
|
27
|
+
throw new Error("Impossible d'obtenir le token développeur");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
console.log('\n[2] Création d\'une organisation...');
|
|
31
|
+
const orgRes = await fetch(`${MGMT_URL}/v1/control/orgs`, {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: {
|
|
34
|
+
'Authorization': `Bearer ${devToken}`,
|
|
35
|
+
'Content-Type': 'application/json',
|
|
36
|
+
},
|
|
37
|
+
body: JSON.stringify({ name: 'Live SDK Validation Org', slug: `live-sdk-org-${runId}` }),
|
|
38
|
+
});
|
|
39
|
+
console.log(`Statut HTTP Org : ${orgRes.status}`);
|
|
40
|
+
const orgData = await orgRes.json();
|
|
41
|
+
console.log('Réponse Org :', JSON.stringify(orgData, null, 2));
|
|
42
|
+
const orgId = orgData.id;
|
|
43
|
+
|
|
44
|
+
console.log('\n[3] Création d\'un projet PostgreSQL dataplane...');
|
|
45
|
+
const projRes = await fetch(`${MGMT_URL}/v1/control/orgs/${orgId}/projects`, {
|
|
46
|
+
method: 'POST',
|
|
47
|
+
headers: {
|
|
48
|
+
'Authorization': `Bearer ${devToken}`,
|
|
49
|
+
'Content-Type': 'application/json',
|
|
50
|
+
},
|
|
51
|
+
body: JSON.stringify({ name: projectName, engine: 'postgres', region: 'eu-west-1' }),
|
|
52
|
+
});
|
|
53
|
+
console.log(`Statut HTTP Création Projet : ${projRes.status}`);
|
|
54
|
+
const projData = await projRes.json();
|
|
55
|
+
console.log('Réponse Création Projet :', JSON.stringify(projData, null, 2));
|
|
56
|
+
const projectId = projData.id;
|
|
57
|
+
|
|
58
|
+
console.log('\n[4] Attente du provisioning actif du projet...');
|
|
59
|
+
let active = false;
|
|
60
|
+
for (let i = 0; i < 30; i++) {
|
|
61
|
+
const statusRes = await fetch(`${MGMT_URL}/v1/control/projects/${projectId}`, {
|
|
62
|
+
headers: { 'Authorization': `Bearer ${devToken}` },
|
|
63
|
+
});
|
|
64
|
+
const statusData = await statusRes.json();
|
|
65
|
+
console.log(`Vérification ${i+1} : statut = ${statusData.status}`);
|
|
66
|
+
if (statusData && statusData.status === 'active') {
|
|
67
|
+
active = true;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
71
|
+
}
|
|
72
|
+
if (!active) {
|
|
73
|
+
throw new Error("Le provisioning du projet a expiré");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
console.log('\n[5] Récupération des clés API (anon et service_role)...');
|
|
77
|
+
let keysRes = null;
|
|
78
|
+
for (let i = 0; i < 15; i++) {
|
|
79
|
+
keysRes = await fetch(`${MGMT_URL}/v1/control/projects/${projectId}/initial-keys`, {
|
|
80
|
+
headers: { 'Authorization': `Bearer ${devToken}` },
|
|
81
|
+
});
|
|
82
|
+
if (keysRes.status === 200) {
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
86
|
+
}
|
|
87
|
+
if (!keysRes || keysRes.status !== 200) {
|
|
88
|
+
throw new Error("Impossible d'obtenir les clés API");
|
|
89
|
+
}
|
|
90
|
+
const keysData = await keysRes.json();
|
|
91
|
+
console.log('Réponse Clés API :', JSON.stringify(keysData, null, 2));
|
|
92
|
+
const keys = keysData.data || keysData;
|
|
93
|
+
const anonKey = keys.find((k) => k.scope === 'anon').key;
|
|
94
|
+
const serviceKey = keys.find((k) => k.scope === 'service_role').key;
|
|
95
|
+
|
|
96
|
+
console.log('\n[6] Création de la table "live_tasks" via l\'API schéma d\'administration...');
|
|
97
|
+
const tableDef = {
|
|
98
|
+
name: 'live_tasks',
|
|
99
|
+
columns: [
|
|
100
|
+
{
|
|
101
|
+
name: 'id',
|
|
102
|
+
col_type: 'uuid',
|
|
103
|
+
nullable: false,
|
|
104
|
+
unique: true,
|
|
105
|
+
default_val: 'gen_random_uuid()',
|
|
106
|
+
references: null
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: 'title',
|
|
110
|
+
col_type: 'text',
|
|
111
|
+
nullable: false,
|
|
112
|
+
unique: false,
|
|
113
|
+
default_val: null,
|
|
114
|
+
references: null
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: 'description',
|
|
118
|
+
col_type: 'text',
|
|
119
|
+
nullable: true,
|
|
120
|
+
unique: false,
|
|
121
|
+
default_val: null,
|
|
122
|
+
references: null
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
name: 'owner_id',
|
|
126
|
+
col_type: 'text',
|
|
127
|
+
nullable: false,
|
|
128
|
+
unique: false,
|
|
129
|
+
default_val: null,
|
|
130
|
+
references: null
|
|
131
|
+
}
|
|
132
|
+
],
|
|
133
|
+
primary_key: 'id',
|
|
134
|
+
indexes: [],
|
|
135
|
+
rls_enabled: true,
|
|
136
|
+
realtime_enabled: true
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const tableRes = await fetch(`${MGMT_URL}/v1/db/${projectId}/schema/tables`, {
|
|
140
|
+
method: 'POST',
|
|
141
|
+
headers: {
|
|
142
|
+
'Authorization': `Bearer ${devToken}`,
|
|
143
|
+
'Content-Type': 'application/json',
|
|
144
|
+
},
|
|
145
|
+
body: JSON.stringify(tableDef),
|
|
146
|
+
});
|
|
147
|
+
console.log(`Statut HTTP Création Table : ${tableRes.status}`);
|
|
148
|
+
const tableData = await tableRes.json();
|
|
149
|
+
console.log('Réponse Création Table :', JSON.stringify(tableData, null, 2));
|
|
150
|
+
|
|
151
|
+
console.log('\n[7] Création d\'une policy RLS (propriétaire uniquement)...');
|
|
152
|
+
const policyDef = {
|
|
153
|
+
name: 'live_tasks_owner_policy',
|
|
154
|
+
table: 'live_tasks',
|
|
155
|
+
command: 'ALL',
|
|
156
|
+
using_expr: 'auth.uid()::text = owner_id',
|
|
157
|
+
check_expr: 'auth.uid()::text = owner_id'
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const policyRes = await fetch(`${MGMT_URL}/v1/db/${projectId}/policies`, {
|
|
161
|
+
method: 'POST',
|
|
162
|
+
headers: {
|
|
163
|
+
'Authorization': `Bearer ${devToken}`,
|
|
164
|
+
'Content-Type': 'application/json',
|
|
165
|
+
},
|
|
166
|
+
body: JSON.stringify(policyDef),
|
|
167
|
+
});
|
|
168
|
+
console.log(`Statut HTTP Création Policy : ${policyRes.status}`);
|
|
169
|
+
|
|
170
|
+
console.log('\n[8] Attente active de la synchronisation PostgREST (Probe loop)...');
|
|
171
|
+
let ready = false;
|
|
172
|
+
for (let i = 0; i < 20; i++) {
|
|
173
|
+
const probeRes = await fetch(`${GATEWAY_URL}/v1/db/${projectId}/live_tasks`, {
|
|
174
|
+
headers: { 'apikey': anonKey },
|
|
175
|
+
});
|
|
176
|
+
console.log(`Probe PostgREST ${i+1} : statut = ${probeRes.status}`);
|
|
177
|
+
if (probeRes.status === 200) {
|
|
178
|
+
ready = true;
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
182
|
+
}
|
|
183
|
+
if (!ready) {
|
|
184
|
+
throw new Error("PostgREST n'a pas réussi à synchroniser la table");
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// ─── INITIALISATION DU SDK CLIENT ───
|
|
188
|
+
console.log('\n[9] Initialisation du client SDK (AuraClient)...');
|
|
189
|
+
const clientA = createClient(GATEWAY_URL, projectId, anonKey, {
|
|
190
|
+
auth: { persistSession: false }
|
|
191
|
+
});
|
|
192
|
+
const clientB = createClient(GATEWAY_URL, projectId, anonKey, {
|
|
193
|
+
auth: { persistSession: false }
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const userAEmail = `usera-${runId}@example.com`;
|
|
197
|
+
const userAPassword = 'UserAPassword123!';
|
|
198
|
+
const userBEmail = `userb-${runId}@example.com`;
|
|
199
|
+
const userBPassword = 'UserBPassword123!';
|
|
200
|
+
|
|
201
|
+
console.log(`\n[10] Inscription de User A (${userAEmail}) et User B (${userBEmail}) via le SDK...`);
|
|
202
|
+
const signUpARes = await clientA.auth.signUp({ email: userAEmail, password: userAPassword });
|
|
203
|
+
if (signUpARes.error) throw new Error(`SignUp A échoué : ${signUpARes.error.message}`);
|
|
204
|
+
const userA = signUpARes.data.user;
|
|
205
|
+
console.log('User A inscrit :', userA.id);
|
|
206
|
+
|
|
207
|
+
const signUpBRes = await clientB.auth.signUp({ email: userBEmail, password: userBPassword });
|
|
208
|
+
if (signUpBRes.error) throw new Error(`SignUp B échoué : ${signUpBRes.error.message}`);
|
|
209
|
+
const userB = signUpBRes.data.user;
|
|
210
|
+
console.log('User B inscrit :', userB.id);
|
|
211
|
+
|
|
212
|
+
console.log('\n[11] Connexion de User A et User B via le SDK...');
|
|
213
|
+
const signInARes = await clientA.auth.signInWithPassword({ email: userAEmail, password: userAPassword });
|
|
214
|
+
if (signInARes.error) throw new Error(`SignIn A échoué : ${signInARes.error.message}`);
|
|
215
|
+
console.log('User A connecté.');
|
|
216
|
+
|
|
217
|
+
const signInBRes = await clientB.auth.signInWithPassword({ email: userBEmail, password: userBPassword });
|
|
218
|
+
if (signInBRes.error) throw new Error(`SignIn B échoué : ${signInBRes.error.message}`);
|
|
219
|
+
console.log('User B connecté.');
|
|
220
|
+
|
|
221
|
+
console.log('\n[12] Insertion d\'une ligne via le SDK par User A...');
|
|
222
|
+
const insertARes = await clientA.db.from('live_tasks').insert({
|
|
223
|
+
title: 'Tâche de User A',
|
|
224
|
+
description: 'Ceci est ma tâche privée.',
|
|
225
|
+
owner_id: userA.id
|
|
226
|
+
});
|
|
227
|
+
if (insertARes.error) {
|
|
228
|
+
console.error('Détails de l\'erreur d\'insertion :', JSON.stringify(insertARes.error, null, 2));
|
|
229
|
+
throw new Error(`Insertion A échouée : ${insertARes.error.message}`);
|
|
230
|
+
}
|
|
231
|
+
console.log('Insertion A réussie :', JSON.stringify(insertARes.data, null, 2));
|
|
232
|
+
|
|
233
|
+
console.log('\n[13] Lecture (SELECT) par User A via le SDK...');
|
|
234
|
+
const selectARes = await clientA.db.from('live_tasks').select('*');
|
|
235
|
+
if (selectARes.error) throw new Error(`Sélection A échouée : ${selectARes.error.message}`);
|
|
236
|
+
console.log('Résultats pour User A :', JSON.stringify(selectARes.data, null, 2));
|
|
237
|
+
if (!selectARes.data || selectARes.data.length === 0) {
|
|
238
|
+
throw new Error("User A n'arrive pas à lire sa propre tâche");
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
console.log('\n[14] Test d\'isolation RLS : Tentative de lecture (SELECT) par User B via le SDK...');
|
|
242
|
+
const selectBRes = await clientB.db.from('live_tasks').select('*');
|
|
243
|
+
if (selectBRes.error) throw new Error(`Sélection B échouée : ${selectBRes.error.message}`);
|
|
244
|
+
console.log('Résultats pour User B (doivent être vides en raison de la RLS) :', JSON.stringify(selectBRes.data, null, 2));
|
|
245
|
+
if (selectBRes.data && selectBRes.data.length > 0) {
|
|
246
|
+
throw new Error("CRITIQUE : Faille d'isolation RLS ! User B peut lire les tâches de User A !");
|
|
247
|
+
}
|
|
248
|
+
console.log("-> Isolation RLS vérifiée avec succès !");
|
|
249
|
+
|
|
250
|
+
console.log('\n[15] Test de l\'API d\'observabilité (db-stats)...');
|
|
251
|
+
const statsRes = await fetch(`${MGMT_URL}/v1/db/${projectId}/observability/db-stats`, {
|
|
252
|
+
headers: { 'Authorization': `Bearer ${devToken}` }
|
|
253
|
+
});
|
|
254
|
+
console.log(`Statut HTTP Métriques DB : ${statsRes.status}`);
|
|
255
|
+
const statsData = await statsRes.status === 200 ? await statsRes.json() : null;
|
|
256
|
+
console.log('Réponse Métriques DB :', JSON.stringify(statsData, null, 2));
|
|
257
|
+
|
|
258
|
+
console.log('\n[16] Lancement d\'un backup SQL en direct...');
|
|
259
|
+
const backupRes = await fetch(`${MGMT_URL}/v1/db/${projectId}/backups`, {
|
|
260
|
+
method: 'POST',
|
|
261
|
+
headers: {
|
|
262
|
+
'Authorization': `Bearer ${devToken}`,
|
|
263
|
+
'Content-Type': 'application/json',
|
|
264
|
+
},
|
|
265
|
+
body: JSON.stringify({ label: `live_backup_${runId}` })
|
|
266
|
+
});
|
|
267
|
+
console.log(`Statut HTTP Backup : ${backupRes.status}`);
|
|
268
|
+
const backupData = await backupRes.json();
|
|
269
|
+
console.log('Réponse Backup :', JSON.stringify(backupData, null, 2));
|
|
270
|
+
const backupId = backupData.data.id;
|
|
271
|
+
|
|
272
|
+
console.log('\n[17] Liste des backups...');
|
|
273
|
+
const listRes = await fetch(`${MGMT_URL}/v1/db/${projectId}/backups`, {
|
|
274
|
+
headers: { 'Authorization': `Bearer ${devToken}` }
|
|
275
|
+
});
|
|
276
|
+
console.log(`Statut HTTP Liste Backups : ${listRes.status}`);
|
|
277
|
+
const listData = await listRes.json();
|
|
278
|
+
console.log('Réponse Liste Backups (extraits) :', JSON.stringify(listData.data.slice(0, 3), null, 2));
|
|
279
|
+
|
|
280
|
+
console.log('\n[18] Nettoyage en cours (Suppression du projet)...');
|
|
281
|
+
const delRes = await fetch(`${MGMT_URL}/v1/control/projects/${projectId}`, {
|
|
282
|
+
method: 'DELETE',
|
|
283
|
+
headers: { 'Authorization': `Bearer ${devToken}` },
|
|
284
|
+
});
|
|
285
|
+
console.log(`Statut HTTP Suppression Projet : ${delRes.status}`);
|
|
286
|
+
|
|
287
|
+
console.log('\n VALIDATION DE PRODUCTION VIA LE SDK TERMINÉE AVEC SUCCÈS !');
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
run().catch((err) => {
|
|
291
|
+
console.error('Erreur critique lors de la validation :', err);
|
|
292
|
+
process.exit(1);
|
|
293
|
+
});
|
|
@@ -0,0 +1,139 @@
|
|
|
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 '@aurabase/core'
|
|
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
|
+
}
|