@allanfsouza/aether-sdk 2.4.9 → 2.4.10

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/database.js CHANGED
@@ -199,7 +199,6 @@ export class CollectionReference {
199
199
  console.warn("[SDK] Realtime falhou: Token ou ProjectId ausentes.");
200
200
  return () => { };
201
201
  }
202
- // URL correta de subscribe
203
202
  const url = `${this.wsUrl}/v1/db/subscribe/${this.collectionName}?token=${token}&projectId=${projectId}`;
204
203
  let ws = null;
205
204
  try {
@@ -207,7 +206,7 @@ export class CollectionReference {
207
206
  if (!ws)
208
207
  return () => { };
209
208
  ws.onopen = () => {
210
- // Conectado
209
+ console.log(`[SDK] Realtime conectado: ${this.collectionName}`);
211
210
  };
212
211
  ws.onmessage = (event) => {
213
212
  try {
@@ -215,16 +214,27 @@ export class CollectionReference {
215
214
  if (raw === "pong")
216
215
  return;
217
216
  const payload = JSON.parse(raw);
218
- callback(payload.action, payload.data);
217
+ console.log(`[SDK] Evento recebido:`, payload.action, payload.data?.id);
218
+ // [FIX] Mapeia 'insert' do Postgres para 'create' do SDK
219
+ let action = payload.action;
220
+ if (payload.action === 'insert') {
221
+ action = 'create';
222
+ }
223
+ callback(action, payload.data);
219
224
  }
220
225
  catch (e) {
221
- // Erro silencioso de parse
226
+ console.error('[SDK] Erro ao parsear evento:', e);
222
227
  }
223
228
  };
229
+ ws.onerror = (err) => {
230
+ console.error('[SDK] WebSocket erro:', err);
231
+ };
232
+ ws.onclose = () => {
233
+ console.log(`[SDK] Realtime desconectado: ${this.collectionName}`);
234
+ };
224
235
  // Heartbeat
225
236
  const pingInterval = setInterval(() => {
226
- // [CORREÇÃO] Adicionada verificação explicita 'ws &&' para evitar erro 'possibly null'
227
- if (ws && ws.readyState === 1) { // 1 = OPEN
237
+ if (ws && ws.readyState === 1) {
228
238
  ws.send("ping");
229
239
  }
230
240
  }, 30000);
@@ -115,7 +115,7 @@ export function createHttpClient(client, retryConfig = {}) {
115
115
  });
116
116
  // ===========================================================================
117
117
  // INTERCEPTOR DE REQUEST
118
- // Injeta token e projectId em todas as requisições
118
+ // Injeta token, projectId e API Key em todas as requisições
119
119
  // ===========================================================================
120
120
  http.interceptors.request.use((reqConfig) => {
121
121
  const token = client.getToken();
@@ -125,6 +125,10 @@ export function createHttpClient(client, retryConfig = {}) {
125
125
  if (client.projectId) {
126
126
  reqConfig.headers["X-Project-ID"] = client.projectId;
127
127
  }
128
+ // [NOVO] Envia API Key para autenticação de operações de banco de dados
129
+ if (client.serviceApiKey) {
130
+ reqConfig.headers["X-API-Key"] = client.serviceApiKey;
131
+ }
128
132
  // Inicializa contador de retry
129
133
  if (reqConfig._retryCount === undefined) {
130
134
  reqConfig._retryCount = 0;
package/dist/index.d.ts CHANGED
@@ -13,6 +13,11 @@ export type ClientConfig = {
13
13
  baseUrl?: string;
14
14
  projectId?: string;
15
15
  apiKey?: string;
16
+ /**
17
+ * [NOVO] API Key de serviço para autenticação em operações de banco de dados.
18
+ * Necessário para apps client-side que usam tenant auth.
19
+ */
20
+ serviceApiKey?: string;
16
21
  /**
17
22
  * Habilita persistência automática de sessão no localStorage.
18
23
  * Padrão: true em browsers, false em Node.js/SSR.
@@ -29,6 +34,7 @@ export declare class PlataformaClient {
29
34
  database: DatabaseModule;
30
35
  apiUrl: string;
31
36
  projectId: string;
37
+ serviceApiKey: string | null;
32
38
  http: AxiosInstance;
33
39
  private _token;
34
40
  private _persistSession;
package/dist/index.js CHANGED
@@ -24,6 +24,7 @@ function isBrowser() {
24
24
  }
25
25
  export class PlataformaClient {
26
26
  constructor(config) {
27
+ this.serviceApiKey = null;
27
28
  this._token = null;
28
29
  // Resolve URL (prioridade para baseUrl se existir, senão apiUrl)
29
30
  const url = config.baseUrl || config.apiUrl;
@@ -33,6 +34,7 @@ export class PlataformaClient {
33
34
  }
34
35
  this.apiUrl = url.replace(/\/+$/, "");
35
36
  this.projectId = project;
37
+ this.serviceApiKey = config.serviceApiKey || null;
36
38
  // Persistência habilitada por padrão apenas em browsers
37
39
  this._persistSession = config.persistSession ?? isBrowser();
38
40
  // Restaura sessão salva ANTES de criar o httpClient
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@allanfsouza/aether-sdk",
3
- "version": "2.4.9",
3
+ "version": "2.4.10",
4
4
  "description": "SDK do Cliente para a Plataforma Aether",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
package/src/database.ts CHANGED
@@ -285,7 +285,6 @@ export class CollectionReference<T> {
285
285
  return () => { };
286
286
  }
287
287
 
288
- // URL correta de subscribe
289
288
  const url = `${this.wsUrl}/v1/db/subscribe/${this.collectionName}?token=${token}&projectId=${projectId}`;
290
289
 
291
290
  let ws: WebSocket | null = null;
@@ -296,7 +295,7 @@ export class CollectionReference<T> {
296
295
  if (!ws) return () => { };
297
296
 
298
297
  ws.onopen = () => {
299
- // Conectado
298
+ console.log(`[SDK] Realtime conectado: ${this.collectionName}`);
300
299
  };
301
300
 
302
301
  ws.onmessage = (event: any) => {
@@ -304,17 +303,32 @@ export class CollectionReference<T> {
304
303
  const raw = event.data?.toString() || event.toString();
305
304
  if (raw === "pong") return;
306
305
 
307
- const payload = JSON.parse(raw) as WebSocketMessage<T>;
308
- callback(payload.action, payload.data);
306
+ const payload = JSON.parse(raw);
307
+ console.log(`[SDK] Evento recebido:`, payload.action, payload.data?.id);
308
+
309
+ // [FIX] Mapeia 'insert' do Postgres para 'create' do SDK
310
+ let action: "create" | "update" | "delete" = payload.action;
311
+ if (payload.action === 'insert') {
312
+ action = 'create';
313
+ }
314
+
315
+ callback(action, payload.data);
309
316
  } catch (e) {
310
- // Erro silencioso de parse
317
+ console.error('[SDK] Erro ao parsear evento:', e);
311
318
  }
312
319
  };
313
320
 
321
+ ws.onerror = (err) => {
322
+ console.error('[SDK] WebSocket erro:', err);
323
+ };
324
+
325
+ ws.onclose = () => {
326
+ console.log(`[SDK] Realtime desconectado: ${this.collectionName}`);
327
+ };
328
+
314
329
  // Heartbeat
315
330
  const pingInterval = setInterval(() => {
316
- // [CORREÇÃO] Adicionada verificação explicita 'ws &&' para evitar erro 'possibly null'
317
- if (ws && ws.readyState === 1) { // 1 = OPEN
331
+ if (ws && ws.readyState === 1) {
318
332
  ws.send("ping");
319
333
  }
320
334
  }, 30000);
@@ -177,7 +177,7 @@ export function createHttpClient(
177
177
 
178
178
  // ===========================================================================
179
179
  // INTERCEPTOR DE REQUEST
180
- // Injeta token e projectId em todas as requisições
180
+ // Injeta token, projectId e API Key em todas as requisições
181
181
  // ===========================================================================
182
182
  http.interceptors.request.use((reqConfig) => {
183
183
  const token = client.getToken();
@@ -189,6 +189,11 @@ export function createHttpClient(
189
189
  reqConfig.headers["X-Project-ID"] = client.projectId;
190
190
  }
191
191
 
192
+ // [NOVO] Envia API Key para autenticação de operações de banco de dados
193
+ if (client.serviceApiKey) {
194
+ reqConfig.headers["X-API-Key"] = client.serviceApiKey;
195
+ }
196
+
192
197
  // Inicializa contador de retry
193
198
  if ((reqConfig as ExtendedAxiosRequestConfig)._retryCount === undefined) {
194
199
  (reqConfig as ExtendedAxiosRequestConfig)._retryCount = 0;
package/src/index.ts CHANGED
@@ -28,6 +28,12 @@ export type ClientConfig = {
28
28
  projectId?: string;
29
29
  apiKey?: string;
30
30
 
31
+ /**
32
+ * [NOVO] API Key de serviço para autenticação em operações de banco de dados.
33
+ * Necessário para apps client-side que usam tenant auth.
34
+ */
35
+ serviceApiKey?: string;
36
+
31
37
  /**
32
38
  * Habilita persistência automática de sessão no localStorage.
33
39
  * Padrão: true em browsers, false em Node.js/SSR.
@@ -59,6 +65,7 @@ export class PlataformaClient {
59
65
 
60
66
  public apiUrl: string;
61
67
  public projectId: string;
68
+ public serviceApiKey: string | null = null;
62
69
 
63
70
  public http: AxiosInstance;
64
71
 
@@ -76,6 +83,7 @@ export class PlataformaClient {
76
83
 
77
84
  this.apiUrl = url.replace(/\/+$/, "");
78
85
  this.projectId = project;
86
+ this.serviceApiKey = config.serviceApiKey || null;
79
87
 
80
88
  // Persistência habilitada por padrão apenas em browsers
81
89
  this._persistSession = config.persistSession ?? isBrowser();