reddb-sdk 1.0.2 → 1.0.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.
Files changed (2) hide show
  1. package/lib/RedDBClient.js +96 -51
  2. package/package.json +1 -1
@@ -1,89 +1,134 @@
1
1
  const fetch = require('node-fetch');
2
2
 
3
3
  class RedDBClient {
4
- constructor(baseURL, reddbPassword, adminPassword = null) {
4
+ constructor(baseURL, reddbPassword, adminPassword = null, options = {}) {
5
5
  this.baseURL = baseURL.replace(/\/$/, '');
6
6
  this.reddbPassword = reddbPassword;
7
7
  this.adminPassword = adminPassword;
8
+
9
+ this.timeout = options.timeout || 5000;
10
+ this.retries = options.retries || 2;
11
+ this.debug = options.debug || false;
12
+ }
13
+
14
+ _log(...args) {
15
+ if (this.debug) console.log('[RedDB]', ...args);
8
16
  }
9
17
 
10
18
  async _safeJson(res) {
11
19
  const text = await res.text();
20
+
12
21
  try {
13
22
  return JSON.parse(text);
14
23
  } catch {
15
- throw new Error(`Resposta inválida (não é JSON):\n${text}`);
24
+ throw new Error(`Resposta inválida do servidor:\n${text}`);
16
25
  }
17
26
  }
18
27
 
19
- async set(key, value, document = 'users.json') {
20
- if (!this.adminPassword) throw new Error('Admin password required for set');
28
+ async _fetchWithTimeout(url, options) {
29
+ const controller = new AbortController();
30
+ const id = setTimeout(() => controller.abort(), this.timeout);
21
31
 
22
- const res = await fetch(`${this.baseURL}/set`, {
23
- method: 'POST',
24
- headers: { 'Content-Type': 'application/json' },
25
- body: JSON.stringify({
26
- key,
27
- value,
28
- document,
29
- reddbPassword: this.reddbPassword,
30
- adminPassword: this.adminPassword
31
- })
32
- });
32
+ try {
33
+ const res = await fetch(url, { ...options, signal: controller.signal });
34
+ clearTimeout(id);
35
+ return res;
36
+ } catch (err) {
37
+ clearTimeout(id);
33
38
 
34
- return this._safeJson(res);
39
+ if (err.name === 'AbortError') {
40
+ throw new Error('Timeout: cluster não respondeu a tempo');
41
+ }
42
+
43
+ throw new Error('Cluster offline ou inacessível');
44
+ }
35
45
  }
36
46
 
37
- async delete(key, document = 'users.json') {
38
- if (!this.adminPassword) throw new Error('Admin password required for delete');
47
+ async _request(path, options = {}, isAdmin = false) {
48
+ let url = `${this.baseURL}${path}`;
49
+ let body = options.body ? JSON.parse(options.body) : {};
50
+
51
+ body.reddbPassword = this.reddbPassword;
52
+
53
+ if (isAdmin) {
54
+ if (!this.adminPassword) throw new Error('Admin password não fornecida');
55
+ body.adminPassword = this.adminPassword;
56
+ }
57
+
58
+ const headers = { 'Content-Type': 'application/json' };
59
+
60
+ if (options.method === 'GET') {
61
+ const query = new URLSearchParams(body).toString();
62
+ url += `?${query}`;
63
+ delete options.body;
64
+ } else {
65
+ options.body = JSON.stringify(body);
66
+ }
67
+
68
+ for (let attempt = 0; attempt <= this.retries; attempt++) {
69
+ try {
70
+ this._log('Request:', options.method, url);
71
+
72
+ const res = await this._fetchWithTimeout(url, {
73
+ ...options,
74
+ headers
75
+ });
39
76
 
40
- const res = await fetch(`${this.baseURL}/delete`, {
77
+ const data = await this._safeJson(res);
78
+
79
+ if (!res.ok) {
80
+ throw new Error(data.error || `Erro HTTP ${res.status}`);
81
+ }
82
+
83
+ return data;
84
+ } catch (err) {
85
+ this._log(`Erro (tentativa ${attempt + 1}):`, err.message);
86
+
87
+ if (attempt === this.retries) {
88
+ throw new Error(`Falha após ${this.retries + 1} tentativas: ${err.message}`);
89
+ }
90
+ }
91
+ }
92
+ }
93
+
94
+ async set(key, value, document = 'users.json') {
95
+ return this._request('/set', {
41
96
  method: 'POST',
42
- headers: { 'Content-Type': 'application/json' },
43
- body: JSON.stringify({
44
- key,
45
- document,
46
- reddbPassword: this.reddbPassword,
47
- adminPassword: this.adminPassword
48
- })
49
- });
97
+ body: JSON.stringify({ key, value, document })
98
+ }, true);
99
+ }
50
100
 
51
- return this._safeJson(res);
101
+ async delete(key, document = 'users.json') {
102
+ return this._request('/delete', {
103
+ method: 'POST',
104
+ body: JSON.stringify({ key, document })
105
+ }, true);
52
106
  }
53
107
 
54
108
  async get(key, document = 'users.json') {
55
- const url = `${this.baseURL}/get/${encodeURIComponent(key)}?document=${encodeURIComponent(document)}&reddbPassword=${encodeURIComponent(this.reddbPassword)}`;
56
- const res = await fetch(url);
57
- return this._safeJson(res);
109
+ return this._request(`/get/${encodeURIComponent(key)}`, {
110
+ method: 'GET',
111
+ body: JSON.stringify({ document })
112
+ });
58
113
  }
59
114
 
60
115
  async listKeys(document = 'users.json') {
61
- const url = `${this.baseURL}/listKeys?document=${encodeURIComponent(document)}&reddbPassword=${encodeURIComponent(this.reddbPassword)}`;
62
- const res = await fetch(url);
63
- return this._safeJson(res);
116
+ return this._request('/listKeys', {
117
+ method: 'GET',
118
+ body: JSON.stringify({ document })
119
+ });
64
120
  }
65
121
 
66
122
  async reset() {
67
- if (!this.adminPassword) throw new Error('Admin password required for reset');
68
-
69
- const res = await fetch(`${this.baseURL}/admin/reset`, {
70
- method: 'POST',
71
- headers: { 'Content-Type': 'application/json' },
72
- body: JSON.stringify({
73
- reddbPassword: this.reddbPassword,
74
- adminPassword: this.adminPassword
75
- })
76
- });
77
-
78
- return this._safeJson(res);
123
+ return this._request('/admin/reset', {
124
+ method: 'POST'
125
+ }, true);
79
126
  }
80
127
 
81
128
  async listAdminKeys() {
82
- if (!this.adminPassword) throw new Error('Admin password required for listAdminKeys');
83
-
84
- const url = `${this.baseURL}/admin/keys?reddbPassword=${encodeURIComponent(this.reddbPassword)}&adminPassword=${encodeURIComponent(this.adminPassword)}`;
85
- const res = await fetch(url);
86
- return this._safeJson(res);
129
+ return this._request('/admin/keys', {
130
+ method: 'POST'
131
+ }, true);
87
132
  }
88
133
  }
89
134
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reddb-sdk",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "SDK Node.js para RedDB Cluster",
5
5
  "main": "lib/RedDBClient.js",
6
6
  "keywords": [