@aurabase/aurabase-js 0.5.3 → 0.6.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.
@@ -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<T = any>(fn: string, args?: Record<string, unknown>, options?: any): any;
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<T = any>(fn: string, args?: Record<string, unknown>, options?: any): any;
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
  }
@@ -265,10 +268,22 @@ Object.defineProperty(exports, "QueryBuilder", {
265
268
  enumerable: true,
266
269
  get: function () { return db.QueryBuilder; }
267
270
  });
271
+ Object.defineProperty(exports, "FunctionsHttpError", {
272
+ enumerable: true,
273
+ get: function () { return functions.FunctionsHttpError; }
274
+ });
275
+ Object.defineProperty(exports, "FunctionsRelayError", {
276
+ enumerable: true,
277
+ get: function () { return functions.FunctionsRelayError; }
278
+ });
268
279
  Object.defineProperty(exports, "FunctionsService", {
269
280
  enumerable: true,
270
281
  get: function () { return functions.FunctionsService; }
271
282
  });
283
+ Object.defineProperty(exports, "isRelayStatus", {
284
+ enumerable: true,
285
+ get: function () { return functions.isRelayStatus; }
286
+ });
272
287
  Object.defineProperty(exports, "NotificationsAdminService", {
273
288
  enumerable: true,
274
289
  get: function () { return notifications.NotificationsAdminService; }
package/dist/index.d.cts CHANGED
@@ -3,11 +3,11 @@ export { AuthAdminService, AuthService, isMfaChallenge } from '@aurabase/auth';
3
3
  import { AuraClientOptions } from '@aurabase/core';
4
4
  export { AdminCreateUserRequest, AdminUpdateUserRequest, AdminUser, AuditLogEntry, AuraClientOptions, AuraError, AuraErrorCode, AuraObservabilityEvent, AuraResponse, AuthChangePayload, AuthEvent, AuthSettings, AuthSettingsUpdate, BaseAuthStore, BatchSendResponse, BroadcastFilter, BroadcastPayload, BroadcastSendStatus, ChannelConfig, ChatMessage, ChatResponse, CountMode, CreatePgFunctionRequest, CreatePgTriggerRequest, CronJob, EmailTemplateUpdate, EmbedRequest, EmbedResponse, FileEntry, FilterOp, FunctionDef, IdentityInfo, Job, LocalAuthStore, LoginResponse, MagicLinkRequest, Meta, MfaChallenge, MfaEnrollResponse, MfaVerifyRequest, Notification, NotificationAttempt, NotificationDeadLetter, NotificationEvent, NotificationProviderLog, NotificationQueueStats, NotificationRule, NotificationSettings, NotificationStats, NotificationTemplate, NotificationTemplatePreview, OAuthProviderSetting, OAuthSignInOptions, PasswordResetRequest, PgExecutableRole, PgFunctionInfo, PgTriggerInfo, PostgresChangesFilter, PresenceFilter, PresenceInfo, PresenceState, QueryFilter, QueryOptions, RagIngestRequest, RagIngestResponse, RagRequest, RagResponse, RealtimeEvent, RealtimeListenType, RealtimeSubscribeStatus, SchemaColumn, SchemaEnum, SchemaFunction, SchemaFunctionArg, SchemaTable, SemanticSearchResult, SendNotificationRequest, SessionInfo, SignInRequest, SignUpRequest, StorageBucket, TokenPair, UpdateUserRequest, UploadResult, User, isAuraError } from '@aurabase/core';
5
5
  export { DatabaseService, QueryBuilder } from '@aurabase/db';
6
- export { FunctionsService } from '@aurabase/functions';
6
+ export { FunctionsHttpError, FunctionsRelayError, FunctionsResponseType, FunctionsService, isRelayStatus } 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-K3hRdh9J.cjs';
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
@@ -3,11 +3,11 @@ export { AuthAdminService, AuthService, isMfaChallenge } from '@aurabase/auth';
3
3
  import { AuraClientOptions } from '@aurabase/core';
4
4
  export { AdminCreateUserRequest, AdminUpdateUserRequest, AdminUser, AuditLogEntry, AuraClientOptions, AuraError, AuraErrorCode, AuraObservabilityEvent, AuraResponse, AuthChangePayload, AuthEvent, AuthSettings, AuthSettingsUpdate, BaseAuthStore, BatchSendResponse, BroadcastFilter, BroadcastPayload, BroadcastSendStatus, ChannelConfig, ChatMessage, ChatResponse, CountMode, CreatePgFunctionRequest, CreatePgTriggerRequest, CronJob, EmailTemplateUpdate, EmbedRequest, EmbedResponse, FileEntry, FilterOp, FunctionDef, IdentityInfo, Job, LocalAuthStore, LoginResponse, MagicLinkRequest, Meta, MfaChallenge, MfaEnrollResponse, MfaVerifyRequest, Notification, NotificationAttempt, NotificationDeadLetter, NotificationEvent, NotificationProviderLog, NotificationQueueStats, NotificationRule, NotificationSettings, NotificationStats, NotificationTemplate, NotificationTemplatePreview, OAuthProviderSetting, OAuthSignInOptions, PasswordResetRequest, PgExecutableRole, PgFunctionInfo, PgTriggerInfo, PostgresChangesFilter, PresenceFilter, PresenceInfo, PresenceState, QueryFilter, QueryOptions, RagIngestRequest, RagIngestResponse, RagRequest, RagResponse, RealtimeEvent, RealtimeListenType, RealtimeSubscribeStatus, SchemaColumn, SchemaEnum, SchemaFunction, SchemaFunctionArg, SchemaTable, SemanticSearchResult, SendNotificationRequest, SessionInfo, SignInRequest, SignUpRequest, StorageBucket, TokenPair, UpdateUserRequest, UploadResult, User, isAuraError } from '@aurabase/core';
5
5
  export { DatabaseService, QueryBuilder } from '@aurabase/db';
6
- export { FunctionsService } from '@aurabase/functions';
6
+ export { FunctionsHttpError, FunctionsRelayError, FunctionsResponseType, FunctionsService, isRelayStatus } 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-K3hRdh9J.js';
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
@@ -7,7 +7,7 @@ export { AuraError, BaseAuthStore, LocalAuthStore, isAuraError } from '@aurabase
7
7
  import { DatabaseService } from '@aurabase/db';
8
8
  export { DatabaseService, QueryBuilder } from '@aurabase/db';
9
9
  import { FunctionsService } from '@aurabase/functions';
10
- export { FunctionsService } from '@aurabase/functions';
10
+ export { FunctionsHttpError, FunctionsRelayError, FunctionsService, isRelayStatus } from '@aurabase/functions';
11
11
  import { NotificationsService } from '@aurabase/notifications';
12
12
  export { NotificationsAdminService, NotificationsService } from '@aurabase/notifications';
13
13
  import { RealtimeService } from '@aurabase/realtime';
@@ -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
  }
@@ -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 };