eufy-security-client 2.4.2 → 2.4.3

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.
Files changed (85) hide show
  1. package/README.md +6 -0
  2. package/build/error.d.ts +57 -57
  3. package/build/error.js +155 -155
  4. package/build/eufysecurity.d.ts +161 -161
  5. package/build/eufysecurity.js +2091 -2091
  6. package/build/http/api.d.ts +90 -90
  7. package/build/http/api.js +1407 -1407
  8. package/build/http/api.js.map +1 -1
  9. package/build/http/cache.d.ts +8 -8
  10. package/build/http/cache.js +33 -33
  11. package/build/http/const.d.ts +3 -3
  12. package/build/http/const.js +8545 -8545
  13. package/build/http/device.d.ts +360 -360
  14. package/build/http/device.js +2793 -2793
  15. package/build/http/device.js.map +1 -1
  16. package/build/http/error.d.ts +28 -28
  17. package/build/http/error.js +76 -76
  18. package/build/http/index.d.ts +10 -10
  19. package/build/http/index.js +29 -29
  20. package/build/http/interfaces.d.ts +202 -202
  21. package/build/http/interfaces.js +2 -2
  22. package/build/http/models.d.ts +561 -561
  23. package/build/http/models.js +2 -2
  24. package/build/http/parameter.d.ts +5 -5
  25. package/build/http/parameter.js +75 -75
  26. package/build/http/station.d.ts +292 -292
  27. package/build/http/station.js +6780 -6780
  28. package/build/http/station.js.map +1 -1
  29. package/build/http/types.d.ts +945 -945
  30. package/build/http/types.js +6070 -6070
  31. package/build/http/utils.d.ts +37 -37
  32. package/build/http/utils.js +370 -370
  33. package/build/index.d.ts +7 -7
  34. package/build/index.js +25 -25
  35. package/build/interfaces.d.ts +113 -113
  36. package/build/interfaces.js +2 -2
  37. package/build/mqtt/interface.d.ts +6 -6
  38. package/build/mqtt/interface.js +2 -2
  39. package/build/mqtt/model.d.ts +24 -24
  40. package/build/mqtt/model.js +2 -2
  41. package/build/mqtt/service.d.ts +30 -30
  42. package/build/mqtt/service.js +168 -168
  43. package/build/mqtt/service.js.map +1 -1
  44. package/build/p2p/ble.d.ts +47 -47
  45. package/build/p2p/ble.js +188 -188
  46. package/build/p2p/ble.js.map +1 -1
  47. package/build/p2p/error.d.ts +24 -24
  48. package/build/p2p/error.js +67 -67
  49. package/build/p2p/index.d.ts +8 -8
  50. package/build/p2p/index.js +27 -27
  51. package/build/p2p/interfaces.d.ts +162 -162
  52. package/build/p2p/interfaces.js +2 -2
  53. package/build/p2p/models.d.ts +146 -146
  54. package/build/p2p/models.js +2 -2
  55. package/build/p2p/session.d.ts +168 -168
  56. package/build/p2p/session.js +2087 -2087
  57. package/build/p2p/session.js.map +1 -1
  58. package/build/p2p/talkback.d.ts +10 -10
  59. package/build/p2p/talkback.js +22 -22
  60. package/build/p2p/types.d.ts +923 -923
  61. package/build/p2p/types.js +957 -957
  62. package/build/p2p/utils.d.ts +56 -56
  63. package/build/p2p/utils.js +653 -653
  64. package/build/push/client.d.ts +51 -51
  65. package/build/push/client.js +311 -311
  66. package/build/push/client.js.map +1 -1
  67. package/build/push/index.d.ts +5 -5
  68. package/build/push/index.js +24 -24
  69. package/build/push/interfaces.d.ts +19 -19
  70. package/build/push/interfaces.js +2 -2
  71. package/build/push/models.d.ts +292 -292
  72. package/build/push/models.js +30 -30
  73. package/build/push/parser.d.ts +28 -28
  74. package/build/push/parser.js +215 -215
  75. package/build/push/parser.js.map +1 -1
  76. package/build/push/service.d.ts +45 -45
  77. package/build/push/service.js +643 -643
  78. package/build/push/service.js.map +1 -1
  79. package/build/push/types.d.ts +176 -176
  80. package/build/push/types.js +192 -192
  81. package/build/push/utils.d.ts +7 -7
  82. package/build/push/utils.js +102 -102
  83. package/build/utils.d.ts +13 -13
  84. package/build/utils.js +191 -191
  85. package/package.json +9 -9
package/build/utils.d.ts CHANGED
@@ -1,13 +1,13 @@
1
- import { Logger } from "ts-log";
2
- import { EufySecurityPersistentData } from "./interfaces";
3
- import { PropertyMetadataAny } from "./http/interfaces";
4
- export declare const removeLastChar: (text: string, char: string) => string;
5
- export declare const generateUDID: () => string;
6
- export declare const generateSerialnumber: (length: number) => string;
7
- export declare const md5: (contents: string) => string;
8
- export declare const handleUpdate: (config: EufySecurityPersistentData, log: Logger, oldVersion: number) => EufySecurityPersistentData;
9
- export declare const isEmpty: (str: string | null | undefined) => boolean;
10
- export declare const parseValue: (metadata: PropertyMetadataAny, value: unknown) => unknown;
11
- export declare const validValue: (metadata: PropertyMetadataAny, value: unknown) => void;
12
- export declare const mergeDeep: (target: Record<string, any> | undefined, source: Record<string, any>) => Record<string, any>;
13
- export declare const parseJSON: (data: string, log: Logger) => any;
1
+ import { Logger } from "ts-log";
2
+ import { EufySecurityPersistentData } from "./interfaces";
3
+ import { PropertyMetadataAny } from "./http/interfaces";
4
+ export declare const removeLastChar: (text: string, char: string) => string;
5
+ export declare const generateUDID: () => string;
6
+ export declare const generateSerialnumber: (length: number) => string;
7
+ export declare const md5: (contents: string) => string;
8
+ export declare const handleUpdate: (config: EufySecurityPersistentData, log: Logger, oldVersion: number) => EufySecurityPersistentData;
9
+ export declare const isEmpty: (str: string | null | undefined) => boolean;
10
+ export declare const parseValue: (metadata: PropertyMetadataAny, value: unknown) => unknown;
11
+ export declare const validValue: (metadata: PropertyMetadataAny, value: unknown) => void;
12
+ export declare const mergeDeep: (target: Record<string, any> | undefined, source: Record<string, any>) => Record<string, any>;
13
+ export declare const parseJSON: (data: string, log: Logger) => any;
package/build/utils.js CHANGED
@@ -1,192 +1,192 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.parseJSON = exports.mergeDeep = exports.validValue = exports.parseValue = exports.isEmpty = exports.handleUpdate = exports.md5 = exports.generateSerialnumber = exports.generateUDID = exports.removeLastChar = void 0;
27
- const crypto = __importStar(require("crypto"));
28
- const error_1 = require("./error");
29
- const removeLastChar = function (text, char) {
30
- const strArr = [...text];
31
- strArr.splice(text.lastIndexOf(char), 1);
32
- return strArr.join("");
33
- };
34
- exports.removeLastChar = removeLastChar;
35
- const generateUDID = function () {
36
- return crypto.randomBytes(8).readBigUInt64BE().toString(16);
37
- };
38
- exports.generateUDID = generateUDID;
39
- const generateSerialnumber = function (length) {
40
- return crypto.randomBytes(length / 2).toString("hex");
41
- };
42
- exports.generateSerialnumber = generateSerialnumber;
43
- const md5 = (contents) => crypto.createHash("md5").update(contents).digest("hex");
44
- exports.md5 = md5;
45
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
46
- const handleUpdate = function (config, log, oldVersion) {
47
- if (oldVersion <= 1.24) {
48
- config.cloud_token = "";
49
- config.cloud_token_expiration = 0;
50
- }
51
- return config;
52
- };
53
- exports.handleUpdate = handleUpdate;
54
- const isEmpty = function (str) {
55
- if (str) {
56
- if (str.length > 0)
57
- return false;
58
- return true;
59
- }
60
- return true;
61
- };
62
- exports.isEmpty = isEmpty;
63
- const parseValue = function (metadata, value) {
64
- if (metadata.type === "boolean") {
65
- if (value !== undefined) {
66
- switch (typeof value) {
67
- case "boolean":
68
- break;
69
- case "number":
70
- if (value === 0 || value === 1) {
71
- value = value === 1 ? true : false;
72
- }
73
- else {
74
- throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a boolean value`);
75
- }
76
- break;
77
- case "string":
78
- if (value.toLowerCase() === "true" || value.toLowerCase() === "false") {
79
- value = value.toLowerCase() === "true" ? true : false;
80
- }
81
- else {
82
- throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a boolean value`);
83
- }
84
- break;
85
- default:
86
- throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a boolean value`);
87
- }
88
- }
89
- else {
90
- throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a boolean value`);
91
- }
92
- }
93
- else if (metadata.type === "number") {
94
- if (value !== undefined) {
95
- switch (typeof value) {
96
- case "number":
97
- break;
98
- case "string":
99
- try {
100
- value = Number.parseInt(value);
101
- }
102
- catch (error) {
103
- throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a number value`);
104
- }
105
- break;
106
- default:
107
- throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a number value`);
108
- }
109
- }
110
- else {
111
- throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a number value`);
112
- }
113
- }
114
- else if (metadata.type === "string") {
115
- if (value !== undefined) {
116
- switch (typeof value) {
117
- case "number":
118
- value = value.toString();
119
- break;
120
- case "string":
121
- break;
122
- case "boolean":
123
- value = value === true ? "true" : "false";
124
- break;
125
- default:
126
- throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a number value`);
127
- }
128
- }
129
- else {
130
- throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a number value`);
131
- }
132
- }
133
- else {
134
- throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a ${metadata.type} value`);
135
- }
136
- return value;
137
- };
138
- exports.parseValue = parseValue;
139
- const validValue = function (metadata, value) {
140
- if (metadata.type === "number") {
141
- const numberMetadata = metadata;
142
- const numericValue = Number(value);
143
- if ((numberMetadata.min !== undefined && numberMetadata.min > numericValue) || (numberMetadata.max !== undefined && numberMetadata.max < numericValue) || (numberMetadata.states !== undefined && numberMetadata.states[numericValue] === undefined) || Number.isNaN(numericValue)) {
144
- throw new error_1.InvalidPropertyValueError(`Value "${numericValue}" isn't a valid value for property "${numberMetadata.name}"`);
145
- }
146
- }
147
- else if (metadata.type === "string") {
148
- const stringMetadata = metadata;
149
- const stringValue = String(value);
150
- if ((stringMetadata.format !== undefined && stringValue.match(stringMetadata.format) === null) || (stringMetadata.minLength !== undefined && stringMetadata.minLength > stringValue.length) || (stringMetadata.maxLength !== undefined && stringMetadata.maxLength < stringValue.length)) {
151
- throw new error_1.InvalidPropertyValueError(`Value "${stringValue}" isn't a valid value for property "${stringMetadata.name}"`);
152
- }
153
- }
154
- else if (metadata.type === "boolean") {
155
- const str = String(value).toLowerCase().trim();
156
- if (str !== "true" && str !== "false") {
157
- throw new error_1.InvalidPropertyValueError(`Value "${value}" isn't a valid value for property "${metadata.name}"`);
158
- }
159
- }
160
- };
161
- exports.validValue = validValue;
162
- const mergeDeep = function (target, source) {
163
- target = target || {};
164
- for (const [key, value] of Object.entries(source)) {
165
- if (!(key in target)) {
166
- target[key] = value;
167
- }
168
- else {
169
- if (typeof value === "object") {
170
- // merge objects
171
- target[key] = (0, exports.mergeDeep)(target[key], value);
172
- }
173
- else if (typeof target[key] === "undefined") {
174
- // don't override single keys
175
- target[key] = value;
176
- }
177
- }
178
- }
179
- return target;
180
- };
181
- exports.mergeDeep = mergeDeep;
182
- const parseJSON = function (data, log) {
183
- try {
184
- return JSON.parse(data.replace(/[\0]+$/g, ""));
185
- }
186
- catch (error) {
187
- log.error("JSON parse error", data, error);
188
- }
189
- return undefined;
190
- };
191
- exports.parseJSON = parseJSON;
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.parseJSON = exports.mergeDeep = exports.validValue = exports.parseValue = exports.isEmpty = exports.handleUpdate = exports.md5 = exports.generateSerialnumber = exports.generateUDID = exports.removeLastChar = void 0;
27
+ const crypto = __importStar(require("crypto"));
28
+ const error_1 = require("./error");
29
+ const removeLastChar = function (text, char) {
30
+ const strArr = [...text];
31
+ strArr.splice(text.lastIndexOf(char), 1);
32
+ return strArr.join("");
33
+ };
34
+ exports.removeLastChar = removeLastChar;
35
+ const generateUDID = function () {
36
+ return crypto.randomBytes(8).readBigUInt64BE().toString(16);
37
+ };
38
+ exports.generateUDID = generateUDID;
39
+ const generateSerialnumber = function (length) {
40
+ return crypto.randomBytes(length / 2).toString("hex");
41
+ };
42
+ exports.generateSerialnumber = generateSerialnumber;
43
+ const md5 = (contents) => crypto.createHash("md5").update(contents).digest("hex");
44
+ exports.md5 = md5;
45
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
46
+ const handleUpdate = function (config, log, oldVersion) {
47
+ if (oldVersion <= 1.24) {
48
+ config.cloud_token = "";
49
+ config.cloud_token_expiration = 0;
50
+ }
51
+ return config;
52
+ };
53
+ exports.handleUpdate = handleUpdate;
54
+ const isEmpty = function (str) {
55
+ if (str) {
56
+ if (str.length > 0)
57
+ return false;
58
+ return true;
59
+ }
60
+ return true;
61
+ };
62
+ exports.isEmpty = isEmpty;
63
+ const parseValue = function (metadata, value) {
64
+ if (metadata.type === "boolean") {
65
+ if (value !== undefined) {
66
+ switch (typeof value) {
67
+ case "boolean":
68
+ break;
69
+ case "number":
70
+ if (value === 0 || value === 1) {
71
+ value = value === 1 ? true : false;
72
+ }
73
+ else {
74
+ throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a boolean value`);
75
+ }
76
+ break;
77
+ case "string":
78
+ if (value.toLowerCase() === "true" || value.toLowerCase() === "false") {
79
+ value = value.toLowerCase() === "true" ? true : false;
80
+ }
81
+ else {
82
+ throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a boolean value`);
83
+ }
84
+ break;
85
+ default:
86
+ throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a boolean value`);
87
+ }
88
+ }
89
+ else {
90
+ throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a boolean value`);
91
+ }
92
+ }
93
+ else if (metadata.type === "number") {
94
+ if (value !== undefined) {
95
+ switch (typeof value) {
96
+ case "number":
97
+ break;
98
+ case "string":
99
+ try {
100
+ value = Number.parseInt(value);
101
+ }
102
+ catch (error) {
103
+ throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a number value`);
104
+ }
105
+ break;
106
+ default:
107
+ throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a number value`);
108
+ }
109
+ }
110
+ else {
111
+ throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a number value`);
112
+ }
113
+ }
114
+ else if (metadata.type === "string") {
115
+ if (value !== undefined) {
116
+ switch (typeof value) {
117
+ case "number":
118
+ value = value.toString();
119
+ break;
120
+ case "string":
121
+ break;
122
+ case "boolean":
123
+ value = value === true ? "true" : "false";
124
+ break;
125
+ default:
126
+ throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a number value`);
127
+ }
128
+ }
129
+ else {
130
+ throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a number value`);
131
+ }
132
+ }
133
+ else {
134
+ throw new error_1.InvalidPropertyValueError(`Property ${metadata.name} expects a ${metadata.type} value`);
135
+ }
136
+ return value;
137
+ };
138
+ exports.parseValue = parseValue;
139
+ const validValue = function (metadata, value) {
140
+ if (metadata.type === "number") {
141
+ const numberMetadata = metadata;
142
+ const numericValue = Number(value);
143
+ if ((numberMetadata.min !== undefined && numberMetadata.min > numericValue) || (numberMetadata.max !== undefined && numberMetadata.max < numericValue) || (numberMetadata.states !== undefined && numberMetadata.states[numericValue] === undefined) || Number.isNaN(numericValue)) {
144
+ throw new error_1.InvalidPropertyValueError(`Value "${numericValue}" isn't a valid value for property "${numberMetadata.name}"`);
145
+ }
146
+ }
147
+ else if (metadata.type === "string") {
148
+ const stringMetadata = metadata;
149
+ const stringValue = String(value);
150
+ if ((stringMetadata.format !== undefined && stringValue.match(stringMetadata.format) === null) || (stringMetadata.minLength !== undefined && stringMetadata.minLength > stringValue.length) || (stringMetadata.maxLength !== undefined && stringMetadata.maxLength < stringValue.length)) {
151
+ throw new error_1.InvalidPropertyValueError(`Value "${stringValue}" isn't a valid value for property "${stringMetadata.name}"`);
152
+ }
153
+ }
154
+ else if (metadata.type === "boolean") {
155
+ const str = String(value).toLowerCase().trim();
156
+ if (str !== "true" && str !== "false") {
157
+ throw new error_1.InvalidPropertyValueError(`Value "${value}" isn't a valid value for property "${metadata.name}"`);
158
+ }
159
+ }
160
+ };
161
+ exports.validValue = validValue;
162
+ const mergeDeep = function (target, source) {
163
+ target = target || {};
164
+ for (const [key, value] of Object.entries(source)) {
165
+ if (!(key in target)) {
166
+ target[key] = value;
167
+ }
168
+ else {
169
+ if (typeof value === "object") {
170
+ // merge objects
171
+ target[key] = (0, exports.mergeDeep)(target[key], value);
172
+ }
173
+ else if (typeof target[key] === "undefined") {
174
+ // don't override single keys
175
+ target[key] = value;
176
+ }
177
+ }
178
+ }
179
+ return target;
180
+ };
181
+ exports.mergeDeep = mergeDeep;
182
+ const parseJSON = function (data, log) {
183
+ try {
184
+ return JSON.parse(data.replace(/[\0]+$/g, ""));
185
+ }
186
+ catch (error) {
187
+ log.error("JSON parse error", data, error);
188
+ }
189
+ return undefined;
190
+ };
191
+ exports.parseJSON = parseJSON;
192
192
  //# sourceMappingURL=utils.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eufy-security-client",
3
- "version": "2.4.2",
3
+ "version": "2.4.3",
4
4
  "description": "Client to comunicate with Eufy-Security devices",
5
5
  "author": {
6
6
  "name": "bropat",
@@ -42,30 +42,30 @@
42
42
  "dependencies": {
43
43
  "got": "^11.8.6",
44
44
  "protobuf-typescript": "^6.8.8",
45
- "qs": "^6.11.0",
45
+ "qs": "^6.11.1",
46
46
  "node-rsa": "^1.1.1",
47
47
  "crypto-js": "^4.1.1",
48
48
  "ts-log": "^2.2.5",
49
49
  "tiny-typed-emitter": "^2.1.0",
50
50
  "i18n-iso-countries": "^7.5.0",
51
- "@cospired/i18n-iso-languages": "^4.0.1",
52
- "fs-extra": "^11.1.0",
51
+ "@cospired/i18n-iso-languages": "^4.1.0",
52
+ "fs-extra": "^11.1.1",
53
53
  "sweet-collections": "^1.1.0",
54
54
  "mqtt": "^4.3.7",
55
55
  "node-schedule": "^2.1.1",
56
56
  "p-throttle": "^4.1.1"
57
57
  },
58
58
  "devDependencies": {
59
- "@types/node": "^16.18.12",
59
+ "@types/node": "^16.18.23",
60
60
  "@types/qs": "^6.9.7",
61
61
  "@types/node-rsa": "^1.1.1",
62
62
  "@types/crypto-js": "^4.1.1",
63
63
  "@types/fs-extra": "^11.0.1",
64
64
  "@types/node-schedule": "^2.1.0",
65
- "@typescript-eslint/eslint-plugin": "^5.52.0",
66
- "@typescript-eslint/parser": "^5.52.0",
67
- "eslint": "^8.34.0",
68
- "typescript": "^4.9.5"
65
+ "@typescript-eslint/eslint-plugin": "^5.58.0",
66
+ "@typescript-eslint/parser": "^5.58.0",
67
+ "eslint": "^8.38.0",
68
+ "typescript": "^5.0.4"
69
69
  },
70
70
  "bugs": {
71
71
  "url": "https://github.com/bropat/eufy-security-client/issues"