@supsis/supsis-js 1.0.0 → 1.1.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.
@@ -3,7 +3,7 @@
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@supsis.com>
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,48 @@ 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) {
94
97
  this.config = Object.assign({}, DEFAULT_CONFIG, config);
95
98
  this.baseUrl = this._resolveBaseUrl();
96
99
  this.token = null;
97
100
  this.siteId = config.siteId || null;
101
+ this.verbose = config.verbose || false;
102
+ }
103
+
104
+ /**
105
+ * Verbose log yazdırır
106
+ * @private
107
+ * @param {string} type - Log tipi (info, warn, error, request, response)
108
+ * @param {...any} args - Log argümanları
109
+ */
110
+ _log(type) {
111
+ if (!this.verbose) return;
112
+
113
+ var args = Array.prototype.slice.call(arguments, 1);
114
+ var prefix = '[SupsisJS]';
115
+ var timestamp = new Date().toISOString();
116
+
117
+ switch (type) {
118
+ case 'info':
119
+ console.log.apply(console, [prefix, timestamp, 'INFO:'].concat(args));
120
+ break;
121
+ case 'warn':
122
+ console.warn.apply(console, [prefix, timestamp, 'WARN:'].concat(args));
123
+ break;
124
+ case 'error':
125
+ console.error.apply(console, [prefix, timestamp, 'ERROR:'].concat(args));
126
+ break;
127
+ case 'request':
128
+ console.log.apply(console, [prefix, timestamp, '→ REQUEST:'].concat(args));
129
+ break;
130
+ case 'response':
131
+ console.log.apply(console, [prefix, timestamp, '← RESPONSE:'].concat(args));
132
+ break;
133
+ default:
134
+ console.log.apply(console, [prefix, timestamp].concat(args));
135
+ }
98
136
  }
99
137
 
100
138
  /**
@@ -153,16 +191,28 @@ class HttpClient {
153
191
  fetchOptions.body = JSON.stringify(options.body);
154
192
  }
155
193
 
194
+ this._log('request', method.toUpperCase(), url, options.body ? JSON.stringify(options.body).substring(0, 200) : '');
195
+
156
196
  let lastError;
157
197
  const retryCount = options.retryCount !== undefined ? options.retryCount : this.config.retryCount;
158
198
 
159
199
  for (let attempt = 0; attempt <= retryCount; attempt++) {
160
200
  try {
201
+ if (attempt > 0) {
202
+ this._log('info', 'Retry attempt', attempt, 'of', retryCount);
203
+ }
204
+
161
205
  const response = await this._fetchWithTimeout(url, fetchOptions);
162
- return await this._handleResponse(response);
206
+ const data = await this._handleResponse(response);
207
+
208
+ this._log('response', response.status, endpoint, typeof data === 'object' ? JSON.stringify(data).substring(0, 200) : data);
209
+
210
+ return data;
163
211
  } catch (error) {
164
212
  lastError = error;
165
213
 
214
+ this._log('error', 'Request failed:', error.message, 'Status:', error.statusCode || 'N/A');
215
+
166
216
  // Auth hatalarında retry yapma
167
217
  if (error.statusCode === HTTP_STATUS.UNAUTHORIZED ||
168
218
  error.statusCode === HTTP_STATUS.FORBIDDEN) {
@@ -171,6 +221,7 @@ class HttpClient {
171
221
 
172
222
  // Son deneme değilse bekle ve tekrar dene
173
223
  if (attempt < retryCount) {
224
+ this._log('info', 'Waiting', this.config.retryDelay * (attempt + 1), 'ms before retry...');
174
225
  await this._sleep(this.config.retryDelay * (attempt + 1));
175
226
  }
176
227
  }
@@ -184,23 +235,34 @@ class HttpClient {
184
235
  * @private
185
236
  */
186
237
  async _fetchWithTimeout(url, options) {
187
- const controller = new AbortController();
188
- const timeoutId = setTimeout(function() {
238
+ var self = this;
239
+ var controller = new AbortController();
240
+ var timeoutId = setTimeout(function() {
189
241
  controller.abort();
190
242
  }, this.config.timeout);
191
243
 
192
244
  try {
193
- const response = await fetch(url, Object.assign({}, options, {
245
+ var response = await fetch(url, Object.assign({}, options, {
194
246
  signal: controller.signal
195
247
  }));
196
248
  clearTimeout(timeoutId);
197
249
  return response;
198
250
  } catch (error) {
199
251
  clearTimeout(timeoutId);
252
+
253
+ self._log('error', 'Fetch error:', error.name, error.message);
254
+
200
255
  if (error.name === 'AbortError') {
201
- throw new SupsisAPIError('Request timeout', 408);
256
+ throw new SupsisAPIError('Request timeout after ' + self.config.timeout + 'ms', 408, { originalError: error.message });
202
257
  }
203
- throw error;
258
+
259
+ // Network hataları için daha açıklayıcı hata mesajı
260
+ if (error.code === 'ECONNREFUSED' || error.code === 'ENOTFOUND' || error.message.indexOf('fetch') !== -1) {
261
+ throw new SupsisAPIError('Network error: ' + error.message, 0, { originalError: error.message, code: error.code });
262
+ }
263
+
264
+ // Diğer hatalar için SupsisAPIError'a çevir
265
+ throw new SupsisAPIError(error.message || 'Unknown fetch error', 0, { originalError: error.message });
204
266
  }
205
267
  }
206
268
 
@@ -3668,13 +3730,17 @@ class SupsisJS {
3668
3730
  /** @private */
3669
3731
  this._config = config;
3670
3732
 
3733
+ /** @private */
3734
+ this._verbose = config.verbose || false;
3735
+
3671
3736
  /** @private */
3672
3737
  this._http = new HttpClient({
3673
3738
  env: config.env || 'production',
3674
3739
  baseApiAddress: config.baseApiAddress,
3675
3740
  siteId: config.siteId,
3676
3741
  timeout: config.timeout,
3677
- retryCount: config.retryCount
3742
+ retryCount: config.retryCount,
3743
+ verbose: config.verbose
3678
3744
  });
3679
3745
 
3680
3746
  /** @private */
@@ -3688,6 +3754,38 @@ class SupsisJS {
3688
3754
 
3689
3755
  // Modülleri oluştur
3690
3756
  this._initModules();
3757
+
3758
+ this._log('info', 'SupsisJS initialized', {
3759
+ env: config.env || 'production',
3760
+ baseApiAddress: config.baseApiAddress || 'default',
3761
+ siteId: config.siteId
3762
+ });
3763
+ }
3764
+
3765
+ /**
3766
+ * Verbose log yazdırır
3767
+ * @private
3768
+ */
3769
+ _log(type) {
3770
+ if (!this._verbose) return;
3771
+
3772
+ var args = Array.prototype.slice.call(arguments, 1);
3773
+ var prefix = '[SupsisJS]';
3774
+ var timestamp = new Date().toISOString();
3775
+
3776
+ switch (type) {
3777
+ case 'info':
3778
+ console.log.apply(console, [prefix, timestamp, 'INFO:'].concat(args));
3779
+ break;
3780
+ case 'warn':
3781
+ console.warn.apply(console, [prefix, timestamp, 'WARN:'].concat(args));
3782
+ break;
3783
+ case 'error':
3784
+ console.error.apply(console, [prefix, timestamp, 'ERROR:'].concat(args));
3785
+ break;
3786
+ default:
3787
+ console.log.apply(console, [prefix, timestamp].concat(args));
3788
+ }
3691
3789
  }
3692
3790
 
3693
3791
  /**
@@ -3793,17 +3891,34 @@ class SupsisJS {
3793
3891
  * console.log('Connected as:', supsis.currentUser.fullname);
3794
3892
  */
3795
3893
  async connect() {
3894
+ var self = this;
3895
+
3796
3896
  if (this._connected) {
3897
+ this._log('info', 'Already connected');
3797
3898
  return this._user;
3798
3899
  }
3799
3900
 
3800
- const response = await this._http.post('/api/users/login', {
3801
- email: this._config.email,
3802
- password: this._config.password
3803
- }, { skipAuth: true });
3901
+ this._log('info', 'Connecting to Supsis API...');
3902
+ this._log('info', 'Base URL:', this._http.baseUrl);
3903
+
3904
+ var response;
3905
+ try {
3906
+ response = await this._http.post('/api/users/login', {
3907
+ email: this._config.email,
3908
+ password: this._config.password
3909
+ }, { skipAuth: true, retryCount: 0 });
3910
+ } catch (error) {
3911
+ self._log('error', 'Login failed:', error.message);
3912
+ throw error;
3913
+ }
3804
3914
 
3805
3915
  if (!response || !response.token) {
3806
- throw new SupsisAPIError('Login failed: No token received', 401);
3916
+ var errorMsg = 'Login failed: No token received';
3917
+ if (response && response.message) {
3918
+ errorMsg = 'Login failed: ' + response.message;
3919
+ }
3920
+ self._log('error', errorMsg);
3921
+ throw new SupsisAPIError(errorMsg, 401, response);
3807
3922
  }
3808
3923
 
3809
3924
  this._token = response.token;
@@ -3811,6 +3926,8 @@ class SupsisJS {
3811
3926
  this._http.setToken(this._token);
3812
3927
  this._connected = true;
3813
3928
 
3929
+ this._log('info', 'Connected successfully as:', this._user.fullname || this._user.email);
3930
+
3814
3931
  return this._user;
3815
3932
  }
3816
3933
 
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 ====================
@@ -3,7 +3,7 @@
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@supsis.com>
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,48 @@ 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) {
90
93
  this.config = Object.assign({}, DEFAULT_CONFIG, config);
91
94
  this.baseUrl = this._resolveBaseUrl();
92
95
  this.token = null;
93
96
  this.siteId = config.siteId || null;
97
+ this.verbose = config.verbose || false;
98
+ }
99
+
100
+ /**
101
+ * Verbose log yazdırır
102
+ * @private
103
+ * @param {string} type - Log tipi (info, warn, error, request, response)
104
+ * @param {...any} args - Log argümanları
105
+ */
106
+ _log(type) {
107
+ if (!this.verbose) return;
108
+
109
+ var args = Array.prototype.slice.call(arguments, 1);
110
+ var prefix = '[SupsisJS]';
111
+ var timestamp = new Date().toISOString();
112
+
113
+ switch (type) {
114
+ case 'info':
115
+ console.log.apply(console, [prefix, timestamp, 'INFO:'].concat(args));
116
+ break;
117
+ case 'warn':
118
+ console.warn.apply(console, [prefix, timestamp, 'WARN:'].concat(args));
119
+ break;
120
+ case 'error':
121
+ console.error.apply(console, [prefix, timestamp, 'ERROR:'].concat(args));
122
+ break;
123
+ case 'request':
124
+ console.log.apply(console, [prefix, timestamp, '→ REQUEST:'].concat(args));
125
+ break;
126
+ case 'response':
127
+ console.log.apply(console, [prefix, timestamp, '← RESPONSE:'].concat(args));
128
+ break;
129
+ default:
130
+ console.log.apply(console, [prefix, timestamp].concat(args));
131
+ }
94
132
  }
95
133
 
96
134
  /**
@@ -149,16 +187,28 @@ class HttpClient {
149
187
  fetchOptions.body = JSON.stringify(options.body);
150
188
  }
151
189
 
190
+ this._log('request', method.toUpperCase(), url, options.body ? JSON.stringify(options.body).substring(0, 200) : '');
191
+
152
192
  let lastError;
153
193
  const retryCount = options.retryCount !== undefined ? options.retryCount : this.config.retryCount;
154
194
 
155
195
  for (let attempt = 0; attempt <= retryCount; attempt++) {
156
196
  try {
197
+ if (attempt > 0) {
198
+ this._log('info', 'Retry attempt', attempt, 'of', retryCount);
199
+ }
200
+
157
201
  const response = await this._fetchWithTimeout(url, fetchOptions);
158
- return await this._handleResponse(response);
202
+ const data = await this._handleResponse(response);
203
+
204
+ this._log('response', response.status, endpoint, typeof data === 'object' ? JSON.stringify(data).substring(0, 200) : data);
205
+
206
+ return data;
159
207
  } catch (error) {
160
208
  lastError = error;
161
209
 
210
+ this._log('error', 'Request failed:', error.message, 'Status:', error.statusCode || 'N/A');
211
+
162
212
  // Auth hatalarında retry yapma
163
213
  if (error.statusCode === HTTP_STATUS.UNAUTHORIZED ||
164
214
  error.statusCode === HTTP_STATUS.FORBIDDEN) {
@@ -167,6 +217,7 @@ class HttpClient {
167
217
 
168
218
  // Son deneme değilse bekle ve tekrar dene
169
219
  if (attempt < retryCount) {
220
+ this._log('info', 'Waiting', this.config.retryDelay * (attempt + 1), 'ms before retry...');
170
221
  await this._sleep(this.config.retryDelay * (attempt + 1));
171
222
  }
172
223
  }
@@ -180,23 +231,34 @@ class HttpClient {
180
231
  * @private
181
232
  */
182
233
  async _fetchWithTimeout(url, options) {
183
- const controller = new AbortController();
184
- const timeoutId = setTimeout(function() {
234
+ var self = this;
235
+ var controller = new AbortController();
236
+ var timeoutId = setTimeout(function() {
185
237
  controller.abort();
186
238
  }, this.config.timeout);
187
239
 
188
240
  try {
189
- const response = await fetch(url, Object.assign({}, options, {
241
+ var response = await fetch(url, Object.assign({}, options, {
190
242
  signal: controller.signal
191
243
  }));
192
244
  clearTimeout(timeoutId);
193
245
  return response;
194
246
  } catch (error) {
195
247
  clearTimeout(timeoutId);
248
+
249
+ self._log('error', 'Fetch error:', error.name, error.message);
250
+
196
251
  if (error.name === 'AbortError') {
197
- throw new SupsisAPIError('Request timeout', 408);
252
+ throw new SupsisAPIError('Request timeout after ' + self.config.timeout + 'ms', 408, { originalError: error.message });
198
253
  }
199
- throw error;
254
+
255
+ // Network hataları için daha açıklayıcı hata mesajı
256
+ if (error.code === 'ECONNREFUSED' || error.code === 'ENOTFOUND' || error.message.indexOf('fetch') !== -1) {
257
+ throw new SupsisAPIError('Network error: ' + error.message, 0, { originalError: error.message, code: error.code });
258
+ }
259
+
260
+ // Diğer hatalar için SupsisAPIError'a çevir
261
+ throw new SupsisAPIError(error.message || 'Unknown fetch error', 0, { originalError: error.message });
200
262
  }
201
263
  }
202
264
 
@@ -3664,13 +3726,17 @@ class SupsisJS {
3664
3726
  /** @private */
3665
3727
  this._config = config;
3666
3728
 
3729
+ /** @private */
3730
+ this._verbose = config.verbose || false;
3731
+
3667
3732
  /** @private */
3668
3733
  this._http = new HttpClient({
3669
3734
  env: config.env || 'production',
3670
3735
  baseApiAddress: config.baseApiAddress,
3671
3736
  siteId: config.siteId,
3672
3737
  timeout: config.timeout,
3673
- retryCount: config.retryCount
3738
+ retryCount: config.retryCount,
3739
+ verbose: config.verbose
3674
3740
  });
3675
3741
 
3676
3742
  /** @private */
@@ -3684,6 +3750,38 @@ class SupsisJS {
3684
3750
 
3685
3751
  // Modülleri oluştur
3686
3752
  this._initModules();
3753
+
3754
+ this._log('info', 'SupsisJS initialized', {
3755
+ env: config.env || 'production',
3756
+ baseApiAddress: config.baseApiAddress || 'default',
3757
+ siteId: config.siteId
3758
+ });
3759
+ }
3760
+
3761
+ /**
3762
+ * Verbose log yazdırır
3763
+ * @private
3764
+ */
3765
+ _log(type) {
3766
+ if (!this._verbose) return;
3767
+
3768
+ var args = Array.prototype.slice.call(arguments, 1);
3769
+ var prefix = '[SupsisJS]';
3770
+ var timestamp = new Date().toISOString();
3771
+
3772
+ switch (type) {
3773
+ case 'info':
3774
+ console.log.apply(console, [prefix, timestamp, 'INFO:'].concat(args));
3775
+ break;
3776
+ case 'warn':
3777
+ console.warn.apply(console, [prefix, timestamp, 'WARN:'].concat(args));
3778
+ break;
3779
+ case 'error':
3780
+ console.error.apply(console, [prefix, timestamp, 'ERROR:'].concat(args));
3781
+ break;
3782
+ default:
3783
+ console.log.apply(console, [prefix, timestamp].concat(args));
3784
+ }
3687
3785
  }
3688
3786
 
3689
3787
  /**
@@ -3789,17 +3887,34 @@ class SupsisJS {
3789
3887
  * console.log('Connected as:', supsis.currentUser.fullname);
3790
3888
  */
3791
3889
  async connect() {
3890
+ var self = this;
3891
+
3792
3892
  if (this._connected) {
3893
+ this._log('info', 'Already connected');
3793
3894
  return this._user;
3794
3895
  }
3795
3896
 
3796
- const response = await this._http.post('/api/users/login', {
3797
- email: this._config.email,
3798
- password: this._config.password
3799
- }, { skipAuth: true });
3897
+ this._log('info', 'Connecting to Supsis API...');
3898
+ this._log('info', 'Base URL:', this._http.baseUrl);
3899
+
3900
+ var response;
3901
+ try {
3902
+ response = await this._http.post('/api/users/login', {
3903
+ email: this._config.email,
3904
+ password: this._config.password
3905
+ }, { skipAuth: true, retryCount: 0 });
3906
+ } catch (error) {
3907
+ self._log('error', 'Login failed:', error.message);
3908
+ throw error;
3909
+ }
3800
3910
 
3801
3911
  if (!response || !response.token) {
3802
- throw new SupsisAPIError('Login failed: No token received', 401);
3912
+ var errorMsg = 'Login failed: No token received';
3913
+ if (response && response.message) {
3914
+ errorMsg = 'Login failed: ' + response.message;
3915
+ }
3916
+ self._log('error', errorMsg);
3917
+ throw new SupsisAPIError(errorMsg, 401, response);
3803
3918
  }
3804
3919
 
3805
3920
  this._token = response.token;
@@ -3807,6 +3922,8 @@ class SupsisJS {
3807
3922
  this._http.setToken(this._token);
3808
3923
  this._connected = true;
3809
3924
 
3925
+ this._log('info', 'Connected successfully as:', this._user.fullname || this._user.email);
3926
+
3810
3927
  return this._user;
3811
3928
  }
3812
3929