@allanfsouza/aether-sdk 2.0.0 → 2.2.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/dist/index.d.ts CHANGED
@@ -1,36 +1,42 @@
1
+ import type { AxiosInstance } from "axios";
1
2
  import { AuthModule } from "./auth.js";
2
3
  import { DatabaseModule } from "./database.js";
3
4
  import { StorageModule } from "./storage.js";
4
5
  import { FunctionsModule } from "./functions.js";
5
- type ClientConfig = {
6
+ import { PushModule } from "./push.js";
7
+ /**
8
+ * Configuração usada para criar o cliente principal da plataforma.
9
+ */
10
+ export type ClientConfig = {
6
11
  apiUrl: string;
7
12
  projectId: string;
8
13
  };
9
14
  /**
10
- * O cliente principal da Plataforma API.
11
- * Ponto de entrada para todos os módulos (Auth, DB, Storage, Functions).
15
+ * O cliente principal da Plataforma API (Aether).
16
+ * Ponto de entrada para todos os módulos (Auth, DB, Storage, Functions, Push).
12
17
  */
13
18
  export declare class PlataformaClient {
14
19
  auth: AuthModule;
15
20
  db: DatabaseModule;
16
21
  storage: StorageModule;
17
22
  functions: FunctionsModule;
23
+ push: PushModule;
18
24
  apiUrl: string;
19
25
  projectId: string;
20
- private http;
26
+ http: AxiosInstance;
21
27
  private _token;
22
28
  constructor(config: ClientConfig);
23
29
  /**
24
30
  * Armazena o token de autenticação em memória.
25
- * Chamado automaticamente pelo AuthModule após login.
26
- * @param token O JWT (ou null para logout)
31
+ * Chamado automaticamente pelo AuthModule após login/registro.
27
32
  */
28
33
  setToken(token: string | null): void;
29
34
  /**
30
35
  * Recupera o token de autenticação atual.
31
36
  * Usado pelo http-client para injetar o header Authorization.
32
- * @returns O JWT ou null
33
37
  */
34
38
  getToken(): string | null;
35
39
  }
36
- export {};
40
+ export { AetherError } from "./errors.js";
41
+ export type { ListOptions } from "./database.js";
42
+ export type { PushPlatform, PushEnvironment, PushDevice, RegisterDeviceParams, SendPushResponse, PushStatus, PushLogEntry, ListPushLogsOptions, PushStats, } from "./push.js";
package/dist/index.js CHANGED
@@ -2,10 +2,11 @@ import { createHttpClient } from "./http-client.js";
2
2
  import { AuthModule } from "./auth.js";
3
3
  import { DatabaseModule } from "./database.js";
4
4
  import { StorageModule } from "./storage.js";
5
- import { FunctionsModule } from "./functions.js"; // [NOVO] Import do módulo
5
+ import { FunctionsModule } from "./functions.js";
6
+ import { PushModule } from "./push.js";
6
7
  /**
7
- * O cliente principal da Plataforma API.
8
- * Ponto de entrada para todos os módulos (Auth, DB, Storage, Functions).
8
+ * O cliente principal da Plataforma API (Aether).
9
+ * Ponto de entrada para todos os módulos (Auth, DB, Storage, Functions, Push).
9
10
  */
10
11
  export class PlataformaClient {
11
12
  constructor(config) {
@@ -13,21 +14,22 @@ export class PlataformaClient {
13
14
  if (!config.apiUrl || !config.projectId) {
14
15
  throw new Error("apiUrl e projectId são obrigatórios.");
15
16
  }
16
- this.apiUrl = config.apiUrl.replace(/\/$/, ""); // Remove barra final se houver
17
+ // Normaliza apiUrl removendo barras finais, se houver
18
+ this.apiUrl = config.apiUrl.replace(/\/+$/, "");
17
19
  this.projectId = config.projectId;
18
- // Inicializa o cliente HTTP (passando 'this', a própria instância para injetar token/ID)
20
+ // Inicializa o cliente HTTP (passando a própria instância)
19
21
  this.http = createHttpClient(this);
20
- // Inicializa os módulos passando a referência do cliente e do axios
22
+ // Inicializa os módulos de alto nível
21
23
  this.auth = new AuthModule(this, this.http);
22
24
  this.db = new DatabaseModule(this, this.http);
23
25
  this.storage = new StorageModule(this, this.http);
24
- this.functions = new FunctionsModule(this, this.http); // [NOVO] Inicialização
26
+ this.functions = new FunctionsModule(this, this.http);
27
+ this.push = new PushModule(this, this.http);
25
28
  }
26
29
  // --- Gerenciamento de Token ---
27
30
  /**
28
31
  * Armazena o token de autenticação em memória.
29
- * Chamado automaticamente pelo AuthModule após login.
30
- * @param token O JWT (ou null para logout)
32
+ * Chamado automaticamente pelo AuthModule após login/registro.
31
33
  */
32
34
  setToken(token) {
33
35
  this._token = token;
@@ -35,9 +37,10 @@ export class PlataformaClient {
35
37
  /**
36
38
  * Recupera o token de autenticação atual.
37
39
  * Usado pelo http-client para injetar o header Authorization.
38
- * @returns O JWT ou null
39
40
  */
40
41
  getToken() {
41
42
  return this._token;
42
43
  }
43
44
  }
45
+ // Re-exports convenientes para quem consome o SDK
46
+ export { AetherError } from "./errors.js";
package/dist/push.d.ts ADDED
@@ -0,0 +1,72 @@
1
+ import type { AxiosInstance } from "axios";
2
+ import type { PlataformaClient } from "./index.js";
3
+ export type PushPlatform = "android" | "ios" | "web";
4
+ export type PushEnvironment = "dev" | "staging" | "prod";
5
+ export interface RegisterDeviceParams {
6
+ platform: PushPlatform;
7
+ token: string;
8
+ environment?: PushEnvironment;
9
+ }
10
+ export interface PushDevice {
11
+ id: string;
12
+ projectId: string;
13
+ userId?: string | null;
14
+ platform: PushPlatform;
15
+ token: string;
16
+ environment: PushEnvironment;
17
+ createdAt: string;
18
+ lastSeenAt: string;
19
+ }
20
+ export interface RegisterDeviceResponse {
21
+ device: PushDevice;
22
+ }
23
+ export interface SendPushResponse {
24
+ sent: number;
25
+ total: number;
26
+ message: string;
27
+ }
28
+ export type PushStatus = "sent" | "failed";
29
+ export interface PushLogEntry {
30
+ id: string;
31
+ projectId: string;
32
+ userId?: string | null;
33
+ deviceId?: string | null;
34
+ title: string;
35
+ body: string;
36
+ data: Record<string, string>;
37
+ status: PushStatus;
38
+ errorMessage?: string | null;
39
+ createdAt: string;
40
+ }
41
+ export interface ListPushLogsOptions {
42
+ limit?: number;
43
+ offset?: number;
44
+ status?: PushStatus;
45
+ }
46
+ export interface PushStats {
47
+ totalDevices: number;
48
+ sent24h: number;
49
+ successRate: number;
50
+ }
51
+ export declare class PushModule {
52
+ private client;
53
+ private http;
54
+ constructor(client: PlataformaClient, http: AxiosInstance);
55
+ registerDevice(params: RegisterDeviceParams): Promise<PushDevice>;
56
+ sendToToken(params: {
57
+ token: string;
58
+ title: string;
59
+ body: string;
60
+ data?: Record<string, string>;
61
+ environment?: PushEnvironment;
62
+ }): Promise<SendPushResponse>;
63
+ sendToUser(params: {
64
+ userId: string;
65
+ title: string;
66
+ body: string;
67
+ data?: Record<string, string>;
68
+ environment?: PushEnvironment;
69
+ }): Promise<SendPushResponse>;
70
+ listLogs(options?: ListPushLogsOptions): Promise<PushLogEntry[]>;
71
+ getStats(): Promise<PushStats>;
72
+ }
package/dist/push.js ADDED
@@ -0,0 +1,53 @@
1
+ export class PushModule {
2
+ constructor(client, http) {
3
+ this.client = client;
4
+ this.http = http;
5
+ }
6
+ async registerDevice(params) {
7
+ const projectId = this.client.projectId;
8
+ const { data } = await this.http.post(`/projects/${projectId}/push/devices`, {
9
+ platform: params.platform,
10
+ token: params.token,
11
+ environment: params.environment ?? "prod",
12
+ });
13
+ return data.device;
14
+ }
15
+ async sendToToken(params) {
16
+ const projectId = this.client.projectId;
17
+ const { data } = await this.http.post(`/projects/${projectId}/push/send`, {
18
+ token: params.token,
19
+ title: params.title,
20
+ body: params.body,
21
+ data: params.data ?? {},
22
+ environment: params.environment ?? "prod",
23
+ });
24
+ return data;
25
+ }
26
+ async sendToUser(params) {
27
+ const projectId = this.client.projectId;
28
+ const { data } = await this.http.post(`/projects/${projectId}/push/send`, {
29
+ userId: params.userId,
30
+ title: params.title,
31
+ body: params.body,
32
+ data: params.data ?? {},
33
+ environment: params.environment ?? "prod",
34
+ });
35
+ return data;
36
+ }
37
+ async listLogs(options = {}) {
38
+ const projectId = this.client.projectId;
39
+ const { data } = await this.http.get(`/projects/${projectId}/push/logs`, {
40
+ params: {
41
+ limit: options.limit,
42
+ offset: options.offset,
43
+ status: options.status,
44
+ },
45
+ });
46
+ return data.data;
47
+ }
48
+ async getStats() {
49
+ const projectId = this.client.projectId;
50
+ const { data } = await this.http.get(`/projects/${projectId}/push/stats`);
51
+ return data;
52
+ }
53
+ }
package/errors.ts ADDED
@@ -0,0 +1,46 @@
1
+ // src/errors.ts
2
+ export class AetherError extends Error {
3
+ constructor(
4
+ public code: string,
5
+ public message: string,
6
+ public status?: number,
7
+ public details?: any
8
+ ) {
9
+ super(message);
10
+ this.name = "AetherError";
11
+ // Garante que instanceof AetherError funcione bem em qualquer bundler (ES5/ES6)
12
+ Object.setPrototypeOf(this, new.target.prototype);
13
+ }
14
+ }
15
+
16
+ export function handleAxiosError(error: any): never {
17
+ if (error?.response) {
18
+ // Erro vindo da API (4xx, 5xx)
19
+ const data = error.response.data;
20
+ const message =
21
+ data?.error || data?.message || "Erro desconhecido na API";
22
+ const status: number = error.response.status;
23
+
24
+ let code = "api_error";
25
+ if (status === 401) code = "unauthorized";
26
+ if (status === 403) code = "permission_denied";
27
+ if (status === 404) code = "not_found";
28
+ if (status === 409) code = "conflict";
29
+ if (status === 429) code = "rate_limit_exceeded";
30
+
31
+ throw new AetherError(code, message, status, data);
32
+ }
33
+
34
+ if (error?.request && !error.response) {
35
+ // Erro de rede (sem resposta, offline, timeout)
36
+ throw new AetherError(
37
+ "network_error",
38
+ "Não foi possível conectar ao servidor Aether. Verifique sua conexão.",
39
+ 0
40
+ );
41
+ }
42
+
43
+ // Erro na configuração / código cliente
44
+ const fallbackMessage = error?.message || "Erro interno no cliente SDK.";
45
+ throw new AetherError("client_error", fallbackMessage);
46
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@allanfsouza/aether-sdk",
3
- "version": "2.0.0",
4
- "description": "SDK do Cliente para a Plataforma API",
3
+ "version": "2.2.0",
4
+ "description": "SDK do Cliente para a Plataforma Aether",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "type": "module",
@@ -15,15 +15,17 @@
15
15
  "build": "npx tsc",
16
16
  "test": "echo \"Error: no test specified\" && exit 1"
17
17
  },
18
- "keywords": [],
18
+ "keywords": [
19
+ "baas",
20
+ "sdk",
21
+ "aether"
22
+ ],
19
23
  "author": "",
20
24
  "license": "ISC",
21
25
  "dependencies": {
22
- "axios": "^1.13.2",
23
- "ws": "^8.18.0"
26
+ "axios": "^1.6.0"
24
27
  },
25
28
  "devDependencies": {
26
- "@types/ws": "^8.5.11",
27
- "typescript": "^5.9.3"
29
+ "typescript": "^5.3.0"
28
30
  }
29
- }
31
+ }
package/src/auth.ts CHANGED
@@ -2,13 +2,33 @@
2
2
  import type { AxiosInstance } from "axios";
3
3
  import type { PlataformaClient } from "./index.js";
4
4
 
5
- /**
6
- * Módulo de Autenticação
7
- * Lida com login, registro, gerenciamento de token e recuperação de senha.
8
- */
5
+ export interface LoginResponse {
6
+ accessToken: string;
7
+ refreshToken: string;
8
+ user: {
9
+ id: string;
10
+ name: string;
11
+ email: string;
12
+ avatarUrl?: string;
13
+ role?: string;
14
+ aetherRole?: string;
15
+ planCode?: string;
16
+ emailVerified?: boolean;
17
+ };
18
+ }
19
+
20
+ export interface Session {
21
+ id: string;
22
+ userAgent?: string;
23
+ ip?: string;
24
+ createdAt: string;
25
+ expiresAt: string;
26
+ }
27
+
9
28
  export class AuthModule {
10
29
  private client: PlataformaClient;
11
30
  private http: AxiosInstance;
31
+ private refreshToken: string | null = null;
12
32
 
13
33
  constructor(client: PlataformaClient, http: AxiosInstance) {
14
34
  this.client = client;
@@ -16,27 +36,30 @@ export class AuthModule {
16
36
  }
17
37
 
18
38
  /**
19
- * Autentica um usuário e armazena o token no SDK.
20
- * @param email O e-mail do usuário
21
- * @param password A senha do usuário
22
- * @returns O objeto do usuário e o token
39
+ * Login com email e senha
23
40
  */
24
- async login(email: string, password: string) {
41
+ async login(email: string, password: string): Promise<LoginResponse> {
25
42
  try {
26
- const { data } = await this.http.post("/auth/login", { email, password });
27
- // Salva o token DENTRO da instância do SDK para uso futuro
28
- this.client.setToken(data.token);
29
- return data; // Retorna { token, user: { ... } }
30
- } catch (e: unknown) {
31
- this.client.setToken(null); // Limpa o token em caso de falha
43
+ const { data } = await this.http.post<LoginResponse>("/auth/login", {
44
+ email,
45
+ password,
46
+ });
47
+
48
+ if (data.accessToken) {
49
+ this.client.setToken(data.accessToken);
50
+ this.refreshToken = data.refreshToken;
51
+ }
52
+
53
+ return data;
54
+ } catch (e) {
55
+ this.client.setToken(null);
56
+ this.refreshToken = null;
32
57
  throw e;
33
58
  }
34
59
  }
35
60
 
36
61
  /**
37
- * Registra um novo usuário e já realiza o login automaticamente.
38
- * @param credentials Nome, email e senha
39
- * @returns O objeto do usuário e o token
62
+ * Registrar novo usuário
40
63
  */
41
64
  async register(credentials: {
42
65
  name: string;
@@ -45,21 +68,86 @@ export class AuthModule {
45
68
  }) {
46
69
  try {
47
70
  const { data } = await this.http.post("/auth/register", credentials);
48
- // Se o backend retornar o token no registro, já salvamos
49
- if (data.token) {
50
- this.client.setToken(data.token);
71
+ return data;
72
+ } catch (e) {
73
+ throw e;
74
+ }
75
+ }
76
+
77
+ /**
78
+ * Renovar access token usando refresh token
79
+ */
80
+ async refresh(): Promise<{ accessToken: string }> {
81
+ if (!this.refreshToken) {
82
+ throw new Error("Nenhum refresh token disponível");
83
+ }
84
+
85
+ try {
86
+ const { data } = await this.http.post("/auth/refresh", {
87
+ refreshToken: this.refreshToken,
88
+ });
89
+
90
+ if (data.accessToken) {
91
+ this.client.setToken(data.accessToken);
51
92
  }
93
+
52
94
  return data;
53
- } catch (e: unknown) {
95
+ } catch (e) {
54
96
  this.client.setToken(null);
97
+ this.refreshToken = null;
55
98
  throw e;
56
99
  }
57
100
  }
58
101
 
59
102
  /**
60
- * Solicita um e-mail de recuperação de senha.
61
- * @param email O e-mail da conta
62
- * @returns A resposta da API (mensagem de sucesso)
103
+ * Obter URL de autenticação do Google
104
+ */
105
+ getGoogleAuthUrl(): string {
106
+ return `${this.client.apiUrl}/v1/auth/google`;
107
+ }
108
+
109
+ /**
110
+ * Logout da sessão atual
111
+ */
112
+ async logout(): Promise<void> {
113
+ if (this.refreshToken) {
114
+ try {
115
+ await this.http.post("/auth/logout", {
116
+ refreshToken: this.refreshToken,
117
+ });
118
+ } catch (e) {
119
+ // Ignora erro de logout
120
+ }
121
+ }
122
+
123
+ this.client.setToken(null);
124
+ this.refreshToken = null;
125
+ }
126
+
127
+ /**
128
+ * Logout de todas as sessões
129
+ */
130
+ async logoutAll(): Promise<void> {
131
+ try {
132
+ await this.http.post("/auth/logout-all");
133
+ } finally {
134
+ this.client.setToken(null);
135
+ this.refreshToken = null;
136
+ }
137
+ }
138
+
139
+ /**
140
+ * Listar sessões ativas
141
+ */
142
+ async getSessions(): Promise<Session[]> {
143
+ const { data } = await this.http.get<{ sessions: Session[] }>(
144
+ "/auth/sessions"
145
+ );
146
+ return data.sessions;
147
+ }
148
+
149
+ /**
150
+ * Esqueci minha senha
63
151
  */
64
152
  async forgotPassword(email: string) {
65
153
  const { data } = await this.http.post("/auth/forgot-password", { email });
@@ -67,10 +155,7 @@ export class AuthModule {
67
155
  }
68
156
 
69
157
  /**
70
- * Redefine a senha usando o token recebido por e-mail.
71
- * @param token O código/token recebido
72
- * @param newPassword A nova senha desejada
73
- * @returns A resposta da API (mensagem de sucesso)
158
+ * Redefinir senha
74
159
  */
75
160
  async resetPassword(token: string, newPassword: string) {
76
161
  const { data } = await this.http.post("/auth/reset-password", {
@@ -81,9 +166,16 @@ export class AuthModule {
81
166
  }
82
167
 
83
168
  /**
84
- * Desconecta o usuário limpando o token da memória do SDK.
169
+ * Obter refresh token atual (para armazenamento)
85
170
  */
86
- logout() {
87
- this.client.setToken(null);
171
+ getRefreshToken(): string | null {
172
+ return this.refreshToken;
88
173
  }
89
- }
174
+
175
+ /**
176
+ * Definir refresh token (para restaurar sessão)
177
+ */
178
+ setRefreshToken(token: string | null) {
179
+ this.refreshToken = token;
180
+ }
181
+ }