@mp-consulting/homebridge-daikin-cloud 1.3.5 → 1.3.7
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 +39 -1
- package/README.md +5 -3
- package/dist/src/accessories/air-conditioning-accessory.d.ts +2 -2
- package/dist/src/accessories/air-conditioning-accessory.d.ts.map +1 -1
- package/dist/src/accessories/air-conditioning-accessory.js.map +1 -1
- package/dist/src/accessories/altherma-accessory.d.ts +2 -2
- package/dist/src/accessories/altherma-accessory.d.ts.map +1 -1
- package/dist/src/accessories/altherma-accessory.js.map +1 -1
- package/dist/src/accessories/base-accessory.d.ts +6 -6
- package/dist/src/accessories/base-accessory.d.ts.map +1 -1
- package/dist/src/accessories/base-accessory.js +15 -15
- package/dist/src/accessories/base-accessory.js.map +1 -1
- package/dist/src/api/daikin-api.d.ts +26 -26
- package/dist/src/api/daikin-api.d.ts.map +1 -1
- package/dist/src/api/daikin-api.js +68 -42
- package/dist/src/api/daikin-api.js.map +1 -1
- package/dist/src/api/daikin-cloud.repository.d.ts.map +1 -1
- package/dist/src/api/daikin-cloud.repository.js +22 -14
- package/dist/src/api/daikin-cloud.repository.js.map +1 -1
- package/dist/src/api/daikin-controller.d.ts +41 -47
- package/dist/src/api/daikin-controller.d.ts.map +1 -1
- package/dist/src/api/daikin-controller.js +40 -64
- package/dist/src/api/daikin-controller.js.map +1 -1
- package/dist/src/api/daikin-device.d.ts +36 -31
- package/dist/src/api/daikin-device.d.ts.map +1 -1
- package/dist/src/api/daikin-device.js +45 -31
- package/dist/src/api/daikin-device.js.map +1 -1
- package/dist/src/api/daikin-mobile-oauth.d.ts +20 -20
- package/dist/src/api/daikin-mobile-oauth.d.ts.map +1 -1
- package/dist/src/api/daikin-mobile-oauth.js +49 -44
- package/dist/src/api/daikin-mobile-oauth.js.map +1 -1
- package/dist/src/api/daikin-oauth.d.ts +32 -32
- package/dist/src/api/daikin-oauth.d.ts.map +1 -1
- package/dist/src/api/daikin-oauth.js +64 -56
- package/dist/src/api/daikin-oauth.js.map +1 -1
- package/dist/src/api/daikin-schemas.d.ts +476 -351
- package/dist/src/api/daikin-schemas.d.ts.map +1 -1
- package/dist/src/api/daikin-schemas.js +11 -42
- package/dist/src/api/daikin-schemas.js.map +1 -1
- package/dist/src/api/daikin-types.d.ts +5 -1
- package/dist/src/api/daikin-types.d.ts.map +1 -1
- package/dist/src/api/daikin-types.js.map +1 -1
- package/dist/src/api/daikin-websocket.d.ts +31 -32
- package/dist/src/api/daikin-websocket.d.ts.map +1 -1
- package/dist/src/api/daikin-websocket.js +55 -35
- package/dist/src/api/daikin-websocket.js.map +1 -1
- package/dist/src/api/index.d.ts +2 -1
- package/dist/src/api/index.d.ts.map +1 -1
- package/dist/src/api/index.js +3 -1
- package/dist/src/api/index.js.map +1 -1
- package/dist/src/api/token-storage.d.ts +21 -0
- package/dist/src/api/token-storage.d.ts.map +1 -0
- package/dist/src/api/token-storage.js +90 -0
- package/dist/src/api/token-storage.js.map +1 -0
- package/dist/src/config/config-manager.d.ts +33 -33
- package/dist/src/config/config-manager.d.ts.map +1 -1
- package/dist/src/config/config-manager.js +33 -33
- package/dist/src/config/config-manager.js.map +1 -1
- package/dist/src/constants/api.constants.d.ts +4 -0
- package/dist/src/constants/api.constants.d.ts.map +1 -1
- package/dist/src/constants/api.constants.js +5 -1
- package/dist/src/constants/api.constants.js.map +1 -1
- package/dist/src/constants/device.constants.d.ts +4 -0
- package/dist/src/constants/device.constants.d.ts.map +1 -1
- package/dist/src/constants/device.constants.js +5 -1
- package/dist/src/constants/device.constants.js.map +1 -1
- package/dist/src/device/accessory-factory.d.ts +10 -10
- package/dist/src/device/accessory-factory.d.ts.map +1 -1
- package/dist/src/device/accessory-factory.js +7 -7
- package/dist/src/device/accessory-factory.js.map +1 -1
- package/dist/src/device/capability-detector.d.ts +8 -8
- package/dist/src/device/capability-detector.d.ts.map +1 -1
- package/dist/src/device/capability-detector.js +6 -6
- package/dist/src/device/capability-detector.js.map +1 -1
- package/dist/src/device/capability-docs.d.ts +1 -9
- package/dist/src/device/capability-docs.d.ts.map +1 -1
- package/dist/src/device/capability-docs.js +19 -73
- package/dist/src/device/capability-docs.js.map +1 -1
- package/dist/src/device/profiles/device-profile.d.ts +1 -1
- package/dist/src/device/profiles/device-profile.d.ts.map +1 -1
- package/dist/src/device/profiles/device-profile.js +4 -4
- package/dist/src/device/profiles/device-profile.js.map +1 -1
- package/dist/src/features/base-feature.d.ts +2 -2
- package/dist/src/features/base-feature.d.ts.map +1 -1
- package/dist/src/features/base-feature.js +2 -3
- package/dist/src/features/base-feature.js.map +1 -1
- package/dist/src/features/feature-manager.d.ts +8 -16
- package/dist/src/features/feature-manager.d.ts.map +1 -1
- package/dist/src/features/feature-manager.js +5 -17
- package/dist/src/features/feature-manager.js.map +1 -1
- package/dist/src/features/modes/dry-operation-mode.feature.d.ts +1 -1
- package/dist/src/features/modes/dry-operation-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/dry-operation-mode.feature.js.map +1 -1
- package/dist/src/features/modes/econo-mode.feature.d.ts +1 -1
- package/dist/src/features/modes/econo-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/econo-mode.feature.js.map +1 -1
- package/dist/src/features/modes/fan-only-operation-mode.feature.d.ts +1 -1
- package/dist/src/features/modes/fan-only-operation-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/fan-only-operation-mode.feature.js.map +1 -1
- package/dist/src/features/modes/indoor-silent-mode.feature.d.ts +1 -1
- package/dist/src/features/modes/indoor-silent-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/indoor-silent-mode.feature.js.map +1 -1
- package/dist/src/features/modes/outdoor-silent-mode.feature.d.ts +1 -1
- package/dist/src/features/modes/outdoor-silent-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/outdoor-silent-mode.feature.js.map +1 -1
- package/dist/src/features/modes/powerful-mode.feature.d.ts +1 -1
- package/dist/src/features/modes/powerful-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/powerful-mode.feature.js.map +1 -1
- package/dist/src/features/modes/streamer-mode.feature.d.ts +1 -1
- package/dist/src/features/modes/streamer-mode.feature.d.ts.map +1 -1
- package/dist/src/features/modes/streamer-mode.feature.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/platform.d.ts +11 -8
- package/dist/src/platform.d.ts.map +1 -1
- package/dist/src/platform.js +64 -15
- package/dist/src/platform.js.map +1 -1
- package/dist/src/services/climate-control.service.d.ts +8 -2
- package/dist/src/services/climate-control.service.d.ts.map +1 -1
- package/dist/src/services/climate-control.service.js +59 -58
- package/dist/src/services/climate-control.service.js.map +1 -1
- package/dist/src/services/hot-water-tank.service.d.ts +6 -2
- package/dist/src/services/hot-water-tank.service.d.ts.map +1 -1
- package/dist/src/services/hot-water-tank.service.js +33 -31
- package/dist/src/services/hot-water-tank.service.js.map +1 -1
- package/dist/src/types/daikin-enums.js +12 -12
- package/dist/src/types/daikin-enums.js.map +1 -1
- package/dist/src/types/device-capabilities.d.ts +1 -1
- package/dist/src/types/device-capabilities.d.ts.map +1 -1
- package/dist/src/utils/log-context.d.ts +23 -23
- package/dist/src/utils/log-context.d.ts.map +1 -1
- package/dist/src/utils/log-context.js +28 -28
- package/dist/src/utils/log-context.js.map +1 -1
- package/dist/src/utils/strings.d.ts.map +1 -1
- package/dist/src/utils/strings.js.map +1 -1
- package/dist/src/utils/update-mapper.d.ts +16 -16
- package/dist/src/utils/update-mapper.d.ts.map +1 -1
- package/dist/src/utils/update-mapper.js +14 -14
- package/dist/src/utils/update-mapper.js.map +1 -1
- package/homebridge-ui/public/index.html +2 -2
- package/homebridge-ui/public/script.js +957 -898
- package/homebridge-ui/server.js +746 -678
- package/package.json +29 -27
- package/.claude/settings.json +0 -3
- package/.claude/settings.local.json +0 -29
- package/CHANGELOG.md +0 -103
- package/CLAUDE.md +0 -269
- package/config.md +0 -2
- package/dist/src/api/daikin-device-tracker.d.ts +0 -97
- package/dist/src/api/daikin-device-tracker.d.ts.map +0 -1
- package/dist/src/api/daikin-device-tracker.js +0 -136
- package/dist/src/api/daikin-device-tracker.js.map +0 -1
- package/dist/src/api/http-interceptor.d.ts +0 -99
- package/dist/src/api/http-interceptor.d.ts.map +0 -1
- package/dist/src/api/http-interceptor.js +0 -177
- package/dist/src/api/http-interceptor.js.map +0 -1
- package/dist/src/di/service-container.d.ts +0 -92
- package/dist/src/di/service-container.d.ts.map +0 -1
- package/dist/src/di/service-container.js +0 -156
- package/dist/src/di/service-container.js.map +0 -1
- package/dist/src/features/feature-registry.d.ts +0 -100
- package/dist/src/features/feature-registry.d.ts.map +0 -1
- package/dist/src/features/feature-registry.js +0 -142
- package/dist/src/features/feature-registry.js.map +0 -1
- package/dist/src/services/service-factory.d.ts +0 -46
- package/dist/src/services/service-factory.d.ts.map +0 -1
- package/dist/src/services/service-factory.js +0 -72
- package/dist/src/services/service-factory.js.map +0 -1
- package/dist/src/utils/error-handler.d.ts +0 -101
- package/dist/src/utils/error-handler.d.ts.map +0 -1
- package/dist/src/utils/error-handler.js +0 -251
- package/dist/src/utils/error-handler.js.map +0 -1
- package/dist/src/utils/retry.d.ts +0 -42
- package/dist/src/utils/retry.d.ts.map +0 -1
- package/dist/src/utils/retry.js +0 -70
- package/dist/src/utils/retry.js.map +0 -1
- package/docs/ARCHITECTURE.md +0 -645
- package/docs/IMPLEMENTATION_GUIDE.md +0 -899
- package/docs/IMPROVEMENTS_SUMMARY.md +0 -415
- package/docs/NEXT_STEPS.md +0 -368
- package/docs/Screenshot 2024-07-04 at 18.41.28.png +0 -0
- package/docs/TROUBLESHOOTING.md +0 -475
- package/docs/api-response-for-BRP069A8x.json +0 -520
- package/docs/api-response-for-BRP069C4x-2.json +0 -881
- package/docs/api-response-for-BRP069C4x.json +0 -916
- package/docs/api-response-for-altherma.json +0 -759
- package/docs/api-response-for-altherma2.json +0 -2735
- package/docs/api-response-with-multiple-devices-incl-heatpump.json +0 -2544
- package/docs/cr-insance-altherma-id-0.json +0 -834
- package/docs/mock-air-to-air-dx23.json +0 -759
- package/docs/mock-air-to-air-dx4.json +0 -1134
- package/docs/mock-airpurifier-with-humidifier.json +0 -732
- package/docs/mock-airpurifier.json +0 -450
- package/docs/mock-altherma-air-to-water-lan.json +0 -845
- package/docs/mock-altherma-air-to-water-wlan.json +0 -845
- package/docs/mock-d2cnd-gas-boiler.json +0 -649
- package/docs/setpointmode-vs-controlmode-vs-setpoints-vs-sensorydata.txt +0 -6
- package/images/fan-speed.jpeg +0 -0
- package/images/homekit-controls.jpeg +0 -0
- package/images/homekit-settings.jpeg +0 -0
- package/images/swing-mode.png +0 -0
- package/jest.config.ts +0 -13
- package/test/fixtures/altherma-crSense-2.ts +0 -834
- package/test/fixtures/altherma-fraction.ts +0 -718
- package/test/fixtures/altherma-heat-pump-2.ts +0 -479
- package/test/fixtures/altherma-heat-pump.ts +0 -757
- package/test/fixtures/altherma-miladcerkic-off.ts +0 -524
- package/test/fixtures/altherma-miladcerkic.ts +0 -524
- package/test/fixtures/altherma-v1ckoeln.ts +0 -644
- package/test/fixtures/altherma-with-embedded-id-zero.ts +0 -834
- package/test/fixtures/dx23-airco-2.ts +0 -343
- package/test/fixtures/dx23-airco.ts +0 -518
- package/test/fixtures/dx4-airco.ts +0 -914
- package/test/fixtures/unknown-jan.ts +0 -488
- package/test/fixtures/unknown-kitchen-guests.ts +0 -488
- package/test/helpers/test-isolation.ts +0 -228
- package/test/integration/air-conditioning.test.ts +0 -410
- package/test/integration/altherma.test.ts +0 -289
- package/test/integration/platform.test.ts +0 -118
- package/test/mocks/index.ts +0 -27
- package/test/test-gigya-auth.js +0 -443
- package/test/test-mobile-oauth.js +0 -175
- package/test/test-websocket-mobile.js +0 -123
- package/test/test-websocket.js +0 -116
- package/test/unit/api/__snapshots__/daikinCloud.test.ts.snap +0 -1320
- package/test/unit/api/daikin-api.test.ts +0 -384
- package/test/unit/api/daikin-oauth.test.ts +0 -214
- package/test/unit/api/daikinCloud.test.ts +0 -12
- package/test/unit/config/config-manager.test.ts +0 -271
- package/test/unit/device/daikin-device.test.ts +0 -79
- package/test/unit/services/hot-water-tank.service.test.ts +0 -123
- package/test/unit/utils/error-handler.test.ts +0 -274
- package/test/unit/utils/log-context.test.ts +0 -271
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Device Tracker
|
|
4
|
-
*
|
|
5
|
-
* Tracks device state changes and errors for differential updates and diagnostics.
|
|
6
|
-
* Enables efficient polling by only updating devices that have changed.
|
|
7
|
-
*/
|
|
8
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.DeviceTracker = void 0;
|
|
13
|
-
const crypto_1 = __importDefault(require("crypto"));
|
|
14
|
-
/**
|
|
15
|
-
* Device Tracker for managing device state and error history
|
|
16
|
-
*/
|
|
17
|
-
class DeviceTracker {
|
|
18
|
-
lastUpdate = new Date();
|
|
19
|
-
dataHash = '';
|
|
20
|
-
errors = [];
|
|
21
|
-
maxErrors = 10; // Keep last 10 errors
|
|
22
|
-
/**
|
|
23
|
-
* Check if device data has changed since last update
|
|
24
|
-
*
|
|
25
|
-
* @param newData - New device data from API
|
|
26
|
-
* @returns True if data has changed
|
|
27
|
-
*/
|
|
28
|
-
hasChanges(newData) {
|
|
29
|
-
const newHash = this.computeHash(newData);
|
|
30
|
-
return this.dataHash !== newHash;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Update the tracked state
|
|
34
|
-
*
|
|
35
|
-
* @param data - Device data to track
|
|
36
|
-
*/
|
|
37
|
-
updateState(data) {
|
|
38
|
-
this.lastUpdate = new Date();
|
|
39
|
-
this.dataHash = this.computeHash(data);
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Get time since last update in milliseconds
|
|
43
|
-
*
|
|
44
|
-
* @returns Milliseconds since last update
|
|
45
|
-
*/
|
|
46
|
-
getTimeSinceLastUpdate() {
|
|
47
|
-
return Date.now() - this.lastUpdate.getTime();
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Get last update timestamp
|
|
51
|
-
*
|
|
52
|
-
* @returns Date of last update
|
|
53
|
-
*/
|
|
54
|
-
getLastUpdateTime() {
|
|
55
|
-
return this.lastUpdate;
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Add an error to the device error history
|
|
59
|
-
*
|
|
60
|
-
* @param error - Error details
|
|
61
|
-
*/
|
|
62
|
-
addError(error) {
|
|
63
|
-
this.errors.unshift(error);
|
|
64
|
-
if (this.errors.length > this.maxErrors) {
|
|
65
|
-
this.errors.pop();
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Get all recorded errors
|
|
70
|
-
*
|
|
71
|
-
* @returns Array of errors
|
|
72
|
-
*/
|
|
73
|
-
getErrors() {
|
|
74
|
-
return [...this.errors];
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Get errors since a specific time
|
|
78
|
-
*
|
|
79
|
-
* @param since - Date to filter errors from
|
|
80
|
-
* @returns Filtered errors
|
|
81
|
-
*/
|
|
82
|
-
getRecentErrors(since) {
|
|
83
|
-
return this.errors.filter(e => e.timestamp >= since);
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Clear all recorded errors
|
|
87
|
-
*/
|
|
88
|
-
clearErrors() {
|
|
89
|
-
this.errors = [];
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Check if device has recent errors (within last 5 minutes)
|
|
93
|
-
*
|
|
94
|
-
* @returns True if recent errors exist
|
|
95
|
-
*/
|
|
96
|
-
hasRecentErrors() {
|
|
97
|
-
const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000);
|
|
98
|
-
return this.getRecentErrors(fiveMinutesAgo).length > 0;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Get error count by severity
|
|
102
|
-
*
|
|
103
|
-
* @returns Object with error and warning counts
|
|
104
|
-
*/
|
|
105
|
-
getErrorStats() {
|
|
106
|
-
return {
|
|
107
|
-
errors: this.errors.filter(e => e.severity === 'error').length,
|
|
108
|
-
warnings: this.errors.filter(e => e.severity === 'warning').length,
|
|
109
|
-
};
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Compute hash of device data for change detection
|
|
113
|
-
*
|
|
114
|
-
* Uses MD5 hash of JSON-stringified data for fast comparison.
|
|
115
|
-
* Note: This is for change detection only, not cryptographic security.
|
|
116
|
-
*
|
|
117
|
-
* @param data - Device data to hash
|
|
118
|
-
* @returns MD5 hash string
|
|
119
|
-
*/
|
|
120
|
-
computeHash(data) {
|
|
121
|
-
try {
|
|
122
|
-
// Create a stable JSON representation
|
|
123
|
-
const stableJson = JSON.stringify(data, Object.keys(data).sort());
|
|
124
|
-
return crypto_1.default
|
|
125
|
-
.createHash('md5')
|
|
126
|
-
.update(stableJson)
|
|
127
|
-
.digest('hex');
|
|
128
|
-
}
|
|
129
|
-
catch (error) {
|
|
130
|
-
// If hashing fails, return a timestamp-based hash to force update
|
|
131
|
-
return Date.now().toString();
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
exports.DeviceTracker = DeviceTracker;
|
|
136
|
-
//# sourceMappingURL=daikin-device-tracker.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"daikin-device-tracker.js","sourceRoot":"","sources":["../../../src/api/daikin-device-tracker.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;AAEH,oDAA4B;AAW5B;;GAEG;AACH,MAAa,aAAa;IACd,UAAU,GAAS,IAAI,IAAI,EAAE,CAAC;IAC9B,QAAQ,GAAW,EAAE,CAAC;IACtB,MAAM,GAAkB,EAAE,CAAC;IAClB,SAAS,GAAG,EAAE,CAAC,CAAC,sBAAsB;IAEvD;;;;;OAKG;IACH,UAAU,CAAC,OAAsB;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC,QAAQ,KAAK,OAAO,CAAC;IACrC,CAAC;IAED;;;;OAIG;IACH,WAAW,CAAC,IAAmB;QAC3B,IAAI,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED;;;;OAIG;IACH,sBAAsB;QAClB,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,iBAAiB;QACb,OAAO,IAAI,CAAC,UAAU,CAAC;IAC3B,CAAC;IAED;;;;OAIG;IACH,QAAQ,CAAC,KAAkB;QACvB,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE;YACrC,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;SACrB;IACL,CAAC;IAED;;;;OAIG;IACH,SAAS;QACL,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IAED;;;;;OAKG;IACH,eAAe,CAAC,KAAW;QACvB,OAAO,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC,CAAC;IACzD,CAAC;IAED;;OAEG;IACH,WAAW;QACP,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IACrB,CAAC;IAED;;;;OAIG;IACH,eAAe;QACX,MAAM,cAAc,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3D,CAAC;IAED;;;;OAIG;IACH,aAAa;QACT,OAAO;YACH,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM;YAC9D,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,MAAM;SACrE,CAAC;IACN,CAAC;IAED;;;;;;;;OAQG;IACK,WAAW,CAAC,IAAmB;QACnC,IAAI;YACA,sCAAsC;YACtC,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAClE,OAAO,gBAAM;iBACR,UAAU,CAAC,KAAK,CAAC;iBACjB,MAAM,CAAC,UAAU,CAAC;iBAClB,MAAM,CAAC,KAAK,CAAC,CAAC;SACtB;QAAC,OAAO,KAAK,EAAE;YACZ,kEAAkE;YAClE,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;SAChC;IACL,CAAC;CACJ;AA/HD,sCA+HC"}
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* HTTP Interceptor Pattern
|
|
3
|
-
*
|
|
4
|
-
* Provides a clean separation of concerns for request/response handling,
|
|
5
|
-
* including rate limiting, retry logic, and error handling.
|
|
6
|
-
*/
|
|
7
|
-
export interface HttpRequest {
|
|
8
|
-
url: string;
|
|
9
|
-
method: 'GET' | 'PATCH' | 'POST' | 'DELETE';
|
|
10
|
-
headers: Record<string, string>;
|
|
11
|
-
body?: string;
|
|
12
|
-
}
|
|
13
|
-
export interface HttpResponse {
|
|
14
|
-
statusCode: number;
|
|
15
|
-
body: string;
|
|
16
|
-
headers: Record<string, string | string[] | undefined>;
|
|
17
|
-
}
|
|
18
|
-
export interface Interceptor {
|
|
19
|
-
/**
|
|
20
|
-
* Called before making the request
|
|
21
|
-
* Can modify the request or throw to prevent it
|
|
22
|
-
*/
|
|
23
|
-
beforeRequest?(request: HttpRequest): Promise<HttpRequest> | HttpRequest;
|
|
24
|
-
/**
|
|
25
|
-
* Called after receiving the response
|
|
26
|
-
* Can modify the response or throw to handle errors
|
|
27
|
-
*/
|
|
28
|
-
afterResponse?(response: HttpResponse, request: HttpRequest): Promise<HttpResponse> | HttpResponse;
|
|
29
|
-
/**
|
|
30
|
-
* Called when an error occurs
|
|
31
|
-
* Can handle the error or re-throw
|
|
32
|
-
*/
|
|
33
|
-
onError?(error: Error, request: HttpRequest): Promise<never> | never;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* HTTP Client with interceptor support
|
|
37
|
-
*/
|
|
38
|
-
export declare class HttpClient {
|
|
39
|
-
private interceptors;
|
|
40
|
-
/**
|
|
41
|
-
* Add an interceptor
|
|
42
|
-
*/
|
|
43
|
-
use(interceptor: Interceptor): void;
|
|
44
|
-
/**
|
|
45
|
-
* Execute request with all interceptors
|
|
46
|
-
*/
|
|
47
|
-
execute(request: HttpRequest, executor: (req: HttpRequest) => Promise<HttpResponse>): Promise<HttpResponse>;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Rate Limit Interceptor
|
|
51
|
-
*/
|
|
52
|
-
export declare class RateLimitInterceptor implements Interceptor {
|
|
53
|
-
private readonly maxBlockSeconds;
|
|
54
|
-
private readonly msPerSecond;
|
|
55
|
-
private blockedUntil;
|
|
56
|
-
constructor(maxBlockSeconds: number, msPerSecond: number);
|
|
57
|
-
beforeRequest(request: HttpRequest): HttpRequest;
|
|
58
|
-
afterResponse(response: HttpResponse): HttpResponse;
|
|
59
|
-
private isBlocked;
|
|
60
|
-
private getRetryAfter;
|
|
61
|
-
private parseRetryAfter;
|
|
62
|
-
/**
|
|
63
|
-
* Check if currently rate limited
|
|
64
|
-
*/
|
|
65
|
-
isRateLimited(): boolean;
|
|
66
|
-
/**
|
|
67
|
-
* Get time until rate limit is lifted
|
|
68
|
-
*/
|
|
69
|
-
getRateLimitRetryAfter(): number;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Retry Interceptor for transient errors
|
|
73
|
-
*/
|
|
74
|
-
export declare class RetryInterceptor implements Interceptor {
|
|
75
|
-
private readonly maxAttempts;
|
|
76
|
-
private readonly baseDelayMs;
|
|
77
|
-
private readonly maxDelayMs;
|
|
78
|
-
private readonly retryableStatusCodes;
|
|
79
|
-
private attemptCount;
|
|
80
|
-
constructor(maxAttempts: number, baseDelayMs: number, maxDelayMs: number, retryableStatusCodes: number[]);
|
|
81
|
-
afterResponse(response: HttpResponse, request: HttpRequest): Promise<HttpResponse>;
|
|
82
|
-
private shouldRetry;
|
|
83
|
-
private getAttempts;
|
|
84
|
-
private incrementAttempts;
|
|
85
|
-
private calculateDelay;
|
|
86
|
-
private sleep;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Custom Error Classes
|
|
90
|
-
*/
|
|
91
|
-
export declare class RateLimitError extends Error {
|
|
92
|
-
readonly retryAfter: number;
|
|
93
|
-
constructor(message: string, retryAfter: number);
|
|
94
|
-
}
|
|
95
|
-
export declare class RetryableError extends Error {
|
|
96
|
-
readonly statusCode: number;
|
|
97
|
-
constructor(message: string, statusCode: number);
|
|
98
|
-
}
|
|
99
|
-
//# sourceMappingURL=http-interceptor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"http-interceptor.d.ts","sourceRoot":"","sources":["../../../src/api/http-interceptor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,WAAW,WAAW;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC;IAC5C,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;CAC1D;AAED,MAAM,WAAW,WAAW;IACxB;;;OAGG;IACH,aAAa,CAAC,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,CAAC;IAEzE;;;OAGG;IACH,aAAa,CAAC,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAAC;IAEnG;;;OAGG;IACH,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;CACxE;AAED;;GAEG;AACH,qBAAa,UAAU;IACnB,OAAO,CAAC,YAAY,CAAqB;IAEzC;;OAEG;IACH,GAAG,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IAInC;;OAEG;IACG,OAAO,CACT,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,YAAY,CAAC,GACtD,OAAO,CAAC,YAAY,CAAC;CA+B3B;AAED;;GAEG;AACH,qBAAa,oBAAqB,YAAW,WAAW;IAIhD,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAJhC,OAAO,CAAC,YAAY,CAAK;gBAGJ,eAAe,EAAE,MAAM,EACvB,WAAW,EAAE,MAAM;IAGxC,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,WAAW;IAWhD,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG,YAAY;IAanD,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,eAAe;IAOvB;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,sBAAsB,IAAI,MAAM;CAGnC;AAED;;GAEG;AACH,qBAAa,gBAAiB,YAAW,WAAW;IAI5C,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,WAAW;IAC5B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,oBAAoB;IANzC,OAAO,CAAC,YAAY,CAAkC;gBAGjC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,oBAAoB,EAAE,MAAM,EAAE;IAG7C,aAAa,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAaxF,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,KAAK;CAGhB;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAK;aAGjB,UAAU,EAAE,MAAM;gBADlC,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM;CAKzC;AAED,qBAAa,cAAe,SAAQ,KAAK;aAGjB,UAAU,EAAE,MAAM;gBADlC,OAAO,EAAE,MAAM,EACC,UAAU,EAAE,MAAM;CAKzC"}
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* HTTP Interceptor Pattern
|
|
4
|
-
*
|
|
5
|
-
* Provides a clean separation of concerns for request/response handling,
|
|
6
|
-
* including rate limiting, retry logic, and error handling.
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.RetryableError = exports.RateLimitError = exports.RetryInterceptor = exports.RateLimitInterceptor = exports.HttpClient = void 0;
|
|
10
|
-
const constants_1 = require("../constants");
|
|
11
|
-
/**
|
|
12
|
-
* HTTP Client with interceptor support
|
|
13
|
-
*/
|
|
14
|
-
class HttpClient {
|
|
15
|
-
interceptors = [];
|
|
16
|
-
/**
|
|
17
|
-
* Add an interceptor
|
|
18
|
-
*/
|
|
19
|
-
use(interceptor) {
|
|
20
|
-
this.interceptors.push(interceptor);
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Execute request with all interceptors
|
|
24
|
-
*/
|
|
25
|
-
async execute(request, executor) {
|
|
26
|
-
try {
|
|
27
|
-
// Apply beforeRequest interceptors
|
|
28
|
-
let processedRequest = request;
|
|
29
|
-
for (const interceptor of this.interceptors) {
|
|
30
|
-
if (interceptor.beforeRequest) {
|
|
31
|
-
processedRequest = await interceptor.beforeRequest(processedRequest);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
// Execute the actual request
|
|
35
|
-
let response = await executor(processedRequest);
|
|
36
|
-
// Apply afterResponse interceptors
|
|
37
|
-
for (const interceptor of this.interceptors) {
|
|
38
|
-
if (interceptor.afterResponse) {
|
|
39
|
-
response = await interceptor.afterResponse(response, processedRequest);
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
return response;
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
// Apply error interceptors
|
|
46
|
-
for (const interceptor of this.interceptors) {
|
|
47
|
-
if (interceptor.onError) {
|
|
48
|
-
await interceptor.onError(error, request);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
throw error;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
exports.HttpClient = HttpClient;
|
|
56
|
-
/**
|
|
57
|
-
* Rate Limit Interceptor
|
|
58
|
-
*/
|
|
59
|
-
class RateLimitInterceptor {
|
|
60
|
-
maxBlockSeconds;
|
|
61
|
-
msPerSecond;
|
|
62
|
-
blockedUntil = 0;
|
|
63
|
-
constructor(maxBlockSeconds, msPerSecond) {
|
|
64
|
-
this.maxBlockSeconds = maxBlockSeconds;
|
|
65
|
-
this.msPerSecond = msPerSecond;
|
|
66
|
-
}
|
|
67
|
-
beforeRequest(request) {
|
|
68
|
-
if (this.isBlocked()) {
|
|
69
|
-
const retryAfter = this.getRetryAfter();
|
|
70
|
-
throw new RateLimitError(`API request blocked due to rate limit. Retry after ${retryAfter} seconds.`, retryAfter);
|
|
71
|
-
}
|
|
72
|
-
return request;
|
|
73
|
-
}
|
|
74
|
-
afterResponse(response) {
|
|
75
|
-
if (response.statusCode === constants_1.HTTP_STATUS.TOO_MANY_REQUESTS) {
|
|
76
|
-
const retryAfter = this.parseRetryAfter(response.headers['retry-after']);
|
|
77
|
-
const blockedFor = Math.min(retryAfter, this.maxBlockSeconds);
|
|
78
|
-
this.blockedUntil = Date.now() + blockedFor * this.msPerSecond;
|
|
79
|
-
throw new RateLimitError(`Rate limited. Retry after ${retryAfter} seconds.`, blockedFor);
|
|
80
|
-
}
|
|
81
|
-
return response;
|
|
82
|
-
}
|
|
83
|
-
isBlocked() {
|
|
84
|
-
return this.blockedUntil > Date.now();
|
|
85
|
-
}
|
|
86
|
-
getRetryAfter() {
|
|
87
|
-
return Math.max(0, Math.ceil((this.blockedUntil - Date.now()) / this.msPerSecond));
|
|
88
|
-
}
|
|
89
|
-
parseRetryAfter(value) {
|
|
90
|
-
if (!value)
|
|
91
|
-
return 60; // Default 60 seconds
|
|
92
|
-
const str = Array.isArray(value) ? value[0] : value;
|
|
93
|
-
const num = parseInt(str, 10);
|
|
94
|
-
return isNaN(num) ? 60 : num;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Check if currently rate limited
|
|
98
|
-
*/
|
|
99
|
-
isRateLimited() {
|
|
100
|
-
return this.isBlocked();
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Get time until rate limit is lifted
|
|
104
|
-
*/
|
|
105
|
-
getRateLimitRetryAfter() {
|
|
106
|
-
return this.getRetryAfter();
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
exports.RateLimitInterceptor = RateLimitInterceptor;
|
|
110
|
-
/**
|
|
111
|
-
* Retry Interceptor for transient errors
|
|
112
|
-
*/
|
|
113
|
-
class RetryInterceptor {
|
|
114
|
-
maxAttempts;
|
|
115
|
-
baseDelayMs;
|
|
116
|
-
maxDelayMs;
|
|
117
|
-
retryableStatusCodes;
|
|
118
|
-
attemptCount = new Map();
|
|
119
|
-
constructor(maxAttempts, baseDelayMs, maxDelayMs, retryableStatusCodes) {
|
|
120
|
-
this.maxAttempts = maxAttempts;
|
|
121
|
-
this.baseDelayMs = baseDelayMs;
|
|
122
|
-
this.maxDelayMs = maxDelayMs;
|
|
123
|
-
this.retryableStatusCodes = retryableStatusCodes;
|
|
124
|
-
}
|
|
125
|
-
async afterResponse(response, request) {
|
|
126
|
-
if (this.shouldRetry(response)) {
|
|
127
|
-
const attempts = this.getAttempts(request);
|
|
128
|
-
if (attempts < this.maxAttempts) {
|
|
129
|
-
this.incrementAttempts(request);
|
|
130
|
-
const delay = this.calculateDelay(attempts);
|
|
131
|
-
await this.sleep(delay);
|
|
132
|
-
throw new RetryableError('Retrying request', response.statusCode);
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return response;
|
|
136
|
-
}
|
|
137
|
-
shouldRetry(response) {
|
|
138
|
-
return this.retryableStatusCodes.includes(response.statusCode);
|
|
139
|
-
}
|
|
140
|
-
getAttempts(request) {
|
|
141
|
-
return this.attemptCount.get(request) || 0;
|
|
142
|
-
}
|
|
143
|
-
incrementAttempts(request) {
|
|
144
|
-
this.attemptCount.set(request, this.getAttempts(request) + 1);
|
|
145
|
-
}
|
|
146
|
-
calculateDelay(attempt) {
|
|
147
|
-
const exponentialDelay = this.baseDelayMs * Math.pow(2, attempt);
|
|
148
|
-
const jitter = Math.random() * this.baseDelayMs;
|
|
149
|
-
return Math.min(exponentialDelay + jitter, this.maxDelayMs);
|
|
150
|
-
}
|
|
151
|
-
sleep(ms) {
|
|
152
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
exports.RetryInterceptor = RetryInterceptor;
|
|
156
|
-
/**
|
|
157
|
-
* Custom Error Classes
|
|
158
|
-
*/
|
|
159
|
-
class RateLimitError extends Error {
|
|
160
|
-
retryAfter;
|
|
161
|
-
constructor(message, retryAfter) {
|
|
162
|
-
super(message);
|
|
163
|
-
this.retryAfter = retryAfter;
|
|
164
|
-
this.name = 'RateLimitError';
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
exports.RateLimitError = RateLimitError;
|
|
168
|
-
class RetryableError extends Error {
|
|
169
|
-
statusCode;
|
|
170
|
-
constructor(message, statusCode) {
|
|
171
|
-
super(message);
|
|
172
|
-
this.statusCode = statusCode;
|
|
173
|
-
this.name = 'RetryableError';
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
exports.RetryableError = RetryableError;
|
|
177
|
-
//# sourceMappingURL=http-interceptor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"http-interceptor.js","sourceRoot":"","sources":["../../../src/api/http-interceptor.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Service Container
|
|
3
|
-
*
|
|
4
|
-
* Lightweight dependency injection container for managing service instances.
|
|
5
|
-
* Provides singleton and factory patterns without the complexity of a full DI framework.
|
|
6
|
-
*/
|
|
7
|
-
export type ServiceFactory<T> = () => T;
|
|
8
|
-
export type ServiceIdentifier<T> = string | symbol;
|
|
9
|
-
/**
|
|
10
|
-
* Service registration options
|
|
11
|
-
*/
|
|
12
|
-
export interface ServiceOptions {
|
|
13
|
-
/** If true, service is created once and reused (default: true) */
|
|
14
|
-
singleton?: boolean;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Lightweight service container
|
|
18
|
-
*/
|
|
19
|
-
export declare class ServiceContainer {
|
|
20
|
-
private readonly factories;
|
|
21
|
-
private readonly instances;
|
|
22
|
-
private readonly options;
|
|
23
|
-
/**
|
|
24
|
-
* Register a service factory
|
|
25
|
-
*/
|
|
26
|
-
register<T>(identifier: ServiceIdentifier<T>, factory: ServiceFactory<T>, opts?: ServiceOptions): void;
|
|
27
|
-
/**
|
|
28
|
-
* Register a singleton service
|
|
29
|
-
*/
|
|
30
|
-
singleton<T>(identifier: ServiceIdentifier<T>, factory: ServiceFactory<T>): void;
|
|
31
|
-
/**
|
|
32
|
-
* Register a transient service (new instance on each resolve)
|
|
33
|
-
*/
|
|
34
|
-
transient<T>(identifier: ServiceIdentifier<T>, factory: ServiceFactory<T>): void;
|
|
35
|
-
/**
|
|
36
|
-
* Register an existing instance
|
|
37
|
-
*/
|
|
38
|
-
instance<T>(identifier: ServiceIdentifier<T>, instance: T): void;
|
|
39
|
-
/**
|
|
40
|
-
* Resolve a service
|
|
41
|
-
*/
|
|
42
|
-
resolve<T>(identifier: ServiceIdentifier<T>): T;
|
|
43
|
-
/**
|
|
44
|
-
* Check if a service is registered
|
|
45
|
-
*/
|
|
46
|
-
has(identifier: ServiceIdentifier<any>): boolean;
|
|
47
|
-
/**
|
|
48
|
-
* Unregister a service
|
|
49
|
-
*/
|
|
50
|
-
unregister(identifier: ServiceIdentifier<any>): void;
|
|
51
|
-
/**
|
|
52
|
-
* Clear all services
|
|
53
|
-
*/
|
|
54
|
-
clear(): void;
|
|
55
|
-
/**
|
|
56
|
-
* Get all registered service identifiers
|
|
57
|
-
*/
|
|
58
|
-
getRegisteredServices(): Array<ServiceIdentifier<any>>;
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Service identifiers (type-safe keys)
|
|
62
|
-
*/
|
|
63
|
-
export declare const Services: {
|
|
64
|
-
readonly LOGGER: symbol;
|
|
65
|
-
readonly CONFIG_MANAGER: symbol;
|
|
66
|
-
readonly ERROR_HANDLER: symbol;
|
|
67
|
-
readonly DAIKIN_API: symbol;
|
|
68
|
-
readonly DAIKIN_OAUTH: symbol;
|
|
69
|
-
readonly DAIKIN_MOBILE_OAUTH: symbol;
|
|
70
|
-
readonly HTTP_CLIENT: symbol;
|
|
71
|
-
readonly SERVICE_FACTORY: symbol;
|
|
72
|
-
readonly FEATURE_REGISTRY: symbol;
|
|
73
|
-
readonly UPDATE_MAPPER: symbol;
|
|
74
|
-
readonly DAIKIN_CONTROLLER: symbol;
|
|
75
|
-
};
|
|
76
|
-
/**
|
|
77
|
-
* Get the global container
|
|
78
|
-
*/
|
|
79
|
-
export declare function getContainer(): ServiceContainer;
|
|
80
|
-
/**
|
|
81
|
-
* Set the global container
|
|
82
|
-
*/
|
|
83
|
-
export declare function setContainer(container: ServiceContainer): void;
|
|
84
|
-
/**
|
|
85
|
-
* Reset the global container
|
|
86
|
-
*/
|
|
87
|
-
export declare function resetContainer(): void;
|
|
88
|
-
/**
|
|
89
|
-
* Create a new container
|
|
90
|
-
*/
|
|
91
|
-
export declare function createContainer(): ServiceContainer;
|
|
92
|
-
//# sourceMappingURL=service-container.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"service-container.d.ts","sourceRoot":"","sources":["../../../src/di/service-container.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,cAAc,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC;AACxC,MAAM,MAAM,iBAAiB,CAAC,CAAC,IAAI,MAAM,GAAG,MAAM,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,kEAAkE;IAClE,SAAS,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,qBAAa,gBAAgB;IACzB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0D;IACpF,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0C;IACpE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqD;IAE7E;;OAEG;IACH,QAAQ,CAAC,CAAC,EACN,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAChC,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,EAC1B,IAAI,GAAE,cAAmB,GAC1B,IAAI;IASP;;OAEG;IACH,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI;IAIhF;;OAEG;IACH,SAAS,CAAC,CAAC,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,IAAI;IAIhF;;OAEG;IACH,QAAQ,CAAC,CAAC,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI;IAKhE;;OAEG;IACH,OAAO,CAAC,CAAC,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,CAAC;IAwB/C;;OAEG;IACH,GAAG,CAAC,UAAU,EAAE,iBAAiB,CAAC,GAAG,CAAC,GAAG,OAAO;IAIhD;;OAEG;IACH,UAAU,CAAC,UAAU,EAAE,iBAAiB,CAAC,GAAG,CAAC,GAAG,IAAI;IAMpD;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,qBAAqB,IAAI,KAAK,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC;CAMzD;AAED;;GAEG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;CAmBX,CAAC;AAOX;;GAEG;AACH,wBAAgB,YAAY,IAAI,gBAAgB,CAK/C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,gBAAgB,GAAG,IAAI,CAE9D;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,gBAAgB,CAElD"}
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Service Container
|
|
4
|
-
*
|
|
5
|
-
* Lightweight dependency injection container for managing service instances.
|
|
6
|
-
* Provides singleton and factory patterns without the complexity of a full DI framework.
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.createContainer = exports.resetContainer = exports.setContainer = exports.getContainer = exports.Services = exports.ServiceContainer = void 0;
|
|
10
|
-
/**
|
|
11
|
-
* Lightweight service container
|
|
12
|
-
*/
|
|
13
|
-
class ServiceContainer {
|
|
14
|
-
factories = new Map();
|
|
15
|
-
instances = new Map();
|
|
16
|
-
options = new Map();
|
|
17
|
-
/**
|
|
18
|
-
* Register a service factory
|
|
19
|
-
*/
|
|
20
|
-
register(identifier, factory, opts = {}) {
|
|
21
|
-
if (this.factories.has(identifier)) {
|
|
22
|
-
throw new Error(`Service '${String(identifier)}' is already registered`);
|
|
23
|
-
}
|
|
24
|
-
this.factories.set(identifier, factory);
|
|
25
|
-
this.options.set(identifier, { singleton: true, ...opts });
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Register a singleton service
|
|
29
|
-
*/
|
|
30
|
-
singleton(identifier, factory) {
|
|
31
|
-
this.register(identifier, factory, { singleton: true });
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Register a transient service (new instance on each resolve)
|
|
35
|
-
*/
|
|
36
|
-
transient(identifier, factory) {
|
|
37
|
-
this.register(identifier, factory, { singleton: false });
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Register an existing instance
|
|
41
|
-
*/
|
|
42
|
-
instance(identifier, instance) {
|
|
43
|
-
this.instances.set(identifier, instance);
|
|
44
|
-
this.options.set(identifier, { singleton: true });
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Resolve a service
|
|
48
|
-
*/
|
|
49
|
-
resolve(identifier) {
|
|
50
|
-
// Check if instance already exists
|
|
51
|
-
if (this.instances.has(identifier)) {
|
|
52
|
-
return this.instances.get(identifier);
|
|
53
|
-
}
|
|
54
|
-
// Get factory
|
|
55
|
-
const factory = this.factories.get(identifier);
|
|
56
|
-
if (!factory) {
|
|
57
|
-
throw new Error(`Service '${String(identifier)}' is not registered`);
|
|
58
|
-
}
|
|
59
|
-
// Create instance
|
|
60
|
-
const instance = factory();
|
|
61
|
-
// Store if singleton
|
|
62
|
-
const opts = this.options.get(identifier);
|
|
63
|
-
if (opts?.singleton) {
|
|
64
|
-
this.instances.set(identifier, instance);
|
|
65
|
-
}
|
|
66
|
-
return instance;
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* Check if a service is registered
|
|
70
|
-
*/
|
|
71
|
-
has(identifier) {
|
|
72
|
-
return this.factories.has(identifier) || this.instances.has(identifier);
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Unregister a service
|
|
76
|
-
*/
|
|
77
|
-
unregister(identifier) {
|
|
78
|
-
this.factories.delete(identifier);
|
|
79
|
-
this.instances.delete(identifier);
|
|
80
|
-
this.options.delete(identifier);
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Clear all services
|
|
84
|
-
*/
|
|
85
|
-
clear() {
|
|
86
|
-
this.factories.clear();
|
|
87
|
-
this.instances.clear();
|
|
88
|
-
this.options.clear();
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Get all registered service identifiers
|
|
92
|
-
*/
|
|
93
|
-
getRegisteredServices() {
|
|
94
|
-
return [
|
|
95
|
-
...Array.from(this.factories.keys()),
|
|
96
|
-
...Array.from(this.instances.keys()),
|
|
97
|
-
];
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
exports.ServiceContainer = ServiceContainer;
|
|
101
|
-
/**
|
|
102
|
-
* Service identifiers (type-safe keys)
|
|
103
|
-
*/
|
|
104
|
-
exports.Services = {
|
|
105
|
-
// Core services
|
|
106
|
-
LOGGER: Symbol('Logger'),
|
|
107
|
-
CONFIG_MANAGER: Symbol('ConfigManager'),
|
|
108
|
-
ERROR_HANDLER: Symbol('ErrorHandler'),
|
|
109
|
-
// API services
|
|
110
|
-
DAIKIN_API: Symbol('DaikinApi'),
|
|
111
|
-
DAIKIN_OAUTH: Symbol('DaikinOAuth'),
|
|
112
|
-
DAIKIN_MOBILE_OAUTH: Symbol('DaikinMobileOAuth'),
|
|
113
|
-
HTTP_CLIENT: Symbol('HttpClient'),
|
|
114
|
-
// Platform services
|
|
115
|
-
SERVICE_FACTORY: Symbol('ServiceFactory'),
|
|
116
|
-
FEATURE_REGISTRY: Symbol('FeatureRegistry'),
|
|
117
|
-
UPDATE_MAPPER: Symbol('UpdateMapper'),
|
|
118
|
-
// Controller
|
|
119
|
-
DAIKIN_CONTROLLER: Symbol('DaikinController'),
|
|
120
|
-
};
|
|
121
|
-
/**
|
|
122
|
-
* Global container instance
|
|
123
|
-
*/
|
|
124
|
-
let globalContainer = null;
|
|
125
|
-
/**
|
|
126
|
-
* Get the global container
|
|
127
|
-
*/
|
|
128
|
-
function getContainer() {
|
|
129
|
-
if (!globalContainer) {
|
|
130
|
-
globalContainer = new ServiceContainer();
|
|
131
|
-
}
|
|
132
|
-
return globalContainer;
|
|
133
|
-
}
|
|
134
|
-
exports.getContainer = getContainer;
|
|
135
|
-
/**
|
|
136
|
-
* Set the global container
|
|
137
|
-
*/
|
|
138
|
-
function setContainer(container) {
|
|
139
|
-
globalContainer = container;
|
|
140
|
-
}
|
|
141
|
-
exports.setContainer = setContainer;
|
|
142
|
-
/**
|
|
143
|
-
* Reset the global container
|
|
144
|
-
*/
|
|
145
|
-
function resetContainer() {
|
|
146
|
-
globalContainer = null;
|
|
147
|
-
}
|
|
148
|
-
exports.resetContainer = resetContainer;
|
|
149
|
-
/**
|
|
150
|
-
* Create a new container
|
|
151
|
-
*/
|
|
152
|
-
function createContainer() {
|
|
153
|
-
return new ServiceContainer();
|
|
154
|
-
}
|
|
155
|
-
exports.createContainer = createContainer;
|
|
156
|
-
//# sourceMappingURL=service-container.js.map
|