tsvesync 1.0.95 → 1.0.97

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/README.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  A TypeScript library for interacting with VeSync smart home devices. This library provides a modern, type-safe interface for controlling VeSync devices including air purifiers, outlets, and switches.
4
4
 
5
+ ## 🆕 Recent Updates
6
+
7
+ - **Enhanced Authentication**: Now supports the new VeSync authentication flow (pyvesync PR #340) with automatic fallback to legacy authentication
8
+ - **Regional API Support**: Automatic detection and routing for US (`smartapi.vesync.com`) and EU (`smartapi.vesync.eu`) endpoints
9
+ - **Improved Error Handling**: Better recovery from API changes and authentication errors
10
+ - **Cross-Region Support**: Handles cross-region authentication errors automatically
11
+
5
12
  ## Features
6
13
 
7
14
  - Full TypeScript support with type definitions
@@ -4,9 +4,12 @@
4
4
  import { VeSync } from './vesync';
5
5
  export declare function getApiBaseUrl(): string;
6
6
  export declare function setApiBaseUrl(url: string): void;
7
+ export declare function getCurrentRegion(): string;
8
+ export declare function setCurrentRegion(region: string): void;
9
+ export declare function getRegionFromCountryCode(countryCode: string): string;
7
10
  export declare const API_RATE_LIMIT = 30;
8
11
  export declare const API_TIMEOUT = 15000;
9
- export declare const APP_VERSION = "2.8.6";
12
+ export declare const APP_VERSION = "5.6.60";
10
13
  export declare const PHONE_BRAND = "SM N9005";
11
14
  export declare const PHONE_OS = "Android";
12
15
  export declare const USER_TYPE = "1";
@@ -14,6 +17,17 @@ export declare const DEFAULT_TZ = "America/New_York";
14
17
  export declare const DEFAULT_REGION = "US";
15
18
  export declare const MOBILE_ID = "1234567890123456";
16
19
  export declare const BYPASS_HEADER_UA = "okhttp/3.12.1";
20
+ export declare const CLIENT_VERSION = "VeSync 5.6.60";
21
+ export declare const REGION_ENDPOINTS: {
22
+ US: string;
23
+ CA: string;
24
+ MX: string;
25
+ JP: string;
26
+ EU: string;
27
+ };
28
+ export declare const CROSS_REGION_ERROR_CODE = -11260022;
29
+ export declare const APP_VERSION_TOO_LOW_ERROR_CODE = -11012022;
30
+ export declare function generateAppId(): string;
17
31
  export interface RequestBody {
18
32
  acceptLanguage?: string;
19
33
  accountID?: string;
@@ -33,8 +47,37 @@ export interface RequestBody {
33
47
  userType?: string;
34
48
  uuid?: string;
35
49
  status?: string;
50
+ authorizeCode?: string;
51
+ bizToken?: string;
52
+ regionChange?: string;
53
+ userCountryCode?: string;
54
+ authProtocolType?: string;
55
+ clientType?: string;
56
+ sourceAppID?: string;
57
+ appID?: string;
58
+ clientVersion?: string;
36
59
  [key: string]: any;
37
60
  }
61
+ export interface AuthResponse {
62
+ code: number;
63
+ msg: string;
64
+ result?: {
65
+ authorizeCode?: string;
66
+ bizToken?: string;
67
+ userCountryCode?: string;
68
+ [key: string]: any;
69
+ };
70
+ }
71
+ export interface LoginResponse {
72
+ code: number;
73
+ msg: string;
74
+ result?: {
75
+ token?: string;
76
+ accountID?: string;
77
+ countryCode?: string;
78
+ [key: string]: any;
79
+ };
80
+ }
38
81
  export declare class Helpers {
39
82
  static shouldRedact: boolean;
40
83
  /**
@@ -49,6 +92,10 @@ export declare class Helpers {
49
92
  * Build header for api requests on 'bypass' endpoint
50
93
  */
51
94
  static reqHeaderBypass(): Record<string, string>;
95
+ /**
96
+ * Build header for new authentication endpoints
97
+ */
98
+ static reqHeaderAuth(): Record<string, string>;
52
99
  /**
53
100
  * Return universal keys for body of api requests
54
101
  */
@@ -61,6 +108,14 @@ export declare class Helpers {
61
108
  * Detail keys for api requests
62
109
  */
63
110
  static reqBodyDetails(): Record<string, string>;
111
+ /**
112
+ * Build request body for initial authentication step
113
+ */
114
+ static reqBodyAuthStep1(manager: VeSync, appId: string): Record<string, any>;
115
+ /**
116
+ * Build request body for second authentication step (login with authorize code)
117
+ */
118
+ static reqBodyAuthStep2(authorizeCode: string, bizToken: string, appId: string, userCountryCode?: string): Record<string, any>;
64
119
  /**
65
120
  * Builder for body of api requests
66
121
  */
@@ -85,4 +140,12 @@ export declare class Helpers {
85
140
  * Calculate MD5 hash
86
141
  */
87
142
  static md5(text: string): string;
143
+ /**
144
+ * Perform new two-step authentication flow
145
+ */
146
+ static authNewFlow(manager: VeSync, appId: string, region?: string): Promise<[boolean, string | null, string | null, string | null]>;
147
+ /**
148
+ * Perform legacy authentication (fallback)
149
+ */
150
+ static authLegacyFlow(manager: VeSync): Promise<[boolean, string | null, string | null, string | null]>;
88
151
  }
@@ -6,23 +6,51 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
6
6
  return (mod && mod.__esModule) ? mod : { "default": mod };
7
7
  };
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.Helpers = exports.BYPASS_HEADER_UA = exports.MOBILE_ID = exports.DEFAULT_REGION = exports.DEFAULT_TZ = exports.USER_TYPE = exports.PHONE_OS = exports.PHONE_BRAND = exports.APP_VERSION = exports.API_TIMEOUT = exports.API_RATE_LIMIT = void 0;
9
+ exports.Helpers = exports.APP_VERSION_TOO_LOW_ERROR_CODE = exports.CROSS_REGION_ERROR_CODE = exports.REGION_ENDPOINTS = exports.CLIENT_VERSION = exports.BYPASS_HEADER_UA = exports.MOBILE_ID = exports.DEFAULT_REGION = exports.DEFAULT_TZ = exports.USER_TYPE = exports.PHONE_OS = exports.PHONE_BRAND = exports.APP_VERSION = exports.API_TIMEOUT = exports.API_RATE_LIMIT = void 0;
10
10
  exports.getApiBaseUrl = getApiBaseUrl;
11
11
  exports.setApiBaseUrl = setApiBaseUrl;
12
+ exports.getCurrentRegion = getCurrentRegion;
13
+ exports.setCurrentRegion = setCurrentRegion;
14
+ exports.getRegionFromCountryCode = getRegionFromCountryCode;
15
+ exports.generateAppId = generateAppId;
12
16
  const axios_1 = __importDefault(require("axios"));
13
17
  const crypto_1 = __importDefault(require("crypto"));
14
18
  const logger_1 = require("./logger");
15
- // API configuration - Always use US endpoint
19
+ // API configuration - Support regional endpoints
16
20
  let _apiBaseUrl = 'https://smartapi.vesync.com';
21
+ let _currentRegion = 'US';
17
22
  function getApiBaseUrl() {
18
23
  return _apiBaseUrl;
19
24
  }
20
25
  function setApiBaseUrl(url) {
21
26
  _apiBaseUrl = url;
22
27
  }
28
+ function getCurrentRegion() {
29
+ return _currentRegion;
30
+ }
31
+ function setCurrentRegion(region) {
32
+ _currentRegion = region;
33
+ if (region in exports.REGION_ENDPOINTS) {
34
+ _apiBaseUrl = exports.REGION_ENDPOINTS[region];
35
+ }
36
+ }
37
+ // Determine region from country code
38
+ function getRegionFromCountryCode(countryCode) {
39
+ const euCountries = [
40
+ 'AT', 'BE', 'BG', 'HR', 'CY', 'CZ', 'DK', 'EE', 'FI', 'FR',
41
+ 'DE', 'GR', 'HU', 'IE', 'IT', 'LV', 'LT', 'LU', 'MT', 'NL',
42
+ 'PL', 'PT', 'RO', 'SK', 'SI', 'ES', 'SE', 'GB', 'IS', 'LI',
43
+ 'NO', 'CH'
44
+ ];
45
+ if (euCountries.includes(countryCode)) {
46
+ return 'EU';
47
+ }
48
+ // Default to US for other countries
49
+ return 'US';
50
+ }
23
51
  exports.API_RATE_LIMIT = 30;
24
52
  exports.API_TIMEOUT = 15000;
25
- exports.APP_VERSION = '2.8.6';
53
+ exports.APP_VERSION = '5.6.60';
26
54
  exports.PHONE_BRAND = 'SM N9005';
27
55
  exports.PHONE_OS = 'Android';
28
56
  exports.USER_TYPE = '1';
@@ -30,6 +58,27 @@ exports.DEFAULT_TZ = 'America/New_York';
30
58
  exports.DEFAULT_REGION = 'US';
31
59
  exports.MOBILE_ID = '1234567890123456';
32
60
  exports.BYPASS_HEADER_UA = 'okhttp/3.12.1';
61
+ exports.CLIENT_VERSION = 'VeSync 5.6.60';
62
+ // Regional API endpoints
63
+ exports.REGION_ENDPOINTS = {
64
+ 'US': 'https://smartapi.vesync.com',
65
+ 'CA': 'https://smartapi.vesync.com',
66
+ 'MX': 'https://smartapi.vesync.com',
67
+ 'JP': 'https://smartapi.vesync.com',
68
+ 'EU': 'https://smartapi.vesync.eu'
69
+ };
70
+ // Cross-region error code
71
+ exports.CROSS_REGION_ERROR_CODE = -11260022;
72
+ exports.APP_VERSION_TOO_LOW_ERROR_CODE = -11012022;
73
+ // Generate unique APP_ID for each session
74
+ function generateAppId() {
75
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
76
+ let result = '';
77
+ for (let i = 0; i < 8; i++) {
78
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
79
+ }
80
+ return result;
81
+ }
33
82
  class Helpers {
34
83
  /**
35
84
  * Calculate MD5 hash
@@ -64,6 +113,16 @@ class Helpers {
64
113
  'User-Agent': exports.BYPASS_HEADER_UA
65
114
  };
66
115
  }
116
+ /**
117
+ * Build header for new authentication endpoints
118
+ */
119
+ static reqHeaderAuth() {
120
+ return {
121
+ 'Content-Type': 'application/json; charset=UTF-8',
122
+ 'User-Agent': exports.BYPASS_HEADER_UA,
123
+ 'accept-language': 'en'
124
+ };
125
+ }
67
126
  /**
68
127
  * Return universal keys for body of api requests
69
128
  */
@@ -96,6 +155,42 @@ class Helpers {
96
155
  'traceId': Date.now().toString()
97
156
  };
98
157
  }
158
+ /**
159
+ * Build request body for initial authentication step
160
+ */
161
+ static reqBodyAuthStep1(manager, appId) {
162
+ return {
163
+ 'email': manager.username,
164
+ 'password': this.hashPassword(manager.password),
165
+ 'timeZone': manager.timeZone,
166
+ 'acceptLanguage': 'en',
167
+ 'appVersion': exports.APP_VERSION,
168
+ 'phoneBrand': exports.PHONE_BRAND,
169
+ 'phoneOS': exports.PHONE_OS,
170
+ 'traceId': Date.now().toString(),
171
+ 'authProtocolType': 'pwd',
172
+ 'clientType': 'android',
173
+ 'sourceAppID': 'vesync_android',
174
+ 'appID': appId,
175
+ 'clientVersion': exports.CLIENT_VERSION
176
+ };
177
+ }
178
+ /**
179
+ * Build request body for second authentication step (login with authorize code)
180
+ */
181
+ static reqBodyAuthStep2(authorizeCode, bizToken, appId, userCountryCode) {
182
+ const body = {
183
+ 'authorizeCode': authorizeCode,
184
+ 'bizToken': bizToken,
185
+ 'appID': appId,
186
+ 'clientVersion': exports.CLIENT_VERSION,
187
+ 'acceptLanguage': 'en'
188
+ };
189
+ if (userCountryCode) {
190
+ body.userCountryCode = userCountryCode;
191
+ }
192
+ return body;
193
+ }
99
194
  /**
100
195
  * Builder for body of api requests
101
196
  */
@@ -270,6 +365,106 @@ class Helpers {
270
365
  static md5(text) {
271
366
  return crypto_1.default.createHash('md5').update(text).digest('hex');
272
367
  }
368
+ /**
369
+ * Perform new two-step authentication flow
370
+ */
371
+ static async authNewFlow(manager, appId, region = 'US') {
372
+ try {
373
+ // Step 1: Get authorization code
374
+ const step1Body = this.reqBodyAuthStep1(manager, appId);
375
+ const step1Headers = this.reqHeaderAuth();
376
+ // Set the correct regional endpoint
377
+ const originalUrl = getApiBaseUrl();
378
+ if (region in exports.REGION_ENDPOINTS) {
379
+ setApiBaseUrl(exports.REGION_ENDPOINTS[region]);
380
+ }
381
+ logger_1.logger.debug('Step 1: Getting authorization code...', {
382
+ region,
383
+ endpoint: getApiBaseUrl(),
384
+ body: { ...step1Body, password: '[REDACTED]' }
385
+ });
386
+ const [authResponse, authStatus] = await this.callApi('/globalPlatform/api/accountAuth/v1/authByPWDOrOTM', 'post', step1Body, step1Headers, manager);
387
+ if (!authResponse || authStatus !== 200) {
388
+ logger_1.logger.error('Step 1 failed:', authResponse);
389
+ setApiBaseUrl(originalUrl); // Restore original URL
390
+ return [false, null, null, null];
391
+ }
392
+ if (authResponse.code !== 0) {
393
+ logger_1.logger.error('Step 1 error code:', authResponse.code, 'message:', authResponse.msg);
394
+ // Handle cross-region error
395
+ if (authResponse.code === exports.CROSS_REGION_ERROR_CODE) {
396
+ logger_1.logger.debug('Cross-region error detected, will try different region');
397
+ setApiBaseUrl(originalUrl); // Restore original URL
398
+ return [false, null, null, 'cross_region'];
399
+ }
400
+ setApiBaseUrl(originalUrl); // Restore original URL
401
+ return [false, null, null, null];
402
+ }
403
+ const { authorizeCode, bizToken, userCountryCode } = authResponse.result || {};
404
+ if (!authorizeCode || !bizToken) {
405
+ logger_1.logger.error('Missing required fields in step 1 response:', authResponse.result);
406
+ setApiBaseUrl(originalUrl); // Restore original URL
407
+ return [false, null, null, null];
408
+ }
409
+ logger_1.logger.debug('Step 1 successful, got authorization code');
410
+ // Step 2: Login with authorization code
411
+ const step2Body = this.reqBodyAuthStep2(authorizeCode, bizToken, appId, userCountryCode);
412
+ logger_1.logger.debug('Step 2: Logging in with authorization code...');
413
+ const [loginResponse, loginStatus] = await this.callApi('/user/api/accountManage/v1/loginByAuthorizeCode4Vesync', 'post', step2Body, step1Headers, manager);
414
+ setApiBaseUrl(originalUrl); // Restore original URL
415
+ if (!loginResponse || loginStatus !== 200) {
416
+ logger_1.logger.error('Step 2 failed:', loginResponse);
417
+ return [false, null, null, null];
418
+ }
419
+ if (loginResponse.code !== 0) {
420
+ logger_1.logger.error('Step 2 error code:', loginResponse.code, 'message:', loginResponse.msg);
421
+ return [false, null, null, null];
422
+ }
423
+ const { token, accountID, countryCode } = loginResponse.result || {};
424
+ if (!token || !accountID) {
425
+ logger_1.logger.error('Missing required fields in step 2 response:', loginResponse.result);
426
+ return [false, null, null, null];
427
+ }
428
+ logger_1.logger.debug('Step 2 successful, got token and accountID');
429
+ return [true, token, accountID, countryCode || userCountryCode];
430
+ }
431
+ catch (error) {
432
+ logger_1.logger.error('New authentication flow error:', error);
433
+ return [false, null, null, null];
434
+ }
435
+ }
436
+ /**
437
+ * Perform legacy authentication (fallback)
438
+ */
439
+ static async authLegacyFlow(manager) {
440
+ try {
441
+ const body = this.reqBody(manager, 'login');
442
+ logger_1.logger.debug('Legacy login attempt...', {
443
+ endpoint: getApiBaseUrl(),
444
+ body: { ...body, password: '[REDACTED]' }
445
+ });
446
+ const [response, status] = await this.callApi('/cloud/v1/user/login', 'post', body, {}, manager);
447
+ if (!response || status !== 200) {
448
+ logger_1.logger.error('Legacy login failed:', response);
449
+ return [false, null, null, null];
450
+ }
451
+ if (response.code && response.code !== 0) {
452
+ logger_1.logger.error('Legacy login error code:', response.code, 'message:', response.msg);
453
+ return [false, null, null, null];
454
+ }
455
+ const { token, accountID, countryCode } = response.result || {};
456
+ if (!token || !accountID) {
457
+ logger_1.logger.error('Missing required fields in legacy login response:', response.result);
458
+ return [false, null, null, null];
459
+ }
460
+ logger_1.logger.debug('Legacy login successful');
461
+ return [true, token, accountID, countryCode];
462
+ }
463
+ catch (error) {
464
+ logger_1.logger.error('Legacy authentication flow error:', error);
465
+ return [false, null, null, null];
466
+ }
467
+ }
273
468
  }
274
469
  exports.Helpers = Helpers;
275
470
  Helpers.shouldRedact = true;
@@ -25,6 +25,8 @@ export declare class VeSync {
25
25
  private _lastUpdateTs;
26
26
  private _inProcess;
27
27
  private _excludeConfig;
28
+ private _appId;
29
+ private _region;
28
30
  username: string;
29
31
  password: string;
30
32
  token: string | null;
@@ -66,6 +68,18 @@ export declare class VeSync {
66
68
  */
67
69
  get energyUpdateInterval(): number;
68
70
  set energyUpdateInterval(interval: number);
71
+ /**
72
+ * Get current App ID
73
+ */
74
+ get appId(): string;
75
+ /**
76
+ * Get current region
77
+ */
78
+ get region(): string;
79
+ /**
80
+ * Set region and update API endpoint
81
+ */
82
+ set region(region: string);
69
83
  /**
70
84
  * Test if device should be removed
71
85
  */
@@ -91,7 +105,7 @@ export declare class VeSync {
91
105
  */
92
106
  getDevices(): Promise<boolean>;
93
107
  /**
94
- * Login to VeSync server
108
+ * Login to VeSync server with new authentication flow and backwards compatibility
95
109
  */
96
110
  login(retryAttempts?: number, initialDelayMs?: number): Promise<boolean>;
97
111
  /**
@@ -139,6 +139,8 @@ class VeSync {
139
139
  this._lastUpdateTs = null;
140
140
  this._inProcess = false;
141
141
  this._excludeConfig = excludeConfig || null;
142
+ this._appId = (0, helpers_1.generateAppId)();
143
+ this._region = 'US';
142
144
  this.username = username;
143
145
  this.password = password;
144
146
  this.token = null;
@@ -178,8 +180,9 @@ class VeSync {
178
180
  (0, helpers_1.setApiBaseUrl)(apiUrl);
179
181
  }
180
182
  else {
181
- // Always use US endpoint
183
+ // Start with US endpoint as default
182
184
  (0, helpers_1.setApiBaseUrl)('https://smartapi.vesync.com');
185
+ (0, helpers_1.setCurrentRegion)('US');
183
186
  }
184
187
  // Set custom logger if provided
185
188
  if (customLogger) {
@@ -222,6 +225,27 @@ class VeSync {
222
225
  this._energyUpdateInterval = interval;
223
226
  }
224
227
  }
228
+ /**
229
+ * Get current App ID
230
+ */
231
+ get appId() {
232
+ return this._appId;
233
+ }
234
+ /**
235
+ * Get current region
236
+ */
237
+ get region() {
238
+ return this._region;
239
+ }
240
+ /**
241
+ * Set region and update API endpoint
242
+ */
243
+ set region(region) {
244
+ if (region in helpers_1.REGION_ENDPOINTS) {
245
+ this._region = region;
246
+ (0, helpers_1.setCurrentRegion)(region);
247
+ }
248
+ }
225
249
  /**
226
250
  * Test if device should be removed
227
251
  */
@@ -408,62 +432,71 @@ class VeSync {
408
432
  return success;
409
433
  }
410
434
  /**
411
- * Login to VeSync server
435
+ * Login to VeSync server with new authentication flow and backwards compatibility
412
436
  */
413
437
  async login(retryAttempts = 3, initialDelayMs = 1000) {
414
- var _a;
415
- const body = helpers_1.Helpers.reqBody(this, 'login');
438
+ logger_1.logger.debug('Starting VeSync authentication...', {
439
+ username: this.username,
440
+ appId: this._appId,
441
+ region: this._region
442
+ });
416
443
  for (let attempt = 0; attempt < retryAttempts; attempt++) {
417
444
  try {
418
- logger_1.logger.debug('Login attempt', {
419
- attempt: attempt + 1,
420
- apiUrl: (0, helpers_1.getApiBaseUrl)(),
421
- timeZone: this.timeZone,
422
- appVersion: body.appVersion
423
- });
424
- const [response, status] = await helpers_1.Helpers.callApi('/cloud/v1/user/login', 'post', body, {}, this);
425
- logger_1.logger.debug('Login response:', { status, response });
426
- // Handle specific error codes
427
- if (response && response.code) {
428
- switch (response.code) {
429
- case -11012022:
430
- logger_1.logger.error('App version too low error. Current version:', body.appVersion);
431
- logger_1.logger.error('This typically indicates an API version compatibility issue.');
432
- break;
433
- case -11003:
434
- logger_1.logger.error('Authentication failed - check credentials');
435
- break;
436
- case -11001:
437
- logger_1.logger.error('Invalid request format');
438
- break;
439
- default:
440
- logger_1.logger.error('API error code:', response.code, 'message:', response.msg);
445
+ logger_1.logger.debug(`Authentication attempt ${attempt + 1} of ${retryAttempts}`);
446
+ // Try new authentication flow first
447
+ let [success, token, accountId, countryCode] = await helpers_1.Helpers.authNewFlow(this, this._appId, this._region);
448
+ if (!success) {
449
+ // Check if we need to try a different region
450
+ if (countryCode === 'cross_region') {
451
+ logger_1.logger.debug('Cross-region error detected, trying EU region...');
452
+ this._region = 'EU';
453
+ (0, helpers_1.setCurrentRegion)('EU');
454
+ [success, token, accountId, countryCode] = await helpers_1.Helpers.authNewFlow(this, this._appId, 'EU');
455
+ }
456
+ // If new flow still fails, try legacy authentication as fallback
457
+ if (!success) {
458
+ logger_1.logger.debug('New authentication flow failed, trying legacy flow...');
459
+ [success, token, accountId, countryCode] = await helpers_1.Helpers.authLegacyFlow(this);
441
460
  }
442
461
  }
443
- if ((_a = response === null || response === void 0 ? void 0 : response.result) === null || _a === void 0 ? void 0 : _a.token) {
444
- this.token = response.result.token;
445
- this.accountId = response.result.accountID;
446
- this.countryCode = response.result.countryCode;
462
+ if (success && token && accountId) {
463
+ this.token = token;
464
+ this.accountId = accountId;
465
+ this.countryCode = countryCode;
447
466
  this.enabled = true;
448
- logger_1.logger.debug('Login successful for region:', this.countryCode);
467
+ // Set region based on country code if we got one
468
+ if (countryCode) {
469
+ const detectedRegion = (0, helpers_1.getRegionFromCountryCode)(countryCode);
470
+ if (detectedRegion !== this._region) {
471
+ logger_1.logger.debug(`Updating region from ${this._region} to ${detectedRegion} based on country code: ${countryCode}`);
472
+ this._region = detectedRegion;
473
+ (0, helpers_1.setCurrentRegion)(detectedRegion);
474
+ }
475
+ }
476
+ logger_1.logger.debug('Authentication successful!', {
477
+ region: this._region,
478
+ countryCode: countryCode,
479
+ endpoint: (0, helpers_1.getApiBaseUrl)()
480
+ });
449
481
  return true;
450
482
  }
451
- // If we reach here, login failed but didn't throw an error
483
+ // If we reach here, authentication failed
452
484
  const delay = initialDelayMs * Math.pow(2, attempt);
453
- logger_1.logger.debug(`Login attempt ${attempt + 1} failed, retrying in ${delay}ms...`);
485
+ logger_1.logger.debug(`Authentication attempt ${attempt + 1} failed, retrying in ${delay}ms...`);
454
486
  await new Promise(resolve => setTimeout(resolve, delay));
455
487
  }
456
488
  catch (error) {
489
+ logger_1.logger.error(`Authentication attempt ${attempt + 1} error:`, error);
457
490
  if (attempt === retryAttempts - 1) {
458
- logger_1.logger.error('Login error after all retry attempts:', error);
491
+ logger_1.logger.error('Authentication failed after all retry attempts');
459
492
  return false;
460
493
  }
461
494
  const delay = initialDelayMs * Math.pow(2, attempt);
462
- logger_1.logger.debug(`Login attempt ${attempt + 1} failed with error, retrying in ${delay}ms...`, error);
495
+ logger_1.logger.debug(`Retrying authentication in ${delay}ms...`);
463
496
  await new Promise(resolve => setTimeout(resolve, delay));
464
497
  }
465
498
  }
466
- logger_1.logger.error('Unable to login with supplied credentials after all retry attempts');
499
+ logger_1.logger.error('Unable to authenticate with supplied credentials after all retry attempts');
467
500
  return false;
468
501
  }
469
502
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tsvesync",
3
- "version": "1.0.95",
3
+ "version": "1.0.97",
4
4
  "description": "A TypeScript library for interacting with VeSync smart home devices",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",