@aurabase/aurabase-js 0.5.3 → 0.5.4
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/dist/{AuraClient-K3hRdh9J.d.cts → AuraClient-5jDiXjrO.d.cts} +1 -1
- package/dist/{AuraClient-K3hRdh9J.d.ts → AuraClient-5jDiXjrO.d.ts} +1 -1
- package/dist/index.cjs +6 -3
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -3
- package/dist/nextjs.cjs +389 -0
- package/dist/nextjs.d.cts +126 -0
- package/dist/nextjs.d.ts +126 -0
- package/dist/nextjs.js +383 -0
- package/dist/react.cjs +150 -0
- package/dist/react.d.cts +82 -0
- package/dist/react.d.ts +82 -0
- package/dist/react.js +143 -0
- package/dist/ssr.cjs +6 -3
- package/dist/ssr.d.cts +1 -1
- package/dist/ssr.d.ts +1 -1
- package/dist/ssr.js +6 -3
- package/package.json +29 -9
|
@@ -93,7 +93,7 @@ declare class AuraClient<Database = any, Schema extends GenericSchema = Database
|
|
|
93
93
|
* const { data, error } = await aura.rpc('echo_test', { message: 'hello' })
|
|
94
94
|
* ```
|
|
95
95
|
*/
|
|
96
|
-
rpc<
|
|
96
|
+
rpc<FnName extends string = string, Args extends Record<string, unknown> = Record<string, unknown>>(fn: FnName, args?: Args, options?: Parameters<DatabaseService<Database, Schema>['rpc']>[2]): ReturnType<DatabaseService<Database, Schema>['rpc']>;
|
|
97
97
|
/**
|
|
98
98
|
* Shortcut: create a realtime channel with Supabase-compatible API.
|
|
99
99
|
* Equivalent to `aura.realtime.channel(name)`.
|
|
@@ -93,7 +93,7 @@ declare class AuraClient<Database = any, Schema extends GenericSchema = Database
|
|
|
93
93
|
* const { data, error } = await aura.rpc('echo_test', { message: 'hello' })
|
|
94
94
|
* ```
|
|
95
95
|
*/
|
|
96
|
-
rpc<
|
|
96
|
+
rpc<FnName extends string = string, Args extends Record<string, unknown> = Record<string, unknown>>(fn: FnName, args?: Args, options?: Parameters<DatabaseService<Database, Schema>['rpc']>[2]): ReturnType<DatabaseService<Database, Schema>['rpc']>;
|
|
97
97
|
/**
|
|
98
98
|
* Shortcut: create a realtime channel with Supabase-compatible API.
|
|
99
99
|
* Equivalent to `aura.realtime.channel(name)`.
|
package/dist/index.cjs
CHANGED
|
@@ -63,6 +63,11 @@ var AuraClient = class {
|
|
|
63
63
|
"[aurabase] No API key provided. Most operations require an API key (apikey header). Only public auth routes (register, login, refresh) will work without one."
|
|
64
64
|
);
|
|
65
65
|
}
|
|
66
|
+
if (typeof console !== "undefined" && /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?\/?$/.test(this.baseUrl)) {
|
|
67
|
+
console.warn(
|
|
68
|
+
"[aurabase] Attention : en local, l'URL du projet doit inclure le sous-domaine (ex: http://<slug>.localhost:8080) pour permettre la r\xE9solution automatique du projet par la passerelle."
|
|
69
|
+
);
|
|
70
|
+
}
|
|
66
71
|
if (this.apiKey?.startsWith(SERVICE_ROLE_KEY_PREFIX) && isBrowserContext()) {
|
|
67
72
|
const refuse = resolvedOptions?.refuseServiceRoleInBrowser ?? true;
|
|
68
73
|
const message = "[aurabase] S\xC9CURIT\xC9 : une cl\xE9 service_role (aura_sk_\u2026) est fournie \xE0 createClient() dans un contexte navigateur. Cette cl\xE9 \xE0 privil\xE8ges \xE9lev\xE9s NE DOIT JAMAIS \xEAtre expos\xE9e c\xF4t\xE9 client (elle fuiterait dans le bundle). Utilisez une cl\xE9 anon (aura_anon_\u2026) c\xF4t\xE9 client, et createAdminClient() c\xF4t\xE9 serveur pour les op\xE9rations d'administration.";
|
|
@@ -80,7 +85,7 @@ var AuraClient = class {
|
|
|
80
85
|
const g = globalThis;
|
|
81
86
|
const proc = g?.process;
|
|
82
87
|
const isTest = !!(proc?.env?.VITEST || proc?.env?.NODE_ENV === "test" || proc?.env?.JEST_WORKER_ID);
|
|
83
|
-
return isTest && g?.localStorage && typeof g.localStorage.getItem === "function";
|
|
88
|
+
return isTest && !!g?.localStorage && typeof g.localStorage.getItem === "function";
|
|
84
89
|
})()) {
|
|
85
90
|
this.authStore = new core.LocalAuthStore(`aura-${core.clientScope(this.baseUrl)}-auth`);
|
|
86
91
|
} else {
|
|
@@ -158,7 +163,6 @@ var AuraClient = class {
|
|
|
158
163
|
if (!this._notifications) this._notifications = new notifications.NotificationsService(this);
|
|
159
164
|
return this._notifications;
|
|
160
165
|
}
|
|
161
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
162
166
|
from(table) {
|
|
163
167
|
return this.db.from(table);
|
|
164
168
|
}
|
|
@@ -171,7 +175,6 @@ var AuraClient = class {
|
|
|
171
175
|
* const { data, error } = await aura.rpc('echo_test', { message: 'hello' })
|
|
172
176
|
* ```
|
|
173
177
|
*/
|
|
174
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
175
178
|
rpc(fn, args, options) {
|
|
176
179
|
return this.db.rpc(fn, args, options);
|
|
177
180
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -7,7 +7,7 @@ export { FunctionsService } from '@aurabase/functions';
|
|
|
7
7
|
export { NotificationsAdminService, NotificationsService } from '@aurabase/notifications';
|
|
8
8
|
export { AuraChannel, RealtimeService } from '@aurabase/realtime';
|
|
9
9
|
export { StorageBucketClient, StorageService } from '@aurabase/storage';
|
|
10
|
-
import { A as AuraClient } from './AuraClient-
|
|
10
|
+
import { A as AuraClient } from './AuraClient-5jDiXjrO.cjs';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Create a new Aurabase client instance.
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { FunctionsService } from '@aurabase/functions';
|
|
|
7
7
|
export { NotificationsAdminService, NotificationsService } from '@aurabase/notifications';
|
|
8
8
|
export { AuraChannel, RealtimeService } from '@aurabase/realtime';
|
|
9
9
|
export { StorageBucketClient, StorageService } from '@aurabase/storage';
|
|
10
|
-
import { A as AuraClient } from './AuraClient-
|
|
10
|
+
import { A as AuraClient } from './AuraClient-5jDiXjrO.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Create a new Aurabase client instance.
|
package/dist/index.js
CHANGED
|
@@ -69,6 +69,11 @@ var AuraClient = class {
|
|
|
69
69
|
"[aurabase] No API key provided. Most operations require an API key (apikey header). Only public auth routes (register, login, refresh) will work without one."
|
|
70
70
|
);
|
|
71
71
|
}
|
|
72
|
+
if (typeof console !== "undefined" && /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?\/?$/.test(this.baseUrl)) {
|
|
73
|
+
console.warn(
|
|
74
|
+
"[aurabase] Attention : en local, l'URL du projet doit inclure le sous-domaine (ex: http://<slug>.localhost:8080) pour permettre la r\xE9solution automatique du projet par la passerelle."
|
|
75
|
+
);
|
|
76
|
+
}
|
|
72
77
|
if (this.apiKey?.startsWith(SERVICE_ROLE_KEY_PREFIX) && isBrowserContext()) {
|
|
73
78
|
const refuse = resolvedOptions?.refuseServiceRoleInBrowser ?? true;
|
|
74
79
|
const message = "[aurabase] S\xC9CURIT\xC9 : une cl\xE9 service_role (aura_sk_\u2026) est fournie \xE0 createClient() dans un contexte navigateur. Cette cl\xE9 \xE0 privil\xE8ges \xE9lev\xE9s NE DOIT JAMAIS \xEAtre expos\xE9e c\xF4t\xE9 client (elle fuiterait dans le bundle). Utilisez une cl\xE9 anon (aura_anon_\u2026) c\xF4t\xE9 client, et createAdminClient() c\xF4t\xE9 serveur pour les op\xE9rations d'administration.";
|
|
@@ -86,7 +91,7 @@ var AuraClient = class {
|
|
|
86
91
|
const g = globalThis;
|
|
87
92
|
const proc = g?.process;
|
|
88
93
|
const isTest = !!(proc?.env?.VITEST || proc?.env?.NODE_ENV === "test" || proc?.env?.JEST_WORKER_ID);
|
|
89
|
-
return isTest && g?.localStorage && typeof g.localStorage.getItem === "function";
|
|
94
|
+
return isTest && !!g?.localStorage && typeof g.localStorage.getItem === "function";
|
|
90
95
|
})()) {
|
|
91
96
|
this.authStore = new LocalAuthStore(`aura-${clientScope(this.baseUrl)}-auth`);
|
|
92
97
|
} else {
|
|
@@ -164,7 +169,6 @@ var AuraClient = class {
|
|
|
164
169
|
if (!this._notifications) this._notifications = new NotificationsService(this);
|
|
165
170
|
return this._notifications;
|
|
166
171
|
}
|
|
167
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
168
172
|
from(table) {
|
|
169
173
|
return this.db.from(table);
|
|
170
174
|
}
|
|
@@ -177,7 +181,6 @@ var AuraClient = class {
|
|
|
177
181
|
* const { data, error } = await aura.rpc('echo_test', { message: 'hello' })
|
|
178
182
|
* ```
|
|
179
183
|
*/
|
|
180
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
181
184
|
rpc(fn, args, options) {
|
|
182
185
|
return this.db.rpc(fn, args, options);
|
|
183
186
|
}
|
package/dist/nextjs.cjs
ADDED
|
@@ -0,0 +1,389 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var core = require('@aurabase/core');
|
|
4
|
+
var ai = require('@aurabase/ai');
|
|
5
|
+
var auth$1 = require('@aurabase/auth');
|
|
6
|
+
var db = require('@aurabase/db');
|
|
7
|
+
var functions = require('@aurabase/functions');
|
|
8
|
+
var notifications = require('@aurabase/notifications');
|
|
9
|
+
var realtime = require('@aurabase/realtime');
|
|
10
|
+
var storage = require('@aurabase/storage');
|
|
11
|
+
|
|
12
|
+
// src/ssr.ts
|
|
13
|
+
function isBrowserContext() {
|
|
14
|
+
if (typeof window !== "undefined") return true;
|
|
15
|
+
const g = globalThis;
|
|
16
|
+
if (typeof g.DedicatedWorkerGlobalScope !== "undefined") return true;
|
|
17
|
+
if (typeof g.SharedWorkerGlobalScope !== "undefined") return true;
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
var SERVICE_ROLE_KEY_PREFIX = "aura_sk_";
|
|
21
|
+
var AuraClient = class {
|
|
22
|
+
/** URL du projet (`https://<slug>.aurabase.cloud`), sans barre finale. */
|
|
23
|
+
baseUrl;
|
|
24
|
+
apiKey;
|
|
25
|
+
fetchFn;
|
|
26
|
+
authStore;
|
|
27
|
+
retryConfig;
|
|
28
|
+
/** Timeout par défaut (ms) des requêtes JSON sans signal. `undefined` → défaut core (30s). */
|
|
29
|
+
requestTimeoutMs;
|
|
30
|
+
/** Hook d'observabilité (LOT 3) — voir `AuraClientOptions.onEvent`. */
|
|
31
|
+
onEvent;
|
|
32
|
+
/** Journalise chaque `AuraObservabilityEvent` via `console.debug` — voir `AuraClientOptions.debug`. */
|
|
33
|
+
debug;
|
|
34
|
+
// Lazy-initialised service instances
|
|
35
|
+
_auth = null;
|
|
36
|
+
_db = null;
|
|
37
|
+
_storage = null;
|
|
38
|
+
_realtime = null;
|
|
39
|
+
_functions = null;
|
|
40
|
+
_ai = null;
|
|
41
|
+
_notifications = null;
|
|
42
|
+
_authAdmin = null;
|
|
43
|
+
_disposed = false;
|
|
44
|
+
_persistSession;
|
|
45
|
+
_autoRefresh;
|
|
46
|
+
_detectSessionInUrl;
|
|
47
|
+
/**
|
|
48
|
+
* @param baseUrl URL du projet (`https://<slug>.aurabase.cloud`).
|
|
49
|
+
* @param apiKey Clé API du projet (`aura_anon_…`, `aura_auth_…`, `aura_sk_…`).
|
|
50
|
+
*/
|
|
51
|
+
constructor(baseUrl, apiKey, options) {
|
|
52
|
+
this.baseUrl = baseUrl.replace(/\/+$/, "");
|
|
53
|
+
const resolvedOptions = options;
|
|
54
|
+
this.apiKey = apiKey || null;
|
|
55
|
+
this.fetchFn = resolvedOptions?.fetch ?? globalThis.fetch.bind(globalThis);
|
|
56
|
+
const r = resolvedOptions?.retry;
|
|
57
|
+
this.retryConfig = r === false ? { enabled: false, maxRetries: 0 } : r === void 0 || r === true ? { enabled: true, maxRetries: core.DEFAULT_MAX_RETRIES } : { enabled: r.enabled ?? true, maxRetries: r.maxRetries ?? core.DEFAULT_MAX_RETRIES };
|
|
58
|
+
this.requestTimeoutMs = resolvedOptions?.requestTimeoutMs;
|
|
59
|
+
this.onEvent = resolvedOptions?.onEvent;
|
|
60
|
+
this.debug = resolvedOptions?.debug;
|
|
61
|
+
if (!this.apiKey && typeof console !== "undefined") {
|
|
62
|
+
console.warn(
|
|
63
|
+
"[aurabase] No API key provided. Most operations require an API key (apikey header). Only public auth routes (register, login, refresh) will work without one."
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
if (typeof console !== "undefined" && /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?\/?$/.test(this.baseUrl)) {
|
|
67
|
+
console.warn(
|
|
68
|
+
"[aurabase] Attention : en local, l'URL du projet doit inclure le sous-domaine (ex: http://<slug>.localhost:8080) pour permettre la r\xE9solution automatique du projet par la passerelle."
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
if (this.apiKey?.startsWith(SERVICE_ROLE_KEY_PREFIX) && isBrowserContext()) {
|
|
72
|
+
const refuse = resolvedOptions?.refuseServiceRoleInBrowser ?? true;
|
|
73
|
+
const message = "[aurabase] S\xC9CURIT\xC9 : une cl\xE9 service_role (aura_sk_\u2026) est fournie \xE0 createClient() dans un contexte navigateur. Cette cl\xE9 \xE0 privil\xE8ges \xE9lev\xE9s NE DOIT JAMAIS \xEAtre expos\xE9e c\xF4t\xE9 client (elle fuiterait dans le bundle). Utilisez une cl\xE9 anon (aura_anon_\u2026) c\xF4t\xE9 client, et createAdminClient() c\xF4t\xE9 serveur pour les op\xE9rations d'administration.";
|
|
74
|
+
if (refuse) {
|
|
75
|
+
throw new Error(message);
|
|
76
|
+
} else if (typeof console !== "undefined") {
|
|
77
|
+
console.warn(message);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (resolvedOptions?.auth?.storage) {
|
|
81
|
+
this.authStore = resolvedOptions.auth.storage;
|
|
82
|
+
} else if (resolvedOptions?.auth?.persistSession === false) {
|
|
83
|
+
this.authStore = new core.BaseAuthStore();
|
|
84
|
+
} else if (isBrowserContext() && typeof window.localStorage !== "undefined" || typeof globalThis !== "undefined" && (() => {
|
|
85
|
+
const g = globalThis;
|
|
86
|
+
const proc = g?.process;
|
|
87
|
+
const isTest = !!(proc?.env?.VITEST || proc?.env?.NODE_ENV === "test" || proc?.env?.JEST_WORKER_ID);
|
|
88
|
+
return isTest && !!g?.localStorage && typeof g.localStorage.getItem === "function";
|
|
89
|
+
})()) {
|
|
90
|
+
this.authStore = new core.LocalAuthStore(`aura-${core.clientScope(this.baseUrl)}-auth`);
|
|
91
|
+
} else {
|
|
92
|
+
this.authStore = new core.BaseAuthStore();
|
|
93
|
+
}
|
|
94
|
+
this.authStore.setObservabilityHook(this.onEvent, this.debug);
|
|
95
|
+
this._persistSession = resolvedOptions?.auth?.persistSession !== false;
|
|
96
|
+
this._autoRefresh = resolvedOptions?.auth?.autoRefresh ?? true;
|
|
97
|
+
this._detectSessionInUrl = resolvedOptions?.auth?.detectSessionInUrl;
|
|
98
|
+
if (this._autoRefresh && this._persistSession && typeof window !== "undefined") {
|
|
99
|
+
void this.auth;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Démonte le client : arrête le refresh proactif (ticker + visibilité + BroadcastChannel),
|
|
104
|
+
* déconnecte le realtime, vide les listeners d'auth. Idempotent. À appeler en teardown
|
|
105
|
+
* (React Strict Mode / HMR / tests).
|
|
106
|
+
*/
|
|
107
|
+
dispose() {
|
|
108
|
+
if (this._disposed) return;
|
|
109
|
+
this._disposed = true;
|
|
110
|
+
this._auth?.dispose();
|
|
111
|
+
this._realtime?.disconnect();
|
|
112
|
+
}
|
|
113
|
+
// -- Lazy service getters ---------------------------------------------------
|
|
114
|
+
get auth() {
|
|
115
|
+
if (!this._auth) {
|
|
116
|
+
this._auth = new auth$1.AuthService(this, {
|
|
117
|
+
autoRefresh: this._autoRefresh,
|
|
118
|
+
persistSession: this._persistSession,
|
|
119
|
+
detectSessionInUrl: this._detectSessionInUrl
|
|
120
|
+
});
|
|
121
|
+
this._auth.onAuthStateChange(({ event, accessToken }) => {
|
|
122
|
+
if (this._realtime) {
|
|
123
|
+
if (accessToken) {
|
|
124
|
+
this._realtime.setAuth(accessToken);
|
|
125
|
+
} else if (event === "SIGNED_OUT") {
|
|
126
|
+
this._realtime.setAuth("");
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return this._auth;
|
|
132
|
+
}
|
|
133
|
+
get authAdmin() {
|
|
134
|
+
if (isBrowserContext()) {
|
|
135
|
+
throw new Error(
|
|
136
|
+
"[aurabase] S\xC9CURIT\xC9 : authAdmin est inaccessible dans un contexte navigateur. L'API admin requiert une cl\xE9 service_role qui ne doit JAMAIS \xEAtre expos\xE9e c\xF4t\xE9 client (elle fuiterait dans le bundle). Utilisez createAdminClient() c\xF4t\xE9 serveur uniquement."
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
if (!this._authAdmin) this._authAdmin = new auth$1.AuthAdminService(this);
|
|
140
|
+
return this._authAdmin;
|
|
141
|
+
}
|
|
142
|
+
get db() {
|
|
143
|
+
if (!this._db) this._db = new db.DatabaseService(this);
|
|
144
|
+
return this._db;
|
|
145
|
+
}
|
|
146
|
+
get storage() {
|
|
147
|
+
if (!this._storage) this._storage = new storage.StorageService(this);
|
|
148
|
+
return this._storage;
|
|
149
|
+
}
|
|
150
|
+
get realtime() {
|
|
151
|
+
if (!this._realtime) this._realtime = new realtime.RealtimeService(this);
|
|
152
|
+
return this._realtime;
|
|
153
|
+
}
|
|
154
|
+
get functions() {
|
|
155
|
+
if (!this._functions) this._functions = new functions.FunctionsService(this);
|
|
156
|
+
return this._functions;
|
|
157
|
+
}
|
|
158
|
+
get ai() {
|
|
159
|
+
if (!this._ai) this._ai = new ai.AiService(this);
|
|
160
|
+
return this._ai;
|
|
161
|
+
}
|
|
162
|
+
get notifications() {
|
|
163
|
+
if (!this._notifications) this._notifications = new notifications.NotificationsService(this);
|
|
164
|
+
return this._notifications;
|
|
165
|
+
}
|
|
166
|
+
from(table) {
|
|
167
|
+
return this.db.from(table);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Shortcut: call a stored procedure / PostgreSQL function via RPC (Supabase-compatible API).
|
|
171
|
+
* Equivalent to `aura.db.rpc(fn, args, options)`.
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```ts
|
|
175
|
+
* const { data, error } = await aura.rpc('echo_test', { message: 'hello' })
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
rpc(fn, args, options) {
|
|
179
|
+
return this.db.rpc(fn, args, options);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Shortcut: create a realtime channel with Supabase-compatible API.
|
|
183
|
+
* Equivalent to `aura.realtime.channel(name)`.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```ts
|
|
187
|
+
* const channel = aura.channel('room-1')
|
|
188
|
+
* .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'messages' }, cb)
|
|
189
|
+
* .subscribe()
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
channel(name, options) {
|
|
193
|
+
return this.realtime.channel(name, options);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Shortcut: remove a realtime channel by name or AuraChannel instance.
|
|
197
|
+
* Equivalent to `aura.realtime.removeChannel(channel)`.
|
|
198
|
+
*/
|
|
199
|
+
removeChannel(channel) {
|
|
200
|
+
return this.realtime.removeChannel(channel);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Shortcut: remove all realtime channels and unsubscribe.
|
|
204
|
+
* Equivalent to `aura.realtime.removeAllChannels()`.
|
|
205
|
+
*/
|
|
206
|
+
removeAllChannels() {
|
|
207
|
+
return this.realtime.removeAllChannels();
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Shortcut: list all active realtime channels.
|
|
211
|
+
* Equivalent to `aura.realtime.getChannels()`.
|
|
212
|
+
*/
|
|
213
|
+
getChannels() {
|
|
214
|
+
return this.realtime.getChannels();
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
var MAX_CHUNK_SIZE = 3600;
|
|
218
|
+
function createServerClient(baseUrl, apiKey, options) {
|
|
219
|
+
const cookieName = `aura-${core.clientScope(baseUrl)}-auth`;
|
|
220
|
+
const store = new core.LocalAuthStore(cookieName);
|
|
221
|
+
const idxRe = new RegExp(`^${cookieName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\.(\\d+)$`);
|
|
222
|
+
const incoming = options.cookies.getAll();
|
|
223
|
+
const numbered = incoming.filter((c) => idxRe.test(c.name)).sort((a, b) => Number(a.name.match(idxRe)[1]) - Number(b.name.match(idxRe)[1]));
|
|
224
|
+
const base = incoming.find((c) => c.name === cookieName);
|
|
225
|
+
const decodedValue = numbered.length > 0 ? numbered.map((c) => c.value).join("") : base?.value;
|
|
226
|
+
if (decodedValue) {
|
|
227
|
+
store.loadFromCookie(`${cookieName}=${encodeURIComponent(decodedValue)}`);
|
|
228
|
+
}
|
|
229
|
+
const initialNames = incoming.filter((c) => c.name === cookieName || idxRe.test(c.name)).map((c) => c.name);
|
|
230
|
+
const defaultCookieOpts = {
|
|
231
|
+
path: "/",
|
|
232
|
+
secure: baseUrl.startsWith("https://"),
|
|
233
|
+
sameSite: "Lax",
|
|
234
|
+
httpOnly: true,
|
|
235
|
+
maxAge: 60 * 60 * 24 * 30,
|
|
236
|
+
// 30 days
|
|
237
|
+
...options.cookieOptions
|
|
238
|
+
};
|
|
239
|
+
store.onChange(() => {
|
|
240
|
+
const toSet = [];
|
|
241
|
+
const used = /* @__PURE__ */ new Set();
|
|
242
|
+
if (store.token) {
|
|
243
|
+
const cookieStr = store.exportToCookie();
|
|
244
|
+
const eqIdx = cookieStr.indexOf("=");
|
|
245
|
+
const rawEncoded = eqIdx >= 0 ? cookieStr.slice(eqIdx + 1).split(";")[0] : "";
|
|
246
|
+
const decoded = rawEncoded ? decodeURIComponent(rawEncoded) : "";
|
|
247
|
+
if (decoded.length <= MAX_CHUNK_SIZE) {
|
|
248
|
+
toSet.push({ name: cookieName, value: decoded, options: defaultCookieOpts });
|
|
249
|
+
used.add(cookieName);
|
|
250
|
+
} else {
|
|
251
|
+
let idx = 0;
|
|
252
|
+
for (let i = 0; i < decoded.length; i += MAX_CHUNK_SIZE, idx++) {
|
|
253
|
+
const name = `${cookieName}.${idx}`;
|
|
254
|
+
toSet.push({
|
|
255
|
+
name,
|
|
256
|
+
value: decoded.slice(i, i + MAX_CHUNK_SIZE),
|
|
257
|
+
options: defaultCookieOpts
|
|
258
|
+
});
|
|
259
|
+
used.add(name);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
const expireOpts = { ...defaultCookieOpts, maxAge: 0 };
|
|
264
|
+
for (const name of initialNames) {
|
|
265
|
+
if (!used.has(name)) toSet.push({ name, value: "", options: expireOpts });
|
|
266
|
+
}
|
|
267
|
+
if (toSet.length > 0) options.cookies.setAll(toSet);
|
|
268
|
+
});
|
|
269
|
+
return new AuraClient(baseUrl, apiKey, {
|
|
270
|
+
auth: { persistSession: false, storage: store }
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// src/nextjs.ts
|
|
275
|
+
async function loadNextModule(specifier) {
|
|
276
|
+
try {
|
|
277
|
+
const mod = await import(
|
|
278
|
+
/* @vite-ignore */
|
|
279
|
+
specifier
|
|
280
|
+
);
|
|
281
|
+
return mod;
|
|
282
|
+
} catch {
|
|
283
|
+
return null;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function createAuthMiddleware(options = {}) {
|
|
287
|
+
return async function middleware(request) {
|
|
288
|
+
const nextServer = await loadNextModule("next/server");
|
|
289
|
+
if (!nextServer?.NextResponse) {
|
|
290
|
+
throw new Error(
|
|
291
|
+
"[@aurabase/nextjs] Next.js n'est pas install\xE9. createAuthMiddleware n\xE9cessite next/server."
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
const { NextResponse } = nextServer;
|
|
295
|
+
const projectUrl = options.projectUrl ?? process.env.NEXT_PUBLIC_AURABASE_URL ?? process.env.AURABASE_URL ?? "";
|
|
296
|
+
const anonKey = options.anonKey ?? process.env.NEXT_PUBLIC_AURABASE_ANON_KEY ?? process.env.AURABASE_ANON_KEY ?? "";
|
|
297
|
+
if (!projectUrl || !anonKey) {
|
|
298
|
+
console.warn(
|
|
299
|
+
"[@aurabase/nextjs] Variables d'environnement manquantes : NEXT_PUBLIC_AURABASE_URL ou NEXT_PUBLIC_AURABASE_ANON_KEY non d\xE9finies."
|
|
300
|
+
);
|
|
301
|
+
return NextResponse.next({ request });
|
|
302
|
+
}
|
|
303
|
+
const response = NextResponse.next({ request });
|
|
304
|
+
const cookieHandler = {
|
|
305
|
+
getAll: () => request.cookies.getAll(),
|
|
306
|
+
setAll: (cookiesToSet) => {
|
|
307
|
+
cookiesToSet.forEach(({ name, value, options: cookieOpts }) => {
|
|
308
|
+
request.cookies.set(name, value);
|
|
309
|
+
response.cookies.set(name, value, cookieOpts);
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
const client = createServerClient(projectUrl, anonKey, {
|
|
314
|
+
cookies: cookieHandler
|
|
315
|
+
});
|
|
316
|
+
const { data: sessionData } = await client.auth.getSession();
|
|
317
|
+
const session = sessionData?.session ?? null;
|
|
318
|
+
const user = session?.user ?? null;
|
|
319
|
+
const pathname = request.nextUrl.pathname;
|
|
320
|
+
const publicPatterns = options.publicRoutes ?? ["/", "/login", "/signup", "/auth/callback"];
|
|
321
|
+
const isPublic = publicPatterns.some((pattern) => {
|
|
322
|
+
if (pattern.endsWith("*")) {
|
|
323
|
+
return pathname.startsWith(pattern.slice(0, -1));
|
|
324
|
+
}
|
|
325
|
+
return pathname === pattern;
|
|
326
|
+
});
|
|
327
|
+
if (!isPublic && !user) {
|
|
328
|
+
const loginUrl = new URL(options.loginUrl ?? "/login", request.url);
|
|
329
|
+
loginUrl.searchParams.set("redirectTo", pathname);
|
|
330
|
+
return NextResponse.redirect(loginUrl);
|
|
331
|
+
}
|
|
332
|
+
if (options.onAuthenticated) {
|
|
333
|
+
const customResponse = await options.onAuthenticated({ user, session, request });
|
|
334
|
+
if (customResponse) return customResponse;
|
|
335
|
+
}
|
|
336
|
+
return response;
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
function createClientForServerComponent(cookieStore, projectUrl, apiKey) {
|
|
340
|
+
const url = projectUrl ?? process.env.NEXT_PUBLIC_AURABASE_URL ?? process.env.AURABASE_URL ?? "";
|
|
341
|
+
const key = apiKey ?? process.env.NEXT_PUBLIC_AURABASE_ANON_KEY ?? process.env.AURABASE_ANON_KEY ?? "";
|
|
342
|
+
return createServerClient(url, key, {
|
|
343
|
+
cookies: {
|
|
344
|
+
getAll: () => cookieStore.getAll(),
|
|
345
|
+
setAll: () => {
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
function createClientForServerAction(cookieStore, projectUrl, apiKey) {
|
|
351
|
+
const url = projectUrl ?? process.env.NEXT_PUBLIC_AURABASE_URL ?? process.env.AURABASE_URL ?? "";
|
|
352
|
+
const key = apiKey ?? process.env.NEXT_PUBLIC_AURABASE_ANON_KEY ?? process.env.AURABASE_ANON_KEY ?? "";
|
|
353
|
+
return createServerClient(url, key, {
|
|
354
|
+
cookies: {
|
|
355
|
+
getAll: () => cookieStore.getAll(),
|
|
356
|
+
setAll: (cookiesToSet) => {
|
|
357
|
+
cookiesToSet.forEach(({ name, value, options }) => {
|
|
358
|
+
cookieStore.set?.(name, value, options);
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
async function auth(options) {
|
|
365
|
+
const nextHeaders = await loadNextModule("next/headers");
|
|
366
|
+
if (!nextHeaders?.cookies) {
|
|
367
|
+
throw new Error("[@aurabase/nextjs] auth() ne peut \xEAtre appel\xE9 que dans un environnement Next.js App Router.");
|
|
368
|
+
}
|
|
369
|
+
const cookieStore = await nextHeaders.cookies();
|
|
370
|
+
const client = createClientForServerComponent(cookieStore, options?.projectUrl, options?.apiKey);
|
|
371
|
+
const { data } = await client.auth.getSession();
|
|
372
|
+
const session = data?.session ?? null;
|
|
373
|
+
const user = session?.user ?? null;
|
|
374
|
+
return {
|
|
375
|
+
userId: user?.id ?? null,
|
|
376
|
+
user,
|
|
377
|
+
session
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
async function currentUser(options) {
|
|
381
|
+
const { user } = await auth(options);
|
|
382
|
+
return user;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
exports.auth = auth;
|
|
386
|
+
exports.createAuthMiddleware = createAuthMiddleware;
|
|
387
|
+
exports.createClientForServerAction = createClientForServerAction;
|
|
388
|
+
exports.createClientForServerComponent = createClientForServerComponent;
|
|
389
|
+
exports.currentUser = currentUser;
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { A as AuraClient } from './AuraClient-5jDiXjrO.cjs';
|
|
2
|
+
import { User, Session } from '@aurabase/core';
|
|
3
|
+
import '@aurabase/ai';
|
|
4
|
+
import '@aurabase/auth';
|
|
5
|
+
import '@aurabase/db';
|
|
6
|
+
import '@aurabase/functions';
|
|
7
|
+
import '@aurabase/notifications';
|
|
8
|
+
import '@aurabase/realtime';
|
|
9
|
+
import '@aurabase/storage';
|
|
10
|
+
|
|
11
|
+
interface NextCookieItem {
|
|
12
|
+
name: string;
|
|
13
|
+
value: string;
|
|
14
|
+
options?: Record<string, unknown>;
|
|
15
|
+
}
|
|
16
|
+
interface NextRequestCookies {
|
|
17
|
+
getAll(): NextCookieItem[];
|
|
18
|
+
set(name: string, value: string): void;
|
|
19
|
+
}
|
|
20
|
+
interface NextUrlLike {
|
|
21
|
+
pathname: string;
|
|
22
|
+
}
|
|
23
|
+
interface NextRequestLike {
|
|
24
|
+
cookies: NextRequestCookies;
|
|
25
|
+
nextUrl: NextUrlLike;
|
|
26
|
+
url: string;
|
|
27
|
+
}
|
|
28
|
+
interface NextResponseCookies {
|
|
29
|
+
set(name: string, value: string, options?: Record<string, unknown>): void;
|
|
30
|
+
}
|
|
31
|
+
interface NextResponseLike {
|
|
32
|
+
cookies: NextResponseCookies;
|
|
33
|
+
headers?: unknown;
|
|
34
|
+
}
|
|
35
|
+
interface NextServerModule {
|
|
36
|
+
NextResponse: {
|
|
37
|
+
next(init?: {
|
|
38
|
+
request?: unknown;
|
|
39
|
+
}): NextResponseLike;
|
|
40
|
+
redirect(url: string | URL): NextResponseLike;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
interface ReadonlyRequestCookiesLike {
|
|
44
|
+
getAll(): NextCookieItem[];
|
|
45
|
+
set?(name: string, value: string, options?: Record<string, unknown>): void;
|
|
46
|
+
}
|
|
47
|
+
interface NextHeadersModule {
|
|
48
|
+
cookies(): Promise<ReadonlyRequestCookiesLike> | ReadonlyRequestCookiesLike;
|
|
49
|
+
}
|
|
50
|
+
interface AuthContextParam {
|
|
51
|
+
user: User | null;
|
|
52
|
+
session: Session | null;
|
|
53
|
+
request: NextRequestLike;
|
|
54
|
+
}
|
|
55
|
+
interface AuthMiddlewareOptions {
|
|
56
|
+
/** Project URL (defaults to process.env.NEXT_PUBLIC_AURABASE_URL or process.env.AURABASE_URL). */
|
|
57
|
+
projectUrl?: string;
|
|
58
|
+
/** Anon API Key (defaults to process.env.NEXT_PUBLIC_AURABASE_ANON_KEY or process.env.AURABASE_ANON_KEY). */
|
|
59
|
+
anonKey?: string;
|
|
60
|
+
/** List of route patterns that do not require authentication (e.g. ['/', '/login', '/signup', '/auth/*']). */
|
|
61
|
+
publicRoutes?: string[];
|
|
62
|
+
/** URL to redirect unauthenticated users to (default: '/login'). */
|
|
63
|
+
loginUrl?: string;
|
|
64
|
+
/** Custom handler executed after session evaluation. */
|
|
65
|
+
onAuthenticated?: (authContext: AuthContextParam) => Promise<NextResponseLike | undefined | null | void> | NextResponseLike | undefined | null | void;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Creates a standard Next.js middleware that validates sessions and protects private routes.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```ts
|
|
72
|
+
* // middleware.ts
|
|
73
|
+
* import { createAuthMiddleware } from '@aurabase/aurabase-js/nextjs'
|
|
74
|
+
*
|
|
75
|
+
* export default createAuthMiddleware({
|
|
76
|
+
* publicRoutes: ['/', '/login', '/signup', '/api/public'],
|
|
77
|
+
* loginUrl: '/login',
|
|
78
|
+
* })
|
|
79
|
+
*
|
|
80
|
+
* export const config = {
|
|
81
|
+
* matcher: ['/((?!_next/static|_next/image|favicon.ico).*)'],
|
|
82
|
+
* }
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
declare function createAuthMiddleware(options?: AuthMiddlewareOptions): (request: NextRequestLike) => Promise<NextResponseLike>;
|
|
86
|
+
/**
|
|
87
|
+
* Creates an Aurabase client optimized for React Server Components (RSC).
|
|
88
|
+
* Safe in read-only RSC context: prevents Next.js errors when evaluating tokens.
|
|
89
|
+
*/
|
|
90
|
+
declare function createClientForServerComponent(cookieStore: ReadonlyRequestCookiesLike, projectUrl?: string, apiKey?: string): AuraClient<any, any>;
|
|
91
|
+
/**
|
|
92
|
+
* Creates an Aurabase client for Server Actions and Route Handlers.
|
|
93
|
+
* Full read-write cookie access for transparent session management.
|
|
94
|
+
*/
|
|
95
|
+
declare function createClientForServerAction(cookieStore: ReadonlyRequestCookiesLike, projectUrl?: string, apiKey?: string): AuraClient<any, any>;
|
|
96
|
+
/**
|
|
97
|
+
* Server Component helper (Clerk-like API) to get the current authentication state.
|
|
98
|
+
*
|
|
99
|
+
* @example
|
|
100
|
+
* ```tsx
|
|
101
|
+
* import { auth } from '@aurabase/aurabase-js/nextjs'
|
|
102
|
+
*
|
|
103
|
+
* export default async function Page() {
|
|
104
|
+
* const { userId, user } = await auth()
|
|
105
|
+
* if (!userId) return <div>Non connecté</div>
|
|
106
|
+
* return <div>Connecté en tant que {user?.email}</div>
|
|
107
|
+
* }
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
declare function auth(options?: {
|
|
111
|
+
projectUrl?: string;
|
|
112
|
+
apiKey?: string;
|
|
113
|
+
}): Promise<{
|
|
114
|
+
userId: string | null;
|
|
115
|
+
user: User | null;
|
|
116
|
+
session: Session | null;
|
|
117
|
+
}>;
|
|
118
|
+
/**
|
|
119
|
+
* Server Component helper to get the currently logged-in user profile.
|
|
120
|
+
*/
|
|
121
|
+
declare function currentUser(options?: {
|
|
122
|
+
projectUrl?: string;
|
|
123
|
+
apiKey?: string;
|
|
124
|
+
}): Promise<User | null>;
|
|
125
|
+
|
|
126
|
+
export { type AuthContextParam, type AuthMiddlewareOptions, type NextCookieItem, type NextHeadersModule, type NextRequestCookies, type NextRequestLike, type NextResponseCookies, type NextResponseLike, type NextServerModule, type NextUrlLike, type ReadonlyRequestCookiesLike, auth, createAuthMiddleware, createClientForServerAction, createClientForServerComponent, currentUser };
|