@supsis/supsis-js 1.0.0 → 1.1.1
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/supsis.cjs.js +174 -18
- package/dist/supsis.d.ts +4 -0
- package/dist/supsis.esm.js +174 -18
- package/dist/supsis.js +174 -18
- package/dist/supsis.min.js +4 -4
- package/dist/supsis.min.js.map +1 -1
- package/package.json +1 -1
- package/types/index.d.ts +4 -0
package/dist/supsis.cjs.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Supsis JS SDK v1.
|
|
2
|
+
* Supsis JS SDK v1.1.0
|
|
3
3
|
* Supsis API SDK - Browser ve Node.js için omnichannel messaging, chatbot, automation, task, ticket ve voice agent entegrasyonu
|
|
4
4
|
*
|
|
5
5
|
* @license MIT
|
|
6
|
-
* @author Supsis <info@
|
|
6
|
+
* @author Supsis Ai <info@softcand.com>
|
|
7
7
|
* @see https://supsis.com
|
|
8
8
|
*/
|
|
9
9
|
'use strict';
|
|
@@ -21,7 +21,7 @@ const ENVIRONMENTS = {
|
|
|
21
21
|
/** Stage/Beta API - beta-api.supsis.live */
|
|
22
22
|
stage: 'https://beta-api.supsis.live',
|
|
23
23
|
/** Local development API */
|
|
24
|
-
local: 'https://tablet-api-local.supsis.live'
|
|
24
|
+
local: 'https://tablet-api-local.supsis.live:50101'
|
|
25
25
|
};
|
|
26
26
|
|
|
27
27
|
/**
|
|
@@ -38,7 +38,9 @@ const DEFAULT_CONFIG = {
|
|
|
38
38
|
/** Başarısız isteklerde retry sayısı */
|
|
39
39
|
retryCount: 3,
|
|
40
40
|
/** Retry'lar arası bekleme süresi (ms) */
|
|
41
|
-
retryDelay: 1000
|
|
41
|
+
retryDelay: 1000,
|
|
42
|
+
/** Debug logları göster */
|
|
43
|
+
verbose: false
|
|
42
44
|
};
|
|
43
45
|
|
|
44
46
|
/**
|
|
@@ -89,12 +91,59 @@ class HttpClient {
|
|
|
89
91
|
* @param {number} [config.timeout=30000] - İstek timeout süresi (ms)
|
|
90
92
|
* @param {number} [config.retryCount=3] - Retry sayısı
|
|
91
93
|
* @param {number} [config.retryDelay=1000] - Retry arası bekleme (ms)
|
|
94
|
+
* @param {boolean} [config.verbose=false] - Debug logları göster
|
|
92
95
|
*/
|
|
93
96
|
constructor(config) {
|
|
97
|
+
config = config || {};
|
|
94
98
|
this.config = Object.assign({}, DEFAULT_CONFIG, config);
|
|
95
99
|
this.baseUrl = this._resolveBaseUrl();
|
|
96
100
|
this.token = null;
|
|
97
|
-
this.siteId = config.siteId || null;
|
|
101
|
+
this.siteId = this.config.siteId || null;
|
|
102
|
+
this.verbose = this.config.verbose || false;
|
|
103
|
+
|
|
104
|
+
// Debug: config değerlerini logla
|
|
105
|
+
if (this.verbose) {
|
|
106
|
+
console.log('[SupsisJS] HttpClient config:', {
|
|
107
|
+
timeout: this.config.timeout,
|
|
108
|
+
retryCount: this.config.retryCount,
|
|
109
|
+
env: this.config.env,
|
|
110
|
+
baseUrl: this.baseUrl
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Verbose log yazdırır
|
|
117
|
+
* @private
|
|
118
|
+
* @param {string} type - Log tipi (info, warn, error, request, response)
|
|
119
|
+
* @param {...any} args - Log argümanları
|
|
120
|
+
*/
|
|
121
|
+
_log(type) {
|
|
122
|
+
if (!this.verbose) return;
|
|
123
|
+
|
|
124
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
|
125
|
+
var prefix = '[SupsisJS]';
|
|
126
|
+
var timestamp = new Date().toISOString();
|
|
127
|
+
|
|
128
|
+
switch (type) {
|
|
129
|
+
case 'info':
|
|
130
|
+
console.log.apply(console, [prefix, timestamp, 'INFO:'].concat(args));
|
|
131
|
+
break;
|
|
132
|
+
case 'warn':
|
|
133
|
+
console.warn.apply(console, [prefix, timestamp, 'WARN:'].concat(args));
|
|
134
|
+
break;
|
|
135
|
+
case 'error':
|
|
136
|
+
console.error.apply(console, [prefix, timestamp, 'ERROR:'].concat(args));
|
|
137
|
+
break;
|
|
138
|
+
case 'request':
|
|
139
|
+
console.log.apply(console, [prefix, timestamp, '→ REQUEST:'].concat(args));
|
|
140
|
+
break;
|
|
141
|
+
case 'response':
|
|
142
|
+
console.log.apply(console, [prefix, timestamp, '← RESPONSE:'].concat(args));
|
|
143
|
+
break;
|
|
144
|
+
default:
|
|
145
|
+
console.log.apply(console, [prefix, timestamp].concat(args));
|
|
146
|
+
}
|
|
98
147
|
}
|
|
99
148
|
|
|
100
149
|
/**
|
|
@@ -153,16 +202,28 @@ class HttpClient {
|
|
|
153
202
|
fetchOptions.body = JSON.stringify(options.body);
|
|
154
203
|
}
|
|
155
204
|
|
|
205
|
+
this._log('request', method.toUpperCase(), url, options.body ? JSON.stringify(options.body).substring(0, 200) : '');
|
|
206
|
+
|
|
156
207
|
let lastError;
|
|
157
208
|
const retryCount = options.retryCount !== undefined ? options.retryCount : this.config.retryCount;
|
|
158
209
|
|
|
159
210
|
for (let attempt = 0; attempt <= retryCount; attempt++) {
|
|
160
211
|
try {
|
|
212
|
+
if (attempt > 0) {
|
|
213
|
+
this._log('info', 'Retry attempt', attempt, 'of', retryCount);
|
|
214
|
+
}
|
|
215
|
+
|
|
161
216
|
const response = await this._fetchWithTimeout(url, fetchOptions);
|
|
162
|
-
|
|
217
|
+
const data = await this._handleResponse(response);
|
|
218
|
+
|
|
219
|
+
this._log('response', response.status, endpoint, typeof data === 'object' ? JSON.stringify(data).substring(0, 200) : data);
|
|
220
|
+
|
|
221
|
+
return data;
|
|
163
222
|
} catch (error) {
|
|
164
223
|
lastError = error;
|
|
165
224
|
|
|
225
|
+
this._log('error', 'Request failed:', error.message, 'Status:', error.statusCode || 'N/A');
|
|
226
|
+
|
|
166
227
|
// Auth hatalarında retry yapma
|
|
167
228
|
if (error.statusCode === HTTP_STATUS.UNAUTHORIZED ||
|
|
168
229
|
error.statusCode === HTTP_STATUS.FORBIDDEN) {
|
|
@@ -171,6 +232,7 @@ class HttpClient {
|
|
|
171
232
|
|
|
172
233
|
// Son deneme değilse bekle ve tekrar dene
|
|
173
234
|
if (attempt < retryCount) {
|
|
235
|
+
this._log('info', 'Waiting', this.config.retryDelay * (attempt + 1), 'ms before retry...');
|
|
174
236
|
await this._sleep(this.config.retryDelay * (attempt + 1));
|
|
175
237
|
}
|
|
176
238
|
}
|
|
@@ -184,23 +246,62 @@ class HttpClient {
|
|
|
184
246
|
* @private
|
|
185
247
|
*/
|
|
186
248
|
async _fetchWithTimeout(url, options) {
|
|
187
|
-
|
|
188
|
-
|
|
249
|
+
var self = this;
|
|
250
|
+
var timeout = this.config.timeout || 30000;
|
|
251
|
+
var controller = new AbortController();
|
|
252
|
+
var timeoutId = setTimeout(function() {
|
|
189
253
|
controller.abort();
|
|
190
|
-
},
|
|
254
|
+
}, timeout);
|
|
255
|
+
|
|
256
|
+
self._log('info', 'Fetch timeout set to:', timeout, 'ms');
|
|
191
257
|
|
|
192
258
|
try {
|
|
193
|
-
|
|
259
|
+
var response = await fetch(url, Object.assign({}, options, {
|
|
194
260
|
signal: controller.signal
|
|
195
261
|
}));
|
|
196
262
|
clearTimeout(timeoutId);
|
|
197
263
|
return response;
|
|
198
264
|
} catch (error) {
|
|
199
265
|
clearTimeout(timeoutId);
|
|
266
|
+
|
|
267
|
+
// Detaylı hata bilgisi
|
|
268
|
+
self._log('error', 'Fetch error details:', {
|
|
269
|
+
name: error.name,
|
|
270
|
+
message: error.message,
|
|
271
|
+
code: error.code,
|
|
272
|
+
cause: error.cause ? String(error.cause) : undefined
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
// AbortError - gerçek timeout mu yoksa başka bir sebep mi?
|
|
200
276
|
if (error.name === 'AbortError') {
|
|
201
|
-
|
|
277
|
+
// error.cause varsa gerçek sebebi göster
|
|
278
|
+
var realCause = error.cause ? String(error.cause) : error.message;
|
|
279
|
+
throw new SupsisAPIError('Request aborted: ' + realCause, 408, {
|
|
280
|
+
originalError: error.message,
|
|
281
|
+
cause: realCause,
|
|
282
|
+
timeout: timeout
|
|
283
|
+
});
|
|
202
284
|
}
|
|
203
|
-
|
|
285
|
+
|
|
286
|
+
// Network hataları için daha açıklayıcı hata mesajı
|
|
287
|
+
if (error.code === 'ECONNREFUSED') {
|
|
288
|
+
throw new SupsisAPIError('Connection refused: ' + url, 0, { originalError: error.message, code: error.code });
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (error.code === 'ENOTFOUND') {
|
|
292
|
+
throw new SupsisAPIError('Host not found: ' + url, 0, { originalError: error.message, code: error.code });
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (error.code === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' || error.code === 'CERT_HAS_EXPIRED' || error.code === 'DEPTH_ZERO_SELF_SIGNED_CERT') {
|
|
296
|
+
throw new SupsisAPIError('SSL/TLS certificate error: ' + error.message, 0, { originalError: error.message, code: error.code });
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Diğer hatalar için SupsisAPIError'a çevir
|
|
300
|
+
throw new SupsisAPIError(error.message || 'Unknown fetch error', 0, {
|
|
301
|
+
originalError: error.message,
|
|
302
|
+
code: error.code,
|
|
303
|
+
cause: error.cause ? String(error.cause) : undefined
|
|
304
|
+
});
|
|
204
305
|
}
|
|
205
306
|
}
|
|
206
307
|
|
|
@@ -3668,13 +3769,17 @@ class SupsisJS {
|
|
|
3668
3769
|
/** @private */
|
|
3669
3770
|
this._config = config;
|
|
3670
3771
|
|
|
3772
|
+
/** @private */
|
|
3773
|
+
this._verbose = config.verbose || false;
|
|
3774
|
+
|
|
3671
3775
|
/** @private */
|
|
3672
3776
|
this._http = new HttpClient({
|
|
3673
3777
|
env: config.env || 'production',
|
|
3674
3778
|
baseApiAddress: config.baseApiAddress,
|
|
3675
3779
|
siteId: config.siteId,
|
|
3676
3780
|
timeout: config.timeout,
|
|
3677
|
-
retryCount: config.retryCount
|
|
3781
|
+
retryCount: config.retryCount,
|
|
3782
|
+
verbose: config.verbose
|
|
3678
3783
|
});
|
|
3679
3784
|
|
|
3680
3785
|
/** @private */
|
|
@@ -3688,6 +3793,38 @@ class SupsisJS {
|
|
|
3688
3793
|
|
|
3689
3794
|
// Modülleri oluştur
|
|
3690
3795
|
this._initModules();
|
|
3796
|
+
|
|
3797
|
+
this._log('info', 'SupsisJS initialized', {
|
|
3798
|
+
env: config.env || 'production',
|
|
3799
|
+
baseApiAddress: config.baseApiAddress || 'default',
|
|
3800
|
+
siteId: config.siteId
|
|
3801
|
+
});
|
|
3802
|
+
}
|
|
3803
|
+
|
|
3804
|
+
/**
|
|
3805
|
+
* Verbose log yazdırır
|
|
3806
|
+
* @private
|
|
3807
|
+
*/
|
|
3808
|
+
_log(type) {
|
|
3809
|
+
if (!this._verbose) return;
|
|
3810
|
+
|
|
3811
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
|
3812
|
+
var prefix = '[SupsisJS]';
|
|
3813
|
+
var timestamp = new Date().toISOString();
|
|
3814
|
+
|
|
3815
|
+
switch (type) {
|
|
3816
|
+
case 'info':
|
|
3817
|
+
console.log.apply(console, [prefix, timestamp, 'INFO:'].concat(args));
|
|
3818
|
+
break;
|
|
3819
|
+
case 'warn':
|
|
3820
|
+
console.warn.apply(console, [prefix, timestamp, 'WARN:'].concat(args));
|
|
3821
|
+
break;
|
|
3822
|
+
case 'error':
|
|
3823
|
+
console.error.apply(console, [prefix, timestamp, 'ERROR:'].concat(args));
|
|
3824
|
+
break;
|
|
3825
|
+
default:
|
|
3826
|
+
console.log.apply(console, [prefix, timestamp].concat(args));
|
|
3827
|
+
}
|
|
3691
3828
|
}
|
|
3692
3829
|
|
|
3693
3830
|
/**
|
|
@@ -3793,17 +3930,34 @@ class SupsisJS {
|
|
|
3793
3930
|
* console.log('Connected as:', supsis.currentUser.fullname);
|
|
3794
3931
|
*/
|
|
3795
3932
|
async connect() {
|
|
3933
|
+
var self = this;
|
|
3934
|
+
|
|
3796
3935
|
if (this._connected) {
|
|
3936
|
+
this._log('info', 'Already connected');
|
|
3797
3937
|
return this._user;
|
|
3798
3938
|
}
|
|
3799
3939
|
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3940
|
+
this._log('info', 'Connecting to Supsis API...');
|
|
3941
|
+
this._log('info', 'Base URL:', this._http.baseUrl);
|
|
3942
|
+
|
|
3943
|
+
var response;
|
|
3944
|
+
try {
|
|
3945
|
+
response = await this._http.post('/api/users/login', {
|
|
3946
|
+
email: this._config.email,
|
|
3947
|
+
password: this._config.password
|
|
3948
|
+
}, { skipAuth: true, retryCount: 0 });
|
|
3949
|
+
} catch (error) {
|
|
3950
|
+
self._log('error', 'Login failed:', error.message);
|
|
3951
|
+
throw error;
|
|
3952
|
+
}
|
|
3804
3953
|
|
|
3805
3954
|
if (!response || !response.token) {
|
|
3806
|
-
|
|
3955
|
+
var errorMsg = 'Login failed: No token received';
|
|
3956
|
+
if (response && response.message) {
|
|
3957
|
+
errorMsg = 'Login failed: ' + response.message;
|
|
3958
|
+
}
|
|
3959
|
+
self._log('error', errorMsg);
|
|
3960
|
+
throw new SupsisAPIError(errorMsg, 401, response);
|
|
3807
3961
|
}
|
|
3808
3962
|
|
|
3809
3963
|
this._token = response.token;
|
|
@@ -3811,6 +3965,8 @@ class SupsisJS {
|
|
|
3811
3965
|
this._http.setToken(this._token);
|
|
3812
3966
|
this._connected = true;
|
|
3813
3967
|
|
|
3968
|
+
this._log('info', 'Connected successfully as:', this._user.fullname || this._user.email);
|
|
3969
|
+
|
|
3814
3970
|
return this._user;
|
|
3815
3971
|
}
|
|
3816
3972
|
|
package/dist/supsis.d.ts
CHANGED
|
@@ -24,6 +24,8 @@ export interface SupsisConfig {
|
|
|
24
24
|
timeout?: number;
|
|
25
25
|
/** Başarısız isteklerde retry sayısı - default: 3 */
|
|
26
26
|
retryCount?: number;
|
|
27
|
+
/** Debug logları göster - default: false */
|
|
28
|
+
verbose?: boolean;
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
/**
|
|
@@ -42,6 +44,8 @@ export interface ModuleAPIConfig {
|
|
|
42
44
|
timeout?: number;
|
|
43
45
|
/** Başarısız isteklerde retry sayısı */
|
|
44
46
|
retryCount?: number;
|
|
47
|
+
/** Debug logları göster - default: false */
|
|
48
|
+
verbose?: boolean;
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
// ==================== RESPONSE TYPES ====================
|
package/dist/supsis.esm.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Supsis JS SDK v1.
|
|
2
|
+
* Supsis JS SDK v1.1.0
|
|
3
3
|
* Supsis API SDK - Browser ve Node.js için omnichannel messaging, chatbot, automation, task, ticket ve voice agent entegrasyonu
|
|
4
4
|
*
|
|
5
5
|
* @license MIT
|
|
6
|
-
* @author Supsis <info@
|
|
6
|
+
* @author Supsis Ai <info@softcand.com>
|
|
7
7
|
* @see https://supsis.com
|
|
8
8
|
*/
|
|
9
9
|
/**
|
|
@@ -17,7 +17,7 @@ const ENVIRONMENTS = {
|
|
|
17
17
|
/** Stage/Beta API - beta-api.supsis.live */
|
|
18
18
|
stage: 'https://beta-api.supsis.live',
|
|
19
19
|
/** Local development API */
|
|
20
|
-
local: 'https://tablet-api-local.supsis.live'
|
|
20
|
+
local: 'https://tablet-api-local.supsis.live:50101'
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
/**
|
|
@@ -34,7 +34,9 @@ const DEFAULT_CONFIG = {
|
|
|
34
34
|
/** Başarısız isteklerde retry sayısı */
|
|
35
35
|
retryCount: 3,
|
|
36
36
|
/** Retry'lar arası bekleme süresi (ms) */
|
|
37
|
-
retryDelay: 1000
|
|
37
|
+
retryDelay: 1000,
|
|
38
|
+
/** Debug logları göster */
|
|
39
|
+
verbose: false
|
|
38
40
|
};
|
|
39
41
|
|
|
40
42
|
/**
|
|
@@ -85,12 +87,59 @@ class HttpClient {
|
|
|
85
87
|
* @param {number} [config.timeout=30000] - İstek timeout süresi (ms)
|
|
86
88
|
* @param {number} [config.retryCount=3] - Retry sayısı
|
|
87
89
|
* @param {number} [config.retryDelay=1000] - Retry arası bekleme (ms)
|
|
90
|
+
* @param {boolean} [config.verbose=false] - Debug logları göster
|
|
88
91
|
*/
|
|
89
92
|
constructor(config) {
|
|
93
|
+
config = config || {};
|
|
90
94
|
this.config = Object.assign({}, DEFAULT_CONFIG, config);
|
|
91
95
|
this.baseUrl = this._resolveBaseUrl();
|
|
92
96
|
this.token = null;
|
|
93
|
-
this.siteId = config.siteId || null;
|
|
97
|
+
this.siteId = this.config.siteId || null;
|
|
98
|
+
this.verbose = this.config.verbose || false;
|
|
99
|
+
|
|
100
|
+
// Debug: config değerlerini logla
|
|
101
|
+
if (this.verbose) {
|
|
102
|
+
console.log('[SupsisJS] HttpClient config:', {
|
|
103
|
+
timeout: this.config.timeout,
|
|
104
|
+
retryCount: this.config.retryCount,
|
|
105
|
+
env: this.config.env,
|
|
106
|
+
baseUrl: this.baseUrl
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Verbose log yazdırır
|
|
113
|
+
* @private
|
|
114
|
+
* @param {string} type - Log tipi (info, warn, error, request, response)
|
|
115
|
+
* @param {...any} args - Log argümanları
|
|
116
|
+
*/
|
|
117
|
+
_log(type) {
|
|
118
|
+
if (!this.verbose) return;
|
|
119
|
+
|
|
120
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
|
121
|
+
var prefix = '[SupsisJS]';
|
|
122
|
+
var timestamp = new Date().toISOString();
|
|
123
|
+
|
|
124
|
+
switch (type) {
|
|
125
|
+
case 'info':
|
|
126
|
+
console.log.apply(console, [prefix, timestamp, 'INFO:'].concat(args));
|
|
127
|
+
break;
|
|
128
|
+
case 'warn':
|
|
129
|
+
console.warn.apply(console, [prefix, timestamp, 'WARN:'].concat(args));
|
|
130
|
+
break;
|
|
131
|
+
case 'error':
|
|
132
|
+
console.error.apply(console, [prefix, timestamp, 'ERROR:'].concat(args));
|
|
133
|
+
break;
|
|
134
|
+
case 'request':
|
|
135
|
+
console.log.apply(console, [prefix, timestamp, '→ REQUEST:'].concat(args));
|
|
136
|
+
break;
|
|
137
|
+
case 'response':
|
|
138
|
+
console.log.apply(console, [prefix, timestamp, '← RESPONSE:'].concat(args));
|
|
139
|
+
break;
|
|
140
|
+
default:
|
|
141
|
+
console.log.apply(console, [prefix, timestamp].concat(args));
|
|
142
|
+
}
|
|
94
143
|
}
|
|
95
144
|
|
|
96
145
|
/**
|
|
@@ -149,16 +198,28 @@ class HttpClient {
|
|
|
149
198
|
fetchOptions.body = JSON.stringify(options.body);
|
|
150
199
|
}
|
|
151
200
|
|
|
201
|
+
this._log('request', method.toUpperCase(), url, options.body ? JSON.stringify(options.body).substring(0, 200) : '');
|
|
202
|
+
|
|
152
203
|
let lastError;
|
|
153
204
|
const retryCount = options.retryCount !== undefined ? options.retryCount : this.config.retryCount;
|
|
154
205
|
|
|
155
206
|
for (let attempt = 0; attempt <= retryCount; attempt++) {
|
|
156
207
|
try {
|
|
208
|
+
if (attempt > 0) {
|
|
209
|
+
this._log('info', 'Retry attempt', attempt, 'of', retryCount);
|
|
210
|
+
}
|
|
211
|
+
|
|
157
212
|
const response = await this._fetchWithTimeout(url, fetchOptions);
|
|
158
|
-
|
|
213
|
+
const data = await this._handleResponse(response);
|
|
214
|
+
|
|
215
|
+
this._log('response', response.status, endpoint, typeof data === 'object' ? JSON.stringify(data).substring(0, 200) : data);
|
|
216
|
+
|
|
217
|
+
return data;
|
|
159
218
|
} catch (error) {
|
|
160
219
|
lastError = error;
|
|
161
220
|
|
|
221
|
+
this._log('error', 'Request failed:', error.message, 'Status:', error.statusCode || 'N/A');
|
|
222
|
+
|
|
162
223
|
// Auth hatalarında retry yapma
|
|
163
224
|
if (error.statusCode === HTTP_STATUS.UNAUTHORIZED ||
|
|
164
225
|
error.statusCode === HTTP_STATUS.FORBIDDEN) {
|
|
@@ -167,6 +228,7 @@ class HttpClient {
|
|
|
167
228
|
|
|
168
229
|
// Son deneme değilse bekle ve tekrar dene
|
|
169
230
|
if (attempt < retryCount) {
|
|
231
|
+
this._log('info', 'Waiting', this.config.retryDelay * (attempt + 1), 'ms before retry...');
|
|
170
232
|
await this._sleep(this.config.retryDelay * (attempt + 1));
|
|
171
233
|
}
|
|
172
234
|
}
|
|
@@ -180,23 +242,62 @@ class HttpClient {
|
|
|
180
242
|
* @private
|
|
181
243
|
*/
|
|
182
244
|
async _fetchWithTimeout(url, options) {
|
|
183
|
-
|
|
184
|
-
|
|
245
|
+
var self = this;
|
|
246
|
+
var timeout = this.config.timeout || 30000;
|
|
247
|
+
var controller = new AbortController();
|
|
248
|
+
var timeoutId = setTimeout(function() {
|
|
185
249
|
controller.abort();
|
|
186
|
-
},
|
|
250
|
+
}, timeout);
|
|
251
|
+
|
|
252
|
+
self._log('info', 'Fetch timeout set to:', timeout, 'ms');
|
|
187
253
|
|
|
188
254
|
try {
|
|
189
|
-
|
|
255
|
+
var response = await fetch(url, Object.assign({}, options, {
|
|
190
256
|
signal: controller.signal
|
|
191
257
|
}));
|
|
192
258
|
clearTimeout(timeoutId);
|
|
193
259
|
return response;
|
|
194
260
|
} catch (error) {
|
|
195
261
|
clearTimeout(timeoutId);
|
|
262
|
+
|
|
263
|
+
// Detaylı hata bilgisi
|
|
264
|
+
self._log('error', 'Fetch error details:', {
|
|
265
|
+
name: error.name,
|
|
266
|
+
message: error.message,
|
|
267
|
+
code: error.code,
|
|
268
|
+
cause: error.cause ? String(error.cause) : undefined
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
// AbortError - gerçek timeout mu yoksa başka bir sebep mi?
|
|
196
272
|
if (error.name === 'AbortError') {
|
|
197
|
-
|
|
273
|
+
// error.cause varsa gerçek sebebi göster
|
|
274
|
+
var realCause = error.cause ? String(error.cause) : error.message;
|
|
275
|
+
throw new SupsisAPIError('Request aborted: ' + realCause, 408, {
|
|
276
|
+
originalError: error.message,
|
|
277
|
+
cause: realCause,
|
|
278
|
+
timeout: timeout
|
|
279
|
+
});
|
|
198
280
|
}
|
|
199
|
-
|
|
281
|
+
|
|
282
|
+
// Network hataları için daha açıklayıcı hata mesajı
|
|
283
|
+
if (error.code === 'ECONNREFUSED') {
|
|
284
|
+
throw new SupsisAPIError('Connection refused: ' + url, 0, { originalError: error.message, code: error.code });
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (error.code === 'ENOTFOUND') {
|
|
288
|
+
throw new SupsisAPIError('Host not found: ' + url, 0, { originalError: error.message, code: error.code });
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
if (error.code === 'UNABLE_TO_VERIFY_LEAF_SIGNATURE' || error.code === 'CERT_HAS_EXPIRED' || error.code === 'DEPTH_ZERO_SELF_SIGNED_CERT') {
|
|
292
|
+
throw new SupsisAPIError('SSL/TLS certificate error: ' + error.message, 0, { originalError: error.message, code: error.code });
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Diğer hatalar için SupsisAPIError'a çevir
|
|
296
|
+
throw new SupsisAPIError(error.message || 'Unknown fetch error', 0, {
|
|
297
|
+
originalError: error.message,
|
|
298
|
+
code: error.code,
|
|
299
|
+
cause: error.cause ? String(error.cause) : undefined
|
|
300
|
+
});
|
|
200
301
|
}
|
|
201
302
|
}
|
|
202
303
|
|
|
@@ -3664,13 +3765,17 @@ class SupsisJS {
|
|
|
3664
3765
|
/** @private */
|
|
3665
3766
|
this._config = config;
|
|
3666
3767
|
|
|
3768
|
+
/** @private */
|
|
3769
|
+
this._verbose = config.verbose || false;
|
|
3770
|
+
|
|
3667
3771
|
/** @private */
|
|
3668
3772
|
this._http = new HttpClient({
|
|
3669
3773
|
env: config.env || 'production',
|
|
3670
3774
|
baseApiAddress: config.baseApiAddress,
|
|
3671
3775
|
siteId: config.siteId,
|
|
3672
3776
|
timeout: config.timeout,
|
|
3673
|
-
retryCount: config.retryCount
|
|
3777
|
+
retryCount: config.retryCount,
|
|
3778
|
+
verbose: config.verbose
|
|
3674
3779
|
});
|
|
3675
3780
|
|
|
3676
3781
|
/** @private */
|
|
@@ -3684,6 +3789,38 @@ class SupsisJS {
|
|
|
3684
3789
|
|
|
3685
3790
|
// Modülleri oluştur
|
|
3686
3791
|
this._initModules();
|
|
3792
|
+
|
|
3793
|
+
this._log('info', 'SupsisJS initialized', {
|
|
3794
|
+
env: config.env || 'production',
|
|
3795
|
+
baseApiAddress: config.baseApiAddress || 'default',
|
|
3796
|
+
siteId: config.siteId
|
|
3797
|
+
});
|
|
3798
|
+
}
|
|
3799
|
+
|
|
3800
|
+
/**
|
|
3801
|
+
* Verbose log yazdırır
|
|
3802
|
+
* @private
|
|
3803
|
+
*/
|
|
3804
|
+
_log(type) {
|
|
3805
|
+
if (!this._verbose) return;
|
|
3806
|
+
|
|
3807
|
+
var args = Array.prototype.slice.call(arguments, 1);
|
|
3808
|
+
var prefix = '[SupsisJS]';
|
|
3809
|
+
var timestamp = new Date().toISOString();
|
|
3810
|
+
|
|
3811
|
+
switch (type) {
|
|
3812
|
+
case 'info':
|
|
3813
|
+
console.log.apply(console, [prefix, timestamp, 'INFO:'].concat(args));
|
|
3814
|
+
break;
|
|
3815
|
+
case 'warn':
|
|
3816
|
+
console.warn.apply(console, [prefix, timestamp, 'WARN:'].concat(args));
|
|
3817
|
+
break;
|
|
3818
|
+
case 'error':
|
|
3819
|
+
console.error.apply(console, [prefix, timestamp, 'ERROR:'].concat(args));
|
|
3820
|
+
break;
|
|
3821
|
+
default:
|
|
3822
|
+
console.log.apply(console, [prefix, timestamp].concat(args));
|
|
3823
|
+
}
|
|
3687
3824
|
}
|
|
3688
3825
|
|
|
3689
3826
|
/**
|
|
@@ -3789,17 +3926,34 @@ class SupsisJS {
|
|
|
3789
3926
|
* console.log('Connected as:', supsis.currentUser.fullname);
|
|
3790
3927
|
*/
|
|
3791
3928
|
async connect() {
|
|
3929
|
+
var self = this;
|
|
3930
|
+
|
|
3792
3931
|
if (this._connected) {
|
|
3932
|
+
this._log('info', 'Already connected');
|
|
3793
3933
|
return this._user;
|
|
3794
3934
|
}
|
|
3795
3935
|
|
|
3796
|
-
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3936
|
+
this._log('info', 'Connecting to Supsis API...');
|
|
3937
|
+
this._log('info', 'Base URL:', this._http.baseUrl);
|
|
3938
|
+
|
|
3939
|
+
var response;
|
|
3940
|
+
try {
|
|
3941
|
+
response = await this._http.post('/api/users/login', {
|
|
3942
|
+
email: this._config.email,
|
|
3943
|
+
password: this._config.password
|
|
3944
|
+
}, { skipAuth: true, retryCount: 0 });
|
|
3945
|
+
} catch (error) {
|
|
3946
|
+
self._log('error', 'Login failed:', error.message);
|
|
3947
|
+
throw error;
|
|
3948
|
+
}
|
|
3800
3949
|
|
|
3801
3950
|
if (!response || !response.token) {
|
|
3802
|
-
|
|
3951
|
+
var errorMsg = 'Login failed: No token received';
|
|
3952
|
+
if (response && response.message) {
|
|
3953
|
+
errorMsg = 'Login failed: ' + response.message;
|
|
3954
|
+
}
|
|
3955
|
+
self._log('error', errorMsg);
|
|
3956
|
+
throw new SupsisAPIError(errorMsg, 401, response);
|
|
3803
3957
|
}
|
|
3804
3958
|
|
|
3805
3959
|
this._token = response.token;
|
|
@@ -3807,6 +3961,8 @@ class SupsisJS {
|
|
|
3807
3961
|
this._http.setToken(this._token);
|
|
3808
3962
|
this._connected = true;
|
|
3809
3963
|
|
|
3964
|
+
this._log('info', 'Connected successfully as:', this._user.fullname || this._user.email);
|
|
3965
|
+
|
|
3810
3966
|
return this._user;
|
|
3811
3967
|
}
|
|
3812
3968
|
|