trane-thermostat-api 1.0.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/LICENSE +21 -0
- package/README.md +150 -0
- package/dist/client/auth.d.ts +50 -0
- package/dist/client/auth.d.ts.map +1 -0
- package/dist/client/auth.js +236 -0
- package/dist/client/auth.js.map +1 -0
- package/dist/client/nexia-client.d.ts +48 -0
- package/dist/client/nexia-client.d.ts.map +1 -0
- package/dist/client/nexia-client.js +311 -0
- package/dist/client/nexia-client.js.map +1 -0
- package/dist/devices/nexia-automation.d.ts +15 -0
- package/dist/devices/nexia-automation.d.ts.map +1 -0
- package/dist/devices/nexia-automation.js +39 -0
- package/dist/devices/nexia-automation.js.map +1 -0
- package/dist/devices/nexia-sensor.d.ts +34 -0
- package/dist/devices/nexia-sensor.d.ts.map +1 -0
- package/dist/devices/nexia-sensor.js +152 -0
- package/dist/devices/nexia-sensor.js.map +1 -0
- package/dist/devices/nexia-thermostat.d.ts +73 -0
- package/dist/devices/nexia-thermostat.d.ts.map +1 -0
- package/dist/devices/nexia-thermostat.js +357 -0
- package/dist/devices/nexia-thermostat.js.map +1 -0
- package/dist/devices/nexia-zone.d.ts +61 -0
- package/dist/devices/nexia-zone.d.ts.map +1 -0
- package/dist/devices/nexia-zone.js +370 -0
- package/dist/devices/nexia-zone.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +1 -0
- package/dist/types/api.d.ts +277 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/api.js +3 -0
- package/dist/types/api.js.map +1 -0
- package/dist/types/constants.d.ts +137 -0
- package/dist/types/constants.d.ts.map +1 -0
- package/dist/types/constants.js +160 -0
- package/dist/types/constants.js.map +1 -0
- package/dist/types/interfaces.d.ts +211 -0
- package/dist/types/interfaces.d.ts.map +1 -0
- package/dist/types/interfaces.js +3 -0
- package/dist/types/interfaces.js.map +1 -0
- package/dist/utils/errors.d.ts +94 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +231 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/http-utils.d.ts +59 -0
- package/dist/utils/http-utils.d.ts.map +1 -0
- package/dist/utils/http-utils.js +273 -0
- package/dist/utils/http-utils.js.map +1 -0
- package/dist/utils/json-utils.d.ts +32 -0
- package/dist/utils/json-utils.d.ts.map +1 -0
- package/dist/utils/json-utils.js +389 -0
- package/dist/utils/json-utils.js.map +1 -0
- package/dist/utils/validation.d.ts +52 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +272 -0
- package/dist/utils/validation.js.map +1 -0
- package/package.json +69 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Spencer S
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# Nexia Homebridge Library
|
|
2
|
+
|
|
3
|
+
A TypeScript/Node.js library for controlling Nexia/Trane/American Standard thermostats, specifically designed for Homebridge integration.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This library provides a complete rewrite of the Python Nexia library in TypeScript, offering:
|
|
8
|
+
|
|
9
|
+
- **Full TypeScript support** with comprehensive type definitions
|
|
10
|
+
- **Homebridge-optimized** architecture for seamless HomeKit integration
|
|
11
|
+
- **Modern async/await** patterns for all API interactions
|
|
12
|
+
- **Multi-zone support** with individual thermostat zone control
|
|
13
|
+
- **RoomIQ sensor integration** for enhanced temperature monitoring
|
|
14
|
+
- **Comprehensive error handling** with structured error hierarchy
|
|
15
|
+
|
|
16
|
+
## Supported Devices
|
|
17
|
+
|
|
18
|
+
- **Nexia Thermostats**: XL950, XL1050, XL824, UX360
|
|
19
|
+
- **Trane Thermostats**: Compatible with Nexia API
|
|
20
|
+
- **American Standard**: Compatible with Nexia API
|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
|
|
24
|
+
### Thermostat Control
|
|
25
|
+
- System mode control (Auto, Heat, Cool, Off)
|
|
26
|
+
- Temperature setpoint management with deadband validation
|
|
27
|
+
- Fan speed and mode control
|
|
28
|
+
- Emergency heat support
|
|
29
|
+
- Outdoor temperature monitoring
|
|
30
|
+
- Variable speed compressor monitoring
|
|
31
|
+
|
|
32
|
+
### Zone Management
|
|
33
|
+
- Individual zone temperature control
|
|
34
|
+
- Zone-specific mode settings
|
|
35
|
+
- Hold/schedule management
|
|
36
|
+
- Preset mode support (Home, Away, Sleep)
|
|
37
|
+
- RoomIQ sensor selection and monitoring
|
|
38
|
+
|
|
39
|
+
### Humidity & Air Quality
|
|
40
|
+
- Humidity monitoring and control
|
|
41
|
+
- Dehumidify/humidify setpoint management
|
|
42
|
+
- Air cleaner mode control (Auto, Quick, Allergy)
|
|
43
|
+
|
|
44
|
+
### Advanced Features
|
|
45
|
+
- ETag-based caching for efficient API usage
|
|
46
|
+
- Automatic session management and re-authentication
|
|
47
|
+
- Rate-limited login attempts to prevent account lockout
|
|
48
|
+
- Brand-specific URL handling (Nexia, Trane, American Standard)
|
|
49
|
+
- Comprehensive device capability detection
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm install trane-thermostat-api
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Quick Start
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { NexiaClient, BrandType } from 'trane-thermostat-api';
|
|
61
|
+
|
|
62
|
+
const client = new NexiaClient({
|
|
63
|
+
username: 'your-email@example.com',
|
|
64
|
+
password: 'your-password',
|
|
65
|
+
brand: BrandType.NEXIA
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Authenticate and discover devices
|
|
69
|
+
await client.login();
|
|
70
|
+
const thermostats = await client.getThermostats();
|
|
71
|
+
|
|
72
|
+
// Control thermostat
|
|
73
|
+
const thermostat = thermostats[0];
|
|
74
|
+
await thermostat.setFanMode('auto');
|
|
75
|
+
|
|
76
|
+
// Control zones
|
|
77
|
+
const zone = thermostat.zones[0];
|
|
78
|
+
await zone.setTemperatures({
|
|
79
|
+
heatingSetpoint: 70,
|
|
80
|
+
coolingSetpoint: 75
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## API Documentation
|
|
85
|
+
|
|
86
|
+
### Core Classes
|
|
87
|
+
|
|
88
|
+
#### NexiaClient
|
|
89
|
+
Main HTTP client for API communication and device discovery.
|
|
90
|
+
|
|
91
|
+
#### NexiaThermostat
|
|
92
|
+
Represents a physical thermostat with full feature detection and control.
|
|
93
|
+
|
|
94
|
+
#### NexiaZone
|
|
95
|
+
Represents a zone/room within a thermostat with independent temperature control.
|
|
96
|
+
|
|
97
|
+
#### NexiaSensor
|
|
98
|
+
RoomIQ temperature and humidity sensor with battery monitoring.
|
|
99
|
+
|
|
100
|
+
## Homebridge Integration
|
|
101
|
+
|
|
102
|
+
This library is designed specifically for Homebridge plugins. See the included platform implementation for complete HomeKit integration examples.
|
|
103
|
+
|
|
104
|
+
## Development
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Install dependencies
|
|
108
|
+
npm install
|
|
109
|
+
|
|
110
|
+
# Build the project
|
|
111
|
+
npm run build
|
|
112
|
+
|
|
113
|
+
# Run tests
|
|
114
|
+
npm test
|
|
115
|
+
|
|
116
|
+
# Run linting
|
|
117
|
+
npm run lint
|
|
118
|
+
|
|
119
|
+
# Watch mode for development
|
|
120
|
+
npm run dev
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Testing
|
|
124
|
+
|
|
125
|
+
The test suite includes:
|
|
126
|
+
- Unit tests for all core classes
|
|
127
|
+
- Mock HTTP responses for API testing
|
|
128
|
+
- Validation logic testing
|
|
129
|
+
- Error handling scenarios
|
|
130
|
+
- Integration tests with real API endpoints
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
npm run test:coverage
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Contributing
|
|
137
|
+
|
|
138
|
+
1. Fork the repository
|
|
139
|
+
2. Create a feature branch
|
|
140
|
+
3. Make your changes with tests
|
|
141
|
+
4. Run the test suite
|
|
142
|
+
5. Submit a pull request
|
|
143
|
+
|
|
144
|
+
## License
|
|
145
|
+
|
|
146
|
+
MIT License - see LICENSE file for details.
|
|
147
|
+
|
|
148
|
+
## Acknowledgments
|
|
149
|
+
|
|
150
|
+
Based on the original Python Nexia library architecture, rewritten for modern TypeScript/Node.js environments with Homebridge-specific optimizations.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { BrandType } from '../types/constants';
|
|
2
|
+
import { AuthTokens } from '../types/api';
|
|
3
|
+
import { HttpClient } from '../utils/http-utils';
|
|
4
|
+
export interface AuthConfig {
|
|
5
|
+
username: string;
|
|
6
|
+
password: string;
|
|
7
|
+
deviceName?: string;
|
|
8
|
+
brand: BrandType;
|
|
9
|
+
stateFile?: string;
|
|
10
|
+
houseId?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface AuthState {
|
|
13
|
+
deviceUuid: string;
|
|
14
|
+
apiKey?: string;
|
|
15
|
+
mobileId?: string;
|
|
16
|
+
loginAttempts: number;
|
|
17
|
+
lastLoginAttempt?: number;
|
|
18
|
+
sessionExpiry?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare class AuthManager {
|
|
21
|
+
private readonly config;
|
|
22
|
+
private readonly httpClient;
|
|
23
|
+
private readonly stateFilePath;
|
|
24
|
+
private authState;
|
|
25
|
+
constructor(httpClient: HttpClient, config: AuthConfig);
|
|
26
|
+
initialize(): Promise<void>;
|
|
27
|
+
authenticate(): Promise<AuthTokens>;
|
|
28
|
+
isSessionValid(): boolean;
|
|
29
|
+
refreshSession(): Promise<void>;
|
|
30
|
+
getApiKey(): string | null;
|
|
31
|
+
getMobileId(): string | null;
|
|
32
|
+
getDeviceUuid(): string;
|
|
33
|
+
needsAuthentication(): boolean;
|
|
34
|
+
logout(): Promise<void>;
|
|
35
|
+
reset(): Promise<void>;
|
|
36
|
+
getSessionInfo(): Promise<{
|
|
37
|
+
houseId: number;
|
|
38
|
+
houseName: string;
|
|
39
|
+
}>;
|
|
40
|
+
private validateConfig;
|
|
41
|
+
private getStateFilePath;
|
|
42
|
+
private loadState;
|
|
43
|
+
private saveState;
|
|
44
|
+
private generateNewDeviceUuid;
|
|
45
|
+
private checkRateLimit;
|
|
46
|
+
private performLogin;
|
|
47
|
+
private handleLoginFailure;
|
|
48
|
+
handleSessionExpired(): void;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/client/auth.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAAgC,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAgD,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAUjD,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,SAAS,CAAY;gBAEjB,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU;IAazC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAa3B,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC;IA6CzC,cAAc,IAAI,OAAO;IAYnB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBrC,SAAS,IAAI,MAAM,GAAG,IAAI;IAO1B,WAAW,IAAI,MAAM,GAAG,IAAI;IAO5B,aAAa,IAAI,MAAM;IAOvB,mBAAmB,IAAI,OAAO;IAOxB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAYvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAatB,cAAc,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IA8C9E,OAAO,CAAC,cAAc;IAsBtB,OAAO,CAAC,gBAAgB;YAaV,SAAS;YA4BT,SAAS;YAiBT,qBAAqB;IAQnC,OAAO,CAAC,cAAc;YA8BR,YAAY;IAuB1B,OAAO,CAAC,kBAAkB;IAQnB,oBAAoB,IAAI,IAAI;CAMpC"}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AuthManager = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const uuid_1 = require("uuid");
|
|
7
|
+
const constants_1 = require("../types/constants");
|
|
8
|
+
const errors_1 = require("../utils/errors");
|
|
9
|
+
class AuthManager {
|
|
10
|
+
constructor(httpClient, config) {
|
|
11
|
+
this.httpClient = httpClient;
|
|
12
|
+
this.config = this.validateConfig(config);
|
|
13
|
+
this.stateFilePath = this.getStateFilePath();
|
|
14
|
+
this.authState = {
|
|
15
|
+
deviceUuid: (0, uuid_1.v4)(),
|
|
16
|
+
loginAttempts: 0
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
async initialize() {
|
|
20
|
+
try {
|
|
21
|
+
await this.loadState();
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
console.warn('Failed to load auth state, starting fresh:', error);
|
|
25
|
+
await this.generateNewDeviceUuid();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
async authenticate() {
|
|
29
|
+
this.checkRateLimit();
|
|
30
|
+
try {
|
|
31
|
+
const response = await this.performLogin();
|
|
32
|
+
if (response.success && response.api_key && response.mobile_id) {
|
|
33
|
+
this.authState.apiKey = response.api_key;
|
|
34
|
+
this.authState.mobileId = response.mobile_id;
|
|
35
|
+
this.authState.loginAttempts = 0;
|
|
36
|
+
this.authState.lastLoginAttempt = Date.now();
|
|
37
|
+
this.authState.sessionExpiry = Date.now() + (24 * 60 * 60 * 1000);
|
|
38
|
+
this.httpClient.setAuthHeaders(response.api_key, response.mobile_id, this.config.brand);
|
|
39
|
+
await this.saveState();
|
|
40
|
+
return {
|
|
41
|
+
apiKey: response.api_key,
|
|
42
|
+
mobileId: response.mobile_id,
|
|
43
|
+
success: true
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
this.handleLoginFailure();
|
|
48
|
+
throw new errors_1.AuthenticationError('Login failed: Invalid credentials');
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
this.handleLoginFailure();
|
|
53
|
+
if (error instanceof errors_1.AuthenticationError) {
|
|
54
|
+
throw error;
|
|
55
|
+
}
|
|
56
|
+
const nexiaError = errors_1.ErrorHandler.handle(error);
|
|
57
|
+
throw new errors_1.AuthenticationError(`Login failed: ${nexiaError.message}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
isSessionValid() {
|
|
61
|
+
return !!(this.authState.apiKey &&
|
|
62
|
+
this.authState.mobileId &&
|
|
63
|
+
this.authState.sessionExpiry &&
|
|
64
|
+
this.authState.sessionExpiry > Date.now());
|
|
65
|
+
}
|
|
66
|
+
async refreshSession() {
|
|
67
|
+
this.authState.apiKey = undefined;
|
|
68
|
+
this.authState.mobileId = undefined;
|
|
69
|
+
this.authState.sessionExpiry = undefined;
|
|
70
|
+
this.httpClient.clearAuthHeaders();
|
|
71
|
+
await this.authenticate();
|
|
72
|
+
}
|
|
73
|
+
getApiKey() {
|
|
74
|
+
return this.authState.apiKey || null;
|
|
75
|
+
}
|
|
76
|
+
getMobileId() {
|
|
77
|
+
return this.authState.mobileId || null;
|
|
78
|
+
}
|
|
79
|
+
getDeviceUuid() {
|
|
80
|
+
return this.authState.deviceUuid;
|
|
81
|
+
}
|
|
82
|
+
needsAuthentication() {
|
|
83
|
+
return !this.isSessionValid();
|
|
84
|
+
}
|
|
85
|
+
async logout() {
|
|
86
|
+
this.authState.apiKey = undefined;
|
|
87
|
+
this.authState.mobileId = undefined;
|
|
88
|
+
this.authState.sessionExpiry = undefined;
|
|
89
|
+
this.httpClient.clearAuthHeaders();
|
|
90
|
+
await this.saveState();
|
|
91
|
+
}
|
|
92
|
+
async reset() {
|
|
93
|
+
this.authState = {
|
|
94
|
+
deviceUuid: (0, uuid_1.v4)(),
|
|
95
|
+
loginAttempts: 0
|
|
96
|
+
};
|
|
97
|
+
this.httpClient.clearAuthHeaders();
|
|
98
|
+
await this.saveState();
|
|
99
|
+
}
|
|
100
|
+
async getSessionInfo() {
|
|
101
|
+
if (!this.isSessionValid()) {
|
|
102
|
+
await this.authenticate();
|
|
103
|
+
}
|
|
104
|
+
try {
|
|
105
|
+
const response = await this.httpClient.post(constants_1.API_ENDPOINTS.SESSION, {});
|
|
106
|
+
if (response.data.success && response.data.result?.homes) {
|
|
107
|
+
const homes = response.data.result.homes;
|
|
108
|
+
if (homes.length === 0) {
|
|
109
|
+
throw new errors_1.AuthenticationError('No homes found in account');
|
|
110
|
+
}
|
|
111
|
+
const targetHouse = this.config.houseId
|
|
112
|
+
? homes.find(h => h.house_id === this.config.houseId)
|
|
113
|
+
: homes[0];
|
|
114
|
+
if (!targetHouse) {
|
|
115
|
+
throw new errors_1.AuthenticationError(`House ID ${this.config.houseId} not found. Available houses: ${homes.map(h => h.house_id).join(', ')}`);
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
houseId: targetHouse.house_id,
|
|
119
|
+
houseName: targetHouse.name
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
throw new errors_1.AuthenticationError('Failed to retrieve session information');
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
if (error instanceof errors_1.AuthenticationError) {
|
|
128
|
+
throw error;
|
|
129
|
+
}
|
|
130
|
+
const nexiaError = errors_1.ErrorHandler.handle(error);
|
|
131
|
+
throw new errors_1.AuthenticationError(`Session discovery failed: ${nexiaError.message}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
validateConfig(config) {
|
|
135
|
+
if (!config.username || typeof config.username !== 'string') {
|
|
136
|
+
throw new errors_1.ConfigurationError('Username is required');
|
|
137
|
+
}
|
|
138
|
+
if (!config.password || typeof config.password !== 'string') {
|
|
139
|
+
throw new errors_1.ConfigurationError('Password is required');
|
|
140
|
+
}
|
|
141
|
+
if (!Object.values(constants_1.BrandType).includes(config.brand)) {
|
|
142
|
+
throw new errors_1.ConfigurationError(`Invalid brand: ${config.brand}. Must be one of: ${Object.values(constants_1.BrandType).join(', ')}`);
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
...config,
|
|
146
|
+
deviceName: config.deviceName || constants_1.API_CONSTANTS.DEFAULT_DEVICE_NAME
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
getStateFilePath() {
|
|
150
|
+
if (this.config.stateFile) {
|
|
151
|
+
return this.config.stateFile;
|
|
152
|
+
}
|
|
153
|
+
const homeDir = process.env['HOME'] || process.env['USERPROFILE'] || process.cwd();
|
|
154
|
+
return (0, path_1.join)(homeDir, '.nexia', 'auth-state.json');
|
|
155
|
+
}
|
|
156
|
+
async loadState() {
|
|
157
|
+
try {
|
|
158
|
+
const stateData = await fs_1.promises.readFile(this.stateFilePath, 'utf8');
|
|
159
|
+
const state = JSON.parse(stateData);
|
|
160
|
+
if (state.deviceUuid && typeof state.deviceUuid === 'string') {
|
|
161
|
+
this.authState = {
|
|
162
|
+
...this.authState,
|
|
163
|
+
...state
|
|
164
|
+
};
|
|
165
|
+
if (this.isSessionValid() && state.apiKey && state.mobileId) {
|
|
166
|
+
this.httpClient.setAuthHeaders(state.apiKey, state.mobileId, this.config.brand);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
throw new Error('Invalid state file format');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
await this.generateNewDeviceUuid();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
async saveState() {
|
|
178
|
+
try {
|
|
179
|
+
await fs_1.promises.mkdir((0, path_1.dirname)(this.stateFilePath), { recursive: true });
|
|
180
|
+
const stateData = JSON.stringify(this.authState, null, 2);
|
|
181
|
+
await fs_1.promises.writeFile(this.stateFilePath, stateData, 'utf8');
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
console.warn('Failed to save auth state:', error);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
async generateNewDeviceUuid() {
|
|
188
|
+
this.authState.deviceUuid = (0, uuid_1.v4)();
|
|
189
|
+
await this.saveState();
|
|
190
|
+
}
|
|
191
|
+
checkRateLimit() {
|
|
192
|
+
const now = Date.now();
|
|
193
|
+
const lastAttempt = this.authState.lastLoginAttempt || 0;
|
|
194
|
+
const timeSinceLastAttempt = now - lastAttempt;
|
|
195
|
+
if (timeSinceLastAttempt > 60 * 60 * 1000) {
|
|
196
|
+
this.authState.loginAttempts = 0;
|
|
197
|
+
}
|
|
198
|
+
if (this.authState.loginAttempts >= constants_1.API_CONSTANTS.MAX_LOGIN_ATTEMPTS) {
|
|
199
|
+
const waitTime = 60 * 60 * 1000;
|
|
200
|
+
const remainingWait = waitTime - timeSinceLastAttempt;
|
|
201
|
+
if (remainingWait > 0) {
|
|
202
|
+
throw new errors_1.RateLimitError(`Too many login attempts. Try again in ${Math.ceil(remainingWait / 60000)} minutes.`, Math.ceil(remainingWait / 1000));
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
this.authState.loginAttempts = 0;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
async performLogin() {
|
|
210
|
+
const loginData = {
|
|
211
|
+
login: this.config.username,
|
|
212
|
+
password: this.config.password,
|
|
213
|
+
device_uuid: this.authState.deviceUuid,
|
|
214
|
+
device_name: this.config.deviceName,
|
|
215
|
+
app_version: constants_1.API_CONSTANTS.APP_VERSION,
|
|
216
|
+
is_commercial: false
|
|
217
|
+
};
|
|
218
|
+
const response = await this.httpClient.post(constants_1.API_ENDPOINTS.SIGN_IN, loginData);
|
|
219
|
+
if (response.status === 302) {
|
|
220
|
+
throw new errors_1.AuthenticationError('Invalid credentials');
|
|
221
|
+
}
|
|
222
|
+
return response.data;
|
|
223
|
+
}
|
|
224
|
+
handleLoginFailure() {
|
|
225
|
+
this.authState.loginAttempts = (this.authState.loginAttempts || 0) + 1;
|
|
226
|
+
this.authState.lastLoginAttempt = Date.now();
|
|
227
|
+
}
|
|
228
|
+
handleSessionExpired() {
|
|
229
|
+
this.authState.apiKey = undefined;
|
|
230
|
+
this.authState.mobileId = undefined;
|
|
231
|
+
this.authState.sessionExpiry = undefined;
|
|
232
|
+
this.httpClient.clearAuthHeaders();
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
exports.AuthManager = AuthManager;
|
|
236
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/client/auth.ts"],"names":[],"mappings":";;;AAKA,2BAAoC;AACpC,+BAAqC;AACrC,+BAAoC;AACpC,kDAA6E;AAG7E,4CAOyB;AAoBzB,MAAa,WAAW;IAMtB,YAAY,UAAsB,EAAE,MAAkB;QACpD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC7C,IAAI,CAAC,SAAS,GAAG;YACf,UAAU,EAAE,IAAA,SAAM,GAAE;YACpB,aAAa,EAAE,CAAC;SACjB,CAAC;IACJ,CAAC;IAKM,KAAK,CAAC,UAAU;QACrB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAEf,OAAO,CAAC,IAAI,CAAC,4CAA4C,EAAE,KAAK,CAAC,CAAC;YAClE,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACrC,CAAC;IACH,CAAC;IAKM,KAAK,CAAC,YAAY;QAEvB,IAAI,CAAC,cAAc,EAAE,CAAC;QAEtB,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;YAE3C,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;gBAE/D,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC;gBACzC,IAAI,CAAC,SAAS,CAAC,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC;gBAC7C,IAAI,CAAC,SAAS,CAAC,aAAa,GAAG,CAAC,CAAC;gBACjC,IAAI,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBAC7C,IAAI,CAAC,SAAS,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;gBAGlE,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAGxF,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;gBAEvB,OAAO;oBACL,MAAM,EAAE,QAAQ,CAAC,OAAO;oBACxB,QAAQ,EAAE,QAAQ,CAAC,SAAS;oBAC5B,OAAO,EAAE,IAAI;iBACd,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC1B,MAAM,IAAI,4BAAmB,CAAC,mCAAmC,CAAC,CAAC;YACrE,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAE1B,IAAI,KAAK,YAAY,4BAAmB,EAAE,CAAC;gBACzC,MAAM,KAAK,CAAC;YACd,CAAC;YAED,MAAM,UAAU,GAAG,qBAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC9C,MAAM,IAAI,4BAAmB,CAAC,iBAAiB,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAKM,cAAc;QACnB,OAAO,CAAC,CAAC,CACP,IAAI,CAAC,SAAS,CAAC,MAAM;YACrB,IAAI,CAAC,SAAS,CAAC,QAAQ;YACvB,IAAI,CAAC,SAAS,CAAC,aAAa;YAC5B,IAAI,CAAC,SAAS,CAAC,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAC1C,CAAC;IACJ,CAAC;IAKM,KAAK,CAAC,cAAc;QAEzB,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC;QAClC,IAAI,CAAC,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC;QACpC,IAAI,CAAC,SAAS,CAAC,aAAa,GAAG,SAAS,CAAC;QAGzC,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC;QAGnC,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;IAC5B,CAAC;IAKM,SAAS;QACd,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC;IACvC,CAAC;IAKM,WAAW;QAChB,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,IAAI,IAAI,CAAC;IACzC,CAAC;IAKM,aAAa;QAClB,OAAO,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;IACnC,CAAC;IAKM,mBAAmB;QACxB,OAAO,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;IAChC,CAAC;IAKM,KAAK,CAAC,MAAM;QACjB,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC;QAClC,IAAI,CAAC,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC;QACpC,IAAI,CAAC,SAAS,CAAC,aAAa,GAAG,SAAS,CAAC;QAEzC,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC;QACnC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;IACzB,CAAC;IAKM,KAAK,CAAC,KAAK;QAChB,IAAI,CAAC,SAAS,GAAG;YACf,UAAU,EAAE,IAAA,SAAM,GAAE;YACpB,aAAa,EAAE,CAAC;SACjB,CAAC;QAEF,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC;QACnC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;IACzB,CAAC;IAKM,KAAK,CAAC,cAAc;QACzB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;YAC3B,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC5B,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAkB,yBAAa,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAExF,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;gBACzD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;gBAEzC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBACvB,MAAM,IAAI,4BAAmB,CAAC,2BAA2B,CAAC,CAAC;gBAC7D,CAAC;gBAGD,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO;oBACrC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;oBACrD,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAEb,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,MAAM,IAAI,4BAAmB,CAC3B,YAAY,IAAI,CAAC,MAAM,CAAC,OAAO,iCAAiC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACxG,CAAC;gBACJ,CAAC;gBAED,OAAO;oBACL,OAAO,EAAE,WAAW,CAAC,QAAQ;oBAC7B,SAAS,EAAE,WAAW,CAAC,IAAI;iBAC5B,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,4BAAmB,CAAC,wCAAwC,CAAC,CAAC;YAC1E,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,4BAAmB,EAAE,CAAC;gBACzC,MAAM,KAAK,CAAC;YACd,CAAC;YAED,MAAM,UAAU,GAAG,qBAAY,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC9C,MAAM,IAAI,4BAAmB,CAAC,6BAA6B,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;QACnF,CAAC;IACH,CAAC;IAKO,cAAc,CAAC,MAAkB;QACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC5D,MAAM,IAAI,2BAAkB,CAAC,sBAAsB,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC5D,MAAM,IAAI,2BAAkB,CAAC,sBAAsB,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,qBAAS,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YACrD,MAAM,IAAI,2BAAkB,CAAC,kBAAkB,MAAM,CAAC,KAAK,qBAAqB,MAAM,CAAC,MAAM,CAAC,qBAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzH,CAAC;QAED,OAAO;YACL,GAAG,MAAM;YACT,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,yBAAa,CAAC,mBAAmB;SACnE,CAAC;IACJ,CAAC;IAKO,gBAAgB;QACtB,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;QAC/B,CAAC;QAGD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QACnF,OAAO,IAAA,WAAI,EAAC,OAAO,EAAE,QAAQ,EAAE,iBAAiB,CAAC,CAAC;IACpD,CAAC;IAKO,KAAK,CAAC,SAAS;QACrB,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,aAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;YAChE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAc,CAAC;YAGjD,IAAI,KAAK,CAAC,UAAU,IAAI,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;gBAC7D,IAAI,CAAC,SAAS,GAAG;oBACf,GAAG,IAAI,CAAC,SAAS;oBACjB,GAAG,KAAK;iBACT,CAAC;gBAGF,IAAI,IAAI,CAAC,cAAc,EAAE,IAAI,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;oBAC5D,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAClF,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC/C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YAEP,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;QACrC,CAAC;IACH,CAAC;IAKO,KAAK,CAAC,SAAS;QACrB,IAAI,CAAC;YAEH,MAAM,aAAE,CAAC,KAAK,CAAC,IAAA,cAAO,EAAC,IAAI,CAAC,aAAa,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAGjE,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC1D,MAAM,aAAE,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QAC5D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;QAEpD,CAAC;IACH,CAAC;IAKO,KAAK,CAAC,qBAAqB;QACjC,IAAI,CAAC,SAAS,CAAC,UAAU,GAAG,IAAA,SAAM,GAAE,CAAC;QACrC,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;IACzB,CAAC;IAKO,cAAc;QACpB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACvB,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,gBAAgB,IAAI,CAAC,CAAC;QACzD,MAAM,oBAAoB,GAAG,GAAG,GAAG,WAAW,CAAC;QAG/C,IAAI,oBAAoB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;YAC1C,IAAI,CAAC,SAAS,CAAC,aAAa,GAAG,CAAC,CAAC;QACnC,CAAC;QAGD,IAAI,IAAI,CAAC,SAAS,CAAC,aAAa,IAAI,yBAAa,CAAC,kBAAkB,EAAE,CAAC;YACrE,MAAM,QAAQ,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;YAChC,MAAM,aAAa,GAAG,QAAQ,GAAG,oBAAoB,CAAC;YAEtD,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;gBACtB,MAAM,IAAI,uBAAc,CACtB,yCAAyC,IAAI,CAAC,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,WAAW,EACpF,IAAI,CAAC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,CAChC,CAAC;YACJ,CAAC;iBAAM,CAAC;gBAEN,IAAI,CAAC,SAAS,CAAC,aAAa,GAAG,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;IACH,CAAC;IAKO,KAAK,CAAC,YAAY;QACxB,MAAM,SAAS,GAAiB;YAC9B,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC3B,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ;YAC9B,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU;YACtC,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,UAAW;YACpC,WAAW,EAAE,yBAAa,CAAC,WAAW;YACtC,aAAa,EAAE,KAAK;SACrB,CAAC;QAEF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAgB,yBAAa,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;QAG7F,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,4BAAmB,CAAC,qBAAqB,CAAC,CAAC;QACvD,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IAKO,kBAAkB;QACxB,IAAI,CAAC,SAAS,CAAC,aAAa,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QACvE,IAAI,CAAC,SAAS,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC/C,CAAC;IAKM,oBAAoB;QACzB,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,SAAS,CAAC;QAClC,IAAI,CAAC,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC;QACpC,IAAI,CAAC,SAAS,CAAC,aAAa,GAAG,SAAS,CAAC;QACzC,IAAI,CAAC,UAAU,CAAC,gBAAgB,EAAE,CAAC;IACrC,CAAC;CACF;AAvWD,kCAuWC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { BrandType } from '../types/constants';
|
|
2
|
+
import { NexiaClientConfig, UpdateOptions } from '../types/api';
|
|
3
|
+
import { INexiaClient, INexiaThermostat, INexiaAutomation } from '../types/interfaces';
|
|
4
|
+
export declare class NexiaClient implements INexiaClient {
|
|
5
|
+
private readonly httpClient;
|
|
6
|
+
private readonly authManager;
|
|
7
|
+
private readonly config;
|
|
8
|
+
private _houseId?;
|
|
9
|
+
private _houseName?;
|
|
10
|
+
private thermostats;
|
|
11
|
+
private automations;
|
|
12
|
+
private _lastUpdate;
|
|
13
|
+
private isInitialized;
|
|
14
|
+
constructor(config: NexiaClientConfig);
|
|
15
|
+
initialize(): Promise<void>;
|
|
16
|
+
login(): Promise<void>;
|
|
17
|
+
logout(): Promise<void>;
|
|
18
|
+
isAuthenticated(): boolean;
|
|
19
|
+
getThermostats(): Promise<INexiaThermostat[]>;
|
|
20
|
+
getAutomations(): Promise<INexiaAutomation[]>;
|
|
21
|
+
getThermostatById(id: string): INexiaThermostat | undefined;
|
|
22
|
+
getAutomationById(id: string): INexiaAutomation | undefined;
|
|
23
|
+
update(options?: UpdateOptions): Promise<void>;
|
|
24
|
+
get<T>(url: string, headers?: Record<string, string>): Promise<T>;
|
|
25
|
+
post<T>(url: string, data: unknown, headers?: Record<string, string>): Promise<T>;
|
|
26
|
+
put<T>(url: string, data: unknown, headers?: Record<string, string>): Promise<T>;
|
|
27
|
+
get brand(): BrandType;
|
|
28
|
+
get username(): string;
|
|
29
|
+
getHouseId(): number | undefined;
|
|
30
|
+
get lastUpdate(): Date | null;
|
|
31
|
+
getThermostatIds(): string[];
|
|
32
|
+
getAutomationIds(): string[];
|
|
33
|
+
clearCache(): void;
|
|
34
|
+
private validateConfig;
|
|
35
|
+
private ensureAuthenticated;
|
|
36
|
+
private processHouseData;
|
|
37
|
+
private processThermostat;
|
|
38
|
+
private processAutomation;
|
|
39
|
+
private clearDeviceCache;
|
|
40
|
+
private isSessionExpiredError;
|
|
41
|
+
private handleSessionExpiry;
|
|
42
|
+
delayedUpdate(delayMs?: number): Promise<void>;
|
|
43
|
+
getBaseUrl(): string;
|
|
44
|
+
getMobileUrl(): string;
|
|
45
|
+
getUpdateUrl(): string | null;
|
|
46
|
+
getHouseName(): string | undefined;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=nexia-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nexia-client.d.ts","sourceRoot":"","sources":["../../src/client/nexia-client.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAA0C,MAAM,oBAAoB,CAAC;AACvF,OAAO,EAIL,iBAAiB,EACjB,aAAa,EACd,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAavF,qBAAa,WAAY,YAAW,YAAY;IAC9C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAE3C,OAAO,CAAC,QAAQ,CAAC,CAAS;IAE1B,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,WAAW,CAA4C;IAC/D,OAAO,CAAC,WAAW,CAA4C;IAC/D,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,aAAa,CAAkB;gBAE3B,MAAM,EAAE,iBAAiB;IA8BxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyBtB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAS7B,eAAe,IAAI,OAAO;IAOpB,cAAc,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAQ7C,cAAc,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAQnD,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAO3D,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS;IAOrD,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC;IAmClD,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAoBjE,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAoBjF,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAkB7F,IAAW,KAAK,IAAI,SAAS,CAE5B;IAED,IAAW,QAAQ,IAAI,MAAM,CAE5B;IAEM,UAAU,IAAI,MAAM,GAAG,SAAS;IAIvC,IAAW,UAAU,IAAI,IAAI,GAAG,IAAI,CAEnC;IAKM,gBAAgB,IAAI,MAAM,EAAE;IAO5B,gBAAgB,IAAI,MAAM,EAAE;IAO5B,UAAU,IAAI,IAAI;IAOzB,OAAO,CAAC,cAAc;YAwBR,mBAAmB;YAanB,gBAAgB;YAqDhB,iBAAiB;YAiBjB,iBAAiB;IAiB/B,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,qBAAqB;YAWf,mBAAmB;IAqBpB,aAAa,CAAC,OAAO,GAAE,MAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB1D,UAAU,IAAI,MAAM;IAOpB,YAAY,IAAI,MAAM;IAOtB,YAAY,IAAI,MAAM,GAAG,IAAI;IAO7B,YAAY,IAAI,MAAM,GAAG,SAAS;CAG1C"}
|