homey-api 3.4.28 → 3.4.30
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.
|
@@ -317,6 +317,17 @@
|
|
|
317
317
|
}
|
|
318
318
|
}
|
|
319
319
|
},
|
|
320
|
+
"getAppIcon": {
|
|
321
|
+
"path": "/app/{appId}/icon",
|
|
322
|
+
"method": "get",
|
|
323
|
+
"parameters": {
|
|
324
|
+
"appId": {
|
|
325
|
+
"in": "path",
|
|
326
|
+
"type": "string",
|
|
327
|
+
"required": true
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
},
|
|
320
331
|
"getAppInstall": {
|
|
321
332
|
"path": "/app/{appId}/install",
|
|
322
333
|
"method": "get",
|
|
@@ -2596,6 +2596,202 @@
|
|
|
2596
2596
|
}
|
|
2597
2597
|
}
|
|
2598
2598
|
},
|
|
2599
|
+
"ManagerMoods": {
|
|
2600
|
+
"id": "moods",
|
|
2601
|
+
"idCamelCase": "moods",
|
|
2602
|
+
"private": true,
|
|
2603
|
+
"items": {
|
|
2604
|
+
"Mood": {
|
|
2605
|
+
"id": "mood",
|
|
2606
|
+
"schema": {
|
|
2607
|
+
"type": "object",
|
|
2608
|
+
"properties": {
|
|
2609
|
+
"id": {
|
|
2610
|
+
"type": "string"
|
|
2611
|
+
},
|
|
2612
|
+
"name": {
|
|
2613
|
+
"type": "string"
|
|
2614
|
+
},
|
|
2615
|
+
"zone": {
|
|
2616
|
+
"type": "string"
|
|
2617
|
+
},
|
|
2618
|
+
"devices": {
|
|
2619
|
+
"type": "object",
|
|
2620
|
+
"additionalProperties": false,
|
|
2621
|
+
"patternProperties": {
|
|
2622
|
+
"^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$": {
|
|
2623
|
+
"type": "object",
|
|
2624
|
+
"additionalProperties": false,
|
|
2625
|
+
"properties": {
|
|
2626
|
+
"state": {
|
|
2627
|
+
"type": "object",
|
|
2628
|
+
"additionalProperties": false,
|
|
2629
|
+
"patternProperties": {
|
|
2630
|
+
".*": {
|
|
2631
|
+
"anyOf": [
|
|
2632
|
+
{
|
|
2633
|
+
"type": "string"
|
|
2634
|
+
},
|
|
2635
|
+
{
|
|
2636
|
+
"type": "boolean"
|
|
2637
|
+
},
|
|
2638
|
+
{
|
|
2639
|
+
"type": "number"
|
|
2640
|
+
}
|
|
2641
|
+
]
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2644
|
+
}
|
|
2645
|
+
}
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
}
|
|
2649
|
+
},
|
|
2650
|
+
"additionalProperties": false
|
|
2651
|
+
}
|
|
2652
|
+
}
|
|
2653
|
+
},
|
|
2654
|
+
"operations": {
|
|
2655
|
+
"getState": {
|
|
2656
|
+
"method": "get",
|
|
2657
|
+
"path": "/state",
|
|
2658
|
+
"private": false,
|
|
2659
|
+
"scopes": [
|
|
2660
|
+
"homey.system.readonly"
|
|
2661
|
+
],
|
|
2662
|
+
"parameters": {}
|
|
2663
|
+
},
|
|
2664
|
+
"getMoods": {
|
|
2665
|
+
"method": "get",
|
|
2666
|
+
"path": "/mood",
|
|
2667
|
+
"private": false,
|
|
2668
|
+
"scopes": [
|
|
2669
|
+
"homey.mood.readonly"
|
|
2670
|
+
],
|
|
2671
|
+
"crud": {
|
|
2672
|
+
"type": "getAll",
|
|
2673
|
+
"item": "Mood"
|
|
2674
|
+
},
|
|
2675
|
+
"parameters": {}
|
|
2676
|
+
},
|
|
2677
|
+
"getMood": {
|
|
2678
|
+
"method": "get",
|
|
2679
|
+
"path": "/mood/:id",
|
|
2680
|
+
"private": false,
|
|
2681
|
+
"scopes": [
|
|
2682
|
+
"homey.mood.readonly"
|
|
2683
|
+
],
|
|
2684
|
+
"crud": {
|
|
2685
|
+
"type": "getOne",
|
|
2686
|
+
"item": "Mood"
|
|
2687
|
+
},
|
|
2688
|
+
"parameters": {
|
|
2689
|
+
"id": {
|
|
2690
|
+
"in": "path",
|
|
2691
|
+
"type": "string",
|
|
2692
|
+
"required": true
|
|
2693
|
+
}
|
|
2694
|
+
}
|
|
2695
|
+
},
|
|
2696
|
+
"createMood": {
|
|
2697
|
+
"method": "post",
|
|
2698
|
+
"path": "/mood",
|
|
2699
|
+
"private": false,
|
|
2700
|
+
"scopes": [
|
|
2701
|
+
"homey.mood"
|
|
2702
|
+
],
|
|
2703
|
+
"crud": {
|
|
2704
|
+
"type": "createOne",
|
|
2705
|
+
"item": "Mood"
|
|
2706
|
+
},
|
|
2707
|
+
"parameters": {
|
|
2708
|
+
"mood": {
|
|
2709
|
+
"in": "body",
|
|
2710
|
+
"type": "object",
|
|
2711
|
+
"root": true,
|
|
2712
|
+
"required": true,
|
|
2713
|
+
"properties": {
|
|
2714
|
+
"name": {
|
|
2715
|
+
"type": "string",
|
|
2716
|
+
"required": true
|
|
2717
|
+
},
|
|
2718
|
+
"devices": {
|
|
2719
|
+
"type": "object",
|
|
2720
|
+
"required": true
|
|
2721
|
+
}
|
|
2722
|
+
}
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
},
|
|
2726
|
+
"updateMood": {
|
|
2727
|
+
"method": "put",
|
|
2728
|
+
"path": "/mood/:id",
|
|
2729
|
+
"private": false,
|
|
2730
|
+
"scopes": [
|
|
2731
|
+
"homey.mood"
|
|
2732
|
+
],
|
|
2733
|
+
"crud": {
|
|
2734
|
+
"type": "updateOne",
|
|
2735
|
+
"item": "Mood"
|
|
2736
|
+
},
|
|
2737
|
+
"parameters": {
|
|
2738
|
+
"id": {
|
|
2739
|
+
"in": "path",
|
|
2740
|
+
"type": "string",
|
|
2741
|
+
"required": true
|
|
2742
|
+
},
|
|
2743
|
+
"mood": {
|
|
2744
|
+
"in": "body",
|
|
2745
|
+
"type": "object",
|
|
2746
|
+
"root": true,
|
|
2747
|
+
"required": true,
|
|
2748
|
+
"properties": {
|
|
2749
|
+
"name": {
|
|
2750
|
+
"type": "string"
|
|
2751
|
+
},
|
|
2752
|
+
"devices": {
|
|
2753
|
+
"type": "object"
|
|
2754
|
+
}
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2758
|
+
},
|
|
2759
|
+
"setMood": {
|
|
2760
|
+
"method": "post",
|
|
2761
|
+
"path": "/mood/:id/set",
|
|
2762
|
+
"private": false,
|
|
2763
|
+
"scopes": [
|
|
2764
|
+
"homey.mood.set"
|
|
2765
|
+
],
|
|
2766
|
+
"parameters": {
|
|
2767
|
+
"id": {
|
|
2768
|
+
"in": "path",
|
|
2769
|
+
"type": "string",
|
|
2770
|
+
"required": true
|
|
2771
|
+
}
|
|
2772
|
+
}
|
|
2773
|
+
},
|
|
2774
|
+
"deleteMood": {
|
|
2775
|
+
"method": "delete",
|
|
2776
|
+
"path": "/mood/:id",
|
|
2777
|
+
"private": false,
|
|
2778
|
+
"scopes": [
|
|
2779
|
+
"homey.mood"
|
|
2780
|
+
],
|
|
2781
|
+
"crud": {
|
|
2782
|
+
"type": "deleteOne",
|
|
2783
|
+
"item": "Mood"
|
|
2784
|
+
},
|
|
2785
|
+
"parameters": {
|
|
2786
|
+
"id": {
|
|
2787
|
+
"in": "path",
|
|
2788
|
+
"type": "string",
|
|
2789
|
+
"required": true
|
|
2790
|
+
}
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
2793
|
+
}
|
|
2794
|
+
},
|
|
2599
2795
|
"ManagerNotifications": {
|
|
2600
2796
|
"id": "notifications",
|
|
2601
2797
|
"idCamelCase": "notifications",
|
|
@@ -935,6 +935,18 @@ export namespace HomeyAPIV3Cloud.ManagerLogic {
|
|
|
935
935
|
}
|
|
936
936
|
}
|
|
937
937
|
|
|
938
|
+
export namespace HomeyAPIV3Cloud.ManagerMoods {
|
|
939
|
+
export class Mood {
|
|
940
|
+
id: string;
|
|
941
|
+
|
|
942
|
+
name: string;
|
|
943
|
+
|
|
944
|
+
zone: string;
|
|
945
|
+
|
|
946
|
+
devices: object;
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
|
|
938
950
|
export namespace HomeyAPIV3Cloud.ManagerNotifications {
|
|
939
951
|
export class Notification {
|
|
940
952
|
id: string;
|
|
@@ -1659,6 +1671,8 @@ export class AthomAppsAPI {
|
|
|
1659
1671
|
userId?: string;
|
|
1660
1672
|
}): Promise<any>;
|
|
1661
1673
|
|
|
1674
|
+
getAppIcon(opts: { appId: string }): Promise<any>;
|
|
1675
|
+
|
|
1662
1676
|
getAppInstall(opts: {
|
|
1663
1677
|
appId: string;
|
|
1664
1678
|
|
|
@@ -1947,6 +1961,8 @@ export class AthomAppsAPI {
|
|
|
1947
1961
|
userId?: string;
|
|
1948
1962
|
}): Promise<any>;
|
|
1949
1963
|
|
|
1964
|
+
getAppIcon(opts: { appId: string }): Promise<any>;
|
|
1965
|
+
|
|
1950
1966
|
getAppInstall(opts: {
|
|
1951
1967
|
appId: string;
|
|
1952
1968
|
|
|
@@ -4589,7 +4605,15 @@ export class HomeyCloudAPI {
|
|
|
4589
4605
|
}
|
|
4590
4606
|
|
|
4591
4607
|
export class Util {
|
|
4592
|
-
static fetch(
|
|
4608
|
+
static fetch(
|
|
4609
|
+
args: string,
|
|
4610
|
+
|
|
4611
|
+
options?: Object,
|
|
4612
|
+
|
|
4613
|
+
timeoutDuration?: number,
|
|
4614
|
+
|
|
4615
|
+
timeoutMessage?: string,
|
|
4616
|
+
): Promise<any>;
|
|
4593
4617
|
|
|
4594
4618
|
static wait(ms: number): Promise<void>;
|
|
4595
4619
|
|
|
@@ -4625,7 +4649,15 @@ export class Util {
|
|
|
4625
4649
|
|
|
4626
4650
|
static encodeUrlSearchParams(params: object): string;
|
|
4627
4651
|
|
|
4628
|
-
static fetch(
|
|
4652
|
+
static fetch(
|
|
4653
|
+
args: string,
|
|
4654
|
+
|
|
4655
|
+
options?: Object,
|
|
4656
|
+
|
|
4657
|
+
timeoutDuration?: number,
|
|
4658
|
+
|
|
4659
|
+
timeoutMessage?: string,
|
|
4660
|
+
): Promise<any>;
|
|
4629
4661
|
|
|
4630
4662
|
static wait(ms: number): Promise<void>;
|
|
4631
4663
|
|
|
@@ -4835,6 +4867,8 @@ export class AthomAppsAPI {
|
|
|
4835
4867
|
userId?: string;
|
|
4836
4868
|
}): Promise<any>;
|
|
4837
4869
|
|
|
4870
|
+
getAppIcon(opts: { appId: string }): Promise<any>;
|
|
4871
|
+
|
|
4838
4872
|
getAppInstall(opts: {
|
|
4839
4873
|
appId: string;
|
|
4840
4874
|
|
|
@@ -5123,6 +5157,8 @@ export class AthomAppsAPI {
|
|
|
5123
5157
|
userId?: string;
|
|
5124
5158
|
}): Promise<any>;
|
|
5125
5159
|
|
|
5160
|
+
getAppIcon(opts: { appId: string }): Promise<any>;
|
|
5161
|
+
|
|
5126
5162
|
getAppInstall(opts: {
|
|
5127
5163
|
appId: string;
|
|
5128
5164
|
|
|
@@ -7701,7 +7737,15 @@ export class HomeyCloudAPI {
|
|
|
7701
7737
|
}
|
|
7702
7738
|
|
|
7703
7739
|
export class Util {
|
|
7704
|
-
static fetch(
|
|
7740
|
+
static fetch(
|
|
7741
|
+
args: string,
|
|
7742
|
+
|
|
7743
|
+
options?: Object,
|
|
7744
|
+
|
|
7745
|
+
timeoutDuration?: number,
|
|
7746
|
+
|
|
7747
|
+
timeoutMessage?: string,
|
|
7748
|
+
): Promise<any>;
|
|
7705
7749
|
|
|
7706
7750
|
static wait(ms: number): Promise<void>;
|
|
7707
7751
|
|
|
@@ -7737,7 +7781,15 @@ export class Util {
|
|
|
7737
7781
|
|
|
7738
7782
|
static encodeUrlSearchParams(params: object): string;
|
|
7739
7783
|
|
|
7740
|
-
static fetch(
|
|
7784
|
+
static fetch(
|
|
7785
|
+
args: string,
|
|
7786
|
+
|
|
7787
|
+
options?: Object,
|
|
7788
|
+
|
|
7789
|
+
timeoutDuration?: number,
|
|
7790
|
+
|
|
7791
|
+
timeoutMessage?: string,
|
|
7792
|
+
): Promise<any>;
|
|
7741
7793
|
|
|
7742
7794
|
static wait(ms: number): Promise<void>;
|
|
7743
7795
|
|
|
@@ -8501,6 +8553,36 @@ export namespace HomeyAPIV3Cloud {
|
|
|
8501
8553
|
}): Promise<any>;
|
|
8502
8554
|
}
|
|
8503
8555
|
|
|
8556
|
+
export class ManagerMoods extends HomeyAPIV3.ManagerMoods {
|
|
8557
|
+
getState(): Promise<any>;
|
|
8558
|
+
|
|
8559
|
+
getMoods(): Promise<{ [key: string]: HomeyAPIV3Cloud.ManagerMoods.Mood }>;
|
|
8560
|
+
|
|
8561
|
+
getMood(opts: { id: string }): Promise<HomeyAPIV3Cloud.ManagerMoods.Mood>;
|
|
8562
|
+
|
|
8563
|
+
createMood(opts: {
|
|
8564
|
+
mood: {
|
|
8565
|
+
name: string;
|
|
8566
|
+
|
|
8567
|
+
devices: object;
|
|
8568
|
+
};
|
|
8569
|
+
}): Promise<HomeyAPIV3Cloud.ManagerMoods.Mood>;
|
|
8570
|
+
|
|
8571
|
+
updateMood(opts: {
|
|
8572
|
+
id: string;
|
|
8573
|
+
|
|
8574
|
+
mood: {
|
|
8575
|
+
name?: string;
|
|
8576
|
+
|
|
8577
|
+
devices?: object;
|
|
8578
|
+
};
|
|
8579
|
+
}): Promise<HomeyAPIV3Cloud.ManagerMoods.Mood>;
|
|
8580
|
+
|
|
8581
|
+
setMood(opts: { id: string }): Promise<any>;
|
|
8582
|
+
|
|
8583
|
+
deleteMood(opts: { id: string }): Promise<any>;
|
|
8584
|
+
}
|
|
8585
|
+
|
|
8504
8586
|
export class ManagerNotifications extends HomeyAPIV3.ManagerNotifications {
|
|
8505
8587
|
getState(): Promise<any>;
|
|
8506
8588
|
|
package/lib/API.js
CHANGED
|
@@ -6,7 +6,6 @@ const Util = require('./Util');
|
|
|
6
6
|
const APIError = require('./APIError');
|
|
7
7
|
|
|
8
8
|
class API {
|
|
9
|
-
|
|
10
9
|
static SPECIFICATION = null;
|
|
11
10
|
static SPECIFICATION_URL = null;
|
|
12
11
|
static DEFINITION_CLASSES = {};
|
|
@@ -16,19 +15,13 @@ class API {
|
|
|
16
15
|
static JSDOC_PRIVATE = null;
|
|
17
16
|
static JSDOC_EXAMPLE = null;
|
|
18
17
|
|
|
19
|
-
constructor({
|
|
20
|
-
baseUrl,
|
|
21
|
-
debug = false,
|
|
22
|
-
secret = null,
|
|
23
|
-
} = {}) {
|
|
18
|
+
constructor({ baseUrl, debug = false, secret = null } = {}) {
|
|
24
19
|
// Set Debug Enabled
|
|
25
20
|
const debugEnvKey = `${Util.envKey(this.constructor.name)}_DEBUG`;
|
|
26
21
|
const debugEnv = Util.env(debugEnvKey);
|
|
27
22
|
|
|
28
23
|
Object.defineProperty(this, '__debugEnabled', {
|
|
29
|
-
value: debugEnv !== null
|
|
30
|
-
? !!debugEnv
|
|
31
|
-
: !!debug,
|
|
24
|
+
value: debugEnv !== null ? !!debugEnv : !!debug,
|
|
32
25
|
enumerable: false,
|
|
33
26
|
writable: true,
|
|
34
27
|
});
|
|
@@ -38,9 +31,7 @@ class API {
|
|
|
38
31
|
const secretEnv = Util.env(secretEnvKey);
|
|
39
32
|
|
|
40
33
|
Object.defineProperty(this, '__secret', {
|
|
41
|
-
value: secretEnv !== null
|
|
42
|
-
? secretEnv
|
|
43
|
-
: secret,
|
|
34
|
+
value: secretEnv !== null ? secretEnv : secret,
|
|
44
35
|
enumerable: false,
|
|
45
36
|
writable: false,
|
|
46
37
|
});
|
|
@@ -49,11 +40,17 @@ class API {
|
|
|
49
40
|
const baseUrlEnvKey = `${Util.envKey(this.constructor.name)}_BASEURL`;
|
|
50
41
|
const baseUrlEnv = Util.env(baseUrlEnvKey);
|
|
51
42
|
|
|
52
|
-
this.baseUrl =
|
|
53
|
-
|
|
43
|
+
this.baseUrl =
|
|
44
|
+
baseUrlEnv ||
|
|
45
|
+
baseUrl ||
|
|
46
|
+
`https://${this.constructor.SPECIFICATION.host}${this.constructor.SPECIFICATION.basePath}`;
|
|
47
|
+
if (this.baseUrl.endsWith('/'))
|
|
48
|
+
this.baseUrl = this.baseUrl.substring(0, this.baseUrl.length - 1);
|
|
54
49
|
|
|
55
50
|
// Create Operations
|
|
56
|
-
for (const [operationId, operation] of Object.entries(
|
|
51
|
+
for (const [operationId, operation] of Object.entries(
|
|
52
|
+
this.constructor.SPECIFICATION.operations || {}
|
|
53
|
+
)) {
|
|
57
54
|
this.__registerOperation(operationId, operation);
|
|
58
55
|
}
|
|
59
56
|
}
|
|
@@ -81,7 +78,11 @@ class API {
|
|
|
81
78
|
let value = args[parameterId];
|
|
82
79
|
|
|
83
80
|
// Set secret if not provided as parameter but in constructor
|
|
84
|
-
if (
|
|
81
|
+
if (
|
|
82
|
+
parameterId === 'secret' &&
|
|
83
|
+
typeof value === 'undefined' &&
|
|
84
|
+
typeof this.__secret === 'string'
|
|
85
|
+
) {
|
|
85
86
|
value = this.__secret;
|
|
86
87
|
}
|
|
87
88
|
|
|
@@ -97,16 +98,26 @@ class API {
|
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
if (typeof value !== 'undefined') {
|
|
100
|
-
if (
|
|
101
|
-
|
|
101
|
+
if (
|
|
102
|
+
parameter.in !== 'query' &&
|
|
103
|
+
parameter.type === 'string' &&
|
|
104
|
+
typeof value !== 'string'
|
|
105
|
+
) {
|
|
106
|
+
throw new Error(
|
|
107
|
+
`Invalid Parameter Type: ${parameterId}. Got: ${typeof value}. Expected: string`
|
|
108
|
+
);
|
|
102
109
|
}
|
|
103
110
|
|
|
104
111
|
if (parameter.type === 'number' && typeof value !== 'number') {
|
|
105
|
-
throw new Error(
|
|
112
|
+
throw new Error(
|
|
113
|
+
`Invalid Parameter Type: ${parameterId}. Got: ${typeof value}. Expected: number`
|
|
114
|
+
);
|
|
106
115
|
}
|
|
107
116
|
|
|
108
117
|
if (parameter.type === 'boolean' && typeof value !== 'boolean') {
|
|
109
|
-
throw new Error(
|
|
118
|
+
throw new Error(
|
|
119
|
+
`Invalid Parameter Type: ${parameterId}. Got: ${typeof value}. Expected: boolean`
|
|
120
|
+
);
|
|
110
121
|
}
|
|
111
122
|
}
|
|
112
123
|
}
|
|
@@ -149,7 +160,7 @@ class API {
|
|
|
149
160
|
context: { operation },
|
|
150
161
|
timeout: $timeout,
|
|
151
162
|
timeoutMessage: $timeoutMessage,
|
|
152
|
-
}).catch(err => {
|
|
163
|
+
}).catch((err) => {
|
|
153
164
|
if (typeof this.__secret === 'string' && err.message.includes(this.__secret)) {
|
|
154
165
|
err.message = err.message.replace(this.__secret, '<redacted>');
|
|
155
166
|
}
|
|
@@ -189,7 +200,7 @@ class API {
|
|
|
189
200
|
// Headers
|
|
190
201
|
request.headers = {
|
|
191
202
|
...request.headers,
|
|
192
|
-
...await this.onCallRequestHeaders({ request }),
|
|
203
|
+
...(await this.onCallRequestHeaders({ request })),
|
|
193
204
|
};
|
|
194
205
|
|
|
195
206
|
// Timeout
|
|
@@ -229,11 +240,18 @@ class API {
|
|
|
229
240
|
async onCallRequestExecute({ request }) {
|
|
230
241
|
this.__debug('onCallRequestExecute', request);
|
|
231
242
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
243
|
+
const result = await Util.fetch(
|
|
244
|
+
request.url,
|
|
245
|
+
{
|
|
246
|
+
method: request.method,
|
|
247
|
+
headers: request.headers,
|
|
248
|
+
body: request.body,
|
|
249
|
+
},
|
|
250
|
+
request.timeout,
|
|
251
|
+
request.timeoutMessage
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
return result;
|
|
237
255
|
}
|
|
238
256
|
|
|
239
257
|
async onCallResponse({ request, response }) {
|
|
@@ -313,7 +331,6 @@ class API {
|
|
|
313
331
|
return body.message;
|
|
314
332
|
}
|
|
315
333
|
|
|
316
|
-
|
|
317
334
|
return body;
|
|
318
335
|
}
|
|
319
336
|
|
|
@@ -343,7 +360,6 @@ class API {
|
|
|
343
360
|
|
|
344
361
|
throw new APIError(message, statusCode);
|
|
345
362
|
}
|
|
346
|
-
|
|
347
363
|
}
|
|
348
364
|
|
|
349
365
|
module.exports = API;
|
|
@@ -455,12 +455,13 @@ class HomeyAPIV3 extends HomeyAPI {
|
|
|
455
455
|
}
|
|
456
456
|
|
|
457
457
|
this.__debug(method, `${baseUrl}${path}`);
|
|
458
|
-
const res = await Util.
|
|
459
|
-
|
|
458
|
+
const res = await Util.fetch(
|
|
459
|
+
`${baseUrl}${path}`,
|
|
460
|
+
{
|
|
460
461
|
method,
|
|
461
462
|
headers,
|
|
462
463
|
body,
|
|
463
|
-
}
|
|
464
|
+
},
|
|
464
465
|
$timeout
|
|
465
466
|
);
|
|
466
467
|
|
package/lib/Util.js
CHANGED
|
@@ -14,25 +14,55 @@ class Util {
|
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Makes a call using `window.fetch` or `node-fetch`.
|
|
17
|
-
* @param {
|
|
18
|
-
* @
|
|
17
|
+
* @param {string} args
|
|
18
|
+
* @param {{}=} options
|
|
19
|
+
* @param {number=} timeoutDuration
|
|
20
|
+
* @param {string=} timeoutMessage
|
|
21
|
+
* @returns {Promise<any>}
|
|
19
22
|
*/
|
|
20
|
-
static async fetch(
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
static async fetch(url, options, timeoutDuration, timeoutMessage) {
|
|
24
|
+
options = { ...options };
|
|
25
|
+
let abortTimeout = null;
|
|
26
|
+
|
|
27
|
+
if (timeoutDuration != null) {
|
|
28
|
+
const abortController = new AbortController();
|
|
29
|
+
|
|
30
|
+
abortTimeout = setTimeout(() => {
|
|
31
|
+
abortController.abort('Timeout');
|
|
32
|
+
}, timeoutDuration);
|
|
33
|
+
|
|
34
|
+
options.signal = abortController.signal;
|
|
23
35
|
}
|
|
24
36
|
|
|
25
|
-
|
|
26
|
-
return window.fetch(...args);
|
|
27
|
-
}
|
|
37
|
+
let responsePromise = null;
|
|
28
38
|
|
|
29
|
-
if (this.
|
|
39
|
+
if (this.isReactNative()) {
|
|
40
|
+
responsePromise = fetch(url, options);
|
|
41
|
+
} else if (this.isBrowser()) {
|
|
42
|
+
responsePromise = window.fetch(url, options);
|
|
43
|
+
} else if (this.isNodeJS()) {
|
|
30
44
|
const fetch = require('node-fetch');
|
|
31
|
-
|
|
45
|
+
responsePromise = fetch(url, options);
|
|
46
|
+
} else if (typeof fetch !== 'undefined') {
|
|
47
|
+
responsePromise = fetch(url, options);
|
|
48
|
+
} else {
|
|
49
|
+
throw new Error('No fetch implementation found');
|
|
32
50
|
}
|
|
33
51
|
|
|
34
|
-
|
|
35
|
-
|
|
52
|
+
try {
|
|
53
|
+
const result = await responsePromise;
|
|
54
|
+
|
|
55
|
+
return result;
|
|
56
|
+
} catch (err) {
|
|
57
|
+
if (err.name === 'AbortError') {
|
|
58
|
+
if (options.signal && options.signal.aborted && options.signal.reason === 'Timeout') {
|
|
59
|
+
throw new APIErrorTimeout(timeoutMessage ?? `Timeout after ${timeoutDuration}ms`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
throw err;
|
|
64
|
+
} finally {
|
|
65
|
+
clearTimeout(abortTimeout);
|
|
36
66
|
}
|
|
37
67
|
}
|
|
38
68
|
|